2014-01-07 23:22:08 +08:00
|
|
|
//===-- ModuleMapChecker.h - Common defs for module-map-checker -*- C++ -*-==//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
///
|
|
|
|
/// \file
|
|
|
|
/// \brief Common definitions for ModuleMapChecker.
|
|
|
|
///
|
|
|
|
//===--------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef MODULEMAPCHECKER_H
|
|
|
|
#define MODULEMAPCHECKER_H
|
|
|
|
|
|
|
|
#include "clang/Basic/Diagnostic.h"
|
|
|
|
#include "clang/Basic/FileManager.h"
|
|
|
|
#include "clang/Basic/LangOptions.h"
|
|
|
|
#include "clang/Basic/TargetInfo.h"
|
|
|
|
#include "clang/Basic/TargetOptions.h"
|
|
|
|
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
|
|
|
#include "clang/Lex/HeaderSearch.h"
|
|
|
|
#include "clang/Lex/HeaderSearchOptions.h"
|
|
|
|
#include "clang/Lex/ModuleMap.h"
|
|
|
|
#include "clang/Lex/Preprocessor.h"
|
|
|
|
#include "llvm/ADT/StringSet.h"
|
|
|
|
#include "llvm/Support/Host.h"
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
/// Subclass TargetOptions so we can construct it inline with
|
|
|
|
/// the minimal option, the triple.
|
|
|
|
class ModuleMapTargetOptions : public clang::TargetOptions {
|
|
|
|
public:
|
|
|
|
ModuleMapTargetOptions() { Triple = llvm::sys::getDefaultTargetTriple(); }
|
|
|
|
};
|
|
|
|
|
|
|
|
/// Module map checker class.
|
|
|
|
/// This is the heart of the checker.
|
|
|
|
/// The doChecks function does the main work.
|
|
|
|
/// The data members store the options and internally collected data.
|
|
|
|
class ModuleMapChecker {
|
|
|
|
// Checker arguments.
|
|
|
|
|
|
|
|
/// The module.map file path. Can be relative or absolute.
|
|
|
|
llvm::StringRef ModuleMapPath;
|
|
|
|
/// The include paths to check for files.
|
|
|
|
/// (Note that other directories above these paths are ignored.
|
|
|
|
/// To expect all files to be accounted for from the module.map
|
|
|
|
/// file directory on down, leave this empty.)
|
|
|
|
std::vector<std::string> IncludePaths;
|
|
|
|
/// Flag to dump the module map information during check.
|
|
|
|
bool DumpModuleMap;
|
|
|
|
/// The remaining arguments, to be passed to the front end.
|
|
|
|
llvm::ArrayRef<std::string> CommandLine;
|
|
|
|
|
|
|
|
// Supporting objects.
|
|
|
|
|
|
|
|
/// Options controlling the language variant.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::LangOptions> LangOpts;
|
|
|
|
/// Diagnostic IDs.
|
|
|
|
const llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs;
|
|
|
|
/// Options controlling the diagnostic engine.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagnosticOpts;
|
|
|
|
/// Diagnostic consumer.
|
|
|
|
clang::TextDiagnosticPrinter DC;
|
|
|
|
/// Diagnostic engine.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::DiagnosticsEngine> Diagnostics;
|
|
|
|
/// Options controlling the target.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::TargetOptions> TargetOpts;
|
|
|
|
/// Target information.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::TargetInfo> Target;
|
|
|
|
/// Options controlling the file system manager.
|
|
|
|
clang::FileSystemOptions FileSystemOpts;
|
|
|
|
/// File system manager.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::FileManager> FileMgr;
|
|
|
|
/// Source manager.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::SourceManager> SourceMgr;
|
|
|
|
/// Options controlling the \#include directive.
|
|
|
|
llvm::IntrusiveRefCntPtr<clang::HeaderSearchOptions> HeaderSearchOpts;
|
|
|
|
/// Header search manager.
|
2014-03-09 17:24:40 +08:00
|
|
|
std::unique_ptr<clang::HeaderSearch> HeaderInfo;
|
2014-01-07 23:22:08 +08:00
|
|
|
/// The module map.
|
2014-03-09 17:24:40 +08:00
|
|
|
std::unique_ptr<clang::ModuleMap> ModMap;
|
2014-01-07 23:22:08 +08:00
|
|
|
|
|
|
|
// Internal data.
|
|
|
|
|
|
|
|
/// Directory containing the module map.
|
|
|
|
/// Might be relative to the current directory, or absolute.
|
|
|
|
std::string ModuleMapDirectory;
|
|
|
|
/// Set of all the headers found in the module map.
|
|
|
|
llvm::StringSet<llvm::MallocAllocator> ModuleMapHeadersSet;
|
|
|
|
/// All the headers found in the file system starting at the
|
|
|
|
/// module map, or the union of those from the include paths.
|
|
|
|
std::vector<std::string> FileSystemHeaders;
|
|
|
|
/// Headers found in file system, but not in module map.
|
|
|
|
std::vector<std::string> UnaccountedForHeaders;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// Constructor.
|
|
|
|
/// You can use the static createModuleMapChecker to create an instance
|
|
|
|
/// of this object.
|
|
|
|
/// \param ModuleMapPath The module.map file path.
|
|
|
|
/// Can be relative or absolute.
|
|
|
|
/// \param IncludePaths The include paths to check for files.
|
|
|
|
/// (Note that other directories above these paths are ignored.
|
|
|
|
/// To expect all files to be accounted for from the module.map
|
|
|
|
/// file directory on down, leave this empty.)
|
|
|
|
/// \param DumpModuleMap Flag to dump the module map information
|
|
|
|
/// during check.
|
|
|
|
ModuleMapChecker(llvm::StringRef ModuleMapPath,
|
|
|
|
std::vector<std::string> &IncludePaths, bool DumpModuleMap,
|
|
|
|
llvm::ArrayRef<std::string> CommandLine);
|
|
|
|
|
|
|
|
/// Create instance of ModuleMapChecker.
|
|
|
|
/// \param ModuleMapPath The module.map file path.
|
|
|
|
/// Can be relative or absolute.
|
|
|
|
/// \param IncludePaths The include paths to check for files.
|
|
|
|
/// (Note that other directories above these paths are ignored.
|
|
|
|
/// To expect all files to be accounted for from the module.map
|
|
|
|
/// file directory on down, leave this empty.)
|
|
|
|
/// \param DumpModuleMap Flag to dump the module map information
|
|
|
|
/// during check.
|
|
|
|
/// \returns Initialized ModuleMapChecker object.
|
|
|
|
static ModuleMapChecker *createModuleMapChecker(
|
|
|
|
llvm::StringRef ModuleMapPath, std::vector<std::string> &IncludePaths,
|
|
|
|
bool DumpModuleMap, llvm::ArrayRef<std::string> CommandLine);
|
|
|
|
|
|
|
|
/// Do checks.
|
|
|
|
/// Starting from the directory of the module.map file,
|
|
|
|
/// Find all header files, optionally looking only at files
|
|
|
|
/// covered by the include path options, and compare against
|
|
|
|
/// the headers referenced by the module.map file.
|
|
|
|
/// Display warnings for unaccounted-for header files.
|
|
|
|
/// \returns 0 if there were no errors or warnings, 1 if there
|
|
|
|
/// were warnings, 2 if any other problem, such as a bad
|
|
|
|
/// module map path argument was specified.
|
|
|
|
llvm::error_code doChecks();
|
|
|
|
|
|
|
|
// The following functions are called by doChecks.
|
|
|
|
|
|
|
|
/// Load module map.
|
|
|
|
/// \returns True if module.map file loaded successfully.
|
|
|
|
bool loadModuleMap();
|
|
|
|
|
|
|
|
/// Collect module headers.
|
|
|
|
/// Walks the modules and collects referenced headers into
|
|
|
|
/// ModuleMapHeadersSet.
|
|
|
|
void collectModuleHeaders();
|
|
|
|
|
|
|
|
/// Collect referenced headers from one module.
|
|
|
|
/// Collects the headers referenced in the given module into
|
|
|
|
/// ModuleMapHeadersSet.
|
|
|
|
/// \param Mod The module reference.
|
|
|
|
/// \return True if no errors.
|
|
|
|
bool collectModuleHeaders(const clang::Module &Mod);
|
|
|
|
|
|
|
|
/// Collect headers from an umbrella directory.
|
|
|
|
/// \param UmbrellaDirName The umbrella directory name.
|
|
|
|
/// \return True if no errors.
|
|
|
|
bool collectUmbrellaHeaders(llvm::StringRef UmbrellaDirName);
|
|
|
|
|
|
|
|
/// Collect headers rferenced from an umbrella file.
|
|
|
|
/// \param UmbrellaHeaderName The umbrella file path.
|
|
|
|
/// \return True if no errors.
|
|
|
|
bool collectUmbrellaHeaderHeaders(llvm::StringRef UmbrellaHeaderName);
|
|
|
|
|
|
|
|
/// Called from ModuleMapCheckerCallbacks to track a header included
|
|
|
|
/// from an umbrella header.
|
|
|
|
/// \param HeaderName The header file path.
|
|
|
|
void collectUmbrellaHeaderHeader(llvm::StringRef HeaderName);
|
|
|
|
|
|
|
|
/// Collect file system header files.
|
|
|
|
/// This function scans the file system for header files,
|
|
|
|
/// starting at the directory of the module.map file,
|
|
|
|
/// optionally filtering out all but the files covered by
|
|
|
|
/// the include path options.
|
|
|
|
/// \returns True if no errors.
|
|
|
|
bool collectFileSystemHeaders();
|
|
|
|
|
|
|
|
/// Collect file system header files from the given path.
|
|
|
|
/// This function scans the file system for header files,
|
|
|
|
/// starting at the given directory, which is assumed to be
|
|
|
|
/// relative to the directory of the module.map file.
|
|
|
|
/// \returns True if no errors.
|
|
|
|
bool collectFileSystemHeaders(llvm::StringRef IncludePath);
|
|
|
|
|
|
|
|
/// Find headers unaccounted-for in module map.
|
|
|
|
/// This function compares the list of collected header files
|
|
|
|
/// against those referenced in the module map. Display
|
|
|
|
/// warnings for unaccounted-for header files.
|
|
|
|
/// Save unaccounted-for file list for possible.
|
|
|
|
/// fixing action.
|
|
|
|
void findUnaccountedForHeaders();
|
|
|
|
|
|
|
|
// Utility functions.
|
|
|
|
|
|
|
|
/// Get directory path component from file path.
|
|
|
|
/// \returns the component of the given path, which will be
|
|
|
|
/// relative if the given path is relative, absolute if the
|
|
|
|
/// given path is absolute, or "." if the path has no leading
|
|
|
|
/// path component.
|
|
|
|
std::string getDirectoryFromPath(llvm::StringRef Path);
|
|
|
|
|
|
|
|
/// Convert header path to canonical form.
|
|
|
|
/// The canonical form is basically just use forward slashes,
|
|
|
|
/// and remove "./".
|
|
|
|
/// \param FilePath The file path.
|
|
|
|
/// \returns The file path in canonical form.
|
|
|
|
std::string getCanonicalPath(llvm::StringRef FilePath);
|
|
|
|
|
|
|
|
/// Check for header file extension.
|
|
|
|
/// If the file extension is .h, .inc, or missing, it's
|
|
|
|
/// assumed to be a header.
|
|
|
|
/// \param FileName The file name. Must not be a directory.
|
|
|
|
/// \returns true if it has a header extension or no extension.
|
|
|
|
bool isHeader(llvm::StringRef FileName);
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif // MODULEMAPCHECKER_H
|