Index: clang-tools-extra/trunk/include-fixer/CMakeLists.txt =================================================================== --- clang-tools-extra/trunk/include-fixer/CMakeLists.txt +++ clang-tools-extra/trunk/include-fixer/CMakeLists.txt @@ -5,6 +5,7 @@ add_clang_library(clangIncludeFixer IncludeFixer.cpp InMemoryXrefsDB.cpp + YamlXrefsDB.cpp LINK_LIBS clangAST @@ -15,6 +16,7 @@ clangSema clangTooling clangToolingCore + findAllSymbols ) add_subdirectory(tool) Index: clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h =================================================================== --- clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h +++ clang-tools-extra/trunk/include-fixer/YamlXrefsDB.h @@ -0,0 +1,35 @@ +//===-- YamlXrefsDB.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_YAMLXREFSDB_H +#define LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_YAMLXREFSDB_H + +#include "XrefsDB.h" +#include "find-all-symbols/SymbolInfo.h" +#include +#include + +namespace clang { +namespace include_fixer { + +/// Yaml format database. +class YamlXrefsDB : public XrefsDB { +public: + YamlXrefsDB(llvm::StringRef FilePath); + + std::vector search(llvm::StringRef Identifier) override; + +private: + std::vector Symbols; +}; + +} // namespace include_fixer +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_INCLUDE_FIXER_YAMLXREFSDB_H Index: clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp =================================================================== --- clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp +++ clang-tools-extra/trunk/include-fixer/YamlXrefsDB.cpp @@ -0,0 +1,64 @@ +//===-- YamlXrefsDB.cpp ---------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "YamlXrefsDB.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" +#include +#include + +namespace clang { +namespace include_fixer { + +YamlXrefsDB::YamlXrefsDB(llvm::StringRef FilePath) { + int ReadFD = 0; + if (llvm::sys::fs::openFileForRead(FilePath, ReadFD)) + return; + auto Buffer = llvm::MemoryBuffer::getOpenFile(ReadFD, FilePath, -1); + if (!Buffer) + return; + Symbols = clang::find_all_symbols::ReadSymbolInfosFromYAML( + Buffer.get()->getBuffer()); +} + +std::vector YamlXrefsDB::search(llvm::StringRef Identifier) { + llvm::SmallVector Names; + std::vector Results; + + // The identifier may be fully qualified, so split it and get all the context + // names. + Identifier.split(Names, "::"); + for (const auto &Symbol : Symbols) { + // Match the identifier name without qualifier. + if (Symbol.Name == Names.back()) { + bool IsMatched = true; + auto SymbolContext = Symbol.Contexts.begin(); + // Match the remaining context names. + for (auto IdentiferContext = Names.rbegin() + 1; + IdentiferContext != Names.rend() && + SymbolContext != Symbol.Contexts.end(); + ++IdentiferContext, ++SymbolContext) { + if (SymbolContext->second != *IdentiferContext) { + IsMatched = false; + break; + } + } + + if (IsMatched) { + Results.push_back("\"" + Symbol.FilePath + "\""); + } + } + } + return Results; +} + +} // namespace include_fixer +} // namespace clang Index: clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp =================================================================== --- clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp +++ clang-tools-extra/trunk/include-fixer/tool/ClangIncludeFixer.cpp @@ -9,11 +9,13 @@ #include "InMemoryXrefsDB.h" #include "IncludeFixer.h" +#include "YamlXrefsDB.h" #include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Rewrite/Core/Rewriter.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" #include "llvm/Support/CommandLine.h" + using namespace clang; using namespace llvm; @@ -22,11 +24,14 @@ enum DatabaseFormatTy { fixed, ///< Hard-coded mapping. + yaml, ///< Yaml database created by find-all-symbols. }; cl::opt DatabaseFormat( "db", cl::desc("Specify input format"), - cl::values(clEnumVal(fixed, "Hard-coded mapping"), clEnumValEnd), + cl::values(clEnumVal(fixed, "Hard-coded mapping"), + clEnumVal(yaml, "Yaml database created by find-all-symbols"), + clEnumValEnd), cl::init(fixed), cl::cat(IncludeFixerCategory)); cl::opt Input("input", @@ -67,6 +72,10 @@ llvm::make_unique(std::move(XrefsMap)); break; } + case yaml: { + XrefsDB = llvm::make_unique(Input); + break; + } } // Now run our tool. Index: clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml =================================================================== --- clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml +++ clang-tools-extra/trunk/test/include-fixer/Inputs/fake_yaml_db.yaml @@ -0,0 +1,11 @@ +--- +Name: foo +Contexts: + - ContextType: Namespace + ContextName: a + - ContextType: Namespace + ContextName: b +FilePath: foo.h +LineNumber: 1 +Type: Class +... Index: clang-tools-extra/trunk/test/include-fixer/yamldb.cpp =================================================================== --- clang-tools-extra/trunk/test/include-fixer/yamldb.cpp +++ clang-tools-extra/trunk/test/include-fixer/yamldb.cpp @@ -0,0 +1,9 @@ +// REQUIRES: shell +// RUN: sed -e 's#//.*$##' %s > %t.cpp +// RUN: clang-include-fixer -db=yaml -input=%p/Inputs/fake_yaml_db.yaml %t.cpp -- +// RUN: FileCheck %s -input-file=%t.cpp + +// CHECK: #include "foo.h" +// CHECK: b::a::foo f; + +b::a::foo f;