//===- extra/modularize/Modularize.cpp - Check modularized headers --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Introduction
//
// This file implements a tool that checks whether a set of headers provides
// the consistent definitions required to use modules.  It can also check an
// existing module map for full coverage of the headers in a directory tree.
//
// For example, in examining headers, it detects whether the same entity
// (say, a NULL macro or size_t typedef) is defined in multiple headers
// or whether a header produces different definitions under
// different circumstances. These conditions cause modules built from the
// headers to behave poorly, and should be fixed before introducing a module
// map.
//
// Modularize takes as input either one or more module maps (by default,
// "module.modulemap") or one or more text files contatining lists of headers
// to check.
//
// In the case of a module map, the module map must be well-formed in
// terms of syntax.  Modularize will extract the header file names
// from the map.  Only normal headers are checked, assuming headers
// marked "private", "textual", or "exclude" are not to be checked
// as a top-level include, assuming they either are included by
// other headers which are checked, or they are not suitable for
// modules.
//
// In the case of a file list, the list is a newline-separated list of headers
// to check with respect to each other.
// Lines beginning with '#' and empty lines are ignored.
// Header file names followed by a colon and other space-separated
// file names will include those extra files as dependencies.
// The file names can be relative or full paths, but must be on the
// same line.
//
// Modularize also accepts regular clang front-end arguments.
//
// Usage:   modularize [(modularize options)]
//   [(include-files_list)|(module map)]+ [(front-end-options) ...]
//
// Options:
//    -prefix=(optional header path prefix)
//          Note that unless a "-prefix (header path)" option is specified,
//          non-absolute file paths in the header list file will be relative
//          to the header list file directory.  Use -prefix to specify a
//          different directory.
//    -module-map-path=(module map)
//          Skip the checks, and instead act as a module.map generation
//          assistant, generating a module map file based on the header list.
//          An optional "-root-module=(rootName)" argument can specify a root
//          module to be created in the generated module.map file.  Note that
//          you will likely need to edit this file to suit the needs of your
//          headers.
//    -problem-files-list=(problem files list file name)
//          For use only with module map assistant.  Input list of files that
//          have problems with respect to modules.  These will still be
//          included in the generated module map, but will be marked as
//          "excluded" headers.
//    -root-module=(root module name)
//          Specifies a root module to be created in the generated module.map
//          file.
//    -block-check-header-list-only
//          Only warn if #include directives are inside extern or namespace
//          blocks if the included header is in the header list.
//    -no-coverage-check
//          Don't do the coverage check.
//    -coverage-check-only
//          Only do the coverage check.
//    -display-file-lists
//          Display lists of good files (no compile errors), problem files,
//          and a combined list with problem files preceded by a '#'.
//          This can be used to quickly determine which files have problems.
//          The latter combined list might be useful in starting to modularize
//          a set of headers.  You can start with a full list of headers,
//          use -display-file-lists option, and then use the combined list as
//          your intermediate list, uncommenting-out headers as you fix them.
//
// Note that by default, the modularize assumes .h files contain C++ source.
// If your .h files in the file list contain another language, you should
// append an appropriate -x option to your command line, i.e.:  -x c
//
// Modularization Issue Checks
//
// In the process of checking headers for modularization issues, modularize
// will do normal parsing, reporting normal errors and warnings,
// but will also report special error messages like the following:
//
//   error: '(symbol)' defined at multiple locations:
//       (file):(row):(column)
//       (file):(row):(column)
//
//   error: header '(file)' has different contents depending on how it was
//     included
//
// The latter might be followed by messages like the following:
//
//   note: '(symbol)' in (file) at (row):(column) not always provided
//
// Checks will also be performed for macro expansions, defined(macro)
// expressions, and preprocessor conditional directives that evaluate
// inconsistently, and can produce error messages like the following:
//
//   (...)/SubHeader.h:11:5:
//   #if SYMBOL == 1
//       ^
//   error: Macro instance 'SYMBOL' has different values in this header,
//          depending on how it was included.
//     'SYMBOL' expanded to: '1' with respect to these inclusion paths:
//       (...)/Header1.h
//         (...)/SubHeader.h
//   (...)/SubHeader.h:3:9:
//   #define SYMBOL 1
//             ^
//   Macro defined here.
//     'SYMBOL' expanded to: '2' with respect to these inclusion paths:
//       (...)/Header2.h
//           (...)/SubHeader.h
//   (...)/SubHeader.h:7:9:
//   #define SYMBOL 2
//             ^
//   Macro defined here.
//
// Checks will also be performed for '#include' directives that are
// nested inside 'extern "C/C++" {}' or 'namespace (name) {}' blocks,
// and can produce error message like the following:
//
// IncludeInExtern.h:2:3
//   #include "Empty.h"
//   ^
// error: Include directive within extern "C" {}.
// IncludeInExtern.h:1:1
// extern "C" {
// ^
// The "extern "C" {}" block is here.
//
// See PreprocessorTracker.cpp for additional details.
//
// Module Map Coverage Check
//
// The coverage check uses the Clang ModuleMap class to read and parse the
// module map file.  Starting at the module map file directory, or just the
// include paths, if specified, it will collect the names of all the files it
// considers headers (no extension, .h, or .inc--if you need more, modify the
// isHeader function).  It then compares the headers against those referenced
// in the module map, either explicitly named, or implicitly named via an
// umbrella directory or umbrella file, as parsed by the ModuleMap object.
// If headers are found which are not referenced or covered by an umbrella
// directory or file, warning messages will be produced, and this program
// will return an error code of 1.  Other errors result in an error code of 2.
// If no problems are found, an error code of 0 is returned.
//
// Note that in the case of umbrella headers, this tool invokes the compiler
// to preprocess the file, and uses a callback to collect the header files
// included by the umbrella header or any of its nested includes.  If any
// front end options are needed for these compiler invocations, these
// can be included on the command line after the module map file argument.
//
// Warning message have the form:
//
//  warning: module.modulemap does not account for file: Level3A.h
//
// Note that for the case of the module map referencing a file that does
// not exist, the module map parser in Clang will (at the time of this
// writing) display an error message.
//
// Module Map Assistant - Module Map Generation
//
// Modularize also has an option ("-module-map-path=module.modulemap") that will
// skip the checks, and instead act as a module.modulemap generation assistant,
// generating a module map file based on the header list.  An optional
// "-root-module=(rootName)" argument can specify a root module to be
// created in the generated module.modulemap file.  Note that you will likely
// need to edit this file to suit the needs of your headers.
//
// An example command line for generating a module.modulemap file:
//
//   modularize -module-map-path=module.modulemap -root-module=myroot \
//      headerlist.txt
//
// Note that if the headers in the header list have partial paths, sub-modules
// will be created for the subdirectires involved, assuming that the
// subdirectories contain headers to be grouped into a module, but still with
// individual modules for the headers in the subdirectory.
//
// See the ModuleAssistant.cpp file comments for additional details about the
// implementation of the assistant mode.
//
// Future directions:
//
// Basically, we want to add new checks for whatever we can check with respect
// to checking headers for module'ability.
//
// Some ideas:
//
// 1. Omit duplicate "not always provided" messages
//
// 2. Add options to disable any of the checks, in case
// there is some problem with them, or the messages get too verbose.
//
// 3. Try to figure out the preprocessor conditional directives that
// contribute to problems and tie them to the inconsistent definitions.
//
// 4. There are some legitimate uses of preprocessor macros that
// modularize will flag as errors, such as repeatedly #include'ing
// a file and using interleaving defined/undefined macros
// to change declarations in the included file.  Is there a way
// to address this?  Maybe have modularize accept a list of macros
// to ignore.  Otherwise you can just exclude the file, after checking
// for legitimate errors.
//
// 5. What else?
//
// General clean-up and refactoring:
//
// 1. The Location class seems to be something that we might
// want to design to be applicable to a wider range of tools, and stick it
// somewhere into Tooling/ in mainline
//
//===----------------------------------------------------------------------===//

