[cfe-commits] r138556 - in /cfe/trunk: include/clang/Serialization/ASTReader.h lib/Serialization/ASTReader.cpp test/Modules/Inputs/lookup_left.h test/Modules/Inputs/lookup_right.h test/Modules/lookup.m
Douglas Gregor
dgregor at apple.com
Thu Aug 25 07:51:20 PDT 2011
Author: dgregor
Date: Thu Aug 25 09:51:20 2011
New Revision: 138556
URL: http://llvm.org/viewvc/llvm-project?rev=138556&view=rev
Log:
Use the module manager's search facility to look for methods with a
given selector, rather than walking the chain backwards. Teach its
visitor how to merge multiple result sets into a single result set,
combining the results of selector lookup in several different modules
into a single result set.
Added:
cfe/trunk/test/Modules/Inputs/lookup_left.h (with props)
cfe/trunk/test/Modules/Inputs/lookup_right.h (with props)
cfe/trunk/test/Modules/lookup.m
Modified:
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/lib/Serialization/ASTReader.cpp
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=138556&r1=138555&r2=138556&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Thu Aug 25 09:51:20 2011
@@ -574,6 +574,8 @@
void *UserData);
};
+class ReadMethodPoolVisitor;
+
} // end namespace serialization
/// \brief Reads an AST files chain containing the contents of a translation
@@ -608,6 +610,7 @@
friend class TypeLocReader;
friend class ASTWriter;
friend class ASTUnit; // ASTUnit needs to remap source locations.
+ friend class serialization::ReadMethodPoolVisitor;
typedef serialization::Module Module;
typedef serialization::ModuleKind ModuleKind;
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=138556&r1=138555&r2=138556&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Thu Aug 25 09:51:20 2011
@@ -487,7 +487,8 @@
public:
struct data_type {
SelectorID ID;
- ObjCMethodList Instance, Factory;
+ llvm::SmallVector<ObjCMethodDecl *, 2> Instance;
+ llvm::SmallVector<ObjCMethodDecl *, 2> Factory;
};
typedef Selector external_key_type;
@@ -548,37 +549,17 @@
// Load instance methods
ObjCMethodList *Prev = 0;
for (unsigned I = 0; I != NumInstanceMethods; ++I) {
- ObjCMethodDecl *Method
- = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d));
- if (!Result.Instance.Method) {
- // This is the first method, which is the easy case.
- Result.Instance.Method = Method;
- Prev = &Result.Instance;
- continue;
- }
-
- ObjCMethodList *Mem =
- Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
- Prev->Next = new (Mem) ObjCMethodList(Method, 0);
- Prev = Prev->Next;
+ if (ObjCMethodDecl *Method
+ = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+ Result.Instance.push_back(Method);
}
// Load factory methods
Prev = 0;
for (unsigned I = 0; I != NumFactoryMethods; ++I) {
- ObjCMethodDecl *Method
- = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d));
- if (!Result.Factory.Method) {
- // This is the first method, which is the easy case.
- Result.Factory.Method = Method;
- Prev = &Result.Factory;
- continue;
- }
-
- ObjCMethodList *Mem =
- Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
- Prev->Next = new (Mem) ObjCMethodList(Method, 0);
- Prev = Prev->Next;
+ if (ObjCMethodDecl *Method
+ = Reader.GetLocalDeclAs<ObjCMethodDecl>(F, ReadUnalignedLE32(d)))
+ Result.Factory.push_back(Method);
}
return Result;
@@ -4693,32 +4674,92 @@
return new ASTIdentifierIterator(*this);
}
-std::pair<ObjCMethodList, ObjCMethodList>
-ASTReader::ReadMethodPool(Selector Sel) {
- // Find this selector in a hash table. We want to find the most recent entry.
- for (ModuleIterator I = ModuleMgr.begin(), E = ModuleMgr.end(); I != E; ++I) {
- Module &F = *(*I);
- if (!F.SelectorLookupTable)
- continue;
-
- ASTSelectorLookupTable *PoolTable
- = (ASTSelectorLookupTable*)F.SelectorLookupTable;
- ASTSelectorLookupTable::iterator Pos = PoolTable->find(Sel);
- if (Pos != PoolTable->end()) {
- ++NumSelectorsRead;
+namespace clang { namespace serialization {
+ class ReadMethodPoolVisitor {
+ ASTReader &Reader;
+ Selector Sel;
+ llvm::SmallVector<ObjCMethodDecl *, 4> InstanceMethods;
+ llvm::SmallVector<ObjCMethodDecl *, 4> FactoryMethods;
+
+ /// \brief Build an ObjCMethodList from a vector of Objective-C method
+ /// declarations.
+ ObjCMethodList
+ buildObjCMethodList(const SmallVectorImpl<ObjCMethodDecl *> &Vec) const
+ {
+ ObjCMethodList List;
+ ObjCMethodList *Prev = 0;
+ for (unsigned I = 0, N = Vec.size(); I != N; ++I) {
+ if (!List.Method) {
+ // This is the first method, which is the easy case.
+ List.Method = Vec[I];
+ Prev = &List;
+ continue;
+ }
+
+ ObjCMethodList *Mem =
+ Reader.getSema()->BumpAlloc.Allocate<ObjCMethodList>();
+ Prev->Next = new (Mem) ObjCMethodList(Vec[I], 0);
+ Prev = Prev->Next;
+ }
+
+ return List;
+ }
+
+ public:
+ ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel)
+ : Reader(Reader), Sel(Sel) { }
+
+ static bool visit(Module &M, void *UserData) {
+ ReadMethodPoolVisitor *This
+ = static_cast<ReadMethodPoolVisitor *>(UserData);
+
+ if (!M.SelectorLookupTable)
+ return false;
+
+ ASTSelectorLookupTable *PoolTable
+ = (ASTSelectorLookupTable*)M.SelectorLookupTable;
+ ASTSelectorLookupTable::iterator Pos = PoolTable->find(This->Sel);
+ if (Pos == PoolTable->end())
+ return false;
+
+ ++This->Reader.NumSelectorsRead;
// FIXME: Not quite happy with the statistics here. We probably should
// disable this tracking when called via LoadSelector.
// Also, should entries without methods count as misses?
- ++NumMethodPoolEntriesRead;
+ ++This->Reader.NumMethodPoolEntriesRead;
ASTSelectorLookupTrait::data_type Data = *Pos;
- if (DeserializationListener)
- DeserializationListener->SelectorRead(Data.ID, Sel);
- return std::make_pair(Data.Instance, Data.Factory);
+ if (This->Reader.DeserializationListener)
+ This->Reader.DeserializationListener->SelectorRead(Data.ID,
+ This->Sel);
+
+ This->InstanceMethods.append(Data.Instance.begin(), Data.Instance.end());
+ This->FactoryMethods.append(Data.Factory.begin(), Data.Factory.end());
+ return true;
}
- }
+
+ /// \brief Retrieve the instance methods found by this visitor.
+ ObjCMethodList getInstanceMethods() const {
+ return buildObjCMethodList(InstanceMethods);
+ }
+
+ /// \brief Retrieve the instance methods found by this visitor.
+ ObjCMethodList getFactoryMethods() const {
+ return buildObjCMethodList(FactoryMethods);
+ }
+ };
+} } // end namespace clang::serialization
- ++NumMethodPoolMisses;
- return std::pair<ObjCMethodList, ObjCMethodList>();
+std::pair<ObjCMethodList, ObjCMethodList>
+ASTReader::ReadMethodPool(Selector Sel) {
+ ReadMethodPoolVisitor Visitor(*this, Sel);
+ ModuleMgr.visit(&ReadMethodPoolVisitor::visit, &Visitor);
+ std::pair<ObjCMethodList, ObjCMethodList> Result;
+ Result.first = Visitor.getInstanceMethods();
+ Result.second = Visitor.getFactoryMethods();
+
+ if (!Result.first.Method && !Result.second.Method)
+ ++NumMethodPoolMisses;
+ return Result;
}
void ASTReader::ReadKnownNamespaces(
Added: cfe/trunk/test/Modules/Inputs/lookup_left.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/lookup_left.h?rev=138556&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/lookup_left.h (added)
+++ cfe/trunk/test/Modules/Inputs/lookup_left.h Thu Aug 25 09:51:20 2011
@@ -0,0 +1,3 @@
+ at interface A
+- (int)method;
+ at end
Propchange: cfe/trunk/test/Modules/Inputs/lookup_left.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Modules/Inputs/lookup_left.h
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Modules/Inputs/lookup_left.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/Modules/Inputs/lookup_right.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/lookup_right.h?rev=138556&view=auto
==============================================================================
--- cfe/trunk/test/Modules/Inputs/lookup_right.h (added)
+++ cfe/trunk/test/Modules/Inputs/lookup_right.h Thu Aug 25 09:51:20 2011
@@ -0,0 +1,5 @@
+
+ at interface B
+- (double)method;
+ at end
+
Propchange: cfe/trunk/test/Modules/Inputs/lookup_right.h
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: cfe/trunk/test/Modules/Inputs/lookup_right.h
------------------------------------------------------------------------------
svn:keywords = Id
Propchange: cfe/trunk/test/Modules/Inputs/lookup_right.h
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: cfe/trunk/test/Modules/lookup.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/lookup.m?rev=138556&view=auto
==============================================================================
--- cfe/trunk/test/Modules/lookup.m (added)
+++ cfe/trunk/test/Modules/lookup.m Thu Aug 25 09:51:20 2011
@@ -0,0 +1,17 @@
+
+// lookup_left.h: expected-note{{using}}
+// lookup_right.h: expected-note{{also found}}
+
+void test(id x) {
+ [x method]; // expected-warning{{multiple methods named 'method' found}}
+}
+
+// RUN: %clang_cc1 -emit-pch -x objective-c -o %t_lookup_left.h.pch %S/Inputs/lookup_left.h
+// RUN: %clang_cc1 -emit-pch -x objective-c -o %t_lookup_right.h.pch %S/Inputs/lookup_right.h
+// RUN: %clang_cc1 -x objective-c -import-module %t_lookup_left.h.pch -import-module %t_lookup_right.h.pch -verify %s
+// RUN: %clang_cc1 -ast-print -x objective-c -import-module %t_lookup_left.h.pch -import-module %t_lookup_right.h.pch %s | FileCheck -check-prefix=CHECK-PRINT %s
+
+// CHECK-PRINT: - (int) method;
+// CHECK-PRINT: - (double) method
+// CHECK-PRINT: void test(id x)
+
More information about the cfe-commits
mailing list