<div dir="ltr"><div>Hi</div><div>I am trying to implement a big set of API + overloads around 10k instructions in a library. I want to minimize the parsing cost, so my approach was to pre generate an ast of my library using clang.</div>
<div><br></div><div>clang -x c++ -emit-ast mylibrary.h -o redistributable.ast </div><div><br></div><div>I plan to make this binary file redistributable along with my aplication.</div><div><br></div><div>Problem:</div><div>
<br></div><div>When I am loading the files from a different machine, it no longer works, since I think the ast binary is linked to the original sources that are no longer redistributed. Is there any way to avoid this link?</div>
<div><br></div><div>Any sugestions or path how to do this.</div><div><br></div><div>Bellow is code that I am trying.</div><div><br></div><div>This is how I currently load the ast and currently works on the same machine.</div>
<div><br></div><div><div><font size="1">#include "precompiled.ast.inc" // this has the ast in static char ast[]</font></div><div><font size="1"> CompilerInstance CI;</font></div><div><font size="1"> CI.createDiagnostics(new TextDiagnosticPrinter(m_Context.GetDiag(), new DiagnosticOptions()), true);</font></div>
<div><font size="1"><br></font></div><div><font size="1"> StringRef theString(ast, sizeof(ast));</font></div><div><font size="1"><br></font></div><div><font size="1"> // Import AST from file.</font></div><div><font size="1"> llvm::MemoryBuffer *theBuffer = llvm::MemoryBuffer::getMemBuffer(theString, "precompiled.ast", false);</font></div>
<div><font size="1"> llvm::OwningPtr<clang::ASTUnit> CUnit(ASTUnit::LoadFromASTMemoryBuffer("hlsl.ast", &ci.getDiagnostics(), CI.getFileSystemOpts(), theBuffer));</font></div><div><font size="1"><br></font></div>
<div><font size="1"> assert(CUnit.get() != nullptr && "Failed to load precomputed AST");</font></div><div><font size="1"><br></font></div><div><font size="1"> ASTImporter Importer(ci.getASTContext(), ci.getFileManager(), CUnit->getASTContext(), CUnit->getFileManager(), false);</font></div>
<div><font size="1"><br></font></div><div><font size="1"> TranslationUnitDecl *TU = CUnit->getASTContext().getTranslationUnitDecl();</font></div><div><font size="1"> for (DeclContext::decl_iterator D = TU->decls_begin(), DEnd = TU->decls_end(); D != DEnd; ++D)</font></div>
<div><font size="1"> {</font></div><div><font size="1"> // Don't re-import __va_list_tag, __builtin_va_list.</font></div><div><font size="1"> if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))</font></div><div>
<font size="1"> if (IdentifierInfo *II = ND->getIdentifier())</font></div><div><font size="1"> if (II->isStr("__va_list_tag") || II->isStr("__builtin_va_list"))</font></div><div><font size="1"> continue;</font></div>
<div><font size="1"><br></font></div><div><font size="1"> Importer.Import(*D);</font></div><div><font size="1"> }</font></div></div><div><br></div><div>I am trying experimentally this code to write the ast, but no longer is recognized by my load method, the previous load method only works for the ast generated by clang.</div>
<div><br></div><div><div><font size="1">CompilerInstance ci;</font></div><div><font size="1"><br></font></div><div><font size="1"> ci.createDiagnostics(new TextDiagnosticPrinter(m_Context.GetDiag(), new DiagnosticOptions()), true);</font></div>
<div><font size="1"> ci.createFileManager();</font></div><div><font size="1"> ci.createSourceManager(ci.getFileManager());</font></div><div><font size="1"> ci.getLangOpts().C11 = true;</font></div><div><font size="1"> ci.getLangOpts().CPlusPlus11 = true;</font></div>
<div><font size="1"> ci.getLangOpts().CPlusPlus = true;</font></div><div><font size="1"><br></font></div><div><font size="1"> ci.getTargetOpts().Triple = llvm::sys::getDefaultTargetTriple();</font></div><div><font size="1"> ci.setTarget(TargetInfo::CreateTargetInfo(ci.getDiagnostics(), &ci.getTargetOpts()));</font></div>
<div><font size="1"> ci.createPreprocessor();</font></div><div><font size="1"> ci.getPreprocessor().getBuiltinInfo().InitializeBuiltins(ci.getPreprocessor().getIdentifierTable(), ci.getLangOpts());</font></div><div><font size="1"> ci.createASTContext();</font></div>
<div><font size="1"><br></font></div><div><font size="1"> llvm::StringRef Code(m_Context.pSource, m_Context.SourceSize);</font></div><div><font size="1"><br></font></div><div><font size="1"> llvm::MemoryBuffer *pSourceBuffer = llvm::MemoryBuffer::getMemBufferCopy(Code);</font></div>
<div><font size="1"><br></font></div><div><font size="1"> ci.getSourceManager().createMainFileIDForMemBuffer(pSourceBuffer);</font></div><div><font size="1"><br></font></div><div><font size="1"> clang::CodeGenOptions codeGenOptions;</font></div>
<div><font size="1"><br></font></div><div><font size="1"> llvm::OwningPtr<clang::CodeGenerator> CG;</font></div><div><font size="1"> CG.reset(clang::CreateLLVMCodeGen(ci.getDiagnostics(),</font></div><div><font size="1"> "clangCodeGen",</font></div>
<div><font size="1"> codeGenOptions,</font></div><div><font size="1"> ci.getTargetOpts(),</font></div><div><font size="1"> m_Context.LLVMContext));</font></div><div><font size="1"> assert(CG.get() != nullptr && "could not create CodeGenerator");</font></div>
<div><font size="1"><br></font></div><div><font size="1"> ci.setASTConsumer(CG.take());</font></div><div><font size="1"><br></font></div><div><font size="1"> ci.createSema(clang::TranslationUnitKind::TU_Complete, nullptr);</font></div>
<div><font size="1"><br></font></div><div><font size="1"> ci.getDiagnosticClient().BeginSourceFile(ci.getPreprocessor().getLangOpts(), &ci.getPreprocessor());</font></div><div><font size="1"><br></font></div><div><font size="1"> clang::ParseAST(ci.getPreprocessor(), &ci.getASTConsumer(), ci.getASTContext());</font></div>
<div><font size="1"> ci.getDiagnosticClient().EndSourceFile();</font></div><div><font size="1"><br></font></div><div><font size="1"> llvm::BitstreamWriter streamWriter(astBytes);</font></div><div><font size="1"> ASTWriter astWriter(streamWriter);</font></div>
<div><font size="1"><br></font></div><div><font size="1"> astWriter.WriteAST(ci.getSema(), std::string(), nullptr, "");</font></div></div><div><br></div></div>