From: Ted Kremenek Date: Thu, 18 Feb 2010 23:05:16 +0000 (+0000) Subject: Allow GNU attributes to appear in an Objective-C method declaration X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9e0493576af77dba1c48858c03e31a2897d0681e;p=clang Allow GNU attributes to appear in an Objective-C method declaration before the selector name (but after the return type). Among other things, this allows IBAction to be implemented with an attribute. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@96623 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index d1c9be233f..4bf183c4c0 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -772,6 +772,12 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, if (Tok.is(tok::l_paren)) ReturnType = ParseObjCTypeName(DSRet); + // If attributes exist before the method, parse them. + llvm::OwningPtr MethodAttrs; + if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) + MethodAttrs.reset(ParseGNUAttributes()); + + // Now parse the selector. SourceLocation selLoc; IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc); @@ -787,9 +793,9 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, llvm::SmallVector CargNames; if (Tok.isNot(tok::colon)) { // If attributes exist after the method, parse them. - llvm::OwningPtr MethodAttrs; if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) - MethodAttrs.reset(ParseGNUAttributes()); + MethodAttrs.reset(addAttributeLists(MethodAttrs.take(), + ParseGNUAttributes())); Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); DeclPtrTy Result @@ -863,9 +869,9 @@ Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, // FIXME: Add support for optional parmameter list... // If attributes exist after the method, parse them. - llvm::OwningPtr MethodAttrs; if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) - MethodAttrs.reset(ParseGNUAttributes()); + MethodAttrs.reset(addAttributeLists(MethodAttrs.take(), + ParseGNUAttributes())); if (KeyIdents.size() == 0) return DeclPtrTy(); diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m index 85cfac37be..5b2f86e543 100644 --- a/test/Index/c-index-api-loadTU-test.m +++ b/test/Index/c-index-api-loadTU-test.m @@ -5,7 +5,7 @@ { __attribute__((iboutlet)) id myoutlet; } - +- (void) __attribute__((ibaction)) myMessage:(id)msg; - foo; + fooC; @@ -58,6 +58,10 @@ int main (int argc, const char * argv[]) { // CHECK: c-index-api-loadTU-test.m:6:32: ObjCIvarDecl=myoutlet:6:32 (Definition) Extent=[6:32 - 6:40] // CHECK: c-index-api-loadTU-test.m:6:32: attribute(iboutlet)= Extent=[6:32 - 6:40] // CHECK: c-index-api-loadTU-test.m:6:29: TypeRef=id:0:0 Extent=[6:29 - 6:31] +// CHECK: c-index-api-loadTU-test.m:8:1: ObjCInstanceMethodDecl=myMessage::8:1 Extent=[8:1 - 8:54] +// CHECK: c-index-api-loadTU-test.m:8:1: attribute(ibaction)= Extent=[8:1 - 8:54] +// CHECK: c-index-api-loadTU-test.m:8:50: ParmDecl=msg:8:50 (Definition) Extent=[8:47 - 8:53] +// CHECK: c-index-api-loadTU-test.m:8:47: TypeRef=id:0:0 Extent=[8:47 - 8:49] // CHECK: c-index-api-loadTU-test.m:9:1: ObjCInstanceMethodDecl=foo:9:1 Extent=[9:1 - 9:7] // CHECK: c-index-api-loadTU-test.m:10:1: ObjCClassMethodDecl=fooC:10:1 Extent=[10:1 - 10:8] // CHECK: c-index-api-loadTU-test.m:14:12: ObjCInterfaceDecl=Bar:14:12 Extent=[14:1 - 18:5]