<div dir="ltr"><div>Hi everyone,</div><div><br></div><div>I'm working on a program to compile C++ code into llvm::Modules at the moment and am having trouble handling files with errors. I'm following along with the <a href="https://github.com/llvm-mirror/clang/blob/324f918438715b4a0d024af5930628c1674f4fcd/unittests/CodeGen/IncrementalProcessingTest.cpp">incremental processing unit test</a>. The method in there works fine, unless the file its asked to parse contains an error in which case it segfaults. The problem seems to extend to <span style="font-family:monospace">clang::parseAST</span> as well and I can reproduce it pretty easily. I attached a program to do that at the end of the email.</div><div><br></div><div>According to gdb, the segfault is happening in clang::DiagnosticRenderer::emitDiagnostic, but the stack trace other than that looks pretty good. The <span style="font-family:monospace">clang::Sema</span> calls <span style="font-family:monospace">clang::Sema::DiagnoseUnknownTypeName</span> which seems like the right idea.</div><div><br></div><div>Does anyone have any ideas why this might be happening or how to fix this? I'm also open to other ideas on how best to approach compiling C++ code into llvm::Modules from inside C++ land. Ultimately, I'd like to be able to JIT the resulting code with LLVM's JIT.<br></div><div><br></div><div>Thanks,</div><div>Zeke<br></div><div><br></div><div><font size="4">Program to reproduce</font><br></div><div><br></div><div><span style="font-family:monospace">#include "clang/AST/ASTConsumer.h"<br>#include "clang/AST/ASTContext.h"<br>#include "clang/AST/RecursiveASTVisitor.h"<br>#include "clang/Basic/TargetInfo.h"<br>#include "clang/CodeGen/ModuleBuilder.h"<br>#include "clang/Frontend/CompilerInstance.h"<br>#include "clang/Lex/Preprocessor.h"<br>#include "clang/Parse/ParseAST.h"<br>#include "clang/Sema/Sema.h"<br>#include "llvm/ADT/Triple.h"<br>#include "llvm/IR/LLVMContext.h"<br>#include "llvm/Support/Host.h"<br>#include "llvm/Support/MemoryBuffer.h"<br><br>using namespace llvm;<br>using namespace clang;<br><br>const char TestProgram[] =<br>    "class EmitCXXGlobalInitFunc    "<br>    "{                              "<br>    "public:                        "<br>    "  <b>err</b> EmitCXXGlobalInitFunc() {}  " // I've added an error here.<br>    "};                             "<br>    "EmitCXXGlobalInitFunc test;    ";<br><br><br>int main()<br>    {<br>    LLVMContext Context;<br>    CompilerInstance compiler;<br><br>    compiler.createDiagnostics();<br>    compiler.getLangOpts().CPlusPlus = 1;<br>    compiler.getLangOpts().CPlusPlus11 = 1;<br><br>    compiler.getTargetOpts().Triple = llvm::Triple::normalize(<br>    llvm::sys::getProcessTriple());<br>    compiler.setTarget(clang::TargetInfo::CreateTargetInfo(<br>         compiler.getDiagnostics(),<br>          std::make_shared<clang::TargetOptions>(<br>       compiler.getTargetOpts())));<br><br>    compiler.createFileManager();<br>    compiler.createSourceManager(compiler.getFileManager());<br>    compiler.createPreprocessor(clang::TU_Prefix);<br><br>    compiler.createASTContext();<br><br>    compiler.setASTConsumer(std::unique_ptr<ASTConsumer>(<br>         CreateLLVMCodeGen(<br>                 compiler.getDiagnostics(),<br>               "EmitCXXGlobalInitFuncTest",<br>                   compiler.getHeaderSearchOpts(),<br>                  compiler.getPreprocessorOpts(),<br>                  compiler.getCodeGenOpts(),<br>               Context)));<br><br>    compiler.createSema(clang::TU_Prefix, nullptr);<br><br>    clang::SourceManager &sm = compiler.getSourceManager();<br>    sm.setMainFileID(sm.createFileID(<br>    llvm::MemoryBuffer::getMemBuffer(TestProgram), clang::SrcMgr::C_User));<br><br>    clang::ParseAST(compiler.getSema(), false, false);  // segfault here.<br>    }</span></div><div><br></div><div><font size="4">Stack Trace:</font></div><div><font size="4"><br></font></div><div><font size="4"><span style="font-family:monospace"><font size="2">#0  0x0000000000df3c2f in clang::DiagnosticRenderer::emitDiagnostic(clang::FullSourceLoc, clang::DiagnosticsEngine::Level, llvm::StringRef, llvm::ArrayRef<clang::CharSourceRange>, llvm::ArrayRef<clang::FixItHint>, llvm::PointerUnion<clang::Diagnostic const*, clang::StoredDiagnostic const*>) ()<br>#1  0x0000000000dbe8d3 in clang::TextDiagnosticPrinter::HandleDiagnostic(clang::DiagnosticsEngine::Level, clang::Diagnostic const&) ()<br>#2  0x0000000001ab8066 in clang::DiagnosticIDs::ProcessDiag(clang::DiagnosticsEngine&) const ()<br>#3  0x0000000001ab28a3 in clang::DiagnosticsEngine::EmitCurrentDiagnostic(bool) ()<br>#4  0x000000000117fa7a in clang::Sema::EmitCurrentDiagnostic(unsigned int) ()<br>#5  0x000000000123a528 in clang::Sema::DiagnoseUnknownTypeName(clang::IdentifierInfo*&, clang::SourceLocation, clang::Scope*, clang::CXXScopeSpec*, clang::OpaquePtr<clang::QualType>&, bool) ()<br>#6  0x0000000000f32aad in clang::Parser::ParseImplicitInt(clang::DeclSpec&, clang::CXXScopeSpec*, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::ParsedAttributesWithRange&) ()<br>#7  0x0000000000f2de92 in clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) ()<br>#8  0x0000000000f4bb6c in clang::Parser::ParseCXXClassMemberDeclaration(clang::AccessSpecifier, clang::ParsedAttributes&, clang::Parser::ParsedTemplateInfo const&, clang::ParsingDeclRAIIObject*) ()<br>#9  0x0000000000f4e3a5 in clang::Parser::ParseCXXClassMemberDeclarationWithPragmas(clang::AccessSpecifier&, clang::Parser::ParsedAttributesWithRange&, clang::TypeSpecifierType, clang::Decl*) ()<br>#10 0x0000000000f49358 in clang::Parser::ParseCXXMemberSpecification(clang::SourceLocation, clang::SourceLocation, clang::Parser::ParsedAttributesWithRange&, unsigned int, clang::Decl*) ()<br>#11 0x0000000000f46e51 in clang::Parser::ParseClassSpecifier(clang::tok::TokenKind, clang::SourceLocation, clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, bool, clang::Parser::DeclSpecContext, clang::Parser::ParsedAttributesWithRange&) ()<br>#12 0x0000000000f2c05e in clang::Parser::ParseDeclarationSpecifiers(clang::DeclSpec&, clang::Parser::ParsedTemplateInfo const&, clang::AccessSpecifier, clang::Parser::DeclSpecContext, clang::Parser::LateParsedAttrList*) ()<br>#13 0x0000000000f1827a in clang::Parser::ParseDeclOrFunctionDefInternal(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec&, clang::AccessSpecifier) ()<br>#14 0x0000000000f17f4c in clang::Parser::ParseDeclarationOrFunctionDefinition(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*, clang::AccessSpecifier) ()<br>#15 0x0000000000f17016 in clang::Parser::ParseExternalDeclaration(clang::Parser::ParsedAttributesWithRange&, clang::ParsingDeclSpec*) ()<br>#16 0x0000000000f15482 in clang::Parser::ParseTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&, bool) ()<br>#17 0x0000000000f14ff6 in clang::Parser::ParseFirstTopLevelDecl(clang::OpaquePtr<clang::DeclGroupRef>&) ()<br>#18 0x0000000000f10ac7 in clang::ParseAST(clang::Sema&, bool, bool) ()<br>#19 0x00000000006b1dd6 in main () at parseASTtest.cpp:68</font></span><br></font></div></div>