Exemple #1
0
ClangTool::ClangTool(const CompilationDatabase &Compilations,
                     ArrayRef<std::string> SourcePaths)
    : Files(new FileManager(FileSystemOptions())), DiagConsumer(NULL) {
  ArgsAdjusters.push_back(new ClangStripOutputAdjuster());
  ArgsAdjusters.push_back(new ClangSyntaxOnlyAdjuster());
  for (const auto &SourcePath : SourcePaths) {
    std::string File(getAbsolutePath(SourcePath));

    std::vector<CompileCommand> CompileCommandsForFile =
      Compilations.getCompileCommands(File);
    if (!CompileCommandsForFile.empty()) {
      for (CompileCommand &CompileCommand : CompileCommandsForFile) {
        CompileCommands.push_back(
            std::make_pair(File, std::move(CompileCommand)));
      }
    } else {
      // FIXME: There are two use cases here: doing a fuzzy
      // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
      // about the .cc files that were not found, and the use case where I
      // specify all files I want to run over explicitly, where this should
      // be an error. We'll want to add an option for this.
      llvm::errs() << "Skipping " << File << ". Compile command not found.\n";
    }
  }
}
chimera::cd_utils::CompileCommandVector
chimera::cd_utils::getCompileCommandsByFilePath(
    const CompilationDatabase &database, StringRef filename) {
  // First search for the correct "file"
  Twine targetFilePath = Twine(filename);
  std::string foundFilePath;
  ChimeraLogger::verboseAndIncr("Retrieving compileCommands for " +
                                targetFilePath.str());
  // Find the foundFilename to access specific compileCommands
  // Get all "file" field of the compilation database
  auto compileFile = database.getAllFiles();
  // Check if it's empty
  if (!compileFile.empty()) {
    // This isn't a FixedCompilationDatabase
    for (auto file = compileFile.begin(); file != compileFile.end(); ++file) {
      // Compare with targetFilename
      Twine filePathToCompare(*file);
      ChimeraLogger::verbose("Comparing with File: " + *file);
      // llvm::sys::fs::equivalent to test the really equivalence
      if (llvm::sys::fs::equivalent(targetFilePath, filePathToCompare)) {
        ChimeraLogger::verbose("Successful. Match found!");
        foundFilePath = *file;
        break;
      }
    }
  } else {
    // This is a FixedCompilationDatabase
    ChimeraLogger::verbose(
        "CompilationDatabase with an empty filelist. Maybe provided by hand");
    foundFilePath = targetFilePath.str();
  }
  ChimeraLogger::decrActualVLevel();
  // Return compileCommands
  return database.getCompileCommands(foundFilePath);
}
Exemple #3
0
ClangTool::ClangTool(const CompilationDatabase &Compilations,
                     ArrayRef<std::string> SourcePaths)
    : Files((FileSystemOptions())),
      ArgsAdjuster(new ClangSyntaxOnlyAdjuster()) {
  llvm::SmallString<1024> BaseDirectory;
  if (const char *PWD = ::getenv("PWD"))
    BaseDirectory = PWD;
  else
    llvm::sys::fs::current_path(BaseDirectory);
  for (unsigned I = 0, E = SourcePaths.size(); I != E; ++I) {
    llvm::SmallString<1024> File(getAbsolutePath(
        SourcePaths[I], BaseDirectory));

    std::vector<CompileCommand> CompileCommandsForFile =
      Compilations.getCompileCommands(File.str());
    if (!CompileCommandsForFile.empty()) {
      for (int I = 0, E = CompileCommandsForFile.size(); I != E; ++I) {
        CompileCommands.push_back(std::make_pair(File.str(),
                                  CompileCommandsForFile[I]));
      }
    } else {
      // FIXME: There are two use cases here: doing a fuzzy
      // "find . -name '*.cc' |xargs tool" match, where as a user I don't care
      // about the .cc files that were not found, and the use case where I
      // specify all files I want to run over explicitly, where this should
      // be an error. We'll want to add an option for this.
      llvm::outs() << "Skipping " << File << ". Command line not found.\n";
    }
  }
}
TranslationUnit::TranslationUnit(Index& index, const std::string& source,
                                 CompilationDatabase& comp_db) {
    auto commands = comp_db.getCompileCommands(source);
    unsigned cmd_args = commands.getSize();
    if (cmd_args == 0) {
        throw std::runtime_error("No compilation info for file `" + source +
                                 "`");
    }
    auto command = commands.getCommand(0);
    auto arguments = command.GetArguments(1);
    arguments.push_back("-I" + comp_db.GetClangHeadersLocation());
    std::vector<const char*> c_arguments;
    c_arguments.reserve(arguments.size());
    bool skip = false;
    for (auto& arg : arguments) {
        if (skip) {
            skip = false;
            continue;
        }
        if (arg == "-c") {
            skip = true;
            continue;
        }
        c_arguments.push_back(arg.c_str());
    }
    CXErrorCode code = clang_parseTranslationUnit2(
        index.index_, source.c_str(), c_arguments.data(), c_arguments.size(),
        nullptr, 0, CXTranslationUnit_DetailedPreprocessingRecord, &unit_);
    if (code != CXError_Success) {
        throw std::runtime_error("Error while parsing file `" + source + "`: " +
                                 ErrorCodeToString(code));
    }
}