diff options
| author | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-15 15:37:28 +0000 |
|---|---|---|
| committer | Roman Divacky <rdivacky@FreeBSD.org> | 2010-01-15 15:37:28 +0000 |
| commit | 829000e035f46f2a227a5466e4e427a2f3cc00a9 (patch) | |
| tree | be5a687969f682edded4aa6f13594ffd9aa9030e /lib/CodeGen/AsmPrinter | |
| parent | 1e7804dbd25b8dbf534c850355d70ad215206f4b (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
| -rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 328 | ||||
| -rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 178 |
2 files changed, 271 insertions, 235 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 6b24e24d3716..876f628336fa 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -807,124 +807,145 @@ void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const { // Print out the specified constant, without a storage class. Only the // constants valid in constant expressions can occur here. void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { - if (CV->isNullValue() || isa<UndefValue>(CV)) + if (CV->isNullValue() || isa<UndefValue>(CV)) { O << '0'; - else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { + return; + } + + if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { O << CI->getZExtValue(); - } else if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { + return; + } + + if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { // This is a constant address for a global variable or function. Use the // name of the variable or function as the address value. O << Mang->getMangledName(GV); - } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) { + return; + } + + if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) { + GetBlockAddressSymbol(BA)->print(O, MAI); + return; + } + + const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); + if (CE == 0) { + llvm_unreachable("Unknown constant value!"); + O << '0'; + return; + } + + switch (CE->getOpcode()) { + case Instruction::ZExt: + case Instruction::SExt: + case Instruction::FPTrunc: + case Instruction::FPExt: + case Instruction::UIToFP: + case Instruction::SIToFP: + case Instruction::FPToUI: + case Instruction::FPToSI: + default: + llvm_unreachable("FIXME: Don't support this constant cast expr"); + case Instruction::GetElementPtr: { + // generate a symbolic expression for the byte address const TargetData *TD = TM.getTargetData(); - unsigned Opcode = CE->getOpcode(); - switch (Opcode) { - case Instruction::Trunc: - case Instruction::ZExt: - case Instruction::SExt: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::FPToUI: - case Instruction::FPToSI: - llvm_unreachable("FIXME: Don't support this constant cast expr"); - case Instruction::GetElementPtr: { - // generate a symbolic expression for the byte address - const Constant *ptrVal = CE->getOperand(0); - SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end()); - if (int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], - idxVec.size())) { - // Truncate/sext the offset to the pointer size. - if (TD->getPointerSizeInBits() != 64) { - int SExtAmount = 64-TD->getPointerSizeInBits(); - Offset = (Offset << SExtAmount) >> SExtAmount; - } - - if (Offset) - O << '('; - EmitConstantValueOnly(ptrVal); - if (Offset > 0) - O << ") + " << Offset; - else if (Offset < 0) - O << ") - " << -Offset; - } else { - EmitConstantValueOnly(ptrVal); - } - break; + const Constant *ptrVal = CE->getOperand(0); + SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end()); + int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], + idxVec.size()); + if (Offset == 0) + return EmitConstantValueOnly(ptrVal); + + // Truncate/sext the offset to the pointer size. + if (TD->getPointerSizeInBits() != 64) { + int SExtAmount = 64-TD->getPointerSizeInBits(); + Offset = (Offset << SExtAmount) >> SExtAmount; } - case Instruction::BitCast: - return EmitConstantValueOnly(CE->getOperand(0)); - - case Instruction::IntToPtr: { - // Handle casts to pointers by changing them into casts to the appropriate - // integer type. This promotes constant folding and simplifies this code. - Constant *Op = CE->getOperand(0); - Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()), - false/*ZExt*/); + + if (Offset) + O << '('; + EmitConstantValueOnly(ptrVal); + if (Offset > 0) + O << ") + " << Offset; + else + O << ") - " << -Offset; + return; + } + case Instruction::BitCast: + return EmitConstantValueOnly(CE->getOperand(0)); + + case Instruction::IntToPtr: { + // Handle casts to pointers by changing them into casts to the appropriate + // integer type. This promotes constant folding and simplifies this code. + const TargetData *TD = TM.getTargetData(); + Constant *Op = CE->getOperand(0); + Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()), + false/*ZExt*/); + return EmitConstantValueOnly(Op); + } + + case Instruction::PtrToInt: { + // Support only foldable casts to/from pointers that can be eliminated by + // changing the pointer to the appropriately sized integer type. + Constant *Op = CE->getOperand(0); + const Type *Ty = CE->getType(); + const TargetData *TD = TM.getTargetData(); + + // We can emit the pointer value into this slot if the slot is an + // integer slot greater or equal to the size of the pointer. + if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType())) return EmitConstantValueOnly(Op); - } - + + O << "(("; + EmitConstantValueOnly(Op); + APInt ptrMask = + APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType())); + + SmallString<40> S; + ptrMask.toStringUnsigned(S); + O << ") & " << S.str() << ')'; + return; + } - case Instruction::PtrToInt: { - // Support only foldable casts to/from pointers that can be eliminated by - // changing the pointer to the appropriately sized integer type. - Constant *Op = CE->getOperand(0); - const Type *Ty = CE->getType(); - - // We can emit the pointer value into this slot if the slot is an - // integer slot greater or equal to the size of the pointer. - if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType())) - return EmitConstantValueOnly(Op); - - O << "(("; - EmitConstantValueOnly(Op); - APInt ptrMask = - APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType())); + case Instruction::Trunc: + // We emit the value and depend on the assembler to truncate the generated + // expression properly. This is important for differences between + // blockaddress labels. Since the two labels are in the same function, it + // is reasonable to treat their delta as a 32-bit value. + return EmitConstantValueOnly(CE->getOperand(0)); - SmallString<40> S; - ptrMask.toStringUnsigned(S); - O << ") & " << S.str() << ')'; - break; - } + case Instruction::Add: + case Instruction::Sub: + case Instruction::And: + case Instruction::Or: + case Instruction::Xor: + O << '('; + EmitConstantValueOnly(CE->getOperand(0)); + O << ')'; + switch (CE->getOpcode()) { case Instruction::Add: + O << " + "; + break; case Instruction::Sub: + O << " - "; + break; case Instruction::And: + O << " & "; + break; case Instruction::Or: + O << " | "; + break; case Instruction::Xor: - O << '('; - EmitConstantValueOnly(CE->getOperand(0)); - O << ')'; - switch (Opcode) { - case Instruction::Add: - O << " + "; - break; - case Instruction::Sub: - O << " - "; - break; - case Instruction::And: - O << " & "; - break; - case Instruction::Or: - O << " | "; - break; - case Instruction::Xor: - O << " ^ "; - break; - default: - break; - } - O << '('; - EmitConstantValueOnly(CE->getOperand(1)); - O << ')'; - break; + O << " ^ "; + break; default: - llvm_unreachable("Unsupported operator!"); + break; } - } else if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) { - GetBlockAddressSymbol(BA)->print(O, MAI); - } else { - llvm_unreachable("Unknown constant value!"); + O << '('; + EmitConstantValueOnly(CE->getOperand(1)); + O << ')'; + break; } } @@ -1225,8 +1246,7 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI, unsigned AddrSpace) { const TargetData *TD = TM.getTargetData(); unsigned BitWidth = CI->getBitWidth(); - assert(isPowerOf2_32(BitWidth) && - "Non-power-of-2-sized integers not handled!"); + assert((BitWidth & 63) == 0 && "only support multiples of 64-bits"); // We don't expect assemblers to support integer data directives // for more than 64 bits, so we emit the data in at most 64-bit @@ -1239,39 +1259,34 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI, else Val = RawData[i]; - if (MAI->getData64bitsDirective(AddrSpace)) + if (MAI->getData64bitsDirective(AddrSpace)) { O << MAI->getData64bitsDirective(AddrSpace) << Val << '\n'; - else if (TD->isBigEndian()) { - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant half of i64 " << Val; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant half of i64 " << Val; - } - O << '\n'; - } else { - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant half of i64 " << Val; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant half of i64 " << Val; - } - O << '\n'; + continue; } + + // Emit two 32-bit chunks, order depends on endianness. + unsigned FirstChunk = unsigned(Val), SecondChunk = unsigned(Val >> 32); + const char *FirstName = " least", *SecondName = " most"; + if (TD->isBigEndian()) { + std::swap(FirstChunk, SecondChunk); + std::swap(FirstName, SecondName); + } + + O << MAI->getData32bitsDirective(AddrSpace) << FirstChunk; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << FirstName << " significant half of i64 " << Val; + } + O << '\n'; + + O << MAI->getData32bitsDirective(AddrSpace) << SecondChunk; + if (VerboseAsm) { + O.PadToColumn(MAI->getCommentColumn()); + O << MAI->getCommentString() + << SecondName << " significant half of i64 " << Val; + } + O << '\n'; } } @@ -1284,22 +1299,39 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { if (CV->isNullValue() || isa<UndefValue>(CV)) { EmitZeros(Size, AddrSpace); return; - } else if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { + } + + if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { EmitGlobalConstantArray(CVA , AddrSpace); return; - } else if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { + } + + if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { EmitGlobalConstantStruct(CVS, AddrSpace); return; - } else if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { + } + + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { EmitGlobalConstantFP(CFP, AddrSpace); return; - } else if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { + } + + if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { + // If we can directly emit an 8-byte constant, do it. + if (Size == 8) + if (const char *Data64Dir = MAI->getData64bitsDirective(AddrSpace)) { + O << Data64Dir << CI->getZExtValue() << '\n'; + return; + } + // Small integers are handled below; large integers are handled here. if (Size > 4) { EmitGlobalConstantLargeInt(CI, AddrSpace); return; } - } else if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { + } + + if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { EmitGlobalConstantVector(CP); return; } @@ -1617,7 +1649,7 @@ void AsmPrinter::printLabel(unsigned Id) const { /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM /// instruction, using the specified assembler variant. Targets should -/// overried this to format as appropriate. +/// override this to format as appropriate. bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode) { // Target doesn't support this yet! @@ -1645,15 +1677,17 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F, // This code must use the function name itself, and not the function number, // since it must be possible to generate the label name from within other // functions. - std::string FuncName = Mang->getMangledName(F); + SmallString<60> FnName; + Mang->getNameWithPrefix(FnName, F, false); - SmallString<60> Name; - raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA" - << FuncName.size() << '_' << FuncName << '_' - << Mang->makeNameProper(BB->getName()) - << Suffix; + // FIXME: THIS IS BROKEN IF THE LLVM BASIC BLOCK DOESN'T HAVE A NAME! + SmallString<60> NameResult; + Mang->getNameWithPrefix(NameResult, + StringRef("BA") + Twine((unsigned)FnName.size()) + + "_" + FnName.str() + "_" + BB->getName() + Suffix, + Mangler::Private); - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateSymbol(NameResult.str()); } MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const { diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 8a3ceb631d03..15f37aec148a 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -212,19 +212,30 @@ public: /// void addVariable(DbgVariable *V) { Variables.push_back(V); } - void fixInstructionMarkers() { + void fixInstructionMarkers(DenseMap<const MachineInstr *, + unsigned> &MIIndexMap) { assert (getFirstInsn() && "First instruction is missing!"); - if (getLastInsn()) - return; - - // If a scope does not have an instruction to mark an end then use - // the end of last child scope. + + // Use the end of last child scope as end of this scope. SmallVector<DbgScope *, 4> &Scopes = getScopes(); - assert (!Scopes.empty() && "Inner most scope does not have last insn!"); - DbgScope *L = Scopes.back(); - if (!L->getLastInsn()) - L->fixInstructionMarkers(); - setLastInsn(L->getLastInsn()); + const MachineInstr *LastInsn = getFirstInsn(); + unsigned LIndex = 0; + if (Scopes.empty()) { + assert (getLastInsn() && "Inner most scope does not have last insn!"); + return; + } + for (SmallVector<DbgScope *, 4>::iterator SI = Scopes.begin(), + SE = Scopes.end(); SI != SE; ++SI) { + DbgScope *DS = *SI; + DS->fixInstructionMarkers(MIIndexMap); + const MachineInstr *DSLastInsn = DS->getLastInsn(); + unsigned DSI = MIIndexMap[DSLastInsn]; + if (DSI > LIndex) { + LastInsn = DSLastInsn; + LIndex = DSI; + } + } + setLastInsn(LastInsn); } #ifndef NDEBUG @@ -1021,6 +1032,16 @@ DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) { return Enumerator; } +/// 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; +} + /// createGlobalVariableDIE - Create new DIE using GV. DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) { // If the global variable was optmized out then no need to create debug info @@ -1033,16 +1054,10 @@ DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) { GV.getDisplayName()); StringRef LinkageName = GV.getLinkageName(); - if (!LinkageName.empty()) { - // Skip special LLVM prefix that is used to inform the asm printer to not - // emit usual symbol prefix before the symbol name. This happens for - // Objective-C symbol names and symbol whose name is replaced using GCC's - // __asm__ attribute. - if (LinkageName[0] == 1) - LinkageName = LinkageName.substr(1); + if (!LinkageName.empty()) addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, - LinkageName); - } + getRealLinkageName(LinkageName)); + addType(GVDie, GV.getType()); if (!GV.isLocalToUnit()) addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); @@ -1074,10 +1089,9 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) { addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits()); uint64_t Offset = DT.getOffsetInBits(); - uint64_t FieldOffset = Offset; uint64_t AlignMask = ~(DT.getAlignInBits() - 1); uint64_t HiMark = (Offset + FieldSize) & AlignMask; - FieldOffset = (HiMark - FieldSize); + uint64_t FieldOffset = (HiMark - FieldSize); Offset -= FieldOffset; // Maybe we need to work from the other end. @@ -1119,16 +1133,10 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) { addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName()); StringRef LinkageName = SP.getLinkageName(); - if (!LinkageName.empty()) { - // Skip special LLVM prefix that is used to inform the asm printer to not - // emit usual symbol prefix before the symbol name. This happens for - // Objective-C symbol names and symbol whose name is replaced using GCC's - // __asm__ attribute. - if (LinkageName[0] == 1) - LinkageName = LinkageName.substr(1); + if (!LinkageName.empty()) addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string, - LinkageName); - } + getRealLinkageName(LinkageName)); + addSourceLine(SPDie, &SP); // Add prototyped tag, if C or ObjC. @@ -1382,7 +1390,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { I->second.push_back(std::make_pair(StartID, ScopeDIE)); StringPool.insert(InlinedSP.getName()); - StringPool.insert(InlinedSP.getLinkageName()); + StringPool.insert(getRealLinkageName(InlinedSP.getLinkageName())); + DILocation DL(Scope->getInlinedAt()); addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID()); addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber()); @@ -1644,8 +1653,11 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { ModuleCU->insertDIE(N, VariableDie); // Add to context owner. - if (DI_GV.isDefinition() - && !DI_GV.getContext().isCompileUnit()) { + DIDescriptor GVContext = DI_GV.getContext(); + // Do not create specification DIE if context is either compile unit + // or a subprogram. + if (DI_GV.isDefinition() && !GVContext.isCompileUnit() + && !GVContext.isSubprogram()) { // Create specification DIE. DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable); addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, @@ -1663,7 +1675,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { Asm->Mang->getMangledName(DI_GV.getGlobal())); addBlock(VariableDie, dwarf::DW_AT_location, 0, Block); } - addToContextOwner(VariableDie, DI_GV.getContext()); + addToContextOwner(VariableDie, GVContext); // Expose as global. FIXME - need to check external flag. ModuleCU->addGlobal(DI_GV.getName(), VariableDie); @@ -1804,7 +1816,8 @@ void DwarfDebug::endModule() { DIE *NDie = ModuleCU->getDIE(N); if (!NDie) continue; addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie); - addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie); + // FIXME - This is not the correct approach. + // addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie); } // Standard sections final addresses. @@ -1976,12 +1989,15 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) { if (!DbgScopeMap.empty()) return false; + DenseMap<const MachineInstr *, unsigned> MIIndexMap; + unsigned MIIndex = 0; // Scan each instruction and create scopes. First build working set of scopes. for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E; ++I) { for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; + MIIndexMap[MInsn] = MIIndex++; DebugLoc DL = MInsn->getDebugLoc(); if (DL.isUnknown()) continue; DebugLocTuple DLT = MF->getDebugLocTuple(DL); @@ -2014,16 +2030,10 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) { } } - // If a scope's last instruction is not set then use its child scope's - // last instruction as this scope's last instrunction. - for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(), - DE = DbgScopeMap.end(); DI != DE; ++DI) { - if (DI->second->isAbstractScope()) - continue; - assert (DI->second->getFirstInsn() && "Invalid first instruction!"); - DI->second->fixInstructionMarkers(); - assert (DI->second->getLastInsn() && "Invalid last instruction!"); - } + if (!CurrentFnDbgScope) + return false; + + CurrentFnDbgScope->fixInstructionMarkers(MIIndexMap); // Each scope has first instruction and last instruction to mark beginning // and end of a scope respectively. Create an inverse map that list scopes @@ -2105,38 +2115,41 @@ void DwarfDebug::endFunction(MachineFunction *MF) { if (DbgScopeMap.empty()) return; - // Define end label for subprogram. - EmitLabel("func_end", SubprogramCount); - - // Get function line info. - if (!Lines.empty()) { - // Get section line info. - unsigned ID = SectionMap.insert(Asm->getCurrentSection()); - if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID); - std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1]; - // Append the function info to section info. - SectionLineInfos.insert(SectionLineInfos.end(), - Lines.begin(), Lines.end()); + if (CurrentFnDbgScope) { + // Define end label for subprogram. + EmitLabel("func_end", SubprogramCount); + + // Get function line info. + if (!Lines.empty()) { + // Get section line info. + unsigned ID = SectionMap.insert(Asm->getCurrentSection()); + if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID); + std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1]; + // Append the function info to section info. + SectionLineInfos.insert(SectionLineInfos.end(), + Lines.begin(), Lines.end()); + } + + // Construct abstract scopes. + for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(), + AE = AbstractScopesList.end(); AI != AE; ++AI) + constructScopeDIE(*AI); + + constructScopeDIE(CurrentFnDbgScope); + + DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, + MMI->getFrameMoves())); } - // Construct abstract scopes. - for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(), - AE = AbstractScopesList.end(); AI != AE; ++AI) - constructScopeDIE(*AI); - - constructScopeDIE(CurrentFnDbgScope); - - DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount, - MMI->getFrameMoves())); - // Clear debug info - CurrentFnDbgScope = NULL; - DbgScopeMap.clear(); - DbgScopeBeginMap.clear(); - DbgScopeEndMap.clear(); - ConcreteScopes.clear(); - AbstractScopesList.clear(); - + if (CurrentFnDbgScope) { + CurrentFnDbgScope = NULL; + DbgScopeMap.clear(); + DbgScopeBeginMap.clear(); + DbgScopeEndMap.clear(); + ConcreteScopes.clear(); + AbstractScopesList.clear(); + } Lines.clear(); if (TimePassesIsEnabled) @@ -2908,8 +2921,6 @@ void DwarfDebug::emitDebugInlineInfo() { for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(), E = InlinedSPNodes.end(); I != E; ++I) { -// for (ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator - // I = InlineInfo.begin(), E = InlineInfo.end(); I != E; ++I) { MDNode *Node = *I; ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II = InlineInfo.find(Node); @@ -2920,20 +2931,11 @@ void DwarfDebug::emitDebugInlineInfo() { if (LName.empty()) Asm->EmitString(Name); - else { - // Skip special LLVM prefix that is used to inform the asm printer to not - // emit usual symbol prefix before the symbol name. This happens for - // Objective-C symbol names and symbol whose name is replaced using GCC's - // __asm__ attribute. - if (LName[0] == 1) - LName = LName.substr(1); -// Asm->EmitString(LName); + else EmitSectionOffset("string", "section_str", - StringPool.idFor(LName), false, true); + StringPool.idFor(getRealLinkageName(LName)), false, true); - } Asm->EOL("MIPS linkage name"); -// Asm->EmitString(Name); EmitSectionOffset("string", "section_str", StringPool.idFor(Name), false, true); Asm->EOL("Function name"); |