#include "Modularize.h"
#include "ModularizeUtilities.h"
#include "PreprocessorTracker.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include <algorithm>
#include <fstream>
#include <iterator>
#include <string>
#include <vector>

using namespace clang;
using namespace clang::driver;
using namespace clang::driver::options;
using namespace clang::tooling;
using namespace llvm;
using namespace llvm::opt;
using namespace Modularize;

// Option to specify a file name for a list of header files to check.
static cl::list<std::string>
    ListFileNames(cl::Positional, cl::value_desc("list"),
                  cl::desc("<list of one or more header list files>"),
                  cl::CommaSeparated);

// Collect all other arguments, which will be passed to the front end.
static cl::list<std::string>
    CC1Arguments(cl::ConsumeAfter,
                 cl::desc("<arguments to be passed to front end>..."));

// Option to specify a prefix to be prepended to the header names.
static cl::opt<std::string> HeaderPrefix(
    "prefix", cl::init(""),
    cl::desc(
        "Prepend header file paths with this prefix."
        " If not specified,"
        " the files are considered to be relative to the header list file."));

// Option for assistant mode, telling modularize to output a module map
// based on the headers list, and where to put it.
static cl::opt<std::string> ModuleMapPath(
    "module-map-path", cl::init(""),
    cl::desc("Turn on module map output and specify output path or file name."
             " If no path is specified and if prefix option is specified,"
             " use prefix for file path."));

