clang  8.0.0svn
ObjectFilePCHContainerOperations.cpp
Go to the documentation of this file.
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 
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"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/TargetInfo.h"
22 #include "clang/Lex/HeaderSearch.h"
23 #include "clang/Lex/Preprocessor.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/Bitcode/BitstreamReader.h"
27 #include "llvm/DebugInfo/DWARF/DWARFContext.h"
28 #include "llvm/IR/Constants.h"
29 #include "llvm/IR/DataLayout.h"
30 #include "llvm/IR/LLVMContext.h"
31 #include "llvm/IR/Module.h"
32 #include "llvm/Object/COFF.h"
33 #include "llvm/Object/ObjectFile.h"
34 #include "llvm/Support/Path.h"
35 #include "llvm/Support/TargetRegistry.h"
36 #include <memory>
37 #include <utility>
38 
39 using namespace clang;
40 
41 #define DEBUG_TYPE "pchcontainer"
42 
43 namespace {
44 class PCHContainerGenerator : public ASTConsumer {
45  DiagnosticsEngine &Diags;
46  const std::string MainFileName;
47  const std::string OutputFileName;
48  ASTContext *Ctx;
49  ModuleMap &MMap;
50  const HeaderSearchOptions &HeaderSearchOpts;
51  const PreprocessorOptions &PreprocessorOpts;
52  CodeGenOptions CodeGenOpts;
53  const TargetOptions TargetOpts;
54  const LangOptions LangOpts;
55  std::unique_ptr<llvm::LLVMContext> VMContext;
56  std::unique_ptr<llvm::Module> M;
57  std::unique_ptr<CodeGen::CodeGenModule> Builder;
58  std::unique_ptr<raw_pwrite_stream> OS;
59  std::shared_ptr<PCHBuffer> Buffer;
60 
61  /// Visit every type and emit debug info for it.
62  struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> {
64  ASTContext &Ctx;
65  DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx)
66  : DI(DI), Ctx(Ctx) {}
67 
68  /// Determine whether this type can be represented in DWARF.
69  static bool CanRepresent(const Type *Ty) {
70  return !Ty->isDependentType() && !Ty->isUndeducedType();
71  }
72 
73  bool VisitImportDecl(ImportDecl *D) {
74  if (!D->getImportedOwningModule())
75  DI.EmitImportDecl(*D);
76  return true;
77  }
78 
79  bool VisitTypeDecl(TypeDecl *D) {
80  // TagDecls may be deferred until after all decls have been merged and we
81  // know the complete type. Pure forward declarations will be skipped, but
82  // they don't need to be emitted into the module anyway.
83  if (auto *TD = dyn_cast<TagDecl>(D))
84  if (!TD->isCompleteDefinition())
85  return true;
86 
87  QualType QualTy = Ctx.getTypeDeclType(D);
88  if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
89  DI.getOrCreateStandaloneType(QualTy, D->getLocation());
90  return true;
91  }
92 
93  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
94  QualType QualTy(D->getTypeForDecl(), 0);
95  if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
96  DI.getOrCreateStandaloneType(QualTy, D->getLocation());
97  return true;
98  }
99 
100  bool VisitFunctionDecl(FunctionDecl *D) {
101  if (isa<CXXMethodDecl>(D))
102  // This is not yet supported. Constructing the `this' argument
103  // mandates a CodeGenFunction.
104  return true;
105 
106  SmallVector<QualType, 16> ArgTypes;
107  for (auto i : D->parameters())
108  ArgTypes.push_back(i->getType());
109  QualType RetTy = D->getReturnType();
110  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
112  if (CanRepresent(FnTy.getTypePtr()))
113  DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
114  return true;
115  }
116 
117  bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
118  if (!D->getClassInterface())
119  return true;
120 
121  bool selfIsPseudoStrong, selfIsConsumed;
122  SmallVector<QualType, 16> ArgTypes;
123  ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(),
124  selfIsPseudoStrong, selfIsConsumed));
125  ArgTypes.push_back(Ctx.getObjCSelType());
126  for (auto i : D->parameters())
127  ArgTypes.push_back(i->getType());
128  QualType RetTy = D->getReturnType();
129  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
131  if (CanRepresent(FnTy.getTypePtr()))
132  DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
133  return true;
134  }
135  };
136 
137 public:
138  PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName,
139  const std::string &OutputFileName,
140  std::unique_ptr<raw_pwrite_stream> OS,
141  std::shared_ptr<PCHBuffer> Buffer)
142  : Diags(CI.getDiagnostics()), MainFileName(MainFileName),
143  OutputFileName(OutputFileName), Ctx(nullptr),
145  HeaderSearchOpts(CI.getHeaderSearchOpts()),
146  PreprocessorOpts(CI.getPreprocessorOpts()),
147  TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
148  OS(std::move(OS)), Buffer(std::move(Buffer)) {
149  // The debug info output isn't affected by CodeModel and
150  // ThreadModel, but the backend expects them to be nonempty.
151  CodeGenOpts.CodeModel = "default";
152  CodeGenOpts.ThreadModel = "single";
153  CodeGenOpts.DebugTypeExtRefs = true;
154  // When building a module MainFileName is the name of the modulemap file.
155  CodeGenOpts.MainFileName =
156  LangOpts.CurrentModule.empty() ? MainFileName : LangOpts.CurrentModule;
157  CodeGenOpts.setDebugInfo(codegenoptions::FullDebugInfo);
158  CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning());
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(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  llvm::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 llvm::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  Section.getName(Name);
339  if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) {
340  Section.getContents(PCH);
341  return PCH;
342  }
343  }
344  }
345  handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
346  if (EIB.convertToErrorCode() ==
347  llvm::object::object_error::invalid_file_type)
348  // As a fallback, treat the buffer as a raw AST.
349  PCH = Buffer.getBuffer();
350  else
351  EIB.log(llvm::errs());
352  });
353  return PCH;
354 }
Defines the clang::ASTContext interface.
LangOptions & getLangOpts()
const Type * getTypeForDecl() const
Definition: DeclObjC.h:1911
Represents a function declaration or definition.
Definition: Decl.h:1717
PreprocessorOptions & getPreprocessorOpts()
bool hasErrorOccurred() const
Definition: Diagnostic.h:746
A (possibly-)qualified type.
Definition: Type.h:642
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1144
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:34
Emit human-readable LLVM assembly.
Definition: BackendUtil.h:34
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:949
The base class of the type hierarchy.
Definition: Type.h:1415
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:699
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:3146
QualType getReturnType() const
Definition: Decl.h:2271
Options for controlling the target.
Definition: TargetOptions.h:26
Extra information about a function prototype.
Definition: Type.h:3669
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:139
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:655
Represents a struct/union/class.
Definition: Decl.h:3570
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:154
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:55
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:50
std::string CodeModel
The code model to use (-mcmodel).
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2231
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:833
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:2851
Defines the Diagnostic-related interfaces.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5953
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:1164
QualType getReturnType() const
Definition: DeclObjC.h:323
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:194
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition: DeclBase.h:728
Defines the clang::Preprocessor interface.
DeclContext * getDeclContext()
Definition: DeclBase.h:427
Emit native object files.
Definition: BackendUtil.h:37
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1758
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:1386
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:1402
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:707
void EmitFunctionDecl(GlobalDecl GD, SourceLocation Loc, QualType FnType)
Emit debug info for a function declaration.
QualType getSelfType(ASTContext &Context, const ObjCInterfaceDecl *OID, bool &selfIsPseudoStrong, bool &selfIsConsumed)
Definition: DeclObjC.cpp:1078
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:3041
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C &#39;SEL&#39; type.
Definition: ASTContext.h:1865
const llvm::DataLayout & getDataLayout() const
Definition: TargetInfo.h:953
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
Definition: DeclBase.h:701
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:4118
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:6523
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:32
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:2056
TargetOptions & getTargetOpts()
SourceLocation getLocation() const
Definition: DeclBase.h:418
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:367