clang  6.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  auto *Import = cast<ImportDecl>(D);
75  if (!Import->getImportedOwningModule())
76  DI.EmitImportDecl(*Import);
77  return true;
78  }
79 
80  bool VisitTypeDecl(TypeDecl *D) {
81  // TagDecls may be deferred until after all decls have been merged and we
82  // know the complete type. Pure forward declarations will be skipped, but
83  // they don't need to be emitted into the module anyway.
84  if (auto *TD = dyn_cast<TagDecl>(D))
85  if (!TD->isCompleteDefinition())
86  return true;
87 
88  QualType QualTy = Ctx.getTypeDeclType(D);
89  if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
90  DI.getOrCreateStandaloneType(QualTy, D->getLocation());
91  return true;
92  }
93 
94  bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
95  QualType QualTy(D->getTypeForDecl(), 0);
96  if (!QualTy.isNull() && CanRepresent(QualTy.getTypePtr()))
97  DI.getOrCreateStandaloneType(QualTy, D->getLocation());
98  return true;
99  }
100 
101  bool VisitFunctionDecl(FunctionDecl *D) {
102  if (isa<CXXMethodDecl>(D))
103  // This is not yet supported. Constructing the `this' argument
104  // mandates a CodeGenFunction.
105  return true;
106 
107  SmallVector<QualType, 16> ArgTypes;
108  for (auto i : D->parameters())
109  ArgTypes.push_back(i->getType());
110  QualType RetTy = D->getReturnType();
111  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
113  if (CanRepresent(FnTy.getTypePtr()))
114  DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
115  return true;
116  }
117 
118  bool VisitObjCMethodDecl(ObjCMethodDecl *D) {
119  if (!D->getClassInterface())
120  return true;
121 
122  bool selfIsPseudoStrong, selfIsConsumed;
123  SmallVector<QualType, 16> ArgTypes;
124  ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(),
125  selfIsPseudoStrong, selfIsConsumed));
126  ArgTypes.push_back(Ctx.getObjCSelType());
127  for (auto i : D->parameters())
128  ArgTypes.push_back(i->getType());
129  QualType RetTy = D->getReturnType();
130  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
132  if (CanRepresent(FnTy.getTypePtr()))
133  DI.EmitFunctionDecl(D, D->getLocation(), FnTy);
134  return true;
135  }
136  };
137 
138 public:
139  PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName,
140  const std::string &OutputFileName,
141  std::unique_ptr<raw_pwrite_stream> OS,
142  std::shared_ptr<PCHBuffer> Buffer)
143  : Diags(CI.getDiagnostics()), MainFileName(MainFileName),
144  OutputFileName(OutputFileName), Ctx(nullptr),
146  HeaderSearchOpts(CI.getHeaderSearchOpts()),
147  PreprocessorOpts(CI.getPreprocessorOpts()),
148  TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()),
149  OS(std::move(OS)), Buffer(std::move(Buffer)) {
150  // The debug info output isn't affected by CodeModel and
151  // ThreadModel, but the backend expects them to be nonempty.
152  CodeGenOpts.CodeModel = "default";
153  CodeGenOpts.ThreadModel = "single";
154  CodeGenOpts.DebugTypeExtRefs = true;
155  // When building a module MainFileName is the name of the modulemap file.
156  CodeGenOpts.MainFileName =
157  LangOpts.CurrentModule.empty() ? MainFileName : LangOpts.CurrentModule;
158  CodeGenOpts.setDebugInfo(codegenoptions::FullDebugInfo);
159  CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning());
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  /// Emit a container holding the serialized AST.
233  void HandleTranslationUnit(ASTContext &Ctx) override {
234  assert(M && VMContext && Builder);
235  // Delete these on function exit.
236  std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
237  std::unique_ptr<llvm::Module> M = std::move(this->M);
238  std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder);
239 
240  if (Diags.hasErrorOccurred())
241  return;
242 
243  M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple());
244  M->setDataLayout(Ctx.getTargetInfo().getDataLayout());
245 
246  // PCH files don't have a signature field in the control block,
247  // but LLVM detects DWO CUs by looking for a non-zero DWO id.
248  // We use the lower 64 bits for debug info.
249  uint64_t Signature =
250  Buffer->Signature
251  ? (uint64_t)Buffer->Signature[1] << 32 | Buffer->Signature[0]
252  : ~1ULL;
253  Builder->getModuleDebugInfo()->setDwoId(Signature);
254 
255  // Finalize the Builder.
256  if (Builder)
257  Builder->Release();
258 
259  // Ensure the target exists.
260  std::string Error;
261  auto Triple = Ctx.getTargetInfo().getTriple();
262  if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error))
263  llvm::report_fatal_error(Error);
264 
265  // Emit the serialized Clang AST into its own section.
266  assert(Buffer->IsComplete && "serialization did not complete");
267  auto &SerializedAST = Buffer->Data;
268  auto Size = SerializedAST.size();
269  auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
270  auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
271  auto *Data = llvm::ConstantDataArray::getString(
272  *VMContext, StringRef(SerializedAST.data(), Size),
273  /*AddNull=*/false);
274  auto *ASTSym = new llvm::GlobalVariable(
275  *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
276  "__clang_ast");
277  // The on-disk hashtable needs to be aligned.
278  ASTSym->setAlignment(8);
279 
280  // Mach-O also needs a segment name.
281  if (Triple.isOSBinFormatMachO())
282  ASTSym->setSection("__CLANG,__clangast");
283  // COFF has an eight character length limit.
284  else if (Triple.isOSBinFormatCOFF())
285  ASTSym->setSection("clangast");
286  else
287  ASTSym->setSection("__clangast");
288 
289  DEBUG({
290  // Print the IR for the PCH container to the debug output.
291  llvm::SmallString<0> Buffer;
293  Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts,
294  Ctx.getTargetInfo().getDataLayout(), M.get(),
296  llvm::make_unique<llvm::raw_svector_ostream>(Buffer));
297  llvm::dbgs() << Buffer;
298  });
299 
300  // Use the LLVM backend to emit the pch container.
301  clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts,
302  LangOpts, Ctx.getTargetInfo().getDataLayout(),
304  std::move(OS));
305 
306  // Free the memory for the temporary buffer.
308  SerializedAST = std::move(Empty);
309  }
310 };
311 
312 } // anonymous namespace
313 
314 std::unique_ptr<ASTConsumer>
315 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
316  CompilerInstance &CI, const std::string &MainFileName,
317  const std::string &OutputFileName,
318  std::unique_ptr<llvm::raw_pwrite_stream> OS,
319  std::shared_ptr<PCHBuffer> Buffer) const {
320  return llvm::make_unique<PCHContainerGenerator>(
321  CI, MainFileName, OutputFileName, std::move(OS), Buffer);
322 }
323 
324 StringRef
325 ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const {
326  StringRef PCH;
327  auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer);
328  if (OFOrErr) {
329  auto &OF = OFOrErr.get();
330  bool IsCOFF = isa<llvm::object::COFFObjectFile>(*OF);
331  // Find the clang AST section in the container.
332  for (auto &Section : OF->sections()) {
333  StringRef Name;
334  Section.getName(Name);
335  if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) {
336  Section.getContents(PCH);
337  return PCH;
338  }
339  }
340  }
341  handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) {
342  if (EIB.convertToErrorCode() ==
343  llvm::object::object_error::invalid_file_type)
344  // As a fallback, treat the buffer as a raw AST.
345  PCH = Buffer.getBuffer();
346  else
347  EIB.log(llvm::errs());
348  });
349  return PCH;
350 }
Defines the clang::ASTContext interface.
LangOptions & getLangOpts()
const Type * getTypeForDecl() const
Definition: DeclObjC.h:1938
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1698
PreprocessorOptions & getPreprocessorOpts()
bool hasErrorOccurred() const
Definition: Diagnostic.h:662
A (possibly-)qualified type.
Definition: Type.h:653
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1101
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:790
The base class of the type hierarchy.
Definition: Type.h:1353
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:671
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
Definition: Decl.h:3091
QualType getReturnType() const
Definition: Decl.h:2205
Options for controlling the target.
Definition: TargetOptions.h:26
Extra information about a function prototype.
Definition: Type.h:3389
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
Definition: CGDebugInfo.h:53
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:139
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:647
RecordDecl - Represents a struct/union/class.
Definition: Decl.h:3482
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
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:48
std::string CodeModel
The code model to use (-mcmodel).
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2164
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:817
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
TypeDecl - Represents a declaration of a type.
Definition: Decl.h:2754
Defines the Diagnostic-related interfaces.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5720
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:1191
QualType getReturnType() const
Definition: DeclObjC.h:361
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:131
Defines the clang::Preprocessor interface.
DeclContext * getDeclContext()
Definition: DeclBase.h:425
Emit native object files.
Definition: BackendUtil.h:37
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1331
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:1333
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:1347
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:719
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:1035
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
Limit generated debug info to reduce size (-fno-standalone-debug).
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2938
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C &#39;SEL&#39; type.
Definition: ASTContext.h:1810
const llvm::DataLayout & getDataLayout() const
Definition: TargetInfo.h:794
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
Definition: DeclBase.h:694
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3965
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:6240
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:33
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
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:270
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:1860
TargetOptions & getTargetOpts()
SourceLocation getLocation() const
Definition: DeclBase.h:416
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:405