summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/modularize/ModularizeUtilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/modularize/ModularizeUtilities.cpp')
-rw-r--r--clang-tools-extra/modularize/ModularizeUtilities.cpp163
1 files changed, 143 insertions, 20 deletions
diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp
index 7594b6725cc..08c92fc90c0 100644
--- a/clang-tools-extra/modularize/ModularizeUtilities.cpp
+++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp
@@ -42,9 +42,11 @@ public:
// Constructor.
ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
- llvm::StringRef Prefix)
+ llvm::StringRef Prefix,
+ llvm::StringRef ProblemFilesListPath)
: InputFilePaths(InputPaths),
HeaderPrefix(Prefix),
+ ProblemFilesPath(ProblemFilesListPath),
HasModuleMap(false),
MissingHeaderCount(0),
// Init clang stuff needed for loading the module map and preprocessing.
@@ -65,9 +67,10 @@ ModularizeUtilities::ModularizeUtilities(std::vector<std::string> &InputPaths,
// Create instance of ModularizeUtilities, to simplify setting up
// subordinate objects.
ModularizeUtilities *ModularizeUtilities::createModularizeUtilities(
- std::vector<std::string> &InputPaths, llvm::StringRef Prefix) {
+ std::vector<std::string> &InputPaths, llvm::StringRef Prefix,
+ llvm::StringRef ProblemFilesListPath) {
- return new ModularizeUtilities(InputPaths, Prefix);
+ return new ModularizeUtilities(InputPaths, Prefix, ProblemFilesListPath);
}
// Load all header lists and dependencies.
@@ -91,6 +94,15 @@ std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() {
}
}
}
+ // If we have a problem files list.
+ if (ProblemFilesPath.size() != 0) {
+ // Load problem files list.
+ if (std::error_code EC = loadProblemHeaderList(ProblemFilesPath)) {
+ errs() << "modularize: error: Unable to get problem header list '" << ProblemFilesPath
+ << "': " << EC.message() << '\n';
+ return EC;
+ }
+ }
return std::error_code();
}
@@ -194,6 +206,58 @@ std::error_code ModularizeUtilities::loadSingleHeaderListsAndDependencies(
return std::error_code();
}
+// Load problem header list.
+std::error_code ModularizeUtilities::loadProblemHeaderList(
+ llvm::StringRef InputPath) {
+
+ // By default, use the path component of the list file name.
+ SmallString<256> HeaderDirectory(InputPath);
+ llvm::sys::path::remove_filename(HeaderDirectory);
+ SmallString<256> CurrentDirectory;
+ llvm::sys::fs::current_path(CurrentDirectory);
+
+ // Get the prefix if we have one.
+ if (HeaderPrefix.size() != 0)
+ HeaderDirectory = HeaderPrefix;
+
+ // Read the header list file into a buffer.
+ ErrorOr<std::unique_ptr<MemoryBuffer>> listBuffer =
+ MemoryBuffer::getFile(InputPath);
+ if (std::error_code EC = listBuffer.getError())
+ return EC;
+
+ // Parse the header list into strings.
+ SmallVector<StringRef, 32> Strings;
+ listBuffer.get()->getBuffer().split(Strings, "\n", -1, false);
+
+ // Collect the header file names from the string list.
+ for (SmallVectorImpl<StringRef>::iterator I = Strings.begin(),
+ E = Strings.end();
+ I != E; ++I) {
+ StringRef Line = I->trim();
+ // Ignore comments and empty lines.
+ if (Line.empty() || (Line[0] == '#'))
+ continue;
+ SmallString<256> HeaderFileName;
+ // Prepend header file name prefix if it's not absolute.
+ if (llvm::sys::path::is_absolute(Line))
+ llvm::sys::path::native(Line, HeaderFileName);
+ else {
+ if (HeaderDirectory.size() != 0)
+ HeaderFileName = HeaderDirectory;
+ else
+ HeaderFileName = CurrentDirectory;
+ llvm::sys::path::append(HeaderFileName, Line);
+ llvm::sys::path::native(HeaderFileName);
+ }
+ // Get canonical form.
+ HeaderFileName = getCanonicalPath(HeaderFileName);
+ // Save the resulting header file path.
+ ProblemFileNames.push_back(HeaderFileName.str());
+ }
+ return std::error_code();
+}
+
// Load single module map and extract header file list.
std::error_code ModularizeUtilities::loadModuleMap(
llvm::StringRef InputPath) {
@@ -364,24 +428,24 @@ bool ModularizeUtilities::collectUmbrellaHeaders(StringRef UmbrellaDirName,
}
// Replace .. embedded in path for purposes of having
-// a canonical path.
+// a canonical path.
static std::string replaceDotDot(StringRef Path) {
- SmallString<128> Buffer;
- llvm::sys::path::const_iterator B = llvm::sys::path::begin(Path),
- E = llvm::sys::path::end(Path);
- while (B != E) {
- if (B->compare(".") == 0) {
- }
- else if (B->compare("..") == 0)
- llvm::sys::path::remove_filename(Buffer);
- else
- llvm::sys::path::append(Buffer, *B);
- ++B;
- }
- if (Path.endswith("/") || Path.endswith("\\"))
- Buffer.append(1, Path.back());
- return Buffer.c_str();
-}
+ SmallString<128> Buffer;
+ llvm::sys::path::const_iterator B = llvm::sys::path::begin(Path),
+ E = llvm::sys::path::end(Path);
+ while (B != E) {
+ if (B->compare(".") == 0) {
+ }
+ else if (B->compare("..") == 0)
+ llvm::sys::path::remove_filename(Buffer);
+ else
+ llvm::sys::path::append(Buffer, *B);
+ ++B;
+ }
+ if (Path.endswith("/") || Path.endswith("\\"))
+ Buffer.append(1, Path.back());
+ return Buffer.c_str();
+}
// Convert header path to canonical form.
// The canonical form is basically just use forward slashes, and remove "./".
@@ -424,3 +488,62 @@ std::string ModularizeUtilities::getDirectoryFromPath(StringRef Path) {
return ".";
return Directory.str();
}
+
+// Add unique problem file.
+// Also standardizes the path.
+void ModularizeUtilities::addUniqueProblemFile(std::string FilePath) {
+ FilePath = getCanonicalPath(FilePath);
+ // Don't add if already present.
+ for(auto &TestFilePath : ProblemFileNames) {
+ if (TestFilePath == FilePath)
+ return;
+ }
+ ProblemFileNames.push_back(FilePath);
+}
+
+// Add file with no compile errors.
+// Also standardizes the path.
+void ModularizeUtilities::addNoCompileErrorsFile(std::string FilePath) {
+ FilePath = getCanonicalPath(FilePath);
+ GoodFileNames.push_back(FilePath);
+}
+
+// List problem files.
+void ModularizeUtilities::displayProblemFiles() {
+ errs() << "\nThese are the files with possible errors:\n\n";
+ for (auto &ProblemFile : ProblemFileNames) {
+ errs() << ProblemFile << "\n";
+ }
+}
+
+// List files with no problems.
+void ModularizeUtilities::displayGoodFiles() {
+ errs() << "\nThese are the files with no detected errors:\n\n";
+ for (auto &GoodFile : HeaderFileNames) {
+ bool Good = true;
+ for (auto &ProblemFile : ProblemFileNames) {
+ if (ProblemFile == GoodFile) {
+ Good = false;
+ break;
+ }
+ }
+ if (Good)
+ errs() << GoodFile << "\n";
+ }
+}
+
+// List files with problem files commented out.
+void ModularizeUtilities::displayCombinedFiles() {
+ errs() <<
+ "\nThese are the combined files, with problem files preceded by #:\n\n";
+ for (auto &File : HeaderFileNames) {
+ bool Good = true;
+ for (auto &ProblemFile : ProblemFileNames) {
+ if (ProblemFile == File) {
+ Good = false;
+ break;
+ }
+ }
+ errs() << (Good ? "" : "#") << File << "\n";
+ }
+}
OpenPOWER on IntegriCloud