[cfe-dev] Invoking Clang Diagnostic Printer

Laurence Herbert laurence.herbert1 at gmail.com
Wed Mar 7 08:18:12 PST 2012


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<DiagnosticIDs> 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<IntegerLiteral>(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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120307/3ea4a520/attachment.html>


More information about the cfe-dev mailing list