| 1 | //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===// |
| 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 | // This builds an AST and converts it to LLVM Code. |
| 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| 13 | #include "clang/CodeGen/ModuleBuilder.h" |
| 14 | #include "CGDebugInfo.h" |
| 15 | #include "CodeGenModule.h" |
| 16 | #include "clang/AST/ASTContext.h" |
| 17 | #include "clang/AST/DeclObjC.h" |
| 18 | #include "clang/AST/Expr.h" |
| 19 | #include "clang/Basic/CodeGenOptions.h" |
| 20 | #include "clang/Basic/Diagnostic.h" |
| 21 | #include "clang/Basic/TargetInfo.h" |
| 22 | #include "clang/Frontend/CompilerInstance.h" |
| 23 | #include "llvm/ADT/StringRef.h" |
| 24 | #include "llvm/IR/DataLayout.h" |
| 25 | #include "llvm/IR/LLVMContext.h" |
| 26 | #include "llvm/IR/Module.h" |
| 27 | #include "llvm/Support/FormatVariadic.h" |
| 28 | #include "llvm/Support/VirtualFileSystem.h" |
| 29 | #include <memory> |
| 30 | |
| 31 | using namespace clang; |
| 32 | using namespace CodeGen; |
| 33 | |
| 34 | namespace { |
| 35 | class CodeGeneratorImpl final : public CodeGenerator { |
| 36 | DiagnosticsEngine &Diags; |
| 37 | ASTContext *Ctx; |
| 38 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info. |
| 39 | const HeaderSearchOptions &; // Only used for debug info. |
| 40 | const PreprocessorOptions &PreprocessorOpts; // Only used for debug info. |
| 41 | const CodeGenOptions &CodeGenOpts; |
| 42 | |
| 43 | unsigned HandlingTopLevelDecls; |
| 44 | |
| 45 | /// Use this when emitting decls to block re-entrant decl emission. It will |
| 46 | /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl |
| 47 | /// emission must be deferred longer, like at the end of a tag definition. |
| 48 | struct HandlingTopLevelDeclRAII { |
| 49 | CodeGeneratorImpl &Self; |
| 50 | bool EmitDeferred; |
| 51 | HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self, |
| 52 | bool EmitDeferred = true) |
| 53 | : Self(Self), EmitDeferred(EmitDeferred) { |
| 54 | ++Self.HandlingTopLevelDecls; |
| 55 | } |
| 56 | ~HandlingTopLevelDeclRAII() { |
| 57 | unsigned Level = --Self.HandlingTopLevelDecls; |
| 58 | if (Level == 0 && EmitDeferred) |
| 59 | Self.EmitDeferredDecls(); |
| 60 | } |
| 61 | }; |
| 62 | |
| 63 | CoverageSourceInfo *CoverageInfo; |
| 64 | std::unique_ptr<llvm::Module> M; |
| 65 | std::unique_ptr<CodeGen::CodeGenModule> Builder; |
| 66 | SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs; |
| 67 | |
| 68 | static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName, |
| 69 | const CodeGenOptions &CGO) { |
| 70 | if (ModuleName == "-" && !CGO.MainFileName.empty()) |
| 71 | return CGO.MainFileName; |
| 72 | return ModuleName; |
| 73 | } |
| 74 | |
| 75 | public: |
| 76 | (DiagnosticsEngine &diags, llvm::StringRef ModuleName, |
| 77 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, |
| 78 | const HeaderSearchOptions &HSO, |
| 79 | const PreprocessorOptions &PPO, const CodeGenOptions &CGO, |
| 80 | llvm::LLVMContext &C, |
| 81 | CoverageSourceInfo *CoverageInfo = nullptr) |
| 82 | : Diags(diags), Ctx(nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO), |
| 83 | PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0), |
| 84 | CoverageInfo(CoverageInfo), |
| 85 | M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) { |
| 86 | C.setDiscardValueNames(CGO.DiscardValueNames); |
| 87 | } |
| 88 | |
| 89 | ~CodeGeneratorImpl() override { |
| 90 | // There should normally not be any leftover inline method definitions. |
| 91 | assert(DeferredInlineMemberFuncDefs.empty() || |
| 92 | Diags.hasErrorOccurred()); |
| 93 | } |
| 94 | |
| 95 | CodeGenModule &CGM() { |
| 96 | return *Builder; |
| 97 | } |
| 98 | |
| 99 | llvm::Module *GetModule() { |
| 100 | return M.get(); |
| 101 | } |
| 102 | |
| 103 | CGDebugInfo *getCGDebugInfo() { |
| 104 | return Builder->getModuleDebugInfo(); |
| 105 | } |
| 106 | |
| 107 | std::unique_ptr<llvm::Module> ReleaseModule() { |
| 108 | return std::exchange(obj&: M, new_val: nullptr); |
| 109 | } |
| 110 | |
| 111 | const Decl *GetDeclForMangledName(StringRef MangledName) { |
| 112 | GlobalDecl Result; |
| 113 | if (!Builder->lookupRepresentativeDecl(MangledName, Result)) |
| 114 | return nullptr; |
| 115 | const Decl *D = Result.getCanonicalDecl().getDecl(); |
| 116 | if (auto FD = dyn_cast<FunctionDecl>(Val: D)) { |
| 117 | if (FD->hasBody(Definition&: FD)) |
| 118 | return FD; |
| 119 | } else if (auto TD = dyn_cast<TagDecl>(Val: D)) { |
| 120 | if (auto Def = TD->getDefinition()) |
| 121 | return Def; |
| 122 | } |
| 123 | return D; |
| 124 | } |
| 125 | |
| 126 | llvm::StringRef GetMangledName(GlobalDecl GD) { |
| 127 | return Builder->getMangledName(GD); |
| 128 | } |
| 129 | |
| 130 | llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) { |
| 131 | return Builder->GetAddrOfGlobal(GD: global, IsForDefinition: ForDefinition_t(isForDefinition)); |
| 132 | } |
| 133 | |
| 134 | llvm::Module *StartModule(llvm::StringRef ModuleName, |
| 135 | llvm::LLVMContext &C) { |
| 136 | assert(!M && "Replacing existing Module?" ); |
| 137 | M.reset(p: new llvm::Module(ExpandModuleName(ModuleName, CGO: CodeGenOpts), C)); |
| 138 | |
| 139 | IRGenFinished = false; |
| 140 | |
| 141 | std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder); |
| 142 | |
| 143 | assert(Ctx && "must call Initialize() before calling StartModule()" ); |
| 144 | Initialize(Context&: *Ctx); |
| 145 | |
| 146 | if (OldBuilder) |
| 147 | OldBuilder->moveLazyEmissionStates(NewBuilder: Builder.get()); |
| 148 | |
| 149 | return M.get(); |
| 150 | } |
| 151 | |
| 152 | void Initialize(ASTContext &Context) override { |
| 153 | Ctx = &Context; |
| 154 | |
| 155 | M->setTargetTriple(Ctx->getTargetInfo().getTriple()); |
| 156 | M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString()); |
| 157 | const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion(); |
| 158 | if (!SDKVersion.empty()) |
| 159 | M->setSDKVersion(SDKVersion); |
| 160 | if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple()) |
| 161 | M->setDarwinTargetVariantTriple(TVT->getTriple()); |
| 162 | if (auto TVSDKVersion = |
| 163 | Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion()) |
| 164 | M->setDarwinTargetVariantSDKVersion(*TVSDKVersion); |
| 165 | Builder.reset(p: new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts, |
| 166 | PreprocessorOpts, CodeGenOpts, |
| 167 | *M, Diags, CoverageInfo)); |
| 168 | |
| 169 | for (auto &&Lib : CodeGenOpts.DependentLibraries) |
| 170 | Builder->AddDependentLib(Lib); |
| 171 | for (auto &&Opt : CodeGenOpts.LinkerOptions) |
| 172 | Builder->AppendLinkerOptions(Opts: Opt); |
| 173 | } |
| 174 | |
| 175 | void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { |
| 176 | if (Diags.hasErrorOccurred()) |
| 177 | return; |
| 178 | |
| 179 | Builder->HandleCXXStaticMemberVarInstantiation(VD); |
| 180 | } |
| 181 | |
| 182 | bool HandleTopLevelDecl(DeclGroupRef DG) override { |
| 183 | // Ignore interesting decls from the AST reader after IRGen is finished. |
| 184 | if (IRGenFinished) |
| 185 | return true; // We can't CodeGen more but pass to other consumers. |
| 186 | |
| 187 | // FIXME: Why not return false and abort parsing? |
| 188 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 189 | return true; |
| 190 | |
| 191 | HandlingTopLevelDeclRAII HandlingDecl(*this); |
| 192 | |
| 193 | // Make sure to emit all elements of a Decl. |
| 194 | for (auto &I : DG) |
| 195 | Builder->EmitTopLevelDecl(D: I); |
| 196 | |
| 197 | return true; |
| 198 | } |
| 199 | |
| 200 | void EmitDeferredDecls() { |
| 201 | if (DeferredInlineMemberFuncDefs.empty()) |
| 202 | return; |
| 203 | |
| 204 | // Emit any deferred inline method definitions. Note that more deferred |
| 205 | // methods may be added during this loop, since ASTConsumer callbacks |
| 206 | // can be invoked if AST inspection results in declarations being added. |
| 207 | HandlingTopLevelDeclRAII HandlingDecl(*this); |
| 208 | for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I) |
| 209 | Builder->EmitTopLevelDecl(D: DeferredInlineMemberFuncDefs[I]); |
| 210 | DeferredInlineMemberFuncDefs.clear(); |
| 211 | } |
| 212 | |
| 213 | void HandleInlineFunctionDefinition(FunctionDecl *D) override { |
| 214 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 215 | return; |
| 216 | |
| 217 | assert(D->doesThisDeclarationHaveABody()); |
| 218 | |
| 219 | // We may want to emit this definition. However, that decision might be |
| 220 | // based on computing the linkage, and we have to defer that in case we |
| 221 | // are inside of something that will change the method's final linkage, |
| 222 | // e.g. |
| 223 | // typedef struct { |
| 224 | // void bar(); |
| 225 | // void foo() { bar(); } |
| 226 | // } A; |
| 227 | DeferredInlineMemberFuncDefs.push_back(Elt: D); |
| 228 | |
| 229 | // Provide some coverage mapping even for methods that aren't emitted. |
| 230 | // Don't do this for templated classes though, as they may not be |
| 231 | // instantiable. |
| 232 | if (!D->getLexicalDeclContext()->isDependentContext()) |
| 233 | Builder->AddDeferredUnusedCoverageMapping(D); |
| 234 | } |
| 235 | |
| 236 | /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl |
| 237 | /// to (e.g. struct, union, enum, class) is completed. This allows the |
| 238 | /// client hack on the type, which can occur at any point in the file |
| 239 | /// (because these can be defined in declspecs). |
| 240 | void HandleTagDeclDefinition(TagDecl *D) override { |
| 241 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 242 | return; |
| 243 | |
| 244 | // Don't allow re-entrant calls to CodeGen triggered by PCH |
| 245 | // deserialization to emit deferred decls. |
| 246 | HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false); |
| 247 | |
| 248 | Builder->UpdateCompletedType(TD: D); |
| 249 | |
| 250 | // For MSVC compatibility, treat declarations of static data members with |
| 251 | // inline initializers as definitions. |
| 252 | assert(Ctx && "Initialize() not called" ); |
| 253 | if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) { |
| 254 | for (Decl *Member : D->decls()) { |
| 255 | if (VarDecl *VD = dyn_cast<VarDecl>(Val: Member)) { |
| 256 | if (Ctx->isMSStaticDataMemberInlineDefinition(VD) && |
| 257 | Ctx->DeclMustBeEmitted(D: VD)) { |
| 258 | Builder->EmitGlobal(D: VD); |
| 259 | } |
| 260 | } |
| 261 | } |
| 262 | } |
| 263 | // For OpenMP emit declare reduction functions, if required. |
| 264 | if (Ctx->getLangOpts().OpenMP) { |
| 265 | for (Decl *Member : D->decls()) { |
| 266 | if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Val: Member)) { |
| 267 | if (Ctx->DeclMustBeEmitted(D: DRD)) |
| 268 | Builder->EmitGlobal(D: DRD); |
| 269 | } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Val: Member)) { |
| 270 | if (Ctx->DeclMustBeEmitted(D: DMD)) |
| 271 | Builder->EmitGlobal(D: DMD); |
| 272 | } |
| 273 | } |
| 274 | } |
| 275 | } |
| 276 | |
| 277 | void HandleTagDeclRequiredDefinition(const TagDecl *D) override { |
| 278 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 279 | return; |
| 280 | |
| 281 | // Don't allow re-entrant calls to CodeGen triggered by PCH |
| 282 | // deserialization to emit deferred decls. |
| 283 | HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false); |
| 284 | |
| 285 | if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo()) |
| 286 | if (const RecordDecl *RD = dyn_cast<RecordDecl>(Val: D)) |
| 287 | DI->completeRequiredType(RD); |
| 288 | } |
| 289 | |
| 290 | void HandleTranslationUnit(ASTContext &Ctx) override { |
| 291 | // Release the Builder when there is no error. |
| 292 | if (!Diags.hasUnrecoverableErrorOccurred() && Builder) |
| 293 | Builder->Release(); |
| 294 | |
| 295 | // If there are errors before or when releasing the Builder, reset |
| 296 | // the module to stop here before invoking the backend. |
| 297 | if (Diags.hasErrorOccurred()) { |
| 298 | if (Builder) |
| 299 | Builder->clear(); |
| 300 | M.reset(); |
| 301 | } |
| 302 | |
| 303 | IRGenFinished = true; |
| 304 | } |
| 305 | |
| 306 | void AssignInheritanceModel(CXXRecordDecl *RD) override { |
| 307 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 308 | return; |
| 309 | |
| 310 | Builder->RefreshTypeCacheForClass(Class: RD); |
| 311 | } |
| 312 | |
| 313 | void CompleteTentativeDefinition(VarDecl *D) override { |
| 314 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 315 | return; |
| 316 | |
| 317 | Builder->EmitTentativeDefinition(D); |
| 318 | } |
| 319 | |
| 320 | void CompleteExternalDeclaration(DeclaratorDecl *D) override { |
| 321 | Builder->EmitExternalDeclaration(D); |
| 322 | } |
| 323 | |
| 324 | void HandleVTable(CXXRecordDecl *RD) override { |
| 325 | if (Diags.hasUnrecoverableErrorOccurred()) |
| 326 | return; |
| 327 | |
| 328 | Builder->EmitVTable(Class: RD); |
| 329 | } |
| 330 | }; |
| 331 | } |
| 332 | |
| 333 | void CodeGenerator::anchor() { } |
| 334 | |
| 335 | CodeGenModule &CodeGenerator::CGM() { |
| 336 | return static_cast<CodeGeneratorImpl*>(this)->CGM(); |
| 337 | } |
| 338 | |
| 339 | llvm::Module *CodeGenerator::GetModule() { |
| 340 | return static_cast<CodeGeneratorImpl*>(this)->GetModule(); |
| 341 | } |
| 342 | |
| 343 | std::unique_ptr<llvm::Module> CodeGenerator::ReleaseModule() { |
| 344 | return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule(); |
| 345 | } |
| 346 | |
| 347 | CGDebugInfo *CodeGenerator::getCGDebugInfo() { |
| 348 | return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo(); |
| 349 | } |
| 350 | |
| 351 | const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) { |
| 352 | return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(MangledName: name); |
| 353 | } |
| 354 | |
| 355 | llvm::StringRef CodeGenerator::GetMangledName(GlobalDecl GD) { |
| 356 | return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD); |
| 357 | } |
| 358 | |
| 359 | llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global, |
| 360 | bool isForDefinition) { |
| 361 | return static_cast<CodeGeneratorImpl*>(this) |
| 362 | ->GetAddrOfGlobal(global, isForDefinition); |
| 363 | } |
| 364 | |
| 365 | llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName, |
| 366 | llvm::LLVMContext &C) { |
| 367 | return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C); |
| 368 | } |
| 369 | |
| 370 | std::unique_ptr<CodeGenerator> |
| 371 | clang::(DiagnosticsEngine &Diags, llvm::StringRef ModuleName, |
| 372 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, |
| 373 | const HeaderSearchOptions &, |
| 374 | const PreprocessorOptions &PreprocessorOpts, |
| 375 | const CodeGenOptions &CGO, llvm::LLVMContext &C, |
| 376 | CoverageSourceInfo *CoverageInfo) { |
| 377 | return std::make_unique<CodeGeneratorImpl>(args&: Diags, args&: ModuleName, args: std::move(FS), |
| 378 | args: HeaderSearchOpts, args: PreprocessorOpts, |
| 379 | args: CGO, args&: C, args&: CoverageInfo); |
| 380 | } |
| 381 | |
| 382 | std::unique_ptr<CodeGenerator> |
| 383 | clang::CreateLLVMCodeGen(const CompilerInstance &CI, StringRef ModuleName, |
| 384 | llvm::LLVMContext &C, |
| 385 | CoverageSourceInfo *CoverageInfo) { |
| 386 | return CreateLLVMCodeGen(Diags&: CI.getDiagnostics(), ModuleName, |
| 387 | FS: CI.getVirtualFileSystemPtr(), |
| 388 | HeaderSearchOpts: CI.getHeaderSearchOpts(), PreprocessorOpts: CI.getPreprocessorOpts(), |
| 389 | CGO: CI.getCodeGenOpts(), C, CoverageInfo); |
| 390 | } |
| 391 | |
| 392 | namespace clang { |
| 393 | namespace CodeGen { |
| 394 | std::optional<std::pair<StringRef, StringRef>> |
| 395 | DemangleTrapReasonInDebugInfo(StringRef FuncName) { |
| 396 | static auto TrapRegex = |
| 397 | llvm::Regex(llvm::formatv(Fmt: "^{0}\\$(.*)\\$(.*)$" , Vals: ClangTrapPrefix).str()); |
| 398 | llvm::SmallVector<llvm::StringRef, 3> Matches; |
| 399 | std::string *ErrorPtr = nullptr; |
| 400 | #ifndef NDEBUG |
| 401 | std::string Error; |
| 402 | ErrorPtr = &Error; |
| 403 | #endif |
| 404 | if (!TrapRegex.match(String: FuncName, Matches: &Matches, Error: ErrorPtr)) { |
| 405 | assert(ErrorPtr && ErrorPtr->empty() && "Invalid regex pattern" ); |
| 406 | return {}; |
| 407 | } |
| 408 | |
| 409 | if (Matches.size() != 3) { |
| 410 | assert(0 && "Expected 3 matches from Regex::match" ); |
| 411 | return {}; |
| 412 | } |
| 413 | |
| 414 | // Returns { Trap Category, Trap Message } |
| 415 | return std::make_pair(x&: Matches[1], y&: Matches[2]); |
| 416 | } |
| 417 | } // namespace CodeGen |
| 418 | } // namespace clang |
| 419 | |