DynScopes: recurse into Decls.
This commit is contained in:
parent
a8608d0a67
commit
608a560140
@ -109,7 +109,42 @@ namespace {
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
class DynScopeDeclVisitor:
|
||||
public DeclVisitor<DynScopeDeclVisitor, bool> {
|
||||
private:
|
||||
cling::EvaluateTSynthesizer& m_EvalTSynth;
|
||||
|
||||
public:
|
||||
DynScopeDeclVisitor(cling::EvaluateTSynthesizer& evalTSynth):
|
||||
m_EvalTSynth(evalTSynth) {}
|
||||
|
||||
bool VisitFunctionDecl(FunctionDecl* FD) {
|
||||
cling::ASTNodeInfo Replacement = m_EvalTSynth.Visit(FD->getBody());
|
||||
if (Replacement.hasErrorOccurred()) {
|
||||
FD->setBody(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Replacement.isForReplacement()) {
|
||||
// FIXME: support multiple Stmt Replacement!
|
||||
FD->setBody(Replacement.getAsSingleNode());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VisitDecl(Decl* D) {
|
||||
bool Replaced = false;
|
||||
if (auto DC = dyn_cast<DeclContext>(D)) {
|
||||
for (auto C: DC->decls())
|
||||
Replaced |= Visit(C);
|
||||
}
|
||||
return Replaced;
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace cling {
|
||||
@ -356,16 +391,15 @@ namespace cling {
|
||||
|
||||
ASTNodeInfo EvaluateTSynthesizer::VisitDeclStmt(DeclStmt* Node) {
|
||||
// Visit all the children, which are the contents of the DeclGroupRef
|
||||
for (Stmt::child_iterator
|
||||
I = Node->child_begin(), E = Node->child_end(); I != E; ++I) {
|
||||
if (*I) {
|
||||
Expr* E = cast_or_null<Expr>(*I);
|
||||
if (!E || !IsArtificiallyDependent(E))
|
||||
if (VarDecl* CuredDecl = dyn_cast<VarDecl>(Node->getSingleDecl())) {
|
||||
//FIXME: don't assume there is only one decl.
|
||||
assert(Node->isSingleDecl() && "There is more that one decl in stmt");
|
||||
for (Stmt::child_iterator
|
||||
I = Node->child_begin(), E = Node->child_end(); I != E; ++I) {
|
||||
Expr* InitExpr = cast_or_null<Expr>(*I);
|
||||
if (!InitExpr || !IsArtificiallyDependent(InitExpr))
|
||||
continue;
|
||||
//FIXME: don't assume there is only one decl.
|
||||
assert(Node->isSingleDecl() && "There is more that one decl in stmt");
|
||||
VarDecl* CuredDecl = cast_or_null<VarDecl>(Node->getSingleDecl());
|
||||
assert(CuredDecl && "Not a variable declaration!");
|
||||
|
||||
QualType CuredDeclTy = CuredDecl->getType();
|
||||
if (isa<AutoType>(CuredDeclTy)) {
|
||||
ASTNodeInfo result(Node, false);
|
||||
@ -410,7 +444,7 @@ namespace cling {
|
||||
// "MyClass"
|
||||
// Interpreter* Interp)
|
||||
// Build Arg0 DynamicExprInfo
|
||||
Inits.push_back(BuildDynamicExprInfo(E));
|
||||
Inits.push_back(BuildDynamicExprInfo(InitExpr));
|
||||
// Build Arg1 DeclContext* DC
|
||||
QualType DCTy = m_Context->getTypeDeclType(m_DeclContextDecl);
|
||||
Inits.push_back(utils::Synthesize::CStyleCastPtrExpr(m_Sema, DCTy,
|
||||
@ -512,10 +546,20 @@ namespace cling {
|
||||
|
||||
// Restore Sema's original DeclContext
|
||||
m_Sema->CurContext = OldDC;
|
||||
// FIXME: this only works if this is the only Decl in the DeclGroup...
|
||||
return NewNode;
|
||||
}
|
||||
}
|
||||
return ASTNodeInfo(Node, 0);
|
||||
|
||||
// Recurse over Decls; they might need transformations, too; e.g. in
|
||||
// void wrapper() { struct X { void f() { ++dynScope; } }; }
|
||||
bool HaveReplacement = false;
|
||||
DynScopeDeclVisitor DSDV(*this);
|
||||
// DynScopeDeclVisitor always changes the Decls in-place, no need to pick up
|
||||
// new ones.
|
||||
for (auto DGI: Node->getDeclGroup())
|
||||
HaveReplacement |= DSDV.Visit(DGI);
|
||||
return ASTNodeInfo(Node, HaveReplacement);
|
||||
}
|
||||
|
||||
ASTNodeInfo EvaluateTSynthesizer::VisitCXXDeleteExpr(CXXDeleteExpr* Node) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user