Skip to content

Commit 34590ae

Browse files
hahnjoJonas Hahnfeld
andcommitted
[cling] Create new CompoundStmt instead of replacing children
For the update of LLVM 9, Cling required another patch to Clang for replacing the children of a CompoundStmt. Instead solve this by creating a new CompoundStmt with the right Stmts attached. Co-authored-by: Jonas Hahnfeld <[email protected]> Co-authored-by: Jonas Hahnfeld <[email protected]>
1 parent f5b4562 commit 34590ae

File tree

6 files changed

+73
-34
lines changed

6 files changed

+73
-34
lines changed

interpreter/cling/lib/Interpreter/AutoSynthesizer.cpp

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ namespace cling {
2525
public:
2626
AutoFixer(Sema* S) : m_Sema(S), m_FoundDRE(0) {}
2727

28-
void Fix(CompoundStmt* CS) {
28+
CompoundStmt* Fix(CompoundStmt* CS) {
2929
if (!CS->size())
30-
return;
30+
return nullptr;
3131
typedef llvm::SmallVector<Stmt*, 32> Statements;
3232
Statements Stmts;
3333
Stmts.append(CS->body_begin(), CS->body_end());
@@ -44,18 +44,30 @@ namespace cling {
4444
}
4545
}
4646
if (CS->size() != Stmts.size())
47-
CS->replaceStmts(m_Sema->getASTContext(), Stmts);
47+
return CompoundStmt::Create(m_Sema->getASTContext(), Stmts,
48+
CS->getLBracLoc(), CS->getRBracLoc());
49+
return nullptr;
4850
}
4951

50-
void Fix(CXXTryStmt* TS) {
51-
Fix(TS->getTryBlock());
52-
for(unsigned int h = 0; h < TS->getNumHandlers(); ++h) {
53-
Stmt *s = TS->getHandler(h)->getHandlerBlock();
54-
if (CompoundStmt* CS = dyn_cast_or_null<CompoundStmt>(s))
55-
Fix(CS);
56-
else if (CXXTryStmt *HandlerTS = dyn_cast_or_null<CXXTryStmt>(s))
57-
Fix(HandlerTS);
52+
CXXTryStmt* Fix(CXXTryStmt* TS) {
53+
CompoundStmt *TryBlock = TS->getTryBlock();
54+
if (CompoundStmt *NewTryBlock = Fix(TryBlock))
55+
TryBlock = NewTryBlock;
56+
57+
llvm::SmallVector<Stmt*, 4> Handlers(TS->getNumHandlers());
58+
for (unsigned int h = 0; h < TS->getNumHandlers(); ++h) {
59+
Stmt *HandlerBlock = TS->getHandler(h)->getHandlerBlock();
60+
if (CompoundStmt *HandlerCS = dyn_cast_or_null<CompoundStmt>(HandlerBlock)) {
61+
if (CompoundStmt *NewHandlerCS = Fix(HandlerCS))
62+
HandlerBlock = NewHandlerCS;
63+
} else if (CXXTryStmt *HandlerTS = dyn_cast_or_null<CXXTryStmt>(HandlerBlock)) {
64+
if (CXXTryStmt *NewHandlerTS = Fix(HandlerTS))
65+
HandlerBlock = NewHandlerTS;
66+
}
5867
}
68+
69+
return CXXTryStmt::Create(m_Sema->getASTContext(), TS->getTryLoc(),
70+
TryBlock, Handlers);
5971
}
6072

6173
bool VisitDeclRefExpr(DeclRefExpr* DRE) {
@@ -92,9 +104,12 @@ namespace cling {
92104
// those.
93105
Stmt *Body = FD->getBody();
94106
if (CompoundStmt* CS = dyn_cast_or_null<CompoundStmt>(Body))
95-
m_AutoFixer->Fix(CS);
107+
Body = m_AutoFixer->Fix(CS);
96108
else if (CXXTryStmt *TS = dyn_cast_or_null<CXXTryStmt>(Body))
97-
m_AutoFixer->Fix(TS);
109+
Body = m_AutoFixer->Fix(TS);
110+
111+
if (Body != nullptr)
112+
FD->setBody(Body);
98113
}
99114
return Result(D, true);
100115
}

interpreter/cling/lib/Interpreter/DeclExtractor.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,10 @@ namespace cling {
211211
}
212212
}
213213

214-
CS->replaceStmts(*m_Context, Stmts);
214+
// Create a new body.
215+
auto newCS = CompoundStmt::Create(*m_Context, Stmts, CS->getLBracLoc(),
216+
CS->getRBracLoc());
217+
FD->setBody(newCS);
215218

216219
if (hasNoErrors && !TouchedDecls.empty()) {
217220
// Put the wrapper after its declarations. (Nice when AST dumping)

interpreter/cling/lib/Interpreter/DynamicLookup.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -289,12 +289,12 @@ namespace cling {
289289
"Cannot have more than one stmt at that point");
290290

291291
if (NewNode.isForReplacement()) {
292-
if (Expr* E = NewNode.getAs<Expr>())
292+
if (Expr* E = NewNode.getAs<Expr>()) {
293293
// Assume void if still not escaped
294294
*I = SubstituteUnknownSymbol(m_Context->VoidTy, E);
295-
}
296-
else {
297-
*I = NewNode.getAsSingleNode();
295+
} else {
296+
*I = NewNode.getAsSingleNode();
297+
}
298298
}
299299
}
300300
}
@@ -328,14 +328,21 @@ namespace cling {
328328
// where we know what to do. For Stmt, though, we need to substitute here,
329329
// knowing the "target" type.
330330
ASTNodeInfo thenInfo = Visit(Node->getThen());
331-
if (thenInfo.isForReplacement())
332-
Node->setThen(SubstituteUnknownSymbol(m_Context->VoidTy,
333-
thenInfo.getAs<Expr>()));
331+
if (thenInfo.isForReplacement()) {
332+
Stmt* thenReplacement = thenInfo.getAsSingleNode();
333+
if (Expr* thenExpr = dyn_cast<Expr>(thenReplacement))
334+
thenReplacement = SubstituteUnknownSymbol(m_Context->VoidTy, thenExpr);
335+
Node->setThen(thenReplacement);
336+
}
334337
if (Stmt* ElseExpr = Node->getElse()) {
335338
ASTNodeInfo elseInfo = Visit(ElseExpr);
336-
if (elseInfo.isForReplacement())
337-
Node->setElse(SubstituteUnknownSymbol(m_Context->VoidTy,
338-
elseInfo.getAs<Expr>()));
339+
if (elseInfo.isForReplacement()) {
340+
Stmt* elseReplacement = elseInfo.getAsSingleNode();
341+
if (Expr* elseExpr = dyn_cast<Expr>(elseReplacement))
342+
elseReplacement =
343+
SubstituteUnknownSymbol(m_Context->VoidTy, elseExpr);
344+
Node->setElse(elseReplacement);
345+
}
339346
}
340347

341348
return ASTNodeInfo(Node, false);
@@ -382,10 +389,12 @@ namespace cling {
382389
}
383390
}
384391

385-
Node->replaceStmts(*m_Context, NewChildren);
392+
auto* NewCS = CompoundStmt::Create(*m_Context, NewChildren,
393+
Node->getLBracLoc(),
394+
Node->getRBracLoc());
386395

387396
--m_NestedCompoundStmts;
388-
return ASTNodeInfo(Node, 0);
397+
return ASTNodeInfo(NewCS, true);
389398
}
390399

