diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/AST/CanonicalType.h | 21 | ||||
-rw-r--r-- | clang/include/clang/AST/Type.h | 9 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 79 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGCall.h | 17 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCGNU.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjCMac.cpp | 21 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.cpp | 8 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenTypes.h | 14 |
8 files changed, 111 insertions, 64 deletions
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h index 93e41d38d48..1f459b08ca7 100644 --- a/clang/include/clang/AST/CanonicalType.h +++ b/clang/include/clang/AST/CanonicalType.h @@ -120,6 +120,13 @@ public: return Stored.isLocalRestrictQualified(); } + /// \brief Determines if this canonical type is furthermore + /// canonical as a parameter. The parameter-canonicalization + /// process decays arrays to pointers and drops top-level qualifiers. + bool isCanonicalAsParam() const { + return Stored.isCanonicalAsParam(); + } + /// \brief Retrieve the unqualified form of this type. CanQual<T> getUnqualifiedType() const; @@ -157,6 +164,10 @@ public: /// ensure that the given type is a canonical type with the correct // (dynamic) type. static CanQual<T> CreateUnsafe(QualType Other); + + void Profile(llvm::FoldingSetNodeID &ID) const { + ID.AddPointer(getAsOpaquePtr()); + } }; template<typename T, typename U> @@ -172,6 +183,10 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) { /// \brief Represents a canonical, potentially-qualified type. typedef CanQual<Type> CanQualType; +inline CanQualType Type::getCanonicalTypeUnqualified() const { + return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); +} + inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, CanQualType T) { DB << static_cast<QualType>(T); @@ -547,18 +562,24 @@ struct CanProxyAdaptor<ExtVectorType> : public CanProxyBase<ExtVectorType> { template<> struct CanProxyAdaptor<FunctionType> : public CanProxyBase<FunctionType> { LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv) }; template<> struct CanProxyAdaptor<FunctionNoProtoType> : public CanProxyBase<FunctionNoProtoType> { LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv) }; template<> struct CanProxyAdaptor<FunctionProtoType> : public CanProxyBase<FunctionProtoType> { LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getResultType) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, getNoReturnAttr) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CallingConv, getCallConv) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs) CanQualType getArgType(unsigned i) const { return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i)); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 40e50988e6d..bd8a6bc8467 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -90,9 +90,13 @@ namespace clang { class TemplateArgument; class TemplateArgumentLoc; class TemplateArgumentListInfo; + class Type; class QualifiedNameType; struct PrintingPolicy; + template <typename> class CanQual; + typedef CanQual<Type> CanQualType; + // Provide forward declarations for all of the *Type classes #define TYPE(Class, Base) class Class##Type; #include "clang/AST/TypeNodes.def" @@ -976,7 +980,10 @@ public: /// \brief Determine the linkage of this type. virtual Linkage getLinkage() const; - QualType getCanonicalTypeInternal() const { return CanonicalType; } + QualType getCanonicalTypeInternal() const { + return CanonicalType; + } + CanQualType getCanonicalTypeUnqualified() const; // in CanonicalType.h void dump() const; static bool classof(const Type *) { return true; } }; diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3f106128325..072b1f6585f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -44,28 +44,29 @@ static unsigned ClangCallConvToLLVMCallConv(CallingConv CC) { /// Derives the 'this' type for codegen purposes, i.e. ignoring method /// qualification. /// FIXME: address space qualification? -static QualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD) { - return Context.getPointerType(Context.getTagDeclType(RD)); +static CanQualType GetThisType(ASTContext &Context, const CXXRecordDecl *RD) { + QualType RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal(); + return Context.getPointerType(CanQualType::CreateUnsafe(RecTy)); } /// Returns the canonical formal type of the given C++ method. -static const FunctionProtoType *GetFormalType(const CXXMethodDecl *MD) { - return cast<FunctionProtoType>(MD->getType()->getCanonicalTypeInternal()); +static CanQual<FunctionProtoType> GetFormalType(const CXXMethodDecl *MD) { + return MD->getType()->getCanonicalTypeUnqualified() + .getAs<FunctionProtoType>(); } /// Returns the "extra-canonicalized" return type, which discards /// qualifiers on the return type. Codegen doesn't care about them, /// and it makes ABI code a little easier to be able to assume that /// all parameter and return types are top-level unqualified. -static QualType GetReturnType(QualType RetTy) { - return RetTy->getCanonicalTypeInternal().getUnqualifiedType(); +static CanQualType GetReturnType(QualType RetTy) { + return RetTy->getCanonicalTypeUnqualified().getUnqualifiedType(); } const CGFunctionInfo & -CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) { - assert(FTNP->isCanonicalUnqualified() && "type must be canonical"); - return getFunctionInfo(GetReturnType(FTNP->getResultType()), - llvm::SmallVector<QualType, 16>(), +CodeGenTypes::getFunctionInfo(CanQual<FunctionNoProtoType> FTNP) { + return getFunctionInfo(FTNP->getResultType().getUnqualifiedType(), + llvm::SmallVector<CanQualType, 16>(), FTNP->getCallConv(), FTNP->getNoReturnAttr()); } @@ -73,21 +74,20 @@ CodeGenTypes::getFunctionInfo(const FunctionNoProtoType *FTNP) { /// \param Args - contains any initial parameters besides those /// in the formal type static const CGFunctionInfo &getFunctionInfo(CodeGenTypes &CGT, - llvm::SmallVectorImpl<QualType> &ArgTys, - const FunctionProtoType *FTP) { - assert(FTP->isCanonicalUnqualified() && "type must be canonical"); + llvm::SmallVectorImpl<CanQualType> &ArgTys, + CanQual<FunctionProtoType> FTP) { // FIXME: Kill copy. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTys.push_back(FTP->getArgType(i)); - return CGT.getFunctionInfo(GetReturnType(FTP->getResultType()), - ArgTys, + CanQualType ResTy = FTP->getResultType().getUnqualifiedType(); + return CGT.getFunctionInfo(ResTy, ArgTys, FTP->getCallConv(), FTP->getNoReturnAttr()); } const CGFunctionInfo & -CodeGenTypes::getFunctionInfo(const FunctionProtoType *FTP) { - llvm::SmallVector<QualType, 16> ArgTys; +CodeGenTypes::getFunctionInfo(CanQual<FunctionProtoType> FTP) { + llvm::SmallVector<CanQualType, 16> ArgTys; return ::getFunctionInfo(*this, ArgTys, FTP); } @@ -104,17 +104,17 @@ static CallingConv getCallingConventionForDecl(const Decl *D) { const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXRecordDecl *RD, const FunctionProtoType *FTP) { - llvm::SmallVector<QualType, 16> ArgTys; + llvm::SmallVector<CanQualType, 16> ArgTys; // Add the 'this' pointer. ArgTys.push_back(GetThisType(Context, RD)); return ::getFunctionInfo(*this, ArgTys, - cast<FunctionProtoType>(FTP->getCanonicalTypeInternal())); + FTP->getCanonicalTypeUnqualified().getAs<FunctionProtoType>()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { - llvm::SmallVector<QualType, 16> ArgTys; + llvm::SmallVector<CanQualType, 16> ArgTys; // Add the 'this' pointer unless this is a static method. if (MD->isInstance()) @@ -125,7 +125,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXMethodDecl *MD) { const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, CXXCtorType Type) { - llvm::SmallVector<QualType, 16> ArgTys; + llvm::SmallVector<CanQualType, 16> ArgTys; // Add the 'this' pointer. ArgTys.push_back(GetThisType(Context, D->getParent())); @@ -139,10 +139,10 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXConstructorDecl *D, const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const CXXDestructorDecl *D, CXXDtorType Type) { - llvm::SmallVector<QualType, 16> ArgTys; + llvm::SmallVector<CanQualType, 16> ArgTys; // Add the 'this' pointer. - ArgTys.push_back(D->getThisType(Context)); + ArgTys.push_back(GetThisType(Context, D->getParent())); // Check if we need to add a VTT parameter (which has type void **). if (Type == Dtor_Base && D->getParent()->getNumVBases() != 0) @@ -156,17 +156,18 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { if (MD->isInstance()) return getFunctionInfo(MD); - const FunctionType *FTy - = cast<FunctionType>(FD->getType()->getCanonicalTypeInternal()); + CanQualType FTy = FD->getType()->getCanonicalTypeUnqualified(); + assert(isa<FunctionType>(FTy)); if (isa<FunctionNoProtoType>(FTy)) - return getFunctionInfo(cast<FunctionNoProtoType>(FTy)); - return getFunctionInfo(cast<FunctionProtoType>(FTy)); + return getFunctionInfo(FTy.getAs<FunctionNoProtoType>()); + assert(isa<FunctionProtoType>(FTy)); + return getFunctionInfo(FTy.getAs<FunctionProtoType>()); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { - llvm::SmallVector<QualType, 16> ArgTys; - ArgTys.push_back(MD->getSelfDecl()->getType()); - ArgTys.push_back(Context.getObjCSelType()); + llvm::SmallVector<CanQualType, 16> ArgTys; + ArgTys.push_back(Context.getCanonicalParamType(MD->getSelfDecl()->getType())); + ArgTys.push_back(Context.getCanonicalParamType(Context.getObjCSelType())); // FIXME: Kill copy? for (ObjCMethodDecl::param_iterator i = MD->param_begin(), e = MD->param_end(); i != e; ++i) { @@ -196,7 +197,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, CallingConv CC, bool NoReturn) { // FIXME: Kill copy. - llvm::SmallVector<QualType, 16> ArgTys; + llvm::SmallVector<CanQualType, 16> ArgTys; for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) ArgTys.push_back(Context.getCanonicalParamType(i->second)); @@ -208,17 +209,23 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, CallingConv CC, bool NoReturn) { // FIXME: Kill copy. - llvm::SmallVector<QualType, 16> ArgTys; + llvm::SmallVector<CanQualType, 16> ArgTys; for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) ArgTys.push_back(Context.getCanonicalParamType(i->second)); return getFunctionInfo(GetReturnType(ResTy), ArgTys, CC, NoReturn); } -const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, - const llvm::SmallVectorImpl<QualType> &ArgTys, +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, + const llvm::SmallVectorImpl<CanQualType> &ArgTys, CallingConv CallConv, bool NoReturn) { +#ifndef NDEBUG + for (llvm::SmallVectorImpl<CanQualType>::const_iterator + I = ArgTys.begin(), E = ArgTys.end(); I != E; ++I) + assert(I->isCanonicalAsParam()); +#endif + unsigned CC = ClangCallConvToLLVMCallConv(CallConv); // Lookup or create unique function info. @@ -243,8 +250,8 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, CGFunctionInfo::CGFunctionInfo(unsigned _CallingConvention, bool _NoReturn, - QualType ResTy, - const llvm::SmallVectorImpl<QualType> &ArgTys) + CanQualType ResTy, + const llvm::SmallVectorImpl<CanQualType> &ArgTys) : CallingConvention(_CallingConvention), EffectiveCallingConvention(_CallingConvention), NoReturn(_NoReturn) diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 1d1b8eeab7b..3d81165b1bf 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -18,6 +18,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/Value.h" #include "clang/AST/Type.h" +#include "clang/AST/CanonicalType.h" #include "CGValue.h" @@ -57,7 +58,7 @@ namespace CodeGen { /// function definition. class CGFunctionInfo : public llvm::FoldingSetNode { struct ArgInfo { - QualType type; + CanQualType type; ABIArgInfo info; }; @@ -81,8 +82,8 @@ namespace CodeGen { CGFunctionInfo(unsigned CallingConvention, bool NoReturn, - QualType ResTy, - const llvm::SmallVectorImpl<QualType> &ArgTys); + CanQualType ResTy, + const llvm::SmallVectorImpl<CanQualType> &ArgTys); ~CGFunctionInfo() { delete[] Args; } const_arg_iterator arg_begin() const { return Args + 1; } @@ -107,7 +108,7 @@ namespace CodeGen { EffectiveCallingConvention = Value; } - QualType getReturnType() const { return Args[0].type; } + CanQualType getReturnType() const { return Args[0].type; } ABIArgInfo &getReturnInfo() { return Args[0].info; } const ABIArgInfo &getReturnInfo() const { return Args[0].info; } @@ -123,14 +124,16 @@ namespace CodeGen { static void Profile(llvm::FoldingSetNodeID &ID, unsigned CallingConvention, bool NoReturn, - QualType ResTy, + CanQualType ResTy, Iterator begin, Iterator end) { ID.AddInteger(CallingConvention); ID.AddBoolean(NoReturn); ResTy.Profile(ID); - for (; begin != end; ++begin) - begin->Profile(ID); + for (; begin != end; ++begin) { + CanQualType T = *begin; // force iterator to be over canonical types + T.Profile(ID); + } } }; diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 1d38ef9e2d2..228054e328d 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -56,7 +56,7 @@ private: const llvm::FunctionType *IMPTy; const llvm::PointerType *IdTy; const llvm::PointerType *PtrToIdTy; - QualType ASTIdTy; + CanQualType ASTIdTy; const llvm::IntegerType *IntTy; const llvm::PointerType *PtrTy; const llvm::IntegerType *LongTy; @@ -262,7 +262,7 @@ CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) PtrTy = PtrToInt8Ty; // Object type - ASTIdTy = CGM.getContext().getObjCIdType(); + ASTIdTy = CGM.getContext().getCanonicalType(CGM.getContext().getObjCIdType()); if (QualType() == ASTIdTy) { IdTy = PtrToInt8Ty; } else { @@ -1685,7 +1685,7 @@ llvm::Constant *CGObjCGNU::EnumerationMutationFunction() { CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); // void objc_enumerationMutation (id) - llvm::SmallVector<QualType,16> Params; + llvm::SmallVector<CanQualType,1> Params; Params.push_back(ASTIdTy); const llvm::FunctionType *FTy = Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 5f9c51813ad..475280b6a01 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -297,9 +297,9 @@ public: CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); // id objc_getProperty (id, SEL, ptrdiff_t, bool) - llvm::SmallVector<QualType,16> Params; - QualType IdType = Ctx.getObjCIdType(); - QualType SelType = Ctx.getObjCSelType(); + llvm::SmallVector<CanQualType,4> Params; + CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); + CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); Params.push_back(IdType); Params.push_back(SelType); Params.push_back(Ctx.LongTy); @@ -314,9 +314,9 @@ public: CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); // void objc_setProperty (id, SEL, ptrdiff_t, id, bool, bool) - llvm::SmallVector<QualType,16> Params; - QualType IdType = Ctx.getObjCIdType(); - QualType SelType = Ctx.getObjCSelType(); + llvm::SmallVector<CanQualType,6> Params; + CanQualType IdType = Ctx.getCanonicalParamType(Ctx.getObjCIdType()); + CanQualType SelType = Ctx.getCanonicalParamType(Ctx.getObjCSelType()); Params.push_back(IdType); Params.push_back(SelType); Params.push_back(Ctx.LongTy); @@ -333,8 +333,8 @@ public: CodeGen::CodeGenTypes &Types = CGM.getTypes(); ASTContext &Ctx = CGM.getContext(); // void objc_enumerationMutation (id) - llvm::SmallVector<QualType,16> Params; - Params.push_back(Ctx.getObjCIdType()); + llvm::SmallVector<CanQualType,1> Params; + Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); const llvm::FunctionType *FTy = Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, CC_Default, false), false); @@ -5093,9 +5093,8 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend( // Find the message function name. // FIXME. This is too much work to get the ABI-specific result type needed to // find the message name. - const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, - llvm::SmallVector<QualType, 16>(), - CC_Default, false); + const CGFunctionInfo &FnInfo + = Types.getFunctionInfo(ResultType, CallArgList(), CC_Default, false); llvm::Constant *Fn = 0; std::string Name("\01l_"); if (CGM.ReturnTypeUsesSret(FnInfo)) { diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 3c20934baf2..f30e03c8c9d 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -313,10 +313,14 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { // The function type can be built; call the appropriate routines to // build it. if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(&Ty)) - return GetFunctionType(getFunctionInfo(FPT), FPT->isVariadic()); + return GetFunctionType(getFunctionInfo( + CanQual<FunctionProtoType>::CreateUnsafe(QualType(FPT,0))), + FPT->isVariadic()); const FunctionNoProtoType *FNPT = cast<FunctionNoProtoType>(&Ty); - return GetFunctionType(getFunctionInfo(FNPT), true); + return GetFunctionType(getFunctionInfo( + CanQual<FunctionNoProtoType>::CreateUnsafe(QualType(FNPT,0))), + true); } case Type::ObjCInterface: { diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index f2e12caa652..b2912efb340 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -35,6 +35,7 @@ namespace llvm { namespace clang { class ABIInfo; class ASTContext; + template <typename> class CanQual; class CXXConstructorDecl; class CXXDestructorDecl; class CXXMethodDecl; @@ -48,6 +49,7 @@ namespace clang { class TagDecl; class TargetInfo; class Type; + typedef CanQual<Type> CanQualType; namespace CodeGen { class CodeGenTypes; @@ -202,8 +204,8 @@ public: return getFunctionInfo(Ty->getResultType(), Args, Ty->getCallConv(), Ty->getNoReturnAttr()); } - const CGFunctionInfo &getFunctionInfo(const FunctionProtoType *Ty); - const CGFunctionInfo &getFunctionInfo(const FunctionNoProtoType *Ty); + const CGFunctionInfo &getFunctionInfo(CanQual<FunctionProtoType> Ty); + const CGFunctionInfo &getFunctionInfo(CanQual<FunctionNoProtoType> Ty); // getFunctionInfo - Get the function info for a member function. const CGFunctionInfo &getFunctionInfo(const CXXRecordDecl *RD, @@ -220,8 +222,12 @@ public: const FunctionArgList &Args, CallingConv CC, bool NoReturn); - const CGFunctionInfo &getFunctionInfo(QualType RetTy, - const llvm::SmallVectorImpl<QualType> &ArgTys, + + /// Retrieves the ABI information for the given function signature. + /// + /// \param ArgTys - must all actually be canonical as params + const CGFunctionInfo &getFunctionInfo(CanQualType RetTy, + const llvm::SmallVectorImpl<CanQualType> &ArgTys, CallingConv CC, bool NoReturn); |