diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-24 09:15:30 +0000 | 
| commit | 9f4dbff6669c8037f3b036bcf580d14f1a4f12a5 (patch) | |
| tree | 47df2c12b57214af6c31e47404b005675b8b7ffc /lib/CodeGen/ModuleBuilder.cpp | |
| parent | f73d5f23a889b93d89ddef61ac0995df40286bb8 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/ModuleBuilder.cpp')
| -rw-r--r-- | lib/CodeGen/ModuleBuilder.cpp | 106 | 
1 files changed, 74 insertions, 32 deletions
| diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index bc7acbc39cab..c5d18d3286a7 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -12,30 +12,31 @@  //===----------------------------------------------------------------------===//  #include "clang/CodeGen/ModuleBuilder.h" -#include "CodeGenModule.h"  #include "CGDebugInfo.h" +#include "CodeGenModule.h"  #include "clang/AST/ASTContext.h"  #include "clang/AST/DeclObjC.h"  #include "clang/AST/Expr.h"  #include "clang/Basic/Diagnostic.h"  #include "clang/Basic/TargetInfo.h"  #include "clang/Frontend/CodeGenOptions.h" -#include "llvm/ADT/OwningPtr.h"  #include "llvm/ADT/StringRef.h"  #include "llvm/IR/DataLayout.h"  #include "llvm/IR/LLVMContext.h"  #include "llvm/IR/Module.h" +#include <memory>  using namespace clang;  namespace {    class CodeGeneratorImpl : public CodeGenerator {      DiagnosticsEngine &Diags; -    OwningPtr<const llvm::DataLayout> TD; +    std::unique_ptr<const llvm::DataLayout> TD;      ASTContext *Ctx;      const CodeGenOptions CodeGenOpts;  // Intentionally copied in.    protected: -    OwningPtr<llvm::Module> M; -    OwningPtr<CodeGen::CodeGenModule> Builder; +    std::unique_ptr<llvm::Module> M; +    std::unique_ptr<CodeGen::CodeGenModule> Builder; +    public:      CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName,                        const CodeGenOptions &CGO, llvm::LLVMContext& C) @@ -44,15 +45,28 @@ namespace {      virtual ~CodeGeneratorImpl() {} -    virtual llvm::Module* GetModule() { +    llvm::Module* GetModule() override {        return M.get();      } -    virtual llvm::Module* ReleaseModule() { -      return M.take(); +    const Decl *GetDeclForMangledName(StringRef MangledName) override { +      GlobalDecl Result; +      if (!Builder->lookupRepresentativeDecl(MangledName, Result)) +        return nullptr; +      const Decl *D = Result.getCanonicalDecl().getDecl(); +      if (auto FD = dyn_cast<FunctionDecl>(D)) { +        if (FD->hasBody(FD)) +          return FD; +      } else if (auto TD = dyn_cast<TagDecl>(D)) { +        if (auto Def = TD->getDefinition()) +          return Def; +      } +      return D;      } -    virtual void Initialize(ASTContext &Context) { +    llvm::Module *ReleaseModule() override { return M.release(); } + +    void Initialize(ASTContext &Context) override {        Ctx = &Context;        M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple()); @@ -65,48 +79,71 @@ namespace {          HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);      } -    virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) { +    void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {        if (Diags.hasErrorOccurred())          return;        Builder->HandleCXXStaticMemberVarInstantiation(VD);      } -    virtual bool HandleTopLevelDecl(DeclGroupRef DG) { +    bool HandleTopLevelDecl(DeclGroupRef DG) override {        if (Diags.hasErrorOccurred())          return true;        // Make sure to emit all elements of a Decl.        for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)          Builder->EmitTopLevelDecl(*I); + +      // Emit any deferred inline method definitions. +      for (CXXMethodDecl *MD : DeferredInlineMethodDefinitions) +        Builder->EmitTopLevelDecl(MD); +      DeferredInlineMethodDefinitions.clear(); +        return true;      } +    void HandleInlineMethodDefinition(CXXMethodDecl *D) override { +      if (Diags.hasErrorOccurred()) +        return; + +      assert(D->doesThisDeclarationHaveABody()); + +      // We may want to emit this definition. However, that decision might be +      // based on computing the linkage, and we have to defer that in case we +      // are inside of something that will change the method's final linkage, +      // e.g. +      //   typedef struct { +      //     void bar(); +      //     void foo() { bar(); } +      //   } A; +      DeferredInlineMethodDefinitions.push_back(D); +    } +      /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl      /// to (e.g. struct, union, enum, class) is completed. This allows the      /// client hack on the type, which can occur at any point in the file      /// (because these can be defined in declspecs). -    virtual void HandleTagDeclDefinition(TagDecl *D) { +    void HandleTagDeclDefinition(TagDecl *D) override {        if (Diags.hasErrorOccurred())          return;        Builder->UpdateCompletedType(D); -       -      // In C++, we may have member functions that need to be emitted at this  -      // point. -      if (Ctx->getLangOpts().CPlusPlus && !D->isDependentContext()) { -        for (DeclContext::decl_iterator M = D->decls_begin(),  -                                     MEnd = D->decls_end(); -             M != MEnd; ++M) -          if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(*M)) -            if (Method->doesThisDeclarationHaveABody() && -                (Method->hasAttr<UsedAttr>() ||  -                 Method->hasAttr<ConstructorAttr>())) -              Builder->EmitTopLevelDecl(Method); + +      // For MSVC compatibility, treat declarations of static data members with +      // inline initializers as definitions. +      if (Ctx->getLangOpts().MSVCCompat) { +        for (Decl *Member : D->decls()) { +          if (VarDecl *VD = dyn_cast<VarDecl>(Member)) { +            if (Ctx->isMSStaticDataMemberInlineDefinition(VD) && +                Ctx->DeclMustBeEmitted(VD)) { +              Builder->EmitGlobal(VD); +            } +          } +        }        }      } -    virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) LLVM_OVERRIDE { +    void HandleTagDeclRequiredDefinition(const TagDecl *D) override {        if (Diags.hasErrorOccurred())          return; @@ -115,8 +152,10 @@ namespace {            DI->completeRequiredType(RD);      } -    virtual void HandleTranslationUnit(ASTContext &Ctx) { +    void HandleTranslationUnit(ASTContext &Ctx) override {        if (Diags.hasErrorOccurred()) { +        if (Builder) +          Builder->clear();          M.reset();          return;        } @@ -125,32 +164,35 @@ namespace {          Builder->Release();      } -    virtual void CompleteTentativeDefinition(VarDecl *D) { +    void CompleteTentativeDefinition(VarDecl *D) override {        if (Diags.hasErrorOccurred())          return;        Builder->EmitTentativeDefinition(D);      } -    virtual void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) { +    void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override {        if (Diags.hasErrorOccurred())          return;        Builder->EmitVTable(RD, DefinitionRequired);      } -    virtual void HandleLinkerOptionPragma(llvm::StringRef Opts) { +    void HandleLinkerOptionPragma(llvm::StringRef Opts) override {        Builder->AppendLinkerOptions(Opts);      } -    virtual void HandleDetectMismatch(llvm::StringRef Name, -                                      llvm::StringRef Value) { +    void HandleDetectMismatch(llvm::StringRef Name, +                              llvm::StringRef Value) override {        Builder->AddDetectMismatch(Name, Value);      } -    virtual void HandleDependentLibrary(llvm::StringRef Lib) { +    void HandleDependentLibrary(llvm::StringRef Lib) override {        Builder->AddDependentLib(Lib);      } + +  private: +    std::vector<CXXMethodDecl *> DeferredInlineMethodDefinitions;    };  } | 
