[cfe-commits] r159626 - in /cfe/trunk: include/clang/Parse/Parser.h include/clang/Sema/Sema.h lib/Parse/ParseDecl.cpp lib/Parse/ParseObjc.cpp lib/Parse/Parser.cpp lib/Sema/SemaDeclObjC.cpp test/SemaObjC/delay-parsing-cfunctions.m
jahanian
fjahanian at apple.com
Tue Jul 3 15:55:01 PDT 2012
On Jul 3, 2012, at 3:02 PM, Jean-Daniel Dupas wrote:
> This commit broke the Obj-C++11 parser:
Fixed in r159691.
- Fariborz
>
> ---- foo.mm
> @interface Foo
> @end
>
> @implementation Foo
>
> static int test() {
> return 0;
> }
>
> @end
>
> ----------
> clang++ -fsyntax-only -std=c++11 foo.mm
> foo.mm:8:2: error: expected expression
> return 0;
> ^
> foo.mm:9:2: error: expected ';' after top level declarator
> }
> ^
> ;
> foo.mm:12:1: error: missing '@end'
> ^
>
> @end
>
> foo.mm:5:1: note: implementation started here
> @implementation Foo
> ^
> 3 errors generated.
>
>
>
> Le 3 juil. 2012 à 01:37, Fariborz Jahanian a écrit :
>
>> Author: fjahanian
>> Date: Mon Jul 2 18:37:09 2012
>> New Revision: 159626
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=159626&view=rev
>> Log:
>> objective-c: just as we have done for method definitions,
>> c-functions declared in implementation should have their
>> parsing delayed until the end so, they can access forward
>> declared private methods. // rdar://10387088
>>
>> Added:
>> cfe/trunk/test/SemaObjC/delay-parsing-cfunctions.m
>> Modified:
>> cfe/trunk/include/clang/Parse/Parser.h
>> cfe/trunk/include/clang/Sema/Sema.h
>> cfe/trunk/lib/Parse/ParseDecl.cpp
>> cfe/trunk/lib/Parse/ParseObjc.cpp
>> cfe/trunk/lib/Parse/Parser.cpp
>> cfe/trunk/lib/Sema/SemaDeclObjC.cpp
>>
>> Modified: cfe/trunk/include/clang/Parse/Parser.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=159626&r1=159625&r2=159626&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Parse/Parser.h (original)
>> +++ cfe/trunk/include/clang/Parse/Parser.h Mon Jul 2 18:37:09 2012
>> @@ -1019,7 +1019,7 @@
>> void ParseLexedMethodDef(LexedMethod &LM);
>> void ParseLexedMemberInitializers(ParsingClass &Class);
>> void ParseLexedMemberInitializer(LateParsedMemberInitializer &MI);
>> - Decl *ParseLexedObjCMethodDefs(LexedMethod &LM);
>> + void ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod);
>> bool ConsumeAndStoreFunctionPrologue(CachedTokens &Toks);
>> bool ConsumeAndStoreUntil(tok::TokenKind T1,
>> CachedTokens &Toks,
>> @@ -1084,11 +1084,12 @@
>> struct ObjCImplParsingDataRAII {
>> Parser &P;
>> Decl *Dcl;
>> + bool HasCFunction;
>> typedef SmallVector<LexedMethod*, 8> LateParsedObjCMethodContainer;
>> LateParsedObjCMethodContainer LateParsedObjCMethods;
>>
>> ObjCImplParsingDataRAII(Parser &parser, Decl *D)
>> - : P(parser), Dcl(D) {
>> + : P(parser), Dcl(D), HasCFunction(false) {
>> P.CurParsedObjCImpl = this;
>> Finished = false;
>> }
>> @@ -1101,6 +1102,7 @@
>> bool Finished;
>> };
>> ObjCImplParsingDataRAII *CurParsedObjCImpl;
>> + void StashAwayMethodOrFunctionBodyTokens(Decl *MDecl);
>>
>> DeclGroupPtrTy ParseObjCAtImplementationDeclaration(SourceLocation AtLoc);
>> DeclGroupPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd);
>>
>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=159626&r1=159625&r2=159626&view=diff
>> ==============================================================================
>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>> +++ cfe/trunk/include/clang/Sema/Sema.h Mon Jul 2 18:37:09 2012
>> @@ -1317,7 +1317,11 @@
>> void CheckForFunctionRedefinition(FunctionDecl *FD);
>> Decl *ActOnStartOfFunctionDef(Scope *S, Declarator &D);
>> Decl *ActOnStartOfFunctionDef(Scope *S, Decl *D);
>> - void ActOnStartOfObjCMethodDef(Scope *S, Decl *D);
>> + void ActOnStartOfObjCMethodOrCFunctionDef(Scope *S, Decl *D,
>> + bool parseMethod);
>> + bool isObjCMethodDecl(Decl *D) {
>> + return D && isa<ObjCMethodDecl>(D);
>> + }
>>
>> void computeNRVO(Stmt *Body, sema::FunctionScopeInfo *Scope);
>> Decl *ActOnFinishFunctionBody(Decl *Decl, Stmt *Body);
>>
>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=159626&r1=159625&r2=159626&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon Jul 2 18:37:09 2012
>> @@ -1379,6 +1379,14 @@
>>
>> bool ExpectSemi = Context != Declarator::ForContext;
>>
>> + if (CurParsedObjCImpl && D.isFunctionDeclarator() &&
>> + Tok.is(tok::l_brace)) {
>> + // Consume the tokens and store them for later parsing.
>> + StashAwayMethodOrFunctionBodyTokens(FirstDecl);
>> + CurParsedObjCImpl->HasCFunction = true;
>> + ExpectSemi = false;
>> + }
>> +
>> // If we don't have a comma, it is either the end of the list (a ';') or an
>> // error, bail out.
>> while (Tok.is(tok::comma)) {
>>
>> Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=159626&r1=159625&r2=159626&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
>> +++ cfe/trunk/lib/Parse/ParseObjc.cpp Mon Jul 2 18:37:09 2012
>> @@ -1575,10 +1575,16 @@
>> assert(!Finished);
>> P.Actions.DefaultSynthesizeProperties(P.getCurScope(), Dcl);
>> for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
>> - P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i]);
>> + P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
>> + true/*Methods*/);
>>
>> P.Actions.ActOnAtEnd(P.getCurScope(), AtEnd);
>>
>> + if (HasCFunction)
>> + for (size_t i = 0; i < LateParsedObjCMethods.size(); ++i)
>> + P.ParseLexedObjCMethodDefs(*LateParsedObjCMethods[i],
>> + false/*c-functions*/);
>> +
>> /// \brief Clear and free the cached objc methods.
>> for (LateParsedObjCMethodContainer::iterator
>> I = LateParsedObjCMethods.begin(),
>> @@ -1915,6 +1921,19 @@
>> AutoreleasePoolBody.take());
>> }
>>
>> +/// StashAwayMethodOrFunctionBodyTokens - Consume the tokens and store them
>> +/// for later parsing.
>> +void Parser::StashAwayMethodOrFunctionBodyTokens(Decl *MDecl) {
>> + LexedMethod* LM = new LexedMethod(this, MDecl);
>> + CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
>> + CachedTokens &Toks = LM->Toks;
>> + // Begin by storing the '{' token.
>> + Toks.push_back(Tok);
>> + ConsumeBrace();
>> + // Consume everything up to (and including) the matching right brace.
>> + ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
>> +}
>> +
>> /// objc-method-def: objc-method-proto ';'[opt] '{' body '}'
>> ///
>> Decl *Parser::ParseObjCMethodDefinition() {
>> @@ -1955,15 +1974,7 @@
>>
>> if (CurParsedObjCImpl) {
>> // Consume the tokens and store them for later parsing.
>> - LexedMethod* LM = new LexedMethod(this, MDecl);
>> - CurParsedObjCImpl->LateParsedObjCMethods.push_back(LM);
>> - CachedTokens &Toks = LM->Toks;
>> - // Begin by storing the '{' token.
>> - Toks.push_back(Tok);
>> - ConsumeBrace();
>> - // Consume everything up to (and including) the matching right brace.
>> - ConsumeAndStoreUntil(tok::r_brace, Toks, /*StopAtSemi=*/false);
>> -
>> + StashAwayMethodOrFunctionBodyTokens(MDecl);
>> } else {
>> ConsumeBrace();
>> SkipUntil(tok::r_brace, /*StopAtSemi=*/false);
>> @@ -2821,8 +2832,15 @@
>> T.getCloseLocation()));
>> }
>>
>> -Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) {
>> -
>> +void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
>> + // MCDecl might be null due to error in method or c-function prototype, etc.
>> + Decl *MCDecl = LM.D;
>> + bool skip = MCDecl &&
>> + ((parseMethod && !Actions.isObjCMethodDecl(MCDecl)) ||
>> + (!parseMethod && Actions.isObjCMethodDecl(MCDecl)));
>> + if (skip)
>> + return;
>> +
>> // Save the current token position.
>> SourceLocation OrigLoc = Tok.getLocation();
>>
>> @@ -2832,24 +2850,25 @@
>> LM.Toks.push_back(Tok);
>> PP.EnterTokenStream(LM.Toks.data(), LM.Toks.size(), true, false);
>>
>> - // MDecl might be null due to error in method prototype, etc.
>> - Decl *MDecl = LM.D;
>> // Consume the previously pushed token.
>> ConsumeAnyToken();
>>
>> assert(Tok.is(tok::l_brace) && "Inline objective-c method not starting with '{'");
>> SourceLocation BraceLoc = Tok.getLocation();
>> - // Enter a scope for the method body.
>> + // Enter a scope for the method or c-fucntion body.
>> ParseScope BodyScope(this,
>> - Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope);
>> + parseMethod
>> + ? Scope::ObjCMethodScope|Scope::FnScope|Scope::DeclScope
>> + : Scope::FnScope|Scope::DeclScope);
>>
>> - // Tell the actions module that we have entered a method definition with the
>> - // specified Declarator for the method.
>> - Actions.ActOnStartOfObjCMethodDef(getCurScope(), MDecl);
>> + // Tell the actions module that we have entered a method or c-function definition
>> + // with the specified Declarator for the method/function.
>> + Actions.ActOnStartOfObjCMethodOrCFunctionDef(getCurScope(), MCDecl, parseMethod);
>>
>> if (SkipFunctionBodies && trySkippingFunctionBody()) {
>> BodyScope.Exit();
>> - return Actions.ActOnFinishFunctionBody(MDecl, 0);
>> + (void)Actions.ActOnFinishFunctionBody(MCDecl, 0);
>> + return;
>> }
>>
>> StmtResult FnBody(ParseCompoundStatementBody());
>> @@ -2864,7 +2883,7 @@
>> // Leave the function body scope.
>> BodyScope.Exit();
>>
>> - MDecl = Actions.ActOnFinishFunctionBody(MDecl, FnBody.take());
>> + (void)Actions.ActOnFinishFunctionBody(MCDecl, FnBody.take());
>>
>> if (Tok.getLocation() != OrigLoc) {
>> // Due to parsing error, we either went over the cached tokens or
>> @@ -2878,5 +2897,5 @@
>> ConsumeAnyToken();
>> }
>>
>> - return MDecl;
>> + return;
>> }
>>
>> Modified: cfe/trunk/lib/Parse/Parser.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=159626&r1=159625&r2=159626&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Parse/Parser.cpp (original)
>> +++ cfe/trunk/lib/Parse/Parser.cpp Mon Jul 2 18:37:09 2012
>> @@ -766,14 +766,16 @@
>> if (KW.is(tok::kw_default) || KW.is(tok::kw_delete))
>> return false;
>> }
>> -
>> +
>> return Tok.is(tok::equal) || // int X()= -> not a function def
>> Tok.is(tok::comma) || // int X(), -> not a function def
>> Tok.is(tok::semi) || // int X(); -> not a function def
>> Tok.is(tok::kw_asm) || // int X() __asm__ -> not a function def
>> Tok.is(tok::kw___attribute) || // int X() __attr__ -> not a function def
>> (getLangOpts().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++]
>> + (CurParsedObjCImpl &&
>> + Tok.is(tok::l_brace)); // C-function nested in an @implementation
>> }
>>
>> /// \brief Determine whether the current token, if it occurs after a
>>
>> Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=159626&r1=159625&r2=159626&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
>> +++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Mon Jul 2 18:37:09 2012
>> @@ -265,12 +265,36 @@
>> AddFactoryMethodToGlobalPool(MDecl, true);
>> }
>>
>> -/// ActOnStartOfObjCMethodDef - This routine sets up parameters; invisible
>> -/// and user declared, in the method definition's AST.
>> -void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
>> - assert(getCurMethodDecl() == 0 && "Method parsing confused");
>> +/// ActOnStartOfObjCMethodOrCFunctionDef - This routine sets up parameters; invisible
>> +/// and user declared, in the method definition's AST. This routine is also called
>> +/// for C-functions defined in an Objective-c class implementation.
>> +void Sema::ActOnStartOfObjCMethodOrCFunctionDef(Scope *FnBodyScope, Decl *D,
>> + bool parseMethod) {
>> + assert((getCurMethodDecl() == 0 && getCurFunctionDecl() == 0) &&
>> + "Method/c-function parsing confused");
>> + if (!parseMethod) {
>> + FunctionDecl *FDecl = FDecl = dyn_cast_or_null<FunctionDecl>(D);
>> + // If we don't have a valid c-function decl, simply return.
>> + if (!FDecl)
>> + return;
>> + PushDeclContext(FnBodyScope, FDecl);
>> + PushFunctionScope();
>> +
>> + for (FunctionDecl::param_const_iterator PI = FDecl->param_begin(),
>> + E = FDecl->param_end(); PI != E; ++PI) {
>> + ParmVarDecl *Param = (*PI);
>> + if (!Param->isInvalidDecl() &&
>> + RequireCompleteType(Param->getLocation(), Param->getType(),
>> + diag::err_typecheck_decl_incomplete_type))
>> + Param->setInvalidDecl();
>> + if ((*PI)->getIdentifier())
>> + PushOnScopeChains(*PI, FnBodyScope);
>> + }
>> + return;
>> + }
>> +
>> ObjCMethodDecl *MDecl = dyn_cast_or_null<ObjCMethodDecl>(D);
>> -
>> +
>> // If we don't have a valid method decl, simply return.
>> if (!MDecl)
>> return;
>>
>> Added: cfe/trunk/test/SemaObjC/delay-parsing-cfunctions.m
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/delay-parsing-cfunctions.m?rev=159626&view=auto
>> ==============================================================================
>> --- cfe/trunk/test/SemaObjC/delay-parsing-cfunctions.m (added)
>> +++ cfe/trunk/test/SemaObjC/delay-parsing-cfunctions.m Mon Jul 2 18:37:09 2012
>> @@ -0,0 +1,32 @@
>> +// RUN: %clang_cc1 -fsyntax-only -Werror -verify -Wno-objc-root-class %s
>> +// RUN: %clang_cc1 -x objective-c++ -fsyntax-only -Werror -verify -Wno-objc-root-class %s
>> +// rdar://10387088
>> +
>> + at interface MyClass
>> +- (void)someMethod;
>> + at end
>> +
>> + at implementation MyClass
>> +- (void)someMethod {
>> + [self privateMethod]; // clang already does not warn here
>> +}
>> +
>> +int bar(MyClass * myObject) {
>> + [myObject privateMethod];
>> + return gorfbar(myObject);
>> +}
>> +- (void)privateMethod { }
>> +
>> +int gorfbar(MyClass * myObject) {
>> + [myObject privateMethod];
>> + [myObject privateMethod1];
>> + return getMe + bar(myObject);
>> +}
>> +
>> +- (void)privateMethod1 {
>> + getMe = getMe+1;
>> +}
>> +
>> +static int getMe;
>> +
>> + at end
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
> -- Jean-Daniel
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20120703/dc0d3f62/attachment.html>
More information about the cfe-commits
mailing list