1*bc068586SAdrian Prantl //===--- ObjectFilePCHContainerOperations.cpp -----------------------------===// 2*bc068586SAdrian Prantl // 3*bc068586SAdrian Prantl // The LLVM Compiler Infrastructure 4*bc068586SAdrian Prantl // 5*bc068586SAdrian Prantl // This file is distributed under the University of Illinois Open Source 6*bc068586SAdrian Prantl // License. See LICENSE.TXT for details. 7*bc068586SAdrian Prantl // 8*bc068586SAdrian Prantl //===----------------------------------------------------------------------===// 9*bc068586SAdrian Prantl 10*bc068586SAdrian Prantl #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" 11*bc068586SAdrian Prantl #include "CGDebugInfo.h" 12*bc068586SAdrian Prantl #include "CodeGenModule.h" 13*bc068586SAdrian Prantl #include "clang/AST/ASTContext.h" 14*bc068586SAdrian Prantl #include "clang/AST/DeclObjC.h" 15*bc068586SAdrian Prantl #include "clang/AST/Expr.h" 16*bc068586SAdrian Prantl #include "clang/AST/RecursiveASTVisitor.h" 17*bc068586SAdrian Prantl #include "clang/Basic/Diagnostic.h" 18*bc068586SAdrian Prantl #include "clang/Basic/TargetInfo.h" 19*bc068586SAdrian Prantl #include "clang/CodeGen/BackendUtil.h" 20*bc068586SAdrian Prantl #include "clang/Frontend/CodeGenOptions.h" 21*bc068586SAdrian Prantl #include "clang/Serialization/ASTWriter.h" 22*bc068586SAdrian Prantl #include "llvm/ADT/StringRef.h" 23*bc068586SAdrian Prantl #include "llvm/Bitcode/BitstreamReader.h" 24*bc068586SAdrian Prantl #include "llvm/DebugInfo/DWARF/DWARFContext.h" 25*bc068586SAdrian Prantl #include "llvm/IR/Constants.h" 26*bc068586SAdrian Prantl #include "llvm/IR/DataLayout.h" 27*bc068586SAdrian Prantl #include "llvm/IR/LLVMContext.h" 28*bc068586SAdrian Prantl #include "llvm/IR/Module.h" 29*bc068586SAdrian Prantl #include "llvm/Object/COFF.h" 30*bc068586SAdrian Prantl #include "llvm/Object/ObjectFile.h" 31*bc068586SAdrian Prantl #include "llvm/Support/TargetRegistry.h" 32*bc068586SAdrian Prantl #include <memory> 33*bc068586SAdrian Prantl using namespace clang; 34*bc068586SAdrian Prantl 35*bc068586SAdrian Prantl #define DEBUG_TYPE "pchcontainer" 36*bc068586SAdrian Prantl 37*bc068586SAdrian Prantl namespace { 38*bc068586SAdrian Prantl class ModuleContainerGenerator : public ASTConsumer { 39*bc068586SAdrian Prantl DiagnosticsEngine &Diags; 40*bc068586SAdrian Prantl const std::string MainFileName; 41*bc068586SAdrian Prantl ASTContext *Ctx; 42*bc068586SAdrian Prantl const HeaderSearchOptions &HeaderSearchOpts; 43*bc068586SAdrian Prantl const PreprocessorOptions &PreprocessorOpts; 44*bc068586SAdrian Prantl CodeGenOptions CodeGenOpts; 45*bc068586SAdrian Prantl const TargetOptions TargetOpts; 46*bc068586SAdrian Prantl const LangOptions LangOpts; 47*bc068586SAdrian Prantl std::unique_ptr<llvm::LLVMContext> VMContext; 48*bc068586SAdrian Prantl std::unique_ptr<llvm::Module> M; 49*bc068586SAdrian Prantl std::unique_ptr<CodeGen::CodeGenModule> Builder; 50*bc068586SAdrian Prantl raw_pwrite_stream *OS; 51*bc068586SAdrian Prantl std::shared_ptr<PCHBuffer> Buffer; 52*bc068586SAdrian Prantl 53*bc068586SAdrian Prantl public: 54*bc068586SAdrian Prantl ModuleContainerGenerator( 55*bc068586SAdrian Prantl DiagnosticsEngine &diags, 56*bc068586SAdrian Prantl const HeaderSearchOptions &HSO, const PreprocessorOptions &PPO, 57*bc068586SAdrian Prantl const TargetOptions &TO, const LangOptions &LO, 58*bc068586SAdrian Prantl const std::string &MainFileName, const std::string &OutputFileName, 59*bc068586SAdrian Prantl raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) 60*bc068586SAdrian Prantl : Diags(diags), HeaderSearchOpts(HSO), PreprocessorOpts(PPO), 61*bc068586SAdrian Prantl TargetOpts(TO), LangOpts(LO), OS(OS), 62*bc068586SAdrian Prantl Buffer(Buffer) { 63*bc068586SAdrian Prantl // The debug info output isn't affected by CodeModel and 64*bc068586SAdrian Prantl // ThreadModel, but the backend expects them to be nonempty. 65*bc068586SAdrian Prantl CodeGenOpts.CodeModel = "default"; 66*bc068586SAdrian Prantl CodeGenOpts.ThreadModel = "single"; 67*bc068586SAdrian Prantl CodeGenOpts.setDebugInfo(CodeGenOptions::FullDebugInfo); 68*bc068586SAdrian Prantl CodeGenOpts.SplitDwarfFile = OutputFileName; 69*bc068586SAdrian Prantl } 70*bc068586SAdrian Prantl 71*bc068586SAdrian Prantl virtual ~ModuleContainerGenerator() {} 72*bc068586SAdrian Prantl 73*bc068586SAdrian Prantl void Initialize(ASTContext &Context) override { 74*bc068586SAdrian Prantl Ctx = &Context; 75*bc068586SAdrian Prantl VMContext.reset(new llvm::LLVMContext()); 76*bc068586SAdrian Prantl M.reset(new llvm::Module(MainFileName, *VMContext)); 77*bc068586SAdrian Prantl M->setDataLayout(Ctx->getTargetInfo().getTargetDescription()); 78*bc068586SAdrian Prantl Builder.reset(new CodeGen::CodeGenModule(*Ctx, HeaderSearchOpts, 79*bc068586SAdrian Prantl PreprocessorOpts, CodeGenOpts, 80*bc068586SAdrian Prantl *M, M->getDataLayout(), Diags)); 81*bc068586SAdrian Prantl } 82*bc068586SAdrian Prantl 83*bc068586SAdrian Prantl /// Emit a container holding the serialized AST. 84*bc068586SAdrian Prantl void HandleTranslationUnit(ASTContext &Ctx) override { 85*bc068586SAdrian Prantl assert(M && VMContext && Builder); 86*bc068586SAdrian Prantl // Delete these on function exit. 87*bc068586SAdrian Prantl std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext); 88*bc068586SAdrian Prantl std::unique_ptr<llvm::Module> M = std::move(this->M); 89*bc068586SAdrian Prantl std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder); 90*bc068586SAdrian Prantl 91*bc068586SAdrian Prantl if (Diags.hasErrorOccurred()) 92*bc068586SAdrian Prantl return; 93*bc068586SAdrian Prantl 94*bc068586SAdrian Prantl M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple()); 95*bc068586SAdrian Prantl M->setDataLayout(Ctx.getTargetInfo().getTargetDescription()); 96*bc068586SAdrian Prantl 97*bc068586SAdrian Prantl // Finalize the Builder. 98*bc068586SAdrian Prantl if (Builder) 99*bc068586SAdrian Prantl Builder->Release(); 100*bc068586SAdrian Prantl 101*bc068586SAdrian Prantl // Ensure the target exists. 102*bc068586SAdrian Prantl std::string Error; 103*bc068586SAdrian Prantl auto Triple = Ctx.getTargetInfo().getTriple(); 104*bc068586SAdrian Prantl if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error)) 105*bc068586SAdrian Prantl llvm::report_fatal_error(Error); 106*bc068586SAdrian Prantl 107*bc068586SAdrian Prantl // Emit the serialized Clang AST into its own section. 108*bc068586SAdrian Prantl assert(Buffer->IsComplete && "serialization did not complete"); 109*bc068586SAdrian Prantl auto &SerializedAST = Buffer->Data; 110*bc068586SAdrian Prantl auto Size = SerializedAST.size(); 111*bc068586SAdrian Prantl auto Int8Ty = llvm::Type::getInt8Ty(*VMContext); 112*bc068586SAdrian Prantl auto *Ty = llvm::ArrayType::get(Int8Ty, Size); 113*bc068586SAdrian Prantl auto *Data = llvm::ConstantDataArray:: 114*bc068586SAdrian Prantl getString(*VMContext, StringRef(SerializedAST.data(), Size), 115*bc068586SAdrian Prantl /*AddNull=*/false); 116*bc068586SAdrian Prantl auto *ASTSym = new llvm::GlobalVariable( 117*bc068586SAdrian Prantl *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data, 118*bc068586SAdrian Prantl "__clang_ast"); 119*bc068586SAdrian Prantl // The on-disk hashtable needs to be aligned. 120*bc068586SAdrian Prantl ASTSym->setAlignment(8); 121*bc068586SAdrian Prantl 122*bc068586SAdrian Prantl // Mach-O also needs a segment name. 123*bc068586SAdrian Prantl if (Triple.isOSBinFormatMachO()) 124*bc068586SAdrian Prantl ASTSym->setSection("__CLANG,__clangast"); 125*bc068586SAdrian Prantl // COFF has an eight character length limit. 126*bc068586SAdrian Prantl else if (Triple.isOSBinFormatCOFF()) 127*bc068586SAdrian Prantl ASTSym->setSection("clangast"); 128*bc068586SAdrian Prantl else 129*bc068586SAdrian Prantl ASTSym->setSection("__clangast"); 130*bc068586SAdrian Prantl 131*bc068586SAdrian Prantl DEBUG({ 132*bc068586SAdrian Prantl // Print the IR for the PCH container to the debug output. 133*bc068586SAdrian Prantl llvm::SmallString<0> Buffer; 134*bc068586SAdrian Prantl llvm::raw_svector_ostream OS(Buffer); 135*bc068586SAdrian Prantl clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, 136*bc068586SAdrian Prantl Ctx.getTargetInfo().getTargetDescription(), 137*bc068586SAdrian Prantl M.get(), BackendAction::Backend_EmitLL, &OS); 138*bc068586SAdrian Prantl OS.flush(); 139*bc068586SAdrian Prantl llvm::dbgs()<<Buffer; 140*bc068586SAdrian Prantl }); 141*bc068586SAdrian Prantl 142*bc068586SAdrian Prantl // Use the LLVM backend to emit the pch container. 143*bc068586SAdrian Prantl clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts, 144*bc068586SAdrian Prantl Ctx.getTargetInfo().getTargetDescription(), 145*bc068586SAdrian Prantl M.get(), BackendAction::Backend_EmitObj, OS); 146*bc068586SAdrian Prantl 147*bc068586SAdrian Prantl // Make sure the pch container hits disk. 148*bc068586SAdrian Prantl OS->flush(); 149*bc068586SAdrian Prantl 150*bc068586SAdrian Prantl // Free the memory for the temporary buffer. 151*bc068586SAdrian Prantl llvm::SmallVector<char, 0> Empty; 152*bc068586SAdrian Prantl SerializedAST = std::move(Empty); 153*bc068586SAdrian Prantl } 154*bc068586SAdrian Prantl }; 155*bc068586SAdrian Prantl } 156*bc068586SAdrian Prantl 157*bc068586SAdrian Prantl std::unique_ptr<ASTConsumer> 158*bc068586SAdrian Prantl ObjectFilePCHContainerOperations::CreatePCHContainerGenerator( 159*bc068586SAdrian Prantl DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO, 160*bc068586SAdrian Prantl const PreprocessorOptions &PPO, const TargetOptions &TO, 161*bc068586SAdrian Prantl const LangOptions &LO, const std::string &MainFileName, 162*bc068586SAdrian Prantl const std::string &OutputFileName, llvm::raw_pwrite_stream *OS, 163*bc068586SAdrian Prantl std::shared_ptr<PCHBuffer> Buffer) const { 164*bc068586SAdrian Prantl return llvm::make_unique<ModuleContainerGenerator> 165*bc068586SAdrian Prantl (Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer); 166*bc068586SAdrian Prantl } 167*bc068586SAdrian Prantl 168*bc068586SAdrian Prantl void ObjectFilePCHContainerOperations::ExtractPCH( 169*bc068586SAdrian Prantl llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const { 170*bc068586SAdrian Prantl if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) { 171*bc068586SAdrian Prantl auto *Obj = OF.get().get(); 172*bc068586SAdrian Prantl bool IsCOFF = isa<llvm::object::COFFObjectFile>(Obj); 173*bc068586SAdrian Prantl // Find the clang AST section in the container. 174*bc068586SAdrian Prantl for (auto &Section : OF->get()->sections()) { 175*bc068586SAdrian Prantl StringRef Name; 176*bc068586SAdrian Prantl Section.getName(Name); 177*bc068586SAdrian Prantl if ((!IsCOFF && Name == "__clangast") || 178*bc068586SAdrian Prantl ( IsCOFF && Name == "clangast")) { 179*bc068586SAdrian Prantl StringRef Buf; 180*bc068586SAdrian Prantl Section.getContents(Buf); 181*bc068586SAdrian Prantl StreamFile.init((const unsigned char *)Buf.begin(), 182*bc068586SAdrian Prantl (const unsigned char *)Buf.end()); 183*bc068586SAdrian Prantl return; 184*bc068586SAdrian Prantl } 185*bc068586SAdrian Prantl } 186*bc068586SAdrian Prantl } 187*bc068586SAdrian Prantl 188*bc068586SAdrian Prantl // As a fallback, treat the buffer as a raw AST. 189*bc068586SAdrian Prantl StreamFile.init((const unsigned char *)Buffer.getBufferStart(), 190*bc068586SAdrian Prantl (const unsigned char *)Buffer.getBufferEnd()); 191*bc068586SAdrian Prantl return; 192*bc068586SAdrian Prantl } 193