[cfe-commits] r116324 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiate.cpp test/CXX/class/class.mem/p1.cpp

Douglas Gregor dgregor at apple.com
Tue Oct 12 11:23:32 PDT 2010


Author: dgregor
Date: Tue Oct 12 13:23:32 2010
New Revision: 116324

URL: http://llvm.org/viewvc/llvm-project?rev=116324&view=rev
Log:
If we end up instantiating a function parameter whose default argument
has not yet been parsed, note that the default argument hasn't been
parsed and keep track of all of the instantiations of that function
parameter. When its default argument does get parsed, imbue the
instantiations with that default argument. Fixes PR8245.

Modified:
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/test/CXX/class/class.mem/p1.cpp

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=116324&r1=116323&r2=116324&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Tue Oct 12 13:23:32 2010
@@ -484,6 +484,22 @@
   /// \brief The number of SFINAE diagnostics that have been trapped.
   unsigned NumSFINAEErrors;
 
+  typedef llvm::DenseMap<ParmVarDecl *, llvm::SmallVector<ParmVarDecl *, 1> >
+    UnparsedDefaultArgInstantiationsMap;
+  
+  /// \brief A mapping from parameters with unparsed default arguments to the
+  /// set of instantiations of each parameter.
+  ///
+  /// This mapping is a temporary data structure used when parsing
+  /// nested class templates or nested classes of class templates,
+  /// where we might end up instantiating an inner class before the
+  /// default arguments of its methods have been parsed. 
+  UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations;
+  
+  // Contains the locations of the beginning of unparsed default
+  // argument locations.
+  llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
+
   typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
   typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
 
@@ -497,7 +513,6 @@
   /// of -Wselector.
   llvm::DenseMap<Selector, SourceLocation> ReferencedSelectors;
 
-
   GlobalMethodPool::iterator ReadMethodPool(Selector Sel);
 
   /// Private Helper predicate to check for 'self'.
@@ -723,11 +738,6 @@
   bool SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg,
                                SourceLocation EqualLoc);
 
-
-  // Contains the locations of the beginning of unparsed default
-  // argument locations.
-  llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
-
   void AddInitializerToDecl(Decl *dcl, Expr *init);
   void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit);
   void ActOnUninitializedDecl(Decl *dcl, bool TypeContainsUndeducedAuto);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=116324&r1=116323&r2=116324&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Oct 12 13:23:32 2010
@@ -142,6 +142,18 @@
   // Okay: add the default argument to the parameter
   Param->setDefaultArg(Arg);
 
+  // We have already instantiated this parameter; provide each of the 
+  // instantiations with the uninstantiated default argument.
+  UnparsedDefaultArgInstantiationsMap::iterator InstPos
+    = UnparsedDefaultArgInstantiations.find(Param);
+  if (InstPos != UnparsedDefaultArgInstantiations.end()) {
+    for (unsigned I = 0, N = InstPos->second.size(); I != N; ++I)
+      InstPos->second[I]->setUninstantiatedDefaultArg(Arg);
+    
+    // We're done tracking this parameter's instantiations.
+    UnparsedDefaultArgInstantiations.erase(InstPos);
+  }
+  
   return false;
 }
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=116324&r1=116323&r2=116324&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Tue Oct 12 13:23:32 2010
@@ -1062,6 +1062,9 @@
   if (OldParm->hasUninstantiatedDefaultArg()) {
     Expr *Arg = OldParm->getUninstantiatedDefaultArg();
     NewParm->setUninstantiatedDefaultArg(Arg);
+  } else if (OldParm->hasUnparsedDefaultArg()) {
+    NewParm->setUnparsedDefaultArg();
+    UnparsedDefaultArgInstantiations[OldParm].push_back(NewParm);
   } else if (Expr *Arg = OldParm->getDefaultArg())
     NewParm->setUninstantiatedDefaultArg(Arg);
 

Modified: cfe/trunk/test/CXX/class/class.mem/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.mem/p1.cpp?rev=116324&r1=116323&r2=116324&view=diff
==============================================================================
--- cfe/trunk/test/CXX/class/class.mem/p1.cpp (original)
+++ cfe/trunk/test/CXX/class/class.mem/p1.cpp Tue Oct 12 13:23:32 2010
@@ -62,3 +62,30 @@
   
   
 };
+
+namespace PR8245 {
+  class X {
+  public:
+    template<class C> 
+    class Inner {
+    public:
+      void foo(bool bar = true);
+      int bam;
+    };
+
+    Inner<int> _foo;    
+  };
+
+  void f() {
+    X::Inner<int> c2i;
+    X::Inner<float> c2f;
+    c2i.foo();
+    c2f.foo();
+  }
+
+  class Y {
+    class Inner {
+      void foo(int = sizeof(Y));
+    };
+  };
+}





More information about the cfe-commits mailing list