diff options
author | Eric Liu <ioeric@google.com> | 2016-12-07 17:04:07 +0000 |
---|---|---|
committer | Eric Liu <ioeric@google.com> | 2016-12-07 17:04:07 +0000 |
commit | 211d52f9f1e2a0eeaf924eb2480b4612a8bb2859 (patch) | |
tree | 70ec36eb344eb6f438a5d445c57ae26dca03963b /clang-tools-extra/change-namespace | |
parent | 57e03c8e8c483af2346b4a69e73934e7ad8b8206 (diff) |
[change-namespace] don't fix using shadow decls in classes.
Summary:
Using shadow declarations in classes always refers to base class, which does not
need to be fixed/qualified since it can be inferred from inheritance.
Reviewers: bkramer
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D27523
Diffstat (limited to 'clang-tools-extra/change-namespace')
-rw-r--r-- | clang-tools-extra/change-namespace/ChangeNamespace.cpp | 34 |
1 files changed, 24 insertions, 10 deletions
diff --git a/clang-tools-extra/change-namespace/ChangeNamespace.cpp b/clang-tools-extra/change-namespace/ChangeNamespace.cpp index a18ad9b109c..45064ebeeb7 100644 --- a/clang-tools-extra/change-namespace/ChangeNamespace.cpp +++ b/clang-tools-extra/change-namespace/ChangeNamespace.cpp @@ -327,6 +327,12 @@ void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) { hasAncestor(cxxRecordDecl()), allOf(IsInMovedNs, unless(cxxRecordDecl(unless(isDefinition()))))))); + // Using shadow declarations in classes always refers to base class, which + // does not need to be qualified since it can be inferred from inheritance. + // Note that this does not match using alias declarations. + auto UsingShadowDeclInClass = + usingDecl(hasAnyUsingShadowDecl(decl()), hasParent(cxxRecordDecl())); + // Match TypeLocs on the declaration. Carefully match only the outermost // TypeLoc and template specialization arguments (which are not outermost) // that are directly linked to types matching `DeclMatcher`. Nested name @@ -337,28 +343,36 @@ void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) { unless(anyOf(hasParent(typeLoc(loc(qualType( allOf(hasDeclaration(DeclMatcher), unless(templateSpecializationType())))))), - hasParent(nestedNameSpecifierLoc()))), + hasParent(nestedNameSpecifierLoc()), + hasAncestor(isImplicit()), + hasAncestor(UsingShadowDeclInClass))), hasAncestor(decl().bind("dc"))) .bind("type"), this); // Types in `UsingShadowDecl` is not matched by `typeLoc` above, so we need to // special case it. - Finder->addMatcher(usingDecl(IsInMovedNs, hasAnyUsingShadowDecl(decl())) + // Since using declarations inside classes must have the base class in the + // nested name specifier, we leave it to the nested name specifier matcher. + Finder->addMatcher(usingDecl(IsInMovedNs, hasAnyUsingShadowDecl(decl()), + unless(UsingShadowDeclInClass)) .bind("using_with_shadow"), this); // Handle types in nested name specifier. Specifiers that are in a TypeLoc // matched above are not matched, e.g. "A::" in "A::A" is not matched since // "A::A" would have already been fixed. - Finder->addMatcher(nestedNameSpecifierLoc( - hasAncestor(decl(IsInMovedNs).bind("dc")), - loc(nestedNameSpecifier(specifiesType( - hasDeclaration(DeclMatcher.bind("from_decl"))))), - unless(hasAncestor(typeLoc(loc(qualType(hasDeclaration( - decl(equalsBoundNode("from_decl"))))))))) - .bind("nested_specifier_loc"), - this); + Finder->addMatcher( + nestedNameSpecifierLoc( + hasAncestor(decl(IsInMovedNs).bind("dc")), + loc(nestedNameSpecifier( + specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"))))), + unless(anyOf(hasAncestor(isImplicit()), + hasAncestor(UsingShadowDeclInClass), + hasAncestor(typeLoc(loc(qualType(hasDeclaration( + decl(equalsBoundNode("from_decl")))))))))) + .bind("nested_specifier_loc"), + this); // Matches base class initializers in constructors. TypeLocs of base class // initializers do not need to be fixed. For example, |