diff options
author | Aaron Ballman <aaron@aaronballman.com> | 2018-04-16 21:07:08 +0000 |
---|---|---|
committer | Aaron Ballman <aaron@aaronballman.com> | 2018-04-16 21:07:08 +0000 |
commit | d742dc20d9809b36a7eec6a1f64c48755e2e5778 (patch) | |
tree | 0baae19648845980c797de4180103438c251459b /clang/unittests/libclang/LibclangTest.cpp | |
parent | 040888b6239358fa4abb495796e308d1d75c0e1d (diff) | |
download | llvm-d742dc20d9809b36a7eec6a1f64c48755e2e5778.zip llvm-d742dc20d9809b36a7eec6a1f64c48755e2e5778.tar.gz llvm-d742dc20d9809b36a7eec6a1f64c48755e2e5778.tar.bz2 |
Defer adding keywords to the identifier table until after the language options have been loaded from the AST file.
This fixes issues with "class" being reported as an identifier in "enum class" because the construct is not present when using default language options.
Patch by Johann Klähn.
llvm-svn: 330159
Diffstat (limited to 'clang/unittests/libclang/LibclangTest.cpp')
-rw-r--r-- | clang/unittests/libclang/LibclangTest.cpp | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp index 17a5067..262ed26 100644 --- a/clang/unittests/libclang/LibclangTest.cpp +++ b/clang/unittests/libclang/LibclangTest.cpp @@ -698,3 +698,67 @@ TEST_F(LibclangReparseTest, PreprocessorSkippedRanges) { clang_disposeSourceRangeList(Ranges); } } + +class LibclangSerializationTest : public LibclangParseTest { +public: + bool SaveAndLoadTU(const std::string &Filename) { + unsigned options = clang_defaultSaveOptions(ClangTU); + if (clang_saveTranslationUnit(ClangTU, Filename.c_str(), options) != + CXSaveError_None) { + DEBUG(llvm::dbgs() << "Saving failed\n"); + return false; + } + + clang_disposeTranslationUnit(ClangTU); + + ClangTU = clang_createTranslationUnit(Index, Filename.c_str()); + + if (!ClangTU) { + DEBUG(llvm::dbgs() << "Loading failed\n"); + return false; + } + + return true; + } +}; + +TEST_F(LibclangSerializationTest, TokenKindsAreCorrectAfterLoading) { + // Ensure that "class" is recognized as a keyword token after serializing + // and reloading the AST, as it is not a keyword for the default LangOptions. + std::string HeaderName = "test.h"; + WriteFile(HeaderName, "enum class Something {};"); + + const char *Argv[] = {"-xc++-header", "-std=c++11"}; + + ClangTU = clang_parseTranslationUnit(Index, HeaderName.c_str(), Argv, + sizeof(Argv) / sizeof(Argv[0]), nullptr, + 0, TUFlags); + + auto CheckTokenKinds = [=]() { + CXSourceRange Range = + clang_getCursorExtent(clang_getTranslationUnitCursor(ClangTU)); + + CXToken *Tokens; + unsigned int NumTokens; + clang_tokenize(ClangTU, Range, &Tokens, &NumTokens); + + ASSERT_EQ(6u, NumTokens); + EXPECT_EQ(CXToken_Keyword, clang_getTokenKind(Tokens[0])); + EXPECT_EQ(CXToken_Keyword, clang_getTokenKind(Tokens[1])); + EXPECT_EQ(CXToken_Identifier, clang_getTokenKind(Tokens[2])); + EXPECT_EQ(CXToken_Punctuation, clang_getTokenKind(Tokens[3])); + EXPECT_EQ(CXToken_Punctuation, clang_getTokenKind(Tokens[4])); + EXPECT_EQ(CXToken_Punctuation, clang_getTokenKind(Tokens[5])); + + clang_disposeTokens(ClangTU, Tokens, NumTokens); + }; + + CheckTokenKinds(); + + std::string ASTName = "test.ast"; + WriteFile(ASTName, ""); + + ASSERT_TRUE(SaveAndLoadTU(ASTName)); + + CheckTokenKinds(); +} |