forked from OSchip/llvm-project
implement the GNU case-range extension. Add todo's for other missing gnu extensions.
llvm-svn: 38902
This commit is contained in:
parent
e7dab44cab
commit
476c3adb69
|
@ -302,22 +302,29 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS) {
|
|||
|
||||
/// ParseStructUnionSpecifier
|
||||
/// struct-or-union-specifier: [C99 6.7.2.1]
|
||||
/// struct-or-union identifier[opt] '{' struct-declaration-list '}'
|
||||
/// struct-or-union identifier[opt] '{' struct-contents '}'
|
||||
/// struct-or-union identifier
|
||||
/// struct-or-union:
|
||||
/// 'struct'
|
||||
/// 'union'
|
||||
/// struct-contents:
|
||||
/// struct-declaration-list
|
||||
/// [EXT] empty
|
||||
/// [GNU] "struct-declaration-list" without terminatoring ';' [TODO]
|
||||
/// struct-declaration-list:
|
||||
/// struct-declaration
|
||||
/// struct-declaration-list struct-declaration
|
||||
/// struct-declaration:
|
||||
/// specifier-qualifier-list struct-declarator-list ';'
|
||||
/// struct-declarator-list:
|
||||
/// struct-declarator
|
||||
/// struct-declarator-list ',' struct-declarator
|
||||
/// struct-declarator:
|
||||
/// declarator
|
||||
/// declarator[opt] ':' constant-expression
|
||||
/// struct-declaration
|
||||
/// struct-declaration-list struct-declaration
|
||||
/// [OBC] '@' 'defs' '(' class-name ')' [TODO]
|
||||
/// struct-declaration:
|
||||
/// specifier-qualifier-list struct-declarator-list ';'
|
||||
/// [GNU] __extension__ struct-declaration [TODO]
|
||||
/// [GNU] specifier-qualifier-list ';' [TODO]
|
||||
/// struct-declarator-list:
|
||||
/// struct-declarator
|
||||
/// struct-declarator-list ',' struct-declarator
|
||||
/// struct-declarator:
|
||||
/// declarator
|
||||
/// declarator[opt] ':' constant-expression
|
||||
///
|
||||
void Parser::ParseStructUnionSpecifier(DeclSpec &DS) {
|
||||
assert((Tok.getKind() == tok::kw_struct ||
|
||||
|
@ -410,6 +417,8 @@ void Parser::ParseStructUnionSpecifier(DeclSpec &DS) {
|
|||
/// enum-specifier: [C99 6.7.2.2]
|
||||
/// 'enum' identifier[opt] '{' enumerator-list '}'
|
||||
/// [C99] 'enum' identifier[opt] '{' enumerator-list ',' '}'
|
||||
/// [GNU] 'enum' identifier[opt] '{' enumerator-list '}' attributes [TODO]
|
||||
/// [GNU] 'enum' identifier[opt] '{' enumerator-list ',' '}' attributes [TODO]
|
||||
/// 'enum' identifier
|
||||
/// enumerator-list:
|
||||
/// enumerator
|
||||
|
|
|
@ -237,8 +237,7 @@ void Parser::ParseIdentifierStatement(bool OnlyStatement) {
|
|||
/// ParseCaseStatement
|
||||
/// labeled-statement:
|
||||
/// 'case' constant-expression ':' statement
|
||||
///
|
||||
/// FIXME: Handle GNU case-range extension.
|
||||
/// [GNU] 'case' constant-expression '...' constant-expression ':' statement
|
||||
///
|
||||
/// Note that this does not parse the 'statement' at the end.
|
||||
///
|
||||
|
@ -246,7 +245,23 @@ void Parser::ParseCaseStatement() {
|
|||
assert(Tok.getKind() == tok::kw_case && "Not a case stmt!");
|
||||
ConsumeToken(); // eat the 'case'.
|
||||
|
||||
ParseAssignmentExpression(); // Expr without commas.
|
||||
ExprResult Res = ParseConstantExpression();
|
||||
if (Res.isInvalid) {
|
||||
SkipUntil(tok::colon);
|
||||
return;
|
||||
}
|
||||
|
||||
// GNU case range extension.
|
||||
if (Tok.getKind() == tok::ellipsis) {
|
||||
Diag(Tok, diag::ext_gnu_case_range);
|
||||
ConsumeToken();
|
||||
|
||||
ExprResult RHS = ParseConstantExpression();
|
||||
if (RHS.isInvalid) {
|
||||
SkipUntil(tok::colon);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Tok.getKind() == tok::colon) {
|
||||
ConsumeToken();
|
||||
|
|
|
@ -282,6 +282,9 @@ DIAG(ext_gnu_missing_equal_designator, EXTENSION,
|
|||
"use of GNU 'missing =' extension in designator")
|
||||
DIAG(ext_gnu_old_style_field_designator, EXTENSION,
|
||||
"use of GNU old-style field designator extension")
|
||||
DIAG(ext_gnu_case_range, EXTENSION,
|
||||
"use of GNU case range extension")
|
||||
|
||||
// Generic errors.
|
||||
DIAG(err_parse_error, ERROR,
|
||||
"parse error")
|
||||
|
|
Loading…
Reference in New Issue