Invoking Clang Diagnostic Printer

Hi,

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();

if(IL){

} 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 -

if(IL){

} else {
// Where “CI” is the Compiler Instance
if(SL.isValid()){
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!

Thanks,
Laurence