diff options
author | Anders Carlsson <andersca@mac.com> | 2009-08-25 03:18:48 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2009-08-25 03:18:48 +0000 |
commit | 4562f1f0668f0fbbaecc225a5c22654809f8cc56 (patch) | |
tree | 2a5670d75eb93b28974a74b2a30848121d415447 /clang/lib | |
parent | 86f72fc3d92ca02d9ff8cd95746ae3a6f7907457 (diff) | |
download | bcm5719-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.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 14 |
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. |