Invoking Clang Diagnostic Printer


I am trying to output some diagnostics with a program I am building on top of Clang. I wish to invoke Clang’s pretty printer i.e. with formatting like -

t.c:38:15: error: invalid operands to binary expression ('int *' and '_Complex float')
   P = (P-42) + Gamma*4;
       ~~~~~~ ^ ~~~~~~~

When an error has occured.

In my code I setup the Compiler Instance with the relevent Diagnostic information (an extract is below) -

clang::CompilerInstance inst;
IntrusiveRefCntPtr DiagID(new DiagnosticIDs());
TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), DiagnosticOptions());
DiagnosticsEngine DE(DiagID, DiagClient);
inst.createDiagnostics(0, NULL, DiagClient);
DiagClient->BeginSourceFile(languageOptions, &inst.getPreprocessor());

I then pass the Compiler Instance reference to a Recursive ASTVisitor to walk over the AST, so say I want to emit a diagnostic if I can’t determine an array index i.e. - arr[i], I do this -

bool VisitExpr(Expr* expr){

// Get the array index the user is attempting to access
ArraySubscriptExpr* AS = (ArraySubscriptExpr*) expr;
Expr* EX = AS->getIdx(); // This grabs the index
IntegerLiteral* IL = dyn_cast(EX); // Cast so we get the value as an integer
SourceLocation SL = expr->getLocStart();


} else {

cerr << "Couldn’t determine array index on line " << pSM->getSpellingLineNumber(SL) << “\n”;


I then want to emit a diagnostic error to the user showing the location of this, so I do this -


} else {
// Where “CI” is the Compiler Instance
FullSourceLoc full(SL, *pSM);
unsigned id = CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Warning, “TEST”);
DiagnosticBuilder B = CI.getDiagnostics().Report(SL, id);


cerr << "Couldn’t determine array index on line " << pSM->getSpellingLineNumber(SL) << “\n”;


When I do this I get the error -

TextDiagnosticPrinter.cpp:155: Assertion `LangOpts && “Unexpected diagnostic outside source file processing”’ failed.

I am stuck as I am not sure what I am doing wrong, I am probabaly not setting up the Diagnostics stuff properly or I am mis-understanding how to actually invoke the Diagnostics engine. It is definatly an issue with the Source Location as when I omit this and only print the Diagnostic ID it works fine (except I don’t get the nice output of the position in the file).

If someone could spot the error of my ways or point me in the right direction that would be great!