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