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