- while (true) {
- // Look past non-namespaces and anonymous namespaces on FromContext.
- // We can skip anonymous namespace because:
- // 1. `FromContext` and `UseContext` must be in the same anonymous
- // namespaces since referencing across anonymous namespaces is not possible.
- // 2. If `FromContext` and `UseContext` are in the same anonymous namespace,
- // the function will still return `false` as expected.
- while (FromContext &&
- (!isa<NamespaceDecl>(FromContext) ||
- cast<NamespaceDecl>(FromContext)->isAnonymousNamespace()))
- FromContext = FromContext->getParent();
-
- // Look past non-namespaces and anonymous namespaces on UseContext.
- while (UseContext &&
- (!isa<NamespaceDecl>(UseContext) ||
- cast<NamespaceDecl>(UseContext)->isAnonymousNamespace()))
- UseContext = UseContext->getParent();
-
- // We hit the root, no namespace collision.
- if (!FromContext || !UseContext)
- return false;
-
+ // We can skip anonymous namespace because:
+ // 1. `FromContext` and `UseContext` must be in the same anonymous namespaces
+ // since referencing across anonymous namespaces is not possible.
+ // 2. If `FromContext` and `UseContext` are in the same anonymous namespace,
+ // the function will still return `false` as expected.
+ llvm::SmallVector<const NamespaceDecl *, 4> FromNamespaces =
+ getAllNamedNamespaces(FromContext);
+ llvm::SmallVector<const NamespaceDecl *, 4> UseNamespaces =
+ getAllNamedNamespaces(UseContext);
+ // If `UseContext` has fewer level of nested namespaces, it cannot be in the
+ // same canonical namespace as the `FromContext`.
+ if (UseNamespaces.size() < FromNamespaces.size())
+ return false;
+ unsigned Diff = UseNamespaces.size() - FromNamespaces.size();
+ auto FromIter = FromNamespaces.begin();
+ // Only compare `FromNamespaces` with namespaces in `UseNamespaces` that can
+ // collide, i.e. the top N namespaces where N is the number of namespaces in
+ // `FromNamespaces`.
+ auto UseIter = UseNamespaces.begin() + Diff;
+ for (; FromIter != FromNamespaces.end() && UseIter != UseNamespaces.end();
+ ++FromIter, ++UseIter) {