]> granicus.if.org Git - clang/commitdiff
When parsing something that looks like an ill-formed
authorDouglas Gregor <dgregor@apple.com>
Fri, 19 Nov 2010 17:10:50 +0000 (17:10 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 19 Nov 2010 17:10:50 +0000 (17:10 +0000)
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

include/clang/Parse/Parser.h
lib/Parse/ParseDecl.cpp
lib/Parse/ParseObjc.cpp
test/Parser/placeholder-recovery.m [new file with mode: 0644]

index f8ca18afa81b558acc1be228174730591d1f9535..e94225813e2f3ae88327d491a650ecfe4a9a9e7f 100644 (file)
@@ -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,
index ed58a92323d98bb59fd307f33b236b55ba806360..121289696db8f69aef17dcfd3bb500a69dab6223 100644 (file)
@@ -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<p> const").
       // If a type specifier follows, it will be diagnosed elsewhere.
index c01bea9cb5a5edcd3b30fb8672e91efaf3dec56d..456c9c72820cd34dcd79a211a719a6ff40a9aa5a 100644 (file)
@@ -1038,18 +1038,19 @@ ParseObjCProtocolReferences(llvm::SmallVectorImpl<Decl *> &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<Decl *, 8> ProtocolDecl;
   llvm::SmallVector<SourceLocation, 8> 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 (file)
index 0000000..1fc1549
--- /dev/null
@@ -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#> <NSObject> // 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}}