diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-02-10 00:53:15 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-02-10 00:53:15 +0000 |
commit | 8b642592a35167a3780074e78674e0bece87c40c (patch) | |
tree | e0ae2fbbb5ae014d68d4a54e1270235928db8fd6 /lib/Parse/ParseTentative.cpp | |
parent | dd0574e76439f31c02ba54bd7708725176f9531f (diff) |
Teach the type-id/expression disambiguator about different
disambiguation contexts, so that we properly parse template arguments
such as
A<int()>
as type-ids rather than as expressions. Since this can be confusing
(especially when the template parameter is a non-type template
parameter), we try to give a friendly error message.
Almost, eliminate a redundant error message (that should have been a
note) and add some ultra-basic checks for non-type template
arguments.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64189 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Parse/ParseTentative.cpp')
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 445dd8b6ef..06c136df91 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -270,16 +270,24 @@ bool Parser::isCXXConditionDeclaration() { return TPR == TPResult::True(); } -/// isCXXTypeIdInParens - Assumes that a '(' was parsed and now we want to -/// know whether the parens contain an expression or a type-id. -/// Returns true for a type-id and false for an expression. -/// If during the disambiguation process a parsing error is encountered, -/// the function returns true to let the declaration parsing code handle it. -/// -/// type-id: -/// type-specifier-seq abstract-declarator[opt] -/// -bool Parser::isCXXTypeIdInParens() { + /// \brief Determine whether the next set of tokens contains a type-id. + /// + /// The context parameter states what context we're parsing right + /// now, which affects how this routine copes with the token + /// following the type-id. If the context is TypeIdInParens, we have + /// already parsed the '(' and we will cease lookahead when we hit + /// the corresponding ')'. If the context is + /// TypeIdAsTemplateArgument, we've already parsed the '<' or ',' + /// before this template argument, and will cease lookahead when we + /// hit a '>', '>>' (in C++0x), or ','. Returns true for a type-id + /// and false for an expression. If during the disambiguation + /// process a parsing error is encountered, the function returns + /// true to let the declaration parsing code handle it. + /// + /// type-id: + /// type-specifier-seq abstract-declarator[opt] + /// +bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context) { // C++ 8.2p2: // The ambiguity arising from the similarity between a function-style cast and @@ -318,7 +326,14 @@ bool Parser::isCXXTypeIdInParens() { if (TPR == TPResult::Ambiguous()) { // We are supposed to be inside parens, so if after the abstract declarator // we encounter a ')' this is a type-id, otherwise it's an expression. - if (Tok.is(tok::r_paren)) + if (Context == TypeIdInParens && Tok.is(tok::r_paren)) + TPR = TPResult::True(); + // We are supposed to be inside a template argument, so if after + // the abstract declarator we encounter a '>', '>>' (in C++0x), or + // ',', this is a type-id. Otherwise, it's an expression. + else if (Context == TypeIdAsTemplateArgument && + (Tok.is(tok::greater) || Tok.is(tok::comma) || + (getLang().CPlusPlus0x && Tok.is(tok::greatergreater)))) TPR = TPResult::True(); else TPR = TPResult::False(); |