summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/include-fixer/YamlXrefsDB.cpp34
-rw-r--r--clang-tools-extra/include-fixer/YamlXrefsDB.h11
-rw-r--r--clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp22
-rw-r--r--clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp12
4 files changed, 67 insertions, 12 deletions
diff --git a/clang-tools-extra/include-fixer/YamlXrefsDB.cpp b/clang-tools-extra/include-fixer/YamlXrefsDB.cpp
index 2311ed88352..45889975fa4 100644
--- a/clang-tools-extra/include-fixer/YamlXrefsDB.cpp
+++ b/clang-tools-extra/include-fixer/YamlXrefsDB.cpp
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "YamlXrefsDB.h"
-
#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Errc.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
#include <string>
#include <vector>
@@ -20,15 +21,30 @@ using clang::find_all_symbols::SymbolInfo;
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);
+llvm::ErrorOr<std::unique_ptr<YamlXrefsDB>>
+YamlXrefsDB::createFromFile(llvm::StringRef FilePath) {
+ auto Buffer = llvm::MemoryBuffer::getFile(FilePath);
if (!Buffer)
- return;
- Symbols = clang::find_all_symbols::ReadSymbolInfosFromYAML(
- Buffer.get()->getBuffer());
+ return Buffer.getError();
+
+ return std::unique_ptr<YamlXrefsDB>(
+ new YamlXrefsDB(clang::find_all_symbols::ReadSymbolInfosFromYAML(
+ Buffer.get()->getBuffer())));
+}
+
+llvm::ErrorOr<std::unique_ptr<YamlXrefsDB>>
+YamlXrefsDB::createFromDirectory(llvm::StringRef Directory,
+ llvm::StringRef Name) {
+ // Walk upwards from Directory, looking for files.
+ for (llvm::SmallString<128> PathStorage = Directory; !Directory.empty();
+ Directory = llvm::sys::path::parent_path(Directory)) {
+ assert(Directory.size() <= PathStorage.size());
+ PathStorage.resize(Directory.size()); // Shrink to parent.
+ llvm::sys::path::append(PathStorage, Name);
+ if (auto DB = createFromFile(PathStorage))
+ return DB;
+ }
+ return llvm::make_error_code(llvm::errc::no_such_file_or_directory);
}
std::vector<SymbolInfo> YamlXrefsDB::search(llvm::StringRef Identifier) {
diff --git a/clang-tools-extra/include-fixer/YamlXrefsDB.h b/clang-tools-extra/include-fixer/YamlXrefsDB.h
index 1efed6bce8a..9901431e411 100644
--- a/clang-tools-extra/include-fixer/YamlXrefsDB.h
+++ b/clang-tools-extra/include-fixer/YamlXrefsDB.h
@@ -12,6 +12,7 @@
#include "XrefsDB.h"
#include "find-all-symbols/SymbolInfo.h"
+#include "llvm/Support/ErrorOr.h"
#include <map>
#include <vector>
@@ -21,12 +22,20 @@ namespace include_fixer {
/// Yaml format database.
class YamlXrefsDB : public XrefsDB {
public:
- YamlXrefsDB(llvm::StringRef FilePath);
+ /// Create a new Yaml db from a file.
+ static llvm::ErrorOr<std::unique_ptr<YamlXrefsDB>>
+ createFromFile(llvm::StringRef FilePath);
+ /// Look for a file called \c Name in \c Directory and all parent directories.
+ static llvm::ErrorOr<std::unique_ptr<YamlXrefsDB>>
+ createFromDirectory(llvm::StringRef Directory, llvm::StringRef Name);
std::vector<clang::find_all_symbols::SymbolInfo>
search(llvm::StringRef Identifier) override;
private:
+ explicit YamlXrefsDB(std::vector<clang::find_all_symbols::SymbolInfo> Symbols)
+ : Symbols(std::move(Symbols)) {}
+
std::vector<clang::find_all_symbols::SymbolInfo> Symbols;
};
diff --git a/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp b/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp
index 8e37a3484a5..9419f6dfbee 100644
--- a/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp
+++ b/clang-tools-extra/include-fixer/tool/ClangIncludeFixer.cpp
@@ -73,8 +73,26 @@ int includeFixerMain(int argc, const char **argv) {
break;
}
case yaml: {
- XrefsDBMgr->addXrefsDB(
- llvm::make_unique<include_fixer::YamlXrefsDB>(Input));
+ llvm::ErrorOr<std::unique_ptr<include_fixer::YamlXrefsDB>> DB(nullptr);
+ if (!Input.empty()) {
+ DB = include_fixer::YamlXrefsDB::createFromFile(Input);
+ } else {
+ // If we don't have any input file, look in the directory of the first
+ // file and its parents.
+ SmallString<128> AbsolutePath(
+ tooling::getAbsolutePath(options.getSourcePathList().front()));
+ StringRef Directory = llvm::sys::path::parent_path(AbsolutePath);
+ DB = include_fixer::YamlXrefsDB::createFromDirectory(
+ Directory, "find_all_symbols_db.yaml");
+ }
+
+ if (!DB) {
+ llvm::errs() << "Couldn't find YAML db: " << DB.getError().message()
+ << '\n';
+ return 1;
+ }
+
+ XrefsDBMgr->addXrefsDB(std::move(*DB));
break;
}
}
diff --git a/clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp b/clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp
new file mode 100644
index 00000000000..9206668aa7b
--- /dev/null
+++ b/clang-tools-extra/test/include-fixer/yamldb_autodetect.cpp
@@ -0,0 +1,12 @@
+// REQUIRES: shell
+// RUN: mkdir -p %T/foo/bar
+// RUN: cp %p/Inputs/fake_yaml_db.yaml %T/find_all_symbols_db.yaml
+// RUN: cd %T/foo
+// RUN: sed -e 's#//.*$##' %s > bar/test.cpp
+// RUN: clang-include-fixer -db=yaml bar/test.cpp --
+// RUN: FileCheck %s -input-file=bar/test.cpp
+
+// CHECK: #include "foo.h"
+// CHECK: b::a::foo f;
+
+b::a::foo f;
OpenPOWER on IntegriCloud