clang: lib/CodeGen/ModuleBuilder.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
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
29
30using namespace clang;
32
33namespace {
35 DiagnosticsEngine &Diags;
36 ASTContext *Ctx;
37 IntrusiveRefCntPtrllvm::vfs::FileSystem FS;
38 const HeaderSearchOptions &HeaderSearchOpts;
39 const PreprocessorOptions &PreprocessorOpts;
40 const CodeGenOptions &CodeGenOpts;
41
42 unsigned HandlingTopLevelDecls;
43
44
45
46
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_ptrllvm::Module M;
66 std::unique_ptrCodeGen::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())
75 return ModuleName;
76 }
77
78 public:
79 CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
80 IntrusiveRefCntPtrllvm::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
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) {
116 if (!Builder->lookupRepresentativeDecl(MangledName, Result))
117 return nullptr;
118 const Decl *D = Result.getCanonicalDecl().getDecl();
119 if (auto FD = dyn_cast(D)) {
120 if (FD->hasBody(FD))
121 return FD;
122 } else if (auto TD = dyn_cast(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 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());
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
186 if (IRGenFinished)
187 return true;
188
189
190 if (Diags.hasUnrecoverableErrorOccurred())
191 return true;
192
193 HandlingTopLevelDeclRAII HandlingDecl(*this);
194
195
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
207
208
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
220
221
222
223
224
225
226
227
228
229 DeferredInlineMemberFuncDefs.push_back(D);
230
231
232
233
235 Builder->AddDeferredUnusedCoverageMapping(D);
236 }
237
238
239
240
241
242 void HandleTagDeclDefinition(TagDecl *D) override {
243 if (Diags.hasUnrecoverableErrorOccurred())
244 return;
245
246
247
248 HandlingTopLevelDeclRAII HandlingDecl(*this, false);
249
250 Builder->UpdateCompletedType(D);
251
252
253
254 if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
256 if (VarDecl *VD = dyn_cast(Member)) {
257 if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
258 Ctx->DeclMustBeEmitted(VD)) {
259 Builder->EmitGlobal(VD);
260 }
261 }
262 }
263 }
264
265 if (Ctx->getLangOpts().OpenMP) {
267 if (auto *DRD = dyn_cast(Member)) {
268 if (Ctx->DeclMustBeEmitted(DRD))
269 Builder->EmitGlobal(DRD);
270 } else if (auto *DMD = dyn_cast(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
283
284 HandlingTopLevelDeclRAII HandlingDecl(*this, false);
285
286 if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
287 if (const RecordDecl *RD = dyn_cast(D))
288 DI->completeRequiredType(RD);
289 }
290
291 void HandleTranslationUnit(ASTContext &Ctx) override {
292
293 if (!Diags.hasUnrecoverableErrorOccurred() && Builder)
294 Builder->Release();
295
296
297
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
337 return static_cast<CodeGeneratorImpl*>(this)->CGM();
338}
339
341 return static_cast<CodeGeneratorImpl*>(this)->GetModule();
342}
343
345 return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
346}
347
349 return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
350}
351
355
357 return static_cast<CodeGeneratorImpl *>(this)->GetMangledName(GD);
358}
359
361 bool isForDefinition) {
362 return static_cast<CodeGeneratorImpl*>(this)
364}
365
367 llvm::LLVMContext &C) {
368 return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
369}
370
378 return new CodeGeneratorImpl(Diags, ModuleName, std::move(FS),
379 HeaderSearchOpts, PreprocessorOpts, CGO, C,
380 CoverageInfo);
381}
382
385std::optional<std::pair<StringRef, StringRef>>
387 static auto TrapRegex =
388 llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());
390 std::string *ErrorPtr = nullptr;
391#ifndef NDEBUG
392 std::string Error;
393 ErrorPtr = &Error;
394#endif
395 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
406 return std::make_pair(Matches[1], Matches[2]);
407}
408}
409}
Defines the clang::ASTContext interface.
Defines the Diagnostic-related interfaces.
constexpr llvm::StringRef ClangTrapPrefix
const TargetInfo & getTargetInfo() const
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...
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.
Definition ModuleBuilder.cpp:344
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...
Definition ModuleBuilder.cpp:352
llvm::Module * StartModule(llvm::StringRef ModuleName, llvm::LLVMContext &C)
Create a new llvm::Module after calling HandleTranslationUnit.
Definition ModuleBuilder.cpp:366
llvm::Constant * GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition)
Return the LLVM address of the given global entity.
Definition ModuleBuilder.cpp:360
llvm::StringRef GetMangledName(GlobalDecl GD)
Given a global declaration, return a mangled name for this declaration which has been added to this c...
Definition ModuleBuilder.cpp:356
CodeGen::CGDebugInfo * getCGDebugInfo()
Return debug info code generator.
Definition ModuleBuilder.cpp:348
CodeGen::CodeGenModule & CGM()
Return an opaque reference to the CodeGenModule object, which can be used in various secondary APIs.
Definition ModuleBuilder.cpp:336
llvm::Module * GetModule()
Return the module that this code generator is building into.
Definition ModuleBuilder.cpp:340
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.
Decl - This represents one declaration (or definition), e.g.
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
Concrete class used by the front-end to report problems and issues.
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
GlobalDecl - represents a global declaration.
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 ...
std::optional< std::pair< StringRef, StringRef > > DemangleTrapReasonInDebugInfo(StringRef FuncName)
Demangle the artificial function name (.
Definition ModuleBuilder.cpp:386
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.
Definition ModuleBuilder.cpp:372
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...
@ Result
The result type of a method or function.