зеркало из https://github.com/microsoft/clang-1.git
Cache llvm::Type through PATypeHolder.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43355 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
0a449eed1d
Коммит
30ec9972be
|
@ -69,7 +69,21 @@ CodeGenTypes::~CodeGenTypes() {
|
|||
|
||||
/// ConvertType - Convert the specified type to its LLVM form.
|
||||
const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
// FIXME: Cache these, move the CodeGenModule, expand, etc.
|
||||
// See if type is already cached.
|
||||
llvm::DenseMap<Type *, llvm::PATypeHolder *>::iterator
|
||||
I = TypeHolderMap.find(T.getTypePtr());
|
||||
if (I != TypeHolderMap.end()) {
|
||||
llvm::PATypeHolder *PAT = I->second;
|
||||
return PAT->get();
|
||||
}
|
||||
|
||||
const llvm::Type *ResultType = ConvertNewType(T);
|
||||
llvm::PATypeHolder *PAT = new llvm::PATypeHolder(ResultType);
|
||||
TypeHolderMap[T.getTypePtr()] = PAT;
|
||||
return ResultType;
|
||||
}
|
||||
|
||||
const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
|
||||
const clang::Type &Ty = *T.getCanonicalType();
|
||||
|
||||
switch (Ty.getTypeClass()) {
|
||||
|
@ -166,7 +180,10 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||
|
||||
// Struct return passes the struct byref.
|
||||
if (!ResultType->isFirstClassType() && ResultType != llvm::Type::VoidTy) {
|
||||
ArgTys.push_back(llvm::PointerType::get(ResultType));
|
||||
const llvm::Type *RType = llvm::PointerType::get(ResultType);
|
||||
QualType RTy = Context.getPointerType(FP.getResultType());
|
||||
TypeHolderMap[RTy.getTypePtr()] = new llvm::PATypeHolder(RType);
|
||||
ArgTys.push_back(RType);
|
||||
ResultType = llvm::Type::VoidTy;
|
||||
}
|
||||
|
||||
|
@ -215,6 +232,8 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
|||
// Reevaluate this when performance analyis finds tons of opaque types.
|
||||
llvm::OpaqueType *OpaqueTy = llvm::OpaqueType::get();
|
||||
RecordTypesToResolve[RD] = OpaqueTy;
|
||||
QualType Opq;
|
||||
TypeHolderMap[Opq.getTypePtr()] = new llvm::PATypeHolder(OpaqueTy);
|
||||
|
||||
// Layout fields.
|
||||
RecordOrganizer RO;
|
||||
|
@ -281,8 +300,12 @@ void CodeGenTypes::DecodeArgumentTypes(const FunctionTypeProto &FTP,
|
|||
const llvm::Type *Ty = ConvertType(FTP.getArgType(i));
|
||||
if (Ty->isFirstClassType())
|
||||
ArgTys.push_back(Ty);
|
||||
else
|
||||
ArgTys.push_back(llvm::PointerType::get(Ty));
|
||||
else {
|
||||
QualType PTy = Context.getPointerType(FTP.getArgType(i));
|
||||
const llvm::Type *PtrTy = llvm::PointerType::get(Ty);
|
||||
TypeHolderMap[PTy.getTypePtr()] = new llvm::PATypeHolder(PtrTy);
|
||||
ArgTys.push_back(PtrTy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
namespace llvm {
|
||||
class Module;
|
||||
class Type;
|
||||
class PATypeHolder;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
@ -27,6 +28,7 @@ namespace clang {
|
|||
class TagDecl;
|
||||
class TargetInfo;
|
||||
class QualType;
|
||||
class Type;
|
||||
class FunctionTypeProto;
|
||||
class FieldDecl;
|
||||
class RecordDecl;
|
||||
|
@ -77,12 +79,18 @@ class CodeGenTypes {
|
|||
/// record.
|
||||
llvm::DenseMap<const RecordDecl *, llvm::Type *> RecordTypesToResolve;
|
||||
|
||||
/// TypeHolderMap - This map keeps cache of llvm::Types (through PATypeHolder)
|
||||
/// and maps llvm::Types to corresponding clang::Type. llvm::PATypeHolder is
|
||||
/// used instead of llvm::Type because it allows us to bypass potential
|
||||
/// dangling type pointers due to type refinement on llvm side.
|
||||
llvm::DenseMap<Type *, llvm::PATypeHolder *> TypeHolderMap;
|
||||
public:
|
||||
CodeGenTypes(ASTContext &Ctx, llvm::Module &M);
|
||||
~CodeGenTypes();
|
||||
|
||||
TargetInfo &getTarget() const { return Target; }
|
||||
|
||||
const llvm::Type *ConvertNewType(QualType T);
|
||||
const llvm::Type *ConvertType(QualType T);
|
||||
void DecodeArgumentTypes(const FunctionTypeProto &FTP,
|
||||
std::vector<const llvm::Type*> &ArgTys);
|
||||
|
|
Загрузка…
Ссылка в новой задаче