r350666 - [libclang] Recommit r336590 with a fix for the memory leak in the test
Alex Lorenz via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 8 14:32:52 PST 2019
Author: arphaman
Date: Tue Jan 8 14:32:51 2019
New Revision: 350666
URL: http://llvm.org/viewvc/llvm-project?rev=350666&view=rev
Log:
[libclang] Recommit r336590 with a fix for the memory leak in the test
The original commit had a memory leak in the test has a leak as it doesn't
dispose of the evaluated cursor result.
This also contains the follow-up NFC refactoring commit r336591.
rdar://45893054
Original commit message:
[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
Modified:
cfe/trunk/tools/libclang/CIndex.cpp
cfe/trunk/unittests/libclang/LibclangTest.cpp
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=350666&r1=350665&r2=350666&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Tue Jan 8 14:32:51 2019
@@ -3902,36 +3902,35 @@ static const ExprEvalResult* evaluateExp
return nullptr;
}
-CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
- const Decl *D = getCursorDecl(C);
- if (D) {
- const Expr *expr = nullptr;
- if (auto *Var = dyn_cast<VarDecl>(D)) {
- expr = Var->getInit();
- } else if (auto *Field = dyn_cast<FieldDecl>(D)) {
- expr = Field->getInClassInitializer();
- }
- if (expr)
- return const_cast<CXEvalResult>(reinterpret_cast<const void *>(
- evaluateExpr(const_cast<Expr *>(expr), C)));
+static const Expr *evaluateDeclExpr(const Decl *D) {
+ if (!D)
return nullptr;
- }
+ if (auto *Var = dyn_cast<VarDecl>(D))
+ return Var->getInit();
+ else if (auto *Field = dyn_cast<FieldDecl>(D))
+ return Field->getInClassInitializer();
+ 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)));
+static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
+ assert(CS && "invalid compound statement");
+ for (auto *bodyIterator : CS->body()) {
+ if (const auto *E = dyn_cast<Expr>(bodyIterator))
+ return E;
}
return nullptr;
}
+CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
+ if (const Expr *E =
+ clang_getCursorKind(C) == CXCursor_CompoundStmt
+ ? evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)))
+ : evaluateDeclExpr(getCursorDecl(C)))
+ return const_cast<CXEvalResult>(
+ reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
+ return nullptr;
+}
+
unsigned clang_Cursor_hasAttrs(CXCursor C) {
const Decl *D = getCursorDecl(C);
if (!D) {
Modified: cfe/trunk/unittests/libclang/LibclangTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/libclang/LibclangTest.cpp?rev=350666&r1=350665&r2=350666&view=diff
==============================================================================
--- cfe/trunk/unittests/libclang/LibclangTest.cpp (original)
+++ cfe/trunk/unittests/libclang/LibclangTest.cpp Tue Jan 8 14:32:51 2019
@@ -461,6 +461,48 @@ TEST_F(LibclangParseTest, AllSkippedRang
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);
+ clang_EvalResult_dispose(RE);
+ return CXChildVisit_Break;
+ }
+ numberedStmt++;
+ }
+ return CXChildVisit_Recurse;
+ },
+ &numberedStmt);
+ EXPECT_EQ(numberedStmt, 1);
+ }
+ return CXChildVisit_Continue;
+ },
+ nullptr);
+}
+
class LibclangReparseTest : public LibclangParseTest {
public:
void DisplayDiagnostics() {
More information about the cfe-commits
mailing list