summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-11 09:03:00 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-11 09:03:00 +0000
commit58f10c3380640962d251db70ac876e5ea7336c59 (patch)
tree8a649d3425186c5779746e250b519b853bcbda91 /clang/lib/Sema/SemaTemplateInstantiate.cpp
parent8c4df8160ed0d6e2b96a31c1c0fb12cc77328c80 (diff)
downloadbcm5719-llvm-58f10c3380640962d251db70ac876e5ea7336c59.tar.gz
bcm5719-llvm-58f10c3380640962d251db70ac876e5ea7336c59.zip
Maintain type source information for functions through template
instantiation. Based on a patch by Enea Zaffanella! I found a way to reduce some of the redundancy between TreeTransform's "standard" FunctionProtoType transformation and TemplateInstantiator's override, and I killed off the old SubstFunctionType by adding type source info for the last cases where we were creating FunctionDecls without TSI (at least that get passed through template instantiation). llvm-svn: 98252
Diffstat (limited to 'clang/lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp62
1 files changed, 62 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 8f73337e436..19c257d5b7c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -567,6 +567,15 @@ namespace {
Sema::OwningExprResult TransformTemplateParmRefExpr(DeclRefExpr *E,
NonTypeTemplateParmDecl *D);
+ /// \brief Transforms a function proto type by performing
+ /// substitution in the function parameters, possibly adjusting
+ /// their types and marking default arguments as uninstantiated.
+ bool TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
+ llvm::SmallVectorImpl<QualType> &PTypes,
+ llvm::SmallVectorImpl<ParmVarDecl*> &PVars);
+
+ ParmVarDecl *TransformFunctionTypeParam(ParmVarDecl *OldParm);
+
/// \brief Transforms a template type parameter type by performing
/// substitution of the corresponding template type argument.
QualType TransformTemplateTypeParmType(TypeLocBuilder &TLB,
@@ -859,6 +868,59 @@ Sema::OwningExprResult TemplateInstantiator::TransformCXXDefaultArgExpr(
}
+bool
+TemplateInstantiator::TransformFunctionTypeParams(FunctionProtoTypeLoc TL,
+ llvm::SmallVectorImpl<QualType> &PTypes,
+ llvm::SmallVectorImpl<ParmVarDecl*> &PVars) {
+ // Create a local instantiation scope for the parameters.
+ Sema::LocalInstantiationScope
+ Scope(SemaRef, SemaRef.CurrentInstantiationScope != 0);
+
+ if (TreeTransform<TemplateInstantiator>::
+ TransformFunctionTypeParams(TL, PTypes, PVars))
+ return true;
+
+ // Check instantiated parameters.
+ if (SemaRef.CheckInstantiatedParams(PVars))
+ return true;
+
+ return false;
+}
+
+ParmVarDecl *
+TemplateInstantiator::TransformFunctionTypeParam(ParmVarDecl *OldParm) {
+ TypeSourceInfo *OldDI = OldParm->getTypeSourceInfo();
+ TypeSourceInfo *NewDI = getDerived().TransformType(OldDI);
+ if (!NewDI)
+ return 0;
+
+ // TODO: do we have to clone this decl if the types match and
+ // there's no default argument?
+
+ ParmVarDecl *NewParm
+ = ParmVarDecl::Create(SemaRef.Context,
+ OldParm->getDeclContext(),
+ OldParm->getLocation(),
+ OldParm->getIdentifier(),
+ NewDI->getType(),
+ NewDI,
+ OldParm->getStorageClass(),
+ /* DefArg */ NULL);
+
+ // Maybe adjust new parameter type.
+ NewParm->setType(SemaRef.adjustParameterType(NewParm->getType()));
+
+ // Mark the (new) default argument as uninstantiated (if any).
+ if (OldParm->hasUninstantiatedDefaultArg()) {
+ Expr *Arg = OldParm->getUninstantiatedDefaultArg();
+ NewParm->setUninstantiatedDefaultArg(Arg);
+ } else if (Expr *Arg = OldParm->getDefaultArg())
+ NewParm->setUninstantiatedDefaultArg(Arg);
+
+ SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParm, NewParm);
+ return NewParm;
+}
+
QualType
TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB,
TemplateTypeParmTypeLoc TL,
OpenPOWER on IntegriCloud