diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 56 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 11 |
2 files changed, 36 insertions, 31 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 1f8522f094c..5de4dd4a7c6 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/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/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 56f922d4005..b34c241fd1b 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/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] /// |