diff options
author | John McCall <rjmccall@apple.com> | 2010-12-14 06:51:39 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-12-14 06:51:39 +0000 |
commit | aa6d98c1603c81a7e4d9926ea554cd296cfb6506 (patch) | |
tree | 66723e5973af0eedb26130f2e985af0474ae973a /clang/lib/Sema | |
parent | d7beca3782b4e555eb2214f9eaab7fe215558fc1 (diff) | |
download | bcm5719-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.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 95 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExceptionSpec.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 24 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 11 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 49 |
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); } } |