mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-21 18:29:46 +00:00
Refactor. A subprogram is part of compile unit so let CompileUnit construct new subprogram.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137618 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8757a4c6ab
commit
dbc64af76d
@ -564,7 +564,7 @@ void CompileUnit::addToContextOwner(DIE *Die, DIDescriptor Context) {
|
|||||||
DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
|
DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
|
||||||
ContextDIE->addChild(Die);
|
ContextDIE->addChild(Die);
|
||||||
} else if (Context.isSubprogram()) {
|
} else if (Context.isSubprogram()) {
|
||||||
DIE *ContextDIE = DD->createSubprogramDIE(DISubprogram(Context));
|
DIE *ContextDIE = getOrCreateSubprogramDIE(DISubprogram(Context));
|
||||||
ContextDIE->addChild(Die);
|
ContextDIE->addChild(Die);
|
||||||
} else if (DIE *ContextDIE = getDIE(Context))
|
} else if (DIE *ContextDIE = getDIE(Context))
|
||||||
ContextDIE->addChild(Die);
|
ContextDIE->addChild(Die);
|
||||||
@ -761,7 +761,7 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
|
|||||||
DIE *ElemDie = NULL;
|
DIE *ElemDie = NULL;
|
||||||
if (Element.isSubprogram()) {
|
if (Element.isSubprogram()) {
|
||||||
DISubprogram SP(Element);
|
DISubprogram SP(Element);
|
||||||
ElemDie = DD->createSubprogramDIE(DISubprogram(Element));
|
ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
|
||||||
if (SP.isProtected())
|
if (SP.isProtected())
|
||||||
addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
|
addUInt(ElemDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
|
||||||
dwarf::DW_ACCESS_protected);
|
dwarf::DW_ACCESS_protected);
|
||||||
@ -889,6 +889,111 @@ DIE *CompileUnit::getOrCreateNameSpace(DINameSpace NS) {
|
|||||||
return NDie;
|
return NDie;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
|
||||||
|
/// printer to not emit usual symbol prefix before the symbol name is used then
|
||||||
|
/// return linkage name after skipping this special LLVM prefix.
|
||||||
|
static StringRef getRealLinkageName(StringRef LinkageName) {
|
||||||
|
char One = '\1';
|
||||||
|
if (LinkageName.startswith(StringRef(&One, 1)))
|
||||||
|
return LinkageName.substr(1);
|
||||||
|
return LinkageName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// getOrCreateSubprogramDIE - Create new DIE using SP.
|
||||||
|
DIE *CompileUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
|
||||||
|
DIE *SPDie = getDIE(SP);
|
||||||
|
if (SPDie)
|
||||||
|
return SPDie;
|
||||||
|
|
||||||
|
SPDie = new DIE(dwarf::DW_TAG_subprogram);
|
||||||
|
|
||||||
|
// DW_TAG_inlined_subroutine may refer to this DIE.
|
||||||
|
insertDIE(SP, SPDie);
|
||||||
|
|
||||||
|
// Add to context owner.
|
||||||
|
addToContextOwner(SPDie, SP.getContext());
|
||||||
|
|
||||||
|
// Add function template parameters.
|
||||||
|
addTemplateParams(*SPDie, SP.getTemplateParams());
|
||||||
|
|
||||||
|
StringRef LinkageName = SP.getLinkageName();
|
||||||
|
if (!LinkageName.empty())
|
||||||
|
addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
|
||||||
|
dwarf::DW_FORM_string,
|
||||||
|
getRealLinkageName(LinkageName));
|
||||||
|
|
||||||
|
// If this DIE is going to refer declaration info using AT_specification
|
||||||
|
// then there is no need to add other attributes.
|
||||||
|
if (SP.getFunctionDeclaration().isSubprogram())
|
||||||
|
return SPDie;
|
||||||
|
|
||||||
|
// Constructors and operators for anonymous aggregates do not have names.
|
||||||
|
if (!SP.getName().empty())
|
||||||
|
addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
|
||||||
|
SP.getName());
|
||||||
|
|
||||||
|
addSourceLine(SPDie, SP);
|
||||||
|
|
||||||
|
if (SP.isPrototyped())
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
|
||||||
|
|
||||||
|
// Add Return Type.
|
||||||
|
DICompositeType SPTy = SP.getType();
|
||||||
|
DIArray Args = SPTy.getTypeArray();
|
||||||
|
unsigned SPTag = SPTy.getTag();
|
||||||
|
|
||||||
|
if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
|
||||||
|
addType(SPDie, SPTy);
|
||||||
|
else
|
||||||
|
addType(SPDie, DIType(Args.getElement(0)));
|
||||||
|
|
||||||
|
unsigned VK = SP.getVirtuality();
|
||||||
|
if (VK) {
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
|
||||||
|
DIEBlock *Block = getDIEBlock();
|
||||||
|
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
||||||
|
addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
|
||||||
|
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
|
||||||
|
ContainingTypeMap.insert(std::make_pair(SPDie,
|
||||||
|
SP.getContainingType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SP.isDefinition()) {
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
|
||||||
|
|
||||||
|
// Add arguments. Do not add arguments for subprogram definition. They will
|
||||||
|
// be handled while processing variables.
|
||||||
|
DICompositeType SPTy = SP.getType();
|
||||||
|
DIArray Args = SPTy.getTypeArray();
|
||||||
|
unsigned SPTag = SPTy.getTag();
|
||||||
|
|
||||||
|
if (SPTag == dwarf::DW_TAG_subroutine_type)
|
||||||
|
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
|
||||||
|
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
|
||||||
|
DIType ATy = DIType(DIType(Args.getElement(i)));
|
||||||
|
addType(Arg, ATy);
|
||||||
|
if (ATy.isArtificial())
|
||||||
|
addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
|
||||||
|
SPDie->addChild(Arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SP.isArtificial())
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
|
||||||
|
|
||||||
|
if (!SP.isLocalToUnit())
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
|
||||||
|
|
||||||
|
if (SP.isOptimized())
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
|
||||||
|
|
||||||
|
if (unsigned isa = Asm->getISAEncoding()) {
|
||||||
|
addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SPDie;
|
||||||
|
}
|
||||||
|
|
||||||
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
|
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
|
||||||
void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
|
void CompileUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
|
||||||
DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
|
DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
|
||||||
@ -953,6 +1058,20 @@ DIE *CompileUnit::constructEnumTypeDIE(DIEnumerator ETy) {
|
|||||||
return Enumerator;
|
return Enumerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// constructContainingTypeDIEs - Construct DIEs for types that contain
|
||||||
|
/// vtables.
|
||||||
|
void CompileUnit::constructContainingTypeDIEs() {
|
||||||
|
for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
|
||||||
|
CE = ContainingTypeMap.end(); CI != CE; ++CI) {
|
||||||
|
DIE *SPDie = CI->first;
|
||||||
|
const MDNode *N = CI->second;
|
||||||
|
if (!N) continue;
|
||||||
|
DIE *NDie = getDIE(N);
|
||||||
|
if (!NDie) continue;
|
||||||
|
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// createMemberDIE - Create new member DIE.
|
/// createMemberDIE - Create new member DIE.
|
||||||
DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
|
DIE *CompileUnit::createMemberDIE(DIDerivedType DT) {
|
||||||
DIE *MemberDie = new DIE(DT.getTag());
|
DIE *MemberDie = new DIE(DT.getTag());
|
||||||
|
@ -67,6 +67,11 @@ class CompileUnit {
|
|||||||
/// DIEBlocks - A list of all the DIEBlocks in use.
|
/// DIEBlocks - A list of all the DIEBlocks in use.
|
||||||
std::vector<DIEBlock *> DIEBlocks;
|
std::vector<DIEBlock *> DIEBlocks;
|
||||||
|
|
||||||
|
/// ContainingTypeMap - This map is used to keep track of subprogram DIEs that
|
||||||
|
/// need DW_AT_containing_type attribute. This attribute points to a DIE that
|
||||||
|
/// corresponds to the MDNode mapped with the subprogram DIE.
|
||||||
|
DenseMap<DIE *, const MDNode *> ContainingTypeMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW);
|
CompileUnit(unsigned I, DIE *D, AsmPrinter *A, DwarfDebug *DW);
|
||||||
~CompileUnit();
|
~CompileUnit();
|
||||||
@ -226,6 +231,9 @@ public:
|
|||||||
/// getOrCreateNameSpace - Create a DIE for DINameSpace.
|
/// getOrCreateNameSpace - Create a DIE for DINameSpace.
|
||||||
DIE *getOrCreateNameSpace(DINameSpace NS);
|
DIE *getOrCreateNameSpace(DINameSpace NS);
|
||||||
|
|
||||||
|
/// getOrCreateSubprogramDIE - Create new DIE using SP.
|
||||||
|
DIE *getOrCreateSubprogramDIE(DISubprogram SP);
|
||||||
|
|
||||||
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
|
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
|
||||||
/// given DIType.
|
/// given DIType.
|
||||||
DIE *getOrCreateTypeDIE(DIType Ty);
|
DIE *getOrCreateTypeDIE(DIType Ty);
|
||||||
@ -266,6 +274,10 @@ public:
|
|||||||
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
|
/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
|
||||||
DIE *constructEnumTypeDIE(DIEnumerator ETy);
|
DIE *constructEnumTypeDIE(DIEnumerator ETy);
|
||||||
|
|
||||||
|
/// constructContainingTypeDIEs - Construct DIEs for types that contain
|
||||||
|
/// vtables.
|
||||||
|
void constructContainingTypeDIEs();
|
||||||
|
|
||||||
/// createMemberDIE - Create new member DIE.
|
/// createMemberDIE - Create new member DIE.
|
||||||
DIE *createMemberDIE(DIDerivedType DT);
|
DIE *createMemberDIE(DIDerivedType DT);
|
||||||
|
|
||||||
|
@ -179,102 +179,6 @@ static StringRef getRealLinkageName(StringRef LinkageName) {
|
|||||||
return LinkageName;
|
return LinkageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createSubprogramDIE - Create new DIE using SP.
|
|
||||||
DIE *DwarfDebug::createSubprogramDIE(DISubprogram SP) {
|
|
||||||
CompileUnit *SPCU = getCompileUnit(SP);
|
|
||||||
DIE *SPDie = SPCU->getDIE(SP);
|
|
||||||
if (SPDie)
|
|
||||||
return SPDie;
|
|
||||||
|
|
||||||
SPDie = new DIE(dwarf::DW_TAG_subprogram);
|
|
||||||
|
|
||||||
// DW_TAG_inlined_subroutine may refer to this DIE.
|
|
||||||
SPCU->insertDIE(SP, SPDie);
|
|
||||||
|
|
||||||
// Add to context owner.
|
|
||||||
SPCU->addToContextOwner(SPDie, SP.getContext());
|
|
||||||
|
|
||||||
// Add function template parameters.
|
|
||||||
SPCU->addTemplateParams(*SPDie, SP.getTemplateParams());
|
|
||||||
|
|
||||||
StringRef LinkageName = SP.getLinkageName();
|
|
||||||
if (!LinkageName.empty())
|
|
||||||
SPCU->addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
|
|
||||||
dwarf::DW_FORM_string,
|
|
||||||
getRealLinkageName(LinkageName));
|
|
||||||
|
|
||||||
// If this DIE is going to refer declaration info using AT_specification
|
|
||||||
// then there is no need to add other attributes.
|
|
||||||
if (SP.getFunctionDeclaration().isSubprogram())
|
|
||||||
return SPDie;
|
|
||||||
|
|
||||||
// Constructors and operators for anonymous aggregates do not have names.
|
|
||||||
if (!SP.getName().empty())
|
|
||||||
SPCU->addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
|
|
||||||
SP.getName());
|
|
||||||
|
|
||||||
SPCU->addSourceLine(SPDie, SP);
|
|
||||||
|
|
||||||
if (SP.isPrototyped())
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
|
|
||||||
|
|
||||||
// Add Return Type.
|
|
||||||
DICompositeType SPTy = SP.getType();
|
|
||||||
DIArray Args = SPTy.getTypeArray();
|
|
||||||
unsigned SPTag = SPTy.getTag();
|
|
||||||
|
|
||||||
if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
|
|
||||||
SPCU->addType(SPDie, SPTy);
|
|
||||||
else
|
|
||||||
SPCU->addType(SPDie, DIType(Args.getElement(0)));
|
|
||||||
|
|
||||||
unsigned VK = SP.getVirtuality();
|
|
||||||
if (VK) {
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
|
|
||||||
DIEBlock *Block = SPCU->getDIEBlock();
|
|
||||||
SPCU->addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
|
|
||||||
SPCU->addUInt(Block, 0, dwarf::DW_FORM_udata, SP.getVirtualIndex());
|
|
||||||
SPCU->addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
|
|
||||||
ContainingTypeMap.insert(std::make_pair(SPDie,
|
|
||||||
SP.getContainingType()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!SP.isDefinition()) {
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
|
|
||||||
|
|
||||||
// Add arguments. Do not add arguments for subprogram definition. They will
|
|
||||||
// be handled while processing variables.
|
|
||||||
DICompositeType SPTy = SP.getType();
|
|
||||||
DIArray Args = SPTy.getTypeArray();
|
|
||||||
unsigned SPTag = SPTy.getTag();
|
|
||||||
|
|
||||||
if (SPTag == dwarf::DW_TAG_subroutine_type)
|
|
||||||
for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
|
|
||||||
DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
|
|
||||||
DIType ATy = DIType(DIType(Args.getElement(i)));
|
|
||||||
SPCU->addType(Arg, ATy);
|
|
||||||
if (ATy.isArtificial())
|
|
||||||
SPCU->addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
|
|
||||||
SPDie->addChild(Arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SP.isArtificial())
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
|
|
||||||
|
|
||||||
if (!SP.isLocalToUnit())
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
|
|
||||||
|
|
||||||
if (SP.isOptimized())
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
|
|
||||||
|
|
||||||
if (unsigned isa = Asm->getISAEncoding()) {
|
|
||||||
SPCU->addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
|
|
||||||
}
|
|
||||||
|
|
||||||
return SPDie;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// isSubprogramContext - Return true if Context is either a subprogram
|
/// isSubprogramContext - Return true if Context is either a subprogram
|
||||||
/// or another context nested inside a subprogram.
|
/// or another context nested inside a subprogram.
|
||||||
static bool isSubprogramContext(const MDNode *Context) {
|
static bool isSubprogramContext(const MDNode *Context) {
|
||||||
@ -303,7 +207,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {
|
|||||||
if (SPDecl.isSubprogram())
|
if (SPDecl.isSubprogram())
|
||||||
// Refer function declaration directly.
|
// Refer function declaration directly.
|
||||||
SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
|
SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
|
||||||
createSubprogramDIE(SPDecl));
|
SPCU->getOrCreateSubprogramDIE(SPDecl));
|
||||||
else {
|
else {
|
||||||
// There is not any need to generate specification DIE for a function
|
// There is not any need to generate specification DIE for a function
|
||||||
// defined at compile unit level. If a function is defined inside another
|
// defined at compile unit level. If a function is defined inside another
|
||||||
@ -922,7 +826,7 @@ void DwarfDebug::constructSubprogramDIE(const MDNode *N) {
|
|||||||
// class type.
|
// class type.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
DIE *SubprogramDie = createSubprogramDIE(SP);
|
DIE *SubprogramDie = TheCU->getOrCreateSubprogramDIE(SP);
|
||||||
|
|
||||||
// Add to map.
|
// Add to map.
|
||||||
TheCU->insertDIE(N, SubprogramDie);
|
TheCU->insertDIE(N, SubprogramDie);
|
||||||
@ -1070,15 +974,12 @@ void DwarfDebug::endModule() {
|
|||||||
FirstCU->addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
|
FirstCU->addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
|
// Emit DW_AT_containing_type attribute to connect types with their
|
||||||
CE = ContainingTypeMap.end(); CI != CE; ++CI) {
|
// vtable holding type.
|
||||||
DIE *SPDie = CI->first;
|
for (DenseMap<const MDNode *, CompileUnit *>::iterator CUI = CUMap.begin(),
|
||||||
const MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
|
CUE = CUMap.end(); CUI != CUE; ++CUI) {
|
||||||
if (!N) continue;
|
CompileUnit *TheCU = CUI->second;
|
||||||
DIE *NDie = getCompileUnit(N)->getDIE(N);
|
TheCU->constructContainingTypeDIEs();
|
||||||
if (!NDie) continue;
|
|
||||||
getCompileUnit(N)->addDIEEntry(SPDie, dwarf::DW_AT_containing_type,
|
|
||||||
dwarf::DW_FORM_ref4, NDie);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Standard sections final addresses.
|
// Standard sections final addresses.
|
||||||
|
@ -229,11 +229,6 @@ class DwarfDebug {
|
|||||||
/// (at the end of the module) as DW_AT_inline.
|
/// (at the end of the module) as DW_AT_inline.
|
||||||
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
|
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
|
||||||
|
|
||||||
/// ContainingTypeMap - This map is used to keep track of subprogram DIEs that
|
|
||||||
/// need DW_AT_containing_type attribute. This attribute points to a DIE that
|
|
||||||
/// corresponds to the MDNode mapped with the subprogram DIE.
|
|
||||||
DenseMap<DIE *, const MDNode *> ContainingTypeMap;
|
|
||||||
|
|
||||||
/// InlineInfo - Keep track of inlined functions and their location. This
|
/// InlineInfo - Keep track of inlined functions and their location. This
|
||||||
/// information is used to populate debug_inlined section.
|
/// information is used to populate debug_inlined section.
|
||||||
typedef std::pair<const MCSymbol *, DIE *> InlineInfoLabels;
|
typedef std::pair<const MCSymbol *, DIE *> InlineInfoLabels;
|
||||||
|
Loading…
Reference in New Issue
Block a user