clang  10.0.0svn
ObjectFilePCHContainerOperations.cpp
Go to the documentation of this file.
1 //===--- ObjectFilePCHContainerOperations.cpp -----------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
10 #include "CGDebugInfo.h"
11 #include "CodeGenModule.h"
12 #include "clang/AST/ASTContext.h"
13 #include "clang/AST/DeclObjC.h"
14 #include "clang/AST/Expr.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Lex/HeaderSearch.h"
22 #include "clang/Lex/Preprocessor.h"
23 #include "llvm/ADT/StringRef.h"
24 #include "llvm/Bitstream/BitstreamReader.h"
25 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
26 #include "llvm/IR/Constants.h"
27 #include "llvm/IR/DataLayout.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/Object/COFF.h"
31 #include "llvm/Object/ObjectFile.h"
32 #include "llvm/Support/Path.h"
33 #include "llvm/Support/TargetRegistry.h"
34 #include <memory>
35 #include <utility>
36 
37 using namespace clang;
38 
39 #define DEBUG_TYPE "pchcontainer"
40 
41 namespace {
42 class PCHContainerGenerator : public ASTConsumer {
43  DiagnosticsEngine &Diags;
44  const std::string MainFileName;
45  const std::string OutputFileName;
46  ASTContext *Ctx;
47  ModuleMap &MMap;
48  const HeaderSearchOptions &HeaderSearchOpts;
49  const PreprocessorOptions &PreprocessorOpts;
50  CodeGenOptions CodeGenOpts;
51  const TargetOptions TargetOpts;
52  const LangOptions LangOpts;
53  std::unique_ptr<llvm::LLVMContext> VMContext;
54  std::unique_ptr<llvm::Module> M;
55  std::unique_ptr<CodeGen::CodeGenModule> Builder;
56  std::unique_ptr<raw_pwrite_stream> OS;
57  std::shared_ptr<PCHBuffer> Buffer;
58 
59  /// Visit every type and emit debug info for it.
60  struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> {
62  ASTContext &Ctx;
63  DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx)
64  : DI(DI), Ctx(Ctx) {}
65 
66  /// Determine whether this type can be represented in DWARF.
67  static bool CanRepresent(const Type *Ty) {
68  return !Ty->isDependentType() && !Ty->isUndeducedType();
69  }
70 
71  bool VisitImportDecl(ImportDecl *D) {
72  if (!D->getImportedOwningModule())
73  DI.EmitImportDecl(*D);
74  return true;
75  }
76 
77  bool VisitTypeDecl(TypeDecl *D) {
78  // TagDecls may be deferred until after all decls have been merged and we
79  // know the complete type. Pure forward declarations will be skipped, but
80  // they don't need to be emitted into the module anyway.
81  if (auto *TD = dyn_cast<TagDecl>(D))
82  if (!TD->isCompleteDefinition())
83  return true;
84 
85  QualType QualTy = Ctx.getTypeDeclType(D);
86  if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
87  DI.getOrCreateStandaloneType(QualTy, D->getLocation());
88  return true;
89  }
90 
91  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
92  QualType QualTy(D->getTypeForDecl(), 0);
93  if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
94  DI.getOrCreateStandaloneType(QualTy, D->getLocation());
95  return true;
96  }
97 
98  bool VisitFunctionDecl(FunctionDecl *D) {
99  if (isa<CXXMethodDecl>(D))
100  // This is not yet supported. Constructing the `this' argument
101  // mandates a CodeGenFunction.
102  return true;
103 
104  SmallVector<QualType, 16> ArgTypes;
105  for (auto i : D->parameters())
106  ArgTypes.push_back(i->getType());
107  QualType RetTy = D->getReturnType();
108  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
110  if (CanRepresent(FnTy.getTypePtr()))
111  DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
112  return true;
113  }
114 
115  bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
116  if (!D->getClassInterface())
117  return true;
118 
119  bool selfIsPseudoStrong, selfIsConsumed;
120  SmallVector<QualType, 16> ArgTypes;
121  ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(),
122  selfIsPseudoStrong, selfIsConsumed));
123  ArgTypes.push_back(Ctx.getObjCSelType());
124  for (auto i : D->parameters())
125  ArgTypes.push_back(i->getType());
126  QualType RetTy = D->getReturnType();
127  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
129  if (CanRepresent(FnTy.getTypePtr()))
130  DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
131  return true;
132  }
133  };
134 
135 public:
136  PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName,
137  const std::string &OutputFileName,
138  std::unique_ptr<raw_pwrite_stream> OS,
139  std::shared_ptr<PCHBuffer> Buffer)
140  : Diags(CI.getDiagnostics()), MainFileName(MainFileName),
141  OutputFileName(OutputFileName), Ctx(nullptr),
143  HeaderSearchOpts(CI.getHeaderSearchOpts()),
144  PreprocessorOpts(CI.getPreprocessorOpts()),
145  TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
146  OS(std::move(OS)), Buffer(std::move(Buffer)) {
147  // The debug info output isn't affected by CodeModel and
148  // ThreadModel, but the backend expects them to be nonempty.
149  CodeGenOpts.CodeModel = "default";
150  CodeGenOpts.ThreadModel = "single";
151  CodeGenOpts.DebugTypeExtRefs = true;
152  // When building a module MainFileName is the name of the modulemap file.
153  CodeGenOpts.MainFileName =
154  LangOpts.CurrentModule.empty() ? MainFileName : LangOpts.CurrentModule;
155  CodeGenOpts.setDebugInfo(codegenoptions::FullDebugInfo);
156  CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning());
157  CodeGenOpts.DebugPrefixMap =
159  }
160 
161  ~PCHContainerGenerator() override = default;
162 
163  void Initialize(ASTContext &Context) override {
164  assert(!Ctx && "initialized multiple times");
165 
166  Ctx = &Context;
167  VMContext.reset(new llvm::LLVMContext());
168  M.reset(new llvm::Module(MainFileName, *VMContext));
169  M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
170  Builder.reset(new CodeGen::CodeGenModule(
171  *Ctx, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags));
172 
173  // Prepare CGDebugInfo to emit debug info for a clang module.
174  auto *DI = Builder->getModuleDebugInfo();
175  StringRef ModuleName = llvm::sys::path::filename(MainFileName);
176  DI->setPCHDescriptor({ModuleName, "", OutputFileName,
177  ASTFileSignature{{{~0U, ~0U, ~0U, ~0U, ~1U}}}});
178  DI->setModuleMap(MMap);
179  }
180 
181  bool HandleTopLevelDecl(DeclGroupRef D) override {
182  if (Diags.hasErrorOccurred())
183  return true;
184 
185  // Collect debug info for all decls in this group.
186  for (auto *I : D)
187  if (!I->isFromASTFile()) {
188  DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
189  DTV.TraverseDecl(I);
190  }
191  return true;
192  }
193 
194  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
195  HandleTopLevelDecl(D);
196  }
197 
198  void HandleTagDeclDefinition(TagDecl *D) override {
199  if (Diags.hasErrorOccurred())
200  return;
201 
202  if (D->isFromASTFile())
203  return;
204 
205  // Anonymous tag decls are deferred until we are building their declcontext.
206  if (D->getName().empty())
207  return;
208 
209  // Defer tag decls until their declcontext is complete.
210  auto *DeclCtx = D->getDeclContext();
211  while (DeclCtx) {
212  if (auto *D = dyn_cast<TagDecl>(DeclCtx))
213  if (!D->isCompleteDefinition())
214  return;
215  DeclCtx = DeclCtx->getParent();
216  }
217 
218  DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
219  DTV.TraverseDecl(D);
220  Builder->UpdateCompletedType(D);
221  }
222 
223  void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
224  if (Diags.hasErrorOccurred())
225  return;
226 
227  if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
228  Builder->getModuleDebugInfo()->completeRequiredType(RD);
229  }
230 
231  void HandleImplicitImportDecl(ImportDecl *D) override {
232  if (!D->getImportedOwningModule())
233  Builder->getModuleDebugInfo()->EmitImportDecl(*D);
234  }
235 
236  /// Emit a container holding the serialized AST.
237  void HandleTranslationUnit(ASTContext &Ctx) override {
238  assert(M && VMContext && Builder);
239  // Delete these on function exit.
240  std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
241  std::unique_ptr<llvm::Module> M = std::move(this->M);
242  std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder);
243 
244  if (Diags.hasErrorOccurred())
245  return;
246 
247  M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple());
248  M->setDataLayout(Ctx.getTargetInfo().getDataLayout());
249 
250  // PCH files don't have a signature field in the control block,
251  // but LLVM detects DWO CUs by looking for a non-zero DWO id.
252  // We use the lower 64 bits for debug info.
253  uint64_t Signature =
254  Buffer->Signature
255  ? (uint64_t)Buffer->Signature[1] << 32 | Buffer->Signature[0]
256  : ~1ULL;
257  Builder->getModuleDebugInfo()->setDwoId(Signature);
258 
259  // Finalize the Builder.
260  if (Builder)
261  Builder->Release();
262 
263  // Ensure the target exists.
264  std::string Error;
265  auto Triple = Ctx.getTargetInfo().getTriple();
266  if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error))
267  llvm::report_fatal_error(Error);
268 
269  // Emit the serialized Clang AST into its own section.
270  assert(Buffer->IsComplete && "serialization did not complete");
271  auto &SerializedAST = Buffer->Data;
272  auto Size = SerializedAST.size();
273  auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
274  auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
275  auto *Data = llvm::ConstantDataArray::getString(
276  *VMContext, StringRef(SerializedAST.data(), Size),
277  /*AddNull=*/false);
278  auto *ASTSym = new llvm::GlobalVariable(
279  *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
280  "__clang_ast");
281  // The on-disk hashtable needs to be aligned.
282  ASTSym->setAlignment(llvm::Align(8));
283 
284  // Mach-O also needs a segment name.
285  if (Triple.isOSBinFormatMachO())
286  ASTSym->setSection("__CLANG,__clangast");
287  // COFF has an eight character length limit.
288  else if (Triple.isOSBinFormatCOFF())
289  ASTSym->setSection("clangast");
290  else
291  ASTSym->setSection("__clangast");
292 
293  LLVM_DEBUG({
294  // Print the IR for the PCH container to the debug output.
295  llvm::SmallString<0> Buffer;
297  Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
298  Ctx.getTargetInfo().getDataLayout(), M.get(),
300  std::make_unique<llvm::raw_svector_ostream>(Buffer));
301  llvm::dbgs() << Buffer;
302  });
303 
304  // Use the LLVM backend to emit the pch container.
305  clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
306  LangOpts, Ctx.getTargetInfo().getDataLayout(),
308  std::move(OS));
309 
310  // Free the memory for the temporary buffer.
312  SerializedAST = std::move(Empty);
313  }
314 };
315 
316 } // anonymous namespace
317 
318 std::unique_ptr<ASTConsumer>
319 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
320  CompilerInstance &CI, const std::string &MainFileName,
321  const std::string &OutputFileName,
322  std::unique_ptr<llvm::raw_pwrite_stream> OS,
323  std::shared_ptr<PCHBuffer> Buffer) const {
324  return std::make_unique<PCHContainerGenerator>(
325  CI, MainFileName, OutputFileName, std::move(OS), Buffer);
326 }
327 
328 StringRef
329 ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const {
330  StringRef PCH;
331  auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer);
332  if (OFOrErr) {
333  auto &OF = OFOrErr.get();
334  bool IsCOFF = isa<llvm::object::COFFObjectFile>(*OF);
335  // Find the clang AST section in the container.
336  for (auto &Section : OF->sections()) {
337  StringRef Name;
338  if (Expected<StringRef> NameOrErr = Section.getName())
339  Name = *NameOrErr;
340  else
341  consumeError(NameOrErr.takeError());
342 
343  if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) {
344  if (Expected<StringRef> E = Section.getContents())
345  return *E;
346  else {
347  handleAllErrors(E.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
348  EIB.log(llvm::errs());
349  });
350  return "";
351  }
352  }
353  }
354  }
355  handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
356  if (EIB.convertToErrorCode() ==
357  llvm::object::object_error::invalid_file_type)
358  // As a fallback, treat the buffer as a raw AST.
359  PCH = Buffer.getBuffer();
360  else
361  EIB.log(llvm::errs());
362  });
363  return PCH;
364 }
Defines the clang::ASTContext interface.
LangOptions & getLangOpts()
const Type * getTypeForDecl() const
Definition: DeclObjC.h:1918
Represents a function declaration or definition.
Definition: Decl.h:1784
CompilerInvocation & getInvocation()
PreprocessorOptions & getPreprocessorOpts()
bool hasErrorOccurred() const
Definition: Diagnostic.h:747
A (possibly-)qualified type.
Definition: Type.h:643
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1143
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:33
Emit human-readable LLVM assembly.
Definition: BackendUtil.h:33
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:991
The base class of the type hierarchy.
Definition: Type.h:1436
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:706
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3238
QualType getReturnType() const
Definition: Decl.h:2365
Options for controlling the target.
Definition: TargetOptions.h:26
Extra information about a function prototype.
Definition: Type.h:3805
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
Definition: CGDebugInfo.h:54
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:138
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:652
Represents a struct/union/class.
Definition: Decl.h:3662
std::map< std::string, std::string > DebugPrefixMap
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
void EmitImportDecl(const ImportDecl &ID)
Emit an declaration.
CodeGenOptions & getCodeGenOpts()
The signature of a module, which is a hash of the AST content.
Definition: Module.h:54
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:49
std::string CodeModel
The code model to use (-mcmodel).
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2325
CodeGenOptions & getCodeGenOpts()
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:909
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
Represents a declaration of a type.
Definition: Decl.h:2943
Defines the Diagnostic-related interfaces.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6148
HeaderSearchOptions & getHeaderSearchOpts()
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Represents an ObjC class declaration.
Definition: DeclObjC.h:1171
QualType getReturnType() const
Definition: DeclObjC.h:322
std::string ThreadModel
The thread model to use.
std::string CurrentModule
The name of the current module, of which the main source file is a part.
Definition: LangOptions.h:243
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition: DeclBase.h:729
Defines the clang::Preprocessor interface.
DeclContext * getDeclContext()
Definition: DeclBase.h:438
Emit native object files.
Definition: BackendUtil.h:36
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1779
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1387
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1403
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:708
QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID, bool &selfIsPseudoStrong, bool &selfIsConsumed)
Definition: DeclObjC.cpp:1077
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Limit generated debug info to reduce size (-fno-standalone-debug).
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3133
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C &#39;SEL&#39; type.
Definition: ASTContext.h:1868
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType, llvm::Function *Fn=nullptr)
Emit debug info for a function declaration.
const llvm::DataLayout & getDataLayout() const
Definition: TargetInfo.h:995
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
Definition: DeclBase.h:702
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:4245
This class organizes the cross-function state that is used while generating LLVM code.
Dataflow Directional Tag Classes.
void EmitBackendOutput(DiagnosticsEngine &Diags, const HeaderSearchOptions &, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, const llvm::DataLayout &TDesc, llvm::Module *M, BackendAction Action, std::unique_ptr< raw_pwrite_stream > OS)
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 &#39;auto&#39; typ...
Definition: Type.h:6773
llvm::DIType * getOrCreateStandaloneType(QualType Ty, SourceLocation Loc)
Emit standalone debug info for a type.
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition: Linkage.h:31
Preprocessor & getPreprocessor() const
Return the current preprocessor.
std::string MainFileName
The user provided name for the "main file", if non-empty.
Defines the clang::TargetInfo interface.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:275
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2121
TargetOptions & getTargetOpts()
SourceLocation getLocation() const
Definition: DeclBase.h:429
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:366