Improve diagnosing when a method type does not start with '-'|'+'

when parsing. Fixes radar 7822196.

llvm-svn: 100248
This commit is contained in:
Fariborz Jahanian 2010-04-02 23:15:40 +00:00
parent dbdd3f8b09
commit d077f719be
3 changed files with 52 additions and 26 deletions

View File

@ -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">;

View File

@ -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();

View File

@ -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