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 "CGDebugInfo.h"
15#include "CodeGenModule.h"
17#include "clang/AST/DeclObjC.h"
18#include "clang/AST/Expr.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
31using namespace clang;
32using namespace CodeGen;
33
34namespace {
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 &HeaderSearchOpts; // 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 CodeGeneratorImpl(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(M, 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>(D)) {
117 if (FD->hasBody(FD))
118 return FD;
119 } else if (auto TD = dyn_cast<TagDecl>(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(global, 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(new llvm::Module(ExpandModuleName(ModuleName, 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(*Ctx);
145
146 if (OldBuilder)
147 OldBuilder->moveLazyEmissionStates(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(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(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(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(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(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.
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(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>(Member)) {
256 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
257 Ctx->DeclMustBeEmitted(VD)) {
258 Builder->EmitGlobal(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>(Member)) {
267 if (Ctx->DeclMustBeEmitted(DRD))
268 Builder->EmitGlobal(DRD);
269 } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Member)) {
270 if (Ctx->DeclMustBeEmitted(DMD))
271 Builder->EmitGlobal(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>(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(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(RD);
329 }
330 };
331}
332
333void CodeGenerator::anchor() { }
334
336 return static_cast<CodeGeneratorImpl*>(this)->CGM();
337}
338
340 return static_cast<CodeGeneratorImpl*>(this)->GetModule();
341}
342
343std::unique_ptr<llvm::Module> CodeGenerator::ReleaseModule() {
344 return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
345}
346
348 return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
349}
350
351const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
352 return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
353}
354
356 return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);
357}
358
360 bool isForDefinition) {
361 return static_cast<CodeGeneratorImpl*>(this)
362 ->GetAddrOfGlobal(global, isForDefinition);
363}
364
365llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
366 llvm::LLVMContext &C) {
367 return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
368}
369
370std::unique_ptr<CodeGenerator>
371clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
373 const HeaderSearchOptions &HeaderSearchOpts,
374 const PreprocessorOptions &PreprocessorOpts,
375 const CodeGenOptions &CGO, llvm::LLVMContext &C,
376 CoverageSourceInfo *CoverageInfo) {
377 return std::make_unique<CodeGeneratorImpl>(Diags, ModuleName, std::move(FS),
378 HeaderSearchOpts, PreprocessorOpts,
379 CGO, C, CoverageInfo);
380}
381
382std::unique_ptr<CodeGenerator>
383clang::CreateLLVMCodeGen(const CompilerInstance &CI, StringRef ModuleName,
384 llvm::LLVMContext &C,
385 CoverageSourceInfo *CoverageInfo) {
386 return CreateLLVMCodeGen(CI.getDiagnostics(), ModuleName,
389 CI.getCodeGenOpts(), C, CoverageInfo);
390}
391
392namespace clang {
393namespace CodeGen {
394std::optional<std::pair<StringRef, StringRef>>
395DemangleTrapReasonInDebugInfo(StringRef FuncName) {
396 static auto TrapRegex =
397 llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());
399 std::string *ErrorPtr = nullptr;
400#ifndef NDEBUG
401 std::string Error;
402 ErrorPtr = &Error;
403#endif
404 if (!TrapRegex.match(FuncName, &Matches, 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(Matches[1], Matches[2]);
416}
417} // namespace CodeGen
418} // namespace clang
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
constexpr llvm::StringRef ClangTrapPrefix
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:909
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...
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:2373
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Definition DeclBase.h:918
Concrete class used by the front-end to report problems and issues.
Definition Diagnostic.h:232
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
Definition Decl.h:2326
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 (.
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.