forked from OSchip/llvm-project
Replace a fake enum class with the real thing.
llvm-svn: 208943
This commit is contained in:
parent
218f71e148
commit
ee390436b9
|
@ -1792,7 +1792,7 @@ private:
|
||||||
/// cast. Return false if it's no a decl-specifier, or we're not sure.
|
/// cast. Return false if it's no a decl-specifier, or we're not sure.
|
||||||
bool isKnownToBeDeclarationSpecifier() {
|
bool isKnownToBeDeclarationSpecifier() {
|
||||||
if (getLangOpts().CPlusPlus)
|
if (getLangOpts().CPlusPlus)
|
||||||
return isCXXDeclarationSpecifier() == TPResult::True();
|
return isCXXDeclarationSpecifier() == TPResult::True;
|
||||||
return isDeclarationSpecifier(true);
|
return isDeclarationSpecifier(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1892,25 +1892,8 @@ private:
|
||||||
|
|
||||||
/// TPResult - Used as the result value for functions whose purpose is to
|
/// TPResult - Used as the result value for functions whose purpose is to
|
||||||
/// disambiguate C++ constructs by "tentatively parsing" them.
|
/// disambiguate C++ constructs by "tentatively parsing" them.
|
||||||
/// This is a class instead of a simple enum because the implicit enum-to-bool
|
enum class TPResult {
|
||||||
/// conversions may cause subtle bugs.
|
True, False, Ambiguous, Error
|
||||||
class TPResult {
|
|
||||||
enum Result {
|
|
||||||
TPR_true,
|
|
||||||
TPR_false,
|
|
||||||
TPR_ambiguous,
|
|
||||||
TPR_error
|
|
||||||
};
|
|
||||||
Result Res;
|
|
||||||
TPResult(Result result) : Res(result) {}
|
|
||||||
public:
|
|
||||||
static TPResult True() { return TPR_true; }
|
|
||||||
static TPResult False() { return TPR_false; }
|
|
||||||
static TPResult Ambiguous() { return TPR_ambiguous; }
|
|
||||||
static TPResult Error() { return TPR_error; }
|
|
||||||
|
|
||||||
bool operator==(const TPResult &RHS) const { return Res == RHS.Res; }
|
|
||||||
bool operator!=(const TPResult &RHS) const { return Res != RHS.Res; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/// \brief Based only on the given token kind, determine whether we know that
|
/// \brief Based only on the given token kind, determine whether we know that
|
||||||
|
@ -1925,15 +1908,15 @@ private:
|
||||||
/// tell.
|
/// tell.
|
||||||
TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
|
TPResult isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind);
|
||||||
|
|
||||||
/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a
|
/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a
|
||||||
/// declaration specifier, TPResult::False() if it is not,
|
/// declaration specifier, TPResult::False if it is not,
|
||||||
/// TPResult::Ambiguous() if it could be either a decl-specifier or a
|
/// TPResult::Ambiguous if it could be either a decl-specifier or a
|
||||||
/// function-style cast, and TPResult::Error() if a parsing error was
|
/// function-style cast, and TPResult::Error if a parsing error was
|
||||||
/// encountered. If it could be a braced C++11 function-style cast, returns
|
/// encountered. If it could be a braced C++11 function-style cast, returns
|
||||||
/// BracedCastResult.
|
/// BracedCastResult.
|
||||||
/// Doesn't consume tokens.
|
/// Doesn't consume tokens.
|
||||||
TPResult
|
TPResult
|
||||||
isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False(),
|
isCXXDeclarationSpecifier(TPResult BracedCastResult = TPResult::False,
|
||||||
bool *HasMissingTypename = nullptr);
|
bool *HasMissingTypename = nullptr);
|
||||||
|
|
||||||
/// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
|
/// Given that isCXXDeclarationSpecifier returns \c TPResult::True or
|
||||||
|
@ -1947,9 +1930,9 @@ private:
|
||||||
bool isTentativelyDeclared(IdentifierInfo *II);
|
bool isTentativelyDeclared(IdentifierInfo *II);
|
||||||
|
|
||||||
// "Tentative parsing" functions, used for disambiguation. If a parsing error
|
// "Tentative parsing" functions, used for disambiguation. If a parsing error
|
||||||
// is encountered they will return TPResult::Error().
|
// is encountered they will return TPResult::Error.
|
||||||
// Returning TPResult::True()/False() indicates that the ambiguity was
|
// Returning TPResult::True/False indicates that the ambiguity was
|
||||||
// resolved and tentative parsing may stop. TPResult::Ambiguous() indicates
|
// resolved and tentative parsing may stop. TPResult::Ambiguous indicates
|
||||||
// that more tentative parsing is necessary for disambiguation.
|
// that more tentative parsing is necessary for disambiguation.
|
||||||
// They all consume tokens, so backtracking should be used after calling them.
|
// They all consume tokens, so backtracking should be used after calling them.
|
||||||
|
|
||||||
|
|
|
@ -923,15 +923,15 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
|
||||||
? tok::semi : tok::r_paren);
|
? tok::semi : tok::r_paren);
|
||||||
Sema::TentativeAnalysisScope Scope(Actions);
|
Sema::TentativeAnalysisScope Scope(Actions);
|
||||||
|
|
||||||
TPResult Result = TPResult::Error();
|
TPResult Result = TPResult::Error;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
switch (CIK) {
|
switch (CIK) {
|
||||||
case CIK_DefaultInitializer:
|
case CIK_DefaultInitializer:
|
||||||
Result = TryParseInitDeclaratorList();
|
Result = TryParseInitDeclaratorList();
|
||||||
// If we parsed a complete, ambiguous init-declarator-list, this
|
// If we parsed a complete, ambiguous init-declarator-list, this
|
||||||
// is only syntactically-valid if it's followed by a semicolon.
|
// is only syntactically-valid if it's followed by a semicolon.
|
||||||
if (Result == TPResult::Ambiguous() && Tok.isNot(tok::semi))
|
if (Result == TPResult::Ambiguous && Tok.isNot(tok::semi))
|
||||||
Result = TPResult::False();
|
Result = TPResult::False;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CIK_DefaultArgument:
|
case CIK_DefaultArgument:
|
||||||
|
@ -940,13 +940,13 @@ bool Parser::ConsumeAndStoreInitializer(CachedTokens &Toks,
|
||||||
&InvalidAsDeclaration, /*VersusTemplateArgument*/true);
|
&InvalidAsDeclaration, /*VersusTemplateArgument*/true);
|
||||||
// If this is an expression or a declaration with a missing
|
// If this is an expression or a declaration with a missing
|
||||||
// 'typename', assume it's not a declaration.
|
// 'typename', assume it's not a declaration.
|
||||||
if (Result == TPResult::Ambiguous() && InvalidAsDeclaration)
|
if (Result == TPResult::Ambiguous && InvalidAsDeclaration)
|
||||||
Result = TPResult::False();
|
Result = TPResult::False;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If what follows could be a declaration, it is a declaration.
|
// If what follows could be a declaration, it is a declaration.
|
||||||
if (Result != TPResult::False() && Result != TPResult::Error()) {
|
if (Result != TPResult::False && Result != TPResult::Error) {
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2129,7 +2129,7 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
|
||||||
TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
|
TPResult TPR = TryParseDeclarator(/*mayBeAbstract*/false);
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
if (TPR != TPResult::False()) {
|
if (TPR != TPResult::False) {
|
||||||
// The identifier is followed by a parenthesized declarator.
|
// The identifier is followed by a parenthesized declarator.
|
||||||
// It's supposed to be a type.
|
// It's supposed to be a type.
|
||||||
break;
|
break;
|
||||||
|
@ -3563,13 +3563,13 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
||||||
TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
|
TPResult TPR = isExpressionOrTypeSpecifierSimple(NextToken().getKind());
|
||||||
// If the next token starts an expression, we know we're parsing a
|
// If the next token starts an expression, we know we're parsing a
|
||||||
// bit-field. This is the common case.
|
// bit-field. This is the common case.
|
||||||
if (TPR == TPResult::True())
|
if (TPR == TPResult::True)
|
||||||
PossibleBitfield = true;
|
PossibleBitfield = true;
|
||||||
// If the next token starts a type-specifier-seq, it may be either a
|
// If the next token starts a type-specifier-seq, it may be either a
|
||||||
// a fixed underlying type or the start of a function-style cast in C++;
|
// a fixed underlying type or the start of a function-style cast in C++;
|
||||||
// lookahead one more token to see if it's obvious that we have a
|
// lookahead one more token to see if it's obvious that we have a
|
||||||
// fixed underlying type.
|
// fixed underlying type.
|
||||||
else if (TPR == TPResult::False() &&
|
else if (TPR == TPResult::False &&
|
||||||
GetLookAheadToken(2).getKind() == tok::semi) {
|
GetLookAheadToken(2).getKind() == tok::semi) {
|
||||||
// Consume the ':'.
|
// Consume the ':'.
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
@ -3589,7 +3589,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
||||||
// FIXME: The standard is not entirely clear on how to disambiguate in
|
// FIXME: The standard is not entirely clear on how to disambiguate in
|
||||||
// this case.
|
// this case.
|
||||||
if ((getLangOpts().CPlusPlus &&
|
if ((getLangOpts().CPlusPlus &&
|
||||||
isCXXDeclarationSpecifier(TPResult::True()) != TPResult::True()) ||
|
isCXXDeclarationSpecifier(TPResult::True) != TPResult::True) ||
|
||||||
(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
|
(!getLangOpts().CPlusPlus && !isDeclarationSpecifier(true))) {
|
||||||
// We'll parse this as a bitfield later.
|
// We'll parse this as a bitfield later.
|
||||||
PossibleBitfield = true;
|
PossibleBitfield = true;
|
||||||
|
|
|
@ -1144,7 +1144,7 @@ bool Parser::IsTemplateArgumentList(unsigned Skip) {
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// See whether we have declaration specifiers, which indicate a type.
|
// See whether we have declaration specifiers, which indicate a type.
|
||||||
while (isCXXDeclarationSpecifier() == TPResult::True())
|
while (isCXXDeclarationSpecifier() == TPResult::True)
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
// If we have a '>' or a ',' then this is a template argument list.
|
// If we have a '>' or a ',' then this is a template argument list.
|
||||||
|
|
|
@ -101,15 +101,15 @@ bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
|
||||||
// an ambiguity if the first decl-specifier is
|
// an ambiguity if the first decl-specifier is
|
||||||
// simple-type-specifier/typename-specifier followed by a '(', which may
|
// simple-type-specifier/typename-specifier followed by a '(', which may
|
||||||
// indicate a function-style cast expression.
|
// indicate a function-style cast expression.
|
||||||
// isCXXDeclarationSpecifier will return TPResult::Ambiguous() only in such
|
// isCXXDeclarationSpecifier will return TPResult::Ambiguous only in such
|
||||||
// a case.
|
// a case.
|
||||||
|
|
||||||
bool InvalidAsDeclaration = false;
|
bool InvalidAsDeclaration = false;
|
||||||
TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),
|
TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
|
||||||
&InvalidAsDeclaration);
|
&InvalidAsDeclaration);
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR != TPResult::False(); // Returns true for TPResult::True() or
|
return TPR != TPResult::False; // Returns true for TPResult::True or
|
||||||
// TPResult::Error().
|
// TPResult::Error.
|
||||||
|
|
||||||
// FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
|
// FIXME: TryParseSimpleDeclaration doesn't look past the first initializer,
|
||||||
// and so gets some cases wrong. We can't carry on if we've already seen
|
// and so gets some cases wrong. We can't carry on if we've already seen
|
||||||
|
@ -131,15 +131,15 @@ bool Parser::isCXXSimpleDeclaration(bool AllowForRangeDecl) {
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
// In case of an error, let the declaration parsing code handle it.
|
// In case of an error, let the declaration parsing code handle it.
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Declarations take precedence over expressions.
|
// Declarations take precedence over expressions.
|
||||||
if (TPR == TPResult::Ambiguous())
|
if (TPR == TPResult::Ambiguous)
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
|
|
||||||
assert(TPR == TPResult::True() || TPR == TPResult::False());
|
assert(TPR == TPResult::True || TPR == TPResult::False);
|
||||||
return TPR == TPResult::True();
|
return TPR == TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to consume a token sequence that we've already identified as
|
/// Try to consume a token sequence that we've already identified as
|
||||||
|
@ -157,10 +157,10 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
|
||||||
case tok::kw___underlying_type: {
|
case tok::kw___underlying_type: {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (Tok.isNot(tok::l_paren))
|
if (Tok.isNot(tok::l_paren))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
if (!SkipUntil(tok::r_paren))
|
if (!SkipUntil(tok::r_paren))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,23 +184,23 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
|
||||||
if (Tok.is(tok::l_square)) {
|
if (Tok.is(tok::l_square)) {
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
if (!SkipUntil(tok::r_square))
|
if (!SkipUntil(tok::r_square))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
} else {
|
} else {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (Tok.isNot(tok::l_paren))
|
if (Tok.isNot(tok::l_paren))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
if (!SkipUntil(tok::r_paren))
|
if (!SkipUntil(tok::r_paren))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TryAnnotateCXXScopeToken())
|
if (TryAnnotateCXXScopeToken())
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
if (Tok.is(tok::annot_cxxscope))
|
if (Tok.is(tok::annot_cxxscope))
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
|
if (Tok.isNot(tok::identifier) && Tok.isNot(tok::annot_template_id))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// simple-declaration:
|
/// simple-declaration:
|
||||||
|
@ -227,29 +227,29 @@ Parser::TPResult Parser::TryConsumeDeclarationSpecifier() {
|
||||||
/// attribute-specifier-seqopt type-specifier-seq declarator
|
/// attribute-specifier-seqopt type-specifier-seq declarator
|
||||||
///
|
///
|
||||||
Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
|
Parser::TPResult Parser::TryParseSimpleDeclaration(bool AllowForRangeDecl) {
|
||||||
if (TryConsumeDeclarationSpecifier() == TPResult::Error())
|
if (TryConsumeDeclarationSpecifier() == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
// Two decl-specifiers in a row conclusively disambiguate this as being a
|
// Two decl-specifiers in a row conclusively disambiguate this as being a
|
||||||
// simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
|
// simple-declaration. Don't bother calling isCXXDeclarationSpecifier in the
|
||||||
// overwhelmingly common case that the next token is a '('.
|
// overwhelmingly common case that the next token is a '('.
|
||||||
if (Tok.isNot(tok::l_paren)) {
|
if (Tok.isNot(tok::l_paren)) {
|
||||||
TPResult TPR = isCXXDeclarationSpecifier();
|
TPResult TPR = isCXXDeclarationSpecifier();
|
||||||
if (TPR == TPResult::Ambiguous())
|
if (TPR == TPResult::Ambiguous)
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
if (TPR == TPResult::True() || TPR == TPResult::Error())
|
if (TPR == TPResult::True || TPR == TPResult::Error)
|
||||||
return TPR;
|
return TPR;
|
||||||
assert(TPR == TPResult::False());
|
assert(TPR == TPResult::False);
|
||||||
}
|
}
|
||||||
|
|
||||||
TPResult TPR = TryParseInitDeclaratorList();
|
TPResult TPR = TryParseInitDeclaratorList();
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR;
|
return TPR;
|
||||||
|
|
||||||
if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
|
if (Tok.isNot(tok::semi) && (!AllowForRangeDecl || Tok.isNot(tok::colon)))
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tentatively parse an init-declarator-list in order to disambiguate it from
|
/// Tentatively parse an init-declarator-list in order to disambiguate it from
|
||||||
|
@ -283,23 +283,23 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() {
|
||||||
while (1) {
|
while (1) {
|
||||||
// declarator
|
// declarator
|
||||||
TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
|
TPResult TPR = TryParseDeclarator(false/*mayBeAbstract*/);
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR;
|
return TPR;
|
||||||
|
|
||||||
// [GNU] simple-asm-expr[opt] attributes[opt]
|
// [GNU] simple-asm-expr[opt] attributes[opt]
|
||||||
if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// initializer[opt]
|
// initializer[opt]
|
||||||
if (Tok.is(tok::l_paren)) {
|
if (Tok.is(tok::l_paren)) {
|
||||||
// Parse through the parens.
|
// Parse through the parens.
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
} else if (Tok.is(tok::l_brace)) {
|
} else if (Tok.is(tok::l_brace)) {
|
||||||
// A left-brace here is sufficient to disambiguate the parse; an
|
// A left-brace here is sufficient to disambiguate the parse; an
|
||||||
// expression can never be followed directly by a braced-init-list.
|
// expression can never be followed directly by a braced-init-list.
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
} else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
|
} else if (Tok.is(tok::equal) || isTokIdentifier_in()) {
|
||||||
// MSVC and g++ won't examine the rest of declarators if '=' is
|
// MSVC and g++ won't examine the rest of declarators if '=' is
|
||||||
// encountered; they just conclude that we have a declaration.
|
// encountered; they just conclude that we have a declaration.
|
||||||
|
@ -317,14 +317,14 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() {
|
||||||
// in any other context 'in' is invalid after a declaration and parser
|
// in any other context 'in' is invalid after a declaration and parser
|
||||||
// issues the error regardless of outcome of this decision.
|
// issues the error regardless of outcome of this decision.
|
||||||
// FIXME: Change if above assumption does not hold.
|
// FIXME: Change if above assumption does not hold.
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryConsumeToken(tok::comma))
|
if (!TryConsumeToken(tok::comma))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isCXXConditionDeclaration - Disambiguates between a declaration or an
|
/// isCXXConditionDeclaration - Disambiguates between a declaration or an
|
||||||
|
@ -342,9 +342,9 @@ Parser::TPResult Parser::TryParseInitDeclaratorList() {
|
||||||
///
|
///
|
||||||
bool Parser::isCXXConditionDeclaration() {
|
bool Parser::isCXXConditionDeclaration() {
|
||||||
TPResult TPR = isCXXDeclarationSpecifier();
|
TPResult TPR = isCXXDeclarationSpecifier();
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR != TPResult::False(); // Returns true for TPResult::True() or
|
return TPR != TPResult::False; // Returns true for TPResult::True or
|
||||||
// TPResult::Error().
|
// TPResult::Error.
|
||||||
|
|
||||||
// FIXME: Add statistics about the number of ambiguous statements encountered
|
// FIXME: Add statistics about the number of ambiguous statements encountered
|
||||||
// and how they were resolved (number of declarations+number of expressions).
|
// and how they were resolved (number of declarations+number of expressions).
|
||||||
|
@ -362,25 +362,25 @@ bool Parser::isCXXConditionDeclaration() {
|
||||||
TPR = TryParseDeclarator(false/*mayBeAbstract*/);
|
TPR = TryParseDeclarator(false/*mayBeAbstract*/);
|
||||||
|
|
||||||
// In case of an error, let the declaration parsing code handle it.
|
// In case of an error, let the declaration parsing code handle it.
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
|
|
||||||
if (TPR == TPResult::Ambiguous()) {
|
if (TPR == TPResult::Ambiguous) {
|
||||||
// '='
|
// '='
|
||||||
// [GNU] simple-asm-expr[opt] attributes[opt]
|
// [GNU] simple-asm-expr[opt] attributes[opt]
|
||||||
if (Tok.is(tok::equal) ||
|
if (Tok.is(tok::equal) ||
|
||||||
Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
|
Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
|
else if (getLangOpts().CPlusPlus11 && Tok.is(tok::l_brace))
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
else
|
else
|
||||||
TPR = TPResult::False();
|
TPR = TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
assert(TPR == TPResult::True() || TPR == TPResult::False());
|
assert(TPR == TPResult::True || TPR == TPResult::False);
|
||||||
return TPR == TPResult::True();
|
return TPR == TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Determine whether the next set of tokens contains a type-id.
|
/// \brief Determine whether the next set of tokens contains a type-id.
|
||||||
|
@ -412,9 +412,9 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
|
||||||
// in its syntactic context shall be considered a type-id.
|
// in its syntactic context shall be considered a type-id.
|
||||||
|
|
||||||
TPResult TPR = isCXXDeclarationSpecifier();
|
TPResult TPR = isCXXDeclarationSpecifier();
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR != TPResult::False(); // Returns true for TPResult::True() or
|
return TPR != TPResult::False; // Returns true for TPResult::True or
|
||||||
// TPResult::Error().
|
// TPResult::Error.
|
||||||
|
|
||||||
// FIXME: Add statistics about the number of ambiguous statements encountered
|
// FIXME: Add statistics about the number of ambiguous statements encountered
|
||||||
// and how they were resolved (number of declarations+number of expressions).
|
// and how they were resolved (number of declarations+number of expressions).
|
||||||
|
@ -432,14 +432,14 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
|
||||||
TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
|
TPR = TryParseDeclarator(true/*mayBeAbstract*/, false/*mayHaveIdentifier*/);
|
||||||
|
|
||||||
// In case of an error, let the declaration parsing code handle it.
|
// In case of an error, let the declaration parsing code handle it.
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
|
|
||||||
if (TPR == TPResult::Ambiguous()) {
|
if (TPR == TPResult::Ambiguous) {
|
||||||
// We are supposed to be inside parens, so if after the abstract declarator
|
// 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.
|
// we encounter a ')' this is a type-id, otherwise it's an expression.
|
||||||
if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
|
if (Context == TypeIdInParens && Tok.is(tok::r_paren)) {
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
isAmbiguous = true;
|
isAmbiguous = true;
|
||||||
|
|
||||||
// We are supposed to be inside a template argument, so if after
|
// We are supposed to be inside a template argument, so if after
|
||||||
|
@ -448,17 +448,17 @@ bool Parser::isCXXTypeId(TentativeCXXTypeIdContext Context, bool &isAmbiguous) {
|
||||||
} else if (Context == TypeIdAsTemplateArgument &&
|
} else if (Context == TypeIdAsTemplateArgument &&
|
||||||
(Tok.is(tok::greater) || Tok.is(tok::comma) ||
|
(Tok.is(tok::greater) || Tok.is(tok::comma) ||
|
||||||
(getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) {
|
(getLangOpts().CPlusPlus11 && Tok.is(tok::greatergreater)))) {
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
isAmbiguous = true;
|
isAmbiguous = true;
|
||||||
|
|
||||||
} else
|
} else
|
||||||
TPR = TPResult::False();
|
TPR = TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
assert(TPR == TPResult::True() || TPR == TPResult::False());
|
assert(TPR == TPResult::True || TPR == TPResult::False);
|
||||||
return TPR == TPResult::True();
|
return TPR == TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Returns true if this is a C++11 attribute-specifier. Per
|
/// \brief Returns true if this is a C++11 attribute-specifier. Per
|
||||||
|
@ -624,7 +624,7 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
|
if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier))
|
||||||
if (TryAnnotateCXXScopeToken(true))
|
if (TryAnnotateCXXScopeToken(true))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
|
if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) ||
|
||||||
Tok.is(tok::ampamp) ||
|
Tok.is(tok::ampamp) ||
|
||||||
|
@ -636,7 +636,7 @@ Parser::TPResult Parser::TryParsePtrOperatorSeq() {
|
||||||
Tok.is(tok::kw_restrict))
|
Tok.is(tok::kw_restrict))
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
} else {
|
} else {
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -671,20 +671,20 @@ Parser::TPResult Parser::TryParseOperatorId() {
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
}
|
}
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
|
#define OVERLOADED_OPERATOR(Name, Spelling, Token, Unary, Binary, MemOnly) \
|
||||||
case tok::Token:
|
case tok::Token:
|
||||||
#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
|
#define OVERLOADED_OPERATOR_MULTI(Name, Spelling, Unary, Binary, MemOnly)
|
||||||
#include "clang/Basic/OperatorKinds.def"
|
#include "clang/Basic/OperatorKinds.def"
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
case tok::l_square:
|
case tok::l_square:
|
||||||
if (NextToken().is(tok::r_square)) {
|
if (NextToken().is(tok::r_square)) {
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -692,7 +692,7 @@ Parser::TPResult Parser::TryParseOperatorId() {
|
||||||
if (NextToken().is(tok::r_paren)) {
|
if (NextToken().is(tok::r_paren)) {
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -712,24 +712,24 @@ Parser::TPResult Parser::TryParseOperatorId() {
|
||||||
if (Tok.is(tok::identifier))
|
if (Tok.is(tok::identifier))
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
else
|
else
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
}
|
}
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Maybe this is a conversion-function-id.
|
// Maybe this is a conversion-function-id.
|
||||||
bool AnyDeclSpecifiers = false;
|
bool AnyDeclSpecifiers = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
TPResult TPR = isCXXDeclarationSpecifier();
|
TPResult TPR = isCXXDeclarationSpecifier();
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
return TPR;
|
return TPR;
|
||||||
if (TPR == TPResult::False()) {
|
if (TPR == TPResult::False) {
|
||||||
if (!AnyDeclSpecifiers)
|
if (!AnyDeclSpecifiers)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (TryConsumeDeclarationSpecifier() == TPResult::Error())
|
if (TryConsumeDeclarationSpecifier() == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
AnyDeclSpecifiers = true;
|
AnyDeclSpecifiers = true;
|
||||||
}
|
}
|
||||||
return TryParsePtrOperatorSeq();
|
return TryParsePtrOperatorSeq();
|
||||||
|
@ -793,8 +793,8 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
|
||||||
// declarator:
|
// declarator:
|
||||||
// direct-declarator
|
// direct-declarator
|
||||||
// ptr-operator declarator
|
// ptr-operator declarator
|
||||||
if (TryParsePtrOperatorSeq() == TPResult::Error())
|
if (TryParsePtrOperatorSeq() == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
// direct-declarator:
|
// direct-declarator:
|
||||||
// direct-abstract-declarator:
|
// direct-abstract-declarator:
|
||||||
|
@ -811,8 +811,8 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
|
||||||
else if (Tok.is(tok::identifier))
|
else if (Tok.is(tok::identifier))
|
||||||
TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
|
TentativelyDeclaredIdentifiers.push_back(Tok.getIdentifierInfo());
|
||||||
if (Tok.is(tok::kw_operator)) {
|
if (Tok.is(tok::kw_operator)) {
|
||||||
if (TryParseOperatorId() == TPResult::Error())
|
if (TryParseOperatorId() == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
} else
|
} else
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
} else if (Tok.is(tok::l_paren)) {
|
} else if (Tok.is(tok::l_paren)) {
|
||||||
|
@ -825,7 +825,7 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
|
||||||
// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
|
// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
|
||||||
// exception-specification[opt]
|
// exception-specification[opt]
|
||||||
TPResult TPR = TryParseFunctionDeclarator();
|
TPResult TPR = TryParseFunctionDeclarator();
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR;
|
return TPR;
|
||||||
} else {
|
} else {
|
||||||
// '(' declarator ')'
|
// '(' declarator ')'
|
||||||
|
@ -838,20 +838,20 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
|
||||||
Tok.is(tok::kw___fastcall) ||
|
Tok.is(tok::kw___fastcall) ||
|
||||||
Tok.is(tok::kw___thiscall) ||
|
Tok.is(tok::kw___thiscall) ||
|
||||||
Tok.is(tok::kw___unaligned))
|
Tok.is(tok::kw___unaligned))
|
||||||
return TPResult::True(); // attributes indicate declaration
|
return TPResult::True; // attributes indicate declaration
|
||||||
TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
|
TPResult TPR = TryParseDeclarator(mayBeAbstract, mayHaveIdentifier);
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR;
|
return TPR;
|
||||||
if (Tok.isNot(tok::r_paren))
|
if (Tok.isNot(tok::r_paren))
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
}
|
}
|
||||||
} else if (!mayBeAbstract) {
|
} else if (!mayBeAbstract) {
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
TPResult TPR(TPResult::Ambiguous());
|
TPResult TPR(TPResult::Ambiguous);
|
||||||
|
|
||||||
// abstract-declarator: ...
|
// abstract-declarator: ...
|
||||||
if (Tok.is(tok::ellipsis))
|
if (Tok.is(tok::ellipsis))
|
||||||
|
@ -877,11 +877,11 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR;
|
return TPR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::TPResult
|
Parser::TPResult
|
||||||
|
@ -943,7 +943,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
|
||||||
#define TYPE_TRAIT(N,Spelling,K) \
|
#define TYPE_TRAIT(N,Spelling,K) \
|
||||||
case tok::kw_##Spelling:
|
case tok::kw_##Spelling:
|
||||||
#include "clang/Basic/TokenKinds.def"
|
#include "clang/Basic/TokenKinds.def"
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// Obviously starts a type-specifier-seq:
|
// Obviously starts a type-specifier-seq:
|
||||||
case tok::kw_char:
|
case tok::kw_char:
|
||||||
|
@ -989,13 +989,13 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
|
||||||
case tok::kw___pixel:
|
case tok::kw___pixel:
|
||||||
case tok::kw__Atomic:
|
case tok::kw__Atomic:
|
||||||
case tok::kw___unknown_anytype:
|
case tok::kw___unknown_anytype:
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
|
bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
|
||||||
|
@ -1004,16 +1004,16 @@ bool Parser::isTentativelyDeclared(IdentifierInfo *II) {
|
||||||
!= TentativelyDeclaredIdentifiers.end();
|
!= TentativelyDeclaredIdentifiers.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isCXXDeclarationSpecifier - Returns TPResult::True() if it is a declaration
|
/// isCXXDeclarationSpecifier - Returns TPResult::True if it is a declaration
|
||||||
/// specifier, TPResult::False() if it is not, TPResult::Ambiguous() if it could
|
/// specifier, TPResult::False if it is not, TPResult::Ambiguous if it could
|
||||||
/// be either a decl-specifier or a function-style cast, and TPResult::Error()
|
/// be either a decl-specifier or a function-style cast, and TPResult::Error
|
||||||
/// if a parsing error was found and reported.
|
/// if a parsing error was found and reported.
|
||||||
///
|
///
|
||||||
/// If HasMissingTypename is provided, a name with a dependent scope specifier
|
/// If HasMissingTypename is provided, a name with a dependent scope specifier
|
||||||
/// will be treated as ambiguous if the 'typename' keyword is missing. If this
|
/// will be treated as ambiguous if the 'typename' keyword is missing. If this
|
||||||
/// happens, *HasMissingTypename will be set to 'true'. This will also be used
|
/// happens, *HasMissingTypename will be set to 'true'. This will also be used
|
||||||
/// as an indicator that undeclared identifiers (which will trigger a later
|
/// as an indicator that undeclared identifiers (which will trigger a later
|
||||||
/// parse error) should be treated as types. Returns TPResult::Ambiguous() in
|
/// parse error) should be treated as types. Returns TPResult::Ambiguous in
|
||||||
/// such cases.
|
/// such cases.
|
||||||
///
|
///
|
||||||
/// decl-specifier:
|
/// decl-specifier:
|
||||||
|
@ -1117,12 +1117,12 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
// Check for need to substitute AltiVec __vector keyword
|
// Check for need to substitute AltiVec __vector keyword
|
||||||
// for "vector" identifier.
|
// for "vector" identifier.
|
||||||
if (TryAltiVecVectorToken())
|
if (TryAltiVecVectorToken())
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
const Token &Next = NextToken();
|
const Token &Next = NextToken();
|
||||||
// In 'foo bar', 'foo' is always a type name outside of Objective-C.
|
// In 'foo bar', 'foo' is always a type name outside of Objective-C.
|
||||||
if (!getLangOpts().ObjC1 && Next.is(tok::identifier))
|
if (!getLangOpts().ObjC1 && Next.is(tok::identifier))
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
|
if (Next.isNot(tok::coloncolon) && Next.isNot(tok::less)) {
|
||||||
// Determine whether this is a valid expression. If not, we will hit
|
// Determine whether this is a valid expression. If not, we will hit
|
||||||
|
@ -1135,15 +1135,15 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
switch (TryAnnotateName(false /* no nested name specifier */,
|
switch (TryAnnotateName(false /* no nested name specifier */,
|
||||||
&TypoCorrection)) {
|
&TypoCorrection)) {
|
||||||
case ANK_Error:
|
case ANK_Error:
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
case ANK_TentativeDecl:
|
case ANK_TentativeDecl:
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
case ANK_TemplateName:
|
case ANK_TemplateName:
|
||||||
// A bare type template-name which can't be a template template
|
// A bare type template-name which can't be a template template
|
||||||
// argument is an error, and was probably intended to be a type.
|
// argument is an error, and was probably intended to be a type.
|
||||||
return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
|
return GreaterThanIsOperator ? TPResult::True : TPResult::False;
|
||||||
case ANK_Unresolved:
|
case ANK_Unresolved:
|
||||||
return HasMissingTypename ? TPResult::Ambiguous() : TPResult::False();
|
return HasMissingTypename ? TPResult::Ambiguous : TPResult::False;
|
||||||
case ANK_Success:
|
case ANK_Success:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1155,12 +1155,12 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
// since it will annotate as a primary expression, and we want to use the
|
// since it will annotate as a primary expression, and we want to use the
|
||||||
// "missing 'typename'" logic.
|
// "missing 'typename'" logic.
|
||||||
if (TryAnnotateTypeOrScopeToken())
|
if (TryAnnotateTypeOrScopeToken())
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
// If annotation failed, assume it's a non-type.
|
// If annotation failed, assume it's a non-type.
|
||||||
// FIXME: If this happens due to an undeclared identifier, treat it as
|
// FIXME: If this happens due to an undeclared identifier, treat it as
|
||||||
// ambiguous.
|
// ambiguous.
|
||||||
if (Tok.is(tok::identifier))
|
if (Tok.is(tok::identifier))
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We annotated this token as something. Recurse to handle whatever we got.
|
// We annotated this token as something. Recurse to handle whatever we got.
|
||||||
|
@ -1171,21 +1171,21 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
// Annotate typenames and C++ scope specifiers. If we get one, just
|
// Annotate typenames and C++ scope specifiers. If we get one, just
|
||||||
// recurse to handle whatever we get.
|
// recurse to handle whatever we get.
|
||||||
if (TryAnnotateTypeOrScopeToken())
|
if (TryAnnotateTypeOrScopeToken())
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
|
return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
|
||||||
|
|
||||||
case tok::coloncolon: { // ::foo::bar
|
case tok::coloncolon: { // ::foo::bar
|
||||||
const Token &Next = NextToken();
|
const Token &Next = NextToken();
|
||||||
if (Next.is(tok::kw_new) || // ::new
|
if (Next.is(tok::kw_new) || // ::new
|
||||||
Next.is(tok::kw_delete)) // ::delete
|
Next.is(tok::kw_delete)) // ::delete
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
// Fall through.
|
// Fall through.
|
||||||
case tok::kw_decltype:
|
case tok::kw_decltype:
|
||||||
// Annotate typenames and C++ scope specifiers. If we get one, just
|
// Annotate typenames and C++ scope specifiers. If we get one, just
|
||||||
// recurse to handle whatever we get.
|
// recurse to handle whatever we get.
|
||||||
if (TryAnnotateTypeOrScopeToken())
|
if (TryAnnotateTypeOrScopeToken())
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
|
return isCXXDeclarationSpecifier(BracedCastResult, HasMissingTypename);
|
||||||
|
|
||||||
// decl-specifier:
|
// decl-specifier:
|
||||||
|
@ -1242,7 +1242,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
case tok::kw_restrict:
|
case tok::kw_restrict:
|
||||||
case tok::kw__Complex:
|
case tok::kw__Complex:
|
||||||
case tok::kw___attribute:
|
case tok::kw___attribute:
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// Microsoft
|
// Microsoft
|
||||||
case tok::kw___declspec:
|
case tok::kw___declspec:
|
||||||
|
@ -1257,20 +1257,20 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
case tok::kw___ptr32:
|
case tok::kw___ptr32:
|
||||||
case tok::kw___forceinline:
|
case tok::kw___forceinline:
|
||||||
case tok::kw___unaligned:
|
case tok::kw___unaligned:
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// Borland
|
// Borland
|
||||||
case tok::kw___pascal:
|
case tok::kw___pascal:
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// AltiVec
|
// AltiVec
|
||||||
case tok::kw___vector:
|
case tok::kw___vector:
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
case tok::annot_template_id: {
|
case tok::annot_template_id: {
|
||||||
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
|
TemplateIdAnnotation *TemplateId = takeTemplateIdAnnotation(Tok);
|
||||||
if (TemplateId->Kind != TNK_Type_template)
|
if (TemplateId->Kind != TNK_Type_template)
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
CXXScopeSpec SS;
|
CXXScopeSpec SS;
|
||||||
AnnotateTemplateIdTokenAsType();
|
AnnotateTemplateIdTokenAsType();
|
||||||
assert(Tok.is(tok::annot_typename));
|
assert(Tok.is(tok::annot_typename));
|
||||||
|
@ -1280,7 +1280,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
|
case tok::annot_cxxscope: // foo::bar or ::foo::bar, but already parsed
|
||||||
// We've already annotated a scope; try to annotate a type.
|
// We've already annotated a scope; try to annotate a type.
|
||||||
if (TryAnnotateTypeOrScopeToken())
|
if (TryAnnotateTypeOrScopeToken())
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
if (!Tok.is(tok::annot_typename)) {
|
if (!Tok.is(tok::annot_typename)) {
|
||||||
// If the next token is an identifier or a type qualifier, then this
|
// If the next token is an identifier or a type qualifier, then this
|
||||||
// can't possibly be a valid expression either.
|
// can't possibly be a valid expression either.
|
||||||
|
@ -1294,37 +1294,37 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
bool isIdentifier = Tok.is(tok::identifier);
|
bool isIdentifier = Tok.is(tok::identifier);
|
||||||
TPResult TPR = TPResult::False();
|
TPResult TPR = TPResult::False;
|
||||||
if (!isIdentifier)
|
if (!isIdentifier)
|
||||||
TPR = isCXXDeclarationSpecifier(BracedCastResult,
|
TPR = isCXXDeclarationSpecifier(BracedCastResult,
|
||||||
HasMissingTypename);
|
HasMissingTypename);
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
if (isIdentifier ||
|
if (isIdentifier ||
|
||||||
TPR == TPResult::True() || TPR == TPResult::Error())
|
TPR == TPResult::True || TPR == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
if (HasMissingTypename) {
|
if (HasMissingTypename) {
|
||||||
// We can't tell whether this is a missing 'typename' or a valid
|
// We can't tell whether this is a missing 'typename' or a valid
|
||||||
// expression.
|
// expression.
|
||||||
*HasMissingTypename = true;
|
*HasMissingTypename = true;
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Try to resolve the name. If it doesn't exist, assume it was
|
// Try to resolve the name. If it doesn't exist, assume it was
|
||||||
// intended to name a type and keep disambiguating.
|
// intended to name a type and keep disambiguating.
|
||||||
switch (TryAnnotateName(false /* SS is not dependent */)) {
|
switch (TryAnnotateName(false /* SS is not dependent */)) {
|
||||||
case ANK_Error:
|
case ANK_Error:
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
case ANK_TentativeDecl:
|
case ANK_TentativeDecl:
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
case ANK_TemplateName:
|
case ANK_TemplateName:
|
||||||
// A bare type template-name which can't be a template template
|
// A bare type template-name which can't be a template template
|
||||||
// argument is an error, and was probably intended to be a type.
|
// argument is an error, and was probably intended to be a type.
|
||||||
return GreaterThanIsOperator ? TPResult::True() : TPResult::False();
|
return GreaterThanIsOperator ? TPResult::True : TPResult::False;
|
||||||
case ANK_Unresolved:
|
case ANK_Unresolved:
|
||||||
return HasMissingTypename ? TPResult::Ambiguous()
|
return HasMissingTypename ? TPResult::Ambiguous
|
||||||
: TPResult::False();
|
: TPResult::False;
|
||||||
case ANK_Success:
|
case ANK_Success:
|
||||||
// Annotated it, check again.
|
// Annotated it, check again.
|
||||||
assert(Tok.isNot(tok::annot_cxxscope) ||
|
assert(Tok.isNot(tok::annot_cxxscope) ||
|
||||||
|
@ -1334,7 +1334,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
// If that succeeded, fallthrough into the generic simple-type-id case.
|
// If that succeeded, fallthrough into the generic simple-type-id case.
|
||||||
|
|
||||||
|
@ -1370,16 +1370,16 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
|
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
if (isFollowedByParen)
|
if (isFollowedByParen)
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
|
|
||||||
if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
|
if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
|
||||||
return BracedCastResult;
|
return BracedCastResult;
|
||||||
|
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
case tok::kw_char:
|
case tok::kw_char:
|
||||||
|
@ -1400,7 +1400,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
case tok::kw_void:
|
case tok::kw_void:
|
||||||
case tok::annot_decltype:
|
case tok::annot_decltype:
|
||||||
if (NextToken().is(tok::l_paren))
|
if (NextToken().is(tok::l_paren))
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
|
|
||||||
// This is a function-style cast in all cases we disambiguate other than
|
// This is a function-style cast in all cases we disambiguate other than
|
||||||
// one:
|
// one:
|
||||||
|
@ -1412,14 +1412,14 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
return BracedCastResult;
|
return BracedCastResult;
|
||||||
|
|
||||||
if (isStartOfObjCClassMessageMissingOpenBracket())
|
if (isStartOfObjCClassMessageMissingOpenBracket())
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
|
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// GNU typeof support.
|
// GNU typeof support.
|
||||||
case tok::kw_typeof: {
|
case tok::kw_typeof: {
|
||||||
if (NextToken().isNot(tok::l_paren))
|
if (NextToken().isNot(tok::l_paren))
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
TentativeParsingAction PA(*this);
|
TentativeParsingAction PA(*this);
|
||||||
|
|
||||||
|
@ -1429,28 +1429,28 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
|
||||||
|
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
if (isFollowedByParen)
|
if (isFollowedByParen)
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
|
|
||||||
if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
|
if (getLangOpts().CPlusPlus11 && isFollowedByBrace)
|
||||||
return BracedCastResult;
|
return BracedCastResult;
|
||||||
|
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
}
|
}
|
||||||
|
|
||||||
// C++0x type traits support
|
// C++0x type traits support
|
||||||
case tok::kw___underlying_type:
|
case tok::kw___underlying_type:
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// C11 _Atomic
|
// C11 _Atomic
|
||||||
case tok::kw__Atomic:
|
case tok::kw__Atomic:
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1516,9 +1516,9 @@ Parser::TPResult Parser::TryParseTypeofSpecifier() {
|
||||||
// Parse through the parens after 'typeof'.
|
// Parse through the parens after 'typeof'.
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [ObjC] protocol-qualifiers:
|
/// [ObjC] protocol-qualifiers:
|
||||||
|
@ -1528,7 +1528,7 @@ Parser::TPResult Parser::TryParseProtocolQualifiers() {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
do {
|
do {
|
||||||
if (Tok.isNot(tok::identifier))
|
if (Tok.isNot(tok::identifier))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
|
||||||
if (Tok.is(tok::comma)) {
|
if (Tok.is(tok::comma)) {
|
||||||
|
@ -1538,11 +1538,11 @@ Parser::TPResult Parser::TryParseProtocolQualifiers() {
|
||||||
|
|
||||||
if (Tok.is(tok::greater)) {
|
if (Tok.is(tok::greater)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
} while (false);
|
} while (false);
|
||||||
|
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
|
/// isCXXFunctionDeclarator - Disambiguates between a function declarator or
|
||||||
|
@ -1571,9 +1571,9 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
bool InvalidAsDeclaration = false;
|
bool InvalidAsDeclaration = false;
|
||||||
TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
|
TPResult TPR = TryParseParameterDeclarationClause(&InvalidAsDeclaration);
|
||||||
if (TPR == TPResult::Ambiguous()) {
|
if (TPR == TPResult::Ambiguous) {
|
||||||
if (Tok.isNot(tok::r_paren))
|
if (Tok.isNot(tok::r_paren))
|
||||||
TPR = TPResult::False();
|
TPR = TPResult::False;
|
||||||
else {
|
else {
|
||||||
const Token &Next = NextToken();
|
const Token &Next = NextToken();
|
||||||
if (Next.is(tok::amp) || Next.is(tok::ampamp) ||
|
if (Next.is(tok::amp) || Next.is(tok::ampamp) ||
|
||||||
|
@ -1585,20 +1585,20 @@ bool Parser::isCXXFunctionDeclarator(bool *IsAmbiguous) {
|
||||||
// The next token cannot appear after a constructor-style initializer,
|
// The next token cannot appear after a constructor-style initializer,
|
||||||
// and can appear next in a function definition. This must be a function
|
// and can appear next in a function definition. This must be a function
|
||||||
// declarator.
|
// declarator.
|
||||||
TPR = TPResult::True();
|
TPR = TPResult::True;
|
||||||
else if (InvalidAsDeclaration)
|
else if (InvalidAsDeclaration)
|
||||||
// Use the absence of 'typename' as a tie-breaker.
|
// Use the absence of 'typename' as a tie-breaker.
|
||||||
TPR = TPResult::False();
|
TPR = TPResult::False;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PA.Revert();
|
PA.Revert();
|
||||||
|
|
||||||
if (IsAmbiguous && TPR == TPResult::Ambiguous())
|
if (IsAmbiguous && TPR == TPResult::Ambiguous)
|
||||||
*IsAmbiguous = true;
|
*IsAmbiguous = true;
|
||||||
|
|
||||||
// In case of an error, let the declaration parsing code handle it.
|
// In case of an error, let the declaration parsing code handle it.
|
||||||
return TPR != TPResult::False();
|
return TPR != TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// parameter-declaration-clause:
|
/// parameter-declaration-clause:
|
||||||
|
@ -1623,7 +1623,7 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
|
||||||
bool VersusTemplateArgument) {
|
bool VersusTemplateArgument) {
|
||||||
|
|
||||||
if (Tok.is(tok::r_paren))
|
if (Tok.is(tok::r_paren))
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
|
|
||||||
// parameter-declaration-list[opt] '...'[opt]
|
// parameter-declaration-list[opt] '...'[opt]
|
||||||
// parameter-declaration-list ',' '...'
|
// parameter-declaration-list ',' '...'
|
||||||
|
@ -1637,15 +1637,15 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
|
||||||
if (Tok.is(tok::ellipsis)) {
|
if (Tok.is(tok::ellipsis)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (Tok.is(tok::r_paren))
|
if (Tok.is(tok::r_paren))
|
||||||
return TPResult::True(); // '...)' is a sign of a function declarator.
|
return TPResult::True; // '...)' is a sign of a function declarator.
|
||||||
else
|
else
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An attribute-specifier-seq here is a sign of a function declarator.
|
// An attribute-specifier-seq here is a sign of a function declarator.
|
||||||
if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
|
if (isCXX11AttributeSpecifier(/*Disambiguate*/false,
|
||||||
/*OuterMightBeMessageSend*/true))
|
/*OuterMightBeMessageSend*/true))
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
ParsedAttributes attrs(AttrFactory);
|
ParsedAttributes attrs(AttrFactory);
|
||||||
MaybeParseMicrosoftAttributes(attrs);
|
MaybeParseMicrosoftAttributes(attrs);
|
||||||
|
@ -1653,43 +1653,43 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
|
||||||
// decl-specifier-seq
|
// decl-specifier-seq
|
||||||
// A parameter-declaration's initializer must be preceded by an '=', so
|
// A parameter-declaration's initializer must be preceded by an '=', so
|
||||||
// decl-specifier-seq '{' is not a parameter in C++11.
|
// decl-specifier-seq '{' is not a parameter in C++11.
|
||||||
TPResult TPR = isCXXDeclarationSpecifier(TPResult::False(),
|
TPResult TPR = isCXXDeclarationSpecifier(TPResult::False,
|
||||||
InvalidAsDeclaration);
|
InvalidAsDeclaration);
|
||||||
|
|
||||||
if (VersusTemplateArgument && TPR == TPResult::True()) {
|
if (VersusTemplateArgument && TPR == TPResult::True) {
|
||||||
// Consume the decl-specifier-seq. We have to look past it, since a
|
// Consume the decl-specifier-seq. We have to look past it, since a
|
||||||
// type-id might appear here in a template argument.
|
// type-id might appear here in a template argument.
|
||||||
bool SeenType = false;
|
bool SeenType = false;
|
||||||
do {
|
do {
|
||||||
SeenType |= isCXXDeclarationSpecifierAType();
|
SeenType |= isCXXDeclarationSpecifierAType();
|
||||||
if (TryConsumeDeclarationSpecifier() == TPResult::Error())
|
if (TryConsumeDeclarationSpecifier() == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
// If we see a parameter name, this can't be a template argument.
|
// If we see a parameter name, this can't be a template argument.
|
||||||
if (SeenType && Tok.is(tok::identifier))
|
if (SeenType && Tok.is(tok::identifier))
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
TPR = isCXXDeclarationSpecifier(TPResult::False(),
|
TPR = isCXXDeclarationSpecifier(TPResult::False,
|
||||||
InvalidAsDeclaration);
|
InvalidAsDeclaration);
|
||||||
if (TPR == TPResult::Error())
|
if (TPR == TPResult::Error)
|
||||||
return TPR;
|
return TPR;
|
||||||
} while (TPR != TPResult::False());
|
} while (TPR != TPResult::False);
|
||||||
} else if (TPR == TPResult::Ambiguous()) {
|
} else if (TPR == TPResult::Ambiguous) {
|
||||||
// Disambiguate what follows the decl-specifier.
|
// Disambiguate what follows the decl-specifier.
|
||||||
if (TryConsumeDeclarationSpecifier() == TPResult::Error())
|
if (TryConsumeDeclarationSpecifier() == TPResult::Error)
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
} else
|
} else
|
||||||
return TPR;
|
return TPR;
|
||||||
|
|
||||||
// declarator
|
// declarator
|
||||||
// abstract-declarator[opt]
|
// abstract-declarator[opt]
|
||||||
TPR = TryParseDeclarator(true/*mayBeAbstract*/);
|
TPR = TryParseDeclarator(true/*mayBeAbstract*/);
|
||||||
if (TPR != TPResult::Ambiguous())
|
if (TPR != TPResult::Ambiguous)
|
||||||
return TPR;
|
return TPR;
|
||||||
|
|
||||||
// [GNU] attributes[opt]
|
// [GNU] attributes[opt]
|
||||||
if (Tok.is(tok::kw___attribute))
|
if (Tok.is(tok::kw___attribute))
|
||||||
return TPResult::True();
|
return TPResult::True;
|
||||||
|
|
||||||
// If we're disambiguating a template argument in a default argument in
|
// If we're disambiguating a template argument in a default argument in
|
||||||
// a class definition versus a parameter declaration, an '=' here
|
// a class definition versus a parameter declaration, an '=' here
|
||||||
|
@ -1702,36 +1702,36 @@ Parser::TryParseParameterDeclarationClause(bool *InvalidAsDeclaration,
|
||||||
// parameter-declaration-clause, and the last param is missing its default
|
// parameter-declaration-clause, and the last param is missing its default
|
||||||
// argument.
|
// argument.
|
||||||
if (VersusTemplateArgument)
|
if (VersusTemplateArgument)
|
||||||
return (Tok.is(tok::equal) || Tok.is(tok::r_paren)) ? TPResult::True()
|
return (Tok.is(tok::equal) || Tok.is(tok::r_paren)) ? TPResult::True
|
||||||
: TPResult::False();
|
: TPResult::False;
|
||||||
|
|
||||||
if (Tok.is(tok::equal)) {
|
if (Tok.is(tok::equal)) {
|
||||||
// '=' assignment-expression
|
// '=' assignment-expression
|
||||||
// Parse through assignment-expression.
|
// Parse through assignment-expression.
|
||||||
// FIXME: assignment-expression may contain an unparenthesized comma.
|
// FIXME: assignment-expression may contain an unparenthesized comma.
|
||||||
if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
|
if (!SkipUntil(tok::comma, tok::r_paren, StopAtSemi | StopBeforeMatch))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Tok.is(tok::ellipsis)) {
|
if (Tok.is(tok::ellipsis)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (Tok.is(tok::r_paren))
|
if (Tok.is(tok::r_paren))
|
||||||
return TPResult::True(); // '...)' is a sign of a function declarator.
|
return TPResult::True; // '...)' is a sign of a function declarator.
|
||||||
else
|
else
|
||||||
return TPResult::False();
|
return TPResult::False;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!TryConsumeToken(tok::comma))
|
if (!TryConsumeToken(tok::comma))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
|
/// TryParseFunctionDeclarator - We parsed a '(' and we want to try to continue
|
||||||
/// parsing as a function declarator.
|
/// parsing as a function declarator.
|
||||||
/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
|
/// If TryParseFunctionDeclarator fully parsed the function declarator, it will
|
||||||
/// return TPResult::Ambiguous(), otherwise it will return either False() or
|
/// return TPResult::Ambiguous, otherwise it will return either False() or
|
||||||
/// Error().
|
/// Error().
|
||||||
///
|
///
|
||||||
/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
|
/// '(' parameter-declaration-clause ')' cv-qualifier-seq[opt]
|
||||||
|
@ -1745,15 +1745,15 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
|
||||||
// The '(' is already parsed.
|
// The '(' is already parsed.
|
||||||
|
|
||||||
TPResult TPR = TryParseParameterDeclarationClause();
|
TPResult TPR = TryParseParameterDeclarationClause();
|
||||||
if (TPR == TPResult::Ambiguous() && Tok.isNot(tok::r_paren))
|
if (TPR == TPResult::Ambiguous && Tok.isNot(tok::r_paren))
|
||||||
TPR = TPResult::False();
|
TPR = TPResult::False;
|
||||||
|
|
||||||
if (TPR == TPResult::False() || TPR == TPResult::Error())
|
if (TPR == TPResult::False || TPR == TPResult::Error)
|
||||||
return TPR;
|
return TPR;
|
||||||
|
|
||||||
// Parse through the parens.
|
// Parse through the parens.
|
||||||
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
// cv-qualifier-seq
|
// cv-qualifier-seq
|
||||||
while (Tok.is(tok::kw_const) ||
|
while (Tok.is(tok::kw_const) ||
|
||||||
|
@ -1769,12 +1769,12 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
|
||||||
if (Tok.is(tok::kw_throw)) {
|
if (Tok.is(tok::kw_throw)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
if (Tok.isNot(tok::l_paren))
|
if (Tok.isNot(tok::l_paren))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
// Parse through the parens after 'throw'.
|
// Parse through the parens after 'throw'.
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
}
|
}
|
||||||
if (Tok.is(tok::kw_noexcept)) {
|
if (Tok.is(tok::kw_noexcept)) {
|
||||||
ConsumeToken();
|
ConsumeToken();
|
||||||
|
@ -1783,11 +1783,11 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
|
||||||
// Find the matching rparen.
|
// Find the matching rparen.
|
||||||
ConsumeParen();
|
ConsumeParen();
|
||||||
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
if (!SkipUntil(tok::r_paren, StopAtSemi))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// '[' constant-expression[opt] ']'
|
/// '[' constant-expression[opt] ']'
|
||||||
|
@ -1795,7 +1795,7 @@ Parser::TPResult Parser::TryParseFunctionDeclarator() {
|
||||||
Parser::TPResult Parser::TryParseBracketDeclarator() {
|
Parser::TPResult Parser::TryParseBracketDeclarator() {
|
||||||
ConsumeBracket();
|
ConsumeBracket();
|
||||||
if (!SkipUntil(tok::r_square, StopAtSemi))
|
if (!SkipUntil(tok::r_square, StopAtSemi))
|
||||||
return TPResult::Error();
|
return TPResult::Error;
|
||||||
|
|
||||||
return TPResult::Ambiguous();
|
return TPResult::Ambiguous;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue