summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-12-14 06:51:39 +0000
committerJohn McCall <rjmccall@apple.com>2010-12-14 06:51:39 +0000
commitaa6d98c1603c81a7e4d9926ea554cd296cfb6506 (patch)
tree66723e5973af0eedb26130f2e985af0474ae973a /clang/lib/Sema
parentd7beca3782b4e555eb2214f9eaab7fe215558fc1 (diff)
downloadbcm5719-llvm-aa6d98c1603c81a7e4d9926ea554cd296cfb6506.tar.gz
bcm5719-llvm-aa6d98c1603c81a7e4d9926ea554cd296cfb6506.zip
Factor out most of the extra state in a FunctionProtoType into a separate
class to be passed around. The line between argument and return types and everything else is kindof vague, but I think it's justifiable. llvm-svn: 121752
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp17
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp95
-rw-r--r--clang/lib/Sema/SemaExceptionSpec.cpp35
-rw-r--r--clang/lib/Sema/SemaExpr.cpp22
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp24
-rw-r--r--clang/lib/Sema/SemaLookup.cpp11
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp15
-rw-r--r--clang/lib/Sema/SemaType.cpp49
8 files changed, 135 insertions, 133 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 403838176c6..66e517008ca 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1285,10 +1285,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
OldProto->arg_type_end());
NewQType = Context.getFunctionType(NewFuncType->getResultType(),
ParamTypes.data(), ParamTypes.size(),
- OldProto->isVariadic(),
- OldProto->getTypeQuals(),
- false, false, 0, 0,
- OldProto->getExtInfo());
+ OldProto->getExtProtoInfo());
New->setType(NewQType);
New->setHasInheritedPrototype();
@@ -1370,9 +1367,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, Decl *OldD) {
New->setType(Context.getFunctionType(MergedReturn, &ArgTypes[0],
ArgTypes.size(),
- OldProto->isVariadic(), 0,
- false, false, 0, 0,
- OldProto->getExtInfo()));
+ OldProto->getExtProtoInfo()));
return MergeCompatibleFunctionDecls(New, Old);
}
@@ -4046,9 +4041,11 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Turn this into a variadic function with no parameters.
const FunctionType *FT = NewFD->getType()->getAs<FunctionType>();
- QualType R = Context.getFunctionType(FT->getResultType(),
- 0, 0, true, 0, false, false, 0, 0,
- FT->getExtInfo());
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.Variadic = true;
+ EPI.ExtInfo = FT->getExtInfo();
+
+ QualType R = Context.getFunctionType(FT->getResultType(), 0, 0, EPI);
NewFD->setType(R);
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 3cfde26d24b..eec80f0d5a4 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -2851,20 +2851,21 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R,
if (FTI.TypeQuals & Qualifiers::Restrict)
Diag(D.getIdentifierLoc(), diag::err_invalid_qualified_constructor)
<< "restrict" << SourceRange(D.getIdentifierLoc());
+ D.setInvalidType();
}
// Rebuild the function type "R" without any type qualifiers (in
// case any of the errors above fired) and with "void" as the
// return type, since constructors don't have return types.
const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
+ if (Proto->getResultType() == Context.VoidTy && !D.isInvalidType())
+ return R;
+
+ FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
+ EPI.TypeQuals = 0;
+
return Context.getFunctionType(Context.VoidTy, Proto->arg_type_begin(),
- Proto->getNumArgs(),
- Proto->isVariadic(), 0,
- Proto->hasExceptionSpec(),
- Proto->hasAnyExceptionSpec(),
- Proto->getNumExceptions(),
- Proto->exception_begin(),
- Proto->getExtInfo());
+ Proto->getNumArgs(), EPI);
}
/// CheckConstructor - Checks a fully-formed constructor for
@@ -3022,16 +3023,14 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, QualType R,
// parameters (in case any of the errors above fired) and with
// "void" as the return type, since destructors don't have return
// types.
+ if (!D.isInvalidType())
+ return R;
+
const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
- if (!Proto)
- return QualType();
-
- return Context.getFunctionType(Context.VoidTy, 0, 0, false, 0,
- Proto->hasExceptionSpec(),
- Proto->hasAnyExceptionSpec(),
- Proto->getNumExceptions(),
- Proto->exception_begin(),
- Proto->getExtInfo());
+ FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
+ EPI.Variadic = false;
+ EPI.TypeQuals = 0;
+ return Context.getFunctionType(Context.VoidTy, 0, 0, EPI);
}
/// CheckConversionDeclarator - Called by ActOnDeclarator to check the
@@ -3111,15 +3110,8 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R,
// Rebuild the function type "R" without any parameters (in case any
// of the errors above fired) and with the conversion type as the
// return type.
- if (D.isInvalidType()) {
- R = Context.getFunctionType(ConvType, 0, 0, false,
- Proto->getTypeQuals(),
- Proto->hasExceptionSpec(),
- Proto->hasAnyExceptionSpec(),
- Proto->getNumExceptions(),
- Proto->exception_begin(),
- Proto->getExtInfo());
- }
+ if (D.isInvalidType())
+ R = Context.getFunctionType(ConvType, 0, 0, Proto->getExtProtoInfo());
// C++0x explicit conversion operators.
if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x)
@@ -4310,7 +4302,12 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
ExceptSpec.CalledDecl(Constructor);
}
}
-
+
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.HasExceptionSpec = ExceptSpec.hasExceptionSpecification();
+ EPI.HasAnyExceptionSpec = ExceptSpec.hasAnyExceptionSpecification();
+ EPI.NumExceptions = ExceptSpec.size();
+ EPI.Exceptions = ExceptSpec.data();
// Create the actual constructor declaration.
CanQualType ClassType
@@ -4321,12 +4318,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
CXXConstructorDecl *DefaultCon
= CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
Context.getFunctionType(Context.VoidTy,
- 0, 0, false, 0,
- ExceptSpec.hasExceptionSpecification(),
- ExceptSpec.hasAnyExceptionSpecification(),
- ExceptSpec.size(),
- ExceptSpec.data(),
- FunctionType::ExtInfo()),
+ 0, 0, EPI),
/*TInfo=*/0,
/*isExplicit=*/false,
/*isInline=*/true,
@@ -4414,13 +4406,12 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
}
// Create the actual destructor declaration.
- QualType Ty = Context.getFunctionType(Context.VoidTy,
- 0, 0, false, 0,
- ExceptSpec.hasExceptionSpecification(),
- ExceptSpec.hasAnyExceptionSpecification(),
- ExceptSpec.size(),
- ExceptSpec.data(),
- FunctionType::ExtInfo());
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.HasExceptionSpec = ExceptSpec.hasExceptionSpecification();
+ EPI.HasAnyExceptionSpec = ExceptSpec.hasAnyExceptionSpecification();
+ EPI.NumExceptions = ExceptSpec.size();
+ EPI.Exceptions = ExceptSpec.data();
+ QualType Ty = Context.getFunctionType(Context.VoidTy, 0, 0, EPI);
CanQualType ClassType
= Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
@@ -4812,17 +4803,16 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
// An implicitly-declared copy assignment operator is an inline public
// member of its class.
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.HasExceptionSpec = ExceptSpec.hasExceptionSpecification();
+ EPI.HasAnyExceptionSpec = ExceptSpec.hasAnyExceptionSpecification();
+ EPI.NumExceptions = ExceptSpec.size();
+ EPI.Exceptions = ExceptSpec.data();
DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Equal);
DeclarationNameInfo NameInfo(Name, ClassDecl->getLocation());
CXXMethodDecl *CopyAssignment
= CXXMethodDecl::Create(Context, ClassDecl, NameInfo,
- Context.getFunctionType(RetType, &ArgType, 1,
- false, 0,
- ExceptSpec.hasExceptionSpecification(),
- ExceptSpec.hasAnyExceptionSpecification(),
- ExceptSpec.size(),
- ExceptSpec.data(),
- FunctionType::ExtInfo()),
+ Context.getFunctionType(RetType, &ArgType, 1, EPI),
/*TInfo=*/0, /*isStatic=*/false,
/*StorageClassAsWritten=*/SC_None,
/*isInline=*/true);
@@ -5278,6 +5268,11 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
// An implicitly-declared copy constructor is an inline public
// member of its class.
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.HasExceptionSpec = ExceptSpec.hasExceptionSpecification();
+ EPI.HasAnyExceptionSpec = ExceptSpec.hasAnyExceptionSpecification();
+ EPI.NumExceptions = ExceptSpec.size();
+ EPI.Exceptions = ExceptSpec.data();
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(
Context.getCanonicalType(ClassType));
@@ -5285,13 +5280,7 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
CXXConstructorDecl *CopyConstructor
= CXXConstructorDecl::Create(Context, ClassDecl, NameInfo,
Context.getFunctionType(Context.VoidTy,
- &ArgType, 1,
- false, 0,
- ExceptSpec.hasExceptionSpecification(),
- ExceptSpec.hasAnyExceptionSpecification(),
- ExceptSpec.size(),
- ExceptSpec.data(),
- FunctionType::ExtInfo()),
+ &ArgType, 1, EPI),
/*TInfo=*/0,
/*isExplicit=*/false,
/*isInline=*/true,
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 885e52dd76a..d08e84dacd2 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -115,6 +115,9 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
if (!MissingExceptionSpecification && !MissingEmptyExceptionSpecification)
return true;
+ const FunctionProtoType *NewProto
+ = New->getType()->getAs<FunctionProtoType>();
+
// The new function declaration is only missing an empty exception
// specification "throw()". If the throw() specification came from a
// function in a system header that has C linkage, just add an empty
@@ -123,42 +126,38 @@ bool Sema::CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New) {
// to many libc functions as an optimization. Unfortunately, that
// optimization isn't permitted by the C++ standard, so we're forced
// to work around it here.
- if (MissingEmptyExceptionSpecification &&
- isa<FunctionProtoType>(New->getType()) &&
+ if (MissingEmptyExceptionSpecification && NewProto &&
(Old->getLocation().isInvalid() ||
Context.getSourceManager().isInSystemHeader(Old->getLocation())) &&
Old->isExternC()) {
- const FunctionProtoType *NewProto
- = cast<FunctionProtoType>(New->getType());
+ FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
+ EPI.HasExceptionSpec = true;
+ EPI.HasAnyExceptionSpec = false;
+ EPI.NumExceptions = 0;
QualType NewType = Context.getFunctionType(NewProto->getResultType(),
NewProto->arg_type_begin(),
NewProto->getNumArgs(),
- NewProto->isVariadic(),
- NewProto->getTypeQuals(),
- true, false, 0, 0,
- NewProto->getExtInfo());
+ EPI);
New->setType(NewType);
return false;
}
- if (MissingExceptionSpecification && isa<FunctionProtoType>(New->getType())) {
- const FunctionProtoType *NewProto
- = cast<FunctionProtoType>(New->getType());
+ if (MissingExceptionSpecification && NewProto) {
const FunctionProtoType *OldProto
= Old->getType()->getAs<FunctionProtoType>();
+ FunctionProtoType::ExtProtoInfo EPI = NewProto->getExtProtoInfo();
+ EPI.HasExceptionSpec = OldProto->hasExceptionSpec();
+ EPI.HasAnyExceptionSpec = OldProto->hasAnyExceptionSpec();
+ EPI.NumExceptions = OldProto->getNumExceptions();
+ EPI.Exceptions = OldProto->exception_begin();
+
// Update the type of the function with the appropriate exception
// specification.
QualType NewType = Context.getFunctionType(NewProto->getResultType(),
NewProto->arg_type_begin(),
NewProto->getNumArgs(),
- NewProto->isVariadic(),
- NewProto->getTypeQuals(),
- OldProto->hasExceptionSpec(),
- OldProto->hasAnyExceptionSpec(),
- OldProto->getNumExceptions(),
- OldProto->exception_begin(),
- NewProto->getExtInfo());
+ EPI);
New->setType(NewType);
// If exceptions are disabled, suppress the warning about missing
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 27e9e62fb3d..3f114dd6296 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -8326,8 +8326,9 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
// Turn protoless block types into nullary block types.
if (isa<FunctionNoProtoType>(FTy)) {
- BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0,
- false, false, 0, 0, Ext);
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.ExtInfo = Ext;
+ BlockTy = Context.getFunctionType(RetTy, 0, 0, EPI);
// Otherwise, if we don't need to change anything about the function type,
// preserve its sugar structure.
@@ -8338,23 +8339,20 @@ ExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc,
// Otherwise, make the minimal modifications to the function type.
} else {
const FunctionProtoType *FPT = cast<FunctionProtoType>(FTy);
+ FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo();
+ EPI.TypeQuals = 0; // FIXME: silently?
+ EPI.ExtInfo = Ext;
BlockTy = Context.getFunctionType(RetTy,
FPT->arg_type_begin(),
FPT->getNumArgs(),
- FPT->isVariadic(),
- /*quals*/ 0,
- FPT->hasExceptionSpec(),
- FPT->hasAnyExceptionSpec(),
- FPT->getNumExceptions(),
- FPT->exception_begin(),
- Ext);
+ EPI);
}
// If we don't have a function type, just build one from nothing.
} else {
- BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0,
- false, false, 0, 0,
- FunctionType::ExtInfo(NoReturn, 0, CC_Default));
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.ExtInfo = FunctionType::ExtInfo(NoReturn, 0, CC_Default);
+ BlockTy = Context.getFunctionType(RetTy, 0, 0, EPI);
}
DiagnoseUnusedParameters(BSI->TheDecl->param_begin(),
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 41a342942c8..76fcaeae58d 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -1074,21 +1074,24 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range,
// To perform this comparison, we compute the function type that
// the deallocation function should have, and use that type both
// for template argument deduction and for comparison purposes.
+ //
+ // FIXME: this comparison should ignore CC and the like.
QualType ExpectedFunctionType;
{
const FunctionProtoType *Proto
= OperatorNew->getType()->getAs<FunctionProtoType>();
+
llvm::SmallVector<QualType, 4> ArgTypes;
ArgTypes.push_back(Context.VoidPtrTy);
for (unsigned I = 1, N = Proto->getNumArgs(); I < N; ++I)
ArgTypes.push_back(Proto->getArgType(I));
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.Variadic = Proto->isVariadic();
+
ExpectedFunctionType
= Context.getFunctionType(Context.VoidTy, ArgTypes.data(),
- ArgTypes.size(),
- Proto->isVariadic(),
- 0, false, false, 0, 0,
- FunctionType::ExtInfo());
+ ArgTypes.size(), EPI);
}
for (LookupResult::iterator D = FoundDelete.begin(),
@@ -1340,12 +1343,15 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
assert(StdBadAlloc && "Must have std::bad_alloc declared");
BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
}
+
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.HasExceptionSpec = true;
+ if (HasBadAllocExceptionSpec) {
+ EPI.NumExceptions = 1;
+ EPI.Exceptions = &BadAllocType;
+ }
- QualType FnType = Context.getFunctionType(Return, &Argument, 1, false, 0,
- true, false,
- HasBadAllocExceptionSpec? 1 : 0,
- &BadAllocType,
- FunctionType::ExtInfo());
+ QualType FnType = Context.getFunctionType(Return, &Argument, 1, EPI);
FunctionDecl *Alloc =
FunctionDecl::Create(Context, GlobalCtx, SourceLocation(), Name,
FnType, /*TInfo=*/0, SC_None,
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6ff9cc69f1c..d4db84b7761 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -671,13 +671,14 @@ 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();
+ FunctionProtoType::ExtProtoInfo EPI = ConvProto->getExtProtoInfo();
+ EPI.ExtInfo = EPI.ExtInfo.withCallingConv(CC_Default);
+ EPI.HasExceptionSpec = false;
+ EPI.HasAnyExceptionSpec = false;
+ EPI.NumExceptions = 0;
QualType ExpectedType
= R.getSema().Context.getFunctionType(R.getLookupName().getCXXNameType(),
- 0, 0, ConvProto->isVariadic(),
- ConvProto->getTypeQuals(),
- false, false, 0, 0,
- ConvProtoInfo.withCallingConv(CC_Default));
+ 0, 0, EPI);
// Perform template argument deduction against the type that we would
// expect the function to have.
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 31692fc1f2e..2f73991ec56 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1995,19 +1995,20 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
// Rebuild the function type
+ FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo();
+ EPI.HasExceptionSpec = Proto->hasExceptionSpec();
+ EPI.HasAnyExceptionSpec = Proto->hasAnyExceptionSpec();
+ EPI.NumExceptions = Exceptions.size();
+ EPI.Exceptions = Exceptions.data();
+ EPI.ExtInfo = Proto->getExtInfo();
+
const FunctionProtoType *NewProto
= New->getType()->getAs<FunctionProtoType>();
assert(NewProto && "Template instantiation without function prototype?");
New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(),
NewProto->arg_type_begin(),
NewProto->getNumArgs(),
- NewProto->isVariadic(),
- NewProto->getTypeQuals(),
- Proto->hasExceptionSpec(),
- Proto->hasAnyExceptionSpec(),
- Exceptions.size(),
- Exceptions.data(),
- Proto->getExtInfo()));
+ EPI));
}
SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New);
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 23c159fbc5a..2a75ff0b340 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -829,7 +829,7 @@ QualType Sema::BuildFunctionType(QualType T,
unsigned NumParamTypes,
bool Variadic, unsigned Quals,
SourceLocation Loc, DeclarationName Entity,
- const FunctionType::ExtInfo &Info) {
+ FunctionType::ExtInfo Info) {
if (T->isArrayType() || T->isFunctionType()) {
Diag(Loc, diag::err_func_returning_array_function)
<< T->isFunctionType() << T;
@@ -850,8 +850,12 @@ QualType Sema::BuildFunctionType(QualType T,
if (Invalid)
return QualType();
- return Context.getFunctionType(T, ParamTypes, NumParamTypes, Variadic,
- Quals, false, false, 0, 0, Info);
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.Variadic = Variadic;
+ EPI.TypeQuals = Quals;
+ EPI.ExtInfo = Info;
+
+ return Context.getFunctionType(T, ParamTypes, NumParamTypes, EPI);
}
/// \brief Build a member pointer type \c T Class::*.
@@ -1265,6 +1269,10 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
break;
}
+ FunctionProtoType::ExtProtoInfo EPI;
+ EPI.Variadic = FTI.isVariadic;
+ EPI.TypeQuals = FTI.TypeQuals;
+
// Otherwise, we have a function with an argument list that is
// potentially variadic.
llvm::SmallVector<QualType, 16> ArgTys;
@@ -1316,22 +1324,23 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
}
llvm::SmallVector<QualType, 4> Exceptions;
- Exceptions.reserve(FTI.NumExceptions);
- for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
- // FIXME: Preserve type source info.
- QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
- // Check that the type is valid for an exception spec, and drop it if
- // not.
- if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
- Exceptions.push_back(ET);
+ if (FTI.hasExceptionSpec) {
+ EPI.HasExceptionSpec = FTI.hasExceptionSpec;
+ EPI.HasAnyExceptionSpec = FTI.hasAnyExceptionSpec;
+ EPI.NumExceptions = FTI.NumExceptions;
+ Exceptions.reserve(FTI.NumExceptions);
+ for (unsigned ei = 0, ee = FTI.NumExceptions; ei != ee; ++ei) {
+ // FIXME: Preserve type source info.
+ QualType ET = GetTypeFromParser(FTI.Exceptions[ei].Ty);
+ // Check that the type is valid for an exception spec, and
+ // drop it if not.
+ if (!CheckSpecifiedExceptionType(ET, FTI.Exceptions[ei].Range))
+ Exceptions.push_back(ET);
+ }
+ EPI.Exceptions = Exceptions.data();
}
- T = Context.getFunctionType(T, ArgTys.data(), ArgTys.size(),
- FTI.isVariadic, FTI.TypeQuals,
- FTI.hasExceptionSpec,
- FTI.hasAnyExceptionSpec,
- Exceptions.size(), Exceptions.data(),
- FunctionType::ExtInfo());
+ T = Context.getFunctionType(T, ArgTys.data(), ArgTys.size(), EPI);
}
// For GCC compatibility, we allow attributes that apply only to
@@ -1437,9 +1446,11 @@ TypeSourceInfo *Sema::GetTypeForDeclarator(Declarator &D, Scope *S,
<< FreeFunction;
// Strip the cv-quals from the type.
+ FunctionProtoType::ExtProtoInfo EPI = FnTy->getExtProtoInfo();
+ EPI.TypeQuals = 0;
+
T = Context.getFunctionType(FnTy->getResultType(), FnTy->arg_type_begin(),
- FnTy->getNumArgs(), FnTy->isVariadic(), 0,
- false, false, 0, 0, FunctionType::ExtInfo());
+ FnTy->getNumArgs(), EPI);
}
}
OpenPOWER on IntegriCloud