LIndex = DSI;
}
}
- setLastInsn(LastInsn);
+
+ unsigned CurrentLastInsnIndex = 0;
+ if (const MachineInstr *CL = getLastInsn())
+ CurrentLastInsnIndex = MIIndexMap[CL];
+ unsigned FIndex = MIIndexMap[getFirstInsn()];
+
+ // Set LastInsn as the last instruction for this scope only if
+ // it follows
+ // 1) this scope's first instruction and
+ // 2) current last instruction for this scope, if any.
+ if (LIndex >= CurrentLastInsnIndex && LIndex >= FIndex)
+ setLastInsn(LastInsn);
}
#ifndef NDEBUG
1). Add the offset of the forwarding field.
- 2). Follow that pointer to get the the real __Block_byref_x_VarName
+ 2). Follow that pointer to get the real __Block_byref_x_VarName
struct to use (the real one may have been copied onto the heap).
3). Add the offset for the field VarName, to find the actual variable.
// This is not a bitfield.
addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
- addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
+ if (DT.getTag() == dwarf::DW_TAG_inheritance
+ && DT.isVirtual()) {
+
+ // For C++, virtual base classes are not at fixed offset. Use following
+ // expression to extract appropriate offset from vtable.
+ // BaseAddr = ObAddr + *((*ObAddr) - Offset)
+
+ DIEBlock *VBaseLocationDie = new DIEBlock();
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+
+ addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
+ VBaseLocationDie);
+ } else
+ addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
if (DT.isProtected())
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
return SPDie;
SPDie = new DIE(dwarf::DW_TAG_subprogram);
- addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
+ // constructors and operators for anonymous aggregates does not names.
+ if (!SP.getName().empty())
+ addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
StringRef LinkageName = SP.getLinkageName();
if (!LinkageName.empty())
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);
- addType(Arg, DIType(Args.getElement(i).getNode()));
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ 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);
+
// DW_TAG_inlined_subroutine may refer to this DIE.
ModuleCU->insertDIE(SP.getNode(), SPDie);
return SPDie;
DIE *SPDie = ModuleCU->getDIE(SPNode);
assert (SPDie && "Unable to find subprogram DIE!");
DISubprogram SP(SPNode);
- if (SP.isDefinition() && !SP.getContext().isCompileUnit()) {
+ // There is not any need to generate specification DIE for a function
+ // defined at compile unit level. If a function is defined inside another
+ // function then gdb prefers the definition at top level and but does not
+ // expect specification DIE in parent function. So avoid creating
+ // specification DIE for a function defined inside a function.
+ if (SP.isDefinition() && !SP.getContext().isCompileUnit()
+ && !SP.getContext().isSubprogram()) {
addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
// Add arguments.
DICompositeType SPTy = SP.getType();
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);
- addType(Arg, DIType(Args.getElement(i).getNode()));
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1); // ??
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ addType(Arg, ATy);
+ if (ATy.isArtificial())
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
SPDie->addChild(Arg);
}
DIE *SPDeclDie = SPDie;
SPDeclDie);
ModuleCU->addDie(SPDie);
}
-
+
addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
DWLabel("func_begin", SubprogramCount));
addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
else
addAddress(VariableDie, dwarf::DW_AT_location, Location);
}
+
+ if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
+ addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
DV->setDIE(VariableDie);
return VariableDie;
addObjectLabel(Block, 0, dwarf::DW_FORM_udata,
Asm->GetGlobalValueSymbol(DI_GV.getGlobal()));
addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
+ addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
ModuleCU->addDie(VariableSpecDIE);
} else {
DIEBlock *Block = new DIEBlock();
EmitLabel("pubtypes_begin", ModuleCU->getID());
- Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version");
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DWARF Version");
+ Asm->EmitInt16(dwarf::DWARF_VERSION);
EmitSectionOffset("info_begin", "section_info",
ModuleCU->getID(), 0, true, false);
const char *Name = GI->getKeyData();
DIE * Entity = GI->second;
- Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset");
+ if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ Asm->EmitInt32(Entity->getOffset());
if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name");
- Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)), 0);
+ Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
}
Asm->EmitInt32(0); EOL("End Mark");