forked from OSchip/llvm-project
Improve diagnosing when a method type does not start with '-'|'+'
when parsing. Fixes radar 7822196. llvm-svn: 100248
This commit is contained in:
parent
dbdd3f8b09
commit
d077f719be
|
@ -182,6 +182,8 @@ def err_unexected_colon_in_nested_name_spec : Error<
|
|||
"unexpected ':' in nested name specifier">;
|
||||
|
||||
/// Objective-C parser diagnostics
|
||||
def err_expected_minus_or_plus : Error<
|
||||
"method type specifier must start with '-' or '+'">;
|
||||
def err_objc_no_attributes_on_category : Error<
|
||||
"attributes may not be specified on a category">;
|
||||
def err_objc_missing_end : Error<"missing @end">;
|
||||
|
|
|
@ -142,12 +142,11 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
|||
// We have a class or category name - consume it.
|
||||
IdentifierInfo *nameId = Tok.getIdentifierInfo();
|
||||
SourceLocation nameLoc = ConsumeToken();
|
||||
|
||||
bool Err = false;
|
||||
if (Tok.is(tok::l_paren)) { // we have a category.
|
||||
SourceLocation lparenLoc = ConsumeParen();
|
||||
SourceLocation categoryLoc, rparenLoc;
|
||||
IdentifierInfo *categoryId = 0;
|
||||
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteObjCInterfaceCategory(CurScope, nameId);
|
||||
ConsumeToken();
|
||||
|
@ -157,7 +156,14 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
|||
if (Tok.is(tok::identifier)) {
|
||||
categoryId = Tok.getIdentifierInfo();
|
||||
categoryLoc = ConsumeToken();
|
||||
} else if (!getLang().ObjC2) {
|
||||
}
|
||||
else if (isKnownToBeTypeSpecifier(Tok)) {
|
||||
// Fall thru after diagnosing for better error recovery.
|
||||
Diag(Tok, diag::err_expected_minus_or_plus);
|
||||
ConsumeToken();
|
||||
Err = true;
|
||||
}
|
||||
else if (!getLang().ObjC2) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing category name.
|
||||
return DeclPtrTy();
|
||||
}
|
||||
|
@ -167,33 +173,34 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
|||
return DeclPtrTy();
|
||||
}
|
||||
rparenLoc = ConsumeParen();
|
||||
|
||||
// Next, we need to check for any protocol references.
|
||||
SourceLocation LAngleLoc, EndProtoLoc;
|
||||
llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
|
||||
llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
|
||||
if (Tok.is(tok::less) &&
|
||||
ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
|
||||
if (!Err) {
|
||||
// Next, we need to check for any protocol references.
|
||||
SourceLocation LAngleLoc, EndProtoLoc;
|
||||
llvm::SmallVector<DeclPtrTy, 8> ProtocolRefs;
|
||||
llvm::SmallVector<SourceLocation, 8> ProtocolLocs;
|
||||
if (Tok.is(tok::less) &&
|
||||
ParseObjCProtocolReferences(ProtocolRefs, ProtocolLocs, true,
|
||||
LAngleLoc, EndProtoLoc))
|
||||
return DeclPtrTy();
|
||||
return DeclPtrTy();
|
||||
|
||||
if (attrList) // categories don't support attributes.
|
||||
Diag(Tok, diag::err_objc_no_attributes_on_category);
|
||||
if (attrList) // categories don't support attributes.
|
||||
Diag(Tok, diag::err_objc_no_attributes_on_category);
|
||||
|
||||
DeclPtrTy CategoryType =
|
||||
Actions.ActOnStartCategoryInterface(atLoc,
|
||||
nameId, nameLoc,
|
||||
categoryId, categoryLoc,
|
||||
ProtocolRefs.data(),
|
||||
ProtocolRefs.size(),
|
||||
ProtocolLocs.data(),
|
||||
EndProtoLoc);
|
||||
if (Tok.is(tok::l_brace))
|
||||
DeclPtrTy CategoryType =
|
||||
Actions.ActOnStartCategoryInterface(atLoc,
|
||||
nameId, nameLoc,
|
||||
categoryId, categoryLoc,
|
||||
ProtocolRefs.data(),
|
||||
ProtocolRefs.size(),
|
||||
ProtocolLocs.data(),
|
||||
EndProtoLoc);
|
||||
if (Tok.is(tok::l_brace))
|
||||
ParseObjCClassInstanceVariables(CategoryType, tok::objc_private,
|
||||
atLoc);
|
||||
|
||||
ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
|
||||
return CategoryType;
|
||||
ParseObjCInterfaceDeclList(CategoryType, tok::objc_not_keyword);
|
||||
return CategoryType;
|
||||
}
|
||||
}
|
||||
// Parse a class interface.
|
||||
IdentifierInfo *superClassId = 0;
|
||||
|
@ -235,7 +242,7 @@ Parser::DeclPtrTy Parser::ParseObjCAtInterfaceDeclaration(
|
|||
ParseObjCClassInstanceVariables(ClsType, tok::objc_protected, atLoc);
|
||||
|
||||
ParseObjCInterfaceDeclList(ClsType, tok::objc_interface);
|
||||
return ClsType;
|
||||
return Err ? DeclPtrTy() : ClsType;
|
||||
}
|
||||
|
||||
/// The Objective-C property callback. This should be defined where
|
||||
|
@ -328,7 +335,14 @@ void Parser::ParseObjCInterfaceDeclList(DeclPtrTy interfaceDecl,
|
|||
"", tok::semi);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Tok.is(tok::l_paren)) {
|
||||
Diag(Tok, diag::err_expected_minus_or_plus);
|
||||
DeclPtrTy methodPrototype = ParseObjCMethodDecl(Tok.getLocation(),
|
||||
tok::minus,
|
||||
interfaceDecl,
|
||||
MethodImplKind);
|
||||
continue;
|
||||
}
|
||||
// Ignore excess semicolons.
|
||||
if (Tok.is(tok::semi)) {
|
||||
ConsumeToken();
|
||||
|
|
|
@ -9,3 +9,13 @@ typedef float CGFloat;
|
|||
// expected-error {{ expected ';' after method prototype}}
|
||||
@end
|
||||
|
||||
// rdar: // 7822196
|
||||
@interface A
|
||||
(void) x; // expected-error {{method type specifier must start with '-' or '+'}} \
|
||||
// expected-warning {{type specifier missing, defaults to 'int' [-Wimplicit-int]}} \
|
||||
// expected-error {{cannot declare variable inside @interface or @protocol}}
|
||||
(int)im; // expected-error {{method type specifier must start with '-' or '+'}} \
|
||||
- ok;
|
||||
@end
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue