clang  3.8.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/Preprocessor.h"
23 #include "clang/Lex/HeaderSearch.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/TargetRegistry.h"
35 #include <memory>
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  ASTContext *Ctx;
46  ModuleMap &MMap;
47  const HeaderSearchOptions &HeaderSearchOpts;
48  const PreprocessorOptions &PreprocessorOpts;
49  CodeGenOptions CodeGenOpts;
50  const TargetOptions TargetOpts;
51  const LangOptions LangOpts;
52  std::unique_ptr<llvm::LLVMContext> VMContext;
53  std::unique_ptr<llvm::Module> M;
54  std::unique_ptr<CodeGen::CodeGenModule> Builder;
55  raw_pwrite_stream *OS;
56  std::shared_ptr<PCHBuffer> Buffer;
57 
58  /// Visit every type and emit debug info for it.
59  struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> {
61  ASTContext &Ctx;
62  bool SkipTagDecls;
63  DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx,
64  bool SkipTagDecls)
65  : DI(DI), Ctx(Ctx), SkipTagDecls(SkipTagDecls) {}
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  auto *Import = cast<ImportDecl>(D);
74  if (!Import->getImportedOwningModule())
75  DI.EmitImportDecl(*Import);
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 (SkipTagDecls && isa<TagDecl>(D))
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->params())
107  ArgTypes.push_back(i->getType());
108  QualType RetTy = D->getReturnType();
109  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
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->params())
126  ArgTypes.push_back(i->getType());
127  QualType RetTy = D->getReturnType();
128  QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes,
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  raw_pwrite_stream *OS,
140  std::shared_ptr<PCHBuffer> Buffer)
141  : Diags(CI.getDiagnostics()), Ctx(nullptr),
143  HeaderSearchOpts(CI.getHeaderSearchOpts()),
144  PreprocessorOpts(CI.getPreprocessorOpts()),
145  TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()), OS(OS),
146  Buffer(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  CodeGenOpts.setDebugInfo(CodeGenOptions::FullDebugInfo);
153  }
154 
155  ~PCHContainerGenerator() override = default;
156 
157  void Initialize(ASTContext &Context) override {
158  assert(!Ctx && "initialized multiple times");
159 
160  Ctx = &Context;
161  VMContext.reset(new llvm::LLVMContext());
162  M.reset(new llvm::Module(MainFileName, *VMContext));
163  M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
165  *Ctx, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags));
166  Builder->getModuleDebugInfo()->setModuleMap(MMap);
167  }
168 
169  bool HandleTopLevelDecl(DeclGroupRef D) override {
170  if (Diags.hasErrorOccurred())
171  return true;
172 
173  // Collect debug info for all decls in this group.
174  for (auto *I : D)
175  if (!I->isFromASTFile()) {
176  DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx, true);
177  DTV.TraverseDecl(I);
178  }
179  return true;
180  }
181 
182  void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override {
183  HandleTopLevelDecl(D);
184  }
185 
186  void HandleTagDeclDefinition(TagDecl *D) override {
187  if (Diags.hasErrorOccurred())
188  return;
189 
190  if (D->isFromASTFile())
191  return;
192 
193  DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx, false);
194  DTV.TraverseDecl(D);
195  Builder->UpdateCompletedType(D);
196  }
197 
198  void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
199  if (Diags.hasErrorOccurred())
200  return;
201 
202  if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
203  Builder->getModuleDebugInfo()->completeRequiredType(RD);
204  }
205 
206  /// Emit a container holding the serialized AST.
207  void HandleTranslationUnit(ASTContext &Ctx) override {
208  assert(M && VMContext && Builder);
209  // Delete these on function exit.
210  std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext);
211  std::unique_ptr<llvm::Module> M = std::move(this->M);
212  std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder);
213 
214  if (Diags.hasErrorOccurred())
215  return;
216 
217  M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple());
218  M->setDataLayout(Ctx.getTargetInfo().getDataLayoutString());
219  Builder->getModuleDebugInfo()->setDwoId(Buffer->Signature);
220 
221  // Finalize the Builder.
222  if (Builder)
223  Builder->Release();
224 
225  // Ensure the target exists.
226  std::string Error;
227  auto Triple = Ctx.getTargetInfo().getTriple();
228  if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error))
229  llvm::report_fatal_error(Error);
230 
231  // Emit the serialized Clang AST into its own section.
232  assert(Buffer->IsComplete && "serialization did not complete");
233  auto &SerializedAST = Buffer->Data;
234  auto Size = SerializedAST.size();
235  auto Int8Ty = llvm::Type::getInt8Ty(*VMContext);
236  auto *Ty = llvm::ArrayType::get(Int8Ty, Size);
237  auto *Data = llvm::ConstantDataArray::getString(
238  *VMContext, StringRef(SerializedAST.data(), Size),
239  /*AddNull=*/false);
240  auto *ASTSym = new llvm::GlobalVariable(
241  *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, Data,
242  "__clang_ast");
243  // The on-disk hashtable needs to be aligned.
244  ASTSym->setAlignment(8);
245 
246  // Mach-O also needs a segment name.
247  if (Triple.isOSBinFormatMachO())
248  ASTSym->setSection("__CLANG,__clangast");
249  // COFF has an eight character length limit.
250  else if (Triple.isOSBinFormatCOFF())
251  ASTSym->setSection("clangast");
252  else
253  ASTSym->setSection("__clangast");
254 
255  DEBUG({
256  // Print the IR for the PCH container to the debug output.
258  llvm::raw_svector_ostream OS(Buffer);
259  clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
261  M.get(), BackendAction::Backend_EmitLL, &OS);
262  llvm::dbgs() << Buffer;
263  });
264 
265  // Use the LLVM backend to emit the pch container.
266  clang::EmitBackendOutput(Diags, CodeGenOpts, TargetOpts, LangOpts,
268  M.get(), BackendAction::Backend_EmitObj, OS);
269 
270  // Make sure the pch container hits disk.
271  OS->flush();
272 
273  // Free the memory for the temporary buffer.
275  SerializedAST = std::move(Empty);
276  }
277 };
278 
279 } // anonymous namespace
280 
281 std::unique_ptr<ASTConsumer>
282 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator(
283  CompilerInstance &CI, const std::string &MainFileName,
284  const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
285  std::shared_ptr<PCHBuffer> Buffer) const {
286  return llvm::make_unique<PCHContainerGenerator>(CI, MainFileName,
287  OutputFileName, OS, Buffer);
288 }
289 
290 void ObjectFilePCHContainerReader::ExtractPCH(
291  llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const {
292  if (auto OF = llvm::object::ObjectFile::createObjectFile(Buffer)) {
293  auto *Obj = OF.get().get();
294  bool IsCOFF = isa<llvm::object::COFFObjectFile>(Obj);
295  // Find the clang AST section in the container.
296  for (auto &Section : OF->get()->sections()) {
297  StringRef Name;
298  Section.getName(Name);
299  if ((!IsCOFF && Name == "__clangast") ||
300  ( IsCOFF && Name == "clangast")) {
301  StringRef Buf;
302  Section.getContents(Buf);
303  StreamFile.init((const unsigned char *)Buf.begin(),
304  (const unsigned char *)Buf.end());
305  return;
306  }
307  }
308  }
309 
310  // As a fallback, treat the buffer as a raw AST.
311  StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
312  (const unsigned char *)Buffer.getBufferEnd());
313 }
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:1483
PreprocessorOptions & getPreprocessorOpts()
A (possibly-)qualified type.
Definition: Type.h:575
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.cpp:1043
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:30
The base class of the type hierarchy.
Definition: Type.h:1249
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:1579
Options for controlling the target.
Definition: TargetOptions.h:24
const char * getDataLayoutString() const
Extra information about a function prototype.
Definition: Type.h:3067
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
Definition: CGDebugInfo.h:51
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
ModuleMap & getModuleMap()
Retrieve the module map.
Definition: HeaderSearch.h:591
RecordDecl - Represents a struct/union/class.
Definition: Decl.h:3166
class LLVM_ALIGNAS(8) DependentTemplateSpecializationType const IdentifierInfo * Name
Represents a template specialization type whose template cannot be resolved, e.g. ...
Definition: Type.h:4381
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:91
void EmitImportDecl(const ImportDecl &ID)
Emit an declaration.
QualType getReturnType() const
Definition: Decl.h:1956
param_range params()
Definition: DeclObjC.h:354
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:1191
void EmitBackendOutput(DiagnosticsEngine &Diags, const CodeGenOptions &CGOpts, const TargetOptions &TOpts, const LangOptions &LOpts, StringRef TDesc, llvm::Module *M, BackendAction Action, raw_pwrite_stream *OS)
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:580
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:135
HeaderSearch & getHeaderSearchInfo() const
Definition: Preprocessor.h:688
TypeDecl - Represents a declaration of a type.
Definition: Decl.h:2486
HeaderSearchOptions & getHeaderSearchOpts()
A class that does preorder depth-first traversal on the entire Clang AST and visits each node...
Represents an ObjC class declaration.
Definition: DeclObjC.h:853
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:5615
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:1751
Emit native object files.
Definition: BackendUtil.h:33
bool isFromASTFile() const
Determine whether this declaration came from an AST file (such as a precompiled header or module) rat...
Definition: DeclBase.h:635
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
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:977
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:5089
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2644
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:3658
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:1603
param_range params()
Definition: Decl.h:1910
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
Defines the clang::TargetInfo interface.
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
Limit generated debug info to reduce size (-fno-standalone-debug).
SourceLocation getLocation() const
Definition: DeclBase.h:384
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:642
TargetOptions & getTargetOpts()