summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2014-06-27 17:04:26 +0000
committerBen Langmuir <blangmuir@apple.com>2014-06-27 17:04:26 +0000
commit54d7831c3b8f99ed297abd939f1cd6a884c03a99 (patch)
tree5cfc5721060916707d6464aff56446ebd46f9203
parentba02d7e2a8adb18f8b4ca6e486a68105a31c52ca (diff)
downloadclang-54d7831c3b8f99ed297abd939f1cd6a884c03a99.tar.gz
clang-54d7831c3b8f99ed297abd939f1cd6a884c03a99.tar.bz2
clang-54d7831c3b8f99ed297abd939f1cd6a884c03a99.tar.xz
Add reparse test for libclang
Adapted from a reproducer by Dan Schmidt, thanks! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@211910 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--unittests/libclang/LibclangTest.cpp89
1 files changed, 89 insertions, 0 deletions
diff --git a/unittests/libclang/LibclangTest.cpp b/unittests/libclang/LibclangTest.cpp
index b69b2ac11f..20f742ef4c 100644
--- a/unittests/libclang/LibclangTest.cpp
+++ b/unittests/libclang/LibclangTest.cpp
@@ -9,6 +9,13 @@
#include "clang-c/Index.h"
#include "gtest/gtest.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
+#include <fstream>
+#include <set>
+#define DEBUG_TYPE "libclang-test"
TEST(libclang, clang_parseTranslationUnit2_InvalidArgs) {
EXPECT_EQ(CXError_InvalidArguments,
@@ -331,3 +338,85 @@ TEST(libclang, ModuleMapDescriptor) {
free(BufPtr);
clang_ModuleMapDescriptor_dispose(MMD);
}
+
+class LibclangReparseTest : public ::testing::Test {
+ std::string TestDir;
+ std::set<std::string> Files;
+public:
+ CXIndex Index;
+ CXTranslationUnit ClangTU;
+ unsigned TUFlags;
+
+ void SetUp() {
+ llvm::SmallString<256> Dir;
+ ASSERT_FALSE(llvm::sys::fs::createUniqueDirectory("libclang-test", Dir));
+ TestDir = Dir.str();
+ TUFlags = CXTranslationUnit_DetailedPreprocessingRecord |
+ clang_defaultEditingTranslationUnitOptions();
+ Index = clang_createIndex(0, 0);
+ }
+ void TearDown() {
+ clang_disposeTranslationUnit(ClangTU);
+ clang_disposeIndex(Index);
+ for (const std::string &Path : Files)
+ llvm::sys::fs::remove(Path);
+ llvm::sys::fs::remove(TestDir);
+ }
+ void WriteFile(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();
+ Files.insert(Filename);
+ }
+ std::ofstream OS(Filename);
+ OS << Contents;
+ }
+ void DisplayDiagnostics() {
+ uint NumDiagnostics = clang_getNumDiagnostics(ClangTU);
+ for (uint i = 0; i < NumDiagnostics; ++i) {
+ auto Diag = clang_getDiagnostic(ClangTU, i);
+ DEBUG(llvm::dbgs() << clang_getCString(clang_formatDiagnostic(
+ Diag, clang_defaultDiagnosticDisplayOptions())) << "\n");
+ clang_disposeDiagnostic(Diag);
+ }
+ }
+ bool ReparseTU(uint num_unsaved_files, CXUnsavedFile* unsaved_files) {
+ if (clang_reparseTranslationUnit(ClangTU, num_unsaved_files, unsaved_files,
+ clang_defaultReparseOptions(ClangTU))) {
+ DEBUG(llvm::dbgs() << "Reparse failed\n");
+ return false;
+ }
+ DisplayDiagnostics();
+ return true;
+ }
+};
+
+
+TEST_F(LibclangReparseTest, Reparse) {
+ const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
+ const char *HeaderBottom = "\n};\n#endif\n";
+ const char *CppFile = "#include \"HeaderFile.h\"\nint main() {"
+ " Foo foo; foo.bar = 7; foo.baz = 8; }\n";
+ std::string HeaderName = "HeaderFile.h";
+ std::string CppName = "CppFile.cpp";
+ WriteFile(CppName, CppFile);
+ WriteFile(HeaderName, std::string(HeaderTop) + HeaderBottom);
+
+ ClangTU = clang_parseTranslationUnit(Index, CppName.c_str(), nullptr, 0,
+ nullptr, 0, TUFlags);
+ EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+ DisplayDiagnostics();
+
+ // Immedaitely reparse.
+ ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+ EXPECT_EQ(1U, clang_getNumDiagnostics(ClangTU));
+
+ std::string NewHeaderContents =
+ std::string(HeaderTop) + "int baz;" + HeaderBottom;
+ WriteFile(HeaderName, NewHeaderContents);
+
+ // Reparse after fix.
+ ASSERT_TRUE(ReparseTU(0, nullptr /* No unsaved files. */));
+ EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
+}