From: Rafael Espindola Date: Tue, 30 Mar 2010 20:24:48 +0000 (+0000) Subject: the big refactoring bits of PR3782. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=264ba48dc98f3f843935a485d5b086f7e0fdc4f1;p=clang the big refactoring bits of PR3782. This introduces FunctionType::ExtInfo to hold the calling convention and the noreturn attribute. The next patch will extend it to include the regparm attribute and fix the bug. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99920 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 22aec7f5be..ae8125511b 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -564,10 +564,11 @@ public: /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// - QualType getFunctionNoProtoType(QualType ResultTy, bool NoReturn, - CallingConv CallConv); + QualType getFunctionNoProtoType(QualType ResultTy, + const FunctionType::ExtInfo &Info); + QualType getFunctionNoProtoType(QualType ResultTy) { - return getFunctionNoProtoType(ResultTy, false, CC_Default); + return getFunctionNoProtoType(ResultTy, FunctionType::ExtInfo()); } /// getFunctionType - Return a normal function type with a typed argument @@ -577,8 +578,7 @@ public: unsigned TypeQuals, bool hasExceptionSpec, bool hasAnyExceptionSpec, unsigned NumExs, const QualType *ExArray, - bool NoReturn, - CallingConv CallConv); + const FunctionType::ExtInfo &Info); /// getTypeDeclType - Return the unique reference to the type for /// the specified type declaration. diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index f4cccf3511..b2a87f6170 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -564,24 +564,21 @@ struct CanProxyAdaptor : public CanProxyBase { template<> struct CanProxyAdaptor : public CanProxyBase { 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(FunctionType::ExtInfo, getExtInfo) }; template<> struct CanProxyAdaptor : public CanProxyBase { 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(FunctionType::ExtInfo, getExtInfo) }; template<> struct CanProxyAdaptor : public CanProxyBase { 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(FunctionType::ExtInfo, getExtInfo) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getNumArgs) CanQualType getArgType(unsigned i) const { return CanQualType::CreateUnsafe(this->getTypePtr()->getArgType(i)); diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index afab9679e6..227085aa0e 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -1095,8 +1095,8 @@ public: : Expr(CXXPseudoDestructorExprClass, Context.getPointerType(Context.getFunctionType(Context.VoidTy, 0, 0, false, 0, false, - false, 0, 0, false, - CC_Default)), + false, 0, 0, + FunctionType::ExtInfo())), /*isTypeDependent=*/(Base->isTypeDependent() || (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index eee1183495..c0bc54a06a 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -939,14 +939,6 @@ public: /// pointer, this returns the respective pointee. QualType getPointeeType() const; - /// getNoReturnAttr - Returns true if the type has the noreturn attribute, - /// false otherwise. - bool getNoReturnAttr() const; - - /// getCallConv - Returns the calling convention of the type if the type - /// is a function type, CC_Default otherwise. - CallingConv getCallConv() const; - /// getUnqualifiedDesugaredType() - Return the specified type with /// any "sugar" removed from the type, removing any typedefs, /// typeofs, etc., as well as any qualifiers. @@ -1753,13 +1745,60 @@ class FunctionType : public Type { // The type returned by the function. QualType ResultType; + + public: + // This class is used for passing arround the information needed to + // construct a call. It is not actually used for storage, just for + // factoring together common arguments. + class ExtInfo { + public: + // Constructor with no defaults. Use this when you know that you + // have all the elements (when reading a PCH file for example). + ExtInfo(bool noReturn, CallingConv cc) : + NoReturn(noReturn), CC(cc) {} + + // Constructor with all defaults. Use when for example creating a + // function know to use defaults. + ExtInfo() : NoReturn(false), CC(CC_Default) {} + + bool getNoReturn() const { return NoReturn; } + CallingConv getCC() const { return CC; } + + bool operator==(const ExtInfo &Other) const { + return getNoReturn() == Other.getNoReturn() && + getCC() == Other.getCC(); + } + bool operator!=(const ExtInfo &Other) const { + return !(*this == Other); + } + + // Note that we don't have setters. That is by design, use + // the following with methods instead of mutating these objects. + + ExtInfo withNoReturn(bool noReturn) const { + return ExtInfo(noReturn, getCC()); + } + + ExtInfo withCallingConv(CallingConv cc) const { + return ExtInfo(getNoReturn(), cc); + } + + private: + // True if we have __attribute__((noreturn)) + bool NoReturn; + // The calling convention as specified via + // __attribute__((cdecl|stdcall||fastcall)) + CallingConv CC; + }; + protected: FunctionType(TypeClass tc, QualType res, bool SubclassInfo, unsigned typeQuals, QualType Canonical, bool Dependent, - bool noReturn, CallingConv callConv) + const ExtInfo &Info) : Type(tc, Canonical, Dependent), - SubClassData(SubclassInfo), TypeQuals(typeQuals), NoReturn(noReturn), - CallConv(callConv), ResultType(res) {} + SubClassData(SubclassInfo), TypeQuals(typeQuals), + NoReturn(Info.getNoReturn()), + CallConv(Info.getCC()), ResultType(res) {} bool getSubClassData() const { return SubClassData; } unsigned getTypeQuals() const { return TypeQuals; } public: @@ -1767,6 +1806,9 @@ public: QualType getResultType() const { return ResultType; } bool getNoReturnAttr() const { return NoReturn; } CallingConv getCallConv() const { return (CallingConv)CallConv; } + ExtInfo getExtInfo() const { + return ExtInfo(NoReturn, (CallingConv)CallConv); + } static llvm::StringRef getNameForCallConv(CallingConv CC); @@ -1781,9 +1823,9 @@ public: /// no information available about its arguments. class FunctionNoProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionNoProtoType(QualType Result, QualType Canonical, - bool NoReturn = false, CallingConv CallConv = CC_Default) + const ExtInfo &Info) : FunctionType(FunctionNoProto, Result, false, 0, Canonical, - /*Dependent=*/false, NoReturn, CallConv) {} + /*Dependent=*/false, Info) {} friend class ASTContext; // ASTContext creates these. public: // No additional state past what FunctionType provides. @@ -1792,12 +1834,12 @@ public: QualType desugar() const { return QualType(this, 0); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getResultType(), getNoReturnAttr(), getCallConv()); + Profile(ID, getResultType(), getExtInfo()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType ResultType, - bool NoReturn, CallingConv CallConv) { - ID.AddInteger(CallConv); - ID.AddInteger(NoReturn); + const ExtInfo &Info) { + ID.AddInteger(Info.getCC()); + ID.AddInteger(Info.getNoReturn()); ID.AddPointer(ResultType.getAsOpaquePtr()); } @@ -1828,12 +1870,12 @@ class FunctionProtoType : public FunctionType, public llvm::FoldingSetNode { FunctionProtoType(QualType Result, const QualType *ArgArray, unsigned numArgs, bool isVariadic, unsigned typeQuals, bool hasExs, bool hasAnyExs, const QualType *ExArray, - unsigned numExs, QualType Canonical, bool NoReturn, - CallingConv CallConv) + unsigned numExs, QualType Canonical, + const ExtInfo &Info) : FunctionType(FunctionProto, Result, isVariadic, typeQuals, Canonical, (Result->isDependentType() || - hasAnyDependentType(ArgArray, numArgs)), NoReturn, - CallConv), + hasAnyDependentType(ArgArray, numArgs)), + Info), NumArgs(numArgs), NumExceptions(numExs), HasExceptionSpec(hasExs), AnyExceptionSpec(hasAnyExs) { // Fill in the trailing argument array. @@ -1919,7 +1961,7 @@ public: bool isVariadic, unsigned TypeQuals, bool hasExceptionSpec, bool anyExceptionSpec, unsigned NumExceptions, exception_iterator Exs, - bool NoReturn, CallingConv CallConv); + const ExtInfo &ExtInfo); }; @@ -2937,36 +2979,18 @@ inline Qualifiers::GC QualType::getObjCGCAttr() const { return Qualifiers::GCNone; } - /// getNoReturnAttr - Returns true if the type has the noreturn attribute, - /// false otherwise. -inline bool Type::getNoReturnAttr() const { - if (const PointerType *PT = getAs()) { +inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { + if (const PointerType *PT = t.getAs()) { if (const FunctionType *FT = PT->getPointeeType()->getAs()) - return FT->getNoReturnAttr(); - } else if (const FunctionType *FT = getAs()) - return FT->getNoReturnAttr(); + return FT->getExtInfo(); + } else if (const FunctionType *FT = t.getAs()) + return FT->getExtInfo(); - return false; + return FunctionType::ExtInfo(); } -/// getCallConv - Returns the calling convention of the type if the type -/// is a function type, CC_Default otherwise. -inline CallingConv Type::getCallConv() const { - if (const PointerType *PT = getAs()) - return PT->getPointeeType()->getCallConv(); - else if (const ReferenceType *RT = getAs()) - return RT->getPointeeType()->getCallConv(); - else if (const MemberPointerType *MPT = - getAs()) - return MPT->getPointeeType()->getCallConv(); - else if (const BlockPointerType *BPT = - getAs()) { - if (const FunctionType *FT = BPT->getPointeeType()->getAs()) - return FT->getCallConv(); - } else if (const FunctionType *FT = getAs()) - return FT->getCallConv(); - - return CC_Default; +inline FunctionType::ExtInfo getFunctionExtInfo(QualType t) { + return getFunctionExtInfo(*t); } /// isMoreQualifiedThan - Determine whether this type is more diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index f8f626a1e4..00a7987a2b 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1097,14 +1097,12 @@ QualType ASTContext::getObjCGCQualType(QualType T, return getExtQualType(TypeNode, Quals); } -static QualType getNoReturnCallConvType(ASTContext& Context, QualType T, - bool AddNoReturn, - CallingConv CallConv) { +static QualType getExtFunctionType(ASTContext& Context, QualType T, + const FunctionType::ExtInfo &Info) { QualType ResultType; if (const PointerType *Pointer = T->getAs()) { QualType Pointee = Pointer->getPointeeType(); - ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn, - CallConv); + ResultType = getExtFunctionType(Context, Pointee, Info); if (ResultType == Pointee) return T; @@ -1112,19 +1110,18 @@ static QualType getNoReturnCallConvType(ASTContext& Context, QualType T, } else if (const BlockPointerType *BlockPointer = T->getAs()) { QualType Pointee = BlockPointer->getPointeeType(); - ResultType = getNoReturnCallConvType(Context, Pointee, AddNoReturn, - CallConv); + ResultType = getExtFunctionType(Context, Pointee, Info); if (ResultType == Pointee) return T; ResultType = Context.getBlockPointerType(ResultType); } else if (const FunctionType *F = T->getAs()) { - if (F->getNoReturnAttr() == AddNoReturn && F->getCallConv() == CallConv) + if (F->getExtInfo() == Info) return T; if (const FunctionNoProtoType *FNPT = dyn_cast(F)) { ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(), - AddNoReturn, CallConv); + Info); } else { const FunctionProtoType *FPT = cast(F); ResultType @@ -1135,7 +1132,7 @@ static QualType getNoReturnCallConvType(ASTContext& Context, QualType T, FPT->hasAnyExceptionSpec(), FPT->getNumExceptions(), FPT->exception_begin(), - AddNoReturn, CallConv); + Info); } } else return T; @@ -1144,11 +1141,15 @@ static QualType getNoReturnCallConvType(ASTContext& Context, QualType T, } QualType ASTContext::getNoReturnType(QualType T, bool AddNoReturn) { - return getNoReturnCallConvType(*this, T, AddNoReturn, T->getCallConv()); + FunctionType::ExtInfo Info = getFunctionExtInfo(*T); + return getExtFunctionType(*this, T, + Info.withNoReturn(AddNoReturn)); } QualType ASTContext::getCallConvType(QualType T, CallingConv CallConv) { - return getNoReturnCallConvType(*this, T, T->getNoReturnAttr(), CallConv); + FunctionType::ExtInfo Info = getFunctionExtInfo(*T); + return getExtFunctionType(*this, T, + Info.withCallingConv(CallConv)); } /// getComplexType - Return the uniqued reference to the type for a complex @@ -1606,12 +1607,13 @@ QualType ASTContext::getDependentSizedExtVectorType(QualType vecType, /// getFunctionNoProtoType - Return a K&R style C function type like 'int()'. /// -QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn, - CallingConv CallConv) { +QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, + const FunctionType::ExtInfo &Info) { + const CallingConv CallConv = Info.getCC(); // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; - FunctionNoProtoType::Profile(ID, ResultTy, NoReturn, CallConv); + FunctionNoProtoType::Profile(ID, ResultTy, Info); void *InsertPos = 0; if (FunctionNoProtoType *FT = @@ -1621,8 +1623,9 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn, QualType Canonical; if (!ResultTy.isCanonical() || getCanonicalCallConv(CallConv) != CallConv) { - Canonical = getFunctionNoProtoType(getCanonicalType(ResultTy), NoReturn, - getCanonicalCallConv(CallConv)); + Canonical = + getFunctionNoProtoType(getCanonicalType(ResultTy), + Info.withCallingConv(getCanonicalCallConv(CallConv))); // Get the new insert position for the node we care about. FunctionNoProtoType *NewIP = @@ -1631,7 +1634,7 @@ QualType ASTContext::getFunctionNoProtoType(QualType ResultTy, bool NoReturn, } FunctionNoProtoType *New = new (*this, TypeAlignment) - FunctionNoProtoType(ResultTy, Canonical, NoReturn, CallConv); + FunctionNoProtoType(ResultTy, Canonical, Info); Types.push_back(New); FunctionNoProtoTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -1643,14 +1646,15 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, unsigned NumArgs, bool isVariadic, unsigned TypeQuals, bool hasExceptionSpec, bool hasAnyExceptionSpec, unsigned NumExs, - const QualType *ExArray, bool NoReturn, - CallingConv CallConv) { + const QualType *ExArray, + const FunctionType::ExtInfo &Info) { + const CallingConv CallConv= Info.getCC(); // Unique functions, to guarantee there is only one function of a particular // structure. llvm::FoldingSetNodeID ID; FunctionProtoType::Profile(ID, ResultTy, ArgArray, NumArgs, isVariadic, TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, - NumExs, ExArray, NoReturn, CallConv); + NumExs, ExArray, Info); void *InsertPos = 0; if (FunctionProtoType *FTP = @@ -1675,8 +1679,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, Canonical = getFunctionType(getCanonicalType(ResultTy), CanonicalArgs.data(), NumArgs, isVariadic, TypeQuals, false, - false, 0, 0, NoReturn, - getCanonicalCallConv(CallConv)); + false, 0, 0, + Info.withCallingConv(getCanonicalCallConv(CallConv))); // Get the new insert position for the node we care about. FunctionProtoType *NewIP = @@ -1693,7 +1697,7 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, NumExs*sizeof(QualType), TypeAlignment); new (FTP) FunctionProtoType(ResultTy, ArgArray, NumArgs, isVariadic, TypeQuals, hasExceptionSpec, hasAnyExceptionSpec, - ExArray, NumExs, Canonical, NoReturn, CallConv); + ExArray, NumExs, Canonical, Info); Types.push_back(FTP); FunctionProtoTypes.InsertNode(FTP, InsertPos); return QualType(FTP, 0); @@ -4304,13 +4308,15 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (getCanonicalType(retType) != getCanonicalType(rbase->getResultType())) allRTypes = false; // FIXME: double check this - bool NoReturn = lbase->getNoReturnAttr() || rbase->getNoReturnAttr(); - if (NoReturn != lbase->getNoReturnAttr()) + FunctionType::ExtInfo lbaseInfo = lbase->getExtInfo(); + FunctionType::ExtInfo rbaseInfo = rbase->getExtInfo(); + bool NoReturn = lbaseInfo.getNoReturn() || rbaseInfo.getNoReturn(); + if (NoReturn != lbaseInfo.getNoReturn()) allLTypes = false; - if (NoReturn != rbase->getNoReturnAttr()) + if (NoReturn != rbaseInfo.getNoReturn()) allRTypes = false; - CallingConv lcc = lbase->getCallConv(); - CallingConv rcc = rbase->getCallConv(); + CallingConv lcc = lbaseInfo.getCC(); + CallingConv rcc = rbaseInfo.getCC(); // Compatible functions must have compatible calling conventions if (!isSameCallConv(lcc, rcc)) return QualType(); @@ -4349,7 +4355,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (allRTypes) return rhs; return getFunctionType(retType, types.begin(), types.size(), lproto->isVariadic(), lproto->getTypeQuals(), - false, false, 0, 0, NoReturn, lcc); + false, false, 0, 0, + FunctionType::ExtInfo(NoReturn, lcc)); } if (lproto) allRTypes = false; @@ -4382,13 +4389,15 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs, if (allRTypes) return rhs; return getFunctionType(retType, proto->arg_type_begin(), proto->getNumArgs(), proto->isVariadic(), - proto->getTypeQuals(), - false, false, 0, 0, NoReturn, lcc); + proto->getTypeQuals(), + false, false, 0, 0, + FunctionType::ExtInfo(NoReturn, lcc)); } if (allLTypes) return lhs; if (allRTypes) return rhs; - return getFunctionNoProtoType(retType, NoReturn, lcc); + FunctionType::ExtInfo Info(NoReturn, lcc); + return getFunctionNoProtoType(retType, Info); } QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, @@ -4892,7 +4901,7 @@ QualType ASTContext::GetBuiltinType(unsigned id, // FIXME: Should we create noreturn types? return getFunctionType(ResType, ArgTypes.data(), ArgTypes.size(), TypeStr[0] == '.', 0, false, false, 0, 0, - false, CC_Default); + FunctionType::ExtInfo()); } QualType diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index dd2528a6b3..9e789bb554 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -484,10 +484,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, Function1->getResultType(), Function2->getResultType())) return false; - if (Function1->getNoReturnAttr() != Function2->getNoReturnAttr()) - return false; - if (Function1->getCallConv() != Function2->getCallConv()) - return false; + if (Function1->getExtInfo() != Function2->getExtInfo()) + return false; break; } @@ -1200,10 +1198,9 @@ QualType ASTNodeImporter::VisitFunctionNoProtoType(FunctionNoProtoType *T) { QualType ToResultType = Importer.Import(T->getResultType()); if (ToResultType.isNull()) return QualType(); - + return Importer.getToContext().getFunctionNoProtoType(ToResultType, - T->getNoReturnAttr(), - T->getCallConv()); + T->getExtInfo()); } QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) { @@ -1241,8 +1238,7 @@ QualType ASTNodeImporter::VisitFunctionProtoType(FunctionProtoType *T) { T->hasAnyExceptionSpec(), ExceptionTypes.size(), ExceptionTypes.data(), - T->getNoReturnAttr(), - T->getCallConv()); + T->getExtInfo()); } QualType ASTNodeImporter::VisitTypedefType(TypedefType *T) { diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 22dd2ecd64..b3675203d7 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -827,8 +827,8 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, unsigned NumArgs, bool isVariadic, unsigned TypeQuals, bool hasExceptionSpec, bool anyExceptionSpec, unsigned NumExceptions, - exception_iterator Exs, bool NoReturn, - CallingConv CallConv) { + exception_iterator Exs, + const FunctionType::ExtInfo &Info) { ID.AddPointer(Result.getAsOpaquePtr()); for (unsigned i = 0; i != NumArgs; ++i) ID.AddPointer(ArgTys[i].getAsOpaquePtr()); @@ -840,15 +840,15 @@ void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID, QualType Result, for (unsigned i = 0; i != NumExceptions; ++i) ID.AddPointer(Exs[i].getAsOpaquePtr()); } - ID.AddInteger(NoReturn); - ID.AddInteger(CallConv); + ID.AddInteger(Info.getNoReturn()); + ID.AddInteger(Info.getCC()); } void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getResultType(), arg_type_begin(), NumArgs, isVariadic(), getTypeQuals(), hasExceptionSpec(), hasAnyExceptionSpec(), - getNumExceptions(), exception_begin(), getNoReturnAttr(), - getCallConv()); + getNumExceptions(), exception_begin(), + getExtInfo()); } void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID, diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 0c4896decf..d1893cc611 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -282,7 +282,8 @@ void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, S += ")"; - switch(T->getCallConv()) { + FunctionType::ExtInfo Info = T->getExtInfo(); + switch(Info.getCC()) { case CC_Default: default: break; case CC_C: @@ -295,7 +296,7 @@ void TypePrinter::PrintFunctionProto(const FunctionProtoType *T, S += " __attribute__((fastcall))"; break; } - if (T->getNoReturnAttr()) + if (Info.getNoReturn()) S += " __attribute__((noreturn))"; @@ -819,4 +820,3 @@ void QualType::getAsStringInternal(std::string &S, TypePrinter Printer(Policy); Printer.Print(*this, S); } - diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index e93ddb34ca..f94f6b3f12 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -571,7 +571,7 @@ static bool CanThrow(Expr *E) { CFGBlock *CFGBuilder::VisitCallExpr(CallExpr *C, AddStmtChoice asc) { // If this is a call to a no-return function, this stops the block here. bool NoReturn = false; - if (C->getCallee()->getType()->getNoReturnAttr()) { + if (getFunctionExtInfo(*C->getCallee()->getType()).getNoReturn()) { NoReturn = true; } diff --git a/lib/Checker/NoReturnFunctionChecker.cpp b/lib/Checker/NoReturnFunctionChecker.cpp index 1a902dc2d8..12527e0762 100644 --- a/lib/Checker/NoReturnFunctionChecker.cpp +++ b/lib/Checker/NoReturnFunctionChecker.cpp @@ -37,7 +37,7 @@ void NoReturnFunctionChecker::PostVisitCallExpr(CheckerContext &C, const GRState *state = C.getState(); const Expr *Callee = CE->getCallee(); - bool BuildSinks = Callee->getType()->getNoReturnAttr(); + bool BuildSinks = getFunctionExtInfo(Callee->getType()).getNoReturn(); if (!BuildSinks) { SVal L = state->getSVal(Callee); diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index c10a401d8a..9217859ef1 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -192,7 +192,7 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { CallArgList Args; CodeGenTypes &Types = CGM.getTypes(); const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, Args, - CC_Default, false); + FunctionType::ExtInfo()); if (CGM.ReturnTypeUsesSret(FnInfo)) flags |= BLOCK_USE_STRET; } @@ -472,8 +472,8 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E, QualType ResultType = FuncTy->getResultType(); const CGFunctionInfo &FnInfo = - CGM.getTypes().getFunctionInfo(ResultType, Args, FuncTy->getCallConv(), - FuncTy->getNoReturnAttr()); + CGM.getTypes().getFunctionInfo(ResultType, Args, + FuncTy->getExtInfo()); // Cast the function pointer to the right type. const llvm::Type *BlockFTy = @@ -678,8 +678,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, const FunctionType *BlockFunctionType = BExpr->getFunctionType(); QualType ResultType; - CallingConv CC = BlockFunctionType->getCallConv(); - bool NoReturn = BlockFunctionType->getNoReturnAttr(); + FunctionType::ExtInfo EInfo = getFunctionExtInfo(*BlockFunctionType); bool IsVariadic; if (const FunctionProtoType *FTy = dyn_cast(BlockFunctionType)) { @@ -718,7 +717,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, Args.push_back(std::make_pair(*i, (*i)->getType())); const CGFunctionInfo &FI = - CGM.getTypes().getFunctionInfo(ResultType, Args, CC, NoReturn); + CGM.getTypes().getFunctionInfo(ResultType, Args, EInfo); CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *LTy = Types.GetFunctionType(FI, IsVariadic); @@ -843,7 +842,7 @@ GenerateCopyHelperFunction(bool BlockHasCopyDispose, const llvm::StructType *T, Args.push_back(std::make_pair(Src, Src->getType())); const CGFunctionInfo &FI = - CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false); + CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo()); // FIXME: We'd like to put these into a mergable by content, with // internal linkage. @@ -924,7 +923,7 @@ GenerateDestroyHelperFunction(bool BlockHasCopyDispose, Args.push_back(std::make_pair(Src, Src->getType())); const CGFunctionInfo &FI = - CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false); + CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo()); // FIXME: We'd like to put these into a mergable by content, with // internal linkage. @@ -1008,7 +1007,7 @@ GeneratebyrefCopyHelperFunction(const llvm::Type *T, int flag) { Args.push_back(std::make_pair(Src, Src->getType())); const CGFunctionInfo &FI = - CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false); + CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo()); CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); @@ -1071,7 +1070,7 @@ BlockFunction::GeneratebyrefDestroyHelperFunction(const llvm::Type *T, Args.push_back(std::make_pair(Src, Src->getType())); const CGFunctionInfo &FI = - CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false); + CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo()); CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *LTy = Types.GetFunctionType(FI, false); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index dcd0beab10..d861348ce8 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -67,8 +67,7 @@ const CGFunctionInfo & CodeGenTypes::getFunctionInfo(CanQual FTNP) { return getFunctionInfo(FTNP->getResultType().getUnqualifiedType(), llvm::SmallVector(), - FTNP->getCallConv(), - FTNP->getNoReturnAttr()); + FTNP->getExtInfo()); } /// \param Args - contains any initial parameters besides those @@ -81,8 +80,7 @@ static const CGFunctionInfo &getFunctionInfo(CodeGenTypes &CGT, ArgTys.push_back(FTP->getArgType(i)); CanQualType ResTy = FTP->getResultType().getUnqualifiedType(); return CGT.getFunctionInfo(ResTy, ArgTys, - FTP->getCallConv(), - FTP->getNoReturnAttr()); + FTP->getExtInfo()); } const CGFunctionInfo & @@ -175,8 +173,9 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { } return getFunctionInfo(GetReturnType(MD->getResultType()), ArgTys, - getCallingConventionForDecl(MD), - /*NoReturn*/ false); + FunctionType::ExtInfo( + /*NoReturn*/ false, + getCallingConventionForDecl(MD))); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(GlobalDecl GD) { @@ -194,32 +193,32 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(GlobalDecl GD) { const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const CallArgList &Args, - CallingConv CC, - bool NoReturn) { + const FunctionType::ExtInfo &Info) { // FIXME: Kill copy. llvm::SmallVector ArgTys; for (CallArgList::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); + return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const FunctionArgList &Args, - CallingConv CC, - bool NoReturn) { + const FunctionType::ExtInfo &Info) { // FIXME: Kill copy. llvm::SmallVector 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); + return getFunctionInfo(GetReturnType(ResTy), ArgTys, Info); } const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, const llvm::SmallVectorImpl &ArgTys, - CallingConv CallConv, - bool NoReturn) { + const FunctionType::ExtInfo &Info) { + const CallingConv CallConv = Info.getCC(); + const bool NoReturn = Info.getNoReturn(); + #ifndef NDEBUG for (llvm::SmallVectorImpl::const_iterator I = ArgTys.begin(), E = ArgTys.end(); I != E; ++I) @@ -230,7 +229,7 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(CanQualType ResTy, // Lookup or create unique function info. llvm::FoldingSetNodeID ID; - CGFunctionInfo::Profile(ID, CC, NoReturn, ResTy, + CGFunctionInfo::Profile(ID, Info, ResTy, ArgTys.begin(), ArgTys.end()); void *InsertPos = 0; diff --git a/lib/CodeGen/CGCall.h b/lib/CodeGen/CGCall.h index 3d81165b1b..235ff9c674 100644 --- a/lib/CodeGen/CGCall.h +++ b/lib/CodeGen/CGCall.h @@ -122,13 +122,12 @@ namespace CodeGen { } template static void Profile(llvm::FoldingSetNodeID &ID, - unsigned CallingConvention, - bool NoReturn, + const FunctionType::ExtInfo &Info, CanQualType ResTy, Iterator begin, Iterator end) { - ID.AddInteger(CallingConvention); - ID.AddBoolean(NoReturn); + ID.AddInteger(Info.getCC()); + ID.AddBoolean(Info.getNoReturn()); ResTy.Profile(ID); for (; begin != end; ++begin) { CanQualType T = *begin; // force iterator to be over canonical types diff --git a/lib/CodeGen/CGClass.cpp b/lib/CodeGen/CGClass.cpp index e702c5e783..177e862304 100644 --- a/lib/CodeGen/CGClass.cpp +++ b/lib/CodeGen/CGClass.cpp @@ -1379,7 +1379,7 @@ CodeGenFunction::GenerateCXXAggrDestructorHelper(const CXXDestructorDecl *D, llvm::raw_svector_ostream(Name) << "__tcf_" << (++UniqueAggrDestructorCount); QualType R = getContext().VoidTy; const CGFunctionInfo &FI - = CGM.getTypes().getFunctionInfo(R, Args, CC_Default, false); + = CGM.getTypes().getFunctionInfo(R, Args, FunctionType::ExtInfo()); const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FI, false); llvm::Function *Fn = llvm::Function::Create(FTy, llvm::GlobalValue::InternalLinkage, diff --git a/lib/CodeGen/CGExprCXX.cpp b/lib/CodeGen/CGExprCXX.cpp index 28b1d3b501..d9585c9c6d 100644 --- a/lib/CodeGen/CGExprCXX.cpp +++ b/lib/CodeGen/CGExprCXX.cpp @@ -44,9 +44,8 @@ RValue CodeGenFunction::EmitCXXMemberCall(const CXXMethodDecl *MD, QualType ResultType = FPT->getResultType(); return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args, - FPT->getCallConv(), - FPT->getNoReturnAttr()), Callee, - ReturnValue, Args, MD); + FPT->getExtInfo()), + Callee, ReturnValue, Args, MD); } /// canDevirtualizeMemberFunctionCalls - Checks whether virtual calls on given diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index d2b7a242e8..9eaf57c445 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -191,7 +191,7 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, // FIXME: We shouldn't need to get the function info here, the // runtime already should have computed it to build the function. RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args, - CC_Default, false), + FunctionType::ExtInfo()), GetPropertyFn, ReturnValueSlot(), Args); // We need to fix the type here. Ivars with copy & retain are // always objects so we don't need to worry about complex or @@ -285,7 +285,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, // FIXME: We shouldn't need to get the function info here, the runtime // already should have computed it to build the function. EmitCall(Types.getFunctionInfo(getContext().VoidTy, Args, - CC_Default, false), SetPropertyFn, + FunctionType::ExtInfo()), + SetPropertyFn, ReturnValueSlot(), Args); } else { // FIXME: Find a clean way to avoid AST node creation. @@ -561,7 +562,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S){ // FIXME: We shouldn't need to get the function info here, the runtime already // should have computed it to build the function. EmitCall(CGM.getTypes().getFunctionInfo(getContext().VoidTy, Args2, - CC_Default, false), + FunctionType::ExtInfo()), EnumerationMutationFn, ReturnValueSlot(), Args2); EmitBlock(WasNotMutated); diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 119819b810..d4452000dc 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -465,7 +465,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, CodeGenTypes &Types = CGM.getTypes(); const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, - CC_Default, false); + FunctionType::ExtInfo()); const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); @@ -573,7 +573,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, CodeGenTypes &Types = CGM.getTypes(); const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, - CC_Default, false); + FunctionType::ExtInfo()); const llvm::FunctionType *impType = Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); @@ -1694,7 +1694,7 @@ llvm::Constant *CGObjCGNU::EnumerationMutationFunction() { Params.push_back(ASTIdTy); const llvm::FunctionType *FTy = Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, - CC_Default, false), false); + FunctionType::ExtInfo()), false); return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); } diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 475280b6a0..1ed41d005f 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -306,7 +306,8 @@ public: Params.push_back(Ctx.BoolTy); const llvm::FunctionType *FTy = Types.GetFunctionType(Types.getFunctionInfo(IdType, Params, - CC_Default, false), false); + FunctionType::ExtInfo()), + false); return CGM.CreateRuntimeFunction(FTy, "objc_getProperty"); } @@ -325,7 +326,8 @@ public: Params.push_back(Ctx.BoolTy); const llvm::FunctionType *FTy = Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, - CC_Default, false), false); + FunctionType::ExtInfo()), + false); return CGM.CreateRuntimeFunction(FTy, "objc_setProperty"); } @@ -337,7 +339,8 @@ public: Params.push_back(Ctx.getCanonicalParamType(Ctx.getObjCIdType())); const llvm::FunctionType *FTy = Types.GetFunctionType(Types.getFunctionInfo(Ctx.VoidTy, Params, - CC_Default, false), false); + FunctionType::ExtInfo()), + false); return CGM.CreateRuntimeFunction(FTy, "objc_enumerationMutation"); } @@ -1559,7 +1562,7 @@ CGObjCCommonMac::EmitLegacyMessageSend(CodeGen::CodeGenFunction &CGF, CodeGenTypes &Types = CGM.getTypes(); const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs, - CC_Default, false); + FunctionType::ExtInfo()); const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo, Method ? Method->isVariadic() : false); @@ -5094,7 +5097,8 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend( // 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, CallArgList(), CC_Default, false); + = Types.getFunctionInfo(ResultType, CallArgList(), + FunctionType::ExtInfo()); llvm::Constant *Fn = 0; std::string Name("\01l_"); if (CGM.ReturnTypeUsesSret(FnInfo)) { @@ -5169,7 +5173,7 @@ CodeGen::RValue CGObjCNonFragileABIMac::EmitMessageSend( ObjCTypes.MessageRefCPtrTy)); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); const CGFunctionInfo &FnInfo1 = Types.getFunctionInfo(ResultType, ActualArgs, - CC_Default, false); + FunctionType::ExtInfo()); llvm::Value *Callee = CGF.Builder.CreateStructGEP(Arg1, 0); Callee = CGF.Builder.CreateLoad(Callee); const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo1, true); diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index bae588ab9b..2d1c73440b 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -2669,8 +2669,8 @@ void CodeGenFunction::GenerateThunk(llvm::Function *Fn, GlobalDecl GD, llvm::Value *Callee = CGM.GetAddrOfFunction(GD, Ty); const CGFunctionInfo &FnInfo = - CGM.getTypes().getFunctionInfo(ResultType, CallArgs, FPT->getCallConv(), - FPT->getNoReturnAttr()); + CGM.getTypes().getFunctionInfo(ResultType, CallArgs, + FPT->getExtInfo()); // Now emit our call. RValue RV = EmitCall(FnInfo, Callee, ReturnValueSlot(), CallArgs, MD); diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index ba5aaf685b..b863aff236 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -199,8 +199,8 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, QualType FnType = getContext().getFunctionType(RetTy, 0, 0, false, 0, false, false, 0, 0, - /*FIXME?*/false, - /*FIXME?*/CC_Default); + /*FIXME?*/ + FunctionType::ExtInfo()); // Emit subprogram debug descriptor. if (CGDebugInfo *DI = getDebugInfo()) { @@ -211,7 +211,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy, // FIXME: Leaked. // CC info is ignored, hopefully? CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args, - CC_Default, false); + FunctionType::ExtInfo()); if (RetTy->isVoidType()) { // Void type; nothing to return. diff --git a/lib/CodeGen/CodeGenTypes.h b/lib/CodeGen/CodeGenTypes.h index b2912efb34..173c4ad378 100644 --- a/lib/CodeGen/CodeGenTypes.h +++ b/lib/CodeGen/CodeGenTypes.h @@ -202,7 +202,7 @@ public: const CGFunctionInfo &getFunctionInfo(const CallArgList &Args, const FunctionType *Ty) { return getFunctionInfo(Ty->getResultType(), Args, - Ty->getCallConv(), Ty->getNoReturnAttr()); + Ty->getExtInfo()); } const CGFunctionInfo &getFunctionInfo(CanQual Ty); const CGFunctionInfo &getFunctionInfo(CanQual Ty); @@ -216,20 +216,17 @@ public: /// specified, the "C" calling convention will be used. const CGFunctionInfo &getFunctionInfo(QualType ResTy, const CallArgList &Args, - CallingConv CC, - bool NoReturn); + const FunctionType::ExtInfo &Info); const CGFunctionInfo &getFunctionInfo(QualType ResTy, const FunctionArgList &Args, - CallingConv CC, - bool NoReturn); + const FunctionType::ExtInfo &Info); /// 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 &ArgTys, - CallingConv CC, - bool NoReturn); + const FunctionType::ExtInfo &Info); public: // These are internal details of CGT that shouldn't be used externally. /// addFieldInfo - Assign field number to field FD. diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 8fd81df098..ceb7a6bf57 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -2080,8 +2080,8 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return QualType(); } QualType ResultType = GetType(Record[0]); - return Context->getFunctionNoProtoType(ResultType, Record[1], - (CallingConv)Record[2]); + FunctionType::ExtInfo Info(Record[1], (CallingConv)Record[2]); + return Context->getFunctionNoProtoType(ResultType, Info); } case pch::TYPE_FUNCTION_PROTO: { @@ -2104,7 +2104,8 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { return Context->getFunctionType(ResultType, ParamTypes.data(), NumParams, isVariadic, Quals, hasExceptionSpec, hasAnyExceptionSpec, NumExceptions, - Exceptions.data(), NoReturn, CallConv); + Exceptions.data(), + FunctionType::ExtInfo(NoReturn, CallConv)); } case pch::TYPE_UNRESOLVED_USING: diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 6c2d1424c8..b4fbd17bd6 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -141,9 +141,10 @@ void PCHTypeWriter::VisitExtVectorType(const ExtVectorType *T) { void PCHTypeWriter::VisitFunctionType(const FunctionType *T) { Writer.AddTypeRef(T->getResultType(), Record); - Record.push_back(T->getNoReturnAttr()); + FunctionType::ExtInfo C = T->getExtInfo(); + Record.push_back(C.getNoReturn()); // FIXME: need to stabilize encoding of calling convention... - Record.push_back(T->getCallConv()); + Record.push_back(C.getCC()); } void PCHTypeWriter::VisitFunctionNoProtoType(const FunctionNoProtoType *T) { diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 79aecceb70..cba92987a3 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -2262,8 +2262,8 @@ void RewriteObjC::SynthSelGetUidFunctionDecl() { QualType getFuncType = Context->getFunctionType(Context->getObjCSelType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); SelGetUidFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), SelGetUidIdent, getFuncType, 0, @@ -2359,8 +2359,8 @@ void RewriteObjC::SynthSuperContructorFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), false, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); SuperContructorFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2380,8 +2380,8 @@ void RewriteObjC::SynthMsgSendFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); MsgSendFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2404,8 +2404,8 @@ void RewriteObjC::SynthMsgSendSuperFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); MsgSendSuperFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2425,8 +2425,8 @@ void RewriteObjC::SynthMsgSendStretFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); MsgSendStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2451,8 +2451,8 @@ void RewriteObjC::SynthMsgSendSuperStretFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), true /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); MsgSendSuperStretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2472,8 +2472,8 @@ void RewriteObjC::SynthMsgSendFpretFunctionDecl() { QualType msgSendType = Context->getFunctionType(Context->DoubleTy, &ArgTys[0], ArgTys.size(), true /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); MsgSendFpretFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), msgSendIdent, msgSendType, 0, @@ -2488,8 +2488,8 @@ void RewriteObjC::SynthGetClassFunctionDecl() { QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); GetClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getClassIdent, getClassType, 0, @@ -2505,8 +2505,8 @@ void RewriteObjC::SynthGetSuperClassFunctionDecl() { QualType getClassType = Context->getFunctionType(Context->getObjCClassType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); GetSuperClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getSuperClassIdent, getClassType, 0, @@ -2521,8 +2521,8 @@ void RewriteObjC::SynthGetMetaClassFunctionDecl() { QualType getClassType = Context->getFunctionType(Context->getObjCIdType(), &ArgTys[0], ArgTys.size(), false /*isVariadic*/, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); GetMetaClassFunctionDecl = FunctionDecl::Create(*Context, TUDecl, SourceLocation(), getClassIdent, getClassType, 0, @@ -2964,8 +2964,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, &ArgTypes[0], ArgTypes.size(), // If we don't have a method decl, force a variadic cast. Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : true, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); castType = Context->getPointerType(castType); cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown, cast); @@ -2995,8 +2995,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, castType = Context->getFunctionType(returnType, &ArgTypes[0], ArgTypes.size(), Exp->getMethodDecl() ? Exp->getMethodDecl()->isVariadic() : false, 0, - false, false, 0, 0, false, - CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); castType = Context->getPointerType(castType); cast = NoTypeInfoCStyleCastExpr(Context, castType, CastExpr::CK_Unknown, cast); @@ -4547,7 +4547,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { QualType PtrToFuncCastType = Context->getFunctionType(Exp->getType(), &ArgTypes[0], ArgTypes.size(), false/*no variadic*/, 0, false, false, 0, 0, - false, CC_Default); + FunctionType::ExtInfo()); PtrToFuncCastType = Context->getPointerType(PtrToFuncCastType); @@ -5673,4 +5673,3 @@ void RewriteObjC::HandleTranslationUnit(ASTContext &C) { } OutFile->flush(); } - diff --git a/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp index 8b79e03ea8..d1f00ca66d 100644 --- a/lib/Sema/AnalysisBasedWarnings.cpp +++ b/lib/Sema/AnalysisBasedWarnings.cpp @@ -154,7 +154,7 @@ static ControlFlowKind CheckFallThrough(AnalysisContext &AC) { continue; } Expr *CEE = C->getCallee()->IgnoreParenCasts(); - if (CEE->getType()->getNoReturnAttr()) { + if (getFunctionExtInfo(CEE->getType()).getNoReturn()) { NoReturnEdge = true; HasFakeEdge = true; } else if (DeclRefExpr *DRE = dyn_cast(CEE)) { @@ -255,7 +255,7 @@ static void CheckFallThroughForBody(Sema &S, const Decl *D, const Stmt *Body, if (const FunctionDecl *FD = dyn_cast(D)) { ReturnsVoid = FD->getResultType()->isVoidType(); HasNoReturn = FD->hasAttr() || - FD->getType()->getAs()->getNoReturnAttr(); + FD->getType()->getAs()->getNoReturnAttr(); } else if (const ObjCMethodDecl *MD = dyn_cast(D)) { ReturnsVoid = MD->getResultType()->isVoidType(); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9dbe821ee8..b60804a189 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -981,25 +981,28 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { // other tests to run. const FunctionType *OldType = OldQType->getAs(); const FunctionType *NewType = New->getType()->getAs(); - if (OldType->getCallConv() != CC_Default && - NewType->getCallConv() == CC_Default) { - NewQType = Context.getCallConvType(NewQType, OldType->getCallConv()); + const FunctionType::ExtInfo OldTypeInfo = OldType->getExtInfo(); + const FunctionType::ExtInfo NewTypeInfo = NewType->getExtInfo(); + if (OldTypeInfo.getCC() != CC_Default && + NewTypeInfo.getCC() == CC_Default) { + NewQType = Context.getCallConvType(NewQType, OldTypeInfo.getCC()); New->setType(NewQType); NewQType = Context.getCanonicalType(NewQType); - } else if (!Context.isSameCallConv(OldType->getCallConv(), - NewType->getCallConv())) { + } else if (!Context.isSameCallConv(OldTypeInfo.getCC(), + NewTypeInfo.getCC())) { // Calling conventions really aren't compatible, so complain. Diag(New->getLocation(), diag::err_cconv_change) - << FunctionType::getNameForCallConv(NewType->getCallConv()) - << (OldType->getCallConv() == CC_Default) - << (OldType->getCallConv() == CC_Default ? "" : - FunctionType::getNameForCallConv(OldType->getCallConv())); + << FunctionType::getNameForCallConv(NewTypeInfo.getCC()) + << (OldTypeInfo.getCC() == CC_Default) + << (OldTypeInfo.getCC() == CC_Default ? "" : + FunctionType::getNameForCallConv(OldTypeInfo.getCC())); Diag(Old->getLocation(), diag::note_previous_declaration); return true; } // FIXME: diagnose the other way around? - if (OldType->getNoReturnAttr() && !NewType->getNoReturnAttr()) { + if (OldType->getNoReturnAttr() && + !NewType->getNoReturnAttr()) { NewQType = Context.getNoReturnType(NewQType); New->setType(NewQType); assert(NewQType.isCanonical()); @@ -1093,8 +1096,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { OldProto->isVariadic(), OldProto->getTypeQuals(), false, false, 0, 0, - OldProto->getNoReturnAttr(), - OldProto->getCallConv()); + OldProto->getExtInfo()); New->setType(NewQType); New->setHasInheritedPrototype(); @@ -1175,8 +1177,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) { ArgTypes.size(), OldProto->isVariadic(), 0, false, false, 0, 0, - OldProto->getNoReturnAttr(), - OldProto->getCallConv())); + OldProto->getExtInfo())); return MergeCompatibleFunctionDecls(New, Old); } @@ -3351,7 +3352,8 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, // Turn this into a variadic function with no parameters. QualType R = Context.getFunctionType( NewFD->getType()->getAs()->getResultType(), - 0, 0, true, 0, false, false, 0, 0, false, CC_Default); + 0, 0, true, 0, false, false, 0, 0, + FunctionType::ExtInfo()); NewFD->setType(R); return NewFD->setInvalidDecl(); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 6a2a037e9e..49352b5f4e 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2217,8 +2217,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { Context.getFunctionType(Context.VoidTy, 0, 0, false, 0, /*FIXME*/false, false, - 0, 0, false, - CC_Default), + 0, 0, + FunctionType::ExtInfo()), /*TInfo=*/0, /*isExplicit=*/false, /*isInline=*/true, @@ -2292,8 +2292,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { &ArgType, 1, false, 0, /*FIXME:*/false, - false, 0, 0, false, - CC_Default), + false, 0, 0, + FunctionType::ExtInfo()), /*TInfo=*/0, /*isExplicit=*/false, /*isInline=*/true, @@ -2381,8 +2381,8 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { Context.getFunctionType(RetType, &ArgType, 1, false, 0, /*FIXME:*/false, - false, 0, 0, false, - CC_Default), + false, 0, 0, + FunctionType::ExtInfo()), /*TInfo=*/0, /*isStatic=*/false, /*isInline=*/true); CopyAssignment->setAccess(AS_public); CopyAssignment->setImplicit(); @@ -2411,8 +2411,7 @@ void Sema::AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl) { QualType Ty = Context.getFunctionType(Context.VoidTy, 0, 0, false, 0, /*FIXME:*/false, - false, 0, 0, false, - CC_Default); + false, 0, 0, FunctionType::ExtInfo()); DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(ClassType); @@ -2585,8 +2584,7 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, Proto->hasAnyExceptionSpec(), Proto->getNumExceptions(), Proto->exception_begin(), - Proto->getNoReturnAttr(), - Proto->getCallConv()); + Proto->getExtInfo()); } /// CheckConstructor - Checks a fully-formed constructor for @@ -2745,7 +2743,7 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, // will put in a result type of "int" when none was specified. // FIXME: Exceptions! return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0, - false, false, 0, 0, false, CC_Default); + false, false, 0, 0, FunctionType::ExtInfo()); } /// CheckConversionDeclarator - Called by ActOnDeclarator to check the @@ -2821,8 +2819,7 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, Proto->hasAnyExceptionSpec(), Proto->getNumExceptions(), Proto->exception_begin(), - Proto->getNoReturnAttr(), - Proto->getCallConv()); + Proto->getExtInfo()); // C++0x explicit conversion operators. if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x) diff --git a/lib/Sema/SemaExceptionSpec.cpp b/lib/Sema/SemaExceptionSpec.cpp index eae30dc972..fab94df4d0 100644 --- a/lib/Sema/SemaExceptionSpec.cpp +++ b/lib/Sema/SemaExceptionSpec.cpp @@ -134,8 +134,7 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { NewProto->isVariadic(), NewProto->getTypeQuals(), true, false, 0, 0, - NewProto->getNoReturnAttr(), - NewProto->getCallConv()); + NewProto->getExtInfo()); New->setType(NewType); return false; } @@ -157,8 +156,7 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) { OldProto->hasAnyExceptionSpec(), OldProto->getNumExceptions(), OldProto->exception_begin(), - NewProto->getNoReturnAttr(), - NewProto->getCallConv()); + NewProto->getExtInfo()); New->setType(NewType); // If exceptions are disabled, suppress the warning about missing diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 4bf26a5224..0c9b3bd44b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -6851,8 +6851,8 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { // The parameter list is optional, if there was none, assume (). if (!T->isFunctionType()) - T = Context.getFunctionType(T, 0, 0, false, 0, false, false, 0, 0, false, - CC_Default); + T = Context.getFunctionType(T, 0, 0, false, 0, false, false, 0, 0, + FunctionType::ExtInfo()); CurBlock->hasPrototype = true; CurBlock->isVariadic = false; @@ -6977,11 +6977,11 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, QualType BlockTy; if (!BSI->hasPrototype) BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0, false, false, 0, 0, - NoReturn, CC_Default); + FunctionType::ExtInfo(NoReturn, CC_Default)); else BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(), BSI->isVariadic, 0, false, false, 0, 0, - NoReturn, CC_Default); + FunctionType::ExtInfo(NoReturn, CC_Default)); // FIXME: Check that return/parameter types are complete/non-abstract DiagnoseUnusedParameters(BSI->Params.begin(), BSI->Params.end()); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 23c30696e1..c31d93416d 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -948,7 +948,8 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, = Context.getFunctionType(Context.VoidTy, ArgTypes.data(), ArgTypes.size(), Proto->isVariadic(), - 0, false, false, 0, 0, false, CC_Default); + 0, false, false, 0, 0, + FunctionType::ExtInfo()); } for (LookupResult::iterator D = FoundDelete.begin(), @@ -1209,7 +1210,8 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name, QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0, true, false, HasBadAllocExceptionSpec? 1 : 0, - &BadAllocType, false, CC_Default); + &BadAllocType, + FunctionType::ExtInfo()); FunctionDecl *Alloc = FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name, FnType, /*TInfo=*/0, FunctionDecl::None, false, true); diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index f1bf88523b..a29c4d4528 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -556,13 +556,13 @@ static bool LookupDirect(Sema &S, LookupResult &R, const DeclContext *DC) { // Compute the type of the function that we would expect the conversion // function to have, if it were to match the name given. // FIXME: Calling convention! + FunctionType::ExtInfo ConvProtoInfo = ConvProto->getExtInfo(); QualType ExpectedType = R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(), 0, 0, ConvProto->isVariadic(), ConvProto->getTypeQuals(), false, false, 0, 0, - ConvProto->getNoReturnAttr(), - CC_Default); + ConvProtoInfo.withCallingConv(CC_Default)); // Perform template argument deduction against the type that we would // expect the function to have. diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 81c036be04..9777569b31 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1844,8 +1844,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, Proto->hasAnyExceptionSpec(), Exceptions.size(), Exceptions.data(), - Proto->getNoReturnAttr(), - Proto->getCallConv())); + Proto->getExtInfo())); } return false; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 660718f98f..099d30a44f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -801,7 +801,8 @@ QualType Sema::BuildFunctionType(QualType T, return QualType(); return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic, - Quals, false, false, 0, 0, false, CC_Default); + Quals, false, false, 0, 0, + FunctionType::ExtInfo()); } /// \brief Build a member pointer type \c T Class::*. @@ -1138,7 +1139,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, FTI.hasExceptionSpec, FTI.hasAnyExceptionSpec, Exceptions.size(), Exceptions.data(), - false, CC_Default); + FunctionType::ExtInfo()); } else if (FTI.isVariadic) { // We allow a zero-parameter variadic function in C if the // function is marked with the "overloadable" @@ -1155,7 +1156,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, if (!Overloadable) Diag(FTI.getEllipsisLoc(), diag::err_ellipsis_first_arg); T = Context.getFunctionType(T, NULL, 0, FTI.isVariadic, 0, - false, false, 0, 0, false, CC_Default); + false, false, 0, 0, + FunctionType::ExtInfo()); } else { // Simple void foo(), where the incoming T is the result type. T = Context.getFunctionNoProtoType(T); @@ -1231,7 +1233,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, FTI.hasExceptionSpec, FTI.hasAnyExceptionSpec, Exceptions.size(), Exceptions.data(), - false, CC_Default); + FunctionType::ExtInfo()); } // For GCC compatibility, we allow attributes that apply only to @@ -1329,7 +1331,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, // Strip the cv-quals from the type. T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(), FnTy->getNumArgs(), FnTy->isVariadic(), 0, - false, false, 0, 0, false, CC_Default); + false, false, 0, 0, FunctionType::ExtInfo()); } } diff --git a/test/CodeGen/regparm.c b/test/CodeGen/regparm.c index ac3797547d..43b1da61ee 100644 --- a/test/CodeGen/regparm.c +++ b/test/CodeGen/regparm.c @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | grep inreg | count 2 +// RUN: %clang_cc1 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s #define FASTCALL __attribute__((regparm(2))) @@ -14,5 +14,6 @@ reduced(char b, double c, foo* d, double e, int f) { int main(void) { + // CHECK: call void @reduced(i8 signext inreg 0, double 0.000000e+00, %struct.anon* inreg null, double 0.000000e+00, i32 0) reduced(0, 0.0, 0, 0.0, 0); }