summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2018-07-09 19:41:28 +0000
committerAlex Lorenz <arphaman@gmail.com>2018-07-09 19:41:28 +0000
commit81f157b40fbc5c369a9a118143bb559a2ecd93f7 (patch)
tree7c553f3ad531cf787589678a5966ded8ffbfe6be /clang
parent9481399c0fd2c198c81b92636c0dcff7d4c41df2 (diff)
downloadbcm5719-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.cpp26
-rw-r--r--clang/unittests/libclang/LibclangTest.cpp41
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() {
OpenPOWER on IntegriCloud