diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2018-07-09 19:41:28 +0000 |
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2018-07-09 19:41:28 +0000 |
| commit | 81f157b40fbc5c369a9a118143bb559a2ecd93f7 (patch) | |
| tree | 7c553f3ad531cf787589678a5966ded8ffbfe6be /clang | |
| parent | 9481399c0fd2c198c81b92636c0dcff7d4c41df2 (diff) | |
| download | bcm5719-llvm-81f157b40fbc5c369a9a118143bb559a2ecd93f7.tar.gz bcm5719-llvm-81f157b40fbc5c369a9a118143bb559a2ecd93f7.zip | |
[libclang] evalute compound statement cursors before trying to evaluate
the cursor like a declaration
This change fixes a bug in libclang in which it tries to evaluate a statement
cursor as a declaration cursor, because that statement still has a pointer to
the declaration parent.
rdar://38888477
Differential Revision: https://reviews.llvm.org/D49051
llvm-svn: 336590
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/tools/libclang/CIndex.cpp | 26 | ||||
| -rw-r--r-- | clang/unittests/libclang/LibclangTest.cpp | 41 |
2 files changed, 54 insertions, 13 deletions
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index b61dff32380..a4698830d9c 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3890,6 +3890,19 @@ static const ExprEvalResult* evaluateExpr(Expr *expr, CXCursor C) { } CXEvalResult clang_Cursor_Evaluate(CXCursor C) { + if (clang_getCursorKind(C) == CXCursor_CompoundStmt) { + const CompoundStmt *compoundStmt = cast<CompoundStmt>(getCursorStmt(C)); + Expr *expr = nullptr; + for (auto *bodyIterator : compoundStmt->body()) { + if ((expr = dyn_cast<Expr>(bodyIterator))) { + break; + } + } + if (expr) + return const_cast<CXEvalResult>( + reinterpret_cast<const void *>(evaluateExpr(expr, C))); + } + const Decl *D = getCursorDecl(C); if (D) { const Expr *expr = nullptr; @@ -3903,19 +3916,6 @@ CXEvalResult clang_Cursor_Evaluate(CXCursor C) { evaluateExpr(const_cast<Expr *>(expr), C))); return nullptr; } - - const CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(getCursorStmt(C)); - if (compoundStmt) { - Expr *expr = nullptr; - for (auto *bodyIterator : compoundStmt->body()) { - if ((expr = dyn_cast<Expr>(bodyIterator))) { - break; - } - } - if (expr) - return const_cast<CXEvalResult>( - reinterpret_cast<const void *>(evaluateExpr(expr, C))); - } return nullptr; } diff --git a/clang/unittests/libclang/LibclangTest.cpp b/clang/unittests/libclang/LibclangTest.cpp index 6fddcb2cbf2..9629b624751 100644 --- a/clang/unittests/libclang/LibclangTest.cpp +++ b/clang/unittests/libclang/LibclangTest.cpp @@ -461,6 +461,47 @@ TEST_F(LibclangParseTest, AllSkippedRanges) { clang_disposeSourceRangeList(Ranges); } +TEST_F(LibclangParseTest, EvaluateChildExpression) { + std::string Main = "main.m"; + WriteFile(Main, "#define kFOO @\"foo\"\n" + "void foobar(void) {\n" + " {kFOO;}\n" + "}\n"); + ClangTU = clang_parseTranslationUnit(Index, Main.c_str(), nullptr, 0, nullptr, + 0, TUFlags); + + CXCursor C = clang_getTranslationUnitCursor(ClangTU); + clang_visitChildren( + C, + [](CXCursor cursor, CXCursor parent, + CXClientData client_data) -> CXChildVisitResult { + if (clang_getCursorKind(cursor) == CXCursor_FunctionDecl) { + int numberedStmt = 0; + clang_visitChildren( + cursor, + [](CXCursor cursor, CXCursor parent, + CXClientData client_data) -> CXChildVisitResult { + int &numberedStmt = *((int *)client_data); + if (clang_getCursorKind(cursor) == CXCursor_CompoundStmt) { + if (numberedStmt) { + CXEvalResult RE = clang_Cursor_Evaluate(cursor); + EXPECT_NE(RE, nullptr); + EXPECT_EQ(clang_EvalResult_getKind(RE), + CXEval_ObjCStrLiteral); + return CXChildVisit_Break; + } + numberedStmt++; + } + return CXChildVisit_Recurse; + }, + &numberedStmt); + EXPECT_EQ(numberedStmt, 1); + } + return CXChildVisit_Continue; + }, + nullptr); +} + class LibclangReparseTest : public LibclangParseTest { public: void DisplayDiagnostics() { |

