aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-13 01:04:01 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2013-04-13 01:04:01 +0000
commit175c8e2e57befe2db15dd339ab5eb27d0c2b6013 (patch)
treeb8aa20a5d67521db1fcc8f26cf939fc6448126b6
parentecc65238c98ba21d08763da7b7972d617677e908 (diff)
Speed-up ObjCMethodDecl::getOverriddenMethods().
Use an newly introduce ASTContext::getBaseObjCCategoriesAfterInterface() which caches its results instead of re-calculating the categories multiple times. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179436 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/AST/ASTContext.h11
-rw-r--r--lib/AST/ASTContext.cpp37
-rw-r--r--lib/AST/DeclObjC.cpp32
3 files changed, 52 insertions, 28 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index d4878a99a6..6a03eefbba 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -328,6 +328,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
typedef llvm::TinyPtrVector<const CXXMethodDecl*> CXXMethodVector;
llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector> OverriddenMethods;
+ /// \brief Used to cache results from \c getBaseObjCCategoriesAfterInterface.
+ mutable llvm::DenseMap<const ObjCInterfaceDecl *,
+ llvm::SmallVector<const ObjCCategoryDecl *, 2> > CatsAfterInterface;
+
/// \brief Mapping from each declaration context to its corresponding lambda
/// mangling context.
llvm::DenseMap<const DeclContext *, LambdaMangleContext> LambdaMangleContexts;
@@ -682,7 +686,12 @@ public:
void getOverriddenMethods(
const NamedDecl *Method,
SmallVectorImpl<const NamedDecl *> &Overridden) const;
-
+
+ /// \brief Returns the ObjC categories of base classes, that were declared
+ /// after the given interface declaration.
+ void getBaseObjCCategoriesAfterInterface(const ObjCInterfaceDecl *D,
+ SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const;
+
/// \brief Notify the AST context that a new import declaration has been
/// parsed or implicitly created within this translation unit.
void addedLocalImportDecl(ImportDecl *Import);
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 170cc0298b..8ede90dede 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1127,8 +1127,8 @@ void ASTContext::getOverriddenMethods(
assert(D);
if (const CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
- Overridden.append(CXXMethod->begin_overridden_methods(),
- CXXMethod->end_overridden_methods());
+ Overridden.append(overridden_methods_begin(CXXMethod),
+ overridden_methods_end(CXXMethod));
return;
}
@@ -1141,6 +1141,39 @@ void ASTContext::getOverriddenMethods(
Overridden.append(OverDecls.begin(), OverDecls.end());
}
+void ASTContext::getBaseObjCCategoriesAfterInterface(
+ const ObjCInterfaceDecl *D,
+ SmallVectorImpl<const ObjCCategoryDecl *> &Cats) const {
+ if (!D)
+ return;
+
+ typedef llvm::SmallVector<const ObjCCategoryDecl *, 2> VecTy;
+ typedef llvm::DenseMap<const ObjCInterfaceDecl *, VecTy> MapTy;
+
+ std::pair<MapTy::iterator, bool>
+ InsertOp = CatsAfterInterface.insert(std::make_pair(D, VecTy()));
+ VecTy &Vec = InsertOp.first->second;
+ if (!InsertOp.second) {
+ // already in map.
+ Cats.append(Vec.begin(), Vec.end());
+ return;
+ }
+
+ SourceLocation Loc = D->getLocation();
+ for (const ObjCInterfaceDecl *
+ Class = D->getSuperClass(); Class; Class = Class->getSuperClass()) {
+ for (ObjCInterfaceDecl::known_categories_iterator
+ CatI = Class->known_categories_begin(),
+ CatEnd = Class->known_categories_end();
+ CatI != CatEnd; ++CatI) {
+ if (SourceMgr.isBeforeInTranslationUnit(Loc, CatI->getLocation()))
+ Vec.push_back(*CatI);
+ }
+ }
+
+ Cats.append(Vec.begin(), Vec.end());
+}
+
void ASTContext::addedLocalImportDecl(ImportDecl *Import) {
assert(!Import->NextLocalImport && "Import declaration already in the chain");
assert(!Import->isFromASTFile() && "Non-local import declaration");
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index 5f5ba52947..1fe262cc0c 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -959,26 +959,6 @@ static void collectOverriddenMethodsSlow(const ObjCMethodDecl *Method,
}
}
-static void collectOnCategoriesAfterLocation(SourceLocation Loc,
- const ObjCInterfaceDecl *Class,
- SourceManager &SM,
- const ObjCMethodDecl *Method,
- SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
- if (!Class)
- return;
-
- for (ObjCInterfaceDecl::known_categories_iterator
- Cat = Class->known_categories_begin(),
- CatEnd = Class->known_categories_end();
- Cat != CatEnd; ++Cat) {
- if (SM.isBeforeInTranslationUnit(Loc, Cat->getLocation()))
- CollectOverriddenMethodsRecurse(*Cat, Method, Methods, true);
- }
-
- collectOnCategoriesAfterLocation(Loc, Class->getSuperClass(), SM,
- Method, Methods);
-}
-
/// \brief Faster collection that is enabled when ObjCMethodDecl::isOverriding()
/// returns false.
/// You'd think that in that case there are no overrides but categories can
@@ -988,7 +968,7 @@ static void collectOnCategoriesAfterLocation(SourceLocation Loc,
/// further in super classes.
/// Methods in an implementation can overide methods in super class's category
/// but not in current class's category. But, such methods
-static void collectOverriddenMethodsFast(SourceManager &SM,
+static void collectOverriddenMethodsFast(ASTContext &Ctx,
const ObjCMethodDecl *Method,
SmallVectorImpl<const ObjCMethodDecl *> &Methods) {
assert(!Method->isOverriding());
@@ -1001,8 +981,11 @@ static void collectOverriddenMethodsFast(SourceManager &SM,
if (!Class)
return;
- collectOnCategoriesAfterLocation(Class->getLocation(), Class->getSuperClass(),
- SM, Method, Methods);
+ SmallVector<const ObjCCategoryDecl *, 32> Cats;
+ Ctx.getBaseObjCCategoriesAfterInterface(Class, Cats);
+ for (SmallVectorImpl<const ObjCCategoryDecl *>::iterator
+ I = Cats.begin(), E = Cats.end(); I != E; ++I)
+ CollectOverriddenMethodsRecurse(*I, Method, Methods, true);
}
void ObjCMethodDecl::getOverriddenMethods(
@@ -1015,8 +998,7 @@ void ObjCMethodDecl::getOverriddenMethods(
}
if (!Method->isOverriding()) {
- collectOverriddenMethodsFast(getASTContext().getSourceManager(),
- Method, Overridden);
+ collectOverriddenMethodsFast(getASTContext(), Method, Overridden);
} else {
collectOverriddenMethodsSlow(Method, Overridden);
assert(!Overridden.empty() &&