diff options
7 files changed, 175 insertions, 2 deletions
diff --git a/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt b/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt index 9977241ddc7..58b35a47d50 100644 --- a/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt +++ b/clang-tools-extra/cpp11-migrate/Core/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(migrateCore Transforms.cpp Transform.cpp + IncludeExcludeInfo.cpp ) target_link_libraries(migrateCore clangTooling diff --git a/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.cpp b/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.cpp new file mode 100644 index 00000000000..cbea61230b8 --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.cpp @@ -0,0 +1,92 @@ +//===-- Core/IncludeExcludeInfo.cpp - IncludeExclude class impl -*- 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 implemention of the IncludeExcludeInfo class +/// to handle the include and exclude command line options. +/// +//===----------------------------------------------------------------------===// + +#include "IncludeExcludeInfo.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Path.h" + +using namespace llvm; + +namespace { +/// \brief Helper function to determine whether a file has the same path +/// prefix as \a Path. +/// +/// \a Path must be an absolute path. +bool fileHasPathPrefix(StringRef File, StringRef Path) { + // Converts File to its absolute path. + SmallString<64> AbsoluteFile = File; + sys::fs::make_absolute(AbsoluteFile); + + // Convert path strings to sys::path to iterate over each of its directories. + sys::path::const_iterator FileI = sys::path::begin(AbsoluteFile), + FileE = sys::path::end(AbsoluteFile), + PathI = sys::path::begin(Path), + PathE = sys::path::end(Path); + while (FileI != FileE && PathI != PathE) { + // If the strings aren't equal then the two paths aren't contained within + // each other. + if (!FileI->equals(*PathI)) + return false; + ++FileI; + ++PathI; + } + return true; +} + +/// \brief Helper function to parse a string of comma seperated paths into +/// the vector. +void parseCLInput(StringRef Line, std::vector<std::string> &List) { + SmallVector<StringRef, 32> Tokens; + Line.split(Tokens, ",", /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (SmallVectorImpl<StringRef>::iterator I = Tokens.begin(), + E = Tokens.end(); + I != E; ++I) { + // Convert each path to its absolute path. + SmallString<64> AbsolutePath = *I; + sys::fs::make_absolute(AbsolutePath); + List.push_back(std::string(AbsolutePath.str())); + } +} +} // end anonymous namespace + +IncludeExcludeInfo::IncludeExcludeInfo(StringRef Include, StringRef Exclude) { + parseCLInput(Include, IncludeList); + parseCLInput(Exclude, ExcludeList); +} + +bool IncludeExcludeInfo::isFileIncluded(StringRef FilePath) { + bool InIncludeList = false; + + for (std::vector<std::string>::iterator I = IncludeList.begin(), + E = IncludeList.end(); + I != E; ++I) + if ((InIncludeList = fileHasPathPrefix(FilePath, *I))) + break; + // If file is not in the list of included paths then it is not necessary + // to check the excluded path list. + if (!InIncludeList) + return false; + + for (std::vector<std::string>::iterator I = ExcludeList.begin(), + E = ExcludeList.end(); + I != E; ++I) + if (fileHasPathPrefix(FilePath, *I)) + return false; + + // If the file is in the included list but not in the excluded list, then + // it is safe to transform. + return true; +} diff --git a/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.h b/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.h new file mode 100644 index 00000000000..add9a9e09ec --- /dev/null +++ b/clang-tools-extra/cpp11-migrate/Core/IncludeExcludeInfo.h @@ -0,0 +1,39 @@ +//===-- Core/IncludeExcludeInfo.h - IncludeExclude class def'n --*- 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 for the IncludeExcludeInfo class +/// to handle the include and exclude command line options. +/// +//===----------------------------------------------------------------------===// +#ifndef LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H +#define LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H + +#include "llvm/ADT/StringRef.h" +#include <vector> + +/// \brief Class encapsulating the handling of include and exclude paths +/// provided by the user through command line options. +class IncludeExcludeInfo { +public: + /// \brief Determine if the given file is safe to transform. + /// + /// \a Include and \a Exclude must be formatted as a comma-seperated list. + IncludeExcludeInfo(llvm::StringRef Include, llvm::StringRef Exclude); + + /// \brief Determine if the given filepath is in the list of include paths but + /// not in the list of exclude paths. + bool isFileIncluded(llvm::StringRef FilePath); + +private: + std::vector<std::string> IncludeList; + std::vector<std::string> ExcludeList; +}; + +#endif // LLVM_TOOLS_CLANG_TOOLS_EXTRA_CPP11_MIGRATE_INCLUDEEXCLUDEINFO_H diff --git a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp index dc335e9e76f..5b0661a9380 100644 --- a/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp +++ b/clang-tools-extra/cpp11-migrate/tool/Cpp11Migrate.cpp @@ -50,6 +50,17 @@ static cl::opt<bool> SummaryMode("summary", cl::desc("Print transform summary"), cl::init(false)); +// TODO: Remove cl::Hidden when functionality for acknowledging include/exclude +// options are implemented in the tool. +static cl::opt<std::string> +IncludePaths("include", cl::Hidden, + cl::desc("Comma seperated list of filepaths to consider to be " + "transformed")); +static cl::opt<std::string> +ExcludePaths("exclude", cl::Hidden, + cl::desc("Comma seperated list of filepaths that can not " + "be transformed")); + class EndSyntaxArgumentsAdjuster : public ArgumentsAdjuster { CommandLineArguments Adjust(const CommandLineArguments &Args) { CommandLineArguments AdjustedArgs = Args; diff --git a/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt b/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt index 7756b6f9738..77b81585d65 100644 --- a/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt +++ b/clang-tools-extra/unittests/cpp11-migrate/CMakeLists.txt @@ -7,7 +7,8 @@ get_filename_component(CPP11_MIGRATE_SOURCE_DIR include_directories(${CPP11_MIGRATE_SOURCE_DIR}) add_extra_unittest(Cpp11MigrateTests - TransformTest.cpp) + TransformTest.cpp + IncludeExcludeTest.cpp) target_link_libraries(Cpp11MigrateTests migrateCore diff --git a/clang-tools-extra/unittests/cpp11-migrate/IncludeExcludeTest.cpp b/clang-tools-extra/unittests/cpp11-migrate/IncludeExcludeTest.cpp new file mode 100644 index 00000000000..a4b270b2ce2 --- /dev/null +++ b/clang-tools-extra/unittests/cpp11-migrate/IncludeExcludeTest.cpp @@ -0,0 +1,29 @@ +#include "Core/IncludeExcludeInfo.h" +#include "gtest/gtest.h" + +IncludeExcludeInfo IEManager(/*include=*/ "a,b/b2,c/c2/c3", + /*exclude=*/ "a/af.cpp,a/a2,b/b2/b2f.cpp,c/c2/c3"); + +TEST(IncludeExcludeTest, NoMatchOnIncludeList) { + // If the file does not appear on the include list then it is not safe to + // transform. Files are not safe to transform by default. + EXPECT_FALSE(IEManager.isFileIncluded("f.cpp")); + EXPECT_FALSE(IEManager.isFileIncluded("b/dir/f.cpp")); +} + +TEST(IncludeExcludeTest, MatchOnIncludeList) { + // If the file appears on only the include list then it is safe to transform. + EXPECT_TRUE(IEManager.isFileIncluded("a/f.cpp")); + EXPECT_TRUE(IEManager.isFileIncluded("a/dir/f.cpp")); + EXPECT_TRUE(IEManager.isFileIncluded("b/b2/f.cpp")); +} + +TEST(IncludeExcludeTest, MatchOnBothLists) { + // If the file appears on both the include or exclude list then it is not + // safe to transform. + EXPECT_FALSE(IEManager.isFileIncluded("a/af.cpp")); + EXPECT_FALSE(IEManager.isFileIncluded("a/a2/f.cpp")); + EXPECT_FALSE(IEManager.isFileIncluded("a/a2/dir/f.cpp")); + EXPECT_FALSE(IEManager.isFileIncluded("b/b2/b2f.cpp")); + EXPECT_FALSE(IEManager.isFileIncluded("c/c2/c3/f.cpp")); +} diff --git a/clang-tools-extra/unittests/cpp11-migrate/Makefile b/clang-tools-extra/unittests/cpp11-migrate/Makefile index 84fed3b4a82..4779c49cf34 100644 --- a/clang-tools-extra/unittests/cpp11-migrate/Makefile +++ b/clang-tools-extra/unittests/cpp11-migrate/Makefile @@ -16,7 +16,7 @@ USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \ clangRewriteFrontend.a clangRewriteCore.a clangParse.a \ clangSema.a clangAnalysis.a \ clangAST.a clangASTMatchers.a clangEdit.a clangLex.a clangBasic.a \ - migrateCore.a + migrateCore.a include $(CLANG_LEVEL)/Makefile MAKEFILE_UNITTEST_NO_INCLUDE_COMMON := 1 |