// Option to specify list of problem files for assistant.
// This will cause assistant to exclude these files.
static cl::opt<std::string> ProblemFilesList(
  "problem-files-list", cl::init(""),
  cl::desc(
  "List of files with compilation or modularization problems for"
    " assistant mode.  This will be excluded."));

// Option for assistant mode, telling modularize the name of the root module.
static cl::opt<std::string>
RootModule("root-module", cl::init(""),
           cl::desc("Specify the name of the root module."));

// Option for limiting the #include-inside-extern-or-namespace-block
// check to only those headers explicitly listed in the header list.
// This is a work-around for private includes that purposefully get
// included inside blocks.
static cl::opt<bool>
BlockCheckHeaderListOnly("block-check-header-list-only", cl::init(false),
cl::desc("Only warn if #include directives are inside extern or namespace"
  " blocks if the included header is in the header list."));

// Option for include paths for coverage check.
static cl::list<std::string>
IncludePaths("I", cl::desc("Include path for coverage check."),
cl::ZeroOrMore, cl::value_desc("path"));

// Option for disabling the coverage check.
static cl::opt<bool>
NoCoverageCheck("no-coverage-check", cl::init(false),
cl::desc("Don't do the coverage check."));

// Option for just doing the coverage check.
static cl::opt<bool>
CoverageCheckOnly("coverage-check-only", cl::init(false),
cl::desc("Only do the coverage check."));

// Option for displaying lists of good, bad, and mixed files.
static cl::opt<bool>
DisplayFileLists("display-file-lists", cl::init(false),
cl::desc("Display lists of good files (no compile errors), problem files,"
  " and a combined list with problem files preceded by a '#'."));

// Save the program name for error messages.
const char *Argv0;
// Save the command line for comments.
std::string CommandLine;

// Helper function for finding the input file in an arguments list.
static std::string findInputFile(const CommandLineArguments &CLArgs) {
  std::unique_ptr<OptTable> Opts(createDriverOptTable());
  const unsigned IncludedFlagsBitmask = options::CC1Option;
  unsigned MissingArgIndex, MissingArgCount;
  SmallVector<const char *, 256> Argv;
  for (CommandLineArguments::const_iterator I = CLArgs.begin(),
                                            E = CLArgs.end();
       I != E; ++I)
    Argv.push_back(I->c_str());
  InputArgList Args = Opts->ParseArgs(Argv, MissingArgIndex, MissingArgCount,
                                      IncludedFlagsBitmask);
  std::vector<std::string> Inputs = Args.getAllArgValues(OPT_INPUT);
  return ModularizeUtilities::getCanonicalPath(Inputs.back());
}

// This arguments adjuster inserts "-include (file)" arguments for header
// dependencies.  It also inserts a "-w" option and a "-x c++",
// if no other "-x" option is present.
static ArgumentsAdjuster
getModularizeArgumentsAdjuster(DependencyMap &Dependencies) {
  return [&Dependencies](const CommandLineArguments &Args) {
    std::string InputFile = findInputFile(Args);
    DependentsVector &FileDependents = Dependencies[InputFile];
    CommandLineArguments NewArgs(Args);
    if (int Count = FileDependents.size()) {
      for (int Index = 0; Index < Count; ++Index) {
        NewArgs.push_back("-include");
        std::string File(std::string("\"") + FileDependents[Index] +
                         std::string("\""));
        NewArgs.push_back(FileDependents[Index]);
      }
    }
    // Ignore warnings.  (Insert after "clang_tool" at beginning.)
    NewArgs.insert(NewArgs.begin() + 1, "-w");
    // Since we are compiling .h files, assume C++ unless given a -x option.
    if (std::find(NewArgs.begin(), NewArgs.end(), "-x") == NewArgs.end()) {
      NewArgs.insert(NewArgs.begin() + 2, "-x");
      NewArgs.insert(NewArgs.begin() + 3, "c++");
    }
    return NewArgs;
  };
}

