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