Logic improvement: if a decl comes from an ASTReader is should not be collected, even if no codegen object exists.

Don't codegen statics and non-inline functions if from AST file or "forModules" is set:
Filter decls to be sent to codegen also based on the "forModules" flag, not only on whether it's from an AST file - in the end they are the same (forModules will vanish once we have modules).
Iterate over NamespaceDecls before emitting, to be able to filter their elements.


git-svn-id: http://root.cern.ch/svn/root/trunk@49152 27541ba8-7e3a-0410-8455-c3a389f83636
This commit is contained in:
Axel Naumann 2013-04-09 15:38:50 +00:00
parent 60cf742050
commit 95db59648c
2 changed files with 66 additions and 13 deletions

View File

@ -17,13 +17,30 @@
using namespace clang;
namespace cling {
static bool comesFromASTReader(DeclGroupRef DGR) {
bool DeclCollector::comesFromASTReader(DeclGroupRef DGR) const {
assert(!DGR.isNull() && "DeclGroupRef is Null!");
if (m_CurTransaction->getCompilationOpts().CodeGenerationForModule)
return true;
// Take the first/only decl in the group.
Decl* D = *DGR.begin();
return D->isFromASTFile();
}
bool DeclCollector::shouldIgnoreDeclFromASTReader(const Decl* D) const {
// Functions that are inlined must be sent to CodeGen - they will not have a
// symbol in the library.
if (const FunctionDecl* FD = dyn_cast<FunctionDecl>(D))
return !FD->isInlined();
// Don't codegen statics coming in from a module; they are already part of
// the library.
if (const VarDecl* VD = dyn_cast<VarDecl>(D))
if (VD->hasGlobalStorage())
return true;
return false;
}
// pin the vtable here.
DeclCollector::~DeclCollector() {
}
@ -31,8 +48,20 @@ namespace cling {
bool DeclCollector::HandleTopLevelDecl(DeclGroupRef DGR) {
// if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
// pipe it directly to codegen.
if (comesFromASTReader(DGR) && m_CodeGen)
return m_CodeGen->HandleTopLevelDecl(DGR);
if (comesFromASTReader(DGR)) {
if (m_CodeGen) {
for (DeclGroupRef::iterator I = DGR.begin(), E = DGR.end();
I != E; ++I)
if (NamespaceDecl* ND = dyn_cast<NamespaceDecl>(*I)) {
for (NamespaceDecl::decl_iterator IN = ND->decls_begin(),
EN = ND->decls_end(); IN != EN; ++IN)
if (!shouldIgnoreDeclFromASTReader(*IN))
m_CodeGen->HandleTopLevelDecl(DeclGroupRef(*IN));
} else if (!shouldIgnoreDeclFromASTReader(*I))
m_CodeGen->HandleTopLevelDecl(DeclGroupRef(*I));
}
return true;
}
Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleTopLevelDecl);
m_CurTransaction->append(DCI);
@ -42,8 +71,15 @@ namespace cling {
void DeclCollector::HandleInterestingDecl(DeclGroupRef DGR) {
// if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
// pipe it directly to codegen.
if (comesFromASTReader(DGR) && m_CodeGen)
return (void)m_CodeGen->HandleTopLevelDecl(DGR);
if (comesFromASTReader(DGR)) {
if (m_CodeGen) {
for (DeclGroupRef::iterator I = DGR.begin(), E = DGR.end();
I != E; ++I)
if (!shouldIgnoreDeclFromASTReader(*I))
m_CodeGen->HandleTopLevelDecl(DeclGroupRef(*I));
}
return;
}
Transaction::DelayCallInfo DCI(DGR, Transaction::kCCIHandleInterestingDecl);
m_CurTransaction->append(DCI);
@ -52,8 +88,11 @@ namespace cling {
void DeclCollector::HandleTagDeclDefinition(TagDecl* TD) {
// if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
// pipe it directly to codegen.
if (comesFromASTReader(DeclGroupRef(TD)) && m_CodeGen)
return m_CodeGen->HandleTagDeclDefinition(TD);
if (comesFromASTReader(DeclGroupRef(TD))) {
if (m_CodeGen)
m_CodeGen->HandleTagDeclDefinition(TD);
return;
}
Transaction::DelayCallInfo DCI(DeclGroupRef(TD),
Transaction::kCCIHandleTagDeclDefinition);
@ -63,8 +102,12 @@ namespace cling {
void DeclCollector::HandleVTable(CXXRecordDecl* RD, bool DefinitionRequired) {
// if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
// pipe it directly to codegen.
if (comesFromASTReader(DeclGroupRef(RD)) && m_CodeGen)
return m_CodeGen->HandleVTable(RD, DefinitionRequired);
if (comesFromASTReader(DeclGroupRef(RD))) {
// FIXME: when is the vtable part of the library?
if (m_CodeGen)
m_CodeGen->HandleVTable(RD, DefinitionRequired);
return;
}
Transaction::DelayCallInfo DCI(DeclGroupRef(RD),
Transaction::kCCIHandleVTable);
@ -88,8 +131,11 @@ namespace cling {
void DeclCollector::HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {
// if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
// pipe it directly to codegen.
if (comesFromASTReader(DeclGroupRef(D)) && m_CodeGen)
return m_CodeGen->HandleCXXImplicitFunctionInstantiation(D);
if (comesFromASTReader(DeclGroupRef(D))) {
if (m_CodeGen)
m_CodeGen->HandleCXXImplicitFunctionInstantiation(D);
return;
}
Transaction::DelayCallInfo DCI(DeclGroupRef(D),
Transaction::kCCIHandleCXXImplicitFunctionInstantiation);
@ -98,8 +144,11 @@ namespace cling {
void DeclCollector::HandleCXXStaticMemberVarInstantiation(VarDecl *D) {
// if that decl comes from an AST File, i.e. PCH/PCM, no transaction needed
// pipe it directly to codegen.
if (comesFromASTReader(DeclGroupRef(D)) && m_CodeGen)
return m_CodeGen->HandleCXXStaticMemberVarInstantiation(D);
if (comesFromASTReader(DeclGroupRef(D))) {
if (m_CodeGen && !shouldIgnoreDeclFromASTReader(D))
m_CodeGen->HandleCXXStaticMemberVarInstantiation(D);
return;
}
Transaction::DelayCallInfo DCI(DeclGroupRef(D),
Transaction::kCCIHandleCXXStaticMemberVarInstantiation);

View File

@ -12,6 +12,7 @@
namespace clang {
class ASTContext;
class CodeGenerator;
class Decl;
class DeclGroupRef;
}
@ -33,6 +34,9 @@ namespace cling {
/// special handling. Eg. deserialized declarations.
clang::CodeGenerator* m_CodeGen; // we do not own.
bool comesFromASTReader(clang::DeclGroupRef DGR) const;
bool shouldIgnoreDeclFromASTReader(const clang::Decl* D) const;
public:
DeclCollector() : m_CurTransaction(0), m_CodeGen(0) {}
virtual ~DeclCollector();