Transform files in a compilation database if no sources are provided.
Compile all files in a compilation database or a subset determined by a sub-directory so you don't have to specify them manually. llvm-svn: 190630
This commit is contained in:
parent
4ff19b3c87
commit
583d095fa4
|
|
@ -157,13 +157,17 @@ bool IncludeExcludeInfo::isFileIncluded(StringRef FilePath) const {
|
||||||
if (!InIncludeList)
|
if (!InIncludeList)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// If the file is in the included list but not is not explicitly excluded,
|
||||||
|
// then it is safe to transform.
|
||||||
|
return !isFileExplicitlyExcluded(FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IncludeExcludeInfo::isFileExplicitlyExcluded(StringRef FilePath) const {
|
||||||
for (std::vector<std::string>::const_iterator I = ExcludeList.begin(),
|
for (std::vector<std::string>::const_iterator I = ExcludeList.begin(),
|
||||||
E = ExcludeList.end();
|
E = ExcludeList.end();
|
||||||
I != E; ++I)
|
I != E; ++I)
|
||||||
if (fileHasPathPrefix(FilePath, *I))
|
if (fileHasPathPrefix(FilePath, *I))
|
||||||
return false;
|
return true;
|
||||||
|
|
||||||
// If the file is in the included list but not in the excluded list, then
|
return false;
|
||||||
// it is safe to transform.
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,12 @@ public:
|
||||||
/// operators were removed.
|
/// operators were removed.
|
||||||
bool isFileIncluded(llvm::StringRef FilePath) const;
|
bool isFileIncluded(llvm::StringRef FilePath) const;
|
||||||
|
|
||||||
|
/// \brief Determine if a file path was explicitly excluded.
|
||||||
|
bool isFileExplicitlyExcluded(llvm::StringRef FilePath) const;
|
||||||
|
|
||||||
|
/// \brief Determine if a list of include paths was provided.
|
||||||
|
bool isIncludeListEmpty() const { return IncludeList.empty(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string> IncludeList;
|
std::vector<std::string> IncludeList;
|
||||||
std::vector<std::string> ExcludeList;
|
std::vector<std::string> ExcludeList;
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ bool Transform::isFileModifiable(const SourceManager &SM,
|
||||||
if (!FE)
|
if (!FE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return GlobalOptions.ModifiableHeaders.isFileIncluded(FE->getName());
|
return GlobalOptions.ModifiableFiles.isFileIncluded(FE->getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
|
bool Transform::handleBeginSource(CompilerInstance &CI, StringRef Filename) {
|
||||||
|
|
|
||||||
|
|
@ -66,9 +66,9 @@ struct TransformOptions {
|
||||||
/// \brief Enable the use of performance timers.
|
/// \brief Enable the use of performance timers.
|
||||||
bool EnableTiming;
|
bool EnableTiming;
|
||||||
|
|
||||||
/// \brief Contains information on which headers are safe to transform and
|
/// \brief Contains information on which files are safe to transform and
|
||||||
/// which aren't.
|
/// which aren't.
|
||||||
IncludeExcludeInfo ModifiableHeaders;
|
IncludeExcludeInfo ModifiableFiles;
|
||||||
|
|
||||||
/// \brief Maximum allowed level of risk.
|
/// \brief Maximum allowed level of risk.
|
||||||
RiskLevel MaxRiskLevel;
|
RiskLevel MaxRiskLevel;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
||||||
static cl::opt<std::string> BuildPath(
|
static cl::opt<std::string> BuildPath(
|
||||||
"p", cl::desc("Build Path"), cl::Optional);
|
"p", cl::desc("Build Path"), cl::Optional);
|
||||||
static cl::list<std::string> SourcePaths(
|
static cl::list<std::string> SourcePaths(
|
||||||
cl::Positional, cl::desc("<source0> [... <sourceN>]"), cl::OneOrMore);
|
cl::Positional, cl::desc("[<sources>...]"), cl::ZeroOrMore);
|
||||||
static cl::extrahelp MoreHelp(
|
static cl::extrahelp MoreHelp(
|
||||||
"EXAMPLES:\n\n"
|
"EXAMPLES:\n\n"
|
||||||
"Apply all transforms on a given file, no compilation database:\n\n"
|
"Apply all transforms on a given file, no compilation database:\n\n"
|
||||||
|
|
@ -281,6 +281,42 @@ bool serializeReplacements(const replace::TUReplacements &Replacements) {
|
||||||
return !Errors;
|
return !Errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CompilationDatabase *autoDetectCompilations(std::string &ErrorMessage) {
|
||||||
|
// Auto-detect a compilation database from BuildPath.
|
||||||
|
if (BuildPath.getNumOccurrences() > 0)
|
||||||
|
return CompilationDatabase::autoDetectFromDirectory(BuildPath,
|
||||||
|
ErrorMessage);
|
||||||
|
// Try to auto-detect a compilation database from the first source.
|
||||||
|
if (!SourcePaths.empty()) {
|
||||||
|
if (CompilationDatabase *Compilations =
|
||||||
|
CompilationDatabase::autoDetectFromSource(SourcePaths[0],
|
||||||
|
ErrorMessage))
|
||||||
|
return Compilations;
|
||||||
|
// If no compilation database can be detected from source then we create a
|
||||||
|
// fixed compilation database with c++11 support.
|
||||||
|
std::string CommandLine[] = { "-std=c++11" };
|
||||||
|
return new FixedCompilationDatabase(".", CommandLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorMessage = "Could not determine sources to transform";
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Predicate definition for determining whether a file is not included.
|
||||||
|
static bool isFileNotIncludedPredicate(llvm::StringRef FilePath) {
|
||||||
|
return !GlobalOptions.ModifiableFiles.isFileIncluded(FilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Predicate definition for determining if a file was explicitly excluded.
|
||||||
|
static bool isFileExplicitlyExcludedPredicate(llvm::StringRef FilePath) {
|
||||||
|
if (GlobalOptions.ModifiableFiles.isFileExplicitlyExcluded(FilePath)) {
|
||||||
|
llvm::errs() << "Warning \"" << FilePath << "\" will not be transformed "
|
||||||
|
<< "because it's in the excluded list.\n";
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, const char **argv) {
|
int main(int argc, const char **argv) {
|
||||||
llvm::sys::PrintStackTraceOnErrorSignal();
|
llvm::sys::PrintStackTraceOnErrorSignal();
|
||||||
Transforms TransformManager;
|
Transforms TransformManager;
|
||||||
|
|
@ -292,23 +328,45 @@ int main(int argc, const char **argv) {
|
||||||
FixedCompilationDatabase::loadFromCommandLine(argc, argv));
|
FixedCompilationDatabase::loadFromCommandLine(argc, argv));
|
||||||
cl::ParseCommandLineOptions(argc, argv);
|
cl::ParseCommandLineOptions(argc, argv);
|
||||||
|
|
||||||
|
// Populate the ModifiableFiles structure.
|
||||||
|
GlobalOptions.ModifiableFiles.readListFromString(IncludePaths, ExcludePaths);
|
||||||
|
GlobalOptions.ModifiableFiles.readListFromFile(IncludeFromFile,
|
||||||
|
ExcludeFromFile);
|
||||||
|
|
||||||
if (!Compilations) {
|
if (!Compilations) {
|
||||||
std::string ErrorMessage;
|
std::string ErrorMessage;
|
||||||
if (BuildPath.getNumOccurrences() > 0) {
|
Compilations.reset(autoDetectCompilations(ErrorMessage));
|
||||||
Compilations.reset(CompilationDatabase::autoDetectFromDirectory(
|
if (!Compilations) {
|
||||||
BuildPath, ErrorMessage));
|
llvm::errs() << llvm::sys::path::filename(argv[0]) << ": " << ErrorMessage
|
||||||
} else {
|
<< "\n";
|
||||||
Compilations.reset(CompilationDatabase::autoDetectFromSource(
|
return 1;
|
||||||
SourcePaths[0], ErrorMessage));
|
|
||||||
// If no compilation database can be detected from source then we create
|
|
||||||
// a new FixedCompilationDatabase with c++11 support.
|
|
||||||
if (!Compilations) {
|
|
||||||
std::string CommandLine[] = {"-std=c++11"};
|
|
||||||
Compilations.reset(new FixedCompilationDatabase(".", CommandLine));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!Compilations)
|
}
|
||||||
llvm::report_fatal_error(ErrorMessage);
|
|
||||||
|
// Populate source files.
|
||||||
|
std::vector<std::string> Sources;
|
||||||
|
if (!SourcePaths.empty()) {
|
||||||
|
// Use only files that are not explicitly excluded.
|
||||||
|
std::remove_copy_if(SourcePaths.begin(), SourcePaths.end(),
|
||||||
|
std::back_inserter(Sources),
|
||||||
|
isFileExplicitlyExcludedPredicate);
|
||||||
|
} else {
|
||||||
|
if (GlobalOptions.ModifiableFiles.isIncludeListEmpty()) {
|
||||||
|
llvm::errs() << llvm::sys::path::filename(argv[0])
|
||||||
|
<< ": Use -include to indicate which files of "
|
||||||
|
<< "the compilatiion database to transform.\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Use source paths from the compilation database.
|
||||||
|
// We only transform files that are explicitly included.
|
||||||
|
Sources = Compilations->getAllFiles();
|
||||||
|
std::remove_if(Sources.begin(), Sources.end(), isFileNotIncludedPredicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Sources.empty()) {
|
||||||
|
llvm::errs() << llvm::sys::path::filename(argv[0])
|
||||||
|
<< ": Could not determine sources to transform.\n";
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Since ExecutionTimeDirectoryName could be an empty string we compare
|
// Since ExecutionTimeDirectoryName could be an empty string we compare
|
||||||
|
|
@ -325,12 +383,6 @@ int main(int argc, const char **argv) {
|
||||||
if (CmdSwitchError)
|
if (CmdSwitchError)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Populate the ModifiableHeaders structure.
|
|
||||||
GlobalOptions.ModifiableHeaders
|
|
||||||
.readListFromString(IncludePaths, ExcludePaths);
|
|
||||||
GlobalOptions.ModifiableHeaders
|
|
||||||
.readListFromFile(IncludeFromFile, ExcludeFromFile);
|
|
||||||
|
|
||||||
TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);
|
TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions);
|
||||||
|
|
||||||
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
|
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts(
|
||||||
|
|
@ -344,9 +396,10 @@ int main(int argc, const char **argv) {
|
||||||
|
|
||||||
if (TransformManager.begin() == TransformManager.end()) {
|
if (TransformManager.begin() == TransformManager.end()) {
|
||||||
if (SupportedCompilers.empty())
|
if (SupportedCompilers.empty())
|
||||||
llvm::errs() << argv[0] << ": no selected transforms\n";
|
llvm::errs() << llvm::sys::path::filename(argv[0])
|
||||||
|
<< ": no selected transforms\n";
|
||||||
else
|
else
|
||||||
llvm::errs() << argv[0]
|
llvm::errs() << llvm::sys::path::filename(argv[0])
|
||||||
<< ": no transforms available for specified compilers\n";
|
<< ": no transforms available for specified compilers\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -372,7 +425,7 @@ int main(int argc, const char **argv) {
|
||||||
I != E; ++I) {
|
I != E; ++I) {
|
||||||
Transform *T = *I;
|
Transform *T = *I;
|
||||||
|
|
||||||
if (T->apply(FileStates, *Compilations, SourcePaths) != 0) {
|
if (T->apply(FileStates, *Compilations, Sources) != 0) {
|
||||||
// FIXME: Improve ClangTool to not abort if just one file fails.
|
// FIXME: Improve ClangTool to not abort if just one file fails.
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -441,12 +494,12 @@ int main(int argc, const char **argv) {
|
||||||
// replacements. Otherwise reformat changes if reformatting is enabled.
|
// replacements. Otherwise reformat changes if reformatting is enabled.
|
||||||
if (!SerializeReplacements) {
|
if (!SerializeReplacements) {
|
||||||
if (ChangesReformatter)
|
if (ChangesReformatter)
|
||||||
reformat(*ChangesReformatter, FileStates, Diagnostics);
|
reformat(*ChangesReformatter, FileStates, Diagnostics);
|
||||||
FileStates.writeToDisk(Diagnostics);
|
FileStates.writeToDisk(Diagnostics);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FinalSyntaxCheck)
|
if (FinalSyntaxCheck)
|
||||||
if (!doSyntaxCheck(*Compilations, SourcePaths, FileStates))
|
if (!doSyntaxCheck(*Compilations, Sources, FileStates))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
// Report execution times.
|
// Report execution times.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
clang-modernize Usage
|
clang-modernize Usage
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
``clang-modernize [options] <source0> [... <sourceN>] [-- [args]]``
|
``clang-modernize [options] [<sources>...] [-- [args]]``
|
||||||
|
|
||||||
``<source#>`` specifies the path to the source to migrate. This path may be
|
``<source#>`` specifies the path to the source to migrate. This path may be
|
||||||
relative to the current directory.
|
relative to the current directory.
|
||||||
|
|
@ -40,6 +40,16 @@ General Command Line Options
|
||||||
|
|
||||||
This option is ignored if ``--`` is present.
|
This option is ignored if ``--`` is present.
|
||||||
|
|
||||||
|
Files in the compilation database that can be transformed if no sources are
|
||||||
|
provided and file paths are explicitly included using ``-include`` or
|
||||||
|
``-include-from``.
|
||||||
|
In order to transform all files in a compilation database the following
|
||||||
|
command line can be used:
|
||||||
|
|
||||||
|
``clang-modernize -p=<build-path> -include=<project_root>``
|
||||||
|
|
||||||
|
Use ``-exclude`` or ``-exclude-from`` to limit the scope of ``-include``.
|
||||||
|
|
||||||
.. option:: -- [args]
|
.. option:: -- [args]
|
||||||
|
|
||||||
Another way to provide compiler arguments is to specify all arguments on the
|
Another way to provide compiler arguments is to specify all arguments on the
|
||||||
|
|
|
||||||
|
|
@ -264,7 +264,7 @@ TEST(Transform, isFileModifiable) {
|
||||||
StringRef ExcludeDir = llvm::sys::path::parent_path(HeaderBFile);
|
StringRef ExcludeDir = llvm::sys::path::parent_path(HeaderBFile);
|
||||||
|
|
||||||
IncludeExcludeInfo IncInfo;
|
IncludeExcludeInfo IncInfo;
|
||||||
Options.ModifiableHeaders.readListFromString(CurrentDir, ExcludeDir);
|
Options.ModifiableFiles.readListFromString(CurrentDir, ExcludeDir);
|
||||||
|
|
||||||
tooling::FixedCompilationDatabase Compilations(CurrentDir.str(),
|
tooling::FixedCompilationDatabase Compilations(CurrentDir.str(),
|
||||||
std::vector<std::string>());
|
std::vector<std::string>());
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue