diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiate.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 90 |
2 files changed, 41 insertions, 52 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 67b53b4c0a7..57eb64d127a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1577,6 +1577,9 @@ static bool NeedsInstantiationAsFunctionType(TypeSourceInfo *T) { for (unsigned I = 0, E = FP.getNumArgs(); I != E; ++I) { ParmVarDecl *P = FP.getArg(I); + // This must be synthesized from a typedef. + if (!P) continue; + // The parameter's type as written might be dependent even if the // decayed type was not dependent. if (TypeSourceInfo *TSInfo = P->getTypeSourceInfo()) diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index ffd7645f713..52075229971 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1233,26 +1233,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, Function->setLexicalDeclContext(LexicalDC); // Attach the parameters - if (isa<FunctionProtoType>(Function->getType().IgnoreParens())) { - // Adopt the already-instantiated parameters into our own context. - for (unsigned P = 0; P < Params.size(); ++P) - if (Params[P]) - Params[P]->setOwningFunction(Function); - } else { - // Since we were instantiated via a typedef of a function type, create - // new parameters. - const FunctionProtoType *Proto - = Function->getType()->getAs<FunctionProtoType>(); - assert(Proto && "No function prototype in template instantiation?"); - for (FunctionProtoType::arg_type_iterator AI = Proto->arg_type_begin(), - AE = Proto->arg_type_end(); AI != AE; ++AI) { - ParmVarDecl *Param - = SemaRef.BuildParmVarDeclForTypedef(Function, Function->getLocation(), - *AI); - Param->setScopeInfo(0, Params.size()); - Params.push_back(Param); - } - } + for (unsigned P = 0; P < Params.size(); ++P) + if (Params[P]) + Params[P]->setOwningFunction(Function); Function->setParams(Params); SourceLocation InstantiateAtPOI; @@ -1502,24 +1485,6 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, return 0; QualType T = adjustFunctionTypeForInstantiation(SemaRef.Context, D, TInfo); - // \brief If the type of this function, after ignoring parentheses, - // is not *directly* a function type, then we're instantiating a function - // that was declared via a typedef, e.g., - // - // typedef int functype(int, int); - // functype func; - // - // In this case, we'll just go instantiate the ParmVarDecls that we - // synthesized in the method declaration. - if (!isa<FunctionProtoType>(T.IgnoreParens())) { - assert(!Params.size() && "Instantiating type could not yield parameters"); - SmallVector<QualType, 4> ParamTypes; - if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), - D->getNumParams(), TemplateArgs, ParamTypes, - &Params)) - return 0; - } - NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); if (QualifierLoc) { QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, @@ -2499,11 +2464,10 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (!NewTInfo) return 0; - if (NewTInfo != OldTInfo) { - // Get parameters from the new type info. - TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); - if (FunctionProtoTypeLoc OldProtoLoc = - OldTL.getAs<FunctionProtoTypeLoc>()) { + TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); + if (FunctionProtoTypeLoc OldProtoLoc = OldTL.getAs<FunctionProtoTypeLoc>()) { + if (NewTInfo != OldTInfo) { + // Get parameters from the new type info. TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens(); FunctionProtoTypeLoc NewProtoLoc = NewTL.castAs<FunctionProtoTypeLoc>(); unsigned NewIdx = 0; @@ -2533,23 +2497,45 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, } } } - } - } else { - // The function type itself was not dependent and therefore no - // substitution occurred. However, we still need to instantiate - // the function parameters themselves. - TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); - if (FunctionProtoTypeLoc OldProtoLoc = - OldTL.getAs<FunctionProtoTypeLoc>()) { + } else { + // The function type itself was not dependent and therefore no + // substitution occurred. However, we still need to instantiate + // the function parameters themselves. + const FunctionProtoType *OldProto = + cast<FunctionProtoType>(OldProtoLoc.getType()); for (unsigned i = 0, i_end = OldProtoLoc.getNumArgs(); i != i_end; ++i) { + ParmVarDecl *OldParam = OldProtoLoc.getArg(i); + if (!OldParam) { + Params.push_back(SemaRef.BuildParmVarDeclForTypedef( + D, D->getLocation(), OldProto->getArgType(i))); + continue; + } + ParmVarDecl *Parm = - cast_or_null<ParmVarDecl>(VisitParmVarDecl(OldProtoLoc.getArg(i))); + cast_or_null<ParmVarDecl>(VisitParmVarDecl(OldParam)); if (!Parm) return 0; Params.push_back(Parm); } } + } else { + // If the type of this function, after ignoring parentheses, is not + // *directly* a function type, then we're instantiating a function that + // was declared via a typedef or with attributes, e.g., + // + // typedef int functype(int, int); + // functype func; + // int __cdecl meth(int, int); + // + // In this case, we'll just go instantiate the ParmVarDecls that we + // synthesized in the method declaration. + SmallVector<QualType, 4> ParamTypes; + if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(), + D->getNumParams(), TemplateArgs, ParamTypes, + &Params)) + return 0; } + return NewTInfo; } |