1 //===--- ParseObjC.cpp - Objective C Parsing ------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Objective-C portions of the Parser interface. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Parse/Parser.h" 15 #include "clang/Parse/DeclSpec.h" 16 #include "clang/Parse/Scope.h" 17 #include "AstGuard.h" 18 #include "clang/Parse/ParseDiagnostic.h" 19 #include "llvm/ADT/SmallVector.h" 20 using namespace clang; 21 22 23 /// ParseObjCAtDirectives - Handle parts of the external-declaration production: 24 /// external-declaration: [C99 6.9] 25 /// [OBJC] objc-class-definition 26 /// [OBJC] objc-class-declaration 27 /// [OBJC] objc-alias-declaration 28 /// [OBJC] objc-protocol-definition 29 /// [OBJC] objc-method-definition 30 /// [OBJC] '@' 'end' 31 Parser::DeclPtrTy Parser::ParseObjCAtDirectives() { 32 SourceLocation AtLoc = ConsumeToken(); // the "@" 33 34 switch (Tok.getObjCKeywordID()) { 35 case tok::objc_class: 36 return ParseObjCAtClassDeclaration(AtLoc); 37 case tok::objc_interface: 38 return ParseObjCAtInterfaceDeclaration(AtLoc); 39 case tok::objc_protocol: 40 return ParseObjCAtProtocolDeclaration(AtLoc); 41 case tok::objc_implementation: 42 return ParseObjCAtImplementationDeclaration(AtLoc); 43 case tok::objc_end: 44 return ParseObjCAtEndDeclaration(AtLoc); 45 case tok::objc_compatibility_alias: 46 return ParseObjCAtAliasDeclaration(AtLoc); 47 case tok::objc_synthesize: 48 return ParseObjCPropertySynthesize(AtLoc); 49 case tok::objc_dynamic: 50 return ParseObjCPropertyDynamic(AtLoc); 51 default: 52 Diag(AtLoc, diag::err_unexpected_at); 53 SkipUntil(tok::semi); 54 return DeclPtrTy(); 55 } 56 } 57 58 /// 59 /// objc-class-declaration: 60 /// '@' 'class' identifier-list ';' 61 /// 62 Parser::DeclPtrTy Parser::ParseObjCAtClassDeclaration(SourceLocation atLoc) { 63 ConsumeToken(); // the identifier "class" 64 llvm::SmallVector<IdentifierInfo *, 8> ClassNames; 65 66 while (1) { 67 if (Tok.isNot(tok::identifier)) { 68 Diag(Tok, diag::err_expected_ident); 69 SkipUntil(tok::semi); 70 return DeclPtrTy(); 71 } 72 ClassNames.push_back(Tok.getIdentifierInfo()); 73 ConsumeToken(); 74 75 if (Tok.isNot(tok::comma)) 76 break; 77 78 ConsumeToken(); 79 } 80 81 // Consume the ';'. 82 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@class")) 83 return DeclPtrTy(); 84 85 return Actions.ActOnForwardClassDeclaration(atLoc, 86 &ClassNames[0], ClassNames.size()); 87 } 88 89 /// 90 /// objc-interface: 91 /// objc-class-interface-attributes[opt] objc-class-interface 92 /// objc-category-interface 93 /// 94 /// objc-class-interface: 95 /// '@' 'interface' identifier objc-superclass[opt] 96 /// objc-protocol-refs[opt] 97 /// objc-class-instance-variables[opt] 98 /// objc-interface-decl-list 99 /// @end 100 /// 101 /// objc-category-interface: 102 /// '@' 'interface' identifier '(' identifier[opt] ')' 103 /// objc-protocol-refs[opt] 104 /// objc-interface-decl-list 105 /// @end 106 /// 107 /// objc-superclass: 108 /// ':' identifier 109 /// 110 /// objc-class-interface-attributes: 111 /// __attribute__((visibility("default"))) 112 /// __attribute__((visibility("hidden"))) 113 /// __attribute__((deprecated)) 114 /// __attribute__((unavailable)) 115 /// __attribute__((objc_exception)) - used by NSException on 64-bit 116 /// 117 Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( 118 SourceLocation atLoc, AttributeList *attrList) { 119 assert(Tok.isObjCAtKeyword(tok::objc_interface) && 120 "ParseObjCAtInterfaceDeclaration(): Expected @interface"); 121 ConsumeToken(); // the "interface" identifier 122 123 if (Tok.isNot(tok::identifier)) { 124 Diag(Tok, diag::err_expected_ident); // missing class or category name. 125 return DeclPtrTy(); 126 } 127 // We have a class or category name - consume it. 128 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 129 SourceLocation nameLoc = ConsumeToken(); 130 131 if (Tok.is(tok::l_paren)) { // we have a category. 132 SourceLocation lparenLoc = ConsumeParen(); 133 SourceLocation categoryLoc, rparenLoc; 134 IdentifierInfo *categoryId = 0; 135 136 // For ObjC2, the category name is optional (not an error). 137 if (Tok.is(tok::identifier)) { 138 categoryId = Tok.getIdentifierInfo(); 139 categoryLoc = ConsumeToken(); 140 } else if (!getLang().ObjC2) { 141 Diag(Tok, diag::err_expected_ident); // missing category name. 142 return DeclPtrTy(); 143 } 144 if (Tok.isNot(tok::r_paren)) { 145 Diag(Tok, diag::err_expected_rparen); 146 SkipUntil(tok::r_paren, false); // don't stop at ';' 147 return DeclPtrTy(); 148 } 149 rparenLoc = ConsumeParen(); 150 151 // Next, we need to check for any protocol references. 152 SourceLocation EndProtoLoc; 153 llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; 154 if (Tok.is(tok::less) && 155 ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) 156 return DeclPtrTy(); 157 158 if (attrList) // categories don't support attributes. 159 Diag(Tok, diag::err_objc_no_attributes_on_category); 160 161 DeclPtrTy CategoryType = Actions.ActOnStartCategoryInterface(atLoc, 162 nameId, nameLoc, categoryId, categoryLoc, 163 &ProtocolRefs[0], ProtocolRefs.size(), 164 EndProtoLoc); 165 166 ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword); 167 return CategoryType; 168 } 169 // Parse a class interface. 170 IdentifierInfo *superClassId = 0; 171 SourceLocation superClassLoc; 172 173 if (Tok.is(tok::colon)) { // a super class is specified. 174 ConsumeToken(); 175 if (Tok.isNot(tok::identifier)) { 176 Diag(Tok, diag::err_expected_ident); // missing super class name. 177 return DeclPtrTy(); 178 } 179 superClassId = Tok.getIdentifierInfo(); 180 superClassLoc = ConsumeToken(); 181 } 182 // Next, we need to check for any protocol references. 183 llvm::SmallVector<Action::DeclPtrTy, 8> ProtocolRefs; 184 SourceLocation EndProtoLoc; 185 if (Tok.is(tok::less) && 186 ParseObjCProtocolReferences(ProtocolRefs, true, EndProtoLoc)) 187 return DeclPtrTy(); 188 189 DeclPtrTy ClsType = 190 Actions.ActOnStartClassInterface(atLoc, nameId, nameLoc, 191 superClassId, superClassLoc, 192 &ProtocolRefs[0], ProtocolRefs.size(), 193 EndProtoLoc, attrList); 194 195 if (Tok.is(tok::l_brace)) 196 ParseObjCClassInstanceVariables(ClsType, atLoc); 197 198 ParseObjCInterfaceDeclList(ClsType, tok::objc_interface); 199 return ClsType; 200 } 201 202 /// objc-interface-decl-list: 203 /// empty 204 /// objc-interface-decl-list objc-property-decl [OBJC2] 205 /// objc-interface-decl-list objc-method-requirement [OBJC2] 206 /// objc-interface-decl-list objc-method-proto ';' 207 /// objc-interface-decl-list declaration 208 /// objc-interface-decl-list ';' 209 /// 210 /// objc-method-requirement: [OBJC2] 211 /// @required 212 /// @optional 213 /// 214 void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl, 215 tok::ObjCKeywordKind contextKey) { 216 llvm::SmallVector<DeclPtrTy, 32> allMethods; 217 llvm::SmallVector<DeclPtrTy, 16> allProperties; 218 llvm::SmallVector<DeclGroupPtrTy, 8> allTUVariables; 219 tok::ObjCKeywordKind MethodImplKind = tok::objc_not_keyword; 220 221 SourceLocation AtEndLoc; 222 223 while (1) { 224 // If this is a method prototype, parse it. 225 if (Tok.is(tok::minus) || Tok.is(tok::plus)) { 226 DeclPtrTy methodPrototype = 227 ParseObjCMethodPrototype(interfaceDecl, MethodImplKind); 228 allMethods.push_back(methodPrototype); 229 // Consume the ';' here, since ParseObjCMethodPrototype() is re-used for 230 // method definitions. 231 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_method_proto, 232 "", tok::semi); 233 continue; 234 } 235 236 // Ignore excess semicolons. 237 if (Tok.is(tok::semi)) { 238 ConsumeToken(); 239 continue; 240 } 241 242 // If we got to the end of the file, exit the loop. 243 if (Tok.is(tok::eof)) 244 break; 245 246 // If we don't have an @ directive, parse it as a function definition. 247 if (Tok.isNot(tok::at)) { 248 // The code below does not consume '}'s because it is afraid of eating the 249 // end of a namespace. Because of the way this code is structured, an 250 // erroneous r_brace would cause an infinite loop if not handled here. 251 if (Tok.is(tok::r_brace)) 252 break; 253 254 // FIXME: as the name implies, this rule allows function definitions. 255 // We could pass a flag or check for functions during semantic analysis. 256 allTUVariables.push_back(ParseDeclarationOrFunctionDefinition()); 257 continue; 258 } 259 260 // Otherwise, we have an @ directive, eat the @. 261 SourceLocation AtLoc = ConsumeToken(); // the "@" 262 tok::ObjCKeywordKind DirectiveKind = Tok.getObjCKeywordID(); 263 264 if (DirectiveKind == tok::objc_end) { // @end -> terminate list 265 AtEndLoc = AtLoc; 266 break; 267 } 268 269 // Eat the identifier. 270 ConsumeToken(); 271 272 switch (DirectiveKind) { 273 default: 274 // FIXME: If someone forgets an @end on a protocol, this loop will 275 // continue to eat up tons of stuff and spew lots of nonsense errors. It 276 // would probably be better to bail out if we saw an @class or @interface 277 // or something like that. 278 Diag(AtLoc, diag::err_objc_illegal_interface_qual); 279 // Skip until we see an '@' or '}' or ';'. 280 SkipUntil(tok::r_brace, tok::at); 281 break; 282 283 case tok::objc_required: 284 case tok::objc_optional: 285 // This is only valid on protocols. 286 // FIXME: Should this check for ObjC2 being enabled? 287 if (contextKey != tok::objc_protocol) 288 Diag(AtLoc, diag::err_objc_directive_only_in_protocol); 289 else 290 MethodImplKind = DirectiveKind; 291 break; 292 293 case tok::objc_property: 294 if (!getLang().ObjC2) 295 Diag(AtLoc, diag::err_objc_propertoes_require_objc2); 296 297 ObjCDeclSpec OCDS; 298 // Parse property attribute list, if any. 299 if (Tok.is(tok::l_paren)) 300 ParseObjCPropertyAttribute(OCDS); 301 302 // Parse all the comma separated declarators. 303 DeclSpec DS; 304 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators; 305 ParseStructDeclaration(DS, FieldDeclarators); 306 307 ExpectAndConsume(tok::semi, diag::err_expected_semi_decl_list, "", 308 tok::at); 309 310 // Convert them all to property declarations. 311 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { 312 FieldDeclarator &FD = FieldDeclarators[i]; 313 if (FD.D.getIdentifier() == 0) { 314 Diag(AtLoc, diag::err_objc_property_requires_field_name) 315 << FD.D.getSourceRange(); 316 continue; 317 } 318 if (FD.BitfieldSize) { 319 Diag(AtLoc, diag::err_objc_property_bitfield) 320 << FD.D.getSourceRange(); 321 continue; 322 } 323 324 // Install the property declarator into interfaceDecl. 325 IdentifierInfo *SelName = 326 OCDS.getGetterName() ? OCDS.getGetterName() : FD.D.getIdentifier(); 327 328 Selector GetterSel = 329 PP.getSelectorTable().getNullarySelector(SelName); 330 IdentifierInfo *SetterName = OCDS.getSetterName(); 331 Selector SetterSel; 332 if (SetterName) 333 SetterSel = PP.getSelectorTable().getSelector(1, &SetterName); 334 else 335 SetterSel = SelectorTable::constructSetterName(PP.getIdentifierTable(), 336 PP.getSelectorTable(), 337 FD.D.getIdentifier()); 338 bool isOverridingProperty = false; 339 DeclPtrTy Property = Actions.ActOnProperty(CurScope, AtLoc, FD, OCDS, 340 GetterSel, SetterSel, 341 interfaceDecl, 342 &isOverridingProperty, 343 MethodImplKind); 344 if (!isOverridingProperty) 345 allProperties.push_back(Property); 346 } 347 break; 348 } 349 } 350 351 // We break out of the big loop in two cases: when we see @end or when we see 352 // EOF. In the former case, eat the @end. In the later case, emit an error. 353 if (Tok.isObjCAtKeyword(tok::objc_end)) 354 ConsumeToken(); // the "end" identifier 355 else 356 Diag(Tok, diag::err_objc_missing_end); 357 358 // Insert collected methods declarations into the @interface object. 359 // This passes in an invalid SourceLocation for AtEndLoc when EOF is hit. 360 Actions.ActOnAtEnd(AtEndLoc, interfaceDecl, 361 &allMethods[0], allMethods.size(), 362 &allProperties[0], allProperties.size(), 363 &allTUVariables[0], allTUVariables.size()); 364 } 365 366 /// Parse property attribute declarations. 367 /// 368 /// property-attr-decl: '(' property-attrlist ')' 369 /// property-attrlist: 370 /// property-attribute 371 /// property-attrlist ',' property-attribute 372 /// property-attribute: 373 /// getter '=' identifier 374 /// setter '=' identifier ':' 375 /// readonly 376 /// readwrite 377 /// assign 378 /// retain 379 /// copy 380 /// nonatomic 381 /// 382 void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { 383 assert(Tok.getKind() == tok::l_paren); 384 SourceLocation LHSLoc = ConsumeParen(); // consume '(' 385 386 while (1) { 387 const IdentifierInfo *II = Tok.getIdentifierInfo(); 388 389 // If this is not an identifier at all, bail out early. 390 if (II == 0) { 391 MatchRHSPunctuation(tok::r_paren, LHSLoc); 392 return; 393 } 394 395 SourceLocation AttrName = ConsumeToken(); // consume last attribute name 396 397 if (II->isStr("readonly")) 398 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readonly); 399 else if (II->isStr("assign")) 400 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_assign); 401 else if (II->isStr("readwrite")) 402 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_readwrite); 403 else if (II->isStr("retain")) 404 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_retain); 405 else if (II->isStr("copy")) 406 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_copy); 407 else if (II->isStr("nonatomic")) 408 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic); 409 else if (II->isStr("getter") || II->isStr("setter")) { 410 // getter/setter require extra treatment. 411 if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "", 412 tok::r_paren)) 413 return; 414 415 if (Tok.isNot(tok::identifier)) { 416 Diag(Tok, diag::err_expected_ident); 417 SkipUntil(tok::r_paren); 418 return; 419 } 420 421 if (II->getName()[0] == 's') { 422 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter); 423 DS.setSetterName(Tok.getIdentifierInfo()); 424 ConsumeToken(); // consume method name 425 426 if (ExpectAndConsume(tok::colon, diag::err_expected_colon, "", 427 tok::r_paren)) 428 return; 429 } else { 430 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_getter); 431 DS.setGetterName(Tok.getIdentifierInfo()); 432 ConsumeToken(); // consume method name 433 } 434 } else { 435 Diag(AttrName, diag::err_objc_expected_property_attr) << II; 436 SkipUntil(tok::r_paren); 437 return; 438 } 439 440 if (Tok.isNot(tok::comma)) 441 break; 442 443 ConsumeToken(); 444 } 445 446 MatchRHSPunctuation(tok::r_paren, LHSLoc); 447 } 448 449 /// objc-method-proto: 450 /// objc-instance-method objc-method-decl objc-method-attributes[opt] 451 /// objc-class-method objc-method-decl objc-method-attributes[opt] 452 /// 453 /// objc-instance-method: '-' 454 /// objc-class-method: '+' 455 /// 456 /// objc-method-attributes: [OBJC2] 457 /// __attribute__((deprecated)) 458 /// 459 Parser::DeclPtrTy Parser::ParseObjCMethodPrototype(DeclPtrTy IDecl, 460 tok::ObjCKeywordKind MethodImplKind) { 461 assert((Tok.is(tok::minus) || Tok.is(tok::plus)) && "expected +/-"); 462 463 tok::TokenKind methodType = Tok.getKind(); 464 SourceLocation mLoc = ConsumeToken(); 465 466 DeclPtrTy MDecl = ParseObjCMethodDecl(mLoc, methodType, IDecl,MethodImplKind); 467 // Since this rule is used for both method declarations and definitions, 468 // the caller is (optionally) responsible for consuming the ';'. 469 return MDecl; 470 } 471 472 /// objc-selector: 473 /// identifier 474 /// one of 475 /// enum struct union if else while do for switch case default 476 /// break continue return goto asm sizeof typeof __alignof 477 /// unsigned long const short volatile signed restrict _Complex 478 /// in out inout bycopy byref oneway int char float double void _Bool 479 /// 480 IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) { 481 switch (Tok.getKind()) { 482 default: 483 return 0; 484 case tok::identifier: 485 case tok::kw_asm: 486 case tok::kw_auto: 487 case tok::kw_bool: 488 case tok::kw_break: 489 case tok::kw_case: 490 case tok::kw_catch: 491 case tok::kw_char: 492 case tok::kw_class: 493 case tok::kw_const: 494 case tok::kw_const_cast: 495 case tok::kw_continue: 496 case tok::kw_default: 497 case tok::kw_delete: 498 case tok::kw_do: 499 case tok::kw_double: 500 case tok::kw_dynamic_cast: 501 case tok::kw_else: 502 case tok::kw_enum: 503 case tok::kw_explicit: 504 case tok::kw_export: 505 case tok::kw_extern: 506 case tok::kw_false: 507 case tok::kw_float: 508 case tok::kw_for: 509 case tok::kw_friend: 510 case tok::kw_goto: 511 case tok::kw_if: 512 case tok::kw_inline: 513 case tok::kw_int: 514 case tok::kw_long: 515 case tok::kw_mutable: 516 case tok::kw_namespace: 517 case tok::kw_new: 518 case tok::kw_operator: 519 case tok::kw_private: 520 case tok::kw_protected: 521 case tok::kw_public: 522 case tok::kw_register: 523 case tok::kw_reinterpret_cast: 524 case tok::kw_restrict: 525 case tok::kw_return: 526 case tok::kw_short: 527 case tok::kw_signed: 528 case tok::kw_sizeof: 529 case tok::kw_static: 530 case tok::kw_static_cast: 531 case tok::kw_struct: 532 case tok::kw_switch: 533 case tok::kw_template: 534 case tok::kw_this: 535 case tok::kw_throw: 536 case tok::kw_true: 537 case tok::kw_try: 538 case tok::kw_typedef: 539 case tok::kw_typeid: 540 case tok::kw_typename: 541 case tok::kw_typeof: 542 case tok::kw_union: 543 case tok::kw_unsigned: 544 case tok::kw_using: 545 case tok::kw_virtual: 546 case tok::kw_void: 547 case tok::kw_volatile: 548 case tok::kw_wchar_t: 549 case tok::kw_while: 550 case tok::kw__Bool: 551 case tok::kw__Complex: 552 case tok::kw___alignof: 553 IdentifierInfo *II = Tok.getIdentifierInfo(); 554 SelectorLoc = ConsumeToken(); 555 return II; 556 } 557 } 558 559 /// objc-for-collection-in: 'in' 560 /// 561 bool Parser::isTokIdentifier_in() const { 562 // FIXME: May have to do additional look-ahead to only allow for 563 // valid tokens following an 'in'; such as an identifier, unary operators, 564 // '[' etc. 565 return (getLang().ObjC2 && Tok.is(tok::identifier) && 566 Tok.getIdentifierInfo() == ObjCTypeQuals[objc_in]); 567 } 568 569 /// ParseObjCTypeQualifierList - This routine parses the objective-c's type 570 /// qualifier list and builds their bitmask representation in the input 571 /// argument. 572 /// 573 /// objc-type-qualifiers: 574 /// objc-type-qualifier 575 /// objc-type-qualifiers objc-type-qualifier 576 /// 577 void Parser::ParseObjCTypeQualifierList(ObjCDeclSpec &DS) { 578 while (1) { 579 if (Tok.isNot(tok::identifier)) 580 return; 581 582 const IdentifierInfo *II = Tok.getIdentifierInfo(); 583 for (unsigned i = 0; i != objc_NumQuals; ++i) { 584 if (II != ObjCTypeQuals[i]) 585 continue; 586 587 ObjCDeclSpec::ObjCDeclQualifier Qual; 588 switch (i) { 589 default: assert(0 && "Unknown decl qualifier"); 590 case objc_in: Qual = ObjCDeclSpec::DQ_In; break; 591 case objc_out: Qual = ObjCDeclSpec::DQ_Out; break; 592 case objc_inout: Qual = ObjCDeclSpec::DQ_Inout; break; 593 case objc_oneway: Qual = ObjCDeclSpec::DQ_Oneway; break; 594 case objc_bycopy: Qual = ObjCDeclSpec::DQ_Bycopy; break; 595 case objc_byref: Qual = ObjCDeclSpec::DQ_Byref; break; 596 } 597 DS.setObjCDeclQualifier(Qual); 598 ConsumeToken(); 599 II = 0; 600 break; 601 } 602 603 // If this wasn't a recognized qualifier, bail out. 604 if (II) return; 605 } 606 } 607 608 /// objc-type-name: 609 /// '(' objc-type-qualifiers[opt] type-name ')' 610 /// '(' objc-type-qualifiers[opt] ')' 611 /// 612 Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) { 613 assert(Tok.is(tok::l_paren) && "expected ("); 614 615 SourceLocation LParenLoc = ConsumeParen(); 616 SourceLocation TypeStartLoc = Tok.getLocation(); 617 618 // Parse type qualifiers, in, inout, etc. 619 ParseObjCTypeQualifierList(DS); 620 621 TypeTy *Ty = 0; 622 if (isTypeSpecifierQualifier()) { 623 TypeResult TypeSpec = ParseTypeName(); 624 if (!TypeSpec.isInvalid()) 625 Ty = TypeSpec.get(); 626 } 627 628 if (Tok.is(tok::r_paren)) 629 ConsumeParen(); 630 else if (Tok.getLocation() == TypeStartLoc) { 631 // If we didn't eat any tokens, then this isn't a type. 632 Diag(Tok, diag::err_expected_type); 633 SkipUntil(tok::r_paren); 634 } else { 635 // Otherwise, we found *something*, but didn't get a ')' in the right 636 // place. Emit an error then return what we have as the type. 637 MatchRHSPunctuation(tok::r_paren, LParenLoc); 638 } 639 return Ty; 640 } 641 642 /// objc-method-decl: 643 /// objc-selector 644 /// objc-keyword-selector objc-parmlist[opt] 645 /// objc-type-name objc-selector 646 /// objc-type-name objc-keyword-selector objc-parmlist[opt] 647 /// 648 /// objc-keyword-selector: 649 /// objc-keyword-decl 650 /// objc-keyword-selector objc-keyword-decl 651 /// 652 /// objc-keyword-decl: 653 /// objc-selector ':' objc-type-name objc-keyword-attributes[opt] identifier 654 /// objc-selector ':' objc-keyword-attributes[opt] identifier 655 /// ':' objc-type-name objc-keyword-attributes[opt] identifier 656 /// ':' objc-keyword-attributes[opt] identifier 657 /// 658 /// objc-parmlist: 659 /// objc-parms objc-ellipsis[opt] 660 /// 661 /// objc-parms: 662 /// objc-parms , parameter-declaration 663 /// 664 /// objc-ellipsis: 665 /// , ... 666 /// 667 /// objc-keyword-attributes: [OBJC2] 668 /// __attribute__((unused)) 669 /// 670 Parser::DeclPtrTy Parser::ParseObjCMethodDecl(SourceLocation mLoc, 671 tok::TokenKind mType, 672 DeclPtrTy IDecl, 673 tok::ObjCKeywordKind MethodImplKind) { 674 // Parse the return type if present. 675 TypeTy *ReturnType = 0; 676 ObjCDeclSpec DSRet; 677 if (Tok.is(tok::l_paren)) 678 ReturnType = ParseObjCTypeName(DSRet); 679 680 SourceLocation selLoc; 681 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(selLoc); 682 683 // An unnamed colon is valid. 684 if (!SelIdent && Tok.isNot(tok::colon)) { // missing selector name. 685 Diag(Tok, diag::err_expected_selector_for_method) 686 << SourceRange(mLoc, Tok.getLocation()); 687 // Skip until we get a ; or {}. 688 SkipUntil(tok::r_brace); 689 return DeclPtrTy(); 690 } 691 692 llvm::SmallVector<Declarator, 8> CargNames; 693 if (Tok.isNot(tok::colon)) { 694 // If attributes exist after the method, parse them. 695 AttributeList *MethodAttrs = 0; 696 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 697 MethodAttrs = ParseAttributes(); 698 699 Selector Sel = PP.getSelectorTable().getNullarySelector(SelIdent); 700 return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), 701 mType, IDecl, DSRet, ReturnType, Sel, 702 0, CargNames, MethodAttrs, 703 MethodImplKind); 704 } 705 706 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 707 llvm::SmallVector<Action::ObjCArgInfo, 12> ArgInfos; 708 709 while (1) { 710 Action::ObjCArgInfo ArgInfo; 711 712 // Each iteration parses a single keyword argument. 713 if (Tok.isNot(tok::colon)) { 714 Diag(Tok, diag::err_expected_colon); 715 break; 716 } 717 ConsumeToken(); // Eat the ':'. 718 719 ArgInfo.Type = 0; 720 if (Tok.is(tok::l_paren)) // Parse the argument type if present. 721 ArgInfo.Type = ParseObjCTypeName(ArgInfo.DeclSpec); 722 723 // If attributes exist before the argument name, parse them. 724 ArgInfo.ArgAttrs = 0; 725 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 726 ArgInfo.ArgAttrs = ParseAttributes(); 727 728 if (Tok.isNot(tok::identifier)) { 729 Diag(Tok, diag::err_expected_ident); // missing argument name. 730 break; 731 } 732 733 ArgInfo.Name = Tok.getIdentifierInfo(); 734 ArgInfo.NameLoc = Tok.getLocation(); 735 ConsumeToken(); // Eat the identifier. 736 737 ArgInfos.push_back(ArgInfo); 738 KeyIdents.push_back(SelIdent); 739 740 // Check for another keyword selector. 741 SourceLocation Loc; 742 SelIdent = ParseObjCSelectorPiece(Loc); 743 if (!SelIdent && Tok.isNot(tok::colon)) 744 break; 745 // We have a selector or a colon, continue parsing. 746 } 747 748 bool isVariadic = false; 749 750 // Parse the (optional) parameter list. 751 while (Tok.is(tok::comma)) { 752 ConsumeToken(); 753 if (Tok.is(tok::ellipsis)) { 754 isVariadic = true; 755 ConsumeToken(); 756 break; 757 } 758 DeclSpec DS; 759 ParseDeclarationSpecifiers(DS); 760 // Parse the declarator. 761 Declarator ParmDecl(DS, Declarator::PrototypeContext); 762 ParseDeclarator(ParmDecl); 763 CargNames.push_back(ParmDecl); 764 } 765 766 // FIXME: Add support for optional parmameter list... 767 // If attributes exist after the method, parse them. 768 AttributeList *MethodAttrs = 0; 769 if (getLang().ObjC2 && Tok.is(tok::kw___attribute)) 770 MethodAttrs = ParseAttributes(); 771 772 Selector Sel = PP.getSelectorTable().getSelector(KeyIdents.size(), 773 &KeyIdents[0]); 774 return Actions.ActOnMethodDeclaration(mLoc, Tok.getLocation(), 775 mType, IDecl, DSRet, ReturnType, Sel, 776 &ArgInfos[0], CargNames, MethodAttrs, 777 MethodImplKind, isVariadic); 778 } 779 780 /// objc-protocol-refs: 781 /// '<' identifier-list '>' 782 /// 783 bool Parser:: 784 ParseObjCProtocolReferences(llvm::SmallVectorImpl<Action::DeclPtrTy> &Protocols, 785 bool WarnOnDeclarations, SourceLocation &EndLoc) { 786 assert(Tok.is(tok::less) && "expected <"); 787 788 ConsumeToken(); // the "<" 789 790 llvm::SmallVector<IdentifierLocPair, 8> ProtocolIdents; 791 792 while (1) { 793 if (Tok.isNot(tok::identifier)) { 794 Diag(Tok, diag::err_expected_ident); 795 SkipUntil(tok::greater); 796 return true; 797 } 798 ProtocolIdents.push_back(std::make_pair(Tok.getIdentifierInfo(), 799 Tok.getLocation())); 800 ConsumeToken(); 801 802 if (Tok.isNot(tok::comma)) 803 break; 804 ConsumeToken(); 805 } 806 807 // Consume the '>'. 808 if (Tok.isNot(tok::greater)) { 809 Diag(Tok, diag::err_expected_greater); 810 return true; 811 } 812 813 EndLoc = ConsumeAnyToken(); 814 815 // Convert the list of protocols identifiers into a list of protocol decls. 816 Actions.FindProtocolDeclaration(WarnOnDeclarations, 817 &ProtocolIdents[0], ProtocolIdents.size(), 818 Protocols); 819 return false; 820 } 821 822 /// objc-class-instance-variables: 823 /// '{' objc-instance-variable-decl-list[opt] '}' 824 /// 825 /// objc-instance-variable-decl-list: 826 /// objc-visibility-spec 827 /// objc-instance-variable-decl ';' 828 /// ';' 829 /// objc-instance-variable-decl-list objc-visibility-spec 830 /// objc-instance-variable-decl-list objc-instance-variable-decl ';' 831 /// objc-instance-variable-decl-list ';' 832 /// 833 /// objc-visibility-spec: 834 /// @private 835 /// @protected 836 /// @public 837 /// @package [OBJC2] 838 /// 839 /// objc-instance-variable-decl: 840 /// struct-declaration 841 /// 842 void Parser::ParseObjCClassInstanceVariables(DeclPtrTy interfaceDecl, 843 SourceLocation atLoc) { 844 assert(Tok.is(tok::l_brace) && "expected {"); 845 llvm::SmallVector<DeclPtrTy, 32> AllIvarDecls; 846 llvm::SmallVector<FieldDeclarator, 8> FieldDeclarators; 847 848 ParseScope ClassScope(this, Scope::DeclScope|Scope::ClassScope); 849 850 SourceLocation LBraceLoc = ConsumeBrace(); // the "{" 851 852 tok::ObjCKeywordKind visibility = tok::objc_protected; 853 // While we still have something to read, read the instance variables. 854 while (Tok.isNot(tok::r_brace) && Tok.isNot(tok::eof)) { 855 // Each iteration of this loop reads one objc-instance-variable-decl. 856 857 // Check for extraneous top-level semicolon. 858 if (Tok.is(tok::semi)) { 859 Diag(Tok, diag::ext_extra_struct_semi); 860 ConsumeToken(); 861 continue; 862 } 863 864 // Set the default visibility to private. 865 if (Tok.is(tok::at)) { // parse objc-visibility-spec 866 ConsumeToken(); // eat the @ sign 867 switch (Tok.getObjCKeywordID()) { 868 case tok::objc_private: 869 case tok::objc_public: 870 case tok::objc_protected: 871 case tok::objc_package: 872 visibility = Tok.getObjCKeywordID(); 873 ConsumeToken(); 874 continue; 875 default: 876 Diag(Tok, diag::err_objc_illegal_visibility_spec); 877 continue; 878 } 879 } 880 881 // Parse all the comma separated declarators. 882 DeclSpec DS; 883 FieldDeclarators.clear(); 884 ParseStructDeclaration(DS, FieldDeclarators); 885 886 // Convert them all to fields. 887 for (unsigned i = 0, e = FieldDeclarators.size(); i != e; ++i) { 888 FieldDeclarator &FD = FieldDeclarators[i]; 889 // Install the declarator into interfaceDecl. 890 DeclPtrTy Field = Actions.ActOnIvar(CurScope, 891 DS.getSourceRange().getBegin(), 892 FD.D, FD.BitfieldSize, visibility); 893 AllIvarDecls.push_back(Field); 894 } 895 896 if (Tok.is(tok::semi)) { 897 ConsumeToken(); 898 } else { 899 Diag(Tok, diag::err_expected_semi_decl_list); 900 // Skip to end of block or statement 901 SkipUntil(tok::r_brace, true, true); 902 } 903 } 904 SourceLocation RBraceLoc = MatchRHSPunctuation(tok::r_brace, LBraceLoc); 905 // Call ActOnFields() even if we don't have any decls. This is useful 906 // for code rewriting tools that need to be aware of the empty list. 907 Actions.ActOnFields(CurScope, atLoc, interfaceDecl, 908 &AllIvarDecls[0], AllIvarDecls.size(), 909 LBraceLoc, RBraceLoc, 0); 910 return; 911 } 912 913 /// objc-protocol-declaration: 914 /// objc-protocol-definition 915 /// objc-protocol-forward-reference 916 /// 917 /// objc-protocol-definition: 918 /// @protocol identifier 919 /// objc-protocol-refs[opt] 920 /// objc-interface-decl-list 921 /// @end 922 /// 923 /// objc-protocol-forward-reference: 924 /// @protocol identifier-list ';' 925 /// 926 /// "@protocol identifier ;" should be resolved as "@protocol 927 /// identifier-list ;": objc-interface-decl-list may not start with a 928 /// semicolon in the first alternative if objc-protocol-refs are omitted. 929 Parser::DeclPtrTy Parser::ParseObjCAtProtocolDeclaration(SourceLocation AtLoc, 930 AttributeList *attrList) { 931 assert(Tok.isObjCAtKeyword(tok::objc_protocol) && 932 "ParseObjCAtProtocolDeclaration(): Expected @protocol"); 933 ConsumeToken(); // the "protocol" identifier 934 935 if (Tok.isNot(tok::identifier)) { 936 Diag(Tok, diag::err_expected_ident); // missing protocol name. 937 return DeclPtrTy(); 938 } 939 // Save the protocol name, then consume it. 940 IdentifierInfo *protocolName = Tok.getIdentifierInfo(); 941 SourceLocation nameLoc = ConsumeToken(); 942 943 if (Tok.is(tok::semi)) { // forward declaration of one protocol. 944 IdentifierLocPair ProtoInfo(protocolName, nameLoc); 945 ConsumeToken(); 946 return Actions.ActOnForwardProtocolDeclaration(AtLoc, &ProtoInfo, 1, 947 attrList); 948 } 949 950 if (Tok.is(tok::comma)) { // list of forward declarations. 951 llvm::SmallVector<IdentifierLocPair, 8> ProtocolRefs; 952 ProtocolRefs.push_back(std::make_pair(protocolName, nameLoc)); 953 954 // Parse the list of forward declarations. 955 while (1) { 956 ConsumeToken(); // the ',' 957 if (Tok.isNot(tok::identifier)) { 958 Diag(Tok, diag::err_expected_ident); 959 SkipUntil(tok::semi); 960 return DeclPtrTy(); 961 } 962 ProtocolRefs.push_back(IdentifierLocPair(Tok.getIdentifierInfo(), 963 Tok.getLocation())); 964 ConsumeToken(); // the identifier 965 966 if (Tok.isNot(tok::comma)) 967 break; 968 } 969 // Consume the ';'. 970 if (ExpectAndConsume(tok::semi, diag::err_expected_semi_after, "@protocol")) 971 return DeclPtrTy(); 972 973 return Actions.ActOnForwardProtocolDeclaration(AtLoc, 974 &ProtocolRefs[0], 975 ProtocolRefs.size(), 976 attrList); 977 } 978 979 // Last, and definitely not least, parse a protocol declaration. 980 SourceLocation EndProtoLoc; 981 982 llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs; 983 if (Tok.is(tok::less) && 984 ParseObjCProtocolReferences(ProtocolRefs, false, EndProtoLoc)) 985 return DeclPtrTy(); 986 987 DeclPtrTy ProtoType = 988 Actions.ActOnStartProtocolInterface(AtLoc, protocolName, nameLoc, 989 &ProtocolRefs[0], ProtocolRefs.size(), 990 EndProtoLoc, attrList); 991 ParseObjCInterfaceDeclList(ProtoType, tok::objc_protocol); 992 return ProtoType; 993 } 994 995 /// objc-implementation: 996 /// objc-class-implementation-prologue 997 /// objc-category-implementation-prologue 998 /// 999 /// objc-class-implementation-prologue: 1000 /// @implementation identifier objc-superclass[opt] 1001 /// objc-class-instance-variables[opt] 1002 /// 1003 /// objc-category-implementation-prologue: 1004 /// @implementation identifier ( identifier ) 1005 Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( 1006 SourceLocation atLoc) { 1007 assert(Tok.isObjCAtKeyword(tok::objc_implementation) && 1008 "ParseObjCAtImplementationDeclaration(): Expected @implementation"); 1009 ConsumeToken(); // the "implementation" identifier 1010 1011 if (Tok.isNot(tok::identifier)) { 1012 Diag(Tok, diag::err_expected_ident); // missing class or category name. 1013 return DeclPtrTy(); 1014 } 1015 // We have a class or category name - consume it. 1016 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 1017 SourceLocation nameLoc = ConsumeToken(); // consume class or category name 1018 1019 if (Tok.is(tok::l_paren)) { 1020 // we have a category implementation. 1021 SourceLocation lparenLoc = ConsumeParen(); 1022 SourceLocation categoryLoc, rparenLoc; 1023 IdentifierInfo *categoryId = 0; 1024 1025 if (Tok.is(tok::identifier)) { 1026 categoryId = Tok.getIdentifierInfo(); 1027 categoryLoc = ConsumeToken(); 1028 } else { 1029 Diag(Tok, diag::err_expected_ident); // missing category name. 1030 return DeclPtrTy(); 1031 } 1032 if (Tok.isNot(tok::r_paren)) { 1033 Diag(Tok, diag::err_expected_rparen); 1034 SkipUntil(tok::r_paren, false); // don't stop at ';' 1035 return DeclPtrTy(); 1036 } 1037 rparenLoc = ConsumeParen(); 1038 DeclPtrTy ImplCatType = Actions.ActOnStartCategoryImplementation( 1039 atLoc, nameId, nameLoc, categoryId, 1040 categoryLoc); 1041 ObjCImpDecl = ImplCatType; 1042 return DeclPtrTy(); 1043 } 1044 // We have a class implementation 1045 SourceLocation superClassLoc; 1046 IdentifierInfo *superClassId = 0; 1047 if (Tok.is(tok::colon)) { 1048 // We have a super class 1049 ConsumeToken(); 1050 if (Tok.isNot(tok::identifier)) { 1051 Diag(Tok, diag::err_expected_ident); // missing super class name. 1052 return DeclPtrTy(); 1053 } 1054 superClassId = Tok.getIdentifierInfo(); 1055 superClassLoc = ConsumeToken(); // Consume super class name 1056 } 1057 DeclPtrTy ImplClsType = Actions.ActOnStartClassImplementation( 1058 atLoc, nameId, nameLoc, 1059 superClassId, superClassLoc); 1060 1061 if (Tok.is(tok::l_brace)) // we have ivars 1062 ParseObjCClassInstanceVariables(ImplClsType/*FIXME*/, atLoc); 1063 ObjCImpDecl = ImplClsType; 1064 1065 return DeclPtrTy(); 1066 } 1067 1068 Parser::DeclPtrTy Parser::ParseObjCAtEndDeclaration(SourceLocation atLoc) { 1069 assert(Tok.isObjCAtKeyword(tok::objc_end) && 1070 "ParseObjCAtEndDeclaration(): Expected @end"); 1071 DeclPtrTy Result = ObjCImpDecl; 1072 ConsumeToken(); // the "end" identifier 1073 if (ObjCImpDecl) { 1074 Actions.ActOnAtEnd(atLoc, ObjCImpDecl); 1075 ObjCImpDecl = DeclPtrTy(); 1076 } 1077 else 1078 Diag(atLoc, diag::warn_expected_implementation); // missing @implementation 1079 return Result; 1080 } 1081 1082 /// compatibility-alias-decl: 1083 /// @compatibility_alias alias-name class-name ';' 1084 /// 1085 Parser::DeclPtrTy Parser::ParseObjCAtAliasDeclaration(SourceLocation atLoc) { 1086 assert(Tok.isObjCAtKeyword(tok::objc_compatibility_alias) && 1087 "ParseObjCAtAliasDeclaration(): Expected @compatibility_alias"); 1088 ConsumeToken(); // consume compatibility_alias 1089 if (Tok.isNot(tok::identifier)) { 1090 Diag(Tok, diag::err_expected_ident); 1091 return DeclPtrTy(); 1092 } 1093 IdentifierInfo *aliasId = Tok.getIdentifierInfo(); 1094 SourceLocation aliasLoc = ConsumeToken(); // consume alias-name 1095 if (Tok.isNot(tok::identifier)) { 1096 Diag(Tok, diag::err_expected_ident); 1097 return DeclPtrTy(); 1098 } 1099 IdentifierInfo *classId = Tok.getIdentifierInfo(); 1100 SourceLocation classLoc = ConsumeToken(); // consume class-name; 1101 if (Tok.isNot(tok::semi)) { 1102 Diag(Tok, diag::err_expected_semi_after) << "@compatibility_alias"; 1103 return DeclPtrTy(); 1104 } 1105 return Actions.ActOnCompatiblityAlias(atLoc, aliasId, aliasLoc, 1106 classId, classLoc); 1107 } 1108 1109 /// property-synthesis: 1110 /// @synthesize property-ivar-list ';' 1111 /// 1112 /// property-ivar-list: 1113 /// property-ivar 1114 /// property-ivar-list ',' property-ivar 1115 /// 1116 /// property-ivar: 1117 /// identifier 1118 /// identifier '=' identifier 1119 /// 1120 Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { 1121 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && 1122 "ParseObjCPropertyDynamic(): Expected '@synthesize'"); 1123 SourceLocation loc = ConsumeToken(); // consume synthesize 1124 if (Tok.isNot(tok::identifier)) { 1125 Diag(Tok, diag::err_expected_ident); 1126 return DeclPtrTy(); 1127 } 1128 1129 while (Tok.is(tok::identifier)) { 1130 IdentifierInfo *propertyIvar = 0; 1131 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1132 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1133 if (Tok.is(tok::equal)) { 1134 // property '=' ivar-name 1135 ConsumeToken(); // consume '=' 1136 if (Tok.isNot(tok::identifier)) { 1137 Diag(Tok, diag::err_expected_ident); 1138 break; 1139 } 1140 propertyIvar = Tok.getIdentifierInfo(); 1141 ConsumeToken(); // consume ivar-name 1142 } 1143 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl, 1144 propertyId, propertyIvar); 1145 if (Tok.isNot(tok::comma)) 1146 break; 1147 ConsumeToken(); // consume ',' 1148 } 1149 if (Tok.isNot(tok::semi)) 1150 Diag(Tok, diag::err_expected_semi_after) << "@synthesize"; 1151 return DeclPtrTy(); 1152 } 1153 1154 /// property-dynamic: 1155 /// @dynamic property-list 1156 /// 1157 /// property-list: 1158 /// identifier 1159 /// property-list ',' identifier 1160 /// 1161 Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { 1162 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && 1163 "ParseObjCPropertyDynamic(): Expected '@dynamic'"); 1164 SourceLocation loc = ConsumeToken(); // consume dynamic 1165 if (Tok.isNot(tok::identifier)) { 1166 Diag(Tok, diag::err_expected_ident); 1167 return DeclPtrTy(); 1168 } 1169 while (Tok.is(tok::identifier)) { 1170 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1171 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1172 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl, 1173 propertyId, 0); 1174 1175 if (Tok.isNot(tok::comma)) 1176 break; 1177 ConsumeToken(); // consume ',' 1178 } 1179 if (Tok.isNot(tok::semi)) 1180 Diag(Tok, diag::err_expected_semi_after) << "@dynamic"; 1181 return DeclPtrTy(); 1182 } 1183 1184 /// objc-throw-statement: 1185 /// throw expression[opt]; 1186 /// 1187 Parser::OwningStmtResult Parser::ParseObjCThrowStmt(SourceLocation atLoc) { 1188 OwningExprResult Res(Actions); 1189 ConsumeToken(); // consume throw 1190 if (Tok.isNot(tok::semi)) { 1191 Res = ParseExpression(); 1192 if (Res.isInvalid()) { 1193 SkipUntil(tok::semi); 1194 return StmtError(); 1195 } 1196 } 1197 ConsumeToken(); // consume ';' 1198 return Actions.ActOnObjCAtThrowStmt(atLoc, move(Res), CurScope); 1199 } 1200 1201 /// objc-synchronized-statement: 1202 /// @synchronized '(' expression ')' compound-statement 1203 /// 1204 Parser::OwningStmtResult 1205 Parser::ParseObjCSynchronizedStmt(SourceLocation atLoc) { 1206 ConsumeToken(); // consume synchronized 1207 if (Tok.isNot(tok::l_paren)) { 1208 Diag(Tok, diag::err_expected_lparen_after) << "@synchronized"; 1209 return StmtError(); 1210 } 1211 ConsumeParen(); // '(' 1212 OwningExprResult Res(ParseExpression()); 1213 if (Res.isInvalid()) { 1214 SkipUntil(tok::semi); 1215 return StmtError(); 1216 } 1217 if (Tok.isNot(tok::r_paren)) { 1218 Diag(Tok, diag::err_expected_lbrace); 1219 return StmtError(); 1220 } 1221 ConsumeParen(); // ')' 1222 if (Tok.isNot(tok::l_brace)) { 1223 Diag(Tok, diag::err_expected_lbrace); 1224 return StmtError(); 1225 } 1226 // Enter a scope to hold everything within the compound stmt. Compound 1227 // statements can always hold declarations. 1228 ParseScope BodyScope(this, Scope::DeclScope); 1229 1230 OwningStmtResult SynchBody(ParseCompoundStatementBody()); 1231 1232 BodyScope.Exit(); 1233 if (SynchBody.isInvalid()) 1234 SynchBody = Actions.ActOnNullStmt(Tok.getLocation()); 1235 return Actions.ActOnObjCAtSynchronizedStmt(atLoc, move(Res), move(SynchBody)); 1236 } 1237 1238 /// objc-try-catch-statement: 1239 /// @try compound-statement objc-catch-list[opt] 1240 /// @try compound-statement objc-catch-list[opt] @finally compound-statement 1241 /// 1242 /// objc-catch-list: 1243 /// @catch ( parameter-declaration ) compound-statement 1244 /// objc-catch-list @catch ( catch-parameter-declaration ) compound-statement 1245 /// catch-parameter-declaration: 1246 /// parameter-declaration 1247 /// '...' [OBJC2] 1248 /// 1249 Parser::OwningStmtResult Parser::ParseObjCTryStmt(SourceLocation atLoc) { 1250 bool catch_or_finally_seen = false; 1251 1252 ConsumeToken(); // consume try 1253 if (Tok.isNot(tok::l_brace)) { 1254 Diag(Tok, diag::err_expected_lbrace); 1255 return StmtError(); 1256 } 1257 OwningStmtResult CatchStmts(Actions); 1258 OwningStmtResult FinallyStmt(Actions); 1259 ParseScope TryScope(this, Scope::DeclScope); 1260 OwningStmtResult TryBody(ParseCompoundStatementBody()); 1261 TryScope.Exit(); 1262 if (TryBody.isInvalid()) 1263 TryBody = Actions.ActOnNullStmt(Tok.getLocation()); 1264 1265 while (Tok.is(tok::at)) { 1266 // At this point, we need to lookahead to determine if this @ is the start 1267 // of an @catch or @finally. We don't want to consume the @ token if this 1268 // is an @try or @encode or something else. 1269 Token AfterAt = GetLookAheadToken(1); 1270 if (!AfterAt.isObjCAtKeyword(tok::objc_catch) && 1271 !AfterAt.isObjCAtKeyword(tok::objc_finally)) 1272 break; 1273 1274 SourceLocation AtCatchFinallyLoc = ConsumeToken(); 1275 if (Tok.isObjCAtKeyword(tok::objc_catch)) { 1276 DeclPtrTy FirstPart; 1277 ConsumeToken(); // consume catch 1278 if (Tok.is(tok::l_paren)) { 1279 ConsumeParen(); 1280 ParseScope CatchScope(this, Scope::DeclScope|Scope::AtCatchScope); 1281 if (Tok.isNot(tok::ellipsis)) { 1282 DeclSpec DS; 1283 ParseDeclarationSpecifiers(DS); 1284 // For some odd reason, the name of the exception variable is 1285 // optional. As a result, we need to use "PrototypeContext", because 1286 // we must accept either 'declarator' or 'abstract-declarator' here. 1287 Declarator ParmDecl(DS, Declarator::PrototypeContext); 1288 ParseDeclarator(ParmDecl); 1289 1290 // Inform the actions module about the parameter declarator, so it 1291 // gets added to the current scope. 1292 FirstPart = Actions.ActOnParamDeclarator(CurScope, ParmDecl); 1293 } else 1294 ConsumeToken(); // consume '...' 1295 1296 SourceLocation RParenLoc; 1297 1298 if (Tok.is(tok::r_paren)) 1299 RParenLoc = ConsumeParen(); 1300 else // Skip over garbage, until we get to ')'. Eat the ')'. 1301 SkipUntil(tok::r_paren, true, false); 1302 1303 OwningStmtResult CatchBody(Actions, true); 1304 if (Tok.is(tok::l_brace)) 1305 CatchBody = ParseCompoundStatementBody(); 1306 else 1307 Diag(Tok, diag::err_expected_lbrace); 1308 if (CatchBody.isInvalid()) 1309 CatchBody = Actions.ActOnNullStmt(Tok.getLocation()); 1310 CatchStmts = Actions.ActOnObjCAtCatchStmt(AtCatchFinallyLoc, 1311 RParenLoc, FirstPart, move(CatchBody), 1312 move(CatchStmts)); 1313 } else { 1314 Diag(AtCatchFinallyLoc, diag::err_expected_lparen_after) 1315 << "@catch clause"; 1316 return StmtError(); 1317 } 1318 catch_or_finally_seen = true; 1319 } else { 1320 assert(Tok.isObjCAtKeyword(tok::objc_finally) && "Lookahead confused?"); 1321 ConsumeToken(); // consume finally 1322 ParseScope FinallyScope(this, Scope::DeclScope); 1323 1324 OwningStmtResult FinallyBody(Actions, true); 1325 if (Tok.is(tok::l_brace)) 1326 FinallyBody = ParseCompoundStatementBody(); 1327 else 1328 Diag(Tok, diag::err_expected_lbrace); 1329 if (FinallyBody.isInvalid()) 1330 FinallyBody = Actions.ActOnNullStmt(Tok.getLocation()); 1331 FinallyStmt = Actions.ActOnObjCAtFinallyStmt(AtCatchFinallyLoc, 1332 move(FinallyBody)); 1333 catch_or_finally_seen = true; 1334 break; 1335 } 1336 } 1337 if (!catch_or_finally_seen) { 1338 Diag(atLoc, diag::err_missing_catch_finally); 1339 return StmtError(); 1340 } 1341 return Actions.ActOnObjCAtTryStmt(atLoc, move(TryBody), move(CatchStmts), 1342 move(FinallyStmt)); 1343 } 1344 1345 /// objc-method-def: objc-method-proto ';'[opt] '{' body '}' 1346 /// 1347 Parser::DeclPtrTy Parser::ParseObjCMethodDefinition() { 1348 DeclPtrTy MDecl = ParseObjCMethodPrototype(ObjCImpDecl); 1349 1350 PrettyStackTraceActionsDecl CrashInfo(MDecl, Tok.getLocation(), Actions, 1351 PP.getSourceManager(), 1352 "parsing Objective-C method"); 1353 1354 // parse optional ';' 1355 if (Tok.is(tok::semi)) 1356 ConsumeToken(); 1357 1358 // We should have an opening brace now. 1359 if (Tok.isNot(tok::l_brace)) { 1360 Diag(Tok, diag::err_expected_method_body); 1361 1362 // Skip over garbage, until we get to '{'. Don't eat the '{'. 1363 SkipUntil(tok::l_brace, true, true); 1364 1365 // If we didn't find the '{', bail out. 1366 if (Tok.isNot(tok::l_brace)) 1367 return DeclPtrTy(); 1368 } 1369 SourceLocation BraceLoc = Tok.getLocation(); 1370 1371 // Enter a scope for the method body. 1372 ParseScope BodyScope(this, Scope::FnScope|Scope::DeclScope); 1373 1374 // Tell the actions module that we have entered a method definition with the 1375 // specified Declarator for the method. 1376 Actions.ActOnStartOfObjCMethodDef(CurScope, MDecl); 1377 1378 OwningStmtResult FnBody(ParseCompoundStatementBody()); 1379 1380 // If the function body could not be parsed, make a bogus compoundstmt. 1381 if (FnBody.isInvalid()) 1382 FnBody = Actions.ActOnCompoundStmt(BraceLoc, BraceLoc, 1383 MultiStmtArg(Actions), false); 1384 1385 // TODO: Pass argument information. 1386 Actions.ActOnFinishFunctionBody(MDecl, move(FnBody)); 1387 1388 // Leave the function body scope. 1389 BodyScope.Exit(); 1390 1391 return MDecl; 1392 } 1393 1394 Parser::OwningStmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { 1395 if (Tok.isObjCAtKeyword(tok::objc_try)) { 1396 return ParseObjCTryStmt(AtLoc); 1397 } else if (Tok.isObjCAtKeyword(tok::objc_throw)) 1398 return ParseObjCThrowStmt(AtLoc); 1399 else if (Tok.isObjCAtKeyword(tok::objc_synchronized)) 1400 return ParseObjCSynchronizedStmt(AtLoc); 1401 OwningExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); 1402 if (Res.isInvalid()) { 1403 // If the expression is invalid, skip ahead to the next semicolon. Not 1404 // doing this opens us up to the possibility of infinite loops if 1405 // ParseExpression does not consume any tokens. 1406 SkipUntil(tok::semi); 1407 return StmtError(); 1408 } 1409 // Otherwise, eat the semicolon. 1410 ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); 1411 return Actions.ActOnExprStmt(Actions.FullExpr(Res)); 1412 } 1413 1414 Parser::OwningExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { 1415 switch (Tok.getKind()) { 1416 case tok::string_literal: // primary-expression: string-literal 1417 case tok::wide_string_literal: 1418 return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc)); 1419 default: 1420 if (Tok.getIdentifierInfo() == 0) 1421 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 1422 1423 switch (Tok.getIdentifierInfo()->getObjCKeywordID()) { 1424 case tok::objc_encode: 1425 return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc)); 1426 case tok::objc_protocol: 1427 return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc)); 1428 case tok::objc_selector: 1429 return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc)); 1430 default: 1431 return ExprError(Diag(AtLoc, diag::err_unexpected_at)); 1432 } 1433 } 1434 } 1435 1436 /// objc-message-expr: 1437 /// '[' objc-receiver objc-message-args ']' 1438 /// 1439 /// objc-receiver: 1440 /// expression 1441 /// class-name 1442 /// type-name 1443 Parser::OwningExprResult Parser::ParseObjCMessageExpression() { 1444 assert(Tok.is(tok::l_square) && "'[' expected"); 1445 SourceLocation LBracLoc = ConsumeBracket(); // consume '[' 1446 1447 // Parse receiver 1448 if (isTokObjCMessageIdentifierReceiver()) { 1449 IdentifierInfo *ReceiverName = Tok.getIdentifierInfo(); 1450 if (ReceiverName != Ident_super || GetLookAheadToken(1).isNot(tok::period)) { 1451 SourceLocation NameLoc = ConsumeToken(); 1452 return ParseObjCMessageExpressionBody(LBracLoc, NameLoc, ReceiverName, 1453 ExprArg(Actions)); 1454 } 1455 } 1456 1457 OwningExprResult Res(ParseExpression()); 1458 if (Res.isInvalid()) { 1459 SkipUntil(tok::r_square); 1460 return move(Res); 1461 } 1462 1463 return ParseObjCMessageExpressionBody(LBracLoc, SourceLocation(), 1464 0, move(Res)); 1465 } 1466 1467 /// ParseObjCMessageExpressionBody - Having parsed "'[' objc-receiver", parse 1468 /// the rest of a message expression. 1469 /// 1470 /// objc-message-args: 1471 /// objc-selector 1472 /// objc-keywordarg-list 1473 /// 1474 /// objc-keywordarg-list: 1475 /// objc-keywordarg 1476 /// objc-keywordarg-list objc-keywordarg 1477 /// 1478 /// objc-keywordarg: 1479 /// selector-name[opt] ':' objc-keywordexpr 1480 /// 1481 /// objc-keywordexpr: 1482 /// nonempty-expr-list 1483 /// 1484 /// nonempty-expr-list: 1485 /// assignment-expression 1486 /// nonempty-expr-list , assignment-expression 1487 /// 1488 Parser::OwningExprResult 1489 Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, 1490 SourceLocation NameLoc, 1491 IdentifierInfo *ReceiverName, 1492 ExprArg ReceiverExpr) { 1493 // Parse objc-selector 1494 SourceLocation Loc; 1495 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc); 1496 1497 SourceLocation SelectorLoc = Loc; 1498 1499 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1500 ExprVector KeyExprs(Actions); 1501 1502 if (Tok.is(tok::colon)) { 1503 while (1) { 1504 // Each iteration parses a single keyword argument. 1505 KeyIdents.push_back(selIdent); 1506 1507 if (Tok.isNot(tok::colon)) { 1508 Diag(Tok, diag::err_expected_colon); 1509 // We must manually skip to a ']', otherwise the expression skipper will 1510 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1511 // the enclosing expression. 1512 SkipUntil(tok::r_square); 1513 return ExprError(); 1514 } 1515 1516 ConsumeToken(); // Eat the ':'. 1517 /// Parse the expression after ':' 1518 OwningExprResult Res(ParseAssignmentExpression()); 1519 if (Res.isInvalid()) { 1520 // We must manually skip to a ']', otherwise the expression skipper will 1521 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1522 // the enclosing expression. 1523 SkipUntil(tok::r_square); 1524 return move(Res); 1525 } 1526 1527 // We have a valid expression. 1528 KeyExprs.push_back(Res.release()); 1529 1530 // Check for another keyword selector. 1531 selIdent = ParseObjCSelectorPiece(Loc); 1532 if (!selIdent && Tok.isNot(tok::colon)) 1533 break; 1534 // We have a selector or a colon, continue parsing. 1535 } 1536 // Parse the, optional, argument list, comma separated. 1537 while (Tok.is(tok::comma)) { 1538 ConsumeToken(); // Eat the ','. 1539 /// Parse the expression after ',' 1540 OwningExprResult Res(ParseAssignmentExpression()); 1541 if (Res.isInvalid()) { 1542 // We must manually skip to a ']', otherwise the expression skipper will 1543 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1544 // the enclosing expression. 1545 SkipUntil(tok::r_square); 1546 return move(Res); 1547 } 1548 1549 // We have a valid expression. 1550 KeyExprs.push_back(Res.release()); 1551 } 1552 } else if (!selIdent) { 1553 Diag(Tok, diag::err_expected_ident); // missing selector name. 1554 1555 // We must manually skip to a ']', otherwise the expression skipper will 1556 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1557 // the enclosing expression. 1558 SkipUntil(tok::r_square); 1559 return ExprError(); 1560 } 1561 1562 if (Tok.isNot(tok::r_square)) { 1563 Diag(Tok, diag::err_expected_rsquare); 1564 // We must manually skip to a ']', otherwise the expression skipper will 1565 // stop at the ']' when it skips to the ';'. We want it to skip beyond 1566 // the enclosing expression. 1567 SkipUntil(tok::r_square); 1568 return ExprError(); 1569 } 1570 1571 SourceLocation RBracLoc = ConsumeBracket(); // consume ']' 1572 1573 unsigned nKeys = KeyIdents.size(); 1574 if (nKeys == 0) 1575 KeyIdents.push_back(selIdent); 1576 Selector Sel = PP.getSelectorTable().getSelector(nKeys, &KeyIdents[0]); 1577 1578 // We've just parsed a keyword message. 1579 if (ReceiverName) 1580 return Owned(Actions.ActOnClassMessage(CurScope, ReceiverName, Sel, 1581 LBracLoc, NameLoc, SelectorLoc, 1582 RBracLoc, 1583 KeyExprs.take(), KeyExprs.size())); 1584 return Owned(Actions.ActOnInstanceMessage(ReceiverExpr.release(), Sel, 1585 LBracLoc, SelectorLoc, RBracLoc, 1586 KeyExprs.take(), KeyExprs.size())); 1587 } 1588 1589 Parser::OwningExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) { 1590 OwningExprResult Res(ParseStringLiteralExpression()); 1591 if (Res.isInvalid()) return move(Res); 1592 1593 // @"foo" @"bar" is a valid concatenated string. Eat any subsequent string 1594 // expressions. At this point, we know that the only valid thing that starts 1595 // with '@' is an @"". 1596 llvm::SmallVector<SourceLocation, 4> AtLocs; 1597 ExprVector AtStrings(Actions); 1598 AtLocs.push_back(AtLoc); 1599 AtStrings.push_back(Res.release()); 1600 1601 while (Tok.is(tok::at)) { 1602 AtLocs.push_back(ConsumeToken()); // eat the @. 1603 1604 // Invalid unless there is a string literal. 1605 if (!isTokenStringLiteral()) 1606 return ExprError(Diag(Tok, diag::err_objc_concat_string)); 1607 1608 OwningExprResult Lit(ParseStringLiteralExpression()); 1609 if (Lit.isInvalid()) 1610 return move(Lit); 1611 1612 AtStrings.push_back(Lit.release()); 1613 } 1614 1615 return Owned(Actions.ParseObjCStringLiteral(&AtLocs[0], AtStrings.take(), 1616 AtStrings.size())); 1617 } 1618 1619 /// objc-encode-expression: 1620 /// @encode ( type-name ) 1621 Parser::OwningExprResult 1622 Parser::ParseObjCEncodeExpression(SourceLocation AtLoc) { 1623 assert(Tok.isObjCAtKeyword(tok::objc_encode) && "Not an @encode expression!"); 1624 1625 SourceLocation EncLoc = ConsumeToken(); 1626 1627 if (Tok.isNot(tok::l_paren)) 1628 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@encode"); 1629 1630 SourceLocation LParenLoc = ConsumeParen(); 1631 1632 TypeResult Ty = ParseTypeName(); 1633 1634 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1635 1636 if (Ty.isInvalid()) 1637 return ExprError(); 1638 1639 return Owned(Actions.ParseObjCEncodeExpression(AtLoc, EncLoc, LParenLoc, 1640 Ty.get(), RParenLoc)); 1641 } 1642 1643 /// objc-protocol-expression 1644 /// @protocol ( protocol-name ) 1645 Parser::OwningExprResult 1646 Parser::ParseObjCProtocolExpression(SourceLocation AtLoc) { 1647 SourceLocation ProtoLoc = ConsumeToken(); 1648 1649 if (Tok.isNot(tok::l_paren)) 1650 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@protocol"); 1651 1652 SourceLocation LParenLoc = ConsumeParen(); 1653 1654 if (Tok.isNot(tok::identifier)) 1655 return ExprError(Diag(Tok, diag::err_expected_ident)); 1656 1657 IdentifierInfo *protocolId = Tok.getIdentifierInfo(); 1658 ConsumeToken(); 1659 1660 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1661 1662 return Owned(Actions.ParseObjCProtocolExpression(protocolId, AtLoc, ProtoLoc, 1663 LParenLoc, RParenLoc)); 1664 } 1665 1666 /// objc-selector-expression 1667 /// @selector '(' objc-keyword-selector ')' 1668 Parser::OwningExprResult 1669 Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { 1670 SourceLocation SelectorLoc = ConsumeToken(); 1671 1672 if (Tok.isNot(tok::l_paren)) 1673 return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@selector"); 1674 1675 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1676 SourceLocation LParenLoc = ConsumeParen(); 1677 SourceLocation sLoc; 1678 IdentifierInfo *SelIdent = ParseObjCSelectorPiece(sLoc); 1679 if (!SelIdent && Tok.isNot(tok::colon)) // missing selector name. 1680 return ExprError(Diag(Tok, diag::err_expected_ident)); 1681 1682 KeyIdents.push_back(SelIdent); 1683 unsigned nColons = 0; 1684 if (Tok.isNot(tok::r_paren)) { 1685 while (1) { 1686 if (Tok.isNot(tok::colon)) 1687 return ExprError(Diag(Tok, diag::err_expected_colon)); 1688 1689 nColons++; 1690 ConsumeToken(); // Eat the ':'. 1691 if (Tok.is(tok::r_paren)) 1692 break; 1693 // Check for another keyword selector. 1694 SourceLocation Loc; 1695 SelIdent = ParseObjCSelectorPiece(Loc); 1696 KeyIdents.push_back(SelIdent); 1697 if (!SelIdent && Tok.isNot(tok::colon)) 1698 break; 1699 } 1700 } 1701 SourceLocation RParenLoc = MatchRHSPunctuation(tok::r_paren, LParenLoc); 1702 Selector Sel = PP.getSelectorTable().getSelector(nColons, &KeyIdents[0]); 1703 return Owned(Actions.ParseObjCSelectorExpression(Sel, AtLoc, SelectorLoc, 1704 LParenLoc, RParenLoc)); 1705 } 1706