[cfe-commits] r79955 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp test/SemaTemplate/nested-template.cpp

Douglas Gregor dgregor at apple.com
Mon Aug 24 16:03:25 PDT 2009


Author: dgregor
Date: Mon Aug 24 18:03:25 2009
New Revision: 79955

URL: http://llvm.org/viewvc/llvm-project?rev=79955&view=rev
Log:
Keep track of the template parameter depth properly when we have
member templates declared inside other templates. This allows us to
match out-of-line definitions of member function templates within
class templates to the declarations within the class template. We
still can't handle out-of-line definitions for member class templates,
however.


Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/test/SemaTemplate/nested-template.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=79955&r1=79954&r2=79955&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Mon Aug 24 18:03:25 2009
@@ -90,6 +90,9 @@
   /// argument list.
   bool GreaterThanIsOperator;
 
+  /// The "depth" of the template parameters currently being parsed.
+  unsigned TemplateParameterDepth;
+  
   /// \brief RAII object that makes '>' behave either as an operator
   /// or as the closing angle bracket for a template argument list.
   struct GreaterThanIsOperatorScope {

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=79955&r1=79954&r2=79955&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Aug 24 18:03:25 2009
@@ -15,6 +15,7 @@
 #include "clang/Parse/ParseDiagnostic.h"
 #include "clang/Parse/DeclSpec.h"
 #include "clang/Parse/Scope.h"
+#include "llvm/Support/Compiler.h"
 using namespace clang;
 
 /// \brief Parse a template declaration, explicit instantiation, or
@@ -29,6 +30,29 @@
   return ParseTemplateDeclarationOrSpecialization(Context, DeclEnd, AS);
 }
 
+/// \brief RAII class that manages the template parameter depth.
+namespace {
+  class VISIBILITY_HIDDEN TemplateParameterDepthCounter {
+    unsigned &Depth;
+    unsigned AddedLevels;
+
+  public:
+    explicit TemplateParameterDepthCounter(unsigned &Depth) 
+      : Depth(Depth), AddedLevels(0) { }
+    
+    ~TemplateParameterDepthCounter() {
+      Depth -= AddedLevels;
+    }
+    
+    void operator++() { 
+      ++Depth;
+      ++AddedLevels;
+    }
+    
+    operator unsigned() const { return Depth; }
+  };
+}
+
 /// \brief Parse a template declaration or an explicit specialization.
 ///
 /// Template declarations include one or more template parameter lists
@@ -77,6 +101,7 @@
   // context).
   bool isSpecialization = true;
   TemplateParameterLists ParamLists;
+  TemplateParameterDepthCounter Depth(TemplateParameterDepth);
   do {
     // Consume the 'export', if any.
     SourceLocation ExportLoc;
@@ -96,7 +121,7 @@
     // Parse the '<' template-parameter-list '>'
     SourceLocation LAngleLoc, RAngleLoc;
     TemplateParameterList TemplateParams;
-    if (ParseTemplateParameters(ParamLists.size(), TemplateParams, LAngleLoc, 
+    if (ParseTemplateParameters(Depth, TemplateParams, LAngleLoc, 
                                 RAngleLoc)) {
       // Skip until the semi-colon or a }.
       SkipUntil(tok::r_brace, true, true);
@@ -104,15 +129,17 @@
         ConsumeToken();
       return DeclPtrTy();      
     }
-      
-    if (!TemplateParams.empty())
-      isSpecialization = false;
 
     ParamLists.push_back(
-      Actions.ActOnTemplateParameterList(ParamLists.size(), ExportLoc, 
+      Actions.ActOnTemplateParameterList(Depth, ExportLoc, 
                                          TemplateLoc, LAngleLoc, 
                                          TemplateParams.data(),
                                          TemplateParams.size(), RAngleLoc));
+
+    if (!TemplateParams.empty()) {
+      isSpecialization = false;
+      ++Depth;
+    }    
   } while (Tok.is(tok::kw_export) || Tok.is(tok::kw_template));
 
   // Parse the actual template declaration.

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=79955&r1=79954&r2=79955&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Mon Aug 24 18:03:25 2009
@@ -35,7 +35,7 @@
 
 Parser::Parser(Preprocessor &pp, Action &actions)
   : CrashInfo(*this), PP(pp), Actions(actions), Diags(PP.getDiagnostics()), 
-    GreaterThanIsOperator(true) {
+    TemplateParameterDepth(0), GreaterThanIsOperator(true) {
   Tok.setKind(tok::eof);
   CurScope = 0;
   NumCachedScopes = 0;

Modified: cfe/trunk/test/SemaTemplate/nested-template.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/nested-template.cpp?rev=79955&r1=79954&r2=79955&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/nested-template.cpp (original)
+++ cfe/trunk/test/SemaTemplate/nested-template.cpp Mon Aug 24 18:03:25 2009
@@ -14,3 +14,17 @@
 int i;
 S::A<int>::Nested::type *ip = &i;
 
+template<typename T>
+struct X0 {
+  template<typename U> void f0(T, U);
+  
+  template<typename U>
+  struct Inner0 {
+    void f1(T, U);
+  };
+};
+
+template<typename X> template<typename Y> void X0<X>::f0(X, Y) { }
+
+// FIXME:
+// template<typename X> template<typename Y> void X0<X>::Inner0<Y>::f1(X, Y) { }





More information about the cfe-commits mailing list