xref: /llvm-project/clang/lib/CodeGen/ModuleBuilder.cpp (revision 94cfc603d1896f0f76e7ede712280f526bc88602)
1 //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This builds an AST and converts it to LLVM Code.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "clang/CodeGen/ModuleBuilder.h"
15 #include "CGDebugInfo.h"
16 #include "CodeGenModule.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/Basic/CodeGenOptions.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "clang/Basic/TargetInfo.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 
28 #include <memory>
29 
30 using namespace clang;
31 
32 namespace {
33   class CodeGeneratorImpl : public CodeGenerator {
34     DiagnosticsEngine &Diags;
35     ASTContext *Ctx;
36     const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
37     const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
38     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
39 
40     unsigned HandlingTopLevelDecls;
41     struct HandlingTopLevelDeclRAII {
42       CodeGeneratorImpl &Self;
43       HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) {
44         ++Self.HandlingTopLevelDecls;
45       }
46       ~HandlingTopLevelDeclRAII() {
47         if (--Self.HandlingTopLevelDecls == 0)
48           Self.EmitDeferredDecls();
49       }
50     };
51 
52     CoverageSourceInfo *CoverageInfo;
53 
54   protected:
55     std::unique_ptr<llvm::Module> M;
56     std::unique_ptr<CodeGen::CodeGenModule> Builder;
57 
58   private:
59     SmallVector<CXXMethodDecl *, 8> DeferredInlineMethodDefinitions;
60 
61   public:
62     CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string &ModuleName,
63                       const HeaderSearchOptions &HSO,
64                       const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
65                       llvm::LLVMContext &C,
66                       CoverageSourceInfo *CoverageInfo = nullptr)
67         : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
68           PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
69           CoverageInfo(CoverageInfo), M(new llvm::Module(ModuleName, C)) {
70       C.setDiscardValueNames(CGO.DiscardValueNames);
71     }
72 
73     ~CodeGeneratorImpl() override {
74       // There should normally not be any leftover inline method definitions.
75       assert(DeferredInlineMethodDefinitions.empty() ||
76              Diags.hasErrorOccurred());
77     }
78 
79     llvm::Module* GetModule() override {
80       return M.get();
81     }
82 
83     const Decl *GetDeclForMangledName(StringRef MangledName) override {
84       GlobalDecl Result;
85       if (!Builder->lookupRepresentativeDecl(MangledName, Result))
86         return nullptr;
87       const Decl *D = Result.getCanonicalDecl().getDecl();
88       if (auto FD = dyn_cast<FunctionDecl>(D)) {
89         if (FD->hasBody(FD))
90           return FD;
91       } else if (auto TD = dyn_cast<TagDecl>(D)) {
92         if (auto Def = TD->getDefinition())
93           return Def;
94       }
95       return D;
96     }
97 
98     llvm::Module *ReleaseModule() override { return M.release(); }
99 
100     void Initialize(ASTContext &Context) override {
101       Ctx = &Context;
102 
103       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
104       M->setDataLayout(Ctx->getTargetInfo().getDataLayout());
105       Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
106                                                PreprocessorOpts, CodeGenOpts,
107                                                *M, Diags, CoverageInfo));
108 
109       for (auto &&Lib : CodeGenOpts.DependentLibraries)
110         Builder->AddDependentLib(Lib);
111       for (auto &&Opt : CodeGenOpts.LinkerOptions)
112         Builder->AppendLinkerOptions(Opt);
113     }
114 
115     void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
116       if (Diags.hasErrorOccurred())
117         return;
118 
119       Builder->HandleCXXStaticMemberVarInstantiation(VD);
120     }
121 
122     bool HandleTopLevelDecl(DeclGroupRef DG) override {
123       if (Diags.hasErrorOccurred())
124         return true;
125 
126       HandlingTopLevelDeclRAII HandlingDecl(*this);
127 
128       // Make sure to emit all elements of a Decl.
129       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
130         Builder->EmitTopLevelDecl(*I);
131 
132       return true;
133     }
134 
135     void EmitDeferredDecls() {
136       if (DeferredInlineMethodDefinitions.empty())
137         return;
138 
139       // Emit any deferred inline method definitions. Note that more deferred
140       // methods may be added during this loop, since ASTConsumer callbacks
141       // can be invoked if AST inspection results in declarations being added.
142       HandlingTopLevelDeclRAII HandlingDecl(*this);
143       for (unsigned I = 0; I != DeferredInlineMethodDefinitions.size(); ++I)
144         Builder->EmitTopLevelDecl(DeferredInlineMethodDefinitions[I]);
145       DeferredInlineMethodDefinitions.clear();
146     }
147 
148     void HandleInlineFunctionDefinition(FunctionDecl *D) override {
149       if (Diags.hasErrorOccurred())
150         return;
151 
152       assert(D->doesThisDeclarationHaveABody());
153 
154       // Handle friend functions.
155       if (D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) {
156         if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()
157             && !D->getLexicalDeclContext()->isDependentContext())
158           Builder->EmitTopLevelDecl(D);
159         return;
160       }
161 
162       // Otherwise, must be a method.
163       auto MD = cast<CXXMethodDecl>(D);
164 
165       // We may want to emit this definition. However, that decision might be
166       // based on computing the linkage, and we have to defer that in case we
167       // are inside of something that will change the method's final linkage,
168       // e.g.
169       //   typedef struct {
170       //     void bar();
171       //     void foo() { bar(); }
172       //   } A;
173       DeferredInlineMethodDefinitions.push_back(MD);
174 
175       // Provide some coverage mapping even for methods that aren't emitted.
176       // Don't do this for templated classes though, as they may not be
177       // instantiable.
178       if (!MD->getParent()->getDescribedClassTemplate())
179         Builder->AddDeferredUnusedCoverageMapping(MD);
180     }
181 
182     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
183     /// to (e.g. struct, union, enum, class) is completed. This allows the
184     /// client hack on the type, which can occur at any point in the file
185     /// (because these can be defined in declspecs).
186     void HandleTagDeclDefinition(TagDecl *D) override {
187       if (Diags.hasErrorOccurred())
188         return;
189 
190       Builder->UpdateCompletedType(D);
191 
192       // For MSVC compatibility, treat declarations of static data members with
193       // inline initializers as definitions.
194       if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
195         for (Decl *Member : D->decls()) {
196           if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
197             if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
198                 Ctx->DeclMustBeEmitted(VD)) {
199               Builder->EmitGlobal(VD);
200             }
201           }
202         }
203       }
204       // For OpenMP emit declare reduction functions, if required.
205       if (Ctx->getLangOpts().OpenMP) {
206         for (Decl *Member : D->decls()) {
207           if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
208             if (Ctx->DeclMustBeEmitted(DRD))
209               Builder->EmitGlobal(DRD);
210           }
211         }
212       }
213     }
214 
215     void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
216       if (Diags.hasErrorOccurred())
217         return;
218 
219       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
220         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
221           DI->completeRequiredType(RD);
222     }
223 
224     void HandleTranslationUnit(ASTContext &Ctx) override {
225       // Release the Builder when there is no error.
226       if (!Diags.hasErrorOccurred() && Builder)
227         Builder->Release();
228 
229       // If there are errors before or when releasing the Builder, reset
230       // the module to stop here before invoking the backend.
231       if (Diags.hasErrorOccurred()) {
232         if (Builder)
233           Builder->clear();
234         M.reset();
235         return;
236       }
237     }
238 
239     void AssignInheritanceModel(CXXRecordDecl *RD) override {
240       if (Diags.hasErrorOccurred())
241         return;
242 
243       Builder->RefreshTypeCacheForClass(RD);
244     }
245 
246     void CompleteTentativeDefinition(VarDecl *D) override {
247       if (Diags.hasErrorOccurred())
248         return;
249 
250       Builder->EmitTentativeDefinition(D);
251     }
252 
253     void HandleVTable(CXXRecordDecl *RD) override {
254       if (Diags.hasErrorOccurred())
255         return;
256 
257       Builder->EmitVTable(RD);
258     }
259   };
260 }
261 
262 void CodeGenerator::anchor() { }
263 
264 CodeGenerator *clang::CreateLLVMCodeGen(
265     DiagnosticsEngine &Diags, const std::string &ModuleName,
266     const HeaderSearchOptions &HeaderSearchOpts,
267     const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,
268     llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {
269   return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts,
270                                PreprocessorOpts, CGO, C, CoverageInfo);
271 }
272