aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiateDecl.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-04-12 07:48:19 +0000
committerDouglas Gregor <dgregor@apple.com>2010-04-12 07:48:19 +0000
commitcb27b0f70d2017295776afafe3616e0bcd74ab51 (patch)
treecb5d84e5272f84f5fba89d178bbdc36bf4d88a42 /lib/Sema/SemaTemplateInstantiateDecl.cpp
parent1e46136c5222ad040fd783ca7ee6b2215f0b89d6 (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.cpp86
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;
}