From d845baecb47f4e74e2cd7ec94dc8d91c15660425 Mon Sep 17 00:00:00 2001 From: John Thompson Date: Fri, 13 Feb 2015 14:29:22 +0000 Subject: Moved header list loading to new class. This is staging for adding module map loading and checking support. llvm-svn: 229108 --- .../modularize/ModularizeUtilities.cpp | 124 +++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 clang-tools-extra/modularize/ModularizeUtilities.cpp (limited to 'clang-tools-extra/modularize/ModularizeUtilities.cpp') diff --git a/clang-tools-extra/modularize/ModularizeUtilities.cpp b/clang-tools-extra/modularize/ModularizeUtilities.cpp new file mode 100644 index 00000000000..14c9f5d2756 --- /dev/null +++ b/clang-tools-extra/modularize/ModularizeUtilities.cpp @@ -0,0 +1,124 @@ +//===--- extra/modularize/ModularizeUtilities.cpp -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements a class for loading and validating a module map or +// header list by checking that all headers in the corresponding directories +// are accounted for. +// +//===----------------------------------------------------------------------===// + +#include "ModularizeUtilities.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Support/FileUtilities.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace Modularize; + +// ModularizeUtilities class implementation. + +// Constructor. +ModularizeUtilities::ModularizeUtilities(std::vector &InputPaths, + llvm::StringRef Prefix) + : InputFilePaths(InputPaths), + HeaderPrefix(Prefix) {} + +// Create instance of ModularizeUtilities, to simplify setting up +// subordinate objects. +ModularizeUtilities *ModularizeUtilities::createModularizeUtilities( + std::vector &InputPaths, llvm::StringRef Prefix) { + + return new ModularizeUtilities(InputPaths, Prefix); +} + +// Load all header lists and dependencies. +std::error_code ModularizeUtilities::loadAllHeaderListsAndDependencies() { + typedef std::vector::iterator Iter; + for (Iter I = InputFilePaths.begin(), E = InputFilePaths.end(); I != E; ++I) { + if (std::error_code EC = loadSingleHeaderListsAndDependencies(*I)) { + errs() << "modularize: error: Unable to get header list '" << *I + << "': " << EC.message() << '\n'; + return EC; + } + } + return std::error_code(); +} + +// Load single header list and dependencies. +std::error_code ModularizeUtilities::loadSingleHeaderListsAndDependencies( + 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> listBuffer = + MemoryBuffer::getFile(InputPath); + if (std::error_code EC = listBuffer.getError()) + return EC; + + // Parse the header list into strings. + SmallVector Strings; + listBuffer.get()->getBuffer().split(Strings, "\n", -1, false); + + // Collect the header file names from the string list. + for (SmallVectorImpl::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; + std::pair TargetAndDependents = Line.split(':'); + SmallString<256> HeaderFileName; + // Prepend header file name prefix if it's not absolute. + if (llvm::sys::path::is_absolute(TargetAndDependents.first)) + llvm::sys::path::native(TargetAndDependents.first, HeaderFileName); + else { + if (HeaderDirectory.size() != 0) + HeaderFileName = HeaderDirectory; + else + HeaderFileName = CurrentDirectory; + llvm::sys::path::append(HeaderFileName, TargetAndDependents.first); + llvm::sys::path::native(HeaderFileName); + } + // Handle optional dependencies. + DependentsVector Dependents; + SmallVector DependentsList; + TargetAndDependents.second.split(DependentsList, " ", -1, false); + int Count = DependentsList.size(); + for (int Index = 0; Index < Count; ++Index) { + SmallString<256> Dependent; + if (llvm::sys::path::is_absolute(DependentsList[Index])) + Dependent = DependentsList[Index]; + else { + if (HeaderDirectory.size() != 0) + Dependent = HeaderDirectory; + else + Dependent = CurrentDirectory; + llvm::sys::path::append(Dependent, DependentsList[Index]); + } + llvm::sys::path::native(Dependent); + Dependents.push_back(Dependent.str()); + } + // Save the resulting header file path and dependencies. + HeaderFileNames.push_back(HeaderFileName.str()); + Dependencies[HeaderFileName.str()] = Dependents; + } + return std::error_code(); +} -- cgit v1.2.3