diff options
author | Cameron Desrochers <cameron@moodycamel.com> | 2016-08-18 15:43:55 +0000 |
---|---|---|
committer | Cameron Desrochers <cameron@moodycamel.com> | 2016-08-18 15:43:55 +0000 |
commit | d80912871d9a96fa06b904ee73113defe3ff8689 (patch) | |
tree | fd8b8e60d6e087aaeb88253bab4af2d825a15d49 /clang/unittests/libclang/LibclangTest.cpp | |
parent | ccdceda1282fa48f304e0cd0c1b6f6861be7dcd3 (diff) | |
download | llvm-d80912871d9a96fa06b904ee73113defe3ff8689.zip llvm-d80912871d9a96fa06b904ee73113defe3ff8689.tar.gz llvm-d80912871d9a96fa06b904ee73113defe3ff8689.tar.bz2 |
[libclang] Add clang_getAllSkippedRanges function
This complements the clang_getSkippedRanges function which returns skipped ranges filtered by a specific file.
This function is useful when all the ranges are desired (and a lot more efficient than the equivalent of asking for the ranges file by file, since the implementation of clang_getSkippedRanges iterates over all ranges anyway).
Differential Revision: https://reviews.llvm.org/D20132
llvm-svn: 279076
Diffstat (limited to 'clang/unittests/libclang/LibclangTest.cpp')
-rw-r--r-- | clang/unittests/libclang/LibclangTest.cpp | 82 |
1 files changed, 80 insertions, 2 deletions
diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp index d5c7827..78229a1 100644 --- a/clang/unittests/libclang/LibclangTest.cpp +++ b/clang/unittests/libclang/LibclangTest.cpp @@ -14,6 +14,9 @@ #include "llvm/Support/raw_ostream.h" #include "gtest/gtest.h" #include <fstream> +#include <functional> +#include <map> +#include <memory> #include <set> #define DEBUG_TYPE "libclang-test" @@ -349,21 +352,25 @@ TEST(libclang, ModuleMapDescriptor) { clang_ModuleMapDescriptor_dispose(MMD); } -class LibclangReparseTest : public ::testing::Test { +class LibclangParseTest : public ::testing::Test { std::set<std::string> Files; + typedef std::unique_ptr<std::string> fixed_addr_string; + std::map<fixed_addr_string, fixed_addr_string> UnsavedFileContents; public: std::string TestDir; CXIndex Index; CXTranslationUnit ClangTU; unsigned TUFlags; + std::vector<CXUnsavedFile> UnsavedFiles; void SetUp() override { llvm::SmallString<256> Dir; ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir)); TestDir = Dir.str(); TUFlags = CXTranslationUnit_DetailedPreprocessingRecord | - clang_defaultEditingTranslationUnitOptions(); + clang_defaultEditingTranslationUnitOptions(); Index = clang_createIndex(0, 0); + ClangTU = nullptr; } void TearDown() override { clang_disposeTranslationUnit(ClangTU); @@ -384,6 +391,77 @@ public: OS << Contents; assert(OS.good()); } + void MapUnsavedFile(std::string Filename, const std::string &Contents) { + if (!llvm::sys::path::is_absolute(Filename)) { + llvm::SmallString<256> Path(TestDir); + llvm::sys::path::append(Path, Filename); + Filename = Path.str(); + } + auto it = UnsavedFileContents.emplace( + fixed_addr_string(new std::string(Filename)), + fixed_addr_string(new std::string(Contents))); + UnsavedFiles.push_back({ + it.first->first->c_str(), // filename + it.first->second->c_str(), // contents + it.first->second->size() // length + }); + } + template<typename F> + void Traverse(const F &TraversalFunctor) { + CXCursor TuCursor = clang_getTranslationUnitCursor(ClangTU); + std::reference_wrapper<const F> FunctorRef = std::cref(TraversalFunctor); + clang_visitChildren(TuCursor, + &TraverseStateless<std::reference_wrapper<const F>>, + &FunctorRef); + } +private: + template<typename TState> + static CXChildVisitResult TraverseStateless(CXCursor cx, CXCursor parent, + CXClientData data) { + TState *State = static_cast<TState*>(data); + return State->get()(cx, parent); + } +}; + +TEST_F(LibclangParseTest, AllSkippedRanges) { + std::string Header = "header.h", Main = "main.cpp"; + WriteFile(Header, + "#ifdef MANGOS\n" + "printf(\"mmm\");\n" + "#endif"); + WriteFile(Main, + "#include \"header.h\"\n" + "#ifdef KIWIS\n" + "printf(\"mmm!!\");\n" + "#endif"); + + ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, + nullptr, 0, TUFlags); + + CXSourceRangeList *Ranges = clang_getAllSkippedRanges(ClangTU); + EXPECT_EQ(2, Ranges->count); + + CXSourceLocation cxl; + unsigned line; + cxl = clang_getRangeStart(Ranges->ranges[0]); + clang_getSpellingLocation(cxl, nullptr, &line, nullptr, nullptr); + EXPECT_EQ(1, line); + cxl = clang_getRangeEnd(Ranges->ranges[0]); + clang_getSpellingLocation(cxl, nullptr, &line, nullptr, nullptr); + EXPECT_EQ(3, line); + + cxl = clang_getRangeStart(Ranges->ranges[1]); + clang_getSpellingLocation(cxl, nullptr, &line, nullptr, nullptr); + EXPECT_EQ(2, line); + cxl = clang_getRangeEnd(Ranges->ranges[1]); + clang_getSpellingLocation(cxl, nullptr, &line, nullptr, nullptr); + EXPECT_EQ(4, line); + + clang_disposeSourceRangeList(Ranges); +} + +class LibclangReparseTest : public LibclangParseTest { +public: void DisplayDiagnostics() { unsigned NumDiagnostics = clang_getNumDiagnostics(ClangTU); for (unsigned i = 0; i < NumDiagnostics; ++i) { |