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.
llvm-svn: 99920
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index f8f626a..00a7987 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1097,14 +1097,12 @@
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 @@
} 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 @@
FPT->hasAnyExceptionSpec(),
FPT->getNumExceptions(),
FPT->exception_begin(),
- AddNoReturn, CallConv);
+ Info);
}
} else
return T;
@@ -1144,11 +1141,15 @@
}
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 @@
/// 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 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 @@
}
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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 @@
// 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