// FIXME: The Location class seems to be something that we might
// want to design to be applicable to a wider range of tools, and stick it
// somewhere into Tooling/ in mainline
struct Location {
  const FileEntry *File;
  unsigned Line, Column;

  Location() : File(), Line(), Column() {}

  Location(SourceManager &SM, SourceLocation Loc) : File(), Line(), Column() {
    Loc = SM.getExpansionLoc(Loc);
    if (Loc.isInvalid())
      return;

    std::pair<FileID, unsigned> Decomposed = SM.getDecomposedLoc(Loc);
    File = SM.getFileEntryForID(Decomposed.first);
    if (!File)
      return;

    Line = SM.getLineNumber(Decomposed.first, Decomposed.second);
    Column = SM.getColumnNumber(Decomposed.first, Decomposed.second);
  }

  operator bool() const { return File != nullptr; }

  friend bool operator==(const Location &X, const Location &Y) {
    return X.File == Y.File && X.Line == Y.Line && X.Column == Y.Column;
  }

  friend bool operator!=(const Location &X, const Location &Y) {
    return !(X == Y);
  }

  friend bool operator<(const Location &X, const Location &Y) {
    if (X.File != Y.File)
      return X.File < Y.File;
    if (X.Line != Y.Line)
      return X.Line < Y.Line;
    return X.Column < Y.Column;
  }
  friend bool operator>(const Location &X, const Location &Y) { return Y < X; }
  friend bool operator<=(const Location &X, const Location &Y) {
    return !(Y < X);
  }
  friend bool operator>=(const Location &X, const Location &Y) {
    return !(X < Y);
  }
};

struct Entry {
  enum EntryKind {
    EK_Tag,
    EK_Value,
    EK_Macro,

    EK_NumberOfKinds
  } Kind;

  Location Loc;

  StringRef getKindName() { return getKindName(Kind); }
  static StringRef getKindName(EntryKind kind);
};

// Return a string representing the given kind.
StringRef Entry::getKindName(Entry::EntryKind kind) {
  switch (kind) {
  case EK_Tag:
    return "tag";
  case EK_Value:
    return "value";
  case EK_Macro:
    return "macro";
  case EK_NumberOfKinds:
    break;
  }
  llvm_unreachable("invalid Entry kind");
}

struct HeaderEntry {
  std::string Name;
  Location Loc;

  friend bool operator==(const HeaderEntry &X, const HeaderEntry &Y) {
    return X.Loc == Y.Loc && X.Name == Y.Name;
  }
  friend bool operator!=(const HeaderEntry &X, const HeaderEntry &Y) {
    return !(X == Y);
  }
  friend bool operator<(const HeaderEntry &X, const HeaderEntry &Y) {
    return X.Loc < Y.Loc || (X.Loc == Y.Loc && X.Name < Y.Name);
  }
  friend bool operator>(const HeaderEntry &X, const HeaderEntry &Y) {
    return Y < X;
  }
  friend bool operator<=(const HeaderEntry &X, const HeaderEntry &Y) {
    return !(Y < X);
  }
  friend bool operator>=(const HeaderEntry &X, const HeaderEntry &Y) {
    return !(X < Y);
  }
};

typedef std::vector<HeaderEntry> HeaderContents;

class EntityMap : public StringMap<SmallVector<Entry, 2> > {
public:
  DenseMap<const FileEntry *, HeaderContents> HeaderContentMismatches;

  void add(const std::string &Name, enum Entry::EntryKind Kind, Location Loc) {
    // Record this entity in its header.
    HeaderEntry HE = { Name, Loc };
    CurHeaderContents[Loc.File].push_back(HE);

    // Check whether we've seen this entry before.
    SmallVector<Entry, 2> &Entries = (*this)[Name];
    for (unsigned I = 0, N = Entries.size(); I != N; ++I) {
      if (Entries[I].Kind == Kind && Entries[I].Loc == Loc)
        return;
    }

    // We have not seen this entry before; record it.
    Entry E = { Kind, Loc };
    Entries.push_back(E);
  }

