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
This commit is contained in:
parent
eaa534450c
commit
601858aed7
|
@ -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<NamespaceDecl>(D)->getIdentifier();
|
||||
|
||||
return Info && Info->isStr("std");
|
||||
}
|
||||
} // namespace ast_matchers
|
||||
} // namespace clang
|
||||
|
||||
#endif // CPP11_MIGRATE_CUSTOMMATCHERS_H
|
|
@ -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<NamespaceDecl>(D)->getIdentifier();
|
||||
|
||||
return Info && Info->isStr("std");
|
||||
}
|
||||
|
||||
} // end namespace ast_matchers
|
||||
} // end namespace clang
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -64,7 +64,7 @@ public:
|
|||
namespace std {
|
||||
|
||||
#if USE_INLINE_NAMESPACE
|
||||
namespace _1 {
|
||||
inline namespace _1 {
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
|
@ -114,7 +114,6 @@ public:
|
|||
|
||||
#if USE_INLINE_NAMESPACE
|
||||
} // namespace _1
|
||||
using _1::CONTAINER;
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
|
|
|
@ -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
|
||||
//
|
||||
//
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue