diff options
| author | Chandler Carruth <chandlerc@gmail.com> | 2013-09-04 17:35:07 +0000 |
|---|---|---|
| committer | Chandler Carruth <chandlerc@gmail.com> | 2013-09-04 17:35:07 +0000 |
| commit | d9063c46f59f4bec47bcbeddca8ca2f789348c03 (patch) | |
| tree | 76505542df7a05016dc71ffe44ed3ba264fb54be /clang-tools-extra/cpp11-migrate/UseAuto | |
| parent | 6a23d212897d5402035cfaea82260f6dae1c8f2a (diff) | |
| download | bcm5719-llvm-d9063c46f59f4bec47bcbeddca8ca2f789348c03.tar.gz bcm5719-llvm-d9063c46f59f4bec47bcbeddca8ca2f789348c03.zip | |
Rename cpp11-migrate to clang-modernize.
There is no reason to expect this tool to be limited to C++11, it seems
very likely to be of on-going interest. It seems likely to be useful for
modernizing even as new libraries come out in TSes and other formats
than a complete standard. Fundamentally, we need something a bit more
general. After some discussion on the list, going with
'clang-modernize'.
I've tried to do a reasonably comprehensive job of fixing up the names,
but I may still have missed some. Feel free to poke me if you spot any
fallout here. Things I've tried reasonably hard to find and fix:
- cpp11-migrate -> clang-modernize
- Migrator -> Modernizer
- Clean up the introductory documentation that was C++11 specific.
I'll also point out that this tool continues to delight me. =] Also,
a huge thanks to those who have so carefully, thoroughly documented the
tool. The docs here are simply phenomenal. Every tool should be this
well documented. I hope I have updated the documentation reasonably
well, but I'm not very good at documentation, so review much
appreciated.
llvm-svn: 189960
Diffstat (limited to 'clang-tools-extra/cpp11-migrate/UseAuto')
6 files changed, 0 insertions, 630 deletions
diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp deleted file mode 100644 index 72f5ae077f2..00000000000 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//===-- UseAuto/UseAuto.cpp - Use auto type specifier ---------------------===// -// -// 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 the implementation of the UseAutoTransform class. -/// -//===----------------------------------------------------------------------===// - -#include "UseAuto.h" -#include "UseAutoActions.h" -#include "UseAutoMatchers.h" - -using clang::ast_matchers::MatchFinder; -using namespace clang; -using namespace clang::tooling; - -int UseAutoTransform::apply(const FileOverrides &InputStates, - const clang::tooling::CompilationDatabase &Database, - const std::vector<std::string> &SourcePaths) { - ClangTool UseAutoTool(Database, SourcePaths); - - unsigned AcceptedChanges = 0; - - MatchFinder Finder; - ReplacementsVec Replaces; - IteratorReplacer ReplaceIterators(AcceptedChanges, Options().MaxRiskLevel, - /*Owner=*/ *this); - NewReplacer ReplaceNew(AcceptedChanges, Options().MaxRiskLevel, - /*Owner=*/ *this); - - Finder.addMatcher(makeIteratorDeclMatcher(), &ReplaceIterators); - Finder.addMatcher(makeDeclWithNewMatcher(), &ReplaceNew); - - setOverrides(InputStates); - - if (int Result = UseAutoTool.run(createActionFactory(Finder))) { - llvm::errs() << "Error encountered during translation.\n"; - return Result; - } - - setAcceptedChanges(AcceptedChanges); - - return 0; -} - -struct UseAutoFactory : TransformFactory { - UseAutoFactory() { - Since.Clang = Version(2, 9); - Since.Gcc = Version(4, 4); - Since.Icc = Version(12); - Since.Msvc = Version(10); - } - - Transform *createTransform(const TransformOptions &Opts) LLVM_OVERRIDE { - return new UseAutoTransform(Opts); - } -}; - -// Register the factory using this statically initialized variable. -static TransformFactoryRegistry::Add<UseAutoFactory> -X("use-auto", "Use of 'auto' type specifier"); - -// This anchor is used to force the linker to link in the generated object file -// and thus register the factory. -volatile int UseAutoTransformAnchorSource = 0; diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h b/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h deleted file mode 100644 index 26b5e4496f6..00000000000 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAuto.h +++ /dev/null @@ -1,42 +0,0 @@ -//===-- UseAuto/UseAuto.h - Use auto type specifier -------------*- 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 the definition of the UseAutoTransform class -/// which is the main interface to the use-auto transform that replaces -/// type specifiers with the special C++11 'auto' type specifier in certain -/// situations. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_USE_AUTO_H -#define CPP11_MIGRATE_USE_AUTO_H - -#include "Core/Transform.h" -#include "llvm/Support/Compiler.h" - -/// \brief Subclass of Transform that transforms type specifiers for variable -/// declarations into the special C++11 'auto' type specifier for certain cases: -/// * Iterators of std containers. -/// * More to come... -/// -/// Other uses of the auto type specifier as outlined in C++11 [dcl.spec.auto] -/// p2 are not handled by this transform. -class UseAutoTransform : public Transform { -public: - UseAutoTransform(const TransformOptions &Options) - : Transform("UseAuto", Options) {} - - /// \see Transform::run(). - virtual int apply(const FileOverrides &InputStates, - const clang::tooling::CompilationDatabase &Database, - const std::vector<std::string> &SourcePaths) LLVM_OVERRIDE; -}; - -#endif // CPP11_MIGRATE_USE_AUTO_H diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp deleted file mode 100644 index 2a8d5c5935d..00000000000 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.cpp +++ /dev/null @@ -1,147 +0,0 @@ -//===-- UseAuto/UseAutoActions.cpp - Matcher callback impl ----------------===// -// -// 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 contains the implementation of callbacks for the UseAuto -/// transform. -/// -//===----------------------------------------------------------------------===// - -#include "UseAutoActions.h" -#include "UseAutoMatchers.h" -#include "clang/AST/ASTContext.h" - -using namespace clang::ast_matchers; -using namespace clang::tooling; -using namespace clang; - -void IteratorReplacer::run(const MatchFinder::MatchResult &Result) { - const DeclStmt *D = Result.Nodes.getNodeAs<DeclStmt>(IteratorDeclStmtId); - assert(D && "Bad Callback. No node provided"); - - SourceManager &SM = *Result.SourceManager; - if (!Owner.isFileModifiable(SM, D->getLocStart())) - return; - - for (clang::DeclStmt::const_decl_iterator DI = D->decl_begin(), - DE = D->decl_end(); - DI != DE; ++DI) { - const VarDecl *V = cast<VarDecl>(*DI); - - const Expr *ExprInit = V->getInit(); - - // Skip expressions with cleanups from the initializer expression. - if (const ExprWithCleanups *E = dyn_cast<ExprWithCleanups>(ExprInit)) - ExprInit = E->getSubExpr(); - - const CXXConstructExpr *Construct = cast<CXXConstructExpr>(ExprInit); - - assert(Construct->getNumArgs() == 1u && - "Expected constructor with single argument"); - - // Drill down to the as-written initializer. - const Expr *E = Construct->arg_begin()->IgnoreParenImpCasts(); - if (E != E->IgnoreConversionOperator()) - // We hit a conversion operator. Early-out now as they imply an implicit - // conversion from a different type. Could also mean an explicit - // conversion from the same type but that's pretty rare. - return; - - if (const CXXConstructExpr *NestedConstruct = dyn_cast<CXXConstructExpr>(E)) - // If we ran into an implicit conversion constructor, can't convert. - // - // FIXME: The following only checks if the constructor can be used - // implicitly, not if it actually was. Cases where the converting - // constructor was used explicitly won't get converted. - if (NestedConstruct->getConstructor()->isConvertingConstructor(false)) - return; - if (!Result.Context->hasSameType(V->getType(), E->getType())) - return; - } - // Get the type location using the first declartion. - const VarDecl *V = cast<VarDecl>(*D->decl_begin()); - TypeLoc TL = V->getTypeSourceInfo()->getTypeLoc(); - - // WARNING: TypeLoc::getSourceRange() will include the identifier for things - // like function pointers. Not a concern since this action only works with - // iterators but something to keep in mind in the future. - - CharSourceRange Range(TL.getSourceRange(), true); - Owner.addReplacementForCurrentTU(tooling::Replacement(SM, Range, "auto")); - ++AcceptedChanges; -} - -void NewReplacer::run(const MatchFinder::MatchResult &Result) { - const DeclStmt *D = Result.Nodes.getNodeAs<DeclStmt>(DeclWithNewId); - assert(D && "Bad Callback. No node provided"); - - SourceManager &SM = *Result.SourceManager; - if (!Owner.isFileModifiable(SM, D->getLocStart())) - return; - - const VarDecl *FirstDecl = cast<VarDecl>(*D->decl_begin()); - // Ensure that there is at least one VarDecl within de DeclStmt. - assert(FirstDecl && "No VarDecl provided"); - - const QualType FirstDeclType = FirstDecl->getType().getCanonicalType(); - - std::vector<SourceLocation> StarLocations; - for (clang::DeclStmt::const_decl_iterator DI = D->decl_begin(), - DE = D->decl_end(); - DI != DE; ++DI) { - - const VarDecl *V = cast<VarDecl>(*DI); - // Ensure that every DeclStmt child is a VarDecl. - assert(V && "No VarDecl provided"); - - const CXXNewExpr *NewExpr = - cast<CXXNewExpr>(V->getInit()->IgnoreParenImpCasts()); - // Ensure that every VarDecl has a CXXNewExpr initializer. - assert(NewExpr && "No CXXNewExpr provided"); - - // If VarDecl and Initializer have mismatching unqualified types. - if (!Result.Context->hasSameUnqualifiedType(V->getType(), - NewExpr->getType())) - return; - - // Remove explicitly written '*' from declarations where there's more than - // one declaration in the declaration list. - if (DI == D->decl_begin()) - continue; - - // All subsequent delcarations should match the same non-decorated type. - if (FirstDeclType != V->getType().getCanonicalType()) - return; - - PointerTypeLoc Q = - V->getTypeSourceInfo()->getTypeLoc().getAs<PointerTypeLoc>(); - while (!Q.isNull()) { - StarLocations.push_back(Q.getStarLoc()); - Q = Q.getNextTypeLoc().getAs<PointerTypeLoc>(); - } - } - - // Remove '*' from declarations using the saved star locations. - for (std::vector<SourceLocation>::iterator I = StarLocations.begin(), - E = StarLocations.end(); - I != E; ++I) { - Owner.addReplacementForCurrentTU(tooling::Replacement(SM, *I, 1, "")); - } - - // FIXME: There is, however, one case we can address: when the VarDecl - // pointee is the same as the initializer, just more CV-qualified. However, - // TypeLoc information is not reliable where CV qualifiers are concerned so - // we can't do anything about this case for now. - CharSourceRange Range( - FirstDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange(), true); - // Space after 'auto' to handle cases where the '*' in the pointer type - // is next to the identifier. This avoids changing 'int *p' into 'autop'. - Owner.addReplacementForCurrentTU(tooling::Replacement(SM, Range, "auto ")); - ++AcceptedChanges; -} diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h deleted file mode 100644 index 0ddb0e0c5af..00000000000 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoActions.h +++ /dev/null @@ -1,56 +0,0 @@ -//===-- UseAuto/Actions.h - Matcher callback --------------------*- 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 contains the declarations for callbacks used by the -/// UseAuto transform. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_USE_AUTO_ACTIONS_H -#define CPP11_MIGRATE_USE_AUTO_ACTIONS_H - -#include "Core/Transform.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Tooling/Refactoring.h" - -/// \brief The callback to be used when replacing type specifiers of variable -/// declarations that are iterators. -class IteratorReplacer - : public clang::ast_matchers::MatchFinder::MatchCallback { -public: - IteratorReplacer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner) - : AcceptedChanges(AcceptedChanges), Owner(Owner) {} - - /// \brief Entry point to the callback called when matches are made. - virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result) - LLVM_OVERRIDE; - -private: - unsigned &AcceptedChanges; - Transform &Owner; -}; - -/// \brief The callback used when replacing type specifiers of variable -/// declarations initialized by a C++ new expression. -class NewReplacer : public clang::ast_matchers::MatchFinder::MatchCallback { -public: - NewReplacer(unsigned &AcceptedChanges, RiskLevel, Transform &Owner) - : AcceptedChanges(AcceptedChanges), Owner(Owner) {} - - /// \brief Entry point to the callback called when matches are made. - virtual void run(const clang::ast_matchers::MatchFinder::MatchResult &Result) - LLVM_OVERRIDE; - -private: - unsigned &AcceptedChanges; - Transform &Owner; -}; - -#endif // CPP11_MIGRATE_USE_AUTO_ACTIONS_H diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp deleted file mode 100644 index 4f314adb2e3..00000000000 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.cpp +++ /dev/null @@ -1,280 +0,0 @@ -//===-- UseAutoMatchers.cpp - Matchers for use-auto transform -------------===// -// -// 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 contains the implementation for matcher-generating -/// functions and custom AST_MATCHERs. -/// -//===----------------------------------------------------------------------===// - -#include "UseAutoMatchers.h" -#include "Core/CustomMatchers.h" -#include "clang/AST/ASTContext.h" - -using namespace clang::ast_matchers; -using namespace clang; - -const char *IteratorDeclStmtId = "iterator_decl"; -const char *DeclWithNewId = "decl_new"; -const char *NewExprId = "new_expr"; - -namespace clang { -namespace ast_matchers { - -/// \brief Matches variable declarations that have explicit initializers that -/// are not initializer lists. -/// -/// Given -/// \code -/// iterator I = Container.begin(); -/// MyType A(42); -/// MyType B{2}; -/// MyType C; -/// \endcode -/// varDecl(hasWrittenNonListInitializer()) matches \c I and \c A but not \c B -/// or \c C. -AST_MATCHER(VarDecl, hasWrittenNonListInitializer) { - const Expr *Init = Node.getAnyInitializer(); - if (!Init) - return false; - - // The following test is based on DeclPrinter::VisitVarDecl() to find if an - // initializer is implicit or not. - bool ImplicitInit = false; - if (const CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) { - if (Construct->isListInitialization()) - return false; - ImplicitInit = Construct->getNumArgs() == 0 || - Construct->getArg(0)->isDefaultArgument(); - } else - if (Node.getInitStyle() == VarDecl::ListInit) - return false; - - return !ImplicitInit; -} - -/// \brief Matches QualTypes that are type sugar for QualTypes that match \c -/// SugarMatcher. -/// -/// Given -/// \code -/// class C {}; -/// typedef C my_type -/// typedef my_type my_other_type; -/// \endcode -/// -/// \c qualType(isSugarFor(recordType(hasDeclaration(namedDecl(hasName("C")))))) -/// matches \c my_type and \c my_other_type. -AST_MATCHER_P(QualType, isSugarFor, internal::Matcher<QualType>, SugarMatcher) { - QualType QT = Node; - for (;;) { - if (SugarMatcher.matches(QT, Finder, Builder)) - return true; - - QualType NewQT = QT.getSingleStepDesugaredType(Finder->getASTContext()); - if (NewQT == QT) - break; - QT = NewQT; - } - return false; -} - -/// \brief Matches named declarations that have one of the standard iterator -/// names: iterator, reverse_iterator, const_iterator, const_reverse_iterator. -/// -/// Given -/// \code -/// iterator I; -/// const_iterator CI; -/// \endcode -/// -/// \c namedDecl(hasStdIteratorName()) matches \c I and \c CI. -AST_MATCHER(NamedDecl, hasStdIteratorName) { - static const char *IteratorNames[] = { - "iterator", - "reverse_iterator", - "const_iterator", - "const_reverse_iterator" - }; - - for (unsigned int i = 0; - i < llvm::array_lengthof(IteratorNames); - ++i) { - if (hasName(IteratorNames[i]).matches(Node, Finder, Builder)) - return true; - } - return false; -} - -/// \brief Matches named declarations that have one of the standard container -/// names. -/// -/// Given -/// \code -/// class vector {}; -/// class forward_list {}; -/// class my_vec {}; -/// \endcode -/// -/// \c recordDecl(hasStdContainerName()) matches \c vector and \c forward_list -/// but not \c my_vec. -AST_MATCHER(NamedDecl, hasStdContainerName) { - static const char *ContainerNames[] = { - "array", - "deque", - "forward_list", - "list", - "vector", - - "map", - "multimap", - "set", - "multiset", - - "unordered_map", - "unordered_multimap", - "unordered_set", - "unordered_multiset", - - "queue", - "priority_queue", - "stack" - }; - - for (unsigned int i = 0; i < llvm::array_lengthof(ContainerNames); ++i) { - if (hasName(ContainerNames[i]).matches(Node, Finder, Builder)) - return true; - } - return false; -} - -} // namespace ast_matchers -} // namespace clang - -namespace { -// \brief Returns a TypeMatcher that matches typedefs for standard iterators -// inside records with a standard container name. -TypeMatcher typedefIterator() { - return typedefType( - hasDeclaration( - allOf( - namedDecl(hasStdIteratorName()), - hasDeclContext( - recordDecl(hasStdContainerName(), isFromStdNamespace()) - ) - ) - ) - ); -} - -// \brief Returns a TypeMatcher that matches records named for standard -// iterators nested inside records named for standard containers. -TypeMatcher nestedIterator() { - return recordType( - hasDeclaration( - allOf( - namedDecl(hasStdIteratorName()), - hasDeclContext( - recordDecl(hasStdContainerName(), isFromStdNamespace()) - ) - ) - ) - ); -} - -// \brief Returns a TypeMatcher that matches types declared with using -// declarations and which name standard iterators for standard containers. -TypeMatcher iteratorFromUsingDeclaration() { - // Types resulting from using declarations are - // represented by ElaboratedType. - return elaboratedType( - allOf( - // Unwrap the nested name specifier to test for - // one of the standard containers. - hasQualifier( - specifiesType( - templateSpecializationType( - hasDeclaration( - namedDecl(hasStdContainerName(), isFromStdNamespace()) - ) - ) - ) - ), - // The named type is what comes after the final - // '::' in the type. It should name one of the - // standard iterator names. - namesType(anyOf( - typedefType( - hasDeclaration( - namedDecl(hasStdIteratorName()) - ) - ), - recordType( - hasDeclaration( - namedDecl(hasStdIteratorName()) - ) - ) - )) - ) - ); -} -} // namespace - -// \brief This matcher returns delaration statements that contain variable -// declarations with written non-list initializer for standard iterators. -StatementMatcher makeIteratorDeclMatcher() { - return declStmt( - // At least one varDecl should be a child of the declStmt to ensure it's a - // declaration list and avoid matching other declarations - // e.g. using directives. - has(varDecl()), - unless(has(varDecl( - anyOf( - unless(hasWrittenNonListInitializer()), - hasType(autoType()), - unless(hasType( - isSugarFor( - anyOf( - typedefIterator(), - nestedIterator(), - iteratorFromUsingDeclaration() - ) - ) - )) - ) - ))) - ).bind(IteratorDeclStmtId); -} - -StatementMatcher makeDeclWithNewMatcher() { - return declStmt( - has(varDecl()), - unless(has(varDecl( - anyOf( - unless(hasInitializer( - ignoringParenImpCasts(newExpr()) - )), - // FIXME: TypeLoc information is not reliable where CV qualifiers are - // concerned so these types can't be handled for now. - hasType(pointerType(pointee(hasCanonicalType(hasLocalQualifiers())))), - - // FIXME: Handle function pointers. For now we ignore them because - // the replacement replaces the entire type specifier source range - // which includes the identifier. - hasType( - pointsTo( - pointsTo( - parenType(innerType(functionType())) - ) - ) - ) - ) - ))) - ).bind(DeclWithNewId); -} diff --git a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.h b/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.h deleted file mode 100644 index 37baceee047..00000000000 --- a/clang-tools-extra/cpp11-migrate/UseAuto/UseAutoMatchers.h +++ /dev/null @@ -1,34 +0,0 @@ -//===-- UseAutoMatchers.h - Matchers for use-auto transform -----*- 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 contains the declarations for matcher-generating functions -/// and names for bound nodes found by AST matchers. -/// -//===----------------------------------------------------------------------===// - -#ifndef CPP11_MIGRATE_USE_AUTO_MATCHERS_H -#define CPP11_MIGRATE_USE_AUTO_MATCHERS_H - -#include "clang/ASTMatchers/ASTMatchers.h" - -extern const char *IteratorDeclStmtId; -extern const char *DeclWithNewId; -extern const char *NewExprId; - -/// \brief Create a matcher that matches declaration staments that have -/// variable declarations where the type is an iterator for an std container -/// and has an explicit initializer of the same type. -clang::ast_matchers::StatementMatcher makeIteratorDeclMatcher(); - -/// \brief Create a matcher that matches variable declarations that are -/// initialized by a C++ new expression. -clang::ast_matchers::StatementMatcher makeDeclWithNewMatcher(); - -#endif // CPP11_MIGRATE_USE_AUTO_MATCHERS_H |

