[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