зеркало из https://github.com/microsoft/clang.git
Fix a FIXME by not creating an invalid AST on erroneous input. Also
make diagnostic output in some other malformed cases significantly more useful. This fixes PR2708 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55215 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
e53c069bda
Коммит
e8904e992c
|
@ -322,8 +322,8 @@ DIAG(err_parse_error, ERROR,
|
|||
"parse error")
|
||||
DIAG(err_expected_expression, ERROR,
|
||||
"expected expression")
|
||||
DIAG(err_invalid_receiver_to_message, ERROR,
|
||||
"invalid receiver to message expression")
|
||||
DIAG(err_expected_type, ERROR,
|
||||
"expected a type")
|
||||
DIAG(err_expected_external_declaration, ERROR,
|
||||
"expected external declaration")
|
||||
DIAG(err_expected_ident, ERROR,
|
||||
|
@ -386,6 +386,8 @@ DIAG(err_expected_string_literal, ERROR,
|
|||
"expected string literal")
|
||||
DIAG(err_expected_asm_operand, ERROR,
|
||||
"expected string literal or '[' for asm operand")
|
||||
DIAG(err_expected_selector_for_method, ERROR,
|
||||
"expected selector for Objective-C method")
|
||||
|
||||
DIAG(err_unexpected_at, ERROR,
|
||||
"unexpected '@' in program")
|
||||
|
@ -409,6 +411,8 @@ DIAG(warn_objc_protocol_qualifier_missing_id, WARNING,
|
|||
DIAG(warn_objc_array_of_interfaces, WARNING,
|
||||
"array of interface '%0' should probably be an array of pointers")
|
||||
|
||||
DIAG(err_invalid_receiver_to_message, ERROR,
|
||||
"invalid receiver to message expression")
|
||||
DIAG(err_objc_illegal_visibility_spec, ERROR,
|
||||
"illegal visibility specification")
|
||||
DIAG(err_objc_illegal_interface_qual, ERROR,
|
||||
|
|
|
@ -561,6 +561,7 @@ Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
|
|||
assert(Tok.is(tok::l_paren) && "expected (");
|
||||
|
||||
SourceLocation LParenLoc = ConsumeParen(), RParenLoc;
|
||||
SourceLocation TypeStartLoc = Tok.getLocation();
|
||||
TypeTy *Ty = 0;
|
||||
|
||||
// Parse type qualifiers, in, inout, etc.
|
||||
|
@ -571,9 +572,17 @@ Parser::TypeTy *Parser::ParseObjCTypeName(ObjCDeclSpec &DS) {
|
|||
// FIXME: back when Sema support is in place...
|
||||
// assert(Ty && "Parser::ParseObjCTypeName(): missing type");
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::r_paren)) {
|
||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||
return 0; // FIXME: decide how we want to handle this error...
|
||||
// If we didn't eat any tokens, then this isn't a type.
|
||||
if (Tok.getLocation() == TypeStartLoc) {
|
||||
Diag(Tok.getLocation(), diag::err_expected_type);
|
||||
SkipUntil(tok::r_brace);
|
||||
} else {
|
||||
// Otherwise, we found *something*, but didn't get a ')' in the right
|
||||
// place. Emit an error then return what we have as the type.
|
||||
MatchRHSPunctuation(tok::r_paren, LParenLoc);
|
||||
}
|
||||
}
|
||||
RParenLoc = ConsumeParen();
|
||||
return Ty;
|
||||
|
@ -612,20 +621,24 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
DeclTy *IDecl,
|
||||
tok::ObjCKeywordKind MethodImplKind)
|
||||
{
|
||||
// Parse the return type.
|
||||
// Parse the return type if present.
|
||||
TypeTy *ReturnType = 0;
|
||||
ObjCDeclSpec DSRet;
|
||||
if (Tok.is(tok::l_paren))
|
||||
ReturnType = ParseObjCTypeName(DSRet);
|
||||
|
||||
SourceLocation selLoc;
|
||||
IdentifierInfo *SelIdent = ParseObjCSelector(selLoc);
|
||||
|
||||
if (!SelIdent) { // missing selector name.
|
||||
Diag(Tok.getLocation(), diag::err_expected_selector_for_method,
|
||||
SourceRange(mLoc, Tok.getLocation()));
|
||||
// Skip until we get a ; or {}.
|
||||
SkipUntil(tok::r_brace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Tok.isNot(tok::colon)) {
|
||||
if (!SelIdent) {
|
||||
Diag(Tok, diag::err_expected_ident); // missing selector name.
|
||||
// FIXME: this creates a unary selector with a null identifier, is this
|
||||
// ok?? Maybe we should skip to the next semicolon or something.
|
||||
}
|
||||
|
||||
// If attributes exist after the method, parse them.
|
||||
AttributeList *MethodAttrs = 0;
|
||||
if (getLang().ObjC2 && Tok.is(tok::kw___attribute))
|
||||
|
@ -653,9 +666,8 @@ Parser::DeclTy *Parser::ParseObjCMethodDecl(SourceLocation mLoc,
|
|||
}
|
||||
ConsumeToken(); // Eat the ':'.
|
||||
ObjCDeclSpec DSType;
|
||||
if (Tok.is(tok::l_paren)) { // Parse the argument type.
|
||||
if (Tok.is(tok::l_paren)) // Parse the argument type.
|
||||
TypeInfo = ParseObjCTypeName(DSType);
|
||||
}
|
||||
else
|
||||
TypeInfo = 0;
|
||||
KeyTypes.push_back(TypeInfo);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: clang -fsyntax-only %s
|
||||
// RUN: clang -fsyntax-only -verify %s
|
||||
|
||||
@interface foo
|
||||
- (int)meth;
|
||||
|
@ -8,3 +8,14 @@
|
|||
- (int) meth { return [self meth]; }
|
||||
@end
|
||||
|
||||
// PR2708
|
||||
@interface MyClass
|
||||
+- (void)myMethod; // expected-error {{expected selector for Objective-C method}}
|
||||
- (vid)myMethod2; // expected-error {{expected a type}}
|
||||
@end
|
||||
|
||||
@implementation MyClass
|
||||
- (void)myMethod { }
|
||||
- (void)myMethod2 { }
|
||||
@end
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче