diff options
Diffstat (limited to 'lib/Parse/ParseTentative.cpp')
-rw-r--r-- | lib/Parse/ParseTentative.cpp | 53 |
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, |