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/lib/Sema/AnalysisBasedWarnings.cpp b/lib/Sema/AnalysisBasedWarnings.cpp
index 8b79e03..d1f00ca 100644
--- a/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/lib/Sema/AnalysisBasedWarnings.cpp
@@ -154,7 +154,7 @@
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<DeclRefExpr>(CEE)) {
@@ -255,7 +255,7 @@
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
ReturnsVoid = FD->getResultType()->isVoidType();
HasNoReturn = FD->hasAttr<NoReturnAttr>() ||
- FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
+ FD->getType()->getAs<FunctionType>()->getNoReturnAttr();
}
else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
ReturnsVoid = MD->getResultType()->isVoidType();
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 9dbe821..b60804a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -981,25 +981,28 @@
// other tests to run.
const FunctionType *OldType = OldQType->getAs<FunctionType>();
const FunctionType *NewType = New->getType()->getAs<FunctionType>();
- 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 @@
OldProto->isVariadic(),
OldProto->getTypeQuals(),
false, false, 0, 0,
- OldProto->getNoReturnAttr(),
- OldProto->getCallConv());
+ OldProto->getExtInfo());
New->setType(NewQType);
New->setHasInheritedPrototype();
@@ -1175,8 +1177,7 @@
ArgTypes.size(),
OldProto->isVariadic(), 0,
false, false, 0, 0,
- OldProto->getNoReturnAttr(),
- OldProto->getCallConv()));
+ OldProto->getExtInfo()));
return MergeCompatibleFunctionDecls(New, Old);
}
@@ -3351,7 +3352,8 @@
// Turn this into a variadic function with no parameters.
QualType R = Context.getFunctionType(
NewFD->getType()->getAs<FunctionType>()->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 6a2a037..49352b5 100644
--- a/lib/Sema/SemaDeclCXX.cpp
+++ b/lib/Sema/SemaDeclCXX.cpp
@@ -2217,8 +2217,8 @@
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 @@
&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 @@
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 @@
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 @@
Proto->hasAnyExceptionSpec(),
Proto->getNumExceptions(),
Proto->exception_begin(),
- Proto->getNoReturnAttr(),
- Proto->getCallConv());
+ Proto->getExtInfo());
}
/// CheckConstructor - Checks a fully-formed constructor for
@@ -2745,7 +2743,7 @@
// 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 @@
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 eae30dc..fab94df 100644
--- a/lib/Sema/SemaExceptionSpec.cpp
+++ b/lib/Sema/SemaExceptionSpec.cpp
@@ -134,8 +134,7 @@
NewProto->isVariadic(),
NewProto->getTypeQuals(),
true, false, 0, 0,
- NewProto->getNoReturnAttr(),
- NewProto->getCallConv());
+ NewProto->getExtInfo());
New->setType(NewType);
return false;
}
@@ -157,8 +156,7 @@
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 4bf26a5..0c9b3bd 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -6851,8 +6851,8 @@
// 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 @@
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 23c3069..c31d934 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -948,7 +948,8 @@
= 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 @@
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 f1bf885..a29c4d4 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -556,13 +556,13 @@
// 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 81c036b..9777569 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1844,8 +1844,7 @@
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 660718f..099d30a 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -801,7 +801,8 @@
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 @@
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 @@
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 @@
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 @@
// 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());
}
}