summaryrefslogtreecommitdiff
path: root/clang-tools-extra/change-namespace
diff options
context:
space:
mode:
authorEric Liu <ioeric@google.com>2016-12-23 10:47:09 +0000
committerEric Liu <ioeric@google.com>2016-12-23 10:47:09 +0000
commit940e1201ff007486ca00035dcc6d455f6fa47adc (patch)
treed37c1b55e0859b064922739f88a851272a5ff1bd /clang-tools-extra/change-namespace
parent9f8d3dd45c2db6f0306b921f88046f524f829b10 (diff)
[change-namespace] consider namespace aliases to shorten qualified names.
Reviewers: hokein Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D28052
Diffstat (limited to 'clang-tools-extra/change-namespace')
-rw-r--r--clang-tools-extra/change-namespace/ChangeNamespace.cpp41
-rw-r--r--clang-tools-extra/change-namespace/ChangeNamespace.h3
2 files changed, 44 insertions, 0 deletions
diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.cpp b/clang-tools-extra/change-namespace/ChangeNamespace.cpp
index 0877519478c..7452b7d1f02 100644
--- a/clang-tools-extra/change-namespace/ChangeNamespace.cpp
+++ b/clang-tools-extra/change-namespace/ChangeNamespace.cpp
@@ -306,6 +306,11 @@ void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) {
IsVisibleInNewNs)
.bind("using_namespace"),
this);
+ // Match namespace alias declarations.
+ Finder->addMatcher(namespaceAliasDecl(isExpansionInFileMatching(FilePattern),
+ IsVisibleInNewNs)
+ .bind("namespace_alias"),
+ this);
// Match old namespace blocks.
Finder->addMatcher(
@@ -429,6 +434,10 @@ void ChangeNamespaceTool::run(
Result.Nodes.getNodeAs<UsingDirectiveDecl>(
"using_namespace")) {
UsingNamespaceDecls.insert(UsingNamespace);
+ } else if (const auto *NamespaceAlias =
+ Result.Nodes.getNodeAs<NamespaceAliasDecl>(
+ "namespace_alias")) {
+ NamespaceAliasDecls.insert(NamespaceAlias);
} else if (const auto *NsDecl =
Result.Nodes.getNodeAs<NamespaceDecl>("old_ns")) {
moveOldNamespace(Result, NsDecl);
@@ -687,6 +696,38 @@ void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext(
ReplaceName = FromDeclNameRef;
}
}
+ // Checks if there is any namespace alias declarations that can shorten the
+ // qualified name.
+ for (const auto *NamespaceAlias : NamespaceAliasDecls) {
+ if (!isDeclVisibleAtLocation(*Result.SourceManager, NamespaceAlias, DeclCtx,
+ Start))
+ continue;
+ StringRef FromDeclNameRef = FromDeclName;
+ if (FromDeclNameRef.consume_front(
+ NamespaceAlias->getNamespace()->getQualifiedNameAsString() +
+ "::")) {
+ std::string AliasName = NamespaceAlias->getNameAsString();
+ std::string AliasQualifiedName =
+ NamespaceAlias->getQualifiedNameAsString();
+ // We only consider namespace aliases define in the global namepspace or
+ // in namespaces that are directly visible from the reference, i.e.
+ // ancestor of the `OldNs`. Note that declarations in ancestor namespaces
+ // but not visible in the new namespace is filtered out by
+ // "IsVisibleInNewNs" matcher.
+ if (AliasQualifiedName != AliasName) {
+ // The alias is defined in some namespace.
+ assert(StringRef(AliasQualifiedName).endswith("::" + AliasName));
+ llvm::StringRef AliasNs =
+ StringRef(AliasQualifiedName).drop_back(AliasName.size() + 2);
+ if (!llvm::StringRef(OldNs).startswith(AliasNs))
+ continue;
+ }
+ std::string NameWithAliasNamespace =
+ (AliasName + "::" + FromDeclNameRef).str();
+ if (NameWithAliasNamespace.size() < ReplaceName.size())
+ ReplaceName = NameWithAliasNamespace;
+ }
+ }
// Checks if there is any using shadow declarations that can shorten the
// qualified name.
bool Matched = false;
diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.h b/clang-tools-extra/change-namespace/ChangeNamespace.h
index c8fb7a22355..5161591db37 100644
--- a/clang-tools-extra/change-namespace/ChangeNamespace.h
+++ b/clang-tools-extra/change-namespace/ChangeNamespace.h
@@ -154,6 +154,9 @@ private:
// Records all using namespace declarations, which can be used to shorten
// namespace specifiers.
llvm::SmallPtrSet<const UsingDirectiveDecl *, 8> UsingNamespaceDecls;
+ // Records all namespace alias declarations, which can be used to shorten
+ // namespace specifiers.
+ llvm::SmallPtrSet<const NamespaceAliasDecl *, 8> NamespaceAliasDecls;
// TypeLocs of CXXCtorInitializer. Types of CXXCtorInitializers do not need to
// be fixed.
llvm::SmallVector<TypeLoc, 8> BaseCtorInitializerTypeLocs;