diff --git a/lib/Interpreter/AutoSynthesizer.cpp b/lib/Interpreter/AutoSynthesizer.cpp index a7e49848..af6f3d0a 100644 --- a/lib/Interpreter/AutoSynthesizer.cpp +++ b/lib/Interpreter/AutoSynthesizer.cpp @@ -43,7 +43,7 @@ namespace cling { m_HandledDecls.insert(m_FoundDRE->getDecl()); } } - CS->setStmts(m_Sema->getASTContext(), Stmts); + CS->replaceStmts(m_Sema->getASTContext(), Stmts); } void Fix(CXXTryStmt* TS) { diff --git a/lib/Interpreter/DeclExtractor.cpp b/lib/Interpreter/DeclExtractor.cpp index ad2efb23..40d44700 100644 --- a/lib/Interpreter/DeclExtractor.cpp +++ b/lib/Interpreter/DeclExtractor.cpp @@ -210,7 +210,7 @@ namespace cling { } } - CS->setStmts(*m_Context, Stmts); + CS->replaceStmts(*m_Context, Stmts); if (hasNoErrors && !TouchedDecls.empty()) { // Put the wrapper after its declarations. (Nice when AST dumping) @@ -261,8 +261,7 @@ namespace cling { // Wrap Stmts into a function body. llvm::ArrayRef StmtsRef(Stmts.data(), Stmts.size()); - CompoundStmt* CS = new (*m_Context)CompoundStmt(*m_Context, StmtsRef, - Loc, Loc); + CompoundStmt* CS = CompoundStmt::Create(*m_Context, StmtsRef, Loc, Loc); FD->setBody(CS); Emit(FD); diff --git a/lib/Interpreter/DynamicLookup.cpp b/lib/Interpreter/DynamicLookup.cpp index 5c7a3659..8cba8391 100644 --- a/lib/Interpreter/DynamicLookup.cpp +++ b/lib/Interpreter/DynamicLookup.cpp @@ -359,7 +359,7 @@ namespace cling { for(unsigned i = 0; i < NewStmts.size(); ++i) NewChildren.push_back(NewStmts[i]); - Node->setStmts(*m_Context, NewChildren); + Node->replaceStmts(*m_Context, NewChildren); // Resolve all 1:n replacements Visit(Node); } @@ -388,7 +388,7 @@ namespace cling { } } - Node->setStmts(*m_Context, NewChildren); + Node->replaceStmts(*m_Context, NewChildren); --m_NestedCompoundStmts; return ASTNodeInfo(Node, 0); diff --git a/lib/Interpreter/ValuePrinter.cpp b/lib/Interpreter/ValuePrinter.cpp index e96f6f13..49c6a8cb 100644 --- a/lib/Interpreter/ValuePrinter.cpp +++ b/lib/Interpreter/ValuePrinter.cpp @@ -626,8 +626,8 @@ static const char* BuildAndEmitVPWrapperBody(cling::Interpreter &Interp, if (RetStmt.isInvalid()) return "ERROR in cling's callPrintValue(): cannot build return expression"; - auto *Body = new (Ctx) clang::CompoundStmt(noSrcLoc); - Body->setStmts(Ctx, {RetStmt.get()}); + auto *Body + = clang::CompoundStmt::Create(Ctx, {RetStmt.get()}, noSrcLoc, noSrcLoc); WrapperFD->setBody(Body); auto &Consumer = Interp.getCI()->getASTConsumer(); Consumer.HandleTopLevelDecl(clang::DeclGroupRef(WrapperFD)); diff --git a/lib/Interpreter/ValuePrinterSynthesizer.cpp b/lib/Interpreter/ValuePrinterSynthesizer.cpp index a19945b0..774281ae 100644 --- a/lib/Interpreter/ValuePrinterSynthesizer.cpp +++ b/lib/Interpreter/ValuePrinterSynthesizer.cpp @@ -172,7 +172,7 @@ namespace cling { if (!isa(child)) FBody.push_back(child); - CS->setStmts(*m_Context, FBody); + CS->replaceStmts(*m_Context, FBody); return FBody.size(); } diff --git a/lib/Utils/AST.cpp b/lib/Utils/AST.cpp index 249343fd..09610563 100644 --- a/lib/Utils/AST.cpp +++ b/lib/Utils/AST.cpp @@ -170,7 +170,7 @@ namespace utils { newBody.insert(newBody.begin() + indexOfLastExpr, DRE); // Attach the new body (note: it does dealloc/alloc of all nodes) - CS->setStmts(S->getASTContext(), newBody); + CS->replaceStmts(S->getASTContext(), newBody); if (FoundAt) *FoundAt = indexOfLastExpr; return DRE; diff --git a/patches/clang-compoundstmt-replaceStmts.diff b/patches/clang-compoundstmt-replaceStmts.diff new file mode 100644 index 00000000..8fbc7cde --- /dev/null +++ b/patches/clang-compoundstmt-replaceStmts.diff @@ -0,0 +1,101 @@ +diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h +index 403b88ac3a..f852ee4b86 100644 +--- a/include/clang/AST/Stmt.h ++++ b/include/clang/AST/Stmt.h +@@ -131,7 +131,8 @@ protected: + + unsigned : NumStmtBits; + +- unsigned NumStmts : 32 - NumStmtBits; ++ unsigned WasReplaced : 1; ++ unsigned NumStmts : 32 - (NumStmtBits + 1); + + /// The location of the opening "{". + SourceLocation LBraceLoc; +@@ -1328,6 +1329,7 @@ public: + explicit CompoundStmt(SourceLocation Loc) + : Stmt(CompoundStmtClass), RBraceLoc(Loc) { + CompoundStmtBits.NumStmts = 0; ++ CompoundStmtBits.WasReplaced = 0; + CompoundStmtBits.LBraceLoc = Loc; + } + +@@ -1341,7 +1343,10 @@ public: + using body_range = llvm::iterator_range; + + body_range body() { return body_range(body_begin(), body_end()); } +- body_iterator body_begin() { return getTrailingObjects(); } ++ body_iterator body_begin() { ++ Stmt** begin = getTrailingObjects(); ++ return !CompoundStmtBits.WasReplaced ? begin : (body_iterator)begin[0]; ++ } + body_iterator body_end() { return body_begin() + size(); } + Stmt *body_front() { return !body_empty() ? body_begin()[0] : nullptr; } + +@@ -1357,7 +1362,7 @@ public: + } + + const_body_iterator body_begin() const { +- return getTrailingObjects(); ++ return const_cast(this)->body_begin(); + } + + const_body_iterator body_end() const { return body_begin() + size(); } +@@ -1391,6 +1396,8 @@ public: + return const_reverse_body_iterator(body_begin()); + } + ++ void replaceStmts(const ASTContext &C, llvm::ArrayRef Stmts); ++ + // Get the Stmt that StmtExpr would consider to be the result of this + // compound statement. This is used by StmtExpr to properly emulate the GCC + // compound expression extension, which ignores trailing NullStmts when +diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp +index 0a4d403106..86d47cf82d 100644 +--- a/lib/AST/Stmt.cpp ++++ b/lib/AST/Stmt.cpp +@@ -293,6 +293,7 @@ CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB, + SourceLocation RB) + : Stmt(CompoundStmtClass), RBraceLoc(RB) { + CompoundStmtBits.NumStmts = Stmts.size(); ++ CompoundStmtBits.WasReplaced = 0; + setStmts(Stmts); + CompoundStmtBits.LBraceLoc = LB; + } +@@ -300,7 +301,7 @@ CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB, + void CompoundStmt::setStmts(ArrayRef Stmts) { + assert(CompoundStmtBits.NumStmts == Stmts.size() && + "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); +- ++ assert(!CompoundStmtBits.WasReplaced && "Call replaceStmts!"); + std::copy(Stmts.begin(), Stmts.end(), body_begin()); + } + +@@ -320,6 +321,27 @@ CompoundStmt *CompoundStmt::CreateEmpty(const ASTContext &C, + return New; + } + ++void CompoundStmt::replaceStmts(const ASTContext &C, ++ llvm::ArrayRef Stmts) { ++ Stmt** Body = body_begin(); ++ ++ if (CompoundStmtBits.WasReplaced) ++ C.Deallocate(Body); ++ else ++ memset(body_begin(), 0, size()); ++ ++ CompoundStmtBits.NumStmts = Stmts.size(); ++ assert(CompoundStmtBits.NumStmts == Stmts.size() && ++ "NumStmts doesn't fit in bits of CompoundStmtBits.NumStmts!"); ++ ++ Body = new (C) Stmt*[Stmts.size()]; ++ std::copy(Stmts.begin(), Stmts.end(), Body); ++ ++ getTrailingObjects()[0] = reinterpret_cast(Body); ++ ++ CompoundStmtBits.WasReplaced = 1; ++} ++ + const Expr *ValueStmt::getExprStmt() const { + const Stmt *S = this; + do {