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 9 #include "clang/CodeGen/ObjectFilePCHContainerOperations.h" 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" 15 #include "clang/AST/RecursiveASTVisitor.h" 16 #include "clang/Basic/CodeGenOptions.h" 17 #include "clang/Basic/Diagnostic.h" 18 #include "clang/Basic/TargetInfo.h" 19 #include "clang/CodeGen/BackendUtil.h" 20 #include "clang/Frontend/CompilerInstance.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/MC/TargetRegistry.h" 31 #include "llvm/Object/COFF.h" 32 #include "llvm/Object/ObjectFile.h" 33 #include "llvm/Support/Path.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 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; 49 const HeaderSearchOptions &HeaderSearchOpts; 50 const PreprocessorOptions &PreprocessorOpts; 51 CodeGenOptions CodeGenOpts; 52 const TargetOptions TargetOpts; 53 LangOptions LangOpts; 54 std::unique_ptr<llvm::LLVMContext> VMContext; 55 std::unique_ptr<llvm::Module> M; 56 std::unique_ptr<CodeGen::CodeGenModule> Builder; 57 std::unique_ptr<raw_pwrite_stream> OS; 58 std::shared_ptr<PCHBuffer> Buffer; 59 60 /// Visit every type and emit debug info for it. 61 struct DebugTypeVisitor : public RecursiveASTVisitor<DebugTypeVisitor> { 62 clang::CodeGen::CGDebugInfo &DI; 63 ASTContext &Ctx; 64 DebugTypeVisitor(clang::CodeGen::CGDebugInfo &DI, ASTContext &Ctx) 65 : DI(DI), Ctx(Ctx) {} 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 if (!D->getImportedOwningModule()) 74 DI.EmitImportDecl(*D); 75 return true; 76 } 77 78 bool VisitTypeDecl(TypeDecl *D) { 79 // TagDecls may be deferred until after all decls have been merged and we 80 // know the complete type. Pure forward declarations will be skipped, but 81 // they don't need to be emitted into the module anyway. 82 if (auto *TD = dyn_cast<TagDecl>(D)) 83 if (!TD->isCompleteDefinition()) 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 // Skip deduction guides. 101 if (isa<CXXDeductionGuideDecl>(D)) 102 return true; 103 104 if (isa<CXXMethodDecl>(D)) 105 // This is not yet supported. Constructing the `this' argument 106 // mandates a CodeGenFunction. 107 return true; 108 109 SmallVector<QualType, 16> ArgTypes; 110 for (auto *i : D->parameters()) 111 ArgTypes.push_back(i->getType()); 112 QualType RetTy = D->getReturnType(); 113 QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes, 114 FunctionProtoType::ExtProtoInfo()); 115 if (CanRepresent(FnTy.getTypePtr())) 116 DI.EmitFunctionDecl(D, D->getLocation(), FnTy); 117 return true; 118 } 119 120 bool VisitObjCMethodDecl(ObjCMethodDecl *D) { 121 if (!D->getClassInterface()) 122 return true; 123 124 bool selfIsPseudoStrong, selfIsConsumed; 125 SmallVector<QualType, 16> ArgTypes; 126 ArgTypes.push_back(D->getSelfType(Ctx, D->getClassInterface(), 127 selfIsPseudoStrong, selfIsConsumed)); 128 ArgTypes.push_back(Ctx.getObjCSelType()); 129 for (auto *i : D->parameters()) 130 ArgTypes.push_back(i->getType()); 131 QualType RetTy = D->getReturnType(); 132 QualType FnTy = Ctx.getFunctionType(RetTy, ArgTypes, 133 FunctionProtoType::ExtProtoInfo()); 134 if (CanRepresent(FnTy.getTypePtr())) 135 DI.EmitFunctionDecl(D, D->getLocation(), FnTy); 136 return true; 137 } 138 }; 139 140 public: 141 PCHContainerGenerator(CompilerInstance &CI, const std::string &MainFileName, 142 const std::string &OutputFileName, 143 std::unique_ptr<raw_pwrite_stream> OS, 144 std::shared_ptr<PCHBuffer> Buffer) 145 : Diags(CI.getDiagnostics()), MainFileName(MainFileName), 146 OutputFileName(OutputFileName), Ctx(nullptr), 147 MMap(CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()), 148 FS(&CI.getVirtualFileSystem()), 149 HeaderSearchOpts(CI.getHeaderSearchOpts()), 150 PreprocessorOpts(CI.getPreprocessorOpts()), 151 TargetOpts(CI.getTargetOpts()), LangOpts(CI.getLangOpts()), 152 OS(std::move(OS)), Buffer(std::move(Buffer)) { 153 // The debug info output isn't affected by CodeModel and 154 // ThreadModel, but the backend expects them to be nonempty. 155 CodeGenOpts.CodeModel = "default"; 156 LangOpts.setThreadModel(LangOptions::ThreadModelKind::Single); 157 CodeGenOpts.DebugTypeExtRefs = true; 158 // When building a module MainFileName is the name of the modulemap file. 159 CodeGenOpts.MainFileName = 160 LangOpts.CurrentModule.empty() ? MainFileName : LangOpts.CurrentModule; 161 CodeGenOpts.setDebugInfo(llvm::codegenoptions::FullDebugInfo); 162 CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning()); 163 CodeGenOpts.DwarfVersion = CI.getCodeGenOpts().DwarfVersion; 164 CodeGenOpts.DebugCompilationDir = 165 CI.getInvocation().getCodeGenOpts().DebugCompilationDir; 166 CodeGenOpts.DebugPrefixMap = 167 CI.getInvocation().getCodeGenOpts().DebugPrefixMap; 168 CodeGenOpts.DebugStrictDwarf = CI.getCodeGenOpts().DebugStrictDwarf; 169 } 170 171 ~PCHContainerGenerator() override = default; 172 173 void Initialize(ASTContext &Context) override { 174 assert(!Ctx && "initialized multiple times"); 175 176 Ctx = &Context; 177 VMContext.reset(new llvm::LLVMContext()); 178 M.reset(new llvm::Module(MainFileName, *VMContext)); 179 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString()); 180 Builder.reset(new CodeGen::CodeGenModule( 181 *Ctx, FS, HeaderSearchOpts, PreprocessorOpts, CodeGenOpts, *M, Diags)); 182 183 // Prepare CGDebugInfo to emit debug info for a clang module. 184 auto *DI = Builder->getModuleDebugInfo(); 185 StringRef ModuleName = llvm::sys::path::filename(MainFileName); 186 DI->setPCHDescriptor( 187 {ModuleName, "", OutputFileName, ASTFileSignature::createDISentinel()}); 188 DI->setModuleMap(MMap); 189 } 190 191 bool HandleTopLevelDecl(DeclGroupRef D) override { 192 if (Diags.hasErrorOccurred()) 193 return true; 194 195 // Collect debug info for all decls in this group. 196 for (auto *I : D) 197 if (!I->isFromASTFile()) { 198 DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx); 199 DTV.TraverseDecl(I); 200 } 201 return true; 202 } 203 204 void HandleTopLevelDeclInObjCContainer(DeclGroupRef D) override { 205 HandleTopLevelDecl(D); 206 } 207 208 void HandleTagDeclDefinition(TagDecl *D) override { 209 if (Diags.hasErrorOccurred()) 210 return; 211 212 if (D->isFromASTFile()) 213 return; 214 215 // Anonymous tag decls are deferred until we are building their declcontext. 216 if (D->getName().empty()) 217 return; 218 219 // Defer tag decls until their declcontext is complete. 220 auto *DeclCtx = D->getDeclContext(); 221 while (DeclCtx) { 222 if (auto *D = dyn_cast<TagDecl>(DeclCtx)) 223 if (!D->isCompleteDefinition()) 224 return; 225 DeclCtx = DeclCtx->getParent(); 226 } 227 228 DebugTypeVisitor DTV(*Builder->getModuleDebugInfo(), *Ctx); 229 DTV.TraverseDecl(D); 230 Builder->UpdateCompletedType(D); 231 } 232 233 void HandleTagDeclRequiredDefinition(const TagDecl *D) override { 234 if (Diags.hasErrorOccurred()) 235 return; 236 237 if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 238 Builder->getModuleDebugInfo()->completeRequiredType(RD); 239 } 240 241 void HandleImplicitImportDecl(ImportDecl *D) override { 242 if (!D->getImportedOwningModule()) 243 Builder->getModuleDebugInfo()->EmitImportDecl(*D); 244 } 245 246 /// Emit a container holding the serialized AST. 247 void HandleTranslationUnit(ASTContext &Ctx) override { 248 assert(M && VMContext && Builder); 249 // Delete these on function exit. 250 std::unique_ptr<llvm::LLVMContext> VMContext = std::move(this->VMContext); 251 std::unique_ptr<llvm::Module> M = std::move(this->M); 252 std::unique_ptr<CodeGen::CodeGenModule> Builder = std::move(this->Builder); 253 254 if (Diags.hasErrorOccurred()) 255 return; 256 257 M->setTargetTriple(Ctx.getTargetInfo().getTriple().getTriple()); 258 M->setDataLayout(Ctx.getTargetInfo().getDataLayoutString()); 259 260 // PCH files don't have a signature field in the control block, 261 // but LLVM detects DWO CUs by looking for a non-zero DWO id. 262 // We use the lower 64 bits for debug info. 263 264 uint64_t Signature = 265 Buffer->Signature ? Buffer->Signature.truncatedValue() : ~1ULL; 266 267 Builder->getModuleDebugInfo()->setDwoId(Signature); 268 269 // Finalize the Builder. 270 if (Builder) 271 Builder->Release(); 272 273 // Ensure the target exists. 274 std::string Error; 275 auto Triple = Ctx.getTargetInfo().getTriple(); 276 if (!llvm::TargetRegistry::lookupTarget(Triple.getTriple(), Error)) 277 llvm::report_fatal_error(llvm::Twine(Error)); 278 279 // Emit the serialized Clang AST into its own section. 280 assert(Buffer->IsComplete && "serialization did not complete"); 281 auto &SerializedAST = Buffer->Data; 282 auto Size = SerializedAST.size(); 283 284 if (Triple.isOSBinFormatWasm()) { 285 // Emit __clangast in custom section instead of named data segment 286 // to find it while iterating sections. 287 // This could be avoided if all data segements (the wasm sense) were 288 // represented as their own sections (in the llvm sense). 289 // TODO: https://github.com/WebAssembly/tool-conventions/issues/138 290 llvm::NamedMDNode *MD = 291 M->getOrInsertNamedMetadata("wasm.custom_sections"); 292 llvm::Metadata *Ops[2] = { 293 llvm::MDString::get(*VMContext, "__clangast"), 294 llvm::MDString::get(*VMContext, 295 StringRef(SerializedAST.data(), Size))}; 296 auto *NameAndContent = llvm::MDTuple::get(*VMContext, Ops); 297 MD->addOperand(NameAndContent); 298 } else { 299 auto Int8Ty = llvm::Type::getInt8Ty(*VMContext); 300 auto *Ty = llvm::ArrayType::get(Int8Ty, Size); 301 auto *Data = llvm::ConstantDataArray::getString( 302 *VMContext, StringRef(SerializedAST.data(), Size), 303 /*AddNull=*/false); 304 auto *ASTSym = new llvm::GlobalVariable( 305 *M, Ty, /*constant*/ true, llvm::GlobalVariable::InternalLinkage, 306 Data, "__clang_ast"); 307 // The on-disk hashtable needs to be aligned. 308 ASTSym->setAlignment(llvm::Align(8)); 309 310 // Mach-O also needs a segment name. 311 if (Triple.isOSBinFormatMachO()) 312 ASTSym->setSection("__CLANG,__clangast"); 313 // COFF has an eight character length limit. 314 else if (Triple.isOSBinFormatCOFF()) 315 ASTSym->setSection("clangast"); 316 else 317 ASTSym->setSection("__clangast"); 318 } 319 320 LLVM_DEBUG({ 321 // Print the IR for the PCH container to the debug output. 322 llvm::SmallString<0> Buffer; 323 clang::EmitBackendOutput( 324 Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts, 325 Ctx.getTargetInfo().getDataLayoutString(), M.get(), 326 BackendAction::Backend_EmitLL, FS, 327 std::make_unique<llvm::raw_svector_ostream>(Buffer)); 328 llvm::dbgs() << Buffer; 329 }); 330 331 // Use the LLVM backend to emit the pch container. 332 clang::EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, 333 LangOpts, 334 Ctx.getTargetInfo().getDataLayoutString(), M.get(), 335 BackendAction::Backend_EmitObj, FS, std::move(OS)); 336 337 // Free the memory for the temporary buffer. 338 llvm::SmallVector<char, 0> Empty; 339 SerializedAST = std::move(Empty); 340 } 341 }; 342 343 } // anonymous namespace 344 345 std::unique_ptr<ASTConsumer> 346 ObjectFilePCHContainerWriter::CreatePCHContainerGenerator( 347 CompilerInstance &CI, const std::string &MainFileName, 348 const std::string &OutputFileName, 349 std::unique_ptr<llvm::raw_pwrite_stream> OS, 350 std::shared_ptr<PCHBuffer> Buffer) const { 351 return std::make_unique<PCHContainerGenerator>( 352 CI, MainFileName, OutputFileName, std::move(OS), Buffer); 353 } 354 355 ArrayRef<StringRef> ObjectFilePCHContainerReader::getFormats() const { 356 static StringRef Formats[] = {"obj", "raw"}; 357 return Formats; 358 } 359 360 StringRef 361 ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { 362 StringRef PCH; 363 auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer); 364 if (OFOrErr) { 365 auto &OF = OFOrErr.get(); 366 bool IsCOFF = isa<llvm::object::COFFObjectFile>(*OF); 367 // Find the clang AST section in the container. 368 for (auto &Section : OF->sections()) { 369 StringRef Name; 370 if (Expected<StringRef> NameOrErr = Section.getName()) 371 Name = *NameOrErr; 372 else 373 consumeError(NameOrErr.takeError()); 374 375 if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) { 376 if (Expected<StringRef> E = Section.getContents()) 377 return *E; 378 else { 379 handleAllErrors(E.takeError(), [&](const llvm::ErrorInfoBase &EIB) { 380 EIB.log(llvm::errs()); 381 }); 382 return ""; 383 } 384 } 385 } 386 } 387 handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) { 388 if (EIB.convertToErrorCode() == 389 llvm::object::object_error::invalid_file_type) 390 // As a fallback, treat the buffer as a raw AST. 391 PCH = Buffer.getBuffer(); 392 else 393 EIB.log(llvm::errs()); 394 }); 395 return PCH; 396 } 397