[cfe-commits] r92078 - in /cfe/trunk: include/clang/AST/ExprCXX.h lib/AST/ExprCXX.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/TreeTransform.h test/SemaTemplate/default-expr-arguments.cpp

Douglas Gregor dgregor at apple.com
Wed Dec 23 15:03:06 PST 2009


Author: dgregor
Date: Wed Dec 23 17:03:06 2009
New Revision: 92078

URL: http://llvm.org/viewvc/llvm-project?rev=92078&view=rev
Log:
When we see a CXXDefaultArgExpr during template instantiation, rebuild
the default argument so that we're sure to mark any referenced
declarations. This gets us another little step closer to fixing
PR5810.

Modified:
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/lib/AST/ExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=92078&r1=92077&r2=92078&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Wed Dec 23 17:03:06 2009
@@ -393,16 +393,20 @@
   /// actual default expression is the subexpression.
   llvm::PointerIntPair<ParmVarDecl *, 1, bool> Param;
 
+  /// \brief The location where the default argument expression was used.
+  SourceLocation Loc;
+  
 protected:
-  CXXDefaultArgExpr(StmtClass SC, ParmVarDecl *param)
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param)
     : Expr(SC, 
            param->hasUnparsedDefaultArg()
              ? param->getType().getNonReferenceType()
              : param->getDefaultArg()->getType()),
-      Param(param, false) { }
+      Param(param, false), Loc(Loc) { }
 
-  CXXDefaultArgExpr(StmtClass SC, ParmVarDecl *param, Expr *SubExpr)
-    : Expr(SC, SubExpr->getType()), Param(param, true) 
+  CXXDefaultArgExpr(StmtClass SC, SourceLocation Loc, ParmVarDecl *param, 
+                    Expr *SubExpr)
+    : Expr(SC, SubExpr->getType()), Param(param, true), Loc(Loc)
   {
     *reinterpret_cast<Expr **>(this + 1) = SubExpr;
   }
@@ -413,13 +417,16 @@
 public:
   // Param is the parameter whose default argument is used by this
   // expression.
-  static CXXDefaultArgExpr *Create(ASTContext &C, ParmVarDecl *Param) {
-    return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Param);
+  static CXXDefaultArgExpr *Create(ASTContext &C, SourceLocation Loc,
+                                   ParmVarDecl *Param) {
+    return new (C) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param);
   }
 
   // Param is the parameter whose default argument is used by this
   // expression, and SubExpr is the expression that will actually be used.
-  static CXXDefaultArgExpr *Create(ASTContext &C, ParmVarDecl *Param, 
+  static CXXDefaultArgExpr *Create(ASTContext &C, 
+                                   SourceLocation Loc,
+                                   ParmVarDecl *Param, 
                                    Expr *SubExpr);
   
   // Retrieve the parameter that the argument was created from.
@@ -438,6 +445,10 @@
     return getParam()->getDefaultArg(); 
   }
 
+  /// \brief Retrieve the location where this default argument was actually 
+  /// used.
+  SourceLocation getUsedLocation() const { return Loc; }
+  
   virtual SourceRange getSourceRange() const {
     // Default argument expressions have no representation in the
     // source, so they have an empty source range.

Modified: cfe/trunk/lib/AST/ExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=92078&r1=92077&r2=92078&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ExprCXX.cpp (original)
+++ cfe/trunk/lib/AST/ExprCXX.cpp Wed Dec 23 17:03:06 2009
@@ -353,9 +353,11 @@
 }
 
 CXXDefaultArgExpr *
-CXXDefaultArgExpr::Create(ASTContext &C, ParmVarDecl *Param, Expr *SubExpr) {
+CXXDefaultArgExpr::Create(ASTContext &C, SourceLocation Loc, 
+                          ParmVarDecl *Param, Expr *SubExpr) {
   void *Mem = C.Allocate(sizeof(CXXDefaultArgExpr) + sizeof(Stmt *));
-  return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Param, SubExpr);
+  return new (Mem) CXXDefaultArgExpr(CXXDefaultArgExprClass, Loc, Param, 
+                                     SubExpr);
 }
 
 void CXXDefaultArgExpr::DoDestroy(ASTContext &C) {

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Dec 23 17:03:06 2009
@@ -3093,7 +3093,7 @@
         return ExprError();
       
       // Build the default argument expression.
-      return Owned(CXXDefaultArgExpr::Create(Context, Param,
+      return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param,
                                              Result.takeAs<Expr>()));
     }
 
@@ -3107,7 +3107,7 @@
   }
 
   // We already type-checked the argument, so we know it works.
-  return Owned(CXXDefaultArgExpr::Create(Context, Param));
+  return Owned(CXXDefaultArgExpr::Create(Context, CallLoc, Param));
 }
 
 /// ConvertArgumentsForCall - Converts the arguments specified in

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

==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Wed Dec 23 17:03:06 2009
@@ -785,7 +785,9 @@
   assert(!cast<FunctionDecl>(E->getParam()->getDeclContext())->
              getDescribedFunctionTemplate() &&
          "Default arg expressions are never formed in dependent cases.");
-  return SemaRef.Owned(E->Retain());
+  return SemaRef.BuildCXXDefaultArgExpr(E->getUsedLocation(),
+                           cast<FunctionDecl>(E->getParam()->getDeclContext()), 
+                                        E->getParam());
 }
 
 

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=92078&r1=92077&r2=92078&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Wed Dec 23 17:03:06 2009
@@ -1358,8 +1358,10 @@
   /// By default, builds a new default-argument expression, which does not
   /// require any semantic analysis. Subclasses may override this routine to
   /// provide different behavior.
-  OwningExprResult RebuildCXXDefaultArgExpr(ParmVarDecl *Param) {
-    return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Param));
+  OwningExprResult RebuildCXXDefaultArgExpr(SourceLocation Loc, 
+                                            ParmVarDecl *Param) {
+    return getSema().Owned(CXXDefaultArgExpr::Create(getSema().Context, Loc,
+                                                     Param));
   }
 
   /// \brief Build a new C++ zero-initialization expression.
@@ -4416,7 +4418,7 @@
       Param == E->getParam())
     return SemaRef.Owned(E->Retain());
 
-  return getDerived().RebuildCXXDefaultArgExpr(Param);
+  return getDerived().RebuildCXXDefaultArgExpr(E->getUsedLocation(), Param);
 }
 
 template<typename Derived>

Modified: cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp?rev=92078&r1=92077&r2=92078&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp (original)
+++ cfe/trunk/test/SemaTemplate/default-expr-arguments.cpp Wed Dec 23 17:03:06 2009
@@ -147,16 +147,17 @@
 namespace PR5810 {
   template<typename T>
   struct allocator {
-    allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error{{array size is negative}}
+    allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error2 {{array size is negative}}
   };
   
   template<typename T>
   struct vector {
-    vector(const allocator<T>& = allocator<T>()) {} // expected-note{{instantiation of}}
+    vector(const allocator<T>& = allocator<T>()) {} // expected-note2 {{instantiation of}}
   };
   
   struct A { };
-  
+  struct B { };
+
   template<typename>
   void FilterVTs() {
     vector<A> Result;
@@ -165,4 +166,14 @@
   void f() {
     vector<A> Result;
   }
+
+  template<typename T>
+  struct X {
+    vector<B> bs;
+    X() { }
+  };
+
+  void f2() {
+    X<float> x; // expected-note{{member function}}
+  }
 }





More information about the cfe-commits mailing list