Hi,<br><br>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 - <br><br><pre>t.c:38:15: error: invalid operands to binary expression ('int *' and '_Complex float')
<span style="color:darkgreen">P = (P-42) + Gamma*4;</span>
<span style="color:blue">~~~~~~ ^ ~~~~~~~</span></pre>When an error has occured. <br><br> In my code I setup the Compiler Instance with the relevent Diagnostic information (an extract is below) - <br><br><br><span style="font-family:courier new,monospace">clang::CompilerInstance inst;</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">IntrusiveRefCntPtr<</span><span style="font-family:courier new,monospace">DiagnosticIDs> DiagID(new DiagnosticIDs()); </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">
TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::</span><span style="font-family:courier new,monospace">errs(), DiagnosticOptions());</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">DiagnosticsEngine DE(DiagID, DiagClient); </span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">inst.createDiagnostics(0, NULL, DiagClient);</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace">DiagClient->BeginSourceFile(</span><span style="font-family:courier new,monospace">languageOptions, &inst.getPreprocessor()); </span><br>
<br>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 - <br><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> bool VisitExpr(Expr* expr){</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> // Get the array index the user is attempting to access </span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> ArraySubscriptExpr* AS = (ArraySubscriptExpr*) expr;</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> Expr* EX = AS->getIdx(); // This grabs the index</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> IntegerLiteral* IL = dyn_cast<IntegerLiteral>(EX); // Cast so we get the value as an integer</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">
SourceLocation SL = expr->getLocStart();</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> </span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> if(IL){</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> } else {</span><br style="font-family:courier new,monospace">
<br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> cerr << "Couldn't determine array index on line " << pSM->getSpellingLineNumber(SL) << "\n";</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">
</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> }</span><br><br><br>I then want to emit a diagnostic error to the user showing the location of this, so I do this - <br>
<br><br><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> if(IL){</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> } else {</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> // Where "CI" is the Compiler Instance </span><br><span style="font-family:courier new,monospace"> if(SL.isValid()){</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> FullSourceLoc full(SL, *pSM);</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> unsigned id = CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Warning, "TEST");</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> DiagnosticBuilder B = CI.getDiagnostics().Report(SL, id);</span><br style="font-family:courier new,monospace"><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace"> }</span><br><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> cerr << "Couldn't determine array index on line " << pSM->getSpellingLineNumber(SL) << "\n";</span><br style="font-family:courier new,monospace">
<span style="font-family:courier new,monospace">
</span><br style="font-family:courier new,monospace"><span style="font-family:courier new,monospace"> }</span><br>
<br><br>When I do this I get the error - <br><br><span style="font-family:courier new,monospace">TextDiagnosticPrinter.cpp:155: Assertion `LangOpts && "Unexpected diagnostic outside source file processing"' failed.</span><br>
<br><br>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). <br>
<br>If someone could spot the error of my ways or point me in the right direction that would be great!<br><br>Thanks,<br>Laurence <br><br> <br><pre><span style="color:blue"></span><br></pre>