Simplify: don't loop over everything to find the WrapperFD but use the one stored in the transaction.
git-svn-id: http://root.cern.ch/svn/root/trunk@47163 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
parent
1a9a90a836
commit
8416a9183c
@ -32,105 +32,93 @@ namespace cling {
|
||||
if (!getTransaction()->getCompilationOpts().DeclarationExtraction)
|
||||
return;
|
||||
|
||||
for (Transaction::const_iterator I = getTransaction()->decls_begin(),
|
||||
E = getTransaction()->decls_end(); I != E; ++I)
|
||||
for (DeclGroupRef::const_iterator J = (*I).begin(),
|
||||
JE = (*I).end(); J != JE; ++J)
|
||||
if(!ExtractDecl(*J))
|
||||
setTransaction(0); // On error set to NULL.
|
||||
if(!ExtractDecl(getTransaction()->getWrapperFD()))
|
||||
setTransaction(0); // On error set to NULL.
|
||||
}
|
||||
|
||||
bool DeclExtractor::ExtractDecl(Decl* D) {
|
||||
FunctionDecl* FD = dyn_cast<FunctionDecl>(D);
|
||||
bool DeclExtractor::ExtractDecl(FunctionDecl* FD) {
|
||||
llvm::SmallVector<NamedDecl*, 4> TouchedDecls;
|
||||
CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody());
|
||||
assert(CS && "Function body not a CompoundStmt?");
|
||||
DeclContext* DC = FD->getTranslationUnitDecl();
|
||||
Scope* TUScope = m_Sema->TUScope;
|
||||
assert(TUScope == m_Sema->getScopeForContext(DC) && "TU scope from DC?");
|
||||
llvm::SmallVector<Stmt*, 4> Stmts;
|
||||
|
||||
if (FD) {
|
||||
if (!utils::Analyze::IsWrapper(FD))
|
||||
return true;
|
||||
for (CompoundStmt::body_iterator I = CS->body_begin(), EI = CS->body_end();
|
||||
I != EI; ++I) {
|
||||
DeclStmt* DS = dyn_cast<DeclStmt>(*I);
|
||||
if (!DS) {
|
||||
Stmts.push_back(*I);
|
||||
continue;
|
||||
}
|
||||
|
||||
llvm::SmallVector<NamedDecl*, 4> TouchedDecls;
|
||||
CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody());
|
||||
assert(CS && "Function body not a CompoundStmt?");
|
||||
DeclContext* DC = FD->getTranslationUnitDecl();
|
||||
Scope* TUScope = m_Sema->TUScope;
|
||||
assert(TUScope == m_Sema->getScopeForContext(DC) && "TU scope from DC?");
|
||||
llvm::SmallVector<Stmt*, 4> Stmts;
|
||||
for (DeclStmt::decl_iterator J = DS->decl_begin();
|
||||
J != DS->decl_end(); ++J) {
|
||||
NamedDecl* ND = dyn_cast<NamedDecl>(*J);
|
||||
if (ND) {
|
||||
DeclContext* OldDC = ND->getDeclContext();
|
||||
|
||||
for (CompoundStmt::body_iterator I = CS->body_begin(), EI = CS->body_end();
|
||||
I != EI; ++I) {
|
||||
DeclStmt* DS = dyn_cast<DeclStmt>(*I);
|
||||
if (!DS) {
|
||||
Stmts.push_back(*I);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (DeclStmt::decl_iterator J = DS->decl_begin();
|
||||
J != DS->decl_end(); ++J) {
|
||||
NamedDecl* ND = dyn_cast<NamedDecl>(*J);
|
||||
if (ND) {
|
||||
DeclContext* OldDC = ND->getDeclContext();
|
||||
|
||||
// Make sure the decl is not found at its old possition
|
||||
OldDC->removeDecl(ND);
|
||||
if (Scope* S = m_Sema->getScopeForContext(OldDC)) {
|
||||
S->RemoveDecl(ND);
|
||||
m_Sema->IdResolver.RemoveDecl(ND);
|
||||
}
|
||||
|
||||
if (ND->getDeclContext() == ND->getLexicalDeclContext())
|
||||
ND->setLexicalDeclContext(DC);
|
||||
else
|
||||
assert("Not implemented: Decl with different lexical context");
|
||||
ND->setDeclContext(DC);
|
||||
|
||||
if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
|
||||
VD->setStorageClass(SC_None);
|
||||
VD->setStorageClassAsWritten(SC_None);
|
||||
}
|
||||
// force recalc of the linkage (to external)
|
||||
ND->ClearLinkageCache();
|
||||
|
||||
TouchedDecls.push_back(ND);
|
||||
// Make sure the decl is not found at its old possition
|
||||
OldDC->removeDecl(ND);
|
||||
if (Scope* S = m_Sema->getScopeForContext(OldDC)) {
|
||||
S->RemoveDecl(ND);
|
||||
m_Sema->IdResolver.RemoveDecl(ND);
|
||||
}
|
||||
|
||||
if (ND->getDeclContext() == ND->getLexicalDeclContext())
|
||||
ND->setLexicalDeclContext(DC);
|
||||
else
|
||||
assert("Not implemented: Decl with different lexical context");
|
||||
ND->setDeclContext(DC);
|
||||
|
||||
if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
|
||||
VD->setStorageClass(SC_None);
|
||||
VD->setStorageClassAsWritten(SC_None);
|
||||
}
|
||||
// force recalc of the linkage (to external)
|
||||
ND->ClearLinkageCache();
|
||||
|
||||
TouchedDecls.push_back(ND);
|
||||
}
|
||||
}
|
||||
bool hasNoErrors = !CheckForClashingNames(TouchedDecls, DC, TUScope);
|
||||
if (hasNoErrors) {
|
||||
for (size_t i = 0; i < TouchedDecls.size(); ++i) {
|
||||
m_Sema->PushOnScopeChains(TouchedDecls[i],
|
||||
m_Sema->getScopeForContext(DC),
|
||||
}
|
||||
bool hasNoErrors = !CheckForClashingNames(TouchedDecls, DC, TUScope);
|
||||
if (hasNoErrors) {
|
||||
for (size_t i = 0; i < TouchedDecls.size(); ++i) {
|
||||
m_Sema->PushOnScopeChains(TouchedDecls[i],
|
||||
m_Sema->getScopeForContext(DC),
|
||||
/*AddCurContext*/!isa<UsingDirectiveDecl>(TouchedDecls[i]));
|
||||
|
||||
// The transparent DeclContexts (eg. scopeless enum) doesn't have
|
||||
// scopes. While extracting their contents we need to update the
|
||||
// lookup tables and telling them to pick up the new possitions
|
||||
// in the AST.
|
||||
if (DeclContext* InnerDC = dyn_cast<DeclContext>(TouchedDecls[i])) {
|
||||
if (InnerDC->isTransparentContext()) {
|
||||
// We can't PushDeclContext, because we don't have scope.
|
||||
Sema::ContextRAII pushedDC(*m_Sema, InnerDC);
|
||||
// The transparent DeclContexts (eg. scopeless enum) doesn't have
|
||||
// scopes. While extracting their contents we need to update the
|
||||
// lookup tables and telling them to pick up the new possitions
|
||||
// in the AST.
|
||||
if (DeclContext* InnerDC = dyn_cast<DeclContext>(TouchedDecls[i])) {
|
||||
if (InnerDC->isTransparentContext()) {
|
||||
// We can't PushDeclContext, because we don't have scope.
|
||||
Sema::ContextRAII pushedDC(*m_Sema, InnerDC);
|
||||
|
||||
for(DeclContext::decl_iterator DI = InnerDC->decls_begin(),
|
||||
DE = InnerDC->decls_end(); DI != DE ; ++DI) {
|
||||
if (NamedDecl* ND = dyn_cast<NamedDecl>(*DI))
|
||||
InnerDC->makeDeclVisibleInContext(ND);
|
||||
}
|
||||
for(DeclContext::decl_iterator DI = InnerDC->decls_begin(),
|
||||
DE = InnerDC->decls_end(); DI != DE ; ++DI) {
|
||||
if (NamedDecl* ND = dyn_cast<NamedDecl>(*DI))
|
||||
InnerDC->makeDeclVisibleInContext(ND);
|
||||
}
|
||||
}
|
||||
|
||||
// Append the new top level decl to the current transaction.
|
||||
getTransaction()->appendUnique(DeclGroupRef(TouchedDecls[i]));
|
||||
}
|
||||
|
||||
// Append the new top level decl to the current transaction.
|
||||
getTransaction()->appendUnique(DeclGroupRef(TouchedDecls[i]));
|
||||
}
|
||||
|
||||
CS->setStmts(*m_Context, Stmts.data(), Stmts.size());
|
||||
|
||||
// Put the wrapper after its declarations. (Nice when AST dumping)
|
||||
DC->removeDecl(FD);
|
||||
DC->addDecl(FD);
|
||||
|
||||
return hasNoErrors;
|
||||
}
|
||||
return true;
|
||||
|
||||
CS->setStmts(*m_Context, Stmts.data(), Stmts.size());
|
||||
|
||||
// Put the wrapper after its declarations. (Nice when AST dumping)
|
||||
DC->removeDecl(FD);
|
||||
DC->addDecl(FD);
|
||||
|
||||
return hasNoErrors;
|
||||
}
|
||||
|
||||
///\brief Checks for clashing names when trying to extract a declaration.
|
||||
|
@ -39,10 +39,10 @@ namespace cling {
|
||||
///\brief Tries to extract the declaration on the global scope (translation
|
||||
/// unit scope).
|
||||
///
|
||||
///\param D[in] - The declaration to be extracted.
|
||||
///\param D[in] - The function declaration to extract from.
|
||||
///\returns true on success.
|
||||
///
|
||||
bool ExtractDecl(clang::Decl* D);
|
||||
bool ExtractDecl(clang::FunctionDecl* FD);
|
||||
|
||||
///\brief Checks for clashing names when trying to extract a declaration.
|
||||
///
|
||||
|
@ -46,80 +46,70 @@ namespace cling {
|
||||
== CompilationOptions::VPDisabled)
|
||||
return;
|
||||
|
||||
for (Transaction::const_iterator I = getTransaction()->decls_begin(),
|
||||
E = getTransaction()->decls_end(); I != E; ++I)
|
||||
if(!tryAttachVP(*I))
|
||||
return setTransaction(0); // On error set to NULL.
|
||||
if (!tryAttachVP(getTransaction()->getWrapperFD()))
|
||||
return setTransaction(0); // On error set to NULL.
|
||||
}
|
||||
|
||||
bool ValuePrinterSynthesizer::tryAttachVP(DeclGroupRef DGR) {
|
||||
for (DeclGroupRef::iterator I = DGR.begin(), E = DGR.end(); I != E; ++I)
|
||||
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*I)) {
|
||||
if (!utils::Analyze::IsWrapper(FD))
|
||||
continue;
|
||||
const CompilationOptions& CO(getTransaction()->getCompilationOpts());
|
||||
if (CO.ValuePrinting == CompilationOptions::VPDisabled)
|
||||
return true; // Nothing to do.
|
||||
bool ValuePrinterSynthesizer::tryAttachVP(FunctionDecl* FD) {
|
||||
// We have to be able to mark the expression for printout. There are
|
||||
// three scenarios:
|
||||
// 0: Expression printing disabled - don't do anything just exit.
|
||||
// 1: Expression printing enabled - print no matter what.
|
||||
// 2: Expression printing auto - analyze - rely on the omitted ';' to
|
||||
// not produce the suppress marker.
|
||||
int indexOfLastExpr = -1;
|
||||
Expr* To = utils::Analyze::GetOrCreateLastExpr(FD, &indexOfLastExpr,
|
||||
/*omitDS*/false,
|
||||
m_Sema);
|
||||
if (To) {
|
||||
// Update the CompoundStmt body, avoiding alloc/dealloc of all the el.
|
||||
CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
|
||||
assert(CS && "Missing body?");
|
||||
|
||||
// We have to be able to mark the expression for printout. There are
|
||||
// three scenarios:
|
||||
// 0: Expression printing disabled - don't do anything just exit.
|
||||
// 1: Expression printing enabled - print no matter what.
|
||||
// 2: Expression printing auto - analyze - rely on the omitted ';' to
|
||||
// not produce the suppress marker.
|
||||
int indexOfLastExpr = -1;
|
||||
Expr* To = utils::Analyze::GetOrCreateLastExpr(FD, &indexOfLastExpr,
|
||||
/*omitDS*/false,
|
||||
m_Sema);
|
||||
if (To) {
|
||||
// Update the CompoundStmt body, avoiding alloc/dealloc of all the el.
|
||||
CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
|
||||
assert(CS && "Missing body?");
|
||||
|
||||
switch (CO.ValuePrinting) {
|
||||
case CompilationOptions::VPDisabled:
|
||||
assert("Don't wait that long. Exit early!");
|
||||
break;
|
||||
case CompilationOptions::VPEnabled:
|
||||
break;
|
||||
case CompilationOptions::VPAuto:
|
||||
if ((int)CS->size() > indexOfLastExpr+1
|
||||
&& (*(CS->body_begin() + indexOfLastExpr + 1))
|
||||
&& isa<NullStmt>(*(CS->body_begin() + indexOfLastExpr + 1)))
|
||||
return true; // If next is NullStmt disable VP is disabled - exit.
|
||||
break;
|
||||
}
|
||||
|
||||
// We can't PushDeclContext, because we don't have scope.
|
||||
Sema::ContextRAII pushedDC(*m_Sema, FD);
|
||||
|
||||
if (To) {
|
||||
// Strip the parenthesis if any
|
||||
if (ParenExpr* PE = dyn_cast<ParenExpr>(To))
|
||||
To = PE->getSubExpr();
|
||||
|
||||
Expr* Result = 0;
|
||||
if (m_Sema->getLangOpts().CPlusPlus)
|
||||
Result = SynthesizeCppVP(To);
|
||||
else
|
||||
Result = SynthesizeVP(To);
|
||||
|
||||
if (Result)
|
||||
*(CS->body_begin()+indexOfLastExpr) = Result;
|
||||
}
|
||||
// Clear the artificial NullStmt-s
|
||||
if (!ClearNullStmts(CS)) {
|
||||
// FIXME: Why it is here? Shouldn't it be in DeclExtractor?
|
||||
// if no body remove the wrapper
|
||||
DeclContext* DC = FD->getDeclContext();
|
||||
Scope* S = m_Sema->getScopeForContext(DC);
|
||||
if (S)
|
||||
S->RemoveDecl(FD);
|
||||
DC->removeDecl(FD);
|
||||
}
|
||||
}
|
||||
const CompilationOptions& CO(getTransaction()->getCompilationOpts());
|
||||
switch (CO.ValuePrinting) {
|
||||
case CompilationOptions::VPDisabled:
|
||||
assert("Don't wait that long. Exit early!");
|
||||
break;
|
||||
case CompilationOptions::VPEnabled:
|
||||
break;
|
||||
case CompilationOptions::VPAuto:
|
||||
if ((int)CS->size() > indexOfLastExpr+1
|
||||
&& (*(CS->body_begin() + indexOfLastExpr + 1))
|
||||
&& isa<NullStmt>(*(CS->body_begin() + indexOfLastExpr + 1)))
|
||||
return true; // If next is NullStmt disable VP is disabled - exit.
|
||||
break;
|
||||
}
|
||||
|
||||
// We can't PushDeclContext, because we don't have scope.
|
||||
Sema::ContextRAII pushedDC(*m_Sema, FD);
|
||||
|
||||
if (To) {
|
||||
// Strip the parenthesis if any
|
||||
if (ParenExpr* PE = dyn_cast<ParenExpr>(To))
|
||||
To = PE->getSubExpr();
|
||||
|
||||
Expr* Result = 0;
|
||||
if (m_Sema->getLangOpts().CPlusPlus)
|
||||
Result = SynthesizeCppVP(To);
|
||||
else
|
||||
Result = SynthesizeVP(To);
|
||||
|
||||
if (Result)
|
||||
*(CS->body_begin()+indexOfLastExpr) = Result;
|
||||
}
|
||||
// Clear the artificial NullStmt-s
|
||||
if (!ClearNullStmts(CS)) {
|
||||
// FIXME: Why it is here? Shouldn't it be in DeclExtractor?
|
||||
// if no body remove the wrapper
|
||||
DeclContext* DC = FD->getDeclContext();
|
||||
Scope* S = m_Sema->getScopeForContext(DC);
|
||||
if (S)
|
||||
S->RemoveDecl(FD);
|
||||
DC->removeDecl(FD);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CompoundStmt;
|
||||
class DeclGroupRef;
|
||||
class FunctionDecl;
|
||||
class Expr;
|
||||
class Sema;
|
||||
}
|
||||
@ -52,13 +52,13 @@ public:
|
||||
///\brief Tries to attach a value printing mechanism to the given decl group
|
||||
/// ref.
|
||||
///
|
||||
///\param[in] DGR - A decl group ref the value printer is being attached to.
|
||||
///\param[in] FD - wrapper function that the value printer will attached to.
|
||||
///
|
||||
///\returns true if the attachment was considered as success. I.e. even if
|
||||
/// even if the value printer wasn't attached because of the compilation
|
||||
/// options disallowint it - it will return still true. Returns false on
|
||||
/// critical error.
|
||||
bool tryAttachVP(clang::DeclGroupRef DGR);
|
||||
bool tryAttachVP(clang::FunctionDecl* FD);
|
||||
clang::Expr* SynthesizeCppVP(clang::Expr* E);
|
||||
clang::Expr* SynthesizeVP(clang::Expr* E);
|
||||
unsigned ClearNullStmts(clang::CompoundStmt* CS);
|
||||
|
Loading…
Reference in New Issue
Block a user