]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / CodeGen / ObjectFilePCHContainerOperations.cpp
1 //===--- ObjectFilePCHContainerOperations.cpp -----------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h"
11 #include "CGDebugInfo.h"
12 #include "CodeGenModule.h"
13 #include "clang/AST/ASTContext.h"
14 #include "clang/AST/DeclObjC.h"
15 #include "clang/AST/Expr.h"
16 #include "clang/AST/RecursiveASTVisitor.h"
17 #include "clang/Basic/CodeGenOptions.h"
18 #include "clang/Basic/Diagnostic.h"
19 #include "clang/Basic/TargetInfo.h"
20 #include "clang/CodeGen/BackendUtil.h"
21 #include "clang/Frontend/CompilerInstance.h"
22 #include "clang/Lex/HeaderSearch.h"
23 #include "clang/Lex/Preprocessor.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/Bitcode/BitstreamReader.h"
26 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DataLayout.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/Object/COFF.h"
32 #include "llvm/Object/ObjectFile.h"
33 #include "llvm/Support/Path.h"
34 #include "llvm/Support/TargetRegistry.h"
35 #include <memory>
36 #include <utility>
37
38 using namespace clang;
39
40 #define DEBUG_TYPE "pchcontainer"
41
42 namespace {
43 class PCHContainerGenerator : public ASTConsumer {
44   DiagnosticsEngine &Diags;
45   const std::string MainFileName;
46   const std::string OutputFileName;
47   ASTContext *Ctx;
48   ModuleMap &MMap;
49   const HeaderSearchOptions &HeaderSearchOpts;
50   const PreprocessorOptions &PreprocessorOpts;
51   CodeGenOptions CodeGenOpts;
52   const TargetOptions TargetOpts;
53   const LangOptions LangOpts;
54   std::unique_ptr<llvm::LLVMContext> VMContext;
55   std::unique_ptr<llvm::Module> M;
56   std::unique_ptr<CodeGen::CodeGenModule> Builder;
57   std::unique_ptr<raw_pwrite_stream> OS;
58   std::shared_ptr<PCHBuffer> Buffer;
59
60   /// Visit every type and emit debug info for it.
61   struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> {
62     clang::CodeGen::CGDebugInfo &DI;
63     ASTContext &Ctx;
64     DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx)
65         : DI(DI), Ctx(Ctx) {}
66
67     /// Determine whether this type can be represented in DWARF.
68     static bool CanRepresent(const Type *Ty) {
69       return !Ty->isDependentType() && !Ty->isUndeducedType();
70     }
71
72     bool VisitImportDecl(ImportDecl *D) {
73       if (!D->getImportedOwningModule())
74         DI.EmitImportDecl(*D);
75       return true;
76     }
77
78     bool VisitTypeDecl(TypeDecl *D) {
79       // TagDecls may be deferred until after all decls have been merged and we
80       // know the complete type. Pure forward declarations will be skipped, but
81       // they don't need to be emitted into the module anyway.
82       if (auto *TD = dyn_cast<TagDecl>(D))
83         if (!TD->isCompleteDefinition())
84           return true;
85
86       QualType QualTy = Ctx.getTypeDeclType(D);
87       if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
88         DI.getOrCreateStandaloneType(QualTy, D->getLocation());
89       return true;
90     }
91
92     bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
93       QualType QualTy(D->getTypeForDecl(), 0);
94       if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
95         DI.getOrCreateStandaloneType(QualTy, D->getLocation());
96       return true;
97     }
98
99     bool VisitFunctionDecl(FunctionDecl *D) {
100       if (isa<CXXMethodDecl>(D))
101         // This is not yet supported. Constructing the `this' argument
102         // mandates a CodeGenFunction.
103         return true;
104
105       SmallVector<QualType, 16> ArgTypes;
106       for (auto i : D->parameters())
107         ArgTypes.push_back(i->getType());
108       QualType RetTy = D->getReturnType();
109       QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
110                                           FunctionProtoType::ExtProtoInfo());
111       if (CanRepresent(FnTy.getTypePtr()))
112         DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
113       return true;
114     }
115
116     bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
117       if (!D->getClassInterface())
118         return true;
119
120       bool selfIsPseudoStrong, selfIsConsumed;
121       SmallVector<QualType, 16> ArgTypes;
122       ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(),
123                                         selfIsPseudoStrong, selfIsConsumed));
124       ArgTypes.push_back(Ctx.getObjCSelType());
125       for (auto i : D->parameters())
126         ArgTypes.push_back(i->getType());
127       QualType RetTy = D->getReturnType();
128       QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
129                                           FunctionProtoType::ExtProtoInfo());
130       if (CanRepresent(FnTy.getTypePtr()))
131         DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
132       return true;
133     }
134   };
135
136 public:
137   PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName,
138                         const std::string &OutputFileName,
139                         std::unique_ptr<raw_pwrite_stream> OS,
140                         std::shared_ptr<PCHBuffer> Buffer)
141       : Diags(CI.getDiagnostics()), MainFileName(MainFileName),
142         OutputFileName(OutputFileName), Ctx(nullptr),
143         MMap(CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()),
144         HeaderSearchOpts(CI.getHeaderSearchOpts()),
145         PreprocessorOpts(CI.getPreprocessorOpts()),
146         TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
147         OS(std::move(OS)), Buffer(std::move(Buffer)) {
148     // The debug info output isn't affected by CodeModel and
149     // ThreadModel, but the backend expects them to be nonempty.
150     CodeGenOpts.CodeModel = "default";
151     CodeGenOpts.ThreadModel = "single";
152     CodeGenOpts.DebugTypeExtRefs = true;
153     // When building a module MainFileName is the name of the modulemap file.
154     CodeGenOpts.MainFileName =
155         LangOpts.CurrentModule.empty() ? MainFileName : LangOpts.CurrentModule;
156     CodeGenOpts.setDebugInfo(codegenoptions::FullDebugInfo);
157     CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning());
158     CodeGenOpts.DebugPrefixMap =
159         CI.getInvocation().getCodeGenOpts().DebugPrefixMap;
160   }
161
162   ~PCHContainerGenerator() override = default;
163
164   void Initialize(ASTContext &Context) override {
165     assert(!Ctx && "initialized multiple times");
166
167     Ctx = &Context;
168     VMContext.reset(new llvm::LLVMContext());
169     M.reset(new llvm::Module(MainFileName, *VMContext));
170     M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
171     Builder.reset(new CodeGen::CodeGenModule(
172         *Ctx, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags));
173
174     // Prepare CGDebugInfo to emit debug info for a clang module.
175     auto *DI = Builder->getModuleDebugInfo();
176     StringRef ModuleName = llvm::sys::path::filename(MainFileName);
177     DI->setPCHDescriptor({ModuleName, "", OutputFileName,
178                           ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U}}}});
179     DI->setModuleMap(MMap);
180   }
181
182   bool HandleTopLevelDecl(DeclGroupRef D) override {
183     if (Diags.hasErrorOccurred())
184       return true;
185
186     // Collect debug info for all decls in this group.
187     for (auto *I : D)
188       if (!I->isFromASTFile()) {
189         DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
190         DTV.TraverseDecl(I);
191       }
192     return true;
193   }
194
195   void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
196     HandleTopLevelDecl(D);
197   }
198
199   void HandleTagDeclDefinition(TagDecl *D) override {
200     if (Diags.hasErrorOccurred())
201       return;
202
203     if (D->isFromASTFile())
204       return;
205
206     // Anonymous tag decls are deferred until we are building their declcontext.
207     if (D->getName().empty())
208       return;
209
210     // Defer tag decls until their declcontext is complete.
211     auto *DeclCtx = D->getDeclContext();
212     while (DeclCtx) {
213       if (auto *D = dyn_cast<TagDecl>(DeclCtx))
214         if (!D->isCompleteDefinition())
215           return;
216       DeclCtx = DeclCtx->getParent();
217     }
218
219     DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
220     DTV.TraverseDecl(D);
221     Builder->UpdateCompletedType(D);
222   }
223
224   void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
225     if (Diags.hasErrorOccurred())
226       return;
227
228     if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
229       Builder->getModuleDebugInfo()->completeRequiredType(RD);
230   }
231
232   void HandleImplicitImportDecl(ImportDecl *D) override {
233     if (!D->getImportedOwningModule())
234       Builder->getModuleDebugInfo()->EmitImportDecl(*D);
235   }
236
237   /// Emit a container holding the serialized AST.
238   void HandleTranslationUnit(ASTContext &Ctx) override {
239     assert(M && VMContext && Builder);
240     // Delete these on function exit.
241     std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
242     std::unique_ptr<llvm::Module> M = std::move(this->M);
243     std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder);
244
245     if (Diags.hasErrorOccurred())
246       return;
247
248     M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple());
249     M->setDataLayout(Ctx.getTargetInfo().getDataLayout());
250
251     // PCH files don't have a signature field in the control block,
252     // but LLVM detects DWO CUs by looking for a non-zero DWO id.
253     // We use the lower 64 bits for debug info.
254     uint64_t Signature =
255         Buffer->Signature
256             ? (uint64_t)Buffer->Signature[1] << 32 | Buffer->Signature[0]
257             : ~1ULL;
258     Builder->getModuleDebugInfo()->setDwoId(Signature);
259
260     // Finalize the Builder.
261     if (Builder)
262       Builder->Release();
263
264     // Ensure the target exists.
265     std::string Error;
266     auto Triple = Ctx.getTargetInfo().getTriple();
267     if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error))
268       llvm::report_fatal_error(Error);
269
270     // Emit the serialized Clang AST into its own section.
271     assert(Buffer->IsComplete && "serialization did not complete");
272     auto &SerializedAST = Buffer->Data;
273     auto Size = SerializedAST.size();
274     auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
275     auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
276     auto *Data = llvm::ConstantDataArray::getString(
277         *VMContext, StringRef(SerializedAST.data(), Size),
278         /*AddNull=*/false);
279     auto *ASTSym = new llvm::GlobalVariable(
280         *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
281         "__clang_ast");
282     // The on-disk hashtable needs to be aligned.
283     ASTSym->setAlignment(8);
284
285     // Mach-O also needs a segment name.
286     if (Triple.isOSBinFormatMachO())
287       ASTSym->setSection("__CLANG,__clangast");
288     // COFF has an eight character length limit.
289     else if (Triple.isOSBinFormatCOFF())
290       ASTSym->setSection("clangast");
291     else
292       ASTSym->setSection("__clangast");
293
294     LLVM_DEBUG({
295       // Print the IR for the PCH container to the debug output.
296       llvm::SmallString<0> Buffer;
297       clang::EmitBackendOutput(
298           Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
299           Ctx.getTargetInfo().getDataLayout(), M.get(),
300           BackendAction::Backend_EmitLL,
301           llvm::make_unique<llvm::raw_svector_ostream>(Buffer));
302       llvm::dbgs() << Buffer;
303     });
304
305     // Use the LLVM backend to emit the pch container.
306     clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
307                              LangOpts, Ctx.getTargetInfo().getDataLayout(),
308                              M.get(), BackendAction::Backend_EmitObj,
309                              std::move(OS));
310
311     // Free the memory for the temporary buffer.
312     llvm::SmallVector<char, 0> Empty;
313     SerializedAST = std::move(Empty);
314   }
315 };
316
317 } // anonymous namespace
318
319 std::unique_ptr<ASTConsumer>
320 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
321     CompilerInstance &CI, const std::string &MainFileName,
322     const std::string &OutputFileName,
323     std::unique_ptr<llvm::raw_pwrite_stream> OS,
324     std::shared_ptr<PCHBuffer> Buffer) const {
325   return llvm::make_unique<PCHContainerGenerator>(
326       CI, MainFileName, OutputFileName, std::move(OS), Buffer);
327 }
328
329 StringRef
330 ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const {
331   StringRef PCH;
332   auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer);
333   if (OFOrErr) {
334     auto &OF = OFOrErr.get();
335     bool IsCOFF = isa<llvm::object::COFFObjectFile>(*OF);
336     // Find the clang AST section in the container.
337     for (auto &Section : OF->sections()) {
338       StringRef Name;
339       Section.getName(Name);
340       if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) {
341         Section.getContents(PCH);
342         return PCH;
343       }
344     }
345   }
346   handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
347     if (EIB.convertToErrorCode() ==
348         llvm::object::object_error::invalid_file_type)
349       // As a fallback, treat the buffer as a raw AST.
350       PCH = Buffer.getBuffer();
351     else
352       EIB.log(llvm::errs());
353   });
354   return PCH;
355 }