aboutsummaryrefslogtreecommitdiff
path: root/lib/Parse/ParseTentative.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Parse/ParseTentative.cpp')
-rw-r--r--lib/Parse/ParseTentative.cpp53
1 files changed, 40 insertions, 13 deletions
diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp
index 40c4eee1994b..5e0ef2b83f67 100644
--- a/lib/Parse/ParseTentative.cpp
+++ b/lib/Parse/ParseTentative.cpp
@@ -184,6 +184,9 @@ Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
return TPResult::Ambiguous();
}
+/// Tentatively parse an init-declarator-list in order to disambiguate it from
+/// an expression.
+///
/// init-declarator-list:
/// init-declarator
/// init-declarator-list ',' init-declarator
@@ -192,14 +195,21 @@ Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
/// declarator initializer[opt]
/// [GNU] declarator simple-asm-expr[opt] attributes[opt] initializer[opt]
///
-/// initializer:
-/// '=' initializer-clause
-/// '(' expression-list ')'
+/// initializer:
+/// brace-or-equal-initializer
+/// '(' expression-list ')'
+///
+/// brace-or-equal-initializer:
+/// '=' initializer-clause
+/// [C++11] braced-init-list
+///
+/// initializer-clause:
+/// assignment-expression
+/// braced-init-list
///
-/// initializer-clause:
-/// assignment-expression
-/// '{' initializer-list ','[opt] '}'
-/// '{' '}'
+/// braced-init-list:
+/// '{' initializer-list ','[opt] '}'
+/// '{' '}'
///
Parser::TPResult Parser::TryParseInitDeclaratorList() {
while (1) {
@@ -218,6 +228,10 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() {
ConsumeParen();
if (!SkipUntil(tok::r_paren))
return TPResult::Error();
+ } else if (Tok.is(tok::l_brace)) {
+ // A left-brace here is sufficient to disambiguate the parse; an
+ // expression can never be followed directly by a braced-init-list.
+ return TPResult::True();
} else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
// MSVC and g++ won't examine the rest of declarators if '=' is
// encountered; they just conclude that we have a declaration.
@@ -295,7 +309,7 @@ bool Parser::isCXXConditionDeclaration() {
if (Tok.is(tok::equal) ||
Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
TPR = TPResult::True();
- else if (getLangOpts().CPlusPlus0x && Tok.is(tok::l_brace))
+ else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
TPR = TPResult::True();
else
TPR = TPResult::False();
@@ -379,7 +393,7 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
// ',', this is a type-id. Otherwise, it's an expression.
} else if (Context == TypeIdAsTemplateArgument &&
(Tok.is(tok::greater) || Tok.is(tok::comma) ||
- (getLangOpts().CPlusPlus0x && Tok.is(tok::greatergreater)))) {
+ (getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) {
TPR = TPResult::True();
isAmbiguous = true;
@@ -837,6 +851,15 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
case tok::kw___vector:
case tok::kw___pixel:
case tok::kw__Atomic:
+ case tok::kw_image1d_t:
+ case tok::kw_image1d_array_t:
+ case tok::kw_image1d_buffer_t:
+ case tok::kw_image2d_t:
+ case tok::kw_image2d_array_t:
+ case tok::kw_image3d_t:
+ case tok::kw_sampler_t:
+ case tok::kw_event_t:
+ case tok::kw___unknown_anytype:
return TPResult::False();
default:
@@ -976,6 +999,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// to types and identifiers, in order to try to recover from errors.
CorrectionCandidateCallback TypoCorrection;
TypoCorrection.WantRemainingKeywords = false;
+ TypoCorrection.WantTypeSpecifiers = Next.isNot(tok::arrow);
switch (TryAnnotateName(false /* no nested name specifier */,
&TypoCorrection)) {
case ANK_Error:
@@ -1056,6 +1080,9 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// Modules
case tok::kw___module_private__:
+
+ // Debugger support
+ case tok::kw___unknown_anytype:
// type-specifier:
// simple-type-specifier
@@ -1212,7 +1239,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
if (isFollowedByParen)
return TPResult::Ambiguous();
- if (getLangOpts().CPlusPlus0x && isFollowedByBrace)
+ if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
return BracedCastResult;
return TPResult::True();
@@ -1244,7 +1271,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
// enum E : int { a = 4 }; // enum
// enum E : int { 4 }; // bit-field
// };
- if (getLangOpts().CPlusPlus0x && NextToken().is(tok::l_brace))
+ if (getLangOpts().CPlusPlus11 && NextToken().is(tok::l_brace))
return BracedCastResult;
if (isStartOfObjCClassMessageMissingOpenBracket())
@@ -1271,7 +1298,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
if (isFollowedByParen)
return TPResult::Ambiguous();
- if (getLangOpts().CPlusPlus0x && isFollowedByBrace)
+ if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
return BracedCastResult;
return TPResult::True();
@@ -1386,7 +1413,7 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
if (Next.is(tok::amp) || Next.is(tok::ampamp) ||
Next.is(tok::kw_const) || Next.is(tok::kw_volatile) ||
Next.is(tok::kw_throw) || Next.is(tok::kw_noexcept) ||
- Next.is(tok::l_square) || isCXX0XVirtSpecifier(Next) ||
+ Next.is(tok::l_square) || isCXX11VirtSpecifier(Next) ||
Next.is(tok::l_brace) || Next.is(tok::kw_try) ||
Next.is(tok::equal) || Next.is(tok::arrow))
// The next token cannot appear after a constructor-style initializer,