  void mergeCurHeaderContents() {
    for (DenseMap<const FileEntry *, HeaderContents>::iterator
             H = CurHeaderContents.begin(),
             HEnd = CurHeaderContents.end();
         H != HEnd; ++H) {
      // Sort contents.
      std::sort(H->second.begin(), H->second.end());

      // Check whether we've seen this header before.
      DenseMap<const FileEntry *, HeaderContents>::iterator KnownH =
          AllHeaderContents.find(H->first);
      if (KnownH == AllHeaderContents.end()) {
        // We haven't seen this header before; record its contents.
        AllHeaderContents.insert(*H);
        continue;
      }

      // If the header contents are the same, we're done.
      if (H->second == KnownH->second)
        continue;

      // Determine what changed.
      std::set_symmetric_difference(
          H->second.begin(), H->second.end(), KnownH->second.begin(),
          KnownH->second.end(),
          std::back_inserter(HeaderContentMismatches[H->first]));
    }

    CurHeaderContents.clear();
  }

private:
  DenseMap<const FileEntry *, HeaderContents> CurHeaderContents;
  DenseMap<const FileEntry *, HeaderContents> AllHeaderContents;
};

class CollectEntitiesVisitor
    : public RecursiveASTVisitor<CollectEntitiesVisitor> {
public:
  CollectEntitiesVisitor(SourceManager &SM, EntityMap &Entities,
                         Preprocessor &PP, PreprocessorTracker &PPTracker,
                         int &HadErrors)
      : SM(SM), Entities(Entities), PP(PP), PPTracker(PPTracker),
        HadErrors(HadErrors) {}

  bool TraverseStmt(Stmt *S) { return true; }
  bool TraverseType(QualType T) { return true; }
  bool TraverseTypeLoc(TypeLoc TL) { return true; }
  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { return true; }
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
    return true;
  }
  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo) {
    return true;
  }
  bool TraverseTemplateName(TemplateName Template) { return true; }
  bool TraverseTemplateArgument(const TemplateArgument &Arg) { return true; }
  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
    return true;
  }
  bool TraverseTemplateArguments(const TemplateArgument *Args,
                                 unsigned NumArgs) {
    return true;
  }
  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { return true; }
  bool TraverseLambdaCapture(LambdaCapture C) { return true; }

  // Check 'extern "*" {}' block for #include directives.
  bool VisitLinkageSpecDecl(LinkageSpecDecl *D) {
    // Bail if not a block.
    if (!D->hasBraces())
      return true;
    SourceRange BlockRange = D->getSourceRange();
    const char *LinkageLabel;
    switch (D->getLanguage()) {
    case LinkageSpecDecl::lang_c:
      LinkageLabel = "extern \"C\" {}";
      break;
    case LinkageSpecDecl::lang_cxx:
      LinkageLabel = "extern \"C++\" {}";
      break;
    }
    if (!PPTracker.checkForIncludesInBlock(PP, BlockRange, LinkageLabel,
                                           errs()))
      HadErrors = 1;
    return true;
  }

  // Check 'namespace (name) {}' block for #include directives.
  bool VisitNamespaceDecl(const NamespaceDecl *D) {
    SourceRange BlockRange = D->getSourceRange();
    std::string Label("namespace ");
    Label += D->getName();
    Label += " {}";
    if (!PPTracker.checkForIncludesInBlock(PP, BlockRange, Label.c_str(),
                                           errs()))
      HadErrors = 1;
    return true;
  }

  // Collect definition entities.
  bool VisitNamedDecl(NamedDecl *ND) {
    // We only care about file-context variables.
    if (!ND->getDeclContext()->isFileContext())
      return true;

    // Skip declarations that tend to be properly multiply-declared.
    if (isa<NamespaceDecl>(ND) || isa<UsingDirectiveDecl>(ND) ||
        isa<NamespaceAliasDecl>(ND) ||
        isa<ClassTemplateSpecializationDecl>(ND) || isa<UsingDecl>(ND) ||
        isa<ClassTemplateDecl>(ND) || isa<TemplateTypeParmDecl>(ND) ||
        isa<TypeAliasTemplateDecl>(ND) || isa<UsingShadowDecl>(ND) ||
        isa<FunctionDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
        (isa<TagDecl>(ND) &&
         !cast<TagDecl>(ND)->isThisDeclarationADefinition()))
      return true;

    // Skip anonymous declarations.
    if (!ND->getDeclName())
      return true;

    // Get the qualified name.
    std::string Name;
    llvm::raw_string_ostream OS(Name);
    ND->printQualifiedName(OS);
    OS.flush();
    if (Name.empty())
      return true;

    Location Loc(SM, ND->getLocation());
    if (!Loc)
      return true;

    Entities.add(Name, isa<TagDecl>(ND) ? Entry::EK_Tag : Entry::EK_Value, Loc);
    return true;
  }

