Readd support (which we had long time ago) for tracking down which decl came from.

This "is meant" to help us generating the missing symbols in the llvm::Module.


git-svn-id: http://root.cern.ch/svn/root/trunk@47790 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
Vassil Vassilev 2012-12-03 16:28:24 +00:00
parent 33e420bb73
commit ef8d4e85ba
3 changed files with 39 additions and 34 deletions

View File

@ -38,7 +38,10 @@ namespace cling {
public:
enum ConsumerCallInfo {
kCCINone,
kCCIHandleTopLevelDecl
kCCIHandleTopLevelDecl,
kCCIHandleInterestingDecl,
kCCIHandleTagDeclDefinition,
kCCIHandleVTable
};
///\brief Each declaration group came through different interface at

View File

@ -9,6 +9,7 @@
#include "cling/Interpreter/Transaction.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
using namespace clang;
@ -20,32 +21,27 @@ namespace cling {
}
bool DeclCollector::HandleTopLevelDecl(DeclGroupRef DGR) {
// ImportDecl is a special decl that triggers module loading in the front
// 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()))) {
Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleTopLevelDecl);
m_CurTransaction->append(DCI);
}
Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleTopLevelDecl);
m_CurTransaction->append(DCI);
return true;
}
void DeclCollector::HandleInterestingDecl(DeclGroupRef DGR) {
HandleTopLevelDecl(DGR);
Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleInterestingDecl);
m_CurTransaction->append(DCI);
}
// Does more than we want:
// if there is class A {enum E {kEnum = 1};};
// we get two different tag decls one for A and one for E. This is not that
// bad because esentially it has no effect on codegen but it differs from what
// one'd expect. For now rely on the HandleTopLevelDecl to provide all the
// declarations in the transaction.
void DeclCollector::HandleTagDeclDefinition(TagDecl* TD) {
// Intentional no-op.
Transaction::DelayCallInfo DCI(DeclGroupRef(TD),
Transaction::kCCIHandleTagDeclDefinition);
m_CurTransaction->append(DCI);
}
void DeclCollector::HandleVTable(CXXRecordDecl* RD, bool DefinitionRequired) {
Transaction::DelayCallInfo DCI(DeclGroupRef(RD),
Transaction::kCCIHandleVTable);
m_CurTransaction->append(DCI);
// Intentional no-op. It comes through Sema::DefineUsedVTables, which
// comes either Sema::ActOnEndOfTranslationUnit or while instantiating a
// template. In our case we will do it on transaction commit, without

View File

@ -203,28 +203,34 @@ namespace cling {
// We assume that there is no ordering of the calls to HandleXYZ, because
// in clang they can happen in different order too, eg. coming from
// 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->m_DGR.begin(),
L = I->m_DGR.end(); J != L; ++J)
if (TagDecl* TD = dyn_cast<TagDecl>(*J))
if (TD->isThisDeclarationADefinition()) {
getCodeGenerator()->HandleTagDeclDefinition(TD);
if (CXXRecordDecl* CXXRD = dyn_cast<CXXRecordDecl>(TD))
if (CXXRD->isDynamicClass())
getCodeGenerator()->HandleVTable(CXXRD, true);
}
getCodeGenerator()->HandleTopLevelDecl(I->m_DGR);
for (Transaction::iterator I = T->decls_begin(), E = T->decls_end();
I != E; ++I) {
switch (I->m_Call) {
case Transaction::kCCIHandleTopLevelDecl :
getCodeGenerator()->HandleTopLevelDecl(I->m_DGR);
break;
case Transaction::kCCIHandleInterestingDecl :
getCodeGenerator()->HandleInterestingDecl(I->m_DGR);
break;
case Transaction::kCCIHandleTagDeclDefinition : {
TagDecl* TD = cast<TagDecl>(I->m_DGR.getSingleDecl());
getCodeGenerator()->HandleTagDeclDefinition(TD);
break;
}
case Transaction::kCCIHandleVTable : {
CXXRecordDecl* CXXRD = cast<CXXRecordDecl>(I->m_DGR.getSingleDecl());
getCodeGenerator()->HandleVTable(CXXRD, /*isRequired*/true);
break;
}
}
}
getCodeGenerator()->HandleTranslationUnit(getCI()->getASTContext());
// run the static initializers that came from codegenning
if (m_Interpreter->runStaticInitializersOnce()
>= Interpreter::kExeFirstError) {
// Roll back on error in a transformer
rollbackTransaction(T);
return;
// Roll back on error in a transformer
rollbackTransaction(T);
return;
}
}