[cfe-commits] r79972 - in /cfe/trunk: lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/default-expr-arguments.cpp

Anders Carlsson andersca at mac.com
Mon Aug 24 20:18:49 PDT 2009


Author: andersca
Date: Mon Aug 24 22:18:48 2009
New Revision: 79972

URL: http://llvm.org/viewvc/llvm-project?rev=79972&view=rev
Log:
Basic support for default argument expressions for function templates.

Added:
    cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp
Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=79972&r1=79971&r2=79972&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Aug 24 22:18:48 2009
@@ -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

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=79972&r1=79971&r2=79972&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Aug 24 22:18:48 2009
@@ -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

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=79972&r1=79971&r2=79972&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Aug 24 22:18:48 2009
@@ -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.

Added: cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp?rev=79972&view=auto

==============================================================================
--- cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp (added)
+++ cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp Mon Aug 24 22:18:48 2009
@@ -0,0 +1,20 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+struct S { };
+
+template<typename T> void f1(T a, T b = 10) { } // expected-error{{cannot initialize 'b' with an rvalue of type 'int'}}
+
+template<typename T> void f2(T a, T b = T()) { }
+
+template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid operands to binary expression ('struct S' and 'struct S')}}
+
+void g() {
+  f1(10);
+  f1(S()); // expected-note{{in instantiation of default argument for 'f1<struct S>' required here}}
+  
+  f2(10);
+  f2(S());
+  
+  f3(10);
+  f3(S()); // expected-note{{in instantiation of default argument for 'f3<struct S>' required here}}
+}





More information about the cfe-commits mailing list