1193326Sed//===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// This builds an AST and converts it to LLVM Code.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/CodeGen/ModuleBuilder.h"
15193326Sed#include "CodeGenModule.h"
16193326Sed#include "clang/AST/ASTContext.h"
17193326Sed#include "clang/AST/DeclObjC.h"
18193326Sed#include "clang/AST/Expr.h"
19193326Sed#include "clang/Basic/Diagnostic.h"
20193326Sed#include "clang/Basic/TargetInfo.h"
21249423Sdim#include "clang/Frontend/CodeGenOptions.h"
22193326Sed#include "llvm/ADT/OwningPtr.h"
23249423Sdim#include "llvm/IR/DataLayout.h"
24249423Sdim#include "llvm/IR/LLVMContext.h"
25249423Sdim#include "llvm/IR/Module.h"
26193326Sedusing namespace clang;
27193326Sed
28193326Sednamespace {
29199990Srdivacky  class CodeGeneratorImpl : public CodeGenerator {
30226633Sdim    DiagnosticsEngine &Diags;
31243830Sdim    OwningPtr<const llvm::DataLayout> TD;
32193326Sed    ASTContext *Ctx;
33199482Srdivacky    const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
34193326Sed  protected:
35234353Sdim    OwningPtr<llvm::Module> M;
36234353Sdim    OwningPtr<CodeGen::CodeGenModule> Builder;
37193326Sed  public:
38226633Sdim    CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName,
39251662Sdim                      const CodeGenOptions &CGO, llvm::LLVMContext& C)
40251662Sdim      : Diags(diags), CodeGenOpts(CGO),
41249423Sdim        M(new llvm::Module(ModuleName, C)) {}
42198092Srdivacky
43193326Sed    virtual ~CodeGeneratorImpl() {}
44198092Srdivacky
45193326Sed    virtual llvm::Module* GetModule() {
46193326Sed      return M.get();
47193326Sed    }
48198092Srdivacky
49193326Sed    virtual llvm::Module* ReleaseModule() {
50193326Sed      return M.take();
51193326Sed    }
52198092Srdivacky
53193326Sed    virtual void Initialize(ASTContext &Context) {
54193326Sed      Ctx = &Context;
55198092Srdivacky
56226633Sdim      M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
57226633Sdim      M->setDataLayout(Ctx->getTargetInfo().getTargetDescription());
58243830Sdim      TD.reset(new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription()));
59251662Sdim      Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD,
60251662Sdim                                               Diags));
61193326Sed    }
62198092Srdivacky
63234353Sdim    virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) {
64234353Sdim      Builder->HandleCXXStaticMemberVarInstantiation(VD);
65234353Sdim    }
66234353Sdim
67234353Sdim    virtual bool HandleTopLevelDecl(DeclGroupRef DG) {
68193326Sed      // Make sure to emit all elements of a Decl.
69193326Sed      for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
70193326Sed        Builder->EmitTopLevelDecl(*I);
71234353Sdim      return true;
72193326Sed    }
73193326Sed
74193326Sed    /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
75193326Sed    /// to (e.g. struct, union, enum, class) is completed. This allows the
76193326Sed    /// client hack on the type, which can occur at any point in the file
77193326Sed    /// (because these can be defined in declspecs).
78193326Sed    virtual void HandleTagDeclDefinition(TagDecl *D) {
79193326Sed      Builder->UpdateCompletedType(D);
80218893Sdim
81218893Sdim      // In C++, we may have member functions that need to be emitted at this
82218893Sdim      // point.
83234353Sdim      if (Ctx->getLangOpts().CPlusPlus && !D->isDependentContext()) {
84218893Sdim        for (DeclContext::decl_iterator M = D->decls_begin(),
85218893Sdim                                     MEnd = D->decls_end();
86218893Sdim             M != MEnd; ++M)
87218893Sdim          if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*M))
88223017Sdim            if (Method->doesThisDeclarationHaveABody() &&
89218893Sdim                (Method->hasAttr<UsedAttr>() ||
90218893Sdim                 Method->hasAttr<ConstructorAttr>()))
91218893Sdim              Builder->EmitTopLevelDecl(Method);
92218893Sdim      }
93193326Sed    }
94193326Sed
95193326Sed    virtual void HandleTranslationUnit(ASTContext &Ctx) {
96193326Sed      if (Diags.hasErrorOccurred()) {
97193326Sed        M.reset();
98193326Sed        return;
99193326Sed      }
100193326Sed
101193326Sed      if (Builder)
102193326Sed        Builder->Release();
103201361Srdivacky    }
104193326Sed
105193326Sed    virtual void CompleteTentativeDefinition(VarDecl *D) {
106193326Sed      if (Diags.hasErrorOccurred())
107193326Sed        return;
108193326Sed
109193326Sed      Builder->EmitTentativeDefinition(D);
110193326Sed    }
111208600Srdivacky
112208600Srdivacky    virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) {
113208600Srdivacky      if (Diags.hasErrorOccurred())
114208600Srdivacky        return;
115208600Srdivacky
116208600Srdivacky      Builder->EmitVTable(RD, DefinitionRequired);
117208600Srdivacky    }
118193326Sed  };
119193326Sed}
120193326Sed
121234353Sdimvoid CodeGenerator::anchor() { }
122234353Sdim
123226633SdimCodeGenerator *clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags,
124193326Sed                                        const std::string& ModuleName,
125199482Srdivacky                                        const CodeGenOptions &CGO,
126251662Sdim                                        const TargetOptions &/*TO*/,
127195341Sed                                        llvm::LLVMContext& C) {
128251662Sdim  return new CodeGeneratorImpl(Diags, ModuleName, CGO, C);
129193326Sed}
130