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:
Vassil Vassilev 2012-12-03 14:27:12 +00:00
parent 8e84e50e2a
commit fdd88b8a47
8 changed files with 66 additions and 34 deletions

View File

@ -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.
///

View File

@ -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);
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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]));
}
}

View File

@ -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.

View File

@ -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

View File

@ -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