From: Douglas Gregor Date: Fri, 19 Nov 2010 17:10:50 +0000 (+0000) Subject: When parsing something that looks like an ill-formed X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=46f936e055d763437accd1e5a1bc49e7e5dbc0a3;p=clang When parsing something that looks like an ill-formed protocol-qualifier list without a leading type (e.g., <#blah#>), don't complain about it being an archaic protocol-qualifier list unless it actually parses as one. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119805 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index f8ca18afa8..e94225813e 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -951,7 +951,7 @@ private: bool WarnOnDeclarations, SourceLocation &LAngleLoc, SourceLocation &EndProtoLoc); - void ParseObjCProtocolQualifiers(DeclSpec &DS); + bool ParseObjCProtocolQualifiers(DeclSpec &DS); void ParseObjCInterfaceDeclList(Decl *interfaceDecl, tok::ObjCKeywordKind contextKey); Decl *ParseObjCAtProtocolDeclaration(SourceLocation atLoc, diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index ed58a92323..121289696d 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1434,11 +1434,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, if (DS.hasTypeSpecifier() || !getLang().ObjC1) goto DoneWithDeclSpec; - ParseObjCProtocolQualifiers(DS); - - Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) - << FixItHint::CreateInsertion(Loc, "id") - << SourceRange(Loc, DS.getSourceRange().getEnd()); + if (!ParseObjCProtocolQualifiers(DS)) + Diag(Loc, diag::warn_objc_protocol_qualifier_missing_id) + << FixItHint::CreateInsertion(Loc, "id") + << SourceRange(Loc, DS.getSourceRange().getEnd()); // Need to support trailing type qualifiers (e.g. "id

const"). // If a type specifier follows, it will be diagnosed elsewhere. diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index c01bea9cb5..456c9c7282 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -1038,18 +1038,19 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl &Protocols, /// \brief Parse the Objective-C protocol qualifiers that follow a typename /// in a decl-specifier-seq, starting at the '<'. -void Parser::ParseObjCProtocolQualifiers(DeclSpec &DS) { +bool Parser::ParseObjCProtocolQualifiers(DeclSpec &DS) { assert(Tok.is(tok::less) && "Protocol qualifiers start with '<'"); assert(getLang().ObjC1 && "Protocol qualifiers only exist in Objective-C"); SourceLocation LAngleLoc, EndProtoLoc; llvm::SmallVector ProtocolDecl; llvm::SmallVector ProtocolLocs; - ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, - LAngleLoc, EndProtoLoc); + bool Result = ParseObjCProtocolReferences(ProtocolDecl, ProtocolLocs, false, + LAngleLoc, EndProtoLoc); DS.setProtocolQualifiers(ProtocolDecl.data(), ProtocolDecl.size(), ProtocolLocs.data(), LAngleLoc); if (EndProtoLoc.isValid()) DS.SetRangeEnd(EndProtoLoc); + return Result; } diff --git a/test/Parser/placeholder-recovery.m b/test/Parser/placeholder-recovery.m new file mode 100644 index 0000000000..1fc154955d --- /dev/null +++ b/test/Parser/placeholder-recovery.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +// FIXME: We could do much better with this, if we recognized +// placeholders somehow. However, we're content with not generating +// bogus 'archaic' warnings with bad location info. +@protocol <#protocol name#> // expected-error 2{{expected identifier}} \ +// expected-error{{cannot find protocol declaration for 'NSObject'}} \ +// expected-warning{{protocol qualifiers without 'id'}} + +<#methods#> // expected-error{{expected identifier}} + +@end // expected-error{{prefix attribute}}