Rework the traversal of Objective-C categories and extensions to
consider (sub)module visibility.
The bulk of this change replaces myriad hand-rolled loops over the
linked list of Objective-C categories/extensions attached to an
interface declaration with loops using one of the four new category
iterator kinds:
visible_categories_iterator: Iterates over all visible categories
and extensions, hiding any that have their "hidden" bit set. This is
by far the most commonly used iterator.
known_categories_iterator: Iterates over all categories and
extensions, ignoring the "hidden" bit. This tends to be used for
redeclaration-like traversals.
visible_extensions_iterator: Iterates over all visible extensions,
hiding any that have their "hidden" bit set.
known_extensions_iterator: Iterates over all extensions, whether
they are visible to normal name lookup or not.
The effect of this change is that any uses of the visible_ iterators
will respect module-import visibility. See the new tests for examples.
Note that the old accessors for categories and extensions are gone;
there are *Raw() forms for some of them, for those (few) areas of the
compiler that have to manipulate the linked list of categories
directly. This is generally discouraged.
Part two of <rdar://problem/10634711>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172665 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DumpXML.cpp b/lib/AST/DumpXML.cpp
index 1e7523f..be22ae4 100644
--- a/lib/AST/DumpXML.cpp
+++ b/lib/AST/DumpXML.cpp
@@ -748,14 +748,6 @@
visitDeclContext(D);
}
- // ObjCInterfaceDecl
- void visitCategoryList(ObjCCategoryDecl *D) {
- if (!D) return;
-
- TemporaryContainer C(*this, "categories");
- for (; D; D = D->getNextClassCategory())
- visitDeclRef(D);
- }
void visitObjCInterfaceDeclAttrs(ObjCInterfaceDecl *D) {
setPointer("typeptr", D->getTypeForDecl());
setFlag("forward_decl", !D->isThisDeclarationADefinition());
@@ -770,7 +762,17 @@
I = D->protocol_begin(), E = D->protocol_end(); I != E; ++I)
visitDeclRef(*I);
}
- visitCategoryList(D->getCategoryList());
+
+ if (!D->visible_categories_empty()) {
+ TemporaryContainer C(*this, "categories");
+
+ for (ObjCInterfaceDecl::visible_categories_iterator
+ Cat = D->visible_categories_begin(),
+ CatEnd = D->visible_categories_end();
+ Cat != CatEnd; ++Cat) {
+ visitDeclRef(*Cat);
+ }
+ }
}
void visitObjCInterfaceDeclAsContext(ObjCInterfaceDecl *D) {
visitDeclContext(D);