clang 23.0.0git
ModuleBuilder.cpp
Go to the documentation of this file.
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
14#include "CGCXXABI.h"
15#include "CGDebugInfo.h"
16#include "CodeGenModule.h"
18#include "clang/AST/DeclObjC.h"
19#include "clang/AST/Expr.h"
24#include "llvm/ADT/StringRef.h"
25#include "llvm/IR/DataLayout.h"
26#include "llvm/IR/LLVMContext.h"
27#include "llvm/IR/Module.h"
28#include "llvm/Support/FormatVariadic.h"
29#include "llvm/Support/VirtualFileSystem.h"
30#include <memory>
31
32using namespace clang;
33using namespace CodeGen;
34
35namespace {
36 class CodeGeneratorImpl final : public CodeGenerator {
37 DiagnosticsEngine &Diags;
38 ASTContext *Ctx;
39 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; // Only used for debug info.
40 const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
41 const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
42 const CodeGenOptions &CodeGenOpts;
43
44 unsigned HandlingTopLevelDecls;
45
46 /// Use this when emitting decls to block re-entrant decl emission. It will
47 /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl
48 /// emission must be deferred longer, like at the end of a tag definition.
49 struct HandlingTopLevelDeclRAII {
50 CodeGeneratorImpl &Self;
51 bool EmitDeferred;
52 HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
53 bool EmitDeferred = true)
54 : Self(Self), EmitDeferred(EmitDeferred) {
55 ++Self.HandlingTopLevelDecls;
56 }
57 ~HandlingTopLevelDeclRAII() {
58 unsigned Level = --Self.HandlingTopLevelDecls;
59 if (Level == 0 && EmitDeferred)
60 Self.EmitDeferredDecls();
61 }
62 };
63
64 CoverageSourceInfo *CoverageInfo;
65 std::unique_ptr<llvm::Module> M;
66 std::unique_ptr<CodeGen::CodeGenModule> Builder;
67 SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
68
69 static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
70 const CodeGenOptions &CGO) {
71 if (ModuleName == "-" && !CGO.MainFileName.empty())
72 return CGO.MainFileName;
73 return ModuleName;
74 }
75
76 public:
77 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
78 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS,
79 const HeaderSearchOptions &HSO,
80 const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
81 llvm::LLVMContext &C,
82 CoverageSourceInfo *CoverageInfo = nullptr)
83 : Diags(diags), Ctx(nullptr), FS(std::move(FS)), HeaderSearchOpts(HSO),
84 PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
85 CoverageInfo(CoverageInfo),
86 M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {
87 C.setDiscardValueNames(CGO.DiscardValueNames);
88 }
89
90 ~CodeGeneratorImpl() override {
91 // There should normally not be any leftover inline method definitions.
92 assert(DeferredInlineMemberFuncDefs.empty() ||
93 Diags.hasErrorOccurred());
94 }
95
96 CodeGenModule &CGM() {
97 return *Builder;
98 }
99
100 llvm::Module *GetModule() {
101 return M.get();
102 }
103
104 CGDebugInfo *getCGDebugInfo() {
105 return Builder->getModuleDebugInfo();
106 }
107
108 std::unique_ptr<llvm::Module> ReleaseModule() {
109 return std::exchange(M, nullptr);
110 }
111
112 const Decl *GetDeclForMangledName(StringRef MangledName) {
113 GlobalDecl Result;
114 if (!Builder->lookupRepresentativeDecl(MangledName, Result))
115 return nullptr;
116 const Decl *D = Result.getCanonicalDecl().getDecl();
117 if (auto FD = dyn_cast<FunctionDecl>(D)) {
118 if (FD->hasBody(FD))
119 return FD;
120 } else if (auto TD = dyn_cast<TagDecl>(D)) {
121 if (auto Def = TD->getDefinition())
122 return Def;
123 }
124 return D;
125 }
126
127 llvm::StringRef GetMangledName(GlobalDecl GD) {
128 return Builder->getMangledName(GD);
129 }
130
131 llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
132 return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));
133 }
134
135 llvm::Constant *GetAddrOfVTable(BaseSubobject subobject,
136 const CXXRecordDecl *decl) {
137 return Builder->getCXXABI().getVTableAddressPoint(subobject, decl);
138 }
139
140 llvm::Module *StartModule(llvm::StringRef ModuleName,
141 llvm::LLVMContext &C) {
142 assert(!M && "Replacing existing Module?");
143 M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
144
145 IRGenFinished = false;
146
147 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
148
149 assert(Ctx && "must call Initialize() before calling StartModule()");
150 Initialize(*Ctx);
151
152 if (OldBuilder)
153 OldBuilder->moveLazyEmissionStates(Builder.get());
154
155 return M.get();
156 }
157
158 void Initialize(ASTContext &Context) override {
159 Ctx = &Context;
160
161 M->setTargetTriple(Ctx->getTargetInfo().getTriple());
162 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
163 const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
164 if (!SDKVersion.empty())
165 M->setSDKVersion(SDKVersion);
166 if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
167 M->setDarwinTargetVariantTriple(TVT->getTriple());
168 if (auto TVSDKVersion =
169 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
170 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
171 Builder.reset(new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
172 PreprocessorOpts, CodeGenOpts,
173 *M, Diags, CoverageInfo));
174
175 for (auto &&Lib : CodeGenOpts.DependentLibraries)
176 Builder->AddDependentLib(Lib);
177 for (auto &&Opt : CodeGenOpts.LinkerOptions)
178 Builder->AppendLinkerOptions(Opt);
179 }
180
181 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
182 if (Diags.hasErrorOccurred())
183 return;
184
185 Builder->HandleCXXStaticMemberVarInstantiation(VD);
186 }
187
188 bool HandleTopLevelDecl(DeclGroupRef DG) override {
189 // Ignore interesting decls from the AST reader after IRGen is finished.
190 if (IRGenFinished)
191 return true; // We can't CodeGen more but pass to other consumers.
192
193 // FIXME: Why not return false and abort parsing?
194 if (Diags.hasUnrecoverableErrorOccurred())
195 return true;
196
197 HandlingTopLevelDeclRAII HandlingDecl(*this);
198
199 // Make sure to emit all elements of a Decl.
200 for (auto &I : DG)
201 Builder->EmitTopLevelDecl(I);
202
203 return true;
204 }
205
206 void EmitDeferredDecls() {
207 if (DeferredInlineMemberFuncDefs.empty())
208 return;
209
210 // Emit any deferred inline method definitions. Note that more deferred
211 // methods may be added during this loop, since ASTConsumer callbacks
212 // can be invoked if AST inspection results in declarations being added.
213 HandlingTopLevelDeclRAII HandlingDecl(*this);
214 for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
215 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
216 DeferredInlineMemberFuncDefs.clear();
217 }
218
219 void HandleInlineFunctionDefinition(FunctionDecl *D) override {
220 if (Diags.hasUnrecoverableErrorOccurred())
221 return;
222
223 assert(D->doesThisDeclarationHaveABody());
224
225 // We may want to emit this definition. However, that decision might be
226 // based on computing the linkage, and we have to defer that in case we
227 // are inside of something that will change the method's final linkage,
228 // e.g.
229 // typedef struct {
230 // void bar();
231 // void foo() { bar(); }
232 // } A;
233 DeferredInlineMemberFuncDefs.push_back(D);
234
235 // Provide some coverage mapping even for methods that aren't emitted.
236 // Don't do this for templated classes though, as they may not be
237 // instantiable. Also skip consteval methods as they are never emitted.
240 Builder->AddDeferredUnusedCoverageMapping(D);
241 }
242
243 /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
244 /// to (e.g. struct, union, enum, class) is completed. This allows the
245 /// client hack on the type, which can occur at any point in the file
246 /// (because these can be defined in declspecs).
247 void HandleTagDeclDefinition(TagDecl *D) override {
248 if (Diags.hasUnrecoverableErrorOccurred())
249 return;
250
251 // Don't allow re-entrant calls to CodeGen triggered by PCH
252 // deserialization to emit deferred decls.
253 HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
254
255 Builder->UpdateCompletedType(D);
256
257 // For MSVC compatibility, treat declarations of static data members with
258 // inline initializers as definitions.
259 assert(Ctx && "Initialize() not called");
260 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
261 for (Decl *Member : D->decls()) {
262 if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
263 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
264 Ctx->DeclMustBeEmitted(VD)) {
265 Builder->EmitGlobal(VD);
266 }
267 }
268 }
269 }
270
271 // Emit dllexport inherited constructors. These are synthesized during
272 // Sema (in checkClassLevelDLLAttribute) but have no written definition,
273 // so they must be emitted now while visiting the class definition.
274 if (auto *RD = dyn_cast<CXXRecordDecl>(D);
275 RD && RD->hasAttr<DLLExportAttr>()) {
276 for (Decl *Member : RD->decls()) {
277 if (auto *CD = dyn_cast<CXXConstructorDecl>(Member)) {
278 if (CD->getInheritedConstructor() && CD->hasAttr<DLLExportAttr>() &&
279 !CD->isDeleted())
280 Builder->EmitTopLevelDecl(CD);
281 }
282 }
283 }
284
285 // For OpenMP emit declare reduction functions, if required.
286 if (Ctx->getLangOpts().OpenMP) {
287 for (Decl *Member : D->decls()) {
288 if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
289 if (Ctx->DeclMustBeEmitted(DRD))
290 Builder->EmitGlobal(DRD);
291 } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Member)) {
292 if (Ctx->DeclMustBeEmitted(DMD))
293 Builder->EmitGlobal(DMD);
294 }
295 }
296 }
297 }
298
299 void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
300 if (Diags.hasUnrecoverableErrorOccurred())
301 return;
302
303 // Don't allow re-entrant calls to CodeGen triggered by PCH
304 // deserialization to emit deferred decls.
305 HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
306
307 if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
308 if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
309 DI->completeRequiredType(RD);
310 }
311
312 void HandleTranslationUnit(ASTContext &Ctx) override {
313 // Release the Builder when there is no error.
314 if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
315 Builder->Release();
316
317 // If there are errors before or when releasing the Builder, reset
318 // the module to stop here before invoking the backend.
319 if (Diags.hasErrorOccurred()) {
320 if (Builder)
321 Builder->clear();
322 M.reset();
323 }
324
325 IRGenFinished = true;
326 }
327
328 void AssignInheritanceModel(CXXRecordDecl *RD) override {
329 if (Diags.hasUnrecoverableErrorOccurred())
330 return;
331
332 Builder->RefreshTypeCacheForClass(RD);
333 }
334
335 void CompleteTentativeDefinition(VarDecl *D) override {
336 if (Diags.hasUnrecoverableErrorOccurred())
337 return;
338
339 Builder->EmitTentativeDefinition(D);
340 }
341
342 void CompleteExternalDeclaration(DeclaratorDecl *D) override {
343 Builder->EmitExternalDeclaration(D);
344 }
345
346 void HandleVTable(CXXRecordDecl *RD) override {
347 if (Diags.hasUnrecoverableErrorOccurred())
348 return;
349
350 Builder->EmitVTable(RD);
351 }
352 };
353}
354
355void CodeGenerator::anchor() { }
356
358 return static_cast<CodeGeneratorImpl*>(this)->CGM();
359}
360
362 return static_cast<CodeGeneratorImpl*>(this)->GetModule();
363}
364
365std::unique_ptr<llvm::Module> CodeGenerator::ReleaseModule() {
366 return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
367}
368
370 return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
371}
372
373const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
374 return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
375}
376
378 return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);
379}
380
382 bool isForDefinition) {
383 return static_cast<CodeGeneratorImpl*>(this)
384 ->GetAddrOfGlobal(global, isForDefinition);
385}
386
388 const CXXRecordDecl *decl) {
389 return static_cast<CodeGeneratorImpl *>(this)->GetAddrOfVTable(base, decl);
390}
391
392llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
393 llvm::LLVMContext &C) {
394 return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
395}
396
397std::unique_ptr<CodeGenerator>
398clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
400 const HeaderSearchOptions &HeaderSearchOpts,
401 const PreprocessorOptions &PreprocessorOpts,
402 const CodeGenOptions &CGO, llvm::LLVMContext &C,
403 CoverageSourceInfo *CoverageInfo) {
404 return std::make_unique<CodeGeneratorImpl>(Diags, ModuleName, std::move(FS),
405 HeaderSearchOpts, PreprocessorOpts,
406 CGO, C, CoverageInfo);
407}
408
409std::unique_ptr<CodeGenerator>
410clang::CreateLLVMCodeGen(const CompilerInstance &CI, StringRef ModuleName,
411 llvm::LLVMContext &C,
412 CoverageSourceInfo *CoverageInfo) {
413 return CreateLLVMCodeGen(CI.getDiagnostics(), ModuleName,
416 CI.getCodeGenOpts(), C, CoverageInfo);
417}
418
419namespace clang {
420namespace CodeGen {
421std::optional<std::pair<StringRef, StringRef>>
422DemangleTrapReasonInDebugInfo(StringRef FuncName) {
423 static const auto TrapRegex =
424 llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());
426 std::string *ErrorPtr = nullptr;
427#ifndef NDEBUG
428 std::string Error;
429 ErrorPtr = &Error;
430#endif
431 if (!TrapRegex.match(FuncName, &Matches, ErrorPtr)) {
432 assert(ErrorPtr && ErrorPtr->empty() && "Invalid regex pattern");
433 return {};
434 }
435
436 if (Matches.size() != 3) {
437 assert(0 && "Expected 3 matches from Regex::match");
438 return {};
439 }
440
441 // Returns { Trap Category, Trap Message }
442 return std::make_pair(Matches[1], Matches[2]);
443}
444} // namespace CodeGen
445} // namespace clang
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
constexpr llvm::StringRef ClangTrapPrefix
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:921
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
std::string MainFileName
The user provided name for the "main file", if non-empty.
This class gathers all debug information during compilation and is responsible for emitting to llvm g...
Definition CGDebugInfo.h:59
This class organizes the cross-function state that is used while generating LLVM code.
The primary public interface to the Clang code generator.
const Decl * GetDeclForMangledName(llvm::StringRef MangledName)
Given a mangled name, return a declaration which mangles that way which has been added to this code g...
llvm::Module * StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C)
Create a new llvm::Module after calling HandleTranslationUnit.
std::unique_ptr< llvm::Module > ReleaseModule()
Release ownership of the module to the caller.
llvm::Constant * GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition)
Return the LLVM address of the given global entity.
llvm::StringRef GetMangledName(GlobalDecl GD)
Given a global declaration, return a mangled name for this declaration which has been added to this c...
llvm::Constant * GetAddrOfVTable(BaseSubobject base, const CXXRecordDecl *decl)
Return the LLVM address of the vtable for the given base subobject.
CodeGen::CGDebugInfo * getCGDebugInfo()
Return debug info code generator.
CodeGen::CodeGenModule & CGM()
Return an opaque reference to the CodeGenModule object, which can be used in various secondary APIs.
llvm::Module * GetModule()
Return the module that this code generator is building into.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
DiagnosticsEngine & getDiagnostics() const
Get the current diagnostics engine.
IntrusiveRefCntPtr< llvm::vfs::FileSystem > getVirtualFileSystemPtr() const
HeaderSearchOptions & getHeaderSearchOpts()
PreprocessorOptions & getPreprocessorOpts()
CodeGenOptions & getCodeGenOpts()
Stores additional source code information like skipped ranges which is required by the coverage mappi...
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2390
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
Definition DeclBase.cpp:273
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:935
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:233
bool isImmediateFunction() const
Definition Decl.cpp:3317
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
Definition Decl.h:2353
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:57
HeaderSearchOptions - Helper class for storing options related to the initialization of the HeaderSea...
PreprocessorOptions - This class is used for passing the various options used in preprocessor initial...
const llvm::VersionTuple & getSDKVersion() const
Defines the clang::TargetInfo interface.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
Definition CGValue.h:146
std::optional< std::pair< StringRef, StringRef > > DemangleTrapReasonInDebugInfo(StringRef FuncName)
Demangle the artificial function name (.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
The JSON file list parser is used to communicate input to InstallAPI.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ Module
Module linkage, which indicates that the entity can be referred to from other translation units withi...
Definition Linkage.h:54
@ Result
The result type of a method or function.
Definition TypeBase.h:905
std::unique_ptr< CodeGenerator > CreateLLVMCodeGen(const CompilerInstance &CI, llvm::StringRef ModuleName, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
CreateLLVMCodeGen - Create a CodeGenerator instance.