Various improvements to the public IRGen interface.

llvm-svn: 269880
This commit is contained in:
John McCall 2016-05-18 05:21:18 +00:00
parent b3174a84b3
commit 6909fee7df
4 changed files with 146 additions and 88 deletions

View File

@ -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<FunctionProtoType> Ty,
const FunctionDecl *FD);
const CGFunctionInfo &arrangeObjCMessageSendSignature(
const ObjCMethodDecl *MD,
QualType receiverType);
const CGFunctionInfo &arrangeFreeFunctionType(CanQual<FunctionProtoType> Ty,
const FunctionDecl *FD);
const CGFunctionInfo &arrangeFreeFunctionType(
CanQual<FunctionNoProtoType> Ty);
const CGFunctionInfo &arrangeCXXMethodType(const CXXRecordDecl *RD,
const FunctionProtoType *FTP,
const CXXMethodDecl *MD);
const CGFunctionInfo &arrangeFreeFunctionCall(CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args);
const CGFunctionInfo &arrangeFreeFunctionType(CodeGenModule &CGM,
CanQual<FunctionNoProtoType> 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<CodeGenOptions> CGO;
std::unique_ptr<HeaderSearchOptions> HSO;
std::unique_ptr<PreprocessorOptions> 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<CodeGen::CodeGenModule> CGM;
};
const CGFunctionInfo &arrangeFreeFunctionCall(CodeGenModule &CGM,
CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args);
} // end namespace CodeGen
} // end namespace clang

View File

@ -15,40 +15,83 @@
#define LLVM_CLANG_CODEGEN_MODULEBUILDER_H
#include "clang/AST/ASTConsumer.h"
#include <string>
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

View File

@ -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<FunctionProtoType> Ty,
const FunctionDecl *FD) {
return CGM->getTypes().arrangeFreeFunctionType(Ty, FD);
CodeGen::arrangeFreeFunctionType(CodeGenModule &CGM,
CanQual<FunctionProtoType> Ty,
const FunctionDecl *FD) {
return CGM.getTypes().arrangeFreeFunctionType(Ty, FD);
}
const CGFunctionInfo &
CodeGenABITypes::arrangeFreeFunctionType(CanQual<FunctionNoProtoType> Ty) {
return CGM->getTypes().arrangeFreeFunctionType(Ty);
CodeGen::arrangeFreeFunctionType(CodeGenModule &CGM,
CanQual<FunctionNoProtoType> 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<CanQualType> argTypes,
FunctionType::ExtInfo info, RequiredArgs args) {
return CGM->getTypes().arrangeLLVMFunctionInfo(
const CGFunctionInfo &
CodeGen::arrangeFreeFunctionCall(CodeGenModule &CGM,
CanQualType returnType,
ArrayRef<CanQualType> argTypes,
FunctionType::ExtInfo info,
RequiredArgs args) {
return CGM.getTypes().arrangeLLVMFunctionInfo(
returnType, /*IsInstanceMethod=*/false, /*IsChainCall=*/false, argTypes,
info, {}, args);
}

View File

@ -25,7 +25,9 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include <memory>
using namespace clang;
using namespace CodeGen;
namespace {
class CodeGeneratorImpl : public CodeGenerator {
@ -65,7 +67,7 @@ namespace {
SmallVector<CXXMethodDecl *, 8> 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<CodeGeneratorImpl*>(this)->CGM();
}
llvm::Module *CodeGenerator::GetModule() {
return static_cast<CodeGeneratorImpl*>(this)->GetModule();
}
llvm::Module *CodeGenerator::ReleaseModule() {
return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
}
const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
}
llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
bool isForDefinition) {
return static_cast<CodeGeneratorImpl*>(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) {