<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Sat, Dec 27, 2014 at 2:14 PM, Nico Weber <span dir="ltr"><<a href="mailto:nicolasweber@gmx.de" target="_blank">nicolasweber@gmx.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: nico<br>
Date: Sat Dec 27 16:14:15 2014<br>
New Revision: 224892<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=224892&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=224892&view=rev</a><br>
Log:<br>
Objective-C: Serialize "more than one decl" state of ObjCMethodList.<br>
<br>
This fixes PR21587, what r221933 fixed for regular programs is now also<br>
fixed for decls coming from PCH files.<br>
<br>
Use another bit from the count/bits uint16_t for storing the "more than one<br>
decl" bit.  This reduces the number of bits for the count from 14 to 13.<br>
The selector with the most overloads in Cocoa.h has ~55 overloads, so 13 bits<br>
should still be plenty.  Since this changes the meaning of a serialized bit<br>
pattern, also increase clang::serialization::VERSION_MAJOR.<br>
<br>
Storing the "more than one decl" state of only the first overload isn't quite<br>
correct, but Sema::AreMultipleMethodsInGlobalPool() currently only looks at<br>
the state of the first overload so it's good enough for now.<br></blockquote><div><br></div><div>I filed <a href="http://llvm.org/PR22047">http://llvm.org/PR22047</a> for things that go wrong with the current approach for this warning (these things go wrong independent of PCH files).</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
Added:<br>
    cfe/trunk/test/SemaObjC/attr-deprecated-pch.m<br>
Modified:<br>
    cfe/trunk/include/clang/Sema/ObjCMethodList.h<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/lib/Serialization/ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/ASTReaderInternals.h<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
