diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-04-24 21:10:55 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-04-24 21:10:55 +0000 |
commit | c78d34699fc47e947939d640b5ba215f9018b4fc (patch) | |
tree | 13b9bb1e1ba83be3469884750063ce1fd910b94a /clang/lib/Sema/SemaDeclObjC.cpp | |
parent | 969bc68195957fffe2f33594d8d9c660795fc56a (diff) | |
download | bcm5719-llvm-c78d34699fc47e947939d640b5ba215f9018b4fc.tar.gz bcm5719-llvm-c78d34699fc47e947939d640b5ba215f9018b4fc.zip |
PCH support for the global method pool (= instance and factory method
pools, combined). The methods in the global method pool are lazily
loaded from an on-disk hash table when Sema looks into its version of
the hash tables.
llvm-svn: 69989
Diffstat (limited to 'clang/lib/Sema/SemaDeclObjC.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclObjC.cpp | 96 |
1 files changed, 93 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index f4014d1f25d..05e471b10df 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "Sema.h" +#include "clang/Sema/ExternalSemaSource.h" #include "clang/AST/Expr.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" @@ -1090,8 +1091,47 @@ bool Sema::MatchTwoMethodDeclarations(const ObjCMethodDecl *Method, return true; } +/// \brief Read the contents of the instance and factory method pools +/// for a given selector from external storage. +/// +/// This routine should only be called once, when neither the instance +/// nor the factory method pool has an entry for this selector. +Sema::MethodPool::iterator Sema::ReadMethodPool(Selector Sel, + bool isInstance) { + assert(ExternalSource && "We need an external AST source"); + assert(InstanceMethodPool.find(Sel) == InstanceMethodPool.end() && + "Selector data already loaded into the instance method pool"); + assert(FactoryMethodPool.find(Sel) == FactoryMethodPool.end() && + "Selector data already loaded into the factory method pool"); + + // Read the method list from the external source. + std::pair<ObjCMethodList, ObjCMethodList> Methods + = ExternalSource->ReadMethodPool(Sel); + + if (isInstance) { + if (Methods.second.Method) + FactoryMethodPool[Sel] = Methods.second; + return InstanceMethodPool.insert(std::make_pair(Sel, Methods.first)).first; + } + + if (Methods.first.Method) + InstanceMethodPool[Sel] = Methods.first; + + return FactoryMethodPool.insert(std::make_pair(Sel, Methods.second)).first; +} + void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) { - ObjCMethodList &Entry = InstanceMethodPool[Method->getSelector()]; + llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos + = InstanceMethodPool.find(Method->getSelector()); + if (Pos == InstanceMethodPool.end()) { + if (ExternalSource && !FactoryMethodPool.count(Method->getSelector())) + Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/true); + else + Pos = InstanceMethodPool.insert(std::make_pair(Method->getSelector(), + ObjCMethodList())).first; + } + + ObjCMethodList &Entry = Pos->second; if (Entry.Method == 0) { // Haven't seen a method with this selector name yet - add it. Entry.Method = Method; @@ -1113,7 +1153,16 @@ void Sema::AddInstanceMethodToGlobalPool(ObjCMethodDecl *Method) { // FIXME: Finish implementing -Wno-strict-selector-match. ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel, SourceRange R) { - ObjCMethodList &MethList = InstanceMethodPool[Sel]; + llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos + = InstanceMethodPool.find(Sel); + if (Pos == InstanceMethodPool.end() && !FactoryMethodPool.count(Sel)) { + if (ExternalSource) + Pos = ReadMethodPool(Sel, /*isInstance=*/true); + else + return 0; + } + + ObjCMethodList &MethList = Pos->second; bool issueWarning = false; if (MethList.Method && MethList.Next) { @@ -1134,7 +1183,17 @@ ObjCMethodDecl *Sema::LookupInstanceMethodInGlobalPool(Selector Sel, } void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) { - ObjCMethodList &FirstMethod = FactoryMethodPool[Method->getSelector()]; + llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos + = FactoryMethodPool.find(Method->getSelector()); + if (Pos == FactoryMethodPool.end()) { + if (ExternalSource && !InstanceMethodPool.count(Method->getSelector())) + Pos = ReadMethodPool(Method->getSelector(), /*isInstance=*/false); + else + Pos = FactoryMethodPool.insert(std::make_pair(Method->getSelector(), + ObjCMethodList())).first; + } + + ObjCMethodList &FirstMethod = Pos->second; if (!FirstMethod.Method) { // Haven't seen a method with this selector name yet - add it. FirstMethod.Method = Method; @@ -1156,6 +1215,37 @@ void Sema::AddFactoryMethodToGlobalPool(ObjCMethodDecl *Method) { } } +ObjCMethodDecl *Sema::LookupFactoryMethodInGlobalPool(Selector Sel, + SourceRange R) { + llvm::DenseMap<Selector, ObjCMethodList>::iterator Pos + = FactoryMethodPool.find(Sel); + if (Pos == FactoryMethodPool.end()) { + if (ExternalSource && !InstanceMethodPool.count(Sel)) + Pos = ReadMethodPool(Sel, /*isInstance=*/false); + else + return 0; + } + + ObjCMethodList &MethList = Pos->second; + bool issueWarning = false; + + if (MethList.Method && MethList.Next) { + for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) + // This checks if the methods differ by size & alignment. + if (!MatchTwoMethodDeclarations(MethList.Method, Next->Method, true)) + issueWarning = true; + } + if (issueWarning && (MethList.Method && MethList.Next)) { + Diag(R.getBegin(), diag::warn_multiple_method_decl) << Sel << R; + Diag(MethList.Method->getLocStart(), diag::note_using_decl) + << MethList.Method->getSourceRange(); + for (ObjCMethodList *Next = MethList.Next; Next; Next = Next->Next) + Diag(Next->Method->getLocStart(), diag::note_also_found_decl) + << Next->Method->getSourceRange(); + } + return MethList.Method; +} + /// ProcessPropertyDecl - Make sure that any user-defined setter/getter methods /// have the property type and issue diagnostics if they don't. /// Also synthesize a getter/setter method if none exist (and update the |