aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2010-03-30 20:24:48 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2010-03-30 20:24:48 +0000
commit264ba48dc98f3f843935a485d5b086f7e0fdc4f1 (patch)
treecb3dd379f85bf26848b5b5eaf6c38a4aa9dd85ef
parentf540305c5d834ad9412b41805b81a74249b7c5af (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
-rw-r--r--include/clang/AST/ASTContext.h10
-rw-r--r--include/clang/AST/CanonicalType.h9
-rw-r--r--include/clang/AST/ExprCXX.h4
-rw-r--r--include/clang/AST/Type.h120
-rw-r--r--lib/AST/ASTContext.cpp77
-rw-r--r--lib/AST/ASTImporter.cpp14
-rw-r--r--lib/AST/Type.cpp12
-rw-r--r--lib/AST/TypePrinter.cpp6
-rw-r--r--lib/Analysis/CFG.cpp2
-rw-r--r--lib/Checker/NoReturnFunctionChecker.cpp2
-rw-r--r--lib/CodeGen/CGBlocks.cpp19
-rw-r--r--lib/CodeGen/CGCall.cpp29
-rw-r--r--lib/CodeGen/CGCall.h7
-rw-r--r--lib/CodeGen/CGClass.cpp2
-rw-r--r--lib/CodeGen/CGExprCXX.cpp5
-rw-r--r--lib/CodeGen/CGObjC.cpp7
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp6
-rw-r--r--lib/CodeGen/CGObjCMac.cpp16
-rw-r--r--lib/CodeGen/CGVtable.cpp4
-rw-r--r--lib/CodeGen/CodeGenFunction.cpp6
-rw-r--r--lib/CodeGen/CodeGenTypes.h11
-rw-r--r--lib/Frontend/PCHReader.cpp7
-rw-r--r--lib/Frontend/PCHWriter.cpp5
-rw-r--r--lib/Frontend/RewriteObjC.cpp51
-rw-r--r--lib/Sema/AnalysisBasedWarnings.cpp4
-rw-r--r--lib/Sema/SemaDecl.cpp32
-rw-r--r--lib/Sema/SemaDeclCXX.cpp23
-rw-r--r--lib/Sema/SemaExceptionSpec.cpp6
-rw-r--r--lib/Sema/SemaExpr.cpp8
-rw-r--r--lib/Sema/SemaExprCXX.cpp6
-rw-r--r--lib/Sema/SemaLookup.cpp4
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--lib/Sema/SemaType.cpp12
-rw-r--r--test/CodeGen/regparm.c3
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();