clang  3.9.0
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  CodeGenOpts.setDebugInfo(codegenoptions::FullDebugInfo);
156  CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning());
157  }
158 
159  ~PCHContainerGenerator() override = default;
160 
161  void Initialize(ASTContext &Context) override {
162  assert(!Ctx && "initialized multiple times");
163 
164  Ctx = &Context;
165  VMContext.reset(new llvm::LLVMContext());
166  M.reset(new llvm::Module(MainFileName, *VMContext));
167  M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
169  *Ctx, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags));
170 
171  // Prepare CGDebugInfo to emit debug info for a clang module.
172  auto *DI = Builder->getModuleDebugInfo();
173  StringRef ModuleName = llvm::sys::path::filename(MainFileName);
174  DI->setPCHDescriptor({ModuleName, "", OutputFileName, ~1ULL});
175  DI->setModuleMap(MMap);
176  }
177 
178  bool HandleTopLevelDecl(DeclGroupRef D) override {
179  if (Diags.hasErrorOccurred())
180  return true;
181 
182  // Collect debug info for all decls in this group.
183  for (auto *I : D)
184  if (!I->isFromASTFile()) {
185  DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
186  DTV.TraverseDecl(I);
187  }
188  return true;
189  }
190 
191  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
192  HandleTopLevelDecl(D);
193  }
194 
195  void HandleTagDeclDefinition(TagDecl *D) override {
196  if (Diags.hasErrorOccurred())
197  return;
198 
199  if (D->isFromASTFile())
200  return;
201 
202  // Anonymous tag decls are deferred until we are building their declcontext.
203  if (D->getName().empty())
204  return;
205 
206  // Defer tag decls until their declcontext is complete.
207  auto *DeclCtx = D->getDeclContext();
208  while (DeclCtx) {
209  if (auto *D = dyn_cast<TagDecl>(DeclCtx))
210  if (!D->isCompleteDefinition())
211  return;
212  DeclCtx = DeclCtx->getParent();
213  }
214 
215  DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx);
216  DTV.TraverseDecl(D);
217  Builder->UpdateCompletedType(D);
218  }
219 
220  void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
221  if (Diags.hasErrorOccurred())
222  return;
223 
224  if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
225  Builder->getModuleDebugInfo()->completeRequiredType(RD);
226  }
227 
228  /// Emit a container holding the serialized AST.
229  void HandleTranslationUnit(ASTContext &Ctx) override {
230  assert(M && VMContext && Builder);
231  // Delete these on function exit.
232  std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
233  std::unique_ptr<llvm::Module> M = std::move(this->M);
234  std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder);
235 
236  if (Diags.hasErrorOccurred())
237  return;
238 
239  M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple());
240  M->setDataLayout(Ctx.getTargetInfo().getDataLayout());
241 
242  // PCH files don't have a signature field in the control block,
243  // but LLVM detects DWO CUs by looking for a non-zero DWO id.
244  uint64_t Signature = Buffer->Signature ? Buffer->Signature : ~1ULL;
245  Builder->getModuleDebugInfo()->setDwoId(Signature);
246 
247  // Finalize the Builder.
248  if (Builder)
249  Builder->Release();
250 
251  // Ensure the target exists.
252  std::string Error;
253  auto Triple = Ctx.getTargetInfo().getTriple();
254  if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error))
255  llvm::report_fatal_error(Error);
256 
257  // Emit the serialized Clang AST into its own section.
258  assert(Buffer->IsComplete && "serialization did not complete");
259  auto &SerializedAST = Buffer->Data;
260  auto Size = SerializedAST.size();
261  auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
262  auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
263  auto *Data = llvm::ConstantDataArray::getString(
264  *VMContext, StringRef(SerializedAST.data(), Size),
265  /*AddNull=*/false);
266  auto *ASTSym = new llvm::GlobalVariable(
267  *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
268  "__clang_ast");
269  // The on-disk hashtable needs to be aligned.
270  ASTSym->setAlignment(8);
271 
272  // Mach-O also needs a segment name.
273  if (Triple.isOSBinFormatMachO())
274  ASTSym->setSection("__CLANG,__clangast");
275  // COFF has an eight character length limit.
276  else if (Triple.isOSBinFormatCOFF())
277  ASTSym->setSection("clangast");
278  else
279  ASTSym->setSection("__clangast");
280 
281  DEBUG({
282  // Print the IR for the PCH container to the debug output.
285  Diags, CodeGenOpts, TargetOpts, LangOpts,
286  Ctx.getTargetInfo().getDataLayout(), M.get(),
288  llvm::make_unique<llvm::raw_svector_ostream>(Buffer));
289  llvm::dbgs() << Buffer;
290  });
291 
292  // Use the LLVM backend to emit the pch container.
293  clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
294  Ctx.getTargetInfo().getDataLayout(), M.get(),
295  BackendAction::Backend_EmitObj, std::move(OS));
296 
297  // Free the memory for the temporary buffer.
299  SerializedAST = std::move(Empty);
300  }
301 };
302 
303 } // anonymous namespace
304 
305 std::unique_ptr<ASTConsumer>
306 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
307  CompilerInstance &CI, const std::string &MainFileName,
308  const std::string &OutputFileName,
309  std::unique_ptr<llvm::raw_pwrite_stream> OS,
310  std::shared_ptr<PCHBuffer> Buffer) const {
311  return llvm::make_unique<PCHContainerGenerator>(
312  CI, MainFileName, OutputFileName, std::move(OS), Buffer);
313 }
314 
315 void ObjectFilePCHContainerReader::ExtractPCH(
316  llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const {
317  if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) {
318  auto *Obj = OF.get().get();
319  bool IsCOFF = isa<llvm::object::COFFObjectFile>(Obj);
320  // Find the clang AST section in the container.
321  for (auto &Section : OF->get()->sections()) {
322  StringRef Name;
323  Section.getName(Name);
324  if ((!IsCOFF && Name == "__clangast") ||
325  ( IsCOFF && Name == "clangast")) {
326  StringRef Buf;
327  Section.getContents(Buf);
328  StreamFile.init((const unsigned char *)Buf.begin(),
329  (const unsigned char *)Buf.end());
330  return;
331  }
332  }
333  }
334 
335  // As a fallback, treat the buffer as a raw AST.
336  StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
337  (const unsigned char *)Buffer.getBufferEnd());
338 }
Defines the clang::ASTContext interface.
LangOptions & getLangOpts()
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1561
PreprocessorOptions & getPreprocessorOpts()
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:237
A (possibly-)qualified type.
Definition: Type.h:598
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1071
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
Definition: ASTConsumer.h:36
Emit human-readable LLVM assembly.
Definition: BackendUtil.h:31
The base class of the type hierarchy.
Definition: Type.h:1281
std::unique_ptr< llvm::MemoryBuffer > Buffer
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
const Type * getTypeForDecl() const
Definition: DeclObjC.h:1819
Options for controlling the target.
Definition: TargetOptions.h:25
Extra information about a function prototype.
Definition: Type.h:3167
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
Definition: CGDebugInfo.h:52
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:590
RecordDecl - Represents a struct/union/class.
Definition: Decl.h:3253
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4549
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:92
void EmitImportDecl(const ImportDecl &ID)
Emit an declaration.
QualType getReturnType() const
Definition: Decl.h:2034
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
Definition: Decl.h:2871
CodeGenOptions & getCodeGenOpts()
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:48
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:1199
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:588
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:135
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:695
TypeDecl - Represents a declaration of a type.
Definition: Decl.h:2569
HeaderSearchOptions & getHeaderSearchOpts()
A class that does preordor or postorder depth-first traversal on the entire Clang AST and visits each...
Represents an ObjC class declaration.
Definition: DeclObjC.h:1091
detail::InMemoryDirectory::const_iterator I
Preprocessor & getPreprocessor() const
Return the current preprocessor.
ASTContext * Context
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
Definition: Type.h:5749
StringRef getName() const
Return the actual identifier string.
Defines the clang::Preprocessor interface.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1774
Emit native object files.
Definition: BackendUtil.h:34
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1214
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:371
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:1005
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5259
Limit generated debug info to reduce size (-fno-standalone-debug).
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2727
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:1989
QualType getReturnType() const
Definition: DeclObjC.h:330
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition: Decl.h:3728
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
QualType getObjCSelType() const
Retrieve the type that corresponds to the predefined Objective-C 'SEL' type.
Definition: ASTContext.h:1623
This class organizes the cross-function state that is used while generating LLVM code.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Defines the Diagnostic-related interfaces.
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
BoundNodesTreeBuilder *const Builder
void EmitBackendOutput(DiagnosticsEngine &Diags, 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)
Defines the clang::TargetInfo interface.
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:665
const llvm::DataLayout & getDataLayout() const
TargetOptions & getTargetOpts()