Basic support for default argument expressions for function templates.
llvm-svn: 79972
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 5452963..0ddf8b0 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -117,7 +117,7 @@
// 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 @@
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 04a1505..013273c 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2500,6 +2500,33 @@
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 ded49b3..86b1cbd 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -591,16 +591,6 @@
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 @@
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.