diff options
author | Eric Liu <ioeric@google.com> | 2016-12-23 10:47:09 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-12-23 10:47:09 +0000 |
commit | 940e1201ff007486ca00035dcc6d455f6fa47adc (patch) | |
tree | d37c1b55e0859b064922739f88a851272a5ff1bd /clang-tools-extra/change-namespace | |
parent | 9f8d3dd45c2db6f0306b921f88046f524f829b10 (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.cpp | 41 | ||||
-rw-r--r-- | clang-tools-extra/change-namespace/ChangeNamespace.h | 3 |
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; |