diff options
Diffstat (limited to 'lib/CodeGen/CodeGenTypes.h')
-rw-r--r-- | lib/CodeGen/CodeGenTypes.h | 130 |
1 files changed, 64 insertions, 66 deletions
diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index ff1eb4c45b598..7c0fb8164373d 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -15,7 +15,7 @@ #define CLANG_CODEGEN_CODEGENTYPES_H #include "CGCall.h" -#include "GlobalDecl.h" +#include "clang/AST/GlobalDecl.h" #include "llvm/Module.h" #include "llvm/ADT/DenseMap.h" #include <vector> @@ -23,11 +23,10 @@ namespace llvm { class FunctionType; class Module; - class OpaqueType; - class PATypeHolder; class TargetData; class Type; class LLVMContext; + class StructType; } namespace clang { @@ -37,6 +36,7 @@ namespace clang { class CXXConstructorDecl; class CXXDestructorDecl; class CXXMethodDecl; + class CodeGenOptions; class FieldDecl; class FunctionProtoType; class ObjCInterfaceDecl; @@ -58,91 +58,83 @@ namespace CodeGen { class CodeGenTypes { ASTContext &Context; const TargetInfo &Target; - llvm::Module& TheModule; - const llvm::TargetData& TheTargetData; - const ABIInfo& TheABIInfo; + llvm::Module &TheModule; + const llvm::TargetData &TheTargetData; + const ABIInfo &TheABIInfo; CGCXXABI &TheCXXABI; - - llvm::SmallVector<std::pair<QualType, - llvm::OpaqueType *>, 8> PointersToResolve; - - llvm::DenseMap<const Type*, llvm::PATypeHolder> TagDeclTypes; - - llvm::DenseMap<const Type*, llvm::PATypeHolder> FunctionTypes; + const CodeGenOptions &CodeGenOpts; /// The opaque type map for Objective-C interfaces. All direct /// manipulation is done by the runtime interfaces, which are /// responsible for coercing to the appropriate type; these opaque /// types are never refined. - llvm::DenseMap<const ObjCInterfaceType*, const llvm::Type *> InterfaceTypes; + llvm::DenseMap<const ObjCInterfaceType*, llvm::Type *> InterfaceTypes; /// CGRecordLayouts - This maps llvm struct type with corresponding /// record layout info. llvm::DenseMap<const Type*, CGRecordLayout *> CGRecordLayouts; + /// RecordDeclTypes - This contains the LLVM IR type for any converted + /// RecordDecl. + llvm::DenseMap<const Type*, llvm::StructType *> RecordDeclTypes; + /// FunctionInfos - Hold memoized CGFunctionInfo results. llvm::FoldingSet<CGFunctionInfo> FunctionInfos; + /// RecordsBeingLaidOut - This set keeps track of records that we're currently + /// converting to an IR type. For example, when converting: + /// struct A { struct B { int x; } } when processing 'x', the 'A' and 'B' + /// types will be in this set. + llvm::SmallPtrSet<const Type*, 4> RecordsBeingLaidOut; + + llvm::SmallPtrSet<const CGFunctionInfo*, 4> FunctionsBeingProcessed; + + /// SkippedLayout - True if we didn't layout a function due to a being inside + /// a recursive struct conversion, set this to true. + bool SkippedLayout; + + llvm::SmallVector<const RecordDecl *, 8> DeferredRecords; + private: - /// TypeCache - 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<const Type *, llvm::PATypeHolder> TypeCache; - - /// ConvertNewType - Convert type T into a llvm::Type. Do not use this - /// method directly because it does not do any type caching. This method - /// is available only for ConvertType(). CovertType() is preferred - /// interface to convert type T into a llvm::Type. - const llvm::Type *ConvertNewType(QualType T); - - /// HandleLateResolvedPointers - For top-level ConvertType calls, this handles - /// pointers that are referenced but have not been converted yet. This is - /// used to handle cyclic structures properly. - void HandleLateResolvedPointers(); - - /// addRecordTypeName - Compute a name from the given record decl with an - /// optional suffix and name the given LLVM type using it. - void addRecordTypeName(const RecordDecl *RD, const llvm::Type *Ty, - llvm::StringRef suffix); + /// TypeCache - This map keeps cache of llvm::Types + /// and maps llvm::Types to corresponding clang::Type. + llvm::DenseMap<const Type *, llvm::Type *> TypeCache; public: CodeGenTypes(ASTContext &Ctx, llvm::Module &M, const llvm::TargetData &TD, - const ABIInfo &Info, CGCXXABI &CXXABI); + const ABIInfo &Info, CGCXXABI &CXXABI, + const CodeGenOptions &Opts); ~CodeGenTypes(); const llvm::TargetData &getTargetData() const { return TheTargetData; } const TargetInfo &getTarget() const { return Target; } ASTContext &getContext() const { return Context; } const ABIInfo &getABIInfo() const { return TheABIInfo; } + const CodeGenOptions &getCodeGenOpts() const { return CodeGenOpts; } CGCXXABI &getCXXABI() const { return TheCXXABI; } llvm::LLVMContext &getLLVMContext() { return TheModule.getContext(); } /// ConvertType - Convert type T into a llvm::Type. - const llvm::Type *ConvertType(QualType T, bool IsRecursive = false); - const llvm::Type *ConvertTypeRecursive(QualType T); + llvm::Type *ConvertType(QualType T); /// ConvertTypeForMem - Convert type T into a llvm::Type. This differs from /// ConvertType in that it is used to convert to the memory representation for /// a type. For example, the scalar representation for _Bool is i1, but the /// memory representation is usually i8 or i32, depending on the target. - const llvm::Type *ConvertTypeForMem(QualType T, bool IsRecursive = false); - const llvm::Type *ConvertTypeForMemRecursive(QualType T) { - return ConvertTypeForMem(T, true); - } + llvm::Type *ConvertTypeForMem(QualType T); /// GetFunctionType - Get the LLVM function type for \arg Info. - const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info, - bool IsVariadic, - bool IsRecursive = false); + llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info, + bool IsVariadic); - const llvm::FunctionType *GetFunctionType(GlobalDecl GD); + llvm::FunctionType *GetFunctionType(GlobalDecl GD); - /// VerifyFuncTypeComplete - Utility to check whether a function type can + /// isFuncTypeConvertible - Utility to check whether a function type can /// be converted to an LLVM type (i.e. doesn't depend on an incomplete tag /// type). - static const TagType *VerifyFuncTypeComplete(const Type* T); - + bool isFuncTypeConvertible(const FunctionType *FT); + bool isFuncTypeArgumentConvertible(QualType Ty); + /// GetFunctionTypeForVTable - Get the LLVM function type for use in a vtable, /// given a CXXMethodDecl. If the method to has an incomplete return type, /// and/or incomplete argument types, this will return the opaque type. @@ -150,11 +142,6 @@ public: const CGRecordLayout &getCGRecordLayout(const RecordDecl*); - /// addBaseSubobjectTypeName - Add a type name for the base subobject of the - /// given record layout. - void addBaseSubobjectTypeName(const CXXRecordDecl *RD, - const CGRecordLayout &layout); - /// UpdateCompletedType - When we find the full definition for a TagDecl, /// replace the 'opaque' type we previously made for it if applicable. void UpdateCompletedType(const TagDecl *TD); @@ -180,10 +167,8 @@ public: Ty->getExtInfo()); } - const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty, - bool IsRecursive = false); - const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty, - bool IsRecursive = false); + const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty); + const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty); /// getFunctionInfo - Get the function info for a member function of /// the given type. This is used for calls through member function @@ -206,23 +191,27 @@ public: /// \param ArgTys - must all actually be canonical as params const CGFunctionInfo &getFunctionInfo(CanQualType RetTy, const llvm::SmallVectorImpl<CanQualType> &ArgTys, - const FunctionType::ExtInfo &Info, - bool IsRecursive = false); + const FunctionType::ExtInfo &Info); /// \brief Compute a new LLVM record layout object for the given record. - CGRecordLayout *ComputeRecordLayout(const RecordDecl *D); + CGRecordLayout *ComputeRecordLayout(const RecordDecl *D, + llvm::StructType *Ty); + + /// addRecordTypeName - Compute a name from the given record decl with an + /// optional suffix and name the given LLVM type using it. + void addRecordTypeName(const RecordDecl *RD, llvm::StructType *Ty, + llvm::StringRef suffix); + public: // These are internal details of CGT that shouldn't be used externally. - /// ConvertTagDeclType - Lay out a tagged decl type like struct or union or - /// enum. - const llvm::Type *ConvertTagDeclType(const TagDecl *TD); + /// ConvertRecordDeclType - Lay out a tagged decl type like struct or union. + llvm::StructType *ConvertRecordDeclType(const RecordDecl *TD); /// GetExpandedTypes - Expand the type \arg Ty into the LLVM /// argument types it would be passed as on the provided vector \arg /// ArgTys. See ABIArgInfo::Expand. void GetExpandedTypes(QualType type, - llvm::SmallVectorImpl<const llvm::Type*> &expanded, - bool isRecursive); + llvm::SmallVectorImpl<llvm::Type*> &expanded); /// IsZeroInitializable - Return whether a type can be /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer. @@ -231,6 +220,15 @@ public: // These are internal details of CGT that shouldn't be used externally. /// IsZeroInitializable - Return whether a record type can be /// zero-initialized (in the C++ sense) with an LLVM zeroinitializer. bool isZeroInitializable(const CXXRecordDecl *RD); + + bool isRecordLayoutComplete(const Type *Ty) const; + bool noRecordsBeingLaidOut() const { + return RecordsBeingLaidOut.empty(); + } + bool isRecordBeingLaidOut(const Type *Ty) const { + return RecordsBeingLaidOut.count(Ty); + } + }; } // end namespace CodeGen |