From 23c4b1883b13dc17484b7214091b73f3ba29096e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 29 Mar 2009 17:18:04 +0000 Subject: [PATCH] hoist checks for ; and in out of ParseInitDeclaratorListAfterFirstDeclarator into ParseSimpleDeclaration, and improve a diagnostic. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68009 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticParseKinds.td | 2 + lib/Parse/ParseDecl.cpp | 56 ++++++++++----------- lib/Parse/Parser.cpp | 11 ++-- test/Parser/typeof.c | 4 +- test/Sema/init.c | 2 +- 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 7b264d3461..ad996b7eeb 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -78,6 +78,8 @@ def err_expected_rparen : Error<"expected ')'">; def err_expected_rsquare : Error<"expected ']'">; def err_expected_rbrace : Error<"expected '}'">; def err_expected_greater : Error<"expected '>'">; +def err_expected_semi_declation : Error< + "expected ';' at end of declaration">; def err_expected_semi_decl_list : Error< "expected ';' at end of declaration list">; def ext_expected_semi_decl_list : Extension< diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 1f8522f094..5de4dd4a7c 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -273,7 +273,30 @@ Parser::DeclGroupPtrTy Parser::ParseSimpleDeclaration(unsigned Context) { Declarator DeclaratorInfo(DS, (Declarator::TheContext)Context); ParseDeclarator(DeclaratorInfo); - return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); + DeclGroupPtrTy DG = + ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); + + if (Tok.is(tok::semi)) { + ConsumeToken(); + // for(is key; in keys) is error. + if (Context == Declarator::ForContext && isTokIdentifier_in()) + Diag(Tok, diag::err_parse_error); + + return DG; + } + + // If this is an ObjC2 for-each loop, this is a successful declarator + // parse. The syntax for these looks like: + // 'for' '(' declaration 'in' expr ')' statement + if (Context == Declarator::ForContext && isTokIdentifier_in()) + return DG; + + Diag(Tok, diag::err_expected_semi_declation); + // Skip to end of block or statement + SkipUntil(tok::r_brace, true, true); + if (Tok.is(tok::semi)) + ConsumeToken(); + return DG; } @@ -315,7 +338,7 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) { SourceLocation Loc; OwningExprResult AsmLabel(ParseSimpleAsm(&Loc)); if (AsmLabel.isInvalid()) { - SkipUntil(tok::semi); + SkipUntil(tok::semi, true, true); return DeclGroupPtrTy(); } @@ -343,7 +366,7 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) { } else { OwningExprResult Init(ParseInitializer()); if (Init.isInvalid()) { - SkipUntil(tok::semi); + SkipUntil(tok::semi, true, true); return DeclGroupPtrTy(); } Actions.AddInitializerToDecl(ThisDecl, move(Init)); @@ -400,31 +423,8 @@ ParseInitDeclaratorListAfterFirstDeclarator(Declarator &D) { ParseDeclarator(D); } - if (Tok.is(tok::semi)) { - ConsumeToken(); - // for(is key; in keys) is error. - if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) { - Diag(Tok, diag::err_parse_error); - return DeclGroupPtrTy(); - } - - return Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0], - DeclsInGroup.size()); - } - - // If this is an ObjC2 for-each loop, this is a successful declarator - // parse. The syntax for these looks like: - // 'for' '(' declaration 'in' expr ')' statement - if (D.getContext() == Declarator::ForContext && isTokIdentifier_in()) - return Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0], - DeclsInGroup.size()); - - Diag(Tok, diag::err_parse_error); - // Skip to end of block or statement - SkipUntil(tok::r_brace, true, true); - if (Tok.is(tok::semi)) - ConsumeToken(); - return DeclGroupPtrTy(); + return Actions.FinalizeDeclaratorGroup(CurScope, &DeclsInGroup[0], + DeclsInGroup.size()); } /// ParseSpecifierQualifierList diff --git a/lib/Parse/Parser.cpp b/lib/Parse/Parser.cpp index 56f922d400..b34c241fd1 100644 --- a/lib/Parse/Parser.cpp +++ b/lib/Parse/Parser.cpp @@ -517,9 +517,13 @@ Parser::ParseDeclarationOrFunctionDefinition( Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def (getLang().CPlusPlus && - Tok.is(tok::l_paren)) ) { // int X(0) -> not a function def [C++] + Tok.is(tok::l_paren))) { // int X(0) -> not a function def [C++] // Parse the init-declarator-list for a normal declaration. - return ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); + DeclGroupPtrTy DG = + ParseInitDeclaratorListAfterFirstDeclarator(DeclaratorInfo); + // Eat the semi colon after the declaration. + ExpectAndConsume(tok::semi, diag::err_expected_semi_declation); + return DG; } @@ -564,7 +568,8 @@ Parser::ParseDeclarationOrFunctionDefinition( /// [C90] function-definition: [C99 6.7.1] - implicit int result /// [C90] decl-specs[opt] declarator declaration-list[opt] compound-statement /// [C++] function-definition: [C++ 8.4] -/// decl-specifier-seq[opt] declarator ctor-initializer[opt] function-body +/// decl-specifier-seq[opt] declarator ctor-initializer[opt] +/// function-body /// [C++] function-definition: [C++ 8.4] /// decl-specifier-seq[opt] declarator function-try-block [TODO] /// diff --git a/test/Parser/typeof.c b/test/Parser/typeof.c index 8cb16c36f2..76e8d479fc 100644 --- a/test/Parser/typeof.c +++ b/test/Parser/typeof.c @@ -9,8 +9,8 @@ static void test() { short typeof (int) aShortInt; // expected-error{{'short typeof' is invalid}} int int ttt; // expected-error{{cannot combine with previous 'int' declaration specifier}} typeof(TInt) anInt; - short TInt eee; // expected-error{{parse error}} - void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{parse error}} + short TInt eee; // expected-error{{expected ';' at end of declaration}} + void ary[7] fff; // expected-error{{array has incomplete element type 'void'}} expected-error{{expected ';' at end of declaration}} typeof(void ary[7]) anIntError; // expected-error{{expected ')'}} expected-note {{to match this '('}} expected-warning {{type specifier missing, defaults to 'int'}} typeof(const int) aci; const typeof (*pi) aConstInt; diff --git a/test/Sema/init.c b/test/Sema/init.c index 9430f312ad..cbf75e1bb1 100644 --- a/test/Sema/init.c +++ b/test/Sema/init.c @@ -20,7 +20,7 @@ int *h = &x; int test() { int a[10]; int b[10] = a; // expected-error {{initialization with '{...}' expected}} -int +; // expected-error {{expected identifier or '('}} expected-error {{parse error}} +int +; // expected-error {{expected identifier or '('}} expected-error {{expected ';' at end of declaration}} } -- 2.40.0