From 601858aed76429a0ddf2324b05946d13e59a6471 Mon Sep 17 00:00:00 2001 From: "Ariel J. Bernal" Date: Mon, 15 Jul 2013 15:37:05 +0000 Subject: [PATCH] Fix UseAuto not transforming iterator when non-fully qualifiers are used and using inline namespaces is specified. UseAuto used to fail to transform iterators when using inline namespaces and non-fully qualified types, relying on a using directive previously declared. - This fix uses the already define isFromStdNamespace matcher. - Fixed tests and added a new test using inline namespaces. - Added CustomMatchers to reuse common matchers among transforms. llvm-svn: 186327 --- .../cpp11-migrate/Core/CustomMatchers.h | 59 ++++++++++++++++++++++ .../ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp | 34 +------------ .../cpp11-migrate/UseAuto/UseAutoMatchers.cpp | 25 ++++----- .../UseAuto/Inputs/test_std_container.h | 3 +- .../cpp11-migrate/UseAuto/basic_iterator_tests.cpp | 6 +-- .../test/cpp11-migrate/UseAuto/iterator.cpp | 6 +++ 6 files changed, 79 insertions(+), 54 deletions(-) create mode 100644 clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h diff --git a/clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h b/clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h new file mode 100644 index 0000000..9af0497 --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/CustomMatchers.h @@ -0,0 +1,59 @@ +//===-- Core/CustomMatchers.h - Perf measurement helpers -----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file provides custom matchers to be used by different +/// transforms that requier the same matchers. +/// +//===----------------------------------------------------------------------===// + +#ifndef CPP11_MIGRATE_CUSTOMMATCHERS_H +#define CPP11_MIGRATE_CUSTOMMATCHERS_H + +#include "clang/ASTMatchers/ASTMatchers.h" + +namespace clang { +namespace ast_matchers { + +/// \brief Matches declarations whose declaration context is the C++ standard +/// library namespace \c std. +/// +/// Note that inline namespaces are silently ignored during the lookup since +/// both libstdc++ and libc++ are known to use them for versioning purposes. +/// +/// Given +/// \code +/// namespace ns { +/// struct my_type {}; +/// using namespace std; +/// } +/// +/// using std::vector; +/// using ns::my_type; +/// using ns::list; +/// \endcode +/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(isFromStdNamespace()))) +/// matches "using std::vector" and "using ns::list". +AST_MATCHER(Decl, isFromStdNamespace) { + const DeclContext *D = Node.getDeclContext(); + + while (D->isInlineNamespace()) + D = D->getParent(); + + if (!D->isNamespace() || !D->getParent()->isTranslationUnit()) + return false; + + const IdentifierInfo *Info = cast(D)->getIdentifier(); + + return Info && Info->isStr("std"); +} +} // namespace ast_matchers +} // namespace clang + +#endif // CPP11_MIGRATE_CUSTOMMATCHERS_H diff --git a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp index 1115229..e03a2c3 100644 --- a/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp +++ b/clang-tools-extra/cpp11-migrate/ReplaceAutoPtr/ReplaceAutoPtrMatchers.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "ReplaceAutoPtrMatchers.h" +#include "Core/CustomMatchers.h" const char *AutoPtrTokenId = "AutoPtrTokenId"; const char *AutoPtrOwnershipTransferId = "AutoPtrOwnershipTransferId"; @@ -34,39 +35,6 @@ AST_MATCHER(Expr, isLValue) { return Node.getValueKind() == VK_LValue; } -/// \brief Matches declarations whose declaration context is the C++ standard -/// library namespace \c std. -/// -/// Note that inline namespaces are silently ignored during the lookup since -/// both libstdc++ and libc++ are known to use them for versioning purposes. -/// -/// Given -/// \code -/// namespace ns { -/// struct my_type {}; -/// using namespace std; -/// } -/// -/// using std::vector; -/// using ns::my_type; -/// using ns::list; -/// \endcode -/// usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(isFromStdNamespace()))) -/// matches "using std::vector" and "using ns::list". -AST_MATCHER(Decl, isFromStdNamespace) { - const DeclContext *D = Node.getDeclContext(); - - while (D->isInlineNamespace()) - D = D->getParent(); - - if (!D->isNamespace() || !D->getParent()->isTranslationUnit()) - return false; - - const IdentifierInfo *Info = cast(D)->getIdentifier(); - - return Info && Info->isStr("std"); -} - } // end namespace ast_matchers } // end namespace clang diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp index a4ada5a..4f314ad 100644 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp +++ b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "UseAutoMatchers.h" +#include "Core/CustomMatchers.h" #include "clang/AST/ASTContext.h" using namespace clang::ast_matchers; @@ -123,7 +124,7 @@ AST_MATCHER(NamedDecl, hasStdIteratorName) { /// /// \c recordDecl(hasStdContainerName()) matches \c vector and \c forward_list /// but not \c my_vec. -AST_MATCHER_P(NamedDecl, hasStdContainerName, bool, WithStd) { +AST_MATCHER(NamedDecl, hasStdContainerName) { static const char *ContainerNames[] = { "array", "deque", @@ -146,13 +147,8 @@ AST_MATCHER_P(NamedDecl, hasStdContainerName, bool, WithStd) { "stack" }; - for (unsigned int i = 0; - i < llvm::array_lengthof(ContainerNames); - ++i) { - std::string Name(ContainerNames[i]); - if (WithStd) - Name = "std::" + Name; - if (hasName(Name).matches(Node, Finder, Builder)) + for (unsigned int i = 0; i < llvm::array_lengthof(ContainerNames); ++i) { + if (hasName(ContainerNames[i]).matches(Node, Finder, Builder)) return true; } return false; @@ -170,7 +166,7 @@ TypeMatcher typedefIterator() { allOf( namedDecl(hasStdIteratorName()), hasDeclContext( - recordDecl(hasStdContainerName(true)) + recordDecl(hasStdContainerName(), isFromStdNamespace()) ) ) ) @@ -185,7 +181,7 @@ TypeMatcher nestedIterator() { allOf( namedDecl(hasStdIteratorName()), hasDeclContext( - recordDecl(hasStdContainerName(true)) + recordDecl(hasStdContainerName(), isFromStdNamespace()) ) ) ) @@ -201,18 +197,15 @@ TypeMatcher iteratorFromUsingDeclaration() { allOf( // Unwrap the nested name specifier to test for // one of the standard containers. - hasQualifier(allOf( + hasQualifier( specifiesType( templateSpecializationType( hasDeclaration( - namedDecl(hasStdContainerName(false)) + namedDecl(hasStdContainerName(), isFromStdNamespace()) ) ) - ), - hasPrefix( - specifiesNamespace(hasName("std")) ) - )), + ), // The named type is what comes after the final // '::' in the type. It should name one of the // standard iterator names. diff --git a/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h b/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h index a856c45..5c92f6e 100644 --- a/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h +++ b/clang-tools-extra/test/cpp11-migrate/UseAuto/Inputs/test_std_container.h @@ -64,7 +64,7 @@ public: namespace std { #if USE_INLINE_NAMESPACE -namespace _1 { +inline namespace _1 { #endif template @@ -114,7 +114,6 @@ public: #if USE_INLINE_NAMESPACE } // namespace _1 -using _1::CONTAINER; #endif } // namespace std diff --git a/clang-tools-extra/test/cpp11-migrate/UseAuto/basic_iterator_tests.cpp b/clang-tools-extra/test/cpp11-migrate/UseAuto/basic_iterator_tests.cpp index 03779a6..30199e9 100644 --- a/clang-tools-extra/test/cpp11-migrate/UseAuto/basic_iterator_tests.cpp +++ b/clang-tools-extra/test/cpp11-migrate/UseAuto/basic_iterator_tests.cpp @@ -15,17 +15,17 @@ // // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp // RUN: cpp11-migrate -use-auto %t.cpp -- -DCONTAINER=array \ -// RUN: -DUSE_INLINE_NAMESPACE -I %S/Inputs +// RUN: -DUSE_INLINE_NAMESPACE=1 -I %S/Inputs // RUN: FileCheck -input-file=%t.cpp %s // // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp // RUN: cpp11-migrate -use-auto %t.cpp -- -DCONTAINER=array \ -// RUN: -DUSE_BASE_CLASS_ITERATORS -I %S/Inputs +// RUN: -DUSE_BASE_CLASS_ITERATORS=1 -I %S/Inputs // RUN: FileCheck -input-file=%t.cpp %s // // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp // RUN: cpp11-migrate -use-auto %t.cpp -- -DCONTAINER=array \ -// RUN: -DUSE_INNER_CLASS_ITERATORS -I %S/Inputs +// RUN: -DUSE_INNER_CLASS_ITERATORS=1 -I %S/Inputs // RUN: FileCheck -input-file=%t.cpp %s // // diff --git a/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp b/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp index 7c4b5aa..8871bc1 100644 --- a/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp +++ b/clang-tools-extra/test/cpp11-migrate/UseAuto/iterator.cpp @@ -1,6 +1,12 @@ // RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp // RUN: cpp11-migrate -use-auto %t.cpp -- --std=c++11 -I %S/Inputs // RUN: FileCheck -input-file=%t.cpp %s +// +// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp +// RUN: cpp11-migrate -use-auto %t.cpp -- --std=c++11 -I %S/Inputs \ +// RUN: -DUSE_INLINE_NAMESPACE=1 +// RUN: FileCheck -input-file=%t.cpp %s + #define CONTAINER array #include "test_std_container.h" -- 2.7.4