mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-07 08:34:59 +00:00
Disambiguate between a declaration or expression for the 'condition' part of a if/switch/while/for statement.
llvm-svn: 57109
This commit is contained in:
parent
7b87f27438
commit
71f3e19df0
@ -610,6 +610,12 @@ private:
|
||||
/// the function returns true to let the declaration parsing code handle it.
|
||||
bool isCXXFunctionDeclarator();
|
||||
|
||||
/// isCXXConditionDeclaration - Disambiguates between a declaration or an
|
||||
/// expression for a condition of a if/switch/while/for statement.
|
||||
/// If during the disambiguation process a parsing error is encountered,
|
||||
/// the function returns true to let the declaration parsing code handle it.
|
||||
bool isCXXConditionDeclaration();
|
||||
|
||||
/// isCXXDeclarationSpecifier - Returns TPR_true if it is a declaration
|
||||
/// specifier, TPR_false if it is not, TPR_ambiguous if it could be either
|
||||
/// a decl-specifier or a function-style cast, and TPR_error if a parsing
|
||||
|
@ -162,7 +162,7 @@ Parser::ExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) {
|
||||
/// '=' assignment-expression
|
||||
///
|
||||
Parser::ExprResult Parser::ParseCXXCondition() {
|
||||
if (!isDeclarationSpecifier())
|
||||
if (!isCXXConditionDeclaration())
|
||||
return ParseExpression(); // expression
|
||||
|
||||
SourceLocation StartLoc = Tok.getLocation();
|
||||
|
@ -225,6 +225,60 @@ Parser::TentativeParsingResult Parser::TryParseInitDeclaratorList() {
|
||||
return TPR_ambiguous;
|
||||
}
|
||||
|
||||
/// isCXXConditionDeclaration - Disambiguates between a declaration or an
|
||||
/// expression for a condition of a if/switch/while/for statement.
|
||||
/// If during the disambiguation process a parsing error is encountered,
|
||||
/// the function returns true to let the declaration parsing code handle it.
|
||||
///
|
||||
/// condition:
|
||||
/// expression
|
||||
/// type-specifier-seq declarator '=' assignment-expression
|
||||
/// [GNU] type-specifier-seq declarator simple-asm-expr[opt] attributes[opt]
|
||||
/// '=' assignment-expression
|
||||
///
|
||||
bool Parser::isCXXConditionDeclaration() {
|
||||
TentativeParsingResult TPR = isCXXDeclarationSpecifier();
|
||||
if (TPR != TPR_ambiguous)
|
||||
return TPR != TPR_false; // Returns true for TPR_true or TPR_error.
|
||||
|
||||
// FIXME: Add statistics about the number of ambiguous statements encountered
|
||||
// and how they were resolved (number of declarations+number of expressions).
|
||||
|
||||
// Ok, we have a simple-type-specifier/typename-specifier followed by a '('.
|
||||
// We need tentative parsing...
|
||||
|
||||
TentativeParsingAction PA(*this);
|
||||
|
||||
// type-specifier-seq
|
||||
if (Tok.is(tok::kw_typeof))
|
||||
TryParseTypeofSpecifier();
|
||||
else
|
||||
ConsumeToken();
|
||||
assert(Tok.is(tok::l_paren) && "Expected '('");
|
||||
|
||||
// declarator
|
||||
TPR = TryParseDeclarator(false/*mayBeAbstract*/);
|
||||
|
||||
PA.Revert();
|
||||
|
||||
// In case of an error, let the declaration parsing code handle it.
|
||||
if (TPR == TPR_error)
|
||||
return true;
|
||||
|
||||
if (TPR == TPR_ambiguous) {
|
||||
// '='
|
||||
// [GNU] simple-asm-expr[opt] attributes[opt]
|
||||
if (Tok.is(tok::equal) ||
|
||||
Tok.is(tok::kw_asm) || Tok.is(tok::kw___attribute))
|
||||
TPR = TPR_true;
|
||||
else
|
||||
TPR = TPR_false;
|
||||
}
|
||||
|
||||
assert(TPR == TPR_true || TPR == TPR_false);
|
||||
return TPR == TPR_true;
|
||||
}
|
||||
|
||||
/// declarator:
|
||||
/// direct-declarator
|
||||
/// ptr-operator declarator
|
||||
|
@ -11,6 +11,7 @@ void f() {
|
||||
__extension__ int(a)++; // expected-error {{invalid lvalue in increment/decrement expression}}
|
||||
typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}}
|
||||
void(a), ++a; // expected-warning {{statement was disambiguated as expression}} expected-warning {{expression result unused}}
|
||||
if (int(a)+1) {}
|
||||
|
||||
// Declarations.
|
||||
T(*d)(int(p)); // expected-warning {{statement was disambiguated as declaration}} expected-error {{previous definition is here}}
|
||||
|
Loading…
Reference in New Issue
Block a user