aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTemplate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-08-24 23:03:25 +0000
committerDouglas Gregor <dgregor@apple.com>2009-08-24 23:03:25 +0000
commitc3058338075a2132e057f1249a13b55a81fe021c (patch)
tree350915cbf9c66e62dcd5ab5d44c9b235e045910e /lib/Parse/ParseTemplate.cpp
parentac50213ec509063151bc1a9c6b7d71561896cdd5 (diff)
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. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@79955 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r--lib/Parse/ParseTemplate.cpp37
1 files changed, 32 insertions, 5 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index b2b7ed06e2..34cabfd7ad 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -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 @@ Parser::ParseDeclarationStartingWithTemplate(unsigned Context,
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 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
// context).
bool isSpecialization = true;
TemplateParameterLists ParamLists;
+ TemplateParameterDepthCounter Depth(TemplateParameterDepth);
do {
// Consume the 'export', if any.
SourceLocation ExportLoc;
@@ -96,7 +121,7 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
// 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 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context,
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.