diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-07-22 23:48:44 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-07-22 23:48:44 +0000 |
commit | 7cdbc5832084f45721693dfb1d93284c3e08efee (patch) | |
tree | 1c31b6a6580709273dc40913ee491c7f44e86eaa /lib/Parse/ParseTemplate.cpp | |
parent | 6016cb2d1e99960675e4c4bb97f6f4ecdff97818 (diff) |
Implement support for out-of-line definitions of the class members of class
templates, e.g.,
template<typename T>
struct Outer {
struct Inner;
};
template<typename T>
struct Outer<T>::Inner {
// ...
};
Implementing this feature required some extensions to ActOnTag, which
now takes a set of template parameter lists, and is the precursor to
removing the ActOnClassTemplate function from the parser Action
interface. The reason for this approach is simple: the parser cannot
tell the difference between a class template definition and the
definition of a member of a class template; both have template
parameter lists, and semantic analysis determines what that template
parameter list means.
There is still some cleanup to do with ActOnTag and
ActOnClassTemplate. This commit provides the basic functionality we
need, however.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76820 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTemplate.cpp')
-rw-r--r-- | lib/Parse/ParseTemplate.cpp | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp index 57a09fbc73..df7c22cf26 100644 --- a/lib/Parse/ParseTemplate.cpp +++ b/lib/Parse/ParseTemplate.cpp @@ -96,9 +96,15 @@ Parser::ParseTemplateDeclarationOrSpecialization(unsigned Context, // Parse the '<' template-parameter-list '>' SourceLocation LAngleLoc, RAngleLoc; TemplateParameterList TemplateParams; - ParseTemplateParameters(ParamLists.size(), TemplateParams, LAngleLoc, - RAngleLoc); - + if (ParseTemplateParameters(ParamLists.size(), TemplateParams, LAngleLoc, + RAngleLoc)) { + // Skip until the semi-colon or a }. + SkipUntil(tok::r_brace, true, true); + if (Tok.is(tok::semi)) + ConsumeToken(); + return DeclPtrTy(); + } + if (!TemplateParams.empty()) isSpecialiation = false; @@ -219,6 +225,8 @@ Parser::ParseSingleDeclarationAfterTemplate( /// The template parameter we parse will be added to this list. LAngleLoc and /// RAngleLoc will receive the positions of the '<' and '>', respectively, /// that enclose this template parameter list. +/// +/// \returns true if an error occurred, false otherwise. bool Parser::ParseTemplateParameters(unsigned Depth, TemplateParameterList &TemplateParams, SourceLocation &LAngleLoc, @@ -226,7 +234,7 @@ bool Parser::ParseTemplateParameters(unsigned Depth, // Get the template parameter list. if(!Tok.is(tok::less)) { Diag(Tok.getLocation(), diag::err_expected_less_after) << "template"; - return false; + return true; } LAngleLoc = ConsumeToken(); @@ -236,11 +244,11 @@ bool Parser::ParseTemplateParameters(unsigned Depth, else if(ParseTemplateParameterList(Depth, TemplateParams)) { if(!Tok.is(tok::greater)) { Diag(Tok.getLocation(), diag::err_expected_greater); - return false; + return true; } RAngleLoc = ConsumeToken(); } - return true; + return false; } /// ParseTemplateParameterList - Parse a template parameter list. If @@ -392,8 +400,8 @@ Parser::ParseTemplateTemplateParameter(unsigned Depth, unsigned Position) { SourceLocation LAngleLoc, RAngleLoc; { ParseScope TemplateParmScope(this, Scope::TemplateParamScope); - if(!ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc, - RAngleLoc)) { + if(ParseTemplateParameters(Depth + 1, TemplateParams, LAngleLoc, + RAngleLoc)) { return DeclPtrTy(); } } |