From 6909fee7df0e6a22ea91206500a0fa48700455d7 Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 18 May 2016 05:21:18 +0000 Subject: [PATCH] Various improvements to the public IRGen interface. llvm-svn: 269880 --- clang/include/clang/CodeGen/CodeGenABITypes.h | 49 ++++------ clang/include/clang/CodeGen/ModuleBuilder.h | 91 ++++++++++++++----- clang/lib/CodeGen/CodeGenABITypes.cpp | 50 +++++----- clang/lib/CodeGen/ModuleBuilder.cpp | 44 ++++++++- 4 files changed, 146 insertions(+), 88 deletions(-) diff --git a/clang/include/clang/CodeGen/CodeGenABITypes.h b/clang/include/clang/CodeGen/CodeGenABITypes.h index 9d9504ad8e9f..e7b7435968fb 100644 --- a/clang/include/clang/CodeGen/CodeGenABITypes.h +++ b/clang/include/clang/CodeGen/CodeGenABITypes.h @@ -48,42 +48,27 @@ namespace CodeGen { class CGFunctionInfo; class CodeGenModule; -class CodeGenABITypes -{ -public: - CodeGenABITypes(ASTContext &C, llvm::Module &M, - CoverageSourceInfo *CoverageInfo = nullptr); - ~CodeGenABITypes(); +const CGFunctionInfo &arrangeObjCMessageSendSignature(CodeGenModule &CGM, + const ObjCMethodDecl *MD, + QualType receiverType); - /// These methods all forward to methods in the private implementation class - /// CodeGenTypes. +const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM, + CanQual Ty, + const FunctionDecl *FD); - const CGFunctionInfo &arrangeObjCMessageSendSignature( - const ObjCMethodDecl *MD, - QualType receiverType); - const CGFunctionInfo &arrangeFreeFunctionType(CanQual Ty, - const FunctionDecl *FD); - const CGFunctionInfo &arrangeFreeFunctionType( - CanQual Ty); - const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD, - const FunctionProtoType *FTP, - const CXXMethodDecl *MD); - const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType, - ArrayRef argTypes, - FunctionType::ExtInfo info, - RequiredArgs args); +const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM, + CanQual Ty); -private: - /// Default CodeGenOptions object used to initialize the - /// CodeGenModule and otherwise not used. More specifically, it is - /// not used in ABI type generation, so none of the options matter. - std::unique_ptr CGO; - std::unique_ptr HSO; - std::unique_ptr PPO; +const CGFunctionInfo &arrangeCXXMethodType(CodeGenModule &CGM, + const CXXRecordDecl *RD, + const FunctionProtoType *FTP, + const CXXMethodDecl *MD); - /// The CodeGenModule we use get to the CodeGenTypes object. - std::unique_ptr CGM; -}; +const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM, + CanQualType returnType, + ArrayRef argTypes, + FunctionType::ExtInfo info, + RequiredArgs args); } // end namespace CodeGen } // end namespace clang diff --git a/clang/include/clang/CodeGen/ModuleBuilder.h b/clang/include/clang/CodeGen/ModuleBuilder.h index 52497d9a9ac8..ce7696dd00cf 100644 --- a/clang/include/clang/CodeGen/ModuleBuilder.h +++ b/clang/include/clang/CodeGen/ModuleBuilder.h @@ -15,40 +15,83 @@ #define LLVM_CLANG_CODEGEN_MODULEBUILDER_H #include "clang/AST/ASTConsumer.h" -#include namespace llvm { + class Constant; class LLVMContext; class Module; } namespace clang { - class DiagnosticsEngine; - class CoverageSourceInfo; - class LangOptions; - class HeaderSearchOptions; - class PreprocessorOptions; class CodeGenOptions; + class CoverageSourceInfo; class Decl; + class DiagnosticsEngine; + class GlobalDecl; + class HeaderSearchOptions; + class LangOptions; + class PreprocessorOptions; - class CodeGenerator : public ASTConsumer { - virtual void anchor(); - public: - virtual llvm::Module* GetModule() = 0; - virtual llvm::Module* ReleaseModule() = 0; - virtual const Decl *GetDeclForMangledName(llvm::StringRef MangledName) = 0; - }; - - /// CreateLLVMCodeGen - Create a CodeGenerator instance. - /// It is the responsibility of the caller to call delete on - /// the allocated CodeGenerator instance. - CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags, - const std::string &ModuleName, - const HeaderSearchOptions &HeaderSearchOpts, - const PreprocessorOptions &PreprocessorOpts, - const CodeGenOptions &CGO, - llvm::LLVMContext& C, - CoverageSourceInfo *CoverageInfo = nullptr); +namespace CodeGen { + class CodeGenModule; } +/// The primary public interface to the Clang code generator. +/// +/// This is not really an abstract interface. +class CodeGenerator : public ASTConsumer { + virtual void anchor(); + +public: + /// Return an opaque reference to the CodeGenModule object, which can + /// be used in various secondary APIs. It is valid as long as the + /// CodeGenerator exists. + CodeGen::CodeGenModule &CGM(); + + /// Return the module that this code generator is building into. + /// + /// This may return null after HandleTranslationUnit is called; + /// this signifies that there was an error generating code. A + /// diagnostic will have been generated in this case, and the module + /// will be deleted. + /// + /// It will also return null if the module is released. + llvm::Module *GetModule(); + + /// Release ownership of the module to the caller. + /// + /// It is illegal to call methods other than GetModule on the + /// CodeGenerator after releasing its module. + llvm::Module *ReleaseModule(); + + /// Given a mangled name, return a declaration which mangles that way + /// which has been added to this code generator via a Handle method. + /// + /// This may return null if there was no matching declaration. + const Decl *GetDeclForMangledName(llvm::StringRef MangledName); + + /// Return the LLVM address of the given global entity. + /// + /// \param isForDefinition If true, the caller intends to define the + /// entity; the object returned will be an llvm::GlobalValue of + /// some sort. If false, the caller just intends to use the entity; + /// the object returned may be any sort of constant value, and the + /// code generator will schedule the entity for emission if a + /// definition has been registered with this code generator. + llvm::Constant *GetAddrOfGlobal(GlobalDecl decl, bool isForDefinition); +}; + +/// CreateLLVMCodeGen - Create a CodeGenerator instance. +/// It is the responsibility of the caller to call delete on +/// the allocated CodeGenerator instance. +CodeGenerator *CreateLLVMCodeGen(DiagnosticsEngine &Diags, + llvm::StringRef ModuleName, + const HeaderSearchOptions &HeaderSearchOpts, + const PreprocessorOptions &PreprocessorOpts, + const CodeGenOptions &CGO, + llvm::LLVMContext& C, + CoverageSourceInfo *CoverageInfo = nullptr); + +} // end namespace clang + #endif diff --git a/clang/lib/CodeGen/CodeGenABITypes.cpp b/clang/lib/CodeGen/CodeGenABITypes.cpp index 16a7db47c809..166f44f816f3 100644 --- a/clang/lib/CodeGen/CodeGenABITypes.cpp +++ b/clang/lib/CodeGen/CodeGenABITypes.cpp @@ -26,45 +26,41 @@ using namespace clang; using namespace CodeGen; -CodeGenABITypes::CodeGenABITypes(ASTContext &C, llvm::Module &M, - CoverageSourceInfo *CoverageInfo) - : CGO(new CodeGenOptions), HSO(new HeaderSearchOptions), - PPO(new PreprocessorOptions), - CGM(new CodeGen::CodeGenModule(C, *HSO, *PPO, *CGO, M, C.getDiagnostics(), - CoverageInfo)) {} - -// Explicitly out-of-line because ~CodeGenModule() is private but -// CodeGenABITypes.h is part of clang's API. -CodeGenABITypes::~CodeGenABITypes() = default; - const CGFunctionInfo & -CodeGenABITypes::arrangeObjCMessageSendSignature(const ObjCMethodDecl *MD, - QualType receiverType) { - return CGM->getTypes().arrangeObjCMessageSendSignature(MD, receiverType); +CodeGen::arrangeObjCMessageSendSignature(CodeGenModule &CGM, + const ObjCMethodDecl *MD, + QualType receiverType) { + return CGM.getTypes().arrangeObjCMessageSendSignature(MD, receiverType); } const CGFunctionInfo & -CodeGenABITypes::arrangeFreeFunctionType(CanQual Ty, - const FunctionDecl *FD) { - return CGM->getTypes().arrangeFreeFunctionType(Ty, FD); +CodeGen::arrangeFreeFunctionType(CodeGenModule &CGM, + CanQual Ty, + const FunctionDecl *FD) { + return CGM.getTypes().arrangeFreeFunctionType(Ty, FD); } const CGFunctionInfo & -CodeGenABITypes::arrangeFreeFunctionType(CanQual Ty) { - return CGM->getTypes().arrangeFreeFunctionType(Ty); +CodeGen::arrangeFreeFunctionType(CodeGenModule &CGM, + CanQual Ty) { + return CGM.getTypes().arrangeFreeFunctionType(Ty); } const CGFunctionInfo & -CodeGenABITypes::arrangeCXXMethodType(const CXXRecordDecl *RD, - const FunctionProtoType *FTP, - const CXXMethodDecl *MD) { - return CGM->getTypes().arrangeCXXMethodType(RD, FTP, MD); +CodeGen::arrangeCXXMethodType(CodeGenModule &CGM, + const CXXRecordDecl *RD, + const FunctionProtoType *FTP, + const CXXMethodDecl *MD) { + return CGM.getTypes().arrangeCXXMethodType(RD, FTP, MD); } -const CGFunctionInfo &CodeGenABITypes::arrangeFreeFunctionCall( - CanQualType returnType, ArrayRef argTypes, - FunctionType::ExtInfo info, RequiredArgs args) { - return CGM->getTypes().arrangeLLVMFunctionInfo( +const CGFunctionInfo & +CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM, + CanQualType returnType, + ArrayRef argTypes, + FunctionType::ExtInfo info, + RequiredArgs args) { + return CGM.getTypes().arrangeLLVMFunctionInfo( returnType, /*IsInstanceMethod=*/false, /*IsChainCall=*/false, argTypes, info, {}, args); } diff --git a/clang/lib/CodeGen/ModuleBuilder.cpp b/clang/lib/CodeGen/ModuleBuilder.cpp index 042712965b00..952d1627fa84 100644 --- a/clang/lib/CodeGen/ModuleBuilder.cpp +++ b/clang/lib/CodeGen/ModuleBuilder.cpp @@ -25,7 +25,9 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include + using namespace clang; +using namespace CodeGen; namespace { class CodeGeneratorImpl : public CodeGenerator { @@ -65,7 +67,7 @@ namespace { SmallVector DeferredInlineMethodDefinitions; public: - CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string &ModuleName, + CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName, const HeaderSearchOptions &HSO, const PreprocessorOptions &PPO, const CodeGenOptions &CGO, llvm::LLVMContext &C, @@ -82,11 +84,19 @@ namespace { Diags.hasErrorOccurred()); } - llvm::Module* GetModule() override { + CodeGenModule &CGM() { + return *Builder; + } + + llvm::Module *GetModule() { return M.get(); } - const Decl *GetDeclForMangledName(StringRef MangledName) override { + llvm::Module *ReleaseModule() { + return M.release(); + } + + const Decl *GetDeclForMangledName(StringRef MangledName) { GlobalDecl Result; if (!Builder->lookupRepresentativeDecl(MangledName, Result)) return nullptr; @@ -101,7 +111,9 @@ namespace { return D; } - llvm::Module *ReleaseModule() override { return M.release(); } + llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) { + return Builder->GetAddrOfGlobal(global, isForDefinition); + } void Initialize(ASTContext &Context) override { Ctx = &Context; @@ -275,8 +287,30 @@ namespace { void CodeGenerator::anchor() { } +CodeGenModule &CodeGenerator::CGM() { + return static_cast(this)->CGM(); +} + +llvm::Module *CodeGenerator::GetModule() { + return static_cast(this)->GetModule(); +} + +llvm::Module *CodeGenerator::ReleaseModule() { + return static_cast(this)->ReleaseModule(); +} + +const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) { + return static_cast(this)->GetDeclForMangledName(name); +} + +llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global, + bool isForDefinition) { + return static_cast(this) + ->GetAddrOfGlobal(global, isForDefinition); +} + CodeGenerator *clang::CreateLLVMCodeGen( - DiagnosticsEngine &Diags, const std::string &ModuleName, + DiagnosticsEngine &Diags, llvm::StringRef ModuleName, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO, llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {