clang 22.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"
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
29using namespace clang;
30using namespace CodeGen;
31
32namespace {
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 &HeaderSearchOpts; // 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 CodeGeneratorImpl(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>(D)) {
119 if (FD->hasBody(FD))
120 return FD;
121 } else if (auto TD = dyn_cast<TagDecl>(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(global, 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(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
140
141 IRGenFinished = false;
142
143 std::unique_ptr<CodeGenModule> OldBuilder = std::move(Builder);
144
145 Initialize(*Ctx);
146
147 if (OldBuilder)
148 OldBuilder->moveLazyEmissionStates(Builder.get());
149
150 return M.get();
151 }
152
153 void Initialize(ASTContext &Context) override {
154 Ctx = &Context;
155
156 M->setTargetTriple(Ctx->getTargetInfo().getTriple());
157 M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
158 const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
159 if (!SDKVersion.empty())
160 M->setSDKVersion(SDKVersion);
161 if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
162 M->setDarwinTargetVariantTriple(TVT->getTriple());
163 if (auto TVSDKVersion =
164 Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
165 M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
166 Builder.reset(new CodeGen::CodeGenModule(Context, FS, HeaderSearchOpts,
167 PreprocessorOpts, CodeGenOpts,
168 *M, Diags, CoverageInfo));
169
170 for (auto &&Lib : CodeGenOpts.DependentLibraries)
171 Builder->AddDependentLib(Lib);
172 for (auto &&Opt : CodeGenOpts.LinkerOptions)
173 Builder->AppendLinkerOptions(Opt);
174 }
175
176 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
177 if (Diags.hasErrorOccurred())
178 return;
179
180 Builder->HandleCXXStaticMemberVarInstantiation(VD);
181 }
182
183 bool HandleTopLevelDecl(DeclGroupRef DG) override {
184 // Ignore interesting decls from the AST reader after IRGen is finished.
185 if (IRGenFinished)
186 return true; // We can't CodeGen more but pass to other consumers.
187
188 // FIXME: Why not return false and abort parsing?
189 if (Diags.hasUnrecoverableErrorOccurred())
190 return true;
191
192 HandlingTopLevelDeclRAII HandlingDecl(*this);
193
194 // Make sure to emit all elements of a Decl.
195 for (auto &I : DG)
196 Builder->EmitTopLevelDecl(I);
197
198 return true;
199 }
200
201 void EmitDeferredDecls() {
202 if (DeferredInlineMemberFuncDefs.empty())
203 return;
204
205 // Emit any deferred inline method definitions. Note that more deferred
206 // methods may be added during this loop, since ASTConsumer callbacks
207 // can be invoked if AST inspection results in declarations being added.
208 HandlingTopLevelDeclRAII HandlingDecl(*this);
209 for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
210 Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
211 DeferredInlineMemberFuncDefs.clear();
212 }
213
214 void HandleInlineFunctionDefinition(FunctionDecl *D) override {
215 if (Diags.hasUnrecoverableErrorOccurred())
216 return;
217
218 assert(D->doesThisDeclarationHaveABody());
219
220 // We may want to emit this definition. However, that decision might be
221 // based on computing the linkage, and we have to defer that in case we
222 // are inside of something that will change the method's final linkage,
223 // e.g.
224 // typedef struct {
225 // void bar();
226 // void foo() { bar(); }
227 // } A;
228 DeferredInlineMemberFuncDefs.push_back(D);
229
230 // Provide some coverage mapping even for methods that aren't emitted.
231 // Don't do this for templated classes though, as they may not be
232 // instantiable.
234 Builder->AddDeferredUnusedCoverageMapping(D);
235 }
236
237 /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
238 /// to (e.g. struct, union, enum, class) is completed. This allows the
239 /// client hack on the type, which can occur at any point in the file
240 /// (because these can be defined in declspecs).
241 void HandleTagDeclDefinition(TagDecl *D) override {
242 if (Diags.hasUnrecoverableErrorOccurred())
243 return;
244
245 // Don't allow re-entrant calls to CodeGen triggered by PCH
246 // deserialization to emit deferred decls.
247 HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
248
249 Builder->UpdateCompletedType(D);
250
251 // For MSVC compatibility, treat declarations of static data members with
252 // inline initializers as definitions.
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
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
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 new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
378 HeaderSearchOpts, PreprocessorOpts, CGO, C,
379 CoverageInfo);
380}
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
const TargetInfo & getTargetInfo() const
Definition ASTContext.h:891
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.
llvm::Module * ReleaseModule()
Release ownership of the module to the caller.
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.
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.
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:145
The JSON file list parser is used to communicate input to InstallAPI.
CodeGenerator * CreateLLVMCodeGen(DiagnosticsEngine &Diags, llvm::StringRef ModuleName, IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo=nullptr)
CreateLLVMCodeGen - Create a CodeGenerator instance.
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