<br>
Modified: cfe/trunk/include/clang/Sema/ObjCMethodList.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ObjCMethodList.h?rev=224892&r1=224891&r2=224892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ObjCMethodList.h?rev=224892&r1=224891&r2=224892&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Sema/ObjCMethodList.h (original)<br>
+++ cfe/trunk/include/clang/Sema/ObjCMethodList.h Sat Dec 27 16:14:15 2014<br>
@@ -23,6 +23,7 @@ class ObjCMethodDecl;<br>
 /// \brief a linked list of methods with the same selector name but different<br>
 /// signatures.<br>
 struct ObjCMethodList {<br>
+  // NOTE: If you add any members to this struct, make sure to serialize them.<br>
   /// \brief If there is more than one decl with this signature.<br>
   llvm::PointerIntPair<ObjCMethodDecl *, 1> MethodAndHasMoreThanOneDecl;<br>
   /// \brief The next list object and 2 bits for extra info.<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=224892&r1=224891&r2=224892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=224892&r1=224891&r2=224892&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Sat Dec 27 16:14:15 2014<br>
@@ -35,7 +35,7 @@ namespace clang {<br>
     /// Version 4 of AST files also requires that the version control branch and<br>
     /// revision match exactly, since there is no backward compatibility of<br>
     /// AST files at this time.<br>
-    const unsigned VERSION_MAJOR = 5;<br>
+    const unsigned VERSION_MAJOR = 6;<br>
<br>
     /// \brief AST file minor version number supported by this version of<br>
     /// Clang.<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=224892&r1=224891&r2=224892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=224892&r1=224891&r2=224892&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Dec 27 16:14:15 2014<br>
@@ -650,14 +650,14 @@ ASTSelectorLookupTrait::ReadData(Selecto<br>
<br>
   Result.ID = Reader.getGlobalSelectorID(<br>
       F, endian::readNext<uint32_t, little, unaligned>(d));<br>
-  unsigned NumInstanceMethodsAndBits =<br>
-      endian::readNext<uint16_t, little, unaligned>(d);<br>
-  unsigned NumFactoryMethodsAndBits =<br>
-      endian::readNext<uint16_t, little, unaligned>(d);<br>
-  Result.InstanceBits = NumInstanceMethodsAndBits & 0x3;<br>
-  Result.FactoryBits = NumFactoryMethodsAndBits & 0x3;<br>
-  unsigned NumInstanceMethods = NumInstanceMethodsAndBits >> 2;<br>
-  unsigned NumFactoryMethods = NumFactoryMethodsAndBits >> 2;<br>
+  unsigned FullInstanceBits = endian::readNext<uint16_t, little, unaligned>(d);<br>
+  unsigned FullFactoryBits = endian::readNext<uint16_t, little, unaligned>(d);<br>
+  Result.InstanceBits = FullInstanceBits & 0x3;<br>
+  Result.InstanceHasMoreThanOneDecl = (FullInstanceBits >> 2) & 0x1;<br>
+  Result.FactoryBits = FullFactoryBits & 0x3;<br>
+  Result.FactoryHasMoreThanOneDecl = (FullFactoryBits >> 2) & 0x1;<br>
+  unsigned NumInstanceMethods = FullInstanceBits >> 3;<br>
+  unsigned NumFactoryMethods = FullFactoryBits >> 3;<br>
<br>
   // Load instance methods<br>
   for (unsigned I = 0; I != NumInstanceMethods; ++I) {<br>
@@ -7061,6 +7061,8 @@ namespace clang { namespace serializatio<br>
     unsigned PriorGeneration;<br>
     unsigned InstanceBits;<br>
     unsigned FactoryBits;<br>
+    bool InstanceHasMoreThanOneDecl;<br>
+    bool FactoryHasMoreThanOneDecl;<br>
     SmallVector<ObjCMethodDecl *, 4> InstanceMethods;<br>
     SmallVector<ObjCMethodDecl *, 4> FactoryMethods;<br>
<br>
@@ -7068,7 +7070,8 @@ namespace clang { namespace serializatio<br>
     ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel,<br>
                           unsigned PriorGeneration)<br>
         : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration),<br>
-          InstanceBits(0), FactoryBits(0) {}<br>
+          InstanceBits(0), FactoryBits(0), InstanceHasMoreThanOneDecl(false),<br>
+          FactoryHasMoreThanOneDecl(false) {}<br>
<br>
     static bool visit(ModuleFile &M, void *UserData) {<br>
       ReadMethodPoolVisitor *This<br>
@@ -7103,6 +7106,8 @@ namespace clang { namespace serializatio<br>
       This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());<br>
       This->InstanceBits = Data.InstanceBits;<br>
       This->FactoryBits = Data.FactoryBits;<br>
+      This->InstanceHasMoreThanOneDecl = Data.InstanceHasMoreThanOneDecl;<br>
+      This->FactoryHasMoreThanOneDecl = Data.FactoryHasMoreThanOneDecl;<br>
       return true;<br>
     }<br>
<br>
@@ -7118,6 +7123,10 @@ namespace clang { namespace serializatio<br>
<br>
     unsigned getInstanceBits() const { return InstanceBits; }<br>
     unsigned getFactoryBits() const { return FactoryBits; }<br>
+    bool instanceHasMoreThanOneDecl() const {<br>
+      return InstanceHasMoreThanOneDecl;<br>
+    }<br>
+    bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; }<br>
   };<br>
 } } // end namespace clang::serialization<br>
<br>
@@ -7156,7 +7165,9 @@ void ASTReader::ReadMethodPool(Selector<br>
   addMethodsToPool(S, Visitor.getInstanceMethods(), Pos->second.first);<br>
   addMethodsToPool(S, Visitor.getFactoryMethods(), Pos->second.second);<br>
   Pos->second.first.setBits(Visitor.getInstanceBits());<br>
+  Pos->second.first.setHasMoreThanOneDecl(Visitor.instanceHasMoreThanOneDecl());<br>
   Pos->second.second.setBits(Visitor.getFactoryBits());<br>
+  Pos->second.second.setHasMoreThanOneDecl(Visitor.factoryHasMoreThanOneDecl());<br>
 }<br>
<br>
 void ASTReader::ReadKnownNamespaces(<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReaderInternals.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderInternals.h?rev=224892&r1=224891&r2=224892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderInternals.h?rev=224892&r1=224891&r2=224892&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderInternals.h (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderInternals.h Sat Dec 27 16:14:15 2014<br>
@@ -156,6 +156,8 @@ public:<br>
     SelectorID ID;<br>
     unsigned InstanceBits;<br>
     unsigned FactoryBits;<br>
+    bool InstanceHasMoreThanOneDecl;<br>
+    bool FactoryHasMoreThanOneDecl;<br>
     SmallVector<ObjCMethodDecl *, 2> Instance;<br>
     SmallVector<ObjCMethodDecl *, 2> Factory;<br>
   };<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=224892&r1=224891&r2=224892&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=224892&r1=224891&r2=224892&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Sat Dec 27 16:14:15 2014<br>
@@ -2940,13 +2940,20 @@ public:<br>
<br>
     unsigned InstanceBits = Methods.Instance.getBits();<br>
     assert(InstanceBits < 4);<br>
-    unsigned NumInstanceMethodsAndBits =<br>
-        (NumInstanceMethods << 2) | InstanceBits;<br>
+    unsigned InstanceHasMoreThanOneDeclBit =<br>
+        Methods.Instance.hasMoreThanOneDecl();<br>
+    unsigned FullInstanceBits = (NumInstanceMethods << 3) |<br>
+                                (InstanceHasMoreThanOneDeclBit << 2) |<br>
+                                InstanceBits;<br>
     unsigned FactoryBits = Methods.Factory.getBits();<br>
     assert(FactoryBits < 4);<br>
-    unsigned NumFactoryMethodsAndBits = (NumFactoryMethods << 2) | FactoryBits;<br>
-    LE.write<uint16_t>(NumInstanceMethodsAndBits);<br>
-    LE.write<uint16_t>(NumFactoryMethodsAndBits);<br>
+    unsigned FactoryHasMoreThanOneDeclBit =<br>
+        Methods.Factory.hasMoreThanOneDecl();<br>
+    unsigned FullFactoryBits = (NumFactoryMethods << 3) |<br>
+                               (FactoryHasMoreThanOneDeclBit << 2) |<br>
+                               FactoryBits;<br>
+    LE.write<uint16_t>(FullInstanceBits);<br>
+    LE.write<uint16_t>(FullFactoryBits);<br>
     for (const ObjCMethodList *Method = &Methods.Instance; Method;<br>
          Method = Method->getNext())<br>
       if (Method->getMethod())<br>
<br>
Added: cfe/trunk/test/SemaObjC/attr-deprecated-pch.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-deprecated-pch.m?rev=224892&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/attr-deprecated-pch.m?rev=224892&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaObjC/attr-deprecated-pch.m (added)<br>
+++ cfe/trunk/test/SemaObjC/attr-deprecated-pch.m Sat Dec 27 16:14:15 2014<br>
@@ -0,0 +1,23 @@<br>
+// RUN: %clang_cc1 -fsyntax-only -DBOTH -verify %s<br>
+// If the decls come from a pch, the behavior shouldn't change:<br>
+// RUN: %clang_cc1 -x objective-c-header %s -emit-pch -o %t<br>
+// RUN: %clang_cc1 -DUSES -include-pch %t -fsyntax-only -verify %s<br>
+// expected-no-diagnostics<br>
+<br>
+// The slightly strange ifdefs are so that the command that builds the gch file<br>
+// doesn't need any -D switches, for these would get embedded in the gch.<br>
+<br>
+#ifndef USES<br>
+@interface Interface1<br>
+- (void)partiallyUnavailableMethod;<br>
+@end<br>
+@interface Interface2<br>
+- (void)partiallyUnavailableMethod __attribute__((unavailable));<br>
+@end<br>
+#endif<br>
+<br>
+#if defined(USES) || defined(BOTH)<br>
+void f(id a) {<br>
+  [a partiallyUnavailableMethod];  // no warning, `a` could be an Interface1.<br>
+}<br>
+#endif<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>