private:
  SourceManager &SM;
  EntityMap &Entities;
  Preprocessor &PP;
  PreprocessorTracker &PPTracker;
  int &HadErrors;
};

class CollectEntitiesConsumer : public ASTConsumer {
public:
  CollectEntitiesConsumer(EntityMap &Entities,
                          PreprocessorTracker &preprocessorTracker,
                          Preprocessor &PP, StringRef InFile, int &HadErrors)
      : Entities(Entities), PPTracker(preprocessorTracker), PP(PP),
        HadErrors(HadErrors) {
    PPTracker.handlePreprocessorEntry(PP, InFile);
  }

  ~CollectEntitiesConsumer() override { PPTracker.handlePreprocessorExit(); }

  void HandleTranslationUnit(ASTContext &Ctx) override {
    SourceManager &SM = Ctx.getSourceManager();

    // Collect declared entities.
    CollectEntitiesVisitor(SM, Entities, PP, PPTracker, HadErrors)
        .TraverseDecl(Ctx.getTranslationUnitDecl());

    // Collect macro definitions.
    for (Preprocessor::macro_iterator M = PP.macro_begin(),
                                      MEnd = PP.macro_end();
         M != MEnd; ++M) {
      Location Loc(SM, M->second.getLatest()->getLocation());
      if (!Loc)
        continue;

      Entities.add(M->first->getName().str(), Entry::EK_Macro, Loc);
    }

    // Merge header contents.
    Entities.mergeCurHeaderContents();
  }

private:
  EntityMap &Entities;
  PreprocessorTracker &PPTracker;
  Preprocessor &PP;
  int &HadErrors;
};

class CollectEntitiesAction : public SyntaxOnlyAction {
public:
  CollectEntitiesAction(EntityMap &Entities,
                        PreprocessorTracker &preprocessorTracker,
                        int &HadErrors)
      : Entities(Entities), PPTracker(preprocessorTracker),
        HadErrors(HadErrors) {}

protected:
  std::unique_ptr<clang::ASTConsumer>
  CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
    return llvm::make_unique<CollectEntitiesConsumer>(
        Entities, PPTracker, CI.getPreprocessor(), InFile, HadErrors);
  }

private:
  EntityMap &Entities;
  PreprocessorTracker &PPTracker;
  int &HadErrors;
};

class ModularizeFrontendActionFactory : public FrontendActionFactory {
public:
  ModularizeFrontendActionFactory(EntityMap &Entities,
                                  PreprocessorTracker &preprocessorTracker,
                                  int &HadErrors)
      : Entities(Entities), PPTracker(preprocessorTracker),
        HadErrors(HadErrors) {}

  CollectEntitiesAction *create() override {
    return new CollectEntitiesAction(Entities, PPTracker, HadErrors);
  }

private:
  EntityMap &Entities;
  PreprocessorTracker &PPTracker;
  int &HadErrors;
};

class CompileCheckVisitor
  : public RecursiveASTVisitor<CompileCheckVisitor> {
public:
  CompileCheckVisitor() {}

  bool TraverseStmt(Stmt *S) { return true; }
  bool TraverseType(QualType T) { return true; }
  bool TraverseTypeLoc(TypeLoc TL) { return true; }
  bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) { return true; }
  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
    return true;
  }
  bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo) {
    return true;
  }
  bool TraverseTemplateName(TemplateName Template) { return true; }
  bool TraverseTemplateArgument(const TemplateArgument &Arg) { return true; }
  bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc) {
    return true;
  }
  bool TraverseTemplateArguments(const TemplateArgument *Args,
    unsigned NumArgs) {
    return true;
  }
  bool TraverseConstructorInitializer(CXXCtorInitializer *Init) { return true; }
  bool TraverseLambdaCapture(LambdaCapture C) { return true; }

  // Check 'extern "*" {}' block for #include directives.
  bool VisitLinkageSpecDecl(LinkageSpecDecl *D) {
    return true;
  }

  // Check 'namespace (name) {}' block for #include directives.
  bool VisitNamespaceDecl(const NamespaceDecl *D) {
    return true;
  }

  // Collect definition entities.
  bool VisitNamedDecl(NamedDecl *ND) {
    return true;
  }
};

