diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-04-12 07:48:19 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-04-12 07:48:19 +0000 |
commit | cb27b0f70d2017295776afafe3616e0bcd74ab51 (patch) | |
tree | cb5d84e5272f84f5fba89d178bbdc36bf4d88a42 /lib/Sema/SemaTemplateInstantiateDecl.cpp | |
parent | 1e46136c5222ad040fd783ca7ee6b2215f0b89d6 (diff) |
Be sure to instantiate the parameters of a function, even when the
function's type is (strictly speaking) non-dependent. This ensures
that, e.g., default function arguments get instantiated properly.
And, since I couldn't resist, collapse the two implementations of
function-parameter instantiation into calls to a single, new function
(Sema::SubstParmVarDecl), since the two had nearly identical code (and
each had bugs the other didn't!). More importantly, factored out the
semantic analysis of a parameter declaration into
Sema::CheckParameter, which is called both by
Sema::ActOnParamDeclarator (when parameters are parsed) and when a
parameter is instantiated. Previously, we were missing some
Objective-C and address-space checks on instantiated function
parameters.
Fixes PR6733.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101029 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiateDecl.cpp')
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 86 |
1 files changed, 21 insertions, 65 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 82270451cb..18b6829744 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1343,41 +1343,7 @@ Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) { } ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { - QualType T; - TypeSourceInfo *DI = D->getTypeSourceInfo(); - if (DI) { - DI = SemaRef.SubstType(DI, TemplateArgs, D->getLocation(), - D->getDeclName()); - if (DI) T = DI->getType(); - } else { - T = SemaRef.SubstType(D->getType(), TemplateArgs, D->getLocation(), - D->getDeclName()); - DI = 0; - } - - if (T.isNull()) - return 0; - - T = SemaRef.adjustParameterType(T); - - // Allocate the parameter - ParmVarDecl *Param - = ParmVarDecl::Create(SemaRef.Context, - SemaRef.Context.getTranslationUnitDecl(), - D->getLocation(), - D->getIdentifier(), T, DI, D->getStorageClass(), 0); - - // Mark the default argument as being uninstantiated. - if (D->hasUninstantiatedDefaultArg()) - Param->setUninstantiatedDefaultArg(D->getUninstantiatedDefaultArg()); - else if (Expr *Arg = D->getDefaultArg()) - Param->setUninstantiatedDefaultArg(Arg); - - // Note: we don't try to instantiate function parameters until after - // we've instantiated the function's type. Therefore, we don't have - // to check for 'void' parameter types here. - SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); - return Param; + return SemaRef.SubstParmVarDecl(D, TemplateArgs); } Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( @@ -1797,29 +1763,6 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( return false; } -bool -Sema::CheckInstantiatedParams(llvm::SmallVectorImpl<ParmVarDecl*> &Params) { - bool Invalid = false; - for (unsigned i = 0, i_end = Params.size(); i != i_end; ++i) - if (ParmVarDecl *PInst = Params[i]) { - if (PInst->isInvalidDecl()) - Invalid = true; - else if (PInst->getType()->isVoidType()) { - Diag(PInst->getLocation(), diag::err_param_with_void_type); - PInst->setInvalidDecl(); - Invalid = true; - } - else if (RequireNonAbstractType(PInst->getLocation(), - PInst->getType(), - diag::err_abstract_type_in_decl, - Sema::AbstractParamType)) { - PInst->setInvalidDecl(); - Invalid = true; - } - } - return Invalid; -} - TypeSourceInfo* TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, llvm::SmallVectorImpl<ParmVarDecl *> &Params) { @@ -1833,13 +1776,26 @@ TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, if (!NewTInfo) return 0; - // Get parameters from the new type info. - TypeLoc NewTL = NewTInfo->getTypeLoc(); - FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL); - assert(NewProtoLoc && "Missing prototype?"); - for (unsigned i = 0, i_end = NewProtoLoc->getNumArgs(); i != i_end; ++i) - Params.push_back(NewProtoLoc->getArg(i)); - + if (NewTInfo != OldTInfo) { + // Get parameters from the new type info. + TypeLoc NewTL = NewTInfo->getTypeLoc(); + FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL); + assert(NewProtoLoc && "Missing prototype?"); + for (unsigned i = 0, i_end = NewProtoLoc->getNumArgs(); i != i_end; ++i) + Params.push_back(NewProtoLoc->getArg(i)); + } 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(); + FunctionProtoTypeLoc *OldProtoLoc = cast<FunctionProtoTypeLoc>(&OldTL); + for (unsigned i = 0, i_end = OldProtoLoc->getNumArgs(); i != i_end; ++i) { + ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc->getArg(i)); + if (!Parm) + return 0; + Params.push_back(Parm); + } + } return NewTInfo; } |