391400
ASTNodeInfo EvaluateTSynthesizer::VisitDeclStmt(DeclStmt* Node) {

interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ namespace cling {
105105
*(CS->body_begin()+indexOfLastExpr) = Result;
106106
}
107107
// Clear the artificial NullStmt-s
108-
if (!ClearNullStmts(CS)) {
108+
if (!ClearNullStmts(FD)) {
109109
// FIXME: Why it is here? Shouldn't it be in DeclExtractor?
110110
// if no body remove the wrapper
111111
DeclContext* DC = FD->getDeclContext();
@@ -166,14 +166,24 @@ namespace cling {
166166
}
167167

168168

169-
unsigned ValuePrinterSynthesizer::ClearNullStmts(CompoundStmt* CS) {
169+
unsigned ValuePrinterSynthesizer::ClearNullStmts(FunctionDecl* FD) {
170+
CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
171+
assert(CS && "Missing body?");
172+
170173
llvm::SmallVector<Stmt*, 8> FBody;
171174
for (auto&& child: CS->children())
172175
if (!isa<NullStmt>(child))
173176
FBody.push_back(child);
174177

175-
if (CS->size() != FBody.size())
176-
CS->replaceStmts(*m_Context, FBody);
178+
// If body would be empty, return early - the function will be removed.
179+
if (FBody.empty())
180+
return 0;
181+
182+
if (CS->size() != FBody.size()) {
183+
auto BodyCS = CompoundStmt::Create(*m_Context, FBody, CS->getLBracLoc(),
184+
CS->getRBracLoc());
185+
FD->setBody(BodyCS);
186+
}
177187

178188
return FBody.size();
179189
}

interpreter/cling/lib/Interpreter/ValuePrinterSynthesizer.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
namespace clang {
1818
class ASTContext;
19-
class CompoundStmt;
2019
class Decl;
2120
class FunctionDecl;
2221
class Expr;
@@ -63,7 +62,7 @@ namespace cling {
6362
/// critical error.
6463
bool tryAttachVP(clang::FunctionDecl* FD);
6564
clang::Expr* SynthesizeVP(clang::Expr* E);
66-
unsigned ClearNullStmts(clang::CompoundStmt* CS);
65+
unsigned ClearNullStmts(clang::FunctionDecl* FD);
6766

6867
// Find and cache cling::runtime on first request.
6968
void FindAndCacheRuntimeLookupResult(clang::SourceLocation SourceLoc);

interpreter/cling/lib/Utils/AST.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,8 +169,11 @@ namespace utils {
169169
indexOfLastExpr++;
170170
newBody.insert(newBody.begin() + indexOfLastExpr, DRE);
171171

172-
// Attach the new body (note: it does dealloc/alloc of all nodes)
173-
CS->replaceStmts(S->getASTContext(), newBody);
172+
// Attach a new body.
173+
auto newCS = CompoundStmt::Create(S->getASTContext(), newBody,
174+
CS->getLBracLoc(),
175+
CS->getRBracLoc());
176+
FD->setBody(newCS);
174177
if (FoundAt)
175178
*FoundAt = indexOfLastExpr;
176179
return DRE;

0 commit comments

Comments
 (0)