ParseObjc.cpp (199482) | ParseObjc.cpp (199512) |
---|---|
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//===----------------------------------------------------------------------===// --- 109 unchanged lines hidden (view full) --- 118/// __attribute__((objc_exception)) - used by NSException on 64-bit 119/// 120Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( 121 SourceLocation atLoc, AttributeList *attrList) { 122 assert(Tok.isObjCAtKeyword(tok::objc_interface) && 123 "ParseObjCAtInterfaceDeclaration(): Expected @interface"); 124 ConsumeToken(); // the "interface" identifier 125 | 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//===----------------------------------------------------------------------===// --- 109 unchanged lines hidden (view full) --- 118/// __attribute__((objc_exception)) - used by NSException on 64-bit 119/// 120Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration( 121 SourceLocation atLoc, AttributeList *attrList) { 122 assert(Tok.isObjCAtKeyword(tok::objc_interface) && 123 "ParseObjCAtInterfaceDeclaration(): Expected @interface"); 124 ConsumeToken(); // the "interface" identifier 125 |
126 // Code completion after '@interface'. 127 if (Tok.is(tok::code_completion)) { 128 Actions.CodeCompleteObjCInterfaceDecl(CurScope); 129 ConsumeToken(); 130 } 131 |
|
126 if (Tok.isNot(tok::identifier)) { 127 Diag(Tok, diag::err_expected_ident); // missing class or category name. 128 return DeclPtrTy(); 129 } 130 131 // We have a class or category name - consume it. 132 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 133 SourceLocation nameLoc = ConsumeToken(); 134 135 if (Tok.is(tok::l_paren)) { // we have a category. 136 SourceLocation lparenLoc = ConsumeParen(); 137 SourceLocation categoryLoc, rparenLoc; 138 IdentifierInfo *categoryId = 0; 139 | 132 if (Tok.isNot(tok::identifier)) { 133 Diag(Tok, diag::err_expected_ident); // missing class or category name. 134 return DeclPtrTy(); 135 } 136 137 // We have a class or category name - consume it. 138 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 139 SourceLocation nameLoc = ConsumeToken(); 140 141 if (Tok.is(tok::l_paren)) { // we have a category. 142 SourceLocation lparenLoc = ConsumeParen(); 143 SourceLocation categoryLoc, rparenLoc; 144 IdentifierInfo *categoryId = 0; 145 |
146 if (Tok.is(tok::code_completion)) { 147 Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId); 148 ConsumeToken(); 149 } 150 |
|
140 // For ObjC2, the category name is optional (not an error). 141 if (Tok.is(tok::identifier)) { 142 categoryId = Tok.getIdentifierInfo(); 143 categoryLoc = ConsumeToken(); 144 } else if (!getLang().ObjC2) { 145 Diag(Tok, diag::err_expected_ident); // missing category name. 146 return DeclPtrTy(); 147 } --- 28 unchanged lines hidden (view full) --- 176 return CategoryType; 177 } 178 // Parse a class interface. 179 IdentifierInfo *superClassId = 0; 180 SourceLocation superClassLoc; 181 182 if (Tok.is(tok::colon)) { // a super class is specified. 183 ConsumeToken(); | 151 // For ObjC2, the category name is optional (not an error). 152 if (Tok.is(tok::identifier)) { 153 categoryId = Tok.getIdentifierInfo(); 154 categoryLoc = ConsumeToken(); 155 } else if (!getLang().ObjC2) { 156 Diag(Tok, diag::err_expected_ident); // missing category name. 157 return DeclPtrTy(); 158 } --- 28 unchanged lines hidden (view full) --- 187 return CategoryType; 188 } 189 // Parse a class interface. 190 IdentifierInfo *superClassId = 0; 191 SourceLocation superClassLoc; 192 193 if (Tok.is(tok::colon)) { // a super class is specified. 194 ConsumeToken(); |
195 196 // Code completion of superclass names. 197 if (Tok.is(tok::code_completion)) { 198 Actions.CodeCompleteObjCSuperclass(CurScope, nameId); 199 ConsumeToken(); 200 } 201 |
|
184 if (Tok.isNot(tok::identifier)) { 185 Diag(Tok, diag::err_expected_ident); // missing super class name. 186 return DeclPtrTy(); 187 } 188 superClassId = Tok.getIdentifierInfo(); 189 superClassLoc = ConsumeToken(); 190 } 191 // Next, we need to check for any protocol references. --- 111 unchanged lines hidden (view full) --- 303 304 case tok::objc_property: 305 if (!getLang().ObjC2) 306 Diag(AtLoc, diag::err_objc_propertoes_require_objc2); 307 308 ObjCDeclSpec OCDS; 309 // Parse property attribute list, if any. 310 if (Tok.is(tok::l_paren)) | 202 if (Tok.isNot(tok::identifier)) { 203 Diag(Tok, diag::err_expected_ident); // missing super class name. 204 return DeclPtrTy(); 205 } 206 superClassId = Tok.getIdentifierInfo(); 207 superClassLoc = ConsumeToken(); 208 } 209 // Next, we need to check for any protocol references. --- 111 unchanged lines hidden (view full) --- 321 322 case tok::objc_property: 323 if (!getLang().ObjC2) 324 Diag(AtLoc, diag::err_objc_propertoes_require_objc2); 325 326 ObjCDeclSpec OCDS; 327 // Parse property attribute list, if any. 328 if (Tok.is(tok::l_paren)) |
311 ParseObjCPropertyAttribute(OCDS); | 329 ParseObjCPropertyAttribute(OCDS, interfaceDecl, 330 allMethods.data(), allMethods.size()); |
312 313 struct ObjCPropertyCallback : FieldCallback { 314 Parser &P; 315 DeclPtrTy IDecl; 316 llvm::SmallVectorImpl<DeclPtrTy> &Props; 317 ObjCDeclSpec &OCDS; 318 SourceLocation AtLoc; 319 tok::ObjCKeywordKind MethodImplKind; --- 82 unchanged lines hidden (view full) --- 402/// setter '=' identifier ':' 403/// readonly 404/// readwrite 405/// assign 406/// retain 407/// copy 408/// nonatomic 409/// | 331 332 struct ObjCPropertyCallback : FieldCallback { 333 Parser &P; 334 DeclPtrTy IDecl; 335 llvm::SmallVectorImpl<DeclPtrTy> &Props; 336 ObjCDeclSpec &OCDS; 337 SourceLocation AtLoc; 338 tok::ObjCKeywordKind MethodImplKind; --- 82 unchanged lines hidden (view full) --- 421/// setter '=' identifier ':' 422/// readonly 423/// readwrite 424/// assign 425/// retain 426/// copy 427/// nonatomic 428/// |
410void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS) { | 429void Parser::ParseObjCPropertyAttribute(ObjCDeclSpec &DS, DeclPtrTy ClassDecl, 430 DeclPtrTy *Methods, 431 unsigned NumMethods) { |
411 assert(Tok.getKind() == tok::l_paren); 412 SourceLocation LHSLoc = ConsumeParen(); // consume '(' 413 414 while (1) { 415 if (Tok.is(tok::code_completion)) { | 432 assert(Tok.getKind() == tok::l_paren); 433 SourceLocation LHSLoc = ConsumeParen(); // consume '(' 434 435 while (1) { 436 if (Tok.is(tok::code_completion)) { |
416 Actions.CodeCompleteObjCProperty(CurScope, DS); | 437 Actions.CodeCompleteObjCPropertyFlags(CurScope, DS); |
417 ConsumeToken(); 418 } 419 const IdentifierInfo *II = Tok.getIdentifierInfo(); 420 421 // If this is not an identifier at all, bail out early. 422 if (II == 0) { 423 MatchRHSPunctuation(tok::r_paren, LHSLoc); 424 return; --- 14 unchanged lines hidden (view full) --- 439 else if (II->isStr("nonatomic")) 440 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic); 441 else if (II->isStr("getter") || II->isStr("setter")) { 442 // getter/setter require extra treatment. 443 if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "", 444 tok::r_paren)) 445 return; 446 | 438 ConsumeToken(); 439 } 440 const IdentifierInfo *II = Tok.getIdentifierInfo(); 441 442 // If this is not an identifier at all, bail out early. 443 if (II == 0) { 444 MatchRHSPunctuation(tok::r_paren, LHSLoc); 445 return; --- 14 unchanged lines hidden (view full) --- 460 else if (II->isStr("nonatomic")) 461 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_nonatomic); 462 else if (II->isStr("getter") || II->isStr("setter")) { 463 // getter/setter require extra treatment. 464 if (ExpectAndConsume(tok::equal, diag::err_objc_expected_equal, "", 465 tok::r_paren)) 466 return; 467 |
468 if (Tok.is(tok::code_completion)) { 469 if (II->getNameStart()[0] == 's') 470 Actions.CodeCompleteObjCPropertySetter(CurScope, ClassDecl, 471 Methods, NumMethods); 472 else 473 Actions.CodeCompleteObjCPropertyGetter(CurScope, ClassDecl, 474 Methods, NumMethods); 475 ConsumeToken(); 476 } 477 |
|
447 if (Tok.isNot(tok::identifier)) { 448 Diag(Tok, diag::err_expected_ident); 449 SkipUntil(tok::r_paren); 450 return; 451 } 452 453 if (II->getNameStart()[0] == 's') { 454 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter); --- 618 unchanged lines hidden (view full) --- 1073/// objc-category-implementation-prologue: 1074/// @implementation identifier ( identifier ) 1075Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( 1076 SourceLocation atLoc) { 1077 assert(Tok.isObjCAtKeyword(tok::objc_implementation) && 1078 "ParseObjCAtImplementationDeclaration(): Expected @implementation"); 1079 ConsumeToken(); // the "implementation" identifier 1080 | 478 if (Tok.isNot(tok::identifier)) { 479 Diag(Tok, diag::err_expected_ident); 480 SkipUntil(tok::r_paren); 481 return; 482 } 483 484 if (II->getNameStart()[0] == 's') { 485 DS.setPropertyAttributes(ObjCDeclSpec::DQ_PR_setter); --- 618 unchanged lines hidden (view full) --- 1104/// objc-category-implementation-prologue: 1105/// @implementation identifier ( identifier ) 1106Parser::DeclPtrTy Parser::ParseObjCAtImplementationDeclaration( 1107 SourceLocation atLoc) { 1108 assert(Tok.isObjCAtKeyword(tok::objc_implementation) && 1109 "ParseObjCAtImplementationDeclaration(): Expected @implementation"); 1110 ConsumeToken(); // the "implementation" identifier 1111 |
1112 // Code completion after '@implementation'. 1113 if (Tok.is(tok::code_completion)) { 1114 Actions.CodeCompleteObjCImplementationDecl(CurScope); 1115 ConsumeToken(); 1116 } 1117 |
|
1081 if (Tok.isNot(tok::identifier)) { 1082 Diag(Tok, diag::err_expected_ident); // missing class or category name. 1083 return DeclPtrTy(); 1084 } 1085 // We have a class or category name - consume it. 1086 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 1087 SourceLocation nameLoc = ConsumeToken(); // consume class or category name 1088 1089 if (Tok.is(tok::l_paren)) { 1090 // we have a category implementation. 1091 SourceLocation lparenLoc = ConsumeParen(); 1092 SourceLocation categoryLoc, rparenLoc; 1093 IdentifierInfo *categoryId = 0; 1094 | 1118 if (Tok.isNot(tok::identifier)) { 1119 Diag(Tok, diag::err_expected_ident); // missing class or category name. 1120 return DeclPtrTy(); 1121 } 1122 // We have a class or category name - consume it. 1123 IdentifierInfo *nameId = Tok.getIdentifierInfo(); 1124 SourceLocation nameLoc = ConsumeToken(); // consume class or category name 1125 1126 if (Tok.is(tok::l_paren)) { 1127 // we have a category implementation. 1128 SourceLocation lparenLoc = ConsumeParen(); 1129 SourceLocation categoryLoc, rparenLoc; 1130 IdentifierInfo *categoryId = 0; 1131 |
1132 if (Tok.is(tok::code_completion)) { 1133 Actions.CodeCompleteObjCImplementationCategory(CurScope, nameId); 1134 ConsumeToken(); 1135 } 1136 |
|
1095 if (Tok.is(tok::identifier)) { 1096 categoryId = Tok.getIdentifierInfo(); 1097 categoryLoc = ConsumeToken(); 1098 } else { 1099 Diag(Tok, diag::err_expected_ident); // missing category name. 1100 return DeclPtrTy(); 1101 } 1102 if (Tok.isNot(tok::r_paren)) { --- 94 unchanged lines hidden (view full) --- 1197/// property-ivar: 1198/// identifier 1199/// identifier '=' identifier 1200/// 1201Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { 1202 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && 1203 "ParseObjCPropertyDynamic(): Expected '@synthesize'"); 1204 SourceLocation loc = ConsumeToken(); // consume synthesize | 1137 if (Tok.is(tok::identifier)) { 1138 categoryId = Tok.getIdentifierInfo(); 1139 categoryLoc = ConsumeToken(); 1140 } else { 1141 Diag(Tok, diag::err_expected_ident); // missing category name. 1142 return DeclPtrTy(); 1143 } 1144 if (Tok.isNot(tok::r_paren)) { --- 94 unchanged lines hidden (view full) --- 1239/// property-ivar: 1240/// identifier 1241/// identifier '=' identifier 1242/// 1243Parser::DeclPtrTy Parser::ParseObjCPropertySynthesize(SourceLocation atLoc) { 1244 assert(Tok.isObjCAtKeyword(tok::objc_synthesize) && 1245 "ParseObjCPropertyDynamic(): Expected '@synthesize'"); 1246 SourceLocation loc = ConsumeToken(); // consume synthesize |
1205 if (Tok.isNot(tok::identifier)) { 1206 Diag(Tok, diag::err_expected_ident); 1207 return DeclPtrTy(); 1208 } | |
1209 | 1247 |
1210 while (Tok.is(tok::identifier)) { | 1248 while (true) { 1249 if (Tok.is(tok::code_completion)) { 1250 Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl); 1251 ConsumeToken(); 1252 } 1253 1254 if (Tok.isNot(tok::identifier)) { 1255 Diag(Tok, diag::err_synthesized_property_name); 1256 SkipUntil(tok::semi); 1257 return DeclPtrTy(); 1258 } 1259 |
1211 IdentifierInfo *propertyIvar = 0; 1212 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1213 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1214 if (Tok.is(tok::equal)) { 1215 // property '=' ivar-name 1216 ConsumeToken(); // consume '=' | 1260 IdentifierInfo *propertyIvar = 0; 1261 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1262 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1263 if (Tok.is(tok::equal)) { 1264 // property '=' ivar-name 1265 ConsumeToken(); // consume '=' |
1266 1267 if (Tok.is(tok::code_completion)) { 1268 Actions.CodeCompleteObjCPropertySynthesizeIvar(CurScope, propertyId, 1269 ObjCImpDecl); 1270 ConsumeToken(); 1271 } 1272 |
|
1217 if (Tok.isNot(tok::identifier)) { 1218 Diag(Tok, diag::err_expected_ident); 1219 break; 1220 } 1221 propertyIvar = Tok.getIdentifierInfo(); 1222 ConsumeToken(); // consume ivar-name 1223 } 1224 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl, 1225 propertyId, propertyIvar); 1226 if (Tok.isNot(tok::comma)) 1227 break; 1228 ConsumeToken(); // consume ',' 1229 } | 1273 if (Tok.isNot(tok::identifier)) { 1274 Diag(Tok, diag::err_expected_ident); 1275 break; 1276 } 1277 propertyIvar = Tok.getIdentifierInfo(); 1278 ConsumeToken(); // consume ivar-name 1279 } 1280 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, true, ObjCImpDecl, 1281 propertyId, propertyIvar); 1282 if (Tok.isNot(tok::comma)) 1283 break; 1284 ConsumeToken(); // consume ',' 1285 } |
1230 if (Tok.isNot(tok::semi)) | 1286 if (Tok.isNot(tok::semi)) { |
1231 Diag(Tok, diag::err_expected_semi_after) << "@synthesize"; | 1287 Diag(Tok, diag::err_expected_semi_after) << "@synthesize"; |
1288 SkipUntil(tok::semi); 1289 } |
|
1232 else 1233 ConsumeToken(); // consume ';' 1234 return DeclPtrTy(); 1235} 1236 1237/// property-dynamic: 1238/// @dynamic property-list 1239/// 1240/// property-list: 1241/// identifier 1242/// property-list ',' identifier 1243/// 1244Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { 1245 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && 1246 "ParseObjCPropertyDynamic(): Expected '@dynamic'"); 1247 SourceLocation loc = ConsumeToken(); // consume dynamic | 1290 else 1291 ConsumeToken(); // consume ';' 1292 return DeclPtrTy(); 1293} 1294 1295/// property-dynamic: 1296/// @dynamic property-list 1297/// 1298/// property-list: 1299/// identifier 1300/// property-list ',' identifier 1301/// 1302Parser::DeclPtrTy Parser::ParseObjCPropertyDynamic(SourceLocation atLoc) { 1303 assert(Tok.isObjCAtKeyword(tok::objc_dynamic) && 1304 "ParseObjCPropertyDynamic(): Expected '@dynamic'"); 1305 SourceLocation loc = ConsumeToken(); // consume dynamic |
1248 if (Tok.isNot(tok::identifier)) { 1249 Diag(Tok, diag::err_expected_ident); 1250 return DeclPtrTy(); 1251 } 1252 while (Tok.is(tok::identifier)) { | 1306 while (true) { 1307 if (Tok.is(tok::code_completion)) { 1308 Actions.CodeCompleteObjCPropertyDefinition(CurScope, ObjCImpDecl); 1309 ConsumeToken(); 1310 } 1311 1312 if (Tok.isNot(tok::identifier)) { 1313 Diag(Tok, diag::err_expected_ident); 1314 SkipUntil(tok::semi); 1315 return DeclPtrTy(); 1316 } 1317 |
1253 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1254 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1255 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl, 1256 propertyId, 0); 1257 1258 if (Tok.isNot(tok::comma)) 1259 break; 1260 ConsumeToken(); // consume ',' --- 314 unchanged lines hidden (view full) --- 1575/// 1576Parser::OwningExprResult 1577Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, 1578 SourceLocation NameLoc, 1579 IdentifierInfo *ReceiverName, 1580 ExprArg ReceiverExpr) { 1581 if (Tok.is(tok::code_completion)) { 1582 if (ReceiverName) | 1318 IdentifierInfo *propertyId = Tok.getIdentifierInfo(); 1319 SourceLocation propertyLoc = ConsumeToken(); // consume property name 1320 Actions.ActOnPropertyImplDecl(atLoc, propertyLoc, false, ObjCImpDecl, 1321 propertyId, 0); 1322 1323 if (Tok.isNot(tok::comma)) 1324 break; 1325 ConsumeToken(); // consume ',' --- 314 unchanged lines hidden (view full) --- 1640/// 1641Parser::OwningExprResult 1642Parser::ParseObjCMessageExpressionBody(SourceLocation LBracLoc, 1643 SourceLocation NameLoc, 1644 IdentifierInfo *ReceiverName, 1645 ExprArg ReceiverExpr) { 1646 if (Tok.is(tok::code_completion)) { 1647 if (ReceiverName) |
1583 Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc); | 1648 Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc, 1649 0, 0); |
1584 else | 1650 else |
1585 Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get()); | 1651 Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(), 1652 0, 0); |
1586 ConsumeToken(); 1587 } | 1653 ConsumeToken(); 1654 } |
1655 |
|
1588 // Parse objc-selector 1589 SourceLocation Loc; 1590 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc); 1591 1592 SourceLocation SelectorLoc = Loc; 1593 1594 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1595 ExprVector KeyExprs(Actions); --- 21 unchanged lines hidden (view full) --- 1617 // the enclosing expression. 1618 SkipUntil(tok::r_square); 1619 return move(Res); 1620 } 1621 1622 // We have a valid expression. 1623 KeyExprs.push_back(Res.release()); 1624 | 1656 // Parse objc-selector 1657 SourceLocation Loc; 1658 IdentifierInfo *selIdent = ParseObjCSelectorPiece(Loc); 1659 1660 SourceLocation SelectorLoc = Loc; 1661 1662 llvm::SmallVector<IdentifierInfo *, 12> KeyIdents; 1663 ExprVector KeyExprs(Actions); --- 21 unchanged lines hidden (view full) --- 1685 // the enclosing expression. 1686 SkipUntil(tok::r_square); 1687 return move(Res); 1688 } 1689 1690 // We have a valid expression. 1691 KeyExprs.push_back(Res.release()); 1692 |
1693 // Code completion after each argument. 1694 if (Tok.is(tok::code_completion)) { 1695 if (ReceiverName) 1696 Actions.CodeCompleteObjCClassMessage(CurScope, ReceiverName, NameLoc, 1697 KeyIdents.data(), 1698 KeyIdents.size()); 1699 else 1700 Actions.CodeCompleteObjCInstanceMessage(CurScope, ReceiverExpr.get(), 1701 KeyIdents.data(), 1702 KeyIdents.size()); 1703 ConsumeToken(); 1704 } 1705 |
|
1625 // Check for another keyword selector. 1626 selIdent = ParseObjCSelectorPiece(Loc); 1627 if (!selIdent && Tok.isNot(tok::colon)) 1628 break; 1629 // We have a selector or a colon, continue parsing. 1630 } 1631 // Parse the, optional, argument list, comma separated. 1632 while (Tok.is(tok::comma)) { --- 168 unchanged lines hidden --- | 1706 // Check for another keyword selector. 1707 selIdent = ParseObjCSelectorPiece(Loc); 1708 if (!selIdent && Tok.isNot(tok::colon)) 1709 break; 1710 // We have a selector or a colon, continue parsing. 1711 } 1712 // Parse the, optional, argument list, comma separated. 1713 while (Tok.is(tok::comma)) { --- 168 unchanged lines hidden --- |