class CompileCheckConsumer : public ASTConsumer {
public:
  CompileCheckConsumer() {}

  void HandleTranslationUnit(ASTContext &Ctx) override {
    CompileCheckVisitor().TraverseDecl(Ctx.getTranslationUnitDecl());
  }
};

class CompileCheckAction : public SyntaxOnlyAction {
public:
  CompileCheckAction() {}

protected:
  std::unique_ptr<clang::ASTConsumer>
    CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override {
    return llvm::make_unique<CompileCheckConsumer>();
  }
};

class CompileCheckFrontendActionFactory : public FrontendActionFactory {
public:
  CompileCheckFrontendActionFactory() {}

  CompileCheckAction *create() override {
    return new CompileCheckAction();
  }
};

int main(int Argc, const char **Argv) {

  // Save program name for error messages.
  Argv0 = Argv[0];

  // Save program arguments for use in module.modulemap comment.
  CommandLine = sys::path::stem(sys::path::filename(Argv0));
  for (int ArgIndex = 1; ArgIndex < Argc; ArgIndex++) {
    CommandLine.append(" ");
    CommandLine.append(Argv[ArgIndex]);
  }

  // This causes options to be parsed.
  cl::ParseCommandLineOptions(Argc, Argv, "modularize.\n");

  // No go if we have no header list file.
  if (ListFileNames.size() == 0) {
    cl::PrintHelpMessage();
    return 1;
  }

  std::unique_ptr<ModularizeUtilities> ModUtil;
  int HadErrors = 0;

  ModUtil.reset(
    ModularizeUtilities::createModularizeUtilities(
      ListFileNames, HeaderPrefix, ProblemFilesList));

  // Get header file names and dependencies.
  if (ModUtil->loadAllHeaderListsAndDependencies())
    HadErrors = 1;

  // If we are in assistant mode, output the module map and quit.
  if (ModuleMapPath.length() != 0) {
    if (!createModuleMap(ModuleMapPath, ModUtil->HeaderFileNames,
                         ModUtil->ProblemFileNames,
                         ModUtil->Dependencies, HeaderPrefix, RootModule))
      return 1; // Failed.
    return 0;   // Success - Skip checks in assistant mode.
  }

  // If we're doing module maps.
  if (!NoCoverageCheck && ModUtil->HasModuleMap) {
    // Do coverage check.
    if (ModUtil->doCoverageCheck(IncludePaths, CommandLine))
      HadErrors = 1;
  }

  // Bail early if only doing the coverage check.
  if (CoverageCheckOnly)
    return HadErrors;

  // Create the compilation database.
  SmallString<256> PathBuf;
  sys::fs::current_path(PathBuf);
  std::unique_ptr<CompilationDatabase> Compilations;
  Compilations.reset(
      new FixedCompilationDatabase(Twine(PathBuf), CC1Arguments));

  // Create preprocessor tracker, to watch for macro and conditional problems.
  std::unique_ptr<PreprocessorTracker> PPTracker(
    PreprocessorTracker::create(ModUtil->HeaderFileNames,
                                BlockCheckHeaderListOnly));

  // Coolect entities here.
  EntityMap Entities;

  // Because we can't easily determine which files failed
  // during the tool run, if we're collecting the file lists
  // for display, we do a first compile pass on individual
  // files to find which ones don't compile stand-alone.
  if (DisplayFileLists) {
    // First, make a pass to just get compile errors.
    for (auto &CompileCheckFile : ModUtil->HeaderFileNames) {
      llvm::SmallVector<std::string, 32> CompileCheckFileArray;
      CompileCheckFileArray.push_back(CompileCheckFile);
      ClangTool CompileCheckTool(*Compilations, CompileCheckFileArray);
      CompileCheckTool.appendArgumentsAdjuster(
        getModularizeArgumentsAdjuster(ModUtil->Dependencies));
      int CompileCheckFileErrors = 0;
      CompileCheckFrontendActionFactory CompileCheckFactory;
      CompileCheckFileErrors |= CompileCheckTool.run(&CompileCheckFactory);
      if (CompileCheckFileErrors != 0) {
        ModUtil->addUniqueProblemFile(CompileCheckFile);   // Save problem file.
        HadErrors |= 1;
      }
      else
        ModUtil->addNoCompileErrorsFile(CompileCheckFile); // Save good file.
    }
  }

  // Then we make another pass on the good files to do the rest of the work.
  ClangTool Tool(*Compilations,
    (DisplayFileLists ? ModUtil->GoodFileNames : ModUtil->HeaderFileNames));
  Tool.appendArgumentsAdjuster(
    getModularizeArgumentsAdjuster(ModUtil->Dependencies));
  ModularizeFrontendActionFactory Factory(Entities, *PPTracker, HadErrors);
  HadErrors |= Tool.run(&Factory);

  // Create a place to save duplicate entity locations, separate bins per kind.
  typedef SmallVector<Location, 8> LocationArray;
  typedef SmallVector<LocationArray, Entry::EK_NumberOfKinds> EntryBinArray;
  EntryBinArray EntryBins;
  int KindIndex;
  for (KindIndex = 0; KindIndex < Entry::EK_NumberOfKinds; ++KindIndex) {
    LocationArray Array;
    EntryBins.push_back(Array);
  }

  // Check for the same entity being defined in multiple places.
  for (EntityMap::iterator E = Entities.begin(), EEnd = Entities.end();
       E != EEnd; ++E) {
    // If only one occurrence, exit early.
    if (E->second.size() == 1)
      continue;
    // Clear entity locations.
    for (EntryBinArray::iterator CI = EntryBins.begin(), CE = EntryBins.end();
         CI != CE; ++CI) {
      CI->clear();
    }
    // Walk the entities of a single name, collecting the locations,
    // separated into separate bins.
    for (unsigned I = 0, N = E->second.size(); I != N; ++I) {
      EntryBins[E->second[I].Kind].push_back(E->second[I].Loc);
    }
    // Report any duplicate entity definition errors.
    int KindIndex = 0;
    for (EntryBinArray::iterator DI = EntryBins.begin(), DE = EntryBins.end();
         DI != DE; ++DI, ++KindIndex) {
      int ECount = DI->size();
      // If only 1 occurrence of this entity, skip it, we only report duplicates.
      if (ECount <= 1)
        continue;
      LocationArray::iterator FI = DI->begin();
      StringRef kindName = Entry::getKindName((Entry::EntryKind)KindIndex);
      errs() << "error: " << kindName << " '" << E->first()
             << "' defined at multiple locations:\n";
      for (LocationArray::iterator FE = DI->end(); FI != FE; ++FI) {
        errs() << "    " << FI->File->getName() << ":" << FI->Line << ":"
               << FI->Column << "\n";
        ModUtil->addUniqueProblemFile(FI->File->getName());
      }
      HadErrors = 1;
    }
  }

  // Complain about macro instance in header files that differ based on how
  // they are included.
  if (PPTracker->reportInconsistentMacros(errs()))
    HadErrors = 1;

  // Complain about preprocessor conditional directives in header files that
  // differ based on how they are included.
  if (PPTracker->reportInconsistentConditionals(errs()))
    HadErrors = 1;

  // Complain about any headers that have contents that differ based on how
  // they are included.
  // FIXME: Could we provide information about which preprocessor conditionals
  // are involved?
  for (DenseMap<const FileEntry *, HeaderContents>::iterator
           H = Entities.HeaderContentMismatches.begin(),
           HEnd = Entities.HeaderContentMismatches.end();
       H != HEnd; ++H) {
    if (H->second.empty()) {
      errs() << "internal error: phantom header content mismatch\n";
      continue;
    }

    HadErrors = 1;
    ModUtil->addUniqueProblemFile(H->first->getName());
    errs() << "error: header '" << H->first->getName()
           << "' has different contents depending on how it was included.\n";
    for (unsigned I = 0, N = H->second.size(); I != N; ++I) {
      errs() << "note: '" << H->second[I].Name << "' in "
             << H->second[I].Loc.File->getName() << " at "
             << H->second[I].Loc.Line << ":" << H->second[I].Loc.Column
             << " not always provided\n";
    }
  }

  if (DisplayFileLists) {
    ModUtil->displayProblemFiles();
    ModUtil->displayGoodFiles();
    ModUtil->displayCombinedFiles();
  }

  return HadErrors;
}
