Implement basic infrastruction to begin tracking down the interfaces from which the decls came.
git-svn-id: http://root.cern.ch/svn/root/trunk@47787 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
parent
8e84e50e2a
commit
fdd88b8a47
@ -35,9 +35,27 @@ namespace cling {
|
||||
/// - committed - code could be produced for the contents of the transaction.
|
||||
///
|
||||
class Transaction {
|
||||
private:
|
||||
public:
|
||||
enum ConsumerCallInfo {
|
||||
kCCINone,
|
||||
kCCIHandleTopLevelDecl
|
||||
};
|
||||
|
||||
typedef llvm::SmallVector<clang::DeclGroupRef, 64> DeclQueue;
|
||||
///\brief Each declaration group came through different interface at
|
||||
/// different time. We are being conservative and we want to keep all the
|
||||
/// call sequence that originally occurred in clang.
|
||||
///
|
||||
struct DelayCallInfo {
|
||||
clang::DeclGroupRef m_DGR;
|
||||
ConsumerCallInfo m_Call;
|
||||
DelayCallInfo(clang::DeclGroupRef DGR, ConsumerCallInfo CCI)
|
||||
: m_DGR(DGR), m_Call(CCI) {}
|
||||
};
|
||||
|
||||
private:
|
||||
// Intentionally use struct instead of pair because we don't need default
|
||||
// init.
|
||||
typedef llvm::SmallVector<DelayCallInfo, 64> DeclQueue;
|
||||
typedef llvm::SmallVector<Transaction*, 2> NestedTransactions;
|
||||
|
||||
///\brief All seen declarations. If we collect the declarations by walking
|
||||
@ -149,7 +167,7 @@ namespace cling {
|
||||
///
|
||||
clang::DeclGroupRef getFirstDecl() const {
|
||||
if (!empty())
|
||||
return m_DeclQueue.front();
|
||||
return m_DeclQueue.front().m_DGR;
|
||||
return clang::DeclGroupRef();
|
||||
}
|
||||
|
||||
@ -157,7 +175,7 @@ namespace cling {
|
||||
///
|
||||
clang::DeclGroupRef getLastDecl() const {
|
||||
if (!empty() && isCompleted())
|
||||
return m_DeclQueue.back();
|
||||
return m_DeclQueue.back().m_DGR;
|
||||
return clang::DeclGroupRef();
|
||||
}
|
||||
|
||||
@ -166,7 +184,7 @@ namespace cling {
|
||||
///
|
||||
clang::DeclGroupRef getCurrentLastDecl() const {
|
||||
if (!empty())
|
||||
return m_DeclQueue.back();
|
||||
return m_DeclQueue.back().m_DGR;
|
||||
return clang::DeclGroupRef();
|
||||
}
|
||||
|
||||
@ -205,8 +223,9 @@ namespace cling {
|
||||
nested->setParent(this);
|
||||
// Leave a marker in the parent transaction, where the nested transaction
|
||||
// started. Using empty DeclGroupRef is save because append() filters
|
||||
// out possible empty DeclGroupRefs.
|
||||
m_DeclQueue.push_back(clang::DeclGroupRef());
|
||||
// out possible empty DeclGroupRefs.
|
||||
m_DeclQueue.push_back(DelayCallInfo(clang::DeclGroupRef(),
|
||||
Transaction::kCCINone));
|
||||
|
||||
m_NestedTransactions.push_back(nested);
|
||||
}
|
||||
@ -219,14 +238,20 @@ namespace cling {
|
||||
///
|
||||
bool empty() const { return m_DeclQueue.empty(); }
|
||||
|
||||
///\brief Appends a declaration group to the transaction if doesn't exist.
|
||||
///\brief Appends a declaration group and source from which consumer interface it
|
||||
/// came from to the transaction.
|
||||
///
|
||||
void appendUnique(clang::DeclGroupRef DGR);
|
||||
void append(DelayCallInfo DCI);
|
||||
|
||||
///\brief Appends the declaration group to the transaction as if it was
|
||||
/// seen through HandleTopLevelDecl.
|
||||
///
|
||||
void append(clang::DeclGroupRef DGR);
|
||||
|
||||
///\brief Wraps the declaration into declaration group and appends it to
|
||||
/// the transaction if doesn't exist.
|
||||
/// the transaction as if it was seen through HandleTopLevelDecl.
|
||||
///
|
||||
void appendUnique(clang::Decl* D);
|
||||
void append(clang::Decl* D);
|
||||
|
||||
///\brief Clears all declarations in the transaction.
|
||||
///
|
||||
|
@ -26,8 +26,8 @@ namespace cling {
|
||||
|
||||
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)
|
||||
for (DeclGroupRef::const_iterator J = (*I).m_DGR.begin(),
|
||||
JE = (*I).m_DGR.end(); J != JE; ++J)
|
||||
printDecl(*J);
|
||||
}
|
||||
|
||||
|
@ -505,7 +505,7 @@ namespace cling {
|
||||
|
||||
for (Transaction::const_reverse_iterator I = T->rdecls_begin(),
|
||||
E = T->rdecls_end(); I != E; ++I) {
|
||||
const DeclGroupRef& DGR = (*I);
|
||||
const DeclGroupRef& DGR = (*I).m_DGR;
|
||||
|
||||
for (DeclGroupRef::const_iterator
|
||||
Di = DGR.end() - 1, E = DGR.begin() - 1; Di != E; --Di) {
|
||||
|
@ -24,8 +24,10 @@ namespace cling {
|
||||
// end. The issue is that HandleImplicitImportDecl now is
|
||||
// bound/forwarded to HandleTopLevelDecl which soon won't be the case
|
||||
// and thus we don't need to bother adding it now.
|
||||
if (!(DGR.isSingleDecl() && isa<ImportDecl>(DGR.getSingleDecl())))
|
||||
m_CurTransaction->appendUnique(DGR);
|
||||
if (!(DGR.isSingleDecl() && isa<ImportDecl>(DGR.getSingleDecl()))) {
|
||||
Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleTopLevelDecl);
|
||||
m_CurTransaction->append(DCI);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ namespace cling {
|
||||
}
|
||||
|
||||
// Append the new top level decl to the current transaction.
|
||||
getTransaction()->appendUnique(DeclGroupRef(TouchedDecls[i]));
|
||||
getTransaction()->append(DeclGroupRef(TouchedDecls[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,8 +240,8 @@ namespace cling {
|
||||
|
||||
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)
|
||||
for (DeclGroupRef::const_iterator J = (*I).m_DGR.begin(),
|
||||
JE = (*I).m_DGR.end(); J != JE; ++J)
|
||||
if (ShouldVisit(*J) && (*J)->hasBody()) {
|
||||
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(*J)) {
|
||||
// Set the decl context, which is needed by Evaluate.
|
||||
|
@ -205,8 +205,8 @@ namespace cling {
|
||||
// template instatiator and so on.
|
||||
for (Transaction::iterator I = T->decls_begin(),
|
||||
E = T->decls_end(); I != E; ++I) {
|
||||
for (DeclGroupRef::const_iterator J = I->begin(), L = I->end();
|
||||
J != L; ++J)
|
||||
for (DeclGroupRef::const_iterator J = I->m_DGR.begin(),
|
||||
L = I->m_DGR.end(); J != L; ++J)
|
||||
if (TagDecl* TD = dyn_cast<TagDecl>(*J))
|
||||
if (TD->isThisDeclarationADefinition()) {
|
||||
getCodeGenerator()->HandleTagDeclDefinition(TD);
|
||||
@ -216,7 +216,7 @@ namespace cling {
|
||||
getCodeGenerator()->HandleVTable(CXXRD, true);
|
||||
}
|
||||
|
||||
getCodeGenerator()->HandleTopLevelDecl(*I);
|
||||
getCodeGenerator()->HandleTopLevelDecl(I->m_DGR);
|
||||
}
|
||||
getCodeGenerator()->HandleTranslationUnit(getCI()->getASTContext());
|
||||
// run the static initializers that came from codegenning
|
||||
|
@ -21,24 +21,28 @@ namespace cling {
|
||||
delete m_NestedTransactions[i];
|
||||
}
|
||||
|
||||
void Transaction::appendUnique(DeclGroupRef DGR) {
|
||||
for (const_iterator I = decls_begin(), E = decls_end(); I != E; ++I) {
|
||||
if (DGR.isNull() || (*I).getAsOpaquePtr() == DGR.getAsOpaquePtr())
|
||||
return;
|
||||
}
|
||||
void Transaction::append(DelayCallInfo DCI) {
|
||||
// for (const_iterator I = decls_begin(), E = decls_end(); I != E; ++I) {
|
||||
// if (DGR.isNull() || (*I).getAsOpaquePtr() == DGR.getAsOpaquePtr())
|
||||
// return;
|
||||
// }
|
||||
// register the wrapper if any.
|
||||
if (DGR.isSingleDecl()) {
|
||||
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(DGR.getSingleDecl()))
|
||||
if (DCI.m_DGR.isSingleDecl()) {
|
||||
if (FunctionDecl* FD = dyn_cast<FunctionDecl>(DCI.m_DGR.getSingleDecl()))
|
||||
if (utils::Analyze::IsWrapper(FD)) {
|
||||
assert(!m_WrapperFD && "Two wrappers in one transaction?");
|
||||
m_WrapperFD = FD;
|
||||
}
|
||||
}
|
||||
m_DeclQueue.push_back(DGR);
|
||||
m_DeclQueue.push_back(DCI);
|
||||
}
|
||||
|
||||
void Transaction::appendUnique(Decl* D) {
|
||||
appendUnique(DeclGroupRef(D));
|
||||
void Transaction::append(clang::DeclGroupRef DGR) {
|
||||
append(DelayCallInfo(DGR, kCCIHandleTopLevelDecl));
|
||||
}
|
||||
|
||||
void Transaction::append(Decl* D) {
|
||||
append(DeclGroupRef(D));
|
||||
}
|
||||
|
||||
void Transaction::dump() const {
|
||||
@ -68,7 +72,7 @@ namespace cling {
|
||||
unsigned Indent, bool PrintInstantiation) const {
|
||||
int nestedT = 0;
|
||||
for (const_iterator I = decls_begin(), E = decls_end(); I != E; ++I) {
|
||||
if (I->isNull()) {
|
||||
if (I->m_DGR.isNull()) {
|
||||
assert(hasNestedTransactions() && "DGR is null even if no nesting?");
|
||||
// print the nested decl
|
||||
Out<< "\n";
|
||||
@ -82,7 +86,8 @@ namespace cling {
|
||||
Out<<" End Transaction" << nestedT << " \n";
|
||||
Out<<"+====================================================+\n";
|
||||
}
|
||||
for (DeclGroupRef::const_iterator J = I->begin(), L = I->end();J != L;++J)
|
||||
for (DeclGroupRef::const_iterator J = I->m_DGR.begin(),
|
||||
L = I->m_DGR.end(); J != L; ++J)
|
||||
if (*J)
|
||||
(*J)->print(Out, Policy, Indent, PrintInstantiation);
|
||||
else
|
||||
|
Loading…
Reference in New Issue
Block a user