summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-08-25 03:18:48 +0000
committerAnders Carlsson <andersca@mac.com>2009-08-25 03:18:48 +0000
commit4562f1f0668f0fbbaecc225a5c22654809f8cc56 (patch)
tree2a5670d75eb93b28974a74b2a30848121d415447 /clang/lib
parent86f72fc3d92ca02d9ff8cd95746ae3a6f7907457 (diff)
downloadbcm5719-llvm-4562f1f0668f0fbbaecc225a5c22654809f8cc56.tar.gz
bcm5719-llvm-4562f1f0668f0fbbaecc225a5c22654809f8cc56.zip
Basic support for default argument expressions for function templates.
llvm-svn: 79972
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp27
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp14
3 files changed, 33 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5452963fad0..0ddf8b0a775 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -117,7 +117,7 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
// copy-initialization semantics (8.5).
if (CheckInitializerTypes(Arg, ParamType, EqualLoc,
Param->getDeclName(), /*DirectInit=*/false))
- return false;
+ return true;
Arg = MaybeCreateCXXExprWithTemporaries(Arg, /*DestroyTemps=*/false);
@@ -126,7 +126,7 @@ Sema::SetParamDefaultArgument(ParmVarDecl *Param, ExprArg DefaultArg,
DefaultArg.release();
- return true;
+ return false;
}
/// ActOnParamDefaultArgument - Check whether the default argument
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 04a15054430..013273cd8c0 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2500,6 +2500,33 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
Diag(UnparsedDefaultArgLocs[Param],
diag::note_default_argument_declared_here);
} else {
+ if (Param->hasUninstantiatedDefaultArg()) {
+ Expr *UninstExpr = Param->getUninstantiatedDefaultArg();
+
+ // Instantiate the expression.
+ const TemplateArgumentList &ArgList =
+ getTemplateInstantiationArgs(FDecl);
+
+ // FIXME: We should really make a new InstantiatingTemplate ctor
+ // that has a better message - right now we're just piggy-backing
+ // off the "default template argument" error message.
+ InstantiatingTemplate Inst(*this, Call->getSourceRange().getBegin(),
+ FDecl->getPrimaryTemplate(),
+ ArgList.getFlatArgumentList(),
+ ArgList.flat_size());
+
+ OwningExprResult Result
+ = InstantiateExpr(UninstExpr,
+ getTemplateInstantiationArgs(FDecl));
+ if (Result.isInvalid())
+ return true;
+
+ if (SetParamDefaultArgument(Param, move(Result),
+ /*FIXME:EqualLoc*/
+ UninstExpr->getSourceRange().getBegin()))
+ return true;
+ }
+
Expr *DefaultExpr = Param->getDefaultArg();
// If the default expression creates temporaries, we need to
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index ded49b33ab1..86b1cbdf9d1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -591,16 +591,6 @@ ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
QualType T = SemaRef.adjustParameterType(OrigT);
- if (D->getDefaultArg()) {
- // FIXME: Leave a marker for "uninstantiated" default
- // arguments. They only get instantiated on demand at the call
- // site.
- unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
- "sorry, dropping default argument during template instantiation");
- SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
- << D->getDefaultArg()->getSourceRange();
- }
-
// Allocate the parameter
ParmVarDecl *Param = 0;
if (T == OrigT)
@@ -613,6 +603,10 @@ ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
T, D->getDeclaratorInfo(), OrigT,
D->getStorageClass(), 0);
+ // Mark the default argument as being uninstantiated.
+ 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.
OpenPOWER on IntegriCloud