diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-03-30 20:24:48 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-03-30 20:24:48 +0000 |
commit | 264ba48dc98f3f843935a485d5b086f7e0fdc4f1 (patch) | |
tree | cb3dd379f85bf26848b5b5eaf6c38a4aa9dd85ef | |
parent | f540305c5d834ad9412b41805b81a74249b7c5af (diff) |
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
34 files changed, 279 insertions, 253 deletions
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<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) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) }; 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) + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(FunctionType::ExtInfo, getExtInfo) }; 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(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<PointerType>()) { +inline FunctionType::ExtInfo getFunctionExtInfo(const Type &t) { + if (const PointerType *PT = t.getAs<PointerType>()) { if (const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>()) - return FT->getNoReturnAttr(); - } else if (const FunctionType *FT = getAs<FunctionType>()) - return FT->getNoReturnAttr(); + return FT->getExtInfo(); + } else if (const FunctionType *FT = t.getAs<FunctionType>()) + 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<PointerType>()) - return PT->getPointeeType()->getCallConv(); - else if (const ReferenceType *RT = getAs<ReferenceType>()) - return RT->getPointeeType()->getCallConv(); - else if (const MemberPointerType *MPT = - getAs<MemberPointerType>()) - return MPT->getPointeeType()->getCallConv(); - else if (const BlockPointerType *BPT = - getAs<BlockPointerType>()) { - if (const FunctionType *FT = BPT->getPointeeType()->getAs<FunctionType>()) - return FT->getCallConv(); - } else if (const FunctionType *FT = getAs<FunctionType>()) - 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<PointerType>()) { 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<BlockPointerType>()) { 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<FunctionType>()) { - if (F->getNoReturnAttr() == AddNoReturn && F->getCallConv() == CallConv) + if (F->getExtInfo() == Info) return T; if (const FunctionNoProtoType *FNPT = dyn_cast<FunctionNoProtoType>(F)) { ResultType = Context.getFunctionNoProtoType(FNPT->getResultType(), - AddNoReturn, CallConv); + Info); } else { const FunctionProtoType *FPT = cast<FunctionProtoType>(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(); |