aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp23
-rw-r--r--lib/CodeGen/AsmPrinter/AddressPool.cpp45
-rw-r--r--lib/CodeGen/AsmPrinter/AddressPool.h52
-rw-r--r--lib/CodeGen/AsmPrinter/Android.mk12
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp287
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp74
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp25
-rw-r--r--lib/CodeGen/AsmPrinter/CMakeLists.txt4
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp21
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h37
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.cpp18
-rw-r--r--lib/CodeGen/AsmPrinter/DIEHash.h2
-rw-r--r--lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp175
-rw-r--r--lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h54
-rw-r--r--lib/CodeGen/AsmPrinter/DebugLocEntry.h138
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp39
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfAccelTable.h29
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp1609
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h211
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp28
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfFile.cpp156
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfFile.h84
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfStringPool.cpp74
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfStringPool.h55
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.cpp838
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.h174
-rw-r--r--lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp27
-rw-r--r--lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h4
28 files changed, 2267 insertions, 2028 deletions
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index 403feb4..1cb0159 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -57,10 +57,10 @@ void ARMException::endModule() {
/// beginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void ARMException::beginFunction(const MachineFunction *MF) {
- getTargetStreamer().emitFnStart();
- if (Asm->MF->getFunction()->needsUnwindTableEntry())
- Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
- Asm->getFunctionNumber()));
+ if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
+ getTargetStreamer().emitFnStart();
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
+ Asm->getFunctionNumber()));
// See if we need call frame info.
AsmPrinter::CFIMoveType MoveType = Asm->needsCFIMoves();
assert(MoveType != AsmPrinter::CFI_M_EH &&
@@ -77,16 +77,16 @@ void ARMException::endFunction(const MachineFunction *) {
if (shouldEmitCFI)
Asm->OutStreamer.EmitCFIEndProc();
+ // Map all labels and get rid of any dead landing pads.
+ MMI->TidyLandingPads();
+
ARMTargetStreamer &ATS = getTargetStreamer();
- if (!Asm->MF->getFunction()->needsUnwindTableEntry())
+ if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
+ MMI->getLandingPads().empty())
ATS.emitCantUnwind();
else {
Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
Asm->getFunctionNumber()));
-
- // Map all labels and get rid of any dead landing pads.
- MMI->TidyLandingPads();
-
if (!MMI->getLandingPads().empty()) {
// Emit references to personality.
if (const Function * Personality =
@@ -104,7 +104,8 @@ void ARMException::endFunction(const MachineFunction *) {
}
}
- ATS.emitFnEnd();
+ if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::ARM)
+ ATS.emitFnEnd();
}
void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
@@ -144,7 +145,7 @@ void ARMException::EmitTypeInfos(unsigned TTypeEncoding) {
Asm->OutStreamer.AddComment("FilterInfo " + Twine(Entry));
}
- Asm->EmitTTypeReference((TypeID == 0 ? 0 : TypeInfos[TypeID - 1]),
+ Asm->EmitTTypeReference((TypeID == 0 ? nullptr : TypeInfos[TypeID - 1]),
TTypeEncoding);
}
}
diff --git a/lib/CodeGen/AsmPrinter/AddressPool.cpp b/lib/CodeGen/AsmPrinter/AddressPool.cpp
new file mode 100644
index 0000000..8dab5e5
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/AddressPool.cpp
@@ -0,0 +1,45 @@
+//===-- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "AddressPool.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+
+using namespace llvm;
+
+class MCExpr;
+
+unsigned AddressPool::getIndex(const MCSymbol *Sym, bool TLS) {
+ HasBeenUsed = true;
+ auto IterBool =
+ Pool.insert(std::make_pair(Sym, AddressPoolEntry(Pool.size(), TLS)));
+ return IterBool.first->second.Number;
+}
+
+// Emit addresses into the section given.
+void AddressPool::emit(AsmPrinter &Asm, const MCSection *AddrSection) {
+ if (Pool.empty())
+ return;
+
+ // Start the dwarf addr section.
+ Asm.OutStreamer.SwitchSection(AddrSection);
+
+ // Order the address pool entries by ID
+ SmallVector<const MCExpr *, 64> Entries(Pool.size());
+
+ for (const auto &I : Pool)
+ Entries[I.second.Number] =
+ I.second.TLS
+ ? Asm.getObjFileLowering().getDebugThreadLocalSymbol(I.first)
+ : MCSymbolRefExpr::Create(I.first, Asm.OutContext);
+
+ for (const MCExpr *Entry : Entries)
+ Asm.OutStreamer.EmitValue(Entry, Asm.getDataLayout().getPointerSize());
+}
diff --git a/lib/CodeGen/AsmPrinter/AddressPool.h b/lib/CodeGen/AsmPrinter/AddressPool.h
new file mode 100644
index 0000000..42757d7
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/AddressPool.h
@@ -0,0 +1,52 @@
+//===-- llvm/CodeGen/AddressPool.h - Dwarf Debug Framework -----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_ASMPRINTER_ADDRESSPOOL_H__
+#define CODEGEN_ASMPRINTER_ADDRESSPOOL_H__
+
+#include "llvm/ADT/DenseMap.h"
+
+namespace llvm {
+class MCSection;
+class MCSymbol;
+class AsmPrinter;
+// Collection of addresses for this unit and assorted labels.
+// A Symbol->unsigned mapping of addresses used by indirect
+// references.
+class AddressPool {
+ struct AddressPoolEntry {
+ unsigned Number;
+ bool TLS;
+ AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
+ };
+ DenseMap<const MCSymbol *, AddressPoolEntry> Pool;
+
+ /// Record whether the AddressPool has been queried for an address index since
+ /// the last "resetUsedFlag" call. Used to implement type unit fallback - a
+ /// type that references addresses cannot be placed in a type unit when using
+ /// fission.
+ bool HasBeenUsed;
+
+public:
+ AddressPool() : HasBeenUsed(false) {}
+
+ /// \brief Returns the index into the address pool with the given
+ /// label/symbol.
+ unsigned getIndex(const MCSymbol *Sym, bool TLS = false);
+
+ void emit(AsmPrinter &Asm, const MCSection *AddrSection);
+
+ bool isEmpty() { return Pool.empty(); }
+
+ bool hasBeenUsed() const { return HasBeenUsed; }
+
+ void resetUsedFlag() { HasBeenUsed = false; }
+};
+}
+#endif
diff --git a/lib/CodeGen/AsmPrinter/Android.mk b/lib/CodeGen/AsmPrinter/Android.mk
index a725fba..f56eb6e 100644
--- a/lib/CodeGen/AsmPrinter/Android.mk
+++ b/lib/CodeGen/AsmPrinter/Android.mk
@@ -8,17 +8,21 @@ codegen_asmprinter_SRC_FILES := \
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
+ AddressPool.cpp \
AsmPrinter.cpp \
AsmPrinterDwarf.cpp \
AsmPrinterInlineAsm.cpp \
ARMException.cpp \
+ DbgValueHistoryCalculator.cpp \
DIE.cpp \
DIEHash.cpp \
DwarfAccelTable.cpp \
DwarfCFIException.cpp \
DwarfDebug.cpp \
DwarfException.cpp \
- DwarfUnit.cpp \
+ DwarfFile.cpp \
+ DwarfStringPool.cpp \
+ DwarfUnit.cpp \
ErlangGCPrinter.cpp \
OcamlGCPrinter.cpp \
Win64Exception.cpp \
@@ -38,17 +42,21 @@ ifneq (true,$(DISABLE_LLVM_DEVICE_BUILDS))
include $(CLEAR_VARS)
LOCAL_SRC_FILES := \
+ AddressPool.cpp \
AsmPrinter.cpp \
AsmPrinterDwarf.cpp \
AsmPrinterInlineAsm.cpp \
ARMException.cpp \
+ DbgValueHistoryCalculator.cpp \
DIE.cpp \
DIEHash.cpp \
DwarfAccelTable.cpp \
DwarfCFIException.cpp \
DwarfDebug.cpp \
DwarfException.cpp \
- DwarfUnit.cpp \
+ DwarfFile.cpp \
+ DwarfStringPool.cpp \
+ DwarfUnit.cpp \
ErlangGCPrinter.cpp \
OcamlGCPrinter.cpp \
Win64Exception.cpp \
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index c3afc8b..7de9c6d 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "asm-printer"
#include "llvm/CodeGen/AsmPrinter.h"
#include "DwarfDebug.h"
#include "DwarfException.h"
@@ -53,6 +52,8 @@
#include "llvm/Transforms/Utils/GlobalStatus.h"
using namespace llvm;
+#define DEBUG_TYPE "asm-printer"
+
static const char *const DWARFGroupName = "DWARF Emission";
static const char *const DbgTimerName = "Debug Info Emission";
static const char *const EHTimerName = "DWARF Exception Writer";
@@ -62,9 +63,9 @@ STATISTIC(EmittedInsts, "Number of machine instrs printed");
char AsmPrinter::ID = 0;
-typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
+typedef DenseMap<GCStrategy*, std::unique_ptr<GCMetadataPrinter>> gcp_map_type;
static gcp_map_type &getGCMap(void *&P) {
- if (P == 0)
+ if (!P)
P = new gcp_map_type();
return *(gcp_map_type*)P;
}
@@ -101,23 +102,21 @@ AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
TM(tm), MAI(tm.getMCAsmInfo()), MII(tm.getInstrInfo()),
OutContext(Streamer.getContext()),
OutStreamer(Streamer),
- LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
- DD = 0; MMI = 0; LI = 0; MF = 0;
- CurrentFnSym = CurrentFnSymForSize = 0;
- GCMetadataPrinters = 0;
+ LastMI(nullptr), LastFn(0), Counter(~0U), SetCounter(0) {
+ DD = nullptr; MMI = nullptr; LI = nullptr; MF = nullptr;
+ CurrentFnSym = CurrentFnSymForSize = nullptr;
+ GCMetadataPrinters = nullptr;
VerboseAsm = Streamer.isVerboseAsm();
}
AsmPrinter::~AsmPrinter() {
- assert(DD == 0 && Handlers.empty() && "Debug/EH info didn't get finalized");
+ assert(!DD && Handlers.empty() && "Debug/EH info didn't get finalized");
- if (GCMetadataPrinters != 0) {
+ if (GCMetadataPrinters) {
gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
- for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I)
- delete I->second;
delete &GCMap;
- GCMetadataPrinters = 0;
+ GCMetadataPrinters = nullptr;
}
delete &OutStreamer;
@@ -209,7 +208,7 @@ bool AsmPrinter::doInitialization(Module &M) {
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
- for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
+ for (auto &I : *MI)
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
MP->beginAssembly(*this);
@@ -233,7 +232,7 @@ bool AsmPrinter::doInitialization(Module &M) {
}
}
- DwarfException *DE = 0;
+ DwarfException *DE = nullptr;
switch (MAI->getExceptionHandlingType()) {
case ExceptionHandling::None:
break;
@@ -370,10 +369,9 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
// sections and expected to be contiguous (e.g. ObjC metadata).
unsigned AlignLog = getGVAlignmentLog2(GV, *DL);
- for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
- const HandlerInfo &OI = Handlers[I];
- NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled);
- OI.Handler->setSymbolSize(GVSym, Size);
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled);
+ HI.Handler->setSymbolSize(GVSym, Size);
}
// Handle common and BSS local symbols (.lcomm).
@@ -545,10 +543,9 @@ void AsmPrinter::EmitFunctionHeader() {
}
// Emit pre-function debug and/or EH information.
- for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
- const HandlerInfo &OI = Handlers[I];
- NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled);
- OI.Handler->beginFunction(MF);
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled);
+ HI.Handler->beginFunction(MF);
}
// Emit the prefix data.
@@ -746,69 +743,65 @@ void AsmPrinter::EmitFunctionBody() {
// Print out code for the function.
bool HasAnyRealCode = false;
- const MachineInstr *LastMI = 0;
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
- I != E; ++I) {
+ const MachineInstr *LastMI = nullptr;
+ for (auto &MBB : *MF) {
// Print a label for the basic block.
- EmitBasicBlockStart(I);
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- LastMI = II;
+ EmitBasicBlockStart(MBB);
+ for (auto &MI : MBB) {
+ LastMI = &MI;
// Print the assembly for the instruction.
- if (!II->isPosition() && !II->isImplicitDef() && !II->isKill() &&
- !II->isDebugValue()) {
+ if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
+ !MI.isDebugValue()) {
HasAnyRealCode = true;
++EmittedInsts;
}
if (ShouldPrintDebugScopes) {
- for (unsigned III = 0, EEE = Handlers.size(); III != EEE; ++III) {
- const HandlerInfo &OI = Handlers[III];
- NamedRegionTimer T(OI.TimerName, OI.TimerGroupName,
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerGroupName,
TimePassesIsEnabled);
- OI.Handler->beginInstruction(II);
+ HI.Handler->beginInstruction(&MI);
}
}
if (isVerbose())
- emitComments(*II, OutStreamer.GetCommentOS());
+ emitComments(MI, OutStreamer.GetCommentOS());
- switch (II->getOpcode()) {
+ switch (MI.getOpcode()) {
case TargetOpcode::CFI_INSTRUCTION:
- emitCFIInstruction(*II);
+ emitCFIInstruction(MI);
break;
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
- OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
+ OutStreamer.EmitLabel(MI.getOperand(0).getMCSymbol());
break;
case TargetOpcode::INLINEASM:
- EmitInlineAsm(II);
+ EmitInlineAsm(&MI);
break;
case TargetOpcode::DBG_VALUE:
if (isVerbose()) {
- if (!emitDebugValueComment(II, *this))
- EmitInstruction(II);
+ if (!emitDebugValueComment(&MI, *this))
+ EmitInstruction(&MI);
}
break;
case TargetOpcode::IMPLICIT_DEF:
- if (isVerbose()) emitImplicitDef(II);
+ if (isVerbose()) emitImplicitDef(&MI);
break;
case TargetOpcode::KILL:
- if (isVerbose()) emitKill(II, *this);
+ if (isVerbose()) emitKill(&MI, *this);
break;
default:
- EmitInstruction(II);
+ EmitInstruction(&MI);
break;
}
if (ShouldPrintDebugScopes) {
- for (unsigned III = 0, EEE = Handlers.size(); III != EEE; ++III) {
- const HandlerInfo &OI = Handlers[III];
- NamedRegionTimer T(OI.TimerName, OI.TimerGroupName,
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerGroupName,
TimePassesIsEnabled);
- OI.Handler->endInstruction();
+ HI.Handler->endInstruction();
}
}
}
@@ -835,11 +828,10 @@ void AsmPrinter::EmitFunctionBody() {
}
const Function *F = MF->getFunction();
- for (Function::const_iterator i = F->begin(), e = F->end(); i != e; ++i) {
- const BasicBlock *BB = i;
- if (!BB->hasAddressTaken())
+ for (const auto &BB : *F) {
+ if (!BB.hasAddressTaken())
continue;
- MCSymbol *Sym = GetBlockAddressSymbol(BB);
+ MCSymbol *Sym = GetBlockAddressSymbol(&BB);
if (Sym->isDefined())
continue;
OutStreamer.AddComment("Address of block that was removed by CodeGen");
@@ -866,10 +858,9 @@ void AsmPrinter::EmitFunctionBody() {
}
// Emit post-function debug and/or EH information.
- for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
- const HandlerInfo &OI = Handlers[I];
- NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled);
- OI.Handler->endFunction(MF);
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerGroupName, TimePassesIsEnabled);
+ HI.Handler->endFunction(MF);
}
MMI->EndFunction();
@@ -881,13 +872,11 @@ void AsmPrinter::EmitFunctionBody() {
bool AsmPrinter::doFinalization(Module &M) {
// Emit global variables.
- for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I)
- EmitGlobalVariable(I);
+ for (const auto &G : M.globals())
+ EmitGlobalVariable(&G);
// Emit visibility info for declarations
- for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
- const Function &F = *I;
+ for (const Function &F : M) {
if (!F.isDeclaration())
continue;
GlobalValue::VisibilityTypes V = F.getVisibility();
@@ -908,15 +897,14 @@ bool AsmPrinter::doFinalization(Module &M) {
OutStreamer.Flush();
// Finalize debug and EH information.
- for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
- const HandlerInfo &OI = Handlers[I];
- NamedRegionTimer T(OI.TimerName, OI.TimerGroupName,
+ for (const HandlerInfo &HI : Handlers) {
+ NamedRegionTimer T(HI.TimerName, HI.TimerGroupName,
TimePassesIsEnabled);
- OI.Handler->endModule();
- delete OI.Handler;
+ HI.Handler->endModule();
+ delete HI.Handler;
}
Handlers.clear();
- DD = 0;
+ DD = nullptr;
// If the target wants to know about weak references, print them all.
if (MAI->getWeakRefDirective()) {
@@ -926,36 +914,36 @@ bool AsmPrinter::doFinalization(Module &M) {
// happen with the MC stuff eventually.
// Print out module-level global variables here.
- for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
- I != E; ++I) {
- if (!I->hasExternalWeakLinkage()) continue;
- OutStreamer.EmitSymbolAttribute(getSymbol(I), MCSA_WeakReference);
+ for (const auto &G : M.globals()) {
+ if (!G.hasExternalWeakLinkage())
+ continue;
+ OutStreamer.EmitSymbolAttribute(getSymbol(&G), MCSA_WeakReference);
}
- for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
- if (!I->hasExternalWeakLinkage()) continue;
- OutStreamer.EmitSymbolAttribute(getSymbol(I), MCSA_WeakReference);
+ for (const auto &F : M) {
+ if (!F.hasExternalWeakLinkage())
+ continue;
+ OutStreamer.EmitSymbolAttribute(getSymbol(&F), MCSA_WeakReference);
}
}
if (MAI->hasSetDirective()) {
OutStreamer.AddBlankLine();
- for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
- I != E; ++I) {
- MCSymbol *Name = getSymbol(I);
+ for (const auto &Alias : M.aliases()) {
+ MCSymbol *Name = getSymbol(&Alias);
- const GlobalValue *GV = I->getAliasedGlobal();
+ const GlobalValue *GV = Alias.getAliasee();
assert(!GV->isDeclaration());
MCSymbol *Target = getSymbol(GV);
- if (I->hasExternalLinkage() || !MAI->getWeakRefDirective())
+ if (Alias.hasExternalLinkage() || !MAI->getWeakRefDirective())
OutStreamer.EmitSymbolAttribute(Name, MCSA_Global);
- else if (I->hasWeakLinkage() || I->hasLinkOnceLinkage())
+ else if (Alias.hasWeakLinkage() || Alias.hasLinkOnceLinkage())
OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference);
else
- assert(I->hasLocalLinkage() && "Invalid alias linkage");
+ assert(Alias.hasLocalLinkage() && "Invalid alias linkage");
- EmitVisibility(Name, I->getVisibility());
+ EmitVisibility(Name, Alias.getVisibility());
// Emit the directives as assignments aka .set:
OutStreamer.EmitAssignment(Name,
@@ -966,7 +954,7 @@ bool AsmPrinter::doFinalization(Module &M) {
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
- if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
+ if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(**--I))
MP->finishAssembly(*this);
// Emit llvm.ident metadata in an '.ident' directive.
@@ -983,8 +971,8 @@ bool AsmPrinter::doFinalization(Module &M) {
// after everything else has gone out.
EmitEndOfAsmFile(M);
- delete Mang; Mang = 0;
- MMI = 0;
+ delete Mang; Mang = nullptr;
+ MMI = nullptr;
OutStreamer.Finish();
OutStreamer.reset();
@@ -1100,7 +1088,7 @@ void AsmPrinter::EmitConstantPool() {
void AsmPrinter::EmitJumpTableInfo() {
const DataLayout *DL = MF->getTarget().getDataLayout();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
- if (MJTI == 0) return;
+ if (!MJTI) return;
if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return;
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
if (JT.empty()) return;
@@ -1185,7 +1173,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB,
unsigned UID) const {
assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block");
- const MCExpr *Value = 0;
+ const MCExpr *Value = nullptr;
switch (MJTI->getEntryKind()) {
case MachineJumpTableInfo::EK_Inline:
llvm_unreachable("Cannot emit EK_Inline jump table entry");
@@ -1308,6 +1296,15 @@ void AsmPrinter::EmitLLVMUsedList(const ConstantArray *InitList) {
}
}
+namespace {
+struct Structor {
+ Structor() : Priority(0), Func(nullptr), ComdatKey(nullptr) {}
+ int Priority;
+ llvm::Constant *Func;
+ llvm::GlobalValue *ComdatKey;
+};
+} // end namespace
+
/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
/// priority.
void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
@@ -1319,37 +1316,52 @@ void AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
const ConstantArray *InitList = dyn_cast<ConstantArray>(List);
if (!InitList) return; // Not an array!
StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType());
- if (!ETy || ETy->getNumElements() != 2) return; // Not an array of pairs!
+ // FIXME: Only allow the 3-field form in LLVM 4.0.
+ if (!ETy || ETy->getNumElements() < 2 || ETy->getNumElements() > 3)
+ return; // Not an array of two or three elements!
if (!isa<IntegerType>(ETy->getTypeAtIndex(0U)) ||
!isa<PointerType>(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr).
+ if (ETy->getNumElements() == 3 && !isa<PointerType>(ETy->getTypeAtIndex(2U)))
+ return; // Not (int, ptr, ptr).
// Gather the structors in a form that's convenient for sorting by priority.
- typedef std::pair<unsigned, Constant *> Structor;
SmallVector<Structor, 8> Structors;
- for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
- ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i));
+ for (Value *O : InitList->operands()) {
+ ConstantStruct *CS = dyn_cast<ConstantStruct>(O);
if (!CS) continue; // Malformed.
if (CS->getOperand(1)->isNullValue())
break; // Found a null terminator, skip the rest.
ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
if (!Priority) continue; // Malformed.
- Structors.push_back(std::make_pair(Priority->getLimitedValue(65535),
- CS->getOperand(1)));
+ Structors.push_back(Structor());
+ Structor &S = Structors.back();
+ S.Priority = Priority->getLimitedValue(65535);
+ S.Func = CS->getOperand(1);
+ if (ETy->getNumElements() == 3 && !CS->getOperand(2)->isNullValue())
+ S.ComdatKey = dyn_cast<GlobalValue>(CS->getOperand(2)->stripPointerCasts());
}
// Emit the function pointers in the target-specific order
const DataLayout *DL = TM.getDataLayout();
unsigned Align = Log2_32(DL->getPointerPrefAlignment());
- std::stable_sort(Structors.begin(), Structors.end(), less_first());
- for (unsigned i = 0, e = Structors.size(); i != e; ++i) {
+ std::stable_sort(Structors.begin(), Structors.end(),
+ [](const Structor &L,
+ const Structor &R) { return L.Priority < R.Priority; });
+ for (Structor &S : Structors) {
+ const TargetLoweringObjectFile &Obj = getObjFileLowering();
+ const MCSymbol *KeySym = nullptr;
+ const MCSection *KeySec = nullptr;
+ if (S.ComdatKey) {
+ KeySym = getSymbol(S.ComdatKey);
+ KeySec = getObjFileLowering().SectionForGlobal(S.ComdatKey, *Mang, TM);
+ }
const MCSection *OutputSection =
- (isCtor ?
- getObjFileLowering().getStaticCtorSection(Structors[i].first) :
- getObjFileLowering().getStaticDtorSection(Structors[i].first));
+ (isCtor ? Obj.getStaticCtorSection(S.Priority, KeySym, KeySec)
+ : Obj.getStaticDtorSection(S.Priority, KeySym, KeySec));
OutStreamer.SwitchSection(OutputSection);
if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection())
EmitAlignment(Align);
- EmitXXStructor(Structors[i].second);
+ EmitXXStructor(S.Func);
}
}
@@ -1470,7 +1482,7 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
// an explicit alignment requested, it will override the alignment request
// if required for correctness.
//
-void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
+void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalObject *GV) const {
if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getDataLayout(), NumBits);
if (NumBits == 0) return; // 1-byte aligned: no need to emit alignment.
@@ -1503,7 +1515,7 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx);
const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
- if (CE == 0) {
+ if (!CE) {
llvm_unreachable("Unknown constant value to lower!");
}
@@ -1528,7 +1540,7 @@ static const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
raw_string_ostream OS(S);
OS << "Unsupported expression in static initializer: ";
CE->printAsOperand(OS, /*PrintType=*/false,
- !AP.MF ? 0 : AP.MF->getFunction()->getParent());
+ !AP.MF ? nullptr : AP.MF->getFunction()->getParent());
report_fatal_error(OS.str());
}
case Instruction::GetElementPtr: {
@@ -2055,7 +2067,7 @@ MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const {
/// PrintParentLoopComment - Print comments about parent loops of this one.
static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,
unsigned FunctionNumber) {
- if (Loop == 0) return;
+ if (!Loop) return;
PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber);
OS.indent(Loop->getLoopDepth()*2)
<< "Parent Loop BB" << FunctionNumber << "_"
@@ -2069,12 +2081,12 @@ static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,
static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
unsigned FunctionNumber) {
// Add child loop information
- for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){
- OS.indent((*CL)->getLoopDepth()*2)
+ for (const MachineLoop *CL : *Loop) {
+ OS.indent(CL->getLoopDepth()*2)
<< "Child Loop BB" << FunctionNumber << "_"
- << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth()
+ << CL->getHeader()->getNumber() << " Depth " << CL->getLoopDepth()
<< '\n';
- PrintChildLoopComment(OS, *CL, FunctionNumber);
+ PrintChildLoopComment(OS, CL, FunctionNumber);
}
}
@@ -2084,7 +2096,7 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
const AsmPrinter &AP) {
// Add loop depth information
const MachineLoop *Loop = LI->getLoopFor(&MBB);
- if (Loop == 0) return;
+ if (!Loop) return;
MachineBasicBlock *Header = Loop->getHeader();
assert(Header && "No header for loop");
@@ -2120,42 +2132,41 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
-void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
+void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
// Emit an alignment directive for this block, if needed.
- if (unsigned Align = MBB->getAlignment())
+ if (unsigned Align = MBB.getAlignment())
EmitAlignment(Align);
// If the block has its address taken, emit any labels that were used to
// reference the block. It is possible that there is more than one label
// here, because multiple LLVM BB's may have been RAUW'd to this block after
// the references were generated.
- if (MBB->hasAddressTaken()) {
- const BasicBlock *BB = MBB->getBasicBlock();
+ if (MBB.hasAddressTaken()) {
+ const BasicBlock *BB = MBB.getBasicBlock();
if (isVerbose())
OutStreamer.AddComment("Block address taken");
- std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);
-
- for (unsigned i = 0, e = Syms.size(); i != e; ++i)
- OutStreamer.EmitLabel(Syms[i]);
+ std::vector<MCSymbol*> Symbols = MMI->getAddrLabelSymbolToEmit(BB);
+ for (auto *Sym : Symbols)
+ OutStreamer.EmitLabel(Sym);
}
// Print some verbose block comments.
if (isVerbose()) {
- if (const BasicBlock *BB = MBB->getBasicBlock())
+ if (const BasicBlock *BB = MBB.getBasicBlock())
if (BB->hasName())
OutStreamer.AddComment("%" + BB->getName());
- emitBasicBlockLoopComments(*MBB, LI, *this);
+ emitBasicBlockLoopComments(MBB, LI, *this);
}
// Print the main label for the block.
- if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) {
+ if (MBB.pred_empty() || isBlockOnlyReachableByFallthrough(&MBB)) {
if (isVerbose()) {
// NOTE: Want this comment at start of line, don't emit with AddComment.
- OutStreamer.emitRawComment(" BB#" + Twine(MBB->getNumber()) + ":", false);
+ OutStreamer.emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false);
}
} else {
- OutStreamer.EmitLabel(MBB->getSymbol());
+ OutStreamer.EmitLabel(MBB.getSymbol());
}
}
@@ -2191,14 +2202,11 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
return false;
// If there isn't exactly one predecessor, it can't be a fall through.
- MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
- ++PI2;
- if (PI2 != MBB->pred_end())
+ if (MBB->pred_size() > 1)
return false;
// The predecessor has to be immediately before this block.
- MachineBasicBlock *Pred = *PI;
-
+ MachineBasicBlock *Pred = *MBB->pred_begin();
if (!Pred->isLayoutSuccessor(MBB))
return false;
@@ -2207,10 +2215,7 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
return true;
// Check the terminators in the previous blocks
- for (MachineBasicBlock::iterator II = Pred->getFirstTerminator(),
- IE = Pred->end(); II != IE; ++II) {
- MachineInstr &MI = *II;
-
+ for (const auto &MI : Pred->terminators()) {
// If it is not a simple branch, we are in a table somewhere.
if (!MI.isBranch() || MI.isIndirectBranch())
return false;
@@ -2231,25 +2236,25 @@ isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
-GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
- if (!S->usesMetadata())
- return 0;
+GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy &S) {
+ if (!S.usesMetadata())
+ return nullptr;
gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
- gcp_map_type::iterator GCPI = GCMap.find(S);
+ gcp_map_type::iterator GCPI = GCMap.find(&S);
if (GCPI != GCMap.end())
- return GCPI->second;
+ return GCPI->second.get();
- const char *Name = S->getName().c_str();
+ const char *Name = S.getName().c_str();
for (GCMetadataPrinterRegistry::iterator
I = GCMetadataPrinterRegistry::begin(),
E = GCMetadataPrinterRegistry::end(); I != E; ++I)
if (strcmp(Name, I->getName()) == 0) {
- GCMetadataPrinter *GMP = I->instantiate();
- GMP->S = S;
- GCMap.insert(std::make_pair(S, GMP));
- return GMP;
+ std::unique_ptr<GCMetadataPrinter> GMP = I->instantiate();
+ GMP->S = &S;
+ auto IterBool = GCMap.insert(std::make_pair(&S, std::move(GMP)));
+ return IterBool.first->second.get();
}
report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index b696069..02cd12b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "asm-printer"
#include "ByteStreamer.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/ADT/SmallBitVector.h"
@@ -30,6 +29,8 @@
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
+#define DEBUG_TYPE "asm-printer"
+
//===----------------------------------------------------------------------===//
// Dwarf Emission Helper Routines
//===----------------------------------------------------------------------===//
@@ -216,30 +217,48 @@ static void emitDwarfRegOpIndirect(ByteStreamer &Streamer, int Reg, int Offset,
/// Emit a dwarf register operation for describing
/// - a small value occupying only part of a register or
/// - a small register representing only part of a value.
-static void emitDwarfOpPiece(ByteStreamer &Streamer, unsigned Size,
- unsigned Offset) {
- assert(Size > 0);
- if (Offset > 0) {
+static void emitDwarfOpPiece(ByteStreamer &Streamer, unsigned SizeInBits,
+ unsigned OffsetInBits) {
+ assert(SizeInBits > 0 && "zero-sized piece");
+ unsigned SizeOfByte = 8;
+ if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
Streamer.EmitInt8(dwarf::DW_OP_bit_piece, "DW_OP_bit_piece");
- Streamer.EmitULEB128(Size, Twine(Size));
- Streamer.EmitULEB128(Offset, Twine(Offset));
+ Streamer.EmitULEB128(SizeInBits, Twine(SizeInBits));
+ Streamer.EmitULEB128(OffsetInBits, Twine(OffsetInBits));
} else {
Streamer.EmitInt8(dwarf::DW_OP_piece, "DW_OP_piece");
- unsigned ByteSize = Size / 8; // Assuming 8 bits per byte.
+ unsigned ByteSize = SizeInBits / SizeOfByte;
Streamer.EmitULEB128(ByteSize, Twine(ByteSize));
}
}
-/// Some targets do not provide a DWARF register number for every
-/// register. This function attempts to emit a dwarf register by
-/// emitting a piece of a super-register or by piecing together
-/// multiple subregisters that alias the register.
-static void EmitDwarfRegOpPiece(ByteStreamer &Streamer, const AsmPrinter &AP,
- const MachineLocation &MLoc) {
- assert(!MLoc.isIndirect());
- const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
+/// Emit a shift-right dwarf expression.
+static void emitDwarfOpShr(ByteStreamer &Streamer,
+ unsigned ShiftBy) {
+ Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu");
+ Streamer.EmitULEB128(ShiftBy);
+ Streamer.EmitInt8(dwarf::DW_OP_shr, "DW_OP_shr");
+}
+
+// Some targets do not provide a DWARF register number for every
+// register. This function attempts to emit a DWARF register by
+// emitting a piece of a super-register or by piecing together
+// multiple subregisters that alias the register.
+void AsmPrinter::EmitDwarfRegOpPiece(ByteStreamer &Streamer,
+ const MachineLocation &MLoc,
+ unsigned PieceSizeInBits,
+ unsigned PieceOffsetInBits) const {
+ assert(MLoc.isReg() && "MLoc must be a register");
+ const TargetRegisterInfo *TRI = TM.getRegisterInfo();
int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
+ // If this is a valid register number, emit it.
+ if (Reg >= 0) {
+ emitDwarfRegOp(Streamer, Reg);
+ emitDwarfOpPiece(Streamer, PieceSizeInBits, PieceOffsetInBits);
+ return;
+ }
+
// Walk up the super-register chain until we find a valid number.
// For example, EAX on x86_64 is a 32-bit piece of RAX with offset 0.
for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid(); ++SR) {
@@ -248,9 +267,19 @@ static void EmitDwarfRegOpPiece(ByteStreamer &Streamer, const AsmPrinter &AP,
unsigned Idx = TRI->getSubRegIndex(*SR, MLoc.getReg());
unsigned Size = TRI->getSubRegIdxSize(Idx);
unsigned Offset = TRI->getSubRegIdxOffset(Idx);
- AP.OutStreamer.AddComment("super-register");
+ OutStreamer.AddComment("super-register");
emitDwarfRegOp(Streamer, Reg);
- emitDwarfOpPiece(Streamer, Size, Offset);
+ if (PieceOffsetInBits == Offset) {
+ emitDwarfOpPiece(Streamer, Size, Offset);
+ } else {
+ // If this is part of a variable in a sub-register at a
+ // non-zero offset, we need to manually shift the value into
+ // place, since the DW_OP_piece describes the part of the
+ // variable, not the position of the subregister.
+ emitDwarfOpPiece(Streamer, Size, PieceOffsetInBits);
+ if (Offset)
+ emitDwarfOpShr(Streamer, Offset);
+ }
return;
}
}
@@ -260,7 +289,7 @@ static void EmitDwarfRegOpPiece(ByteStreamer &Streamer, const AsmPrinter &AP,
//
// Keep track of the current position so we can emit the more
// efficient DW_OP_piece.
- unsigned CurPos = 0;
+ unsigned CurPos = PieceOffsetInBits;
// The size of the register in bits, assuming 8 bits per byte.
unsigned RegSize = TRI->getMinimalPhysRegClass(MLoc.getReg())->getSize() * 8;
// Keep track of the bits in the register we already emitted, so we
@@ -281,7 +310,7 @@ static void EmitDwarfRegOpPiece(ByteStreamer &Streamer, const AsmPrinter &AP,
// If this sub-register has a DWARF number and we haven't covered
// its range, emit a DWARF piece for it.
if (Reg >= 0 && Intersection.any()) {
- AP.OutStreamer.AddComment("sub-register");
+ OutStreamer.AddComment("sub-register");
emitDwarfRegOp(Streamer, Reg);
emitDwarfOpPiece(Streamer, Size, Offset == CurPos ? 0 : Offset);
CurPos = Offset + Size;
@@ -291,7 +320,7 @@ static void EmitDwarfRegOpPiece(ByteStreamer &Streamer, const AsmPrinter &AP,
}
}
- if (CurPos == 0) {
+ if (CurPos == PieceOffsetInBits) {
// FIXME: We have no reasonable way of handling errors in here.
Streamer.EmitInt8(dwarf::DW_OP_nop,
"nop (could not find a dwarf register number)");
@@ -317,8 +346,7 @@ void AsmPrinter::EmitDwarfRegOp(ByteStreamer &Streamer,
}
// Attempt to find a valid super- or sub-register.
- if (!Indirect && !MLoc.isIndirect())
- return EmitDwarfRegOpPiece(Streamer, *this, MLoc);
+ return EmitDwarfRegOpPiece(Streamer, MLoc);
}
if (MLoc.isIndirect())
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index 567b6e3..46ee0c8 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -11,11 +11,11 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "asm-printer"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
@@ -36,6 +36,8 @@
#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
+#define DEBUG_TYPE "asm-printer"
+
namespace {
struct SrcMgrDiagInfo {
const MDNode *LocInfo;
@@ -88,7 +90,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
if (!MCAI->useIntegratedAssembler() &&
!OutStreamer.isIntegratedAssemblerRequired()) {
OutStreamer.EmitRawText(Str);
- emitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), 0);
+ emitInlineAsmEnd(TM.getSubtarget<MCSubtargetInfo>(), nullptr);
return;
}
@@ -98,7 +100,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
// If the current LLVMContext has an inline asm handler, set it in SourceMgr.
LLVMContext &LLVMCtx = MMI->getModule()->getContext();
bool HasDiagHandler = false;
- if (LLVMCtx.getInlineAsmDiagnosticHandler() != 0) {
+ if (LLVMCtx.getInlineAsmDiagnosticHandler() != nullptr) {
// If the source manager has an issue, we arrange for srcMgrDiagHandler
// to be invoked, getting DiagInfo passed into it.
DiagInfo.LocInfo = LocMDNode;
@@ -134,8 +136,11 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MDNode *LocMDNode,
// emitInlineAsmEnd().
MCSubtargetInfo STIOrig = *STI;
+ MCTargetOptions MCOptions;
+ if (MF)
+ MCOptions = MF->getTarget().Options.MCOptions;
std::unique_ptr<MCTargetAsmParser> TAP(
- TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
+ TM.getTarget().createMCAsmParser(*STI, *Parser, *MII, MCOptions));
if (!TAP)
report_fatal_error("Inline asm not supported by this streamer because"
" we don't have an asm parser for this target\n");
@@ -229,10 +234,10 @@ static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
if (InlineAsm::isMemKind(OpFlags)) {
Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
- /*Modifier*/ 0, OS);
+ /*Modifier*/ nullptr, OS);
} else {
Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
- /*Modifier*/ 0, OS);
+ /*Modifier*/ nullptr, OS);
}
}
if (Error) {
@@ -324,7 +329,7 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
++LastEmitted;
const char *StrStart = LastEmitted;
const char *StrEnd = strchr(StrStart, '}');
- if (StrEnd == 0)
+ if (!StrEnd)
report_fatal_error("Unterminated ${:foo} operand in inline asm"
" string: '" + Twine(AsmStr) + "'");
@@ -399,11 +404,11 @@ static void EmitGCCInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
else {
if (InlineAsm::isMemKind(OpFlags)) {
Error = AP->PrintAsmMemoryOperand(MI, OpNo, InlineAsmVariant,
- Modifier[0] ? Modifier : 0,
+ Modifier[0] ? Modifier : nullptr,
OS);
} else {
Error = AP->PrintAsmOperand(MI, OpNo, InlineAsmVariant,
- Modifier[0] ? Modifier : 0, OS);
+ Modifier[0] ? Modifier : nullptr, OS);
}
}
}
@@ -452,7 +457,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
// Get the !srcloc metadata node if we have it, and decode the loc cookie from
// it.
unsigned LocCookie = 0;
- const MDNode *LocMD = 0;
+ const MDNode *LocMD = nullptr;
for (unsigned i = MI->getNumOperands(); i != 0; --i) {
if (MI->getOperand(i-1).isMetadata() &&
(LocMD = MI->getOperand(i-1).getMetadata()) &&
diff --git a/lib/CodeGen/AsmPrinter/CMakeLists.txt b/lib/CodeGen/AsmPrinter/CMakeLists.txt
index b3eddac..b4ef185 100644
--- a/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -1,14 +1,18 @@
add_llvm_library(LLVMAsmPrinter
+ AddressPool.cpp
ARMException.cpp
AsmPrinter.cpp
AsmPrinterDwarf.cpp
AsmPrinterInlineAsm.cpp
+ DbgValueHistoryCalculator.cpp
DIE.cpp
DIEHash.cpp
DwarfAccelTable.cpp
DwarfCFIException.cpp
DwarfDebug.cpp
DwarfException.cpp
+ DwarfFile.cpp
+ DwarfStringPool.cpp
DwarfUnit.cpp
ErlangGCPrinter.cpp
OcamlGCPrinter.cpp
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 26e8f2d..c3dcd9c 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -104,15 +104,6 @@ void DIEAbbrev::print(raw_ostream &O) {
void DIEAbbrev::dump() { print(dbgs()); }
#endif
-//===----------------------------------------------------------------------===//
-// DIE Implementation
-//===----------------------------------------------------------------------===//
-
-DIE::~DIE() {
- for (unsigned i = 0, N = Children.size(); i < N; ++i)
- delete Children[i];
-}
-
/// Climb up the parent chain to get the unit DIE to which this DIE
/// belongs.
const DIE *DIE::getUnit() const {
@@ -131,7 +122,7 @@ const DIE *DIE::getUnitOrNull() const {
return p;
p = p->getParent();
}
- return NULL;
+ return nullptr;
}
DIEValue *DIE::findAttribute(dwarf::Attribute Attribute) const {
@@ -143,7 +134,7 @@ DIEValue *DIE::findAttribute(dwarf::Attribute Attribute) const {
for (size_t i = 0; i < Values.size(); ++i)
if (Abbrevs.getData()[i].getAttribute() == Attribute)
return Values[i];
- return NULL;
+ return nullptr;
}
#ifndef NDEBUG
@@ -385,12 +376,12 @@ void DIEEntry::EmitValue(AsmPrinter *AP, dwarf::Form Form) const {
if (Form == dwarf::DW_FORM_ref_addr) {
const DwarfDebug *DD = AP->getDwarfDebug();
- unsigned Addr = Entry->getOffset();
+ unsigned Addr = Entry.getOffset();
assert(!DD->useSplitDwarf() && "TODO: dwo files can't have relocations.");
// For DW_FORM_ref_addr, output the offset from beginning of debug info
// section. Entry->getOffset() returns the offset from start of the
// compile unit.
- DwarfCompileUnit *CU = DD->lookupUnit(Entry->getUnit());
+ DwarfCompileUnit *CU = DD->lookupUnit(Entry.getUnit());
assert(CU && "CUDie should belong to a CU.");
Addr += CU->getDebugInfoOffset();
if (AP->MAI->doesDwarfUseRelocationsAcrossSections())
@@ -401,7 +392,7 @@ void DIEEntry::EmitValue(AsmPrinter *AP, dwarf::Form Form) const {
CU->getSectionSym(),
DIEEntry::getRefAddrSize(AP));
} else
- AP->EmitInt32(Entry->getOffset());
+ AP->EmitInt32(Entry.getOffset());
}
unsigned DIEEntry::getRefAddrSize(AsmPrinter *AP) {
@@ -418,7 +409,7 @@ unsigned DIEEntry::getRefAddrSize(AsmPrinter *AP) {
#ifndef NDEBUG
void DIEEntry::print(raw_ostream &O) const {
- O << format("Die: 0x%lx", (long)(intptr_t)Entry);
+ O << format("Die: 0x%lx", (long)(intptr_t)&Entry);
}
#endif
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index 7fefd4f..ef05f17 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -124,7 +124,13 @@ protected:
/// Children DIEs.
///
- std::vector<DIE *> Children;
+ // This can't be a vector<DIE> because pointer validity is requirent for the
+ // Parent pointer and DIEEntry.
+ // It can't be a list<DIE> because some clients need pointer validity before
+ // the object has been added to any child list
+ // (eg: DwarfUnit::constructVariableDIE). These aren't insurmountable, but may
+ // be more convoluted than beneficial.
+ std::vector<std::unique_ptr<DIE>> Children;
DIE *Parent;
@@ -132,11 +138,15 @@ protected:
///
SmallVector<DIEValue *, 12> Values;
+protected:
+ DIE()
+ : Offset(0), Size(0), Abbrev((dwarf::Tag)0, dwarf::DW_CHILDREN_no),
+ Parent(nullptr) {}
+
public:
- explicit DIE(unsigned Tag)
+ explicit DIE(dwarf::Tag Tag)
: Offset(0), Size(0), Abbrev((dwarf::Tag)Tag, dwarf::DW_CHILDREN_no),
- Parent(0) {}
- ~DIE();
+ Parent(nullptr) {}
// Accessors.
DIEAbbrev &getAbbrev() { return Abbrev; }
@@ -145,7 +155,9 @@ public:
dwarf::Tag getTag() const { return Abbrev.getTag(); }
unsigned getOffset() const { return Offset; }
unsigned getSize() const { return Size; }
- const std::vector<DIE *> &getChildren() const { return Children; }
+ const std::vector<std::unique_ptr<DIE>> &getChildren() const {
+ return Children;
+ }
const SmallVectorImpl<DIEValue *> &getValues() const { return Values; }
DIE *getParent() const { return Parent; }
/// Climb up the parent chain to get the compile or type unit DIE this DIE
@@ -166,11 +178,11 @@ public:
/// addChild - Add a child to the DIE.
///
- void addChild(DIE *Child) {
+ void addChild(std::unique_ptr<DIE> Child) {
assert(!Child->getParent());
Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
- Children.push_back(Child);
Child->Parent = this;
+ Children.push_back(std::move(Child));
}
/// findAttribute - Find a value in the DIE with the attribute given,
@@ -399,14 +411,13 @@ public:
/// this class can also be used as a proxy for a debug information entry not
/// yet defined (ie. types.)
class DIEEntry : public DIEValue {
- DIE *const Entry;
+ DIE &Entry;
public:
- explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {
- assert(E && "Cannot construct a DIEEntry with a null DIE");
+ explicit DIEEntry(DIE &E) : DIEValue(isEntry), Entry(E) {
}
- DIE *getEntry() const { return Entry; }
+ DIE &getEntry() const { return Entry; }
/// EmitValue - Emit debug information entry offset.
///
@@ -464,7 +475,7 @@ public:
class DIELoc : public DIEValue, public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
public:
- DIELoc() : DIEValue(isLoc), DIE(0), Size(0) {}
+ DIELoc() : DIEValue(isLoc), Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
@@ -507,7 +518,7 @@ public:
class DIEBlock : public DIEValue, public DIE {
mutable unsigned Size; // Size in bytes excluding size header.
public:
- DIEBlock() : DIEValue(isBlock), DIE(0), Size(0) {}
+ DIEBlock() : DIEValue(isBlock), Size(0) {}
/// ComputeSize - Calculate the size of the location expression.
///
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.cpp b/lib/CodeGen/AsmPrinter/DIEHash.cpp
index 74beec1..c2fad59 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.cpp
+++ b/lib/CodeGen/AsmPrinter/DIEHash.cpp
@@ -11,8 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dwarfdebug"
-
#include "ByteStreamer.h"
#include "DIEHash.h"
#include "DIE.h"
@@ -28,6 +26,8 @@
using namespace llvm;
+#define DEBUG_TYPE "dwarfdebug"
+
/// \brief Grabs the string in whichever attribute is passed in and returns
/// a reference to it.
static StringRef getDIEStringAttr(const DIE &Die, uint16_t Attr) {
@@ -309,7 +309,7 @@ void DIEHash::hashAttribute(AttrEntry Attr, dwarf::Tag Tag) {
// ... An attribute that refers to another type entry T is processed as
// follows:
case DIEValue::isEntry:
- hashDIEEntry(Attribute, Tag, *cast<DIEEntry>(Value)->getEntry());
+ hashDIEEntry(Attribute, Tag, cast<DIEEntry>(Value)->getEntry());
break;
case DIEValue::isInteger: {
addULEB128('A');
@@ -463,20 +463,18 @@ void DIEHash::computeHash(const DIE &Die) {
addAttributes(Die);
// Then hash each of the children of the DIE.
- for (std::vector<DIE *>::const_iterator I = Die.getChildren().begin(),
- E = Die.getChildren().end();
- I != E; ++I) {
+ for (auto &C : Die.getChildren()) {
// 7.27 Step 7
// If C is a nested type entry or a member function entry, ...
- if (isType((*I)->getTag()) || (*I)->getTag() == dwarf::DW_TAG_subprogram) {
- StringRef Name = getDIEStringAttr(**I, dwarf::DW_AT_name);
+ if (isType(C->getTag()) || C->getTag() == dwarf::DW_TAG_subprogram) {
+ StringRef Name = getDIEStringAttr(*C, dwarf::DW_AT_name);
// ... and has a DW_AT_name attribute
if (!Name.empty()) {
- hashNestedType(**I, Name);
+ hashNestedType(*C, Name);
continue;
}
}
- computeHash(**I);
+ computeHash(*C);
}
// Following the last (or if there are no children), append a zero byte.
diff --git a/lib/CodeGen/AsmPrinter/DIEHash.h b/lib/CodeGen/AsmPrinter/DIEHash.h
index 48f1601..175d660 100644
--- a/lib/CodeGen/AsmPrinter/DIEHash.h
+++ b/lib/CodeGen/AsmPrinter/DIEHash.h
@@ -89,7 +89,7 @@ class DIEHash {
};
public:
- DIEHash(AsmPrinter *A = NULL) : AP(A) {}
+ DIEHash(AsmPrinter *A = nullptr) : AP(A) {}
/// \brief Computes the ODR signature.
uint64_t computeDIEODRSignature(const DIE &Die);
diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
new file mode 100644
index 0000000..6103254
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
@@ -0,0 +1,175 @@
+//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DbgValueHistoryCalculator.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include <algorithm>
+#include <map>
+
+#define DEBUG_TYPE "dwarfdebug"
+
+namespace llvm {
+
+// \brief If @MI is a DBG_VALUE with debug value described by a
+// defined register, returns the number of this register.
+// In the other case, returns 0.
+static unsigned isDescribedByReg(const MachineInstr &MI) {
+ assert(MI.isDebugValue());
+ assert(MI.getNumOperands() == 3);
+ // If location of variable is described using a register (directly or
+ // indirecltly), this register is always a first operand.
+ return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
+}
+
+void DbgValueHistoryMap::startInstrRange(const MDNode *Var,
+ const MachineInstr &MI) {
+ // Instruction range should start with a DBG_VALUE instruction for the
+ // variable.
+ assert(MI.isDebugValue() && MI.getDebugVariable() == Var);
+ auto &Ranges = VarInstrRanges[Var];
+ if (!Ranges.empty() && Ranges.back().second == nullptr &&
+ Ranges.back().first->isIdenticalTo(&MI)) {
+ DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
+ << "\t" << Ranges.back().first << "\t" << MI << "\n");
+ return;
+ }
+ Ranges.push_back(std::make_pair(&MI, nullptr));
+}
+
+void DbgValueHistoryMap::endInstrRange(const MDNode *Var,
+ const MachineInstr &MI) {
+ auto &Ranges = VarInstrRanges[Var];
+ // Verify that the current instruction range is not yet closed.
+ assert(!Ranges.empty() && Ranges.back().second == nullptr);
+ // For now, instruction ranges are not allowed to cross basic block
+ // boundaries.
+ assert(Ranges.back().first->getParent() == MI.getParent());
+ Ranges.back().second = &MI;
+}
+
+unsigned DbgValueHistoryMap::getRegisterForVar(const MDNode *Var) const {
+ const auto &I = VarInstrRanges.find(Var);
+ if (I == VarInstrRanges.end())
+ return 0;
+ const auto &Ranges = I->second;
+ if (Ranges.empty() || Ranges.back().second != nullptr)
+ return 0;
+ return isDescribedByReg(*Ranges.back().first);
+}
+
+namespace {
+// Maps physreg numbers to the variables they describe.
+typedef std::map<unsigned, SmallVector<const MDNode *, 1>> RegDescribedVarsMap;
+}
+
+// \brief Claim that @Var is not described by @RegNo anymore.
+static void dropRegDescribedVar(RegDescribedVarsMap &RegVars,
+ unsigned RegNo, const MDNode *Var) {
+ const auto &I = RegVars.find(RegNo);
+ assert(RegNo != 0U && I != RegVars.end());
+ auto &VarSet = I->second;
+ const auto &VarPos = std::find(VarSet.begin(), VarSet.end(), Var);
+ assert(VarPos != VarSet.end());
+ VarSet.erase(VarPos);
+ // Don't keep empty sets in a map to keep it as small as possible.
+ if (VarSet.empty())
+ RegVars.erase(I);
+}
+
+// \brief Claim that @Var is now described by @RegNo.
+static void addRegDescribedVar(RegDescribedVarsMap &RegVars,
+ unsigned RegNo, const MDNode *Var) {
+ assert(RegNo != 0U);
+ auto &VarSet = RegVars[RegNo];
+ assert(std::find(VarSet.begin(), VarSet.end(), Var) == VarSet.end());
+ VarSet.push_back(Var);
+}
+
+// \brief Terminate the location range for variables described by register
+// @RegNo by inserting @ClobberingInstr to their history.
+static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo,
+ DbgValueHistoryMap &HistMap,
+ const MachineInstr &ClobberingInstr) {
+ const auto &I = RegVars.find(RegNo);
+ if (I == RegVars.end())
+ return;
+ // Iterate over all variables described by this register and add this
+ // instruction to their history, clobbering it.
+ for (const auto &Var : I->second)
+ HistMap.endInstrRange(Var, ClobberingInstr);
+ RegVars.erase(I);
+}
+
+// \brief Terminate location ranges for all variables, described by registers
+// clobbered by @MI.
+static void clobberRegisterUses(RegDescribedVarsMap &RegVars,
+ const MachineInstr &MI,
+ const TargetRegisterInfo *TRI,
+ DbgValueHistoryMap &HistMap) {
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!MO.isReg() || !MO.isDef() || !MO.getReg())
+ continue;
+ for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
+ ++AI) {
+ unsigned RegNo = *AI;
+ clobberRegisterUses(RegVars, RegNo, HistMap, MI);
+ }
+ }
+}
+
+// \brief Terminate the location range for all register-described variables
+// by inserting @ClobberingInstr to their history.
+static void clobberAllRegistersUses(RegDescribedVarsMap &RegVars,
+ DbgValueHistoryMap &HistMap,
+ const MachineInstr &ClobberingInstr) {
+ for (const auto &I : RegVars)
+ for (const auto &Var : I.second)
+ HistMap.endInstrRange(Var, ClobberingInstr);
+ RegVars.clear();
+}
+
+void calculateDbgValueHistory(const MachineFunction *MF,
+ const TargetRegisterInfo *TRI,
+ DbgValueHistoryMap &Result) {
+ RegDescribedVarsMap RegVars;
+
+ for (const auto &MBB : *MF) {
+ for (const auto &MI : MBB) {
+ if (!MI.isDebugValue()) {
+ // Not a DBG_VALUE instruction. It may clobber registers which describe
+ // some variables.
+ clobberRegisterUses(RegVars, MI, TRI, Result);
+ continue;
+ }
+
+ assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!");
+ const MDNode *Var = MI.getDebugVariable();
+
+ if (unsigned PrevReg = Result.getRegisterForVar(Var))
+ dropRegDescribedVar(RegVars, PrevReg, Var);
+
+ Result.startInstrRange(Var, MI);
+
+ if (unsigned NewReg = isDescribedByReg(MI))
+ addRegDescribedVar(RegVars, NewReg, Var);
+ }
+
+ // Make sure locations for register-described variables are valid only
+ // until the end of the basic block (unless it's the last basic block, in
+ // which case let their liveness run off to the end of the function).
+ if (!MBB.empty() && &MBB != &MF->back())
+ clobberAllRegistersUses(RegVars, Result, MBB.back());
+ }
+}
+
+}
diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
new file mode 100644
index 0000000..b9177f0
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
@@ -0,0 +1,54 @@
+//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ----*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H_
+#define CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H_
+
+#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/SmallVector.h"
+
+namespace llvm {
+
+class MachineFunction;
+class MachineInstr;
+class MDNode;
+class TargetRegisterInfo;
+
+// For each user variable, keep a list of instruction ranges where this variable
+// is accessible. The variables are listed in order of appearance.
+class DbgValueHistoryMap {
+ // Each instruction range starts with a DBG_VALUE instruction, specifying the
+ // location of a variable, which is assumed to be valid until the end of the
+ // range. If end is not specified, location is valid until the start
+ // instruction of the next instruction range, or until the end of the
+ // function.
+ typedef std::pair<const MachineInstr *, const MachineInstr *> InstrRange;
+ typedef SmallVector<InstrRange, 4> InstrRanges;
+ typedef MapVector<const MDNode *, InstrRanges> InstrRangesMap;
+ InstrRangesMap VarInstrRanges;
+
+public:
+ void startInstrRange(const MDNode *Var, const MachineInstr &MI);
+ void endInstrRange(const MDNode *Var, const MachineInstr &MI);
+ // Returns register currently describing @Var. If @Var is currently
+ // unaccessible or is not described by a register, returns 0.
+ unsigned getRegisterForVar(const MDNode *Var) const;
+
+ bool empty() const { return VarInstrRanges.empty(); }
+ void clear() { VarInstrRanges.clear(); }
+ InstrRangesMap::const_iterator begin() const { return VarInstrRanges.begin(); }
+ InstrRangesMap::const_iterator end() const { return VarInstrRanges.end(); }
+};
+
+void calculateDbgValueHistory(const MachineFunction *MF,
+ const TargetRegisterInfo *TRI,
+ DbgValueHistoryMap &Result);
+}
+
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 470453f..3beb799 100644
--- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -23,75 +23,82 @@ class DebugLocEntry {
const MCSymbol *Begin;
const MCSymbol *End;
- // Type of entry that this represents.
- enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
- enum EntryType EntryKind;
+public:
+ /// A single location or constant.
+ struct Value {
+ Value(const MDNode *Var, int64_t i)
+ : Variable(Var), EntryKind(E_Integer) {
+ Constant.Int = i;
+ }
+ Value(const MDNode *Var, const ConstantFP *CFP)
+ : Variable(Var), EntryKind(E_ConstantFP) {
+ Constant.CFP = CFP;
+ }
+ Value(const MDNode *Var, const ConstantInt *CIP)
+ : Variable(Var), EntryKind(E_ConstantInt) {
+ Constant.CIP = CIP;
+ }
+ Value(const MDNode *Var, MachineLocation Loc)
+ : Variable(Var), EntryKind(E_Location), Loc(Loc) {
+ }
- union {
- int64_t Int;
- const ConstantFP *CFP;
- const ConstantInt *CIP;
- } Constants;
+ // The variable to which this location entry corresponds.
+ const MDNode *Variable;
- // The location in the machine frame.
- MachineLocation Loc;
+ // Type of entry that this represents.
+ enum EntryType { E_Location, E_Integer, E_ConstantFP, E_ConstantInt };
+ enum EntryType EntryKind;
- // The variable to which this location entry corresponds.
- const MDNode *Variable;
+ // Either a constant,
+ union {
+ int64_t Int;
+ const ConstantFP *CFP;
+ const ConstantInt *CIP;
+ } Constant;
- // The compile unit to which this location entry is referenced by.
- const DwarfCompileUnit *Unit;
+ // Or a location in the machine frame.
+ MachineLocation Loc;
- bool hasSameValueOrLocation(const DebugLocEntry &Next) {
- if (EntryKind != Next.EntryKind)
- return false;
+ bool operator==(const Value &other) const {
+ if (EntryKind != other.EntryKind)
+ return false;
- bool EqualValues;
- switch (EntryKind) {
- case E_Location:
- EqualValues = Loc == Next.Loc;
- break;
- case E_Integer:
- EqualValues = Constants.Int == Next.Constants.Int;
- break;
- case E_ConstantFP:
- EqualValues = Constants.CFP == Next.Constants.CFP;
- break;
- case E_ConstantInt:
- EqualValues = Constants.CIP == Next.Constants.CIP;
- break;
+ switch (EntryKind) {
+ case E_Location:
+ return Loc == other.Loc;
+ case E_Integer:
+ return Constant.Int == other.Constant.Int;
+ case E_ConstantFP:
+ return Constant.CFP == other.Constant.CFP;
+ case E_ConstantInt:
+ return Constant.CIP == other.Constant.CIP;
+ }
+ llvm_unreachable("unhandled EntryKind");
}
- return EqualValues;
- }
+ bool isLocation() const { return EntryKind == E_Location; }
+ bool isInt() const { return EntryKind == E_Integer; }
+ bool isConstantFP() const { return EntryKind == E_ConstantFP; }
+ bool isConstantInt() const { return EntryKind == E_ConstantInt; }
+ int64_t getInt() const { return Constant.Int; }
+ const ConstantFP *getConstantFP() const { return Constant.CFP; }
+ const ConstantInt *getConstantInt() const { return Constant.CIP; }
+ MachineLocation getLoc() const { return Loc; }
+ const MDNode *getVariable() const { return Variable; }
+ };
+private:
+ /// A list of locations/constants belonging to this entry.
+ SmallVector<Value, 1> Values;
+
+ /// The compile unit that this location entry is referenced by.
+ const DwarfCompileUnit *Unit;
public:
- DebugLocEntry() : Begin(0), End(0), Variable(0), Unit(0) {
- Constants.Int = 0;
- }
- DebugLocEntry(const MCSymbol *B, const MCSymbol *E, MachineLocation &L,
- const MDNode *V, const DwarfCompileUnit *U)
- : Begin(B), End(E), Loc(L), Variable(V), Unit(U) {
- Constants.Int = 0;
- EntryKind = E_Location;
- }
- DebugLocEntry(const MCSymbol *B, const MCSymbol *E, int64_t i,
- const DwarfCompileUnit *U)
- : Begin(B), End(E), Variable(0), Unit(U) {
- Constants.Int = i;
- EntryKind = E_Integer;
- }
- DebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantFP *FPtr,
- const DwarfCompileUnit *U)
- : Begin(B), End(E), Variable(0), Unit(U) {
- Constants.CFP = FPtr;
- EntryKind = E_ConstantFP;
- }
- DebugLocEntry(const MCSymbol *B, const MCSymbol *E, const ConstantInt *IPtr,
- const DwarfCompileUnit *U)
- : Begin(B), End(E), Variable(0), Unit(U) {
- Constants.CIP = IPtr;
- EntryKind = E_ConstantInt;
+ DebugLocEntry() : Begin(nullptr), End(nullptr), Unit(nullptr) {}
+ DebugLocEntry(const MCSymbol *B, const MCSymbol *E,
+ Value Val, const DwarfCompileUnit *U)
+ : Begin(B), End(E), Unit(U) {
+ Values.push_back(std::move(Val));
}
/// \brief Attempt to merge this DebugLocEntry with Next and return
@@ -99,24 +106,17 @@ public:
/// share the same Loc/Constant and if Next immediately follows this
/// Entry.
bool Merge(const DebugLocEntry &Next) {
- if (End == Next.Begin && hasSameValueOrLocation(Next)) {
+ if ((End == Next.Begin && Values == Next.Values)) {
End = Next.End;
return true;
}
return false;
}
- bool isLocation() const { return EntryKind == E_Location; }
- bool isInt() const { return EntryKind == E_Integer; }
- bool isConstantFP() const { return EntryKind == E_ConstantFP; }
- bool isConstantInt() const { return EntryKind == E_ConstantInt; }
- int64_t getInt() const { return Constants.Int; }
- const ConstantFP *getConstantFP() const { return Constants.CFP; }
- const ConstantInt *getConstantInt() const { return Constants.CIP; }
- const MDNode *getVariable() const { return Variable; }
const MCSymbol *getBeginSym() const { return Begin; }
const MCSymbol *getEndSym() const { return End; }
const DwarfCompileUnit *getCU() const { return Unit; }
- MachineLocation getLoc() const { return Loc; }
+ const ArrayRef<Value> getValues() const { return Values; }
+ void addValue(Value Val) { Values.push_back(Val); }
};
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
index bcbb6c8..e9527c4 100644
--- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
@@ -29,14 +29,15 @@ DwarfAccelTable::DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom> atomList)
: Header(8 + (atomList.size() * 4)), HeaderData(atomList),
Entries(Allocator) {}
-DwarfAccelTable::~DwarfAccelTable() {}
-
-void DwarfAccelTable::AddName(StringRef Name, const DIE *die, char Flags) {
+void DwarfAccelTable::AddName(StringRef Name, MCSymbol *StrSym, const DIE *die,
+ char Flags) {
assert(Data.empty() && "Already finalized!");
// If the string is in the list already then add this die to the list
// otherwise add a new one.
DataArray &DIEs = Entries[Name];
- DIEs.push_back(new (Allocator) HashDataContents(die, Flags));
+ assert(!DIEs.StrSym || DIEs.StrSym == StrSym);
+ DIEs.StrSym = StrSym;
+ DIEs.Values.push_back(new (Allocator) HashDataContents(die, Flags));
}
void DwarfAccelTable::ComputeBucketCount(void) {
@@ -72,9 +73,10 @@ void DwarfAccelTable::FinalizeTable(AsmPrinter *Asm, StringRef Prefix) {
EI != EE; ++EI) {
// Unique the entries.
- std::stable_sort(EI->second.begin(), EI->second.end(), compareDIEs);
- EI->second.erase(std::unique(EI->second.begin(), EI->second.end()),
- EI->second.end());
+ std::stable_sort(EI->second.Values.begin(), EI->second.Values.end(), compareDIEs);
+ EI->second.Values.erase(
+ std::unique(EI->second.Values.begin(), EI->second.Values.end()),
+ EI->second.Values.end());
HashData *Entry = new (Allocator) HashData(EI->getKey(), EI->second);
Data.push_back(Entry);
@@ -181,21 +183,18 @@ void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfFile *D) {
// Remember to emit the label for our offset.
Asm->OutStreamer.EmitLabel((*HI)->Sym);
Asm->OutStreamer.AddComment((*HI)->Str);
- Asm->EmitSectionOffset(D->getStringPoolEntry((*HI)->Str),
- D->getStringPoolSym());
+ Asm->EmitSectionOffset((*HI)->Data.StrSym,
+ D->getStringPool().getSectionSymbol());
Asm->OutStreamer.AddComment("Num DIEs");
- Asm->EmitInt32((*HI)->Data.size());
- for (ArrayRef<HashDataContents *>::const_iterator
- DI = (*HI)->Data.begin(),
- DE = (*HI)->Data.end();
- DI != DE; ++DI) {
+ Asm->EmitInt32((*HI)->Data.Values.size());
+ for (HashDataContents *HD : (*HI)->Data.Values) {
// Emit the DIE offset
- Asm->EmitInt32((*DI)->Die->getOffset());
+ Asm->EmitInt32(HD->Die->getOffset());
// If we have multiple Atoms emit that info too.
// FIXME: A bit of a hack, we either emit only one atom or all info.
if (HeaderData.Atoms.size() > 1) {
- Asm->EmitInt16((*DI)->Die->getTag());
- Asm->EmitInt8((*DI)->Flags);
+ Asm->EmitInt16(HD->Die->getTag());
+ Asm->EmitInt8(HD->Flags);
}
}
// Emit a 0 to terminate the data unless we have a hash collision.
@@ -235,10 +234,8 @@ void DwarfAccelTable::print(raw_ostream &O) {
EE = Entries.end();
EI != EE; ++EI) {
O << "Name: " << EI->getKeyData() << "\n";
- for (DataArray::const_iterator DI = EI->second.begin(),
- DE = EI->second.end();
- DI != DE; ++DI)
- (*DI)->print(O);
+ for (HashDataContents *HD : EI->second.Values)
+ HD->print(O);
}
O << "Buckets and Hashes: \n";
diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
index 4a14497..a3cc95f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
+++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Dwarf.h"
@@ -125,7 +126,8 @@ public:
uint16_t type; // enum AtomType
uint16_t form; // DWARF DW_FORM_ defines
- Atom(uint16_t type, uint16_t form) : type(type), form(form) {}
+ LLVM_CONSTEXPR Atom(uint16_t type, uint16_t form)
+ : type(type), form(form) {}
#ifndef NDEBUG
void print(raw_ostream &O) {
O << "Type: " << dwarf::AtomTypeString(type) << "\n"
@@ -177,12 +179,19 @@ public:
};
private:
+ // String Data
+ struct DataArray {
+ MCSymbol *StrSym;
+ std::vector<HashDataContents *> Values;
+ DataArray() : StrSym(nullptr) {}
+ };
+ friend struct HashData;
struct HashData {
StringRef Str;
uint32_t HashValue;
MCSymbol *Sym;
- ArrayRef<HashDataContents *> Data; // offsets
- HashData(StringRef S, ArrayRef<HashDataContents *> Data)
+ DwarfAccelTable::DataArray &Data; // offsets
+ HashData(StringRef S, DwarfAccelTable::DataArray &Data)
: Str(S), Data(Data) {
HashValue = DwarfAccelTable::HashDJB(S);
}
@@ -196,10 +205,10 @@ private:
else
O << "<none>";
O << "\n";
- for (size_t i = 0; i < Data.size(); i++) {
- O << " Offset: " << Data[i]->Die->getOffset() << "\n";
- O << " Tag: " << dwarf::TagString(Data[i]->Die->getTag()) << "\n";
- O << " Flags: " << Data[i]->Flags << "\n";
+ for (HashDataContents *C : Data.Values) {
+ O << " Offset: " << C->Die->getOffset() << "\n";
+ O << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n";
+ O << " Flags: " << C->Flags << "\n";
}
}
void dump() { print(dbgs()); }
@@ -224,8 +233,6 @@ private:
TableHeaderData HeaderData;
std::vector<HashData *> Data;
- // String Data
- typedef std::vector<HashDataContents *> DataArray;
typedef StringMap<DataArray, BumpPtrAllocator &> StringEntries;
StringEntries Entries;
@@ -238,8 +245,8 @@ private:
// Public Implementation
public:
DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom>);
- ~DwarfAccelTable();
- void AddName(StringRef, const DIE *, char = 0);
+ void AddName(StringRef Name, MCSymbol *StrSym, const DIE *Die,
+ char Flags = 0);
void FinalizeTable(AsmPrinter *, StringRef);
void Emit(AsmPrinter *, MCSymbol *, DwarfFile *);
#ifndef NDEBUG
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 11345eb..2a0615d 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -11,12 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dwarfdebug"
#include "ByteStreamer.h"
#include "DwarfDebug.h"
#include "DIE.h"
#include "DIEHash.h"
-#include "DwarfAccelTable.h"
#include "DwarfUnit.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/Statistic.h"
@@ -51,6 +49,8 @@
#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
+#define DEBUG_TYPE "dwarfdebug"
+
static cl::opt<bool>
DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
cl::desc("Disable debug info printing"));
@@ -107,8 +107,6 @@ static const char *const DbgTimerName = "DWARF Debug Writer";
//===----------------------------------------------------------------------===//
-namespace llvm {
-
/// resolve - Look in the DwarfDebug map for the MDNode that
/// corresponds to the reference.
template <typename T> T DbgVariable::resolve(DIRef<T> Ref) const {
@@ -120,7 +118,6 @@ bool DbgVariable::isBlockByrefVariable() const {
return Var.isBlockByrefVariable(DD->getTypeIdentifierMap());
}
-
DIType DbgVariable::getType() const {
DIType Ty = Var.getType().resolve(DD->getTypeIdentifierMap());
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
@@ -166,29 +163,32 @@ DIType DbgVariable::getType() const {
return Ty;
}
-} // end llvm namespace
-
-/// Return Dwarf Version by checking module flags.
-static unsigned getDwarfVersionFromModule(const Module *M) {
- Value *Val = M->getModuleFlag("Dwarf Version");
- if (!Val)
- return dwarf::DWARF_VERSION;
- return cast<ConstantInt>(Val)->getZExtValue();
-}
+static LLVM_CONSTEXPR DwarfAccelTable::Atom TypeAtoms[] = {
+ DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
+ DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
+ DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1)};
DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
- : Asm(A), MMI(Asm->MMI), FirstCU(0), PrevLabel(NULL), GlobalRangeCount(0),
- InfoHolder(A, "info_string", DIEValueAllocator),
+ : Asm(A), MMI(Asm->MMI), FirstCU(nullptr), PrevLabel(nullptr),
+ GlobalRangeCount(0), InfoHolder(A, "info_string", DIEValueAllocator),
UsedNonDefaultText(false),
- SkeletonHolder(A, "skel_string", DIEValueAllocator) {
-
- DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = 0;
- DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = DwarfLineSectionSym = 0;
- DwarfAddrSectionSym = 0;
- DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0;
- FunctionBeginSym = FunctionEndSym = 0;
- CurFn = 0;
- CurMI = 0;
+ SkeletonHolder(A, "skel_string", DIEValueAllocator),
+ AccelNames(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
+ dwarf::DW_FORM_data4)),
+ AccelObjC(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
+ dwarf::DW_FORM_data4)),
+ AccelNamespace(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
+ dwarf::DW_FORM_data4)),
+ AccelTypes(TypeAtoms) {
+
+ DwarfInfoSectionSym = DwarfAbbrevSectionSym = DwarfStrSectionSym = nullptr;
+ DwarfDebugRangeSectionSym = DwarfDebugLocSectionSym = nullptr;
+ DwarfLineSectionSym = nullptr;
+ DwarfAddrSectionSym = nullptr;
+ DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = nullptr;
+ FunctionBeginSym = FunctionEndSym = nullptr;
+ CurFn = nullptr;
+ CurMI = nullptr;
// Turn on accelerator tables for Darwin by default, pubnames by
// default for non-Darwin, and handle split dwarf.
@@ -209,9 +209,8 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
else
HasDwarfPubSections = DwarfPubSections == Enable;
- DwarfVersion = DwarfVersionNumber
- ? DwarfVersionNumber
- : getDwarfVersionFromModule(MMI->getModule());
+ DwarfVersion = DwarfVersionNumber ? DwarfVersionNumber
+ : MMI->getModule()->getDwarfVersion();
{
NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
@@ -219,76 +218,22 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
}
}
+// Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h.
+DwarfDebug::~DwarfDebug() { }
+
// Switch to the specified MCSection and emit an assembler
// temporary label to it if SymbolStem is specified.
static MCSymbol *emitSectionSym(AsmPrinter *Asm, const MCSection *Section,
- const char *SymbolStem = 0) {
+ const char *SymbolStem = nullptr) {
Asm->OutStreamer.SwitchSection(Section);
if (!SymbolStem)
- return 0;
+ return nullptr;
MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
Asm->OutStreamer.EmitLabel(TmpSym);
return TmpSym;
}
-DwarfFile::~DwarfFile() {
- for (DwarfUnit *DU : CUs)
- delete DU;
-}
-
-MCSymbol *DwarfFile::getStringPoolSym() {
- return Asm->GetTempSymbol(StringPref);
-}
-
-MCSymbol *DwarfFile::getStringPoolEntry(StringRef Str) {
- std::pair<MCSymbol *, unsigned> &Entry =
- StringPool.GetOrCreateValue(Str).getValue();
- if (Entry.first)
- return Entry.first;
-
- Entry.second = NextStringPoolNumber++;
- return Entry.first = Asm->GetTempSymbol(StringPref, Entry.second);
-}
-
-unsigned DwarfFile::getStringPoolIndex(StringRef Str) {
- std::pair<MCSymbol *, unsigned> &Entry =
- StringPool.GetOrCreateValue(Str).getValue();
- if (Entry.first)
- return Entry.second;
-
- Entry.second = NextStringPoolNumber++;
- Entry.first = Asm->GetTempSymbol(StringPref, Entry.second);
- return Entry.second;
-}
-
-unsigned DwarfFile::getAddrPoolIndex(const MCSymbol *Sym, bool TLS) {
- std::pair<AddrPool::iterator, bool> P = AddressPool.insert(
- std::make_pair(Sym, AddressPoolEntry(NextAddrPoolNumber, TLS)));
- if (P.second)
- ++NextAddrPoolNumber;
- return P.first->second.Number;
-}
-
-// Define a unique number for the abbreviation.
-//
-void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) {
- // Check the set for priors.
- DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
-
- // If it's newly added.
- if (InSet == &Abbrev) {
- // Add to abbreviation list.
- Abbreviations.push_back(&Abbrev);
-
- // Assign the vector position + 1 as its number.
- Abbrev.setNumber(Abbreviations.size());
- } else {
- // Assign existing abbreviation number.
- Abbrev.setNumber(InSet->getNumber());
- }
-}
-
static bool isObjCClass(StringRef Name) {
return Name.startswith("+") || Name.startswith("-");
}
@@ -328,26 +273,26 @@ static bool SectionSort(const MCSection *A, const MCSection *B) {
// TODO: Determine whether or not we should add names for programs
// that do not have a DW_AT_name or DW_AT_linkage_name field - this
// is only slightly different than the lookup of non-standard ObjC names.
-static void addSubprogramNames(DwarfUnit *TheU, DISubprogram SP, DIE *Die) {
+void DwarfDebug::addSubprogramNames(DISubprogram SP, DIE &Die) {
if (!SP.isDefinition())
return;
- TheU->addAccelName(SP.getName(), Die);
+ addAccelName(SP.getName(), Die);
// If the linkage name is different than the name, go ahead and output
// that as well into the name table.
if (SP.getLinkageName() != "" && SP.getName() != SP.getLinkageName())
- TheU->addAccelName(SP.getLinkageName(), Die);
+ addAccelName(SP.getLinkageName(), Die);
// If this is an Objective-C selector name add it to the ObjC accelerator
// too.
if (isObjCClass(SP.getName())) {
StringRef Class, Category;
getObjCClassCategory(SP.getName(), Class, Category);
- TheU->addAccelObjC(Class, Die);
+ addAccelObjC(Class, Die);
if (Category != "")
- TheU->addAccelObjC(Category, Die);
+ addAccelObjC(Category, Die);
// Also add the base method name to the name table.
- TheU->addAccelName(getObjCMethodName(SP.getName()), Die);
+ addAccelName(getObjCMethodName(SP.getName()), Die);
}
}
@@ -367,58 +312,21 @@ bool DwarfDebug::isSubprogramContext(const MDNode *Context) {
// Find DIE for the given subprogram and attach appropriate DW_AT_low_pc
// and DW_AT_high_pc attributes. If there are global variables in this
// scope then create and insert DIEs for these variables.
-DIE *DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit *SPCU,
+DIE &DwarfDebug::updateSubprogramScopeDIE(DwarfCompileUnit &SPCU,
DISubprogram SP) {
- DIE *SPDie = SPCU->getDIE(SP);
-
- assert(SPDie && "Unable to find subprogram DIE!");
-
- // If we're updating an abstract DIE, then we will be adding the children and
- // object pointer later on. But what we don't want to do is process the
- // concrete DIE twice.
- if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) {
- // Pick up abstract subprogram DIE.
- SPDie =
- SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram, *SPCU->getUnitDie());
- SPCU->addDIEEntry(SPDie, dwarf::DW_AT_abstract_origin, AbsSPDIE);
- } else {
- DISubprogram SPDecl = SP.getFunctionDeclaration();
- if (!SPDecl.isSubprogram()) {
- // 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.
- DIScope SPContext = resolve(SP.getContext());
- if (SP.isDefinition() && !SPContext.isCompileUnit() &&
- !SPContext.isFile() && !isSubprogramContext(SPContext)) {
- SPCU->addFlag(SPDie, dwarf::DW_AT_declaration);
-
- // Add arguments.
- DICompositeType SPTy = SP.getType();
- DIArray Args = SPTy.getTypeArray();
- uint16_t SPTag = SPTy.getTag();
- if (SPTag == dwarf::DW_TAG_subroutine_type)
- SPCU->constructSubprogramArguments(*SPDie, Args);
- DIE *SPDeclDie = SPDie;
- SPDie = SPCU->createAndAddDIE(dwarf::DW_TAG_subprogram,
- *SPCU->getUnitDie());
- SPCU->addDIEEntry(SPDie, dwarf::DW_AT_specification, SPDeclDie);
- }
- }
- }
+ DIE *SPDie = SPCU.getOrCreateSubprogramDIE(SP);
- attachLowHighPC(SPCU, SPDie, FunctionBeginSym, FunctionEndSym);
+ attachLowHighPC(SPCU, *SPDie, FunctionBeginSym, FunctionEndSym);
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
MachineLocation Location(RI->getFrameRegister(*Asm->MF));
- SPCU->addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
+ SPCU.addAddress(*SPDie, dwarf::DW_AT_frame_base, Location);
// Add name to the name table, we do this here because we're guaranteed
// to have concrete versions of our DW_TAG_subprogram nodes.
- addSubprogramNames(SPCU, SP, SPDie);
+ addSubprogramNames(SP, *SPDie);
- return SPDie;
+ return *SPDie;
}
/// Check whether we should create a DIE for the given Scope, return true
@@ -442,16 +350,16 @@ bool DwarfDebug::isLexicalScopeDIENull(LexicalScope *Scope) {
return !End;
}
-static void addSectionLabel(AsmPrinter *Asm, DwarfUnit *U, DIE *D,
+static void addSectionLabel(AsmPrinter &Asm, DwarfUnit &U, DIE &D,
dwarf::Attribute A, const MCSymbol *L,
const MCSymbol *Sec) {
- if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- U->addSectionLabel(D, A, L);
+ if (Asm.MAI->doesDwarfUseRelocationsAcrossSections())
+ U.addSectionLabel(D, A, L);
else
- U->addSectionDelta(D, A, L, Sec);
+ U.addSectionDelta(D, A, L, Sec);
}
-void DwarfDebug::addScopeRangeList(DwarfCompileUnit *TheCU, DIE *ScopeDIE,
+void DwarfDebug::addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE,
const SmallVectorImpl<InsnRange> &Range) {
// Emit offset in .debug_range as a relocatable label. emitDIE will handle
// emitting it appropriately.
@@ -460,10 +368,10 @@ void DwarfDebug::addScopeRangeList(DwarfCompileUnit *TheCU, DIE *ScopeDIE,
// Under fission, ranges are specified by constant offsets relative to the
// CU's DW_AT_GNU_ranges_base.
if (useSplitDwarf())
- TheCU->addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
- DwarfDebugRangeSectionSym);
+ TheCU.addSectionDelta(ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
+ DwarfDebugRangeSectionSym);
else
- addSectionLabel(Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
+ addSectionLabel(*Asm, TheCU, ScopeDIE, dwarf::DW_AT_ranges, RangeSym,
DwarfDebugRangeSectionSym);
RangeSpanList List(RangeSym);
@@ -473,227 +381,256 @@ void DwarfDebug::addScopeRangeList(DwarfCompileUnit *TheCU, DIE *ScopeDIE,
}
// Add the range list to the set of ranges to be emitted.
- TheCU->addRangeList(std::move(List));
+ TheCU.addRangeList(std::move(List));
+}
+
+void DwarfDebug::attachRangesOrLowHighPC(DwarfCompileUnit &TheCU, DIE &Die,
+ const SmallVectorImpl<InsnRange> &Ranges) {
+ assert(!Ranges.empty());
+ if (Ranges.size() == 1)
+ attachLowHighPC(TheCU, Die, getLabelBeforeInsn(Ranges.front().first),
+ getLabelAfterInsn(Ranges.front().second));
+ else
+ addScopeRangeList(TheCU, Die, Ranges);
}
// Construct new DW_TAG_lexical_block for this scope and attach
// DW_AT_low_pc/DW_AT_high_pc labels.
-DIE *DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit *TheCU,
- LexicalScope *Scope) {
+std::unique_ptr<DIE>
+DwarfDebug::constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope) {
if (isLexicalScopeDIENull(Scope))
- return 0;
+ return nullptr;
- DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
+ auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_lexical_block);
if (Scope->isAbstractScope())
return ScopeDIE;
- const SmallVectorImpl<InsnRange> &ScopeRanges = Scope->getRanges();
-
- // If we have multiple ranges, emit them into the range section.
- if (ScopeRanges.size() > 1) {
- addScopeRangeList(TheCU, ScopeDIE, ScopeRanges);
- return ScopeDIE;
- }
-
- // Construct the address range for this DIE.
- SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
- MCSymbol *Start = getLabelBeforeInsn(RI->first);
- MCSymbol *End = getLabelAfterInsn(RI->second);
- assert(End && "End label should not be null!");
-
- assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
- assert(End->isDefined() && "Invalid end label for an inlined scope!");
-
- attachLowHighPC(TheCU, ScopeDIE, Start, End);
+ attachRangesOrLowHighPC(TheCU, *ScopeDIE, Scope->getRanges());
return ScopeDIE;
}
// This scope represents inlined body of a function. Construct DIE to
// represent this concrete inlined copy of the function.
-DIE *DwarfDebug::constructInlinedScopeDIE(DwarfCompileUnit *TheCU,
- LexicalScope *Scope) {
- const SmallVectorImpl<InsnRange> &ScopeRanges = Scope->getRanges();
- assert(!ScopeRanges.empty() &&
- "LexicalScope does not have instruction markers!");
-
- if (!Scope->getScopeNode())
- return NULL;
+std::unique_ptr<DIE>
+DwarfDebug::constructInlinedScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope) {
+ assert(Scope->getScopeNode());
DIScope DS(Scope->getScopeNode());
DISubprogram InlinedSP = getDISubprogram(DS);
- DIE *OriginDIE = TheCU->getDIE(InlinedSP);
- if (!OriginDIE) {
- DEBUG(dbgs() << "Unable to find original DIE for an inlined subprogram.");
- return NULL;
- }
-
- DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
- TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, OriginDIE);
+ // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
+ // was inlined from another compile unit.
+ DIE *OriginDIE = AbstractSPDies[InlinedSP];
+ assert(OriginDIE && "Unable to find original DIE for an inlined subprogram.");
- // If we have multiple ranges, emit them into the range section.
- if (ScopeRanges.size() > 1)
- addScopeRangeList(TheCU, ScopeDIE, ScopeRanges);
- else {
- SmallVectorImpl<InsnRange>::const_iterator RI = ScopeRanges.begin();
- MCSymbol *StartLabel = getLabelBeforeInsn(RI->first);
- MCSymbol *EndLabel = getLabelAfterInsn(RI->second);
+ auto ScopeDIE = make_unique<DIE>(dwarf::DW_TAG_inlined_subroutine);
+ TheCU.addDIEEntry(*ScopeDIE, dwarf::DW_AT_abstract_origin, *OriginDIE);
- if (StartLabel == 0 || EndLabel == 0)
- llvm_unreachable("Unexpected Start and End labels for an inlined scope!");
-
- assert(StartLabel->isDefined() &&
- "Invalid starting label for an inlined scope!");
- assert(EndLabel->isDefined() && "Invalid end label for an inlined scope!");
-
- attachLowHighPC(TheCU, ScopeDIE, StartLabel, EndLabel);
- }
+ attachRangesOrLowHighPC(TheCU, *ScopeDIE, Scope->getRanges());
InlinedSubprogramDIEs.insert(OriginDIE);
// Add the call site information to the DIE.
DILocation DL(Scope->getInlinedAt());
- TheCU->addUInt(
- ScopeDIE, dwarf::DW_AT_call_file, None,
- TheCU->getOrCreateSourceID(DL.getFilename(), DL.getDirectory()));
- TheCU->addUInt(ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber());
+ TheCU.addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
+ TheCU.getOrCreateSourceID(DL.getFilename(), DL.getDirectory()));
+ TheCU.addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber());
// Add name to the name table, we do this here because we're guaranteed
// to have concrete versions of our DW_TAG_inlined_subprogram nodes.
- addSubprogramNames(TheCU, InlinedSP, ScopeDIE);
+ addSubprogramNames(InlinedSP, *ScopeDIE);
return ScopeDIE;
}
-DIE *DwarfDebug::createScopeChildrenDIE(DwarfCompileUnit *TheCU,
- LexicalScope *Scope,
- SmallVectorImpl<DIE *> &Children) {
- DIE *ObjectPointer = NULL;
+static std::unique_ptr<DIE> constructVariableDIE(DwarfCompileUnit &TheCU,
+ DbgVariable &DV,
+ const LexicalScope &Scope,
+ DIE *&ObjectPointer) {
+ auto Var = TheCU.constructVariableDIE(DV, Scope.isAbstractScope());
+ if (DV.isObjectPointer())
+ ObjectPointer = Var.get();
+ return Var;
+}
+
+DIE *DwarfDebug::createScopeChildrenDIE(
+ DwarfCompileUnit &TheCU, LexicalScope *Scope,
+ SmallVectorImpl<std::unique_ptr<DIE>> &Children) {
+ DIE *ObjectPointer = nullptr;
// Collect arguments for current function.
if (LScopes.isCurrentFunctionScope(Scope)) {
for (DbgVariable *ArgDV : CurrentFnArguments)
if (ArgDV)
- if (DIE *Arg =
- TheCU->constructVariableDIE(*ArgDV, Scope->isAbstractScope())) {
- Children.push_back(Arg);
- if (ArgDV->isObjectPointer())
- ObjectPointer = Arg;
- }
+ Children.push_back(
+ constructVariableDIE(TheCU, *ArgDV, *Scope, ObjectPointer));
// If this is a variadic function, add an unspecified parameter.
DISubprogram SP(Scope->getScopeNode());
DIArray FnArgs = SP.getType().getTypeArray();
if (FnArgs.getElement(FnArgs.getNumElements() - 1)
.isUnspecifiedParameter()) {
- DIE *Ellipsis = new DIE(dwarf::DW_TAG_unspecified_parameters);
- Children.push_back(Ellipsis);
+ Children.push_back(
+ make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
}
}
// Collect lexical scope children first.
for (DbgVariable *DV : ScopeVariables.lookup(Scope))
- if (DIE *Variable = TheCU->constructVariableDIE(*DV,
- Scope->isAbstractScope())) {
- Children.push_back(Variable);
- if (DV->isObjectPointer())
- ObjectPointer = Variable;
- }
+ Children.push_back(constructVariableDIE(TheCU, *DV, *Scope, ObjectPointer));
+
for (LexicalScope *LS : Scope->getChildren())
- if (DIE *Nested = constructScopeDIE(TheCU, LS))
- Children.push_back(Nested);
+ if (std::unique_ptr<DIE> Nested = constructScopeDIE(TheCU, LS))
+ Children.push_back(std::move(Nested));
return ObjectPointer;
}
+void DwarfDebug::createAndAddScopeChildren(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope, DIE &ScopeDIE) {
+ // We create children when the scope DIE is not null.
+ SmallVector<std::unique_ptr<DIE>, 8> Children;
+ if (DIE *ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children))
+ TheCU.addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, *ObjectPointer);
+
+ // Add children
+ for (auto &I : Children)
+ ScopeDIE.addChild(std::move(I));
+}
+
+void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope) {
+ assert(Scope && Scope->getScopeNode());
+ assert(Scope->isAbstractScope());
+ assert(!Scope->getInlinedAt());
+
+ DISubprogram SP(Scope->getScopeNode());
+
+ ProcessedSPNodes.insert(SP);
+
+ DIE *&AbsDef = AbstractSPDies[SP];
+ if (AbsDef)
+ return;
+
+ // Find the subprogram's DwarfCompileUnit in the SPMap in case the subprogram
+ // was inlined from another compile unit.
+ DwarfCompileUnit &SPCU = *SPMap[SP];
+ DIE *ContextDIE;
+
+ // Some of this is duplicated from DwarfUnit::getOrCreateSubprogramDIE, with
+ // the important distinction that the DIDescriptor is not associated with the
+ // DIE (since the DIDescriptor will be associated with the concrete DIE, if
+ // any). It could be refactored to some common utility function.
+ if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+ ContextDIE = &SPCU.getUnitDie();
+ SPCU.getOrCreateSubprogramDIE(SPDecl);
+ } else
+ ContextDIE = SPCU.getOrCreateContextDIE(resolve(SP.getContext()));
+
+ // Passing null as the associated DIDescriptor because the abstract definition
+ // shouldn't be found by lookup.
+ AbsDef = &SPCU.createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE,
+ DIDescriptor());
+ SPCU.applySubprogramAttributes(SP, *AbsDef);
+ SPCU.addGlobalName(SP.getName(), *AbsDef, resolve(SP.getContext()));
+
+ SPCU.addUInt(*AbsDef, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
+ createAndAddScopeChildren(SPCU, Scope, *AbsDef);
+}
+
+DIE &DwarfDebug::constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope) {
+ assert(Scope && Scope->getScopeNode());
+ assert(!Scope->getInlinedAt());
+ assert(!Scope->isAbstractScope());
+ DISubprogram Sub(Scope->getScopeNode());
+
+ assert(Sub.isSubprogram());
+
+ ProcessedSPNodes.insert(Sub);
+
+ DIE &ScopeDIE = updateSubprogramScopeDIE(TheCU, Sub);
+
+ createAndAddScopeChildren(TheCU, Scope, ScopeDIE);
+
+ return ScopeDIE;
+}
+
// Construct a DIE for this scope.
-DIE *DwarfDebug::constructScopeDIE(DwarfCompileUnit *TheCU,
- LexicalScope *Scope) {
+std::unique_ptr<DIE> DwarfDebug::constructScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope) {
if (!Scope || !Scope->getScopeNode())
- return NULL;
+ return nullptr;
DIScope DS(Scope->getScopeNode());
- SmallVector<DIE *, 8> Children;
- DIE *ObjectPointer = NULL;
- bool ChildrenCreated = false;
+ assert((Scope->getInlinedAt() || !DS.isSubprogram()) &&
+ "Only handle inlined subprograms here, use "
+ "constructSubprogramScopeDIE for non-inlined "
+ "subprograms");
+
+ SmallVector<std::unique_ptr<DIE>, 8> Children;
// We try to create the scope DIE first, then the children DIEs. This will
// avoid creating un-used children then removing them later when we find out
// the scope DIE is null.
- DIE *ScopeDIE = NULL;
- if (Scope->getInlinedAt())
+ std::unique_ptr<DIE> ScopeDIE;
+ if (Scope->getParent() && DS.isSubprogram()) {
ScopeDIE = constructInlinedScopeDIE(TheCU, Scope);
- else if (DS.isSubprogram()) {
- ProcessedSPNodes.insert(DS);
- if (Scope->isAbstractScope()) {
- ScopeDIE = TheCU->getDIE(DS);
- // Note down abstract DIE.
- if (ScopeDIE)
- AbstractSPDies.insert(std::make_pair(DS, ScopeDIE));
- } else
- ScopeDIE = updateSubprogramScopeDIE(TheCU, DISubprogram(DS));
+ if (!ScopeDIE)
+ return nullptr;
+ // We create children when the scope DIE is not null.
+ createScopeChildrenDIE(TheCU, Scope, Children);
} else {
// Early exit when we know the scope DIE is going to be null.
if (isLexicalScopeDIENull(Scope))
- return NULL;
+ return nullptr;
// We create children here when we know the scope DIE is not going to be
// null and the children will be added to the scope DIE.
- ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children);
- ChildrenCreated = true;
+ createScopeChildrenDIE(TheCU, Scope, Children);
// There is no need to emit empty lexical block DIE.
std::pair<ImportedEntityMap::const_iterator,
ImportedEntityMap::const_iterator> Range =
- std::equal_range(
- ScopesWithImportedEntities.begin(),
- ScopesWithImportedEntities.end(),
- std::pair<const MDNode *, const MDNode *>(DS, (const MDNode *)0),
- less_first());
+ std::equal_range(ScopesWithImportedEntities.begin(),
+ ScopesWithImportedEntities.end(),
+ std::pair<const MDNode *, const MDNode *>(DS, nullptr),
+ less_first());
if (Children.empty() && Range.first == Range.second)
- return NULL;
+ return nullptr;
ScopeDIE = constructLexicalScopeDIE(TheCU, Scope);
assert(ScopeDIE && "Scope DIE should not be null.");
for (ImportedEntityMap::const_iterator i = Range.first; i != Range.second;
++i)
- constructImportedEntityDIE(TheCU, i->second, ScopeDIE);
+ constructImportedEntityDIE(TheCU, i->second, *ScopeDIE);
}
- if (!ScopeDIE) {
- assert(Children.empty() &&
- "We create children only when the scope DIE is not null.");
- return NULL;
- }
- if (!ChildrenCreated)
- // We create children when the scope DIE is not null.
- ObjectPointer = createScopeChildrenDIE(TheCU, Scope, Children);
-
// Add children
- for (DIE *I : Children)
- ScopeDIE->addChild(I);
-
- if (DS.isSubprogram() && ObjectPointer != NULL)
- TheCU->addDIEEntry(ScopeDIE, dwarf::DW_AT_object_pointer, ObjectPointer);
+ for (auto &I : Children)
+ ScopeDIE->addChild(std::move(I));
return ScopeDIE;
}
-void DwarfDebug::addGnuPubAttributes(DwarfUnit *U, DIE *D) const {
+void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
if (!GenerateGnuPubSections)
return;
- U->addFlag(D, dwarf::DW_AT_GNU_pubnames);
+ U.addFlag(D, dwarf::DW_AT_GNU_pubnames);
}
// Create new DwarfCompileUnit for the given metadata node with tag
// DW_TAG_compile_unit.
-DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
+DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
StringRef FN = DIUnit.getFilename();
CompilationDir = DIUnit.getDirectory();
- DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
- DwarfCompileUnit *NewCU = new DwarfCompileUnit(
- InfoHolder.getUnits().size(), Die, DIUnit, Asm, this, &InfoHolder);
- InfoHolder.addUnit(NewCU);
+ auto OwnedUnit = make_unique<DwarfCompileUnit>(
+ InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
+ DwarfCompileUnit &NewCU = *OwnedUnit;
+ DIE &Die = NewCU.getUnitDie();
+ InfoHolder.addUnit(std::move(OwnedUnit));
// LTO with assembly output shares a single line table amongst multiple CUs.
// To avoid the compilation directory being ambiguous, let the line table
@@ -701,116 +638,89 @@ DwarfCompileUnit *DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
// compilation directory.
if (!Asm->OutStreamer.hasRawTextSupport() || SingleCU)
Asm->OutStreamer.getContext().setMCLineTableCompilationDir(
- NewCU->getUniqueID(), CompilationDir);
+ NewCU.getUniqueID(), CompilationDir);
- NewCU->addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer());
- NewCU->addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
- DIUnit.getLanguage());
- NewCU->addString(Die, dwarf::DW_AT_name, FN);
+ NewCU.addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer());
+ NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+ DIUnit.getLanguage());
+ NewCU.addString(Die, dwarf::DW_AT_name, FN);
if (!useSplitDwarf()) {
- NewCU->initStmtList(DwarfLineSectionSym);
+ NewCU.initStmtList(DwarfLineSectionSym);
// If we're using split dwarf the compilation dir is going to be in the
// skeleton CU and so we don't need to duplicate it here.
if (!CompilationDir.empty())
- NewCU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
+ NewCU.addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
addGnuPubAttributes(NewCU, Die);
}
if (DIUnit.isOptimized())
- NewCU->addFlag(Die, dwarf::DW_AT_APPLE_optimized);
+ NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized);
StringRef Flags = DIUnit.getFlags();
if (!Flags.empty())
- NewCU->addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
+ NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
if (unsigned RVer = DIUnit.getRunTimeVersion())
- NewCU->addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
- dwarf::DW_FORM_data1, RVer);
+ NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
+ dwarf::DW_FORM_data1, RVer);
if (!FirstCU)
- FirstCU = NewCU;
+ FirstCU = &NewCU;
if (useSplitDwarf()) {
- NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection(),
- DwarfInfoDWOSectionSym);
- NewCU->setSkeleton(constructSkeletonCU(NewCU));
+ NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoDWOSection(),
+ DwarfInfoDWOSectionSym);
+ NewCU.setSkeleton(constructSkeletonCU(NewCU));
} else
- NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoSection(),
- DwarfInfoSectionSym);
+ NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection(),
+ DwarfInfoSectionSym);
- CUMap.insert(std::make_pair(DIUnit, NewCU));
- CUDieMap.insert(std::make_pair(Die, NewCU));
+ CUMap.insert(std::make_pair(DIUnit, &NewCU));
+ CUDieMap.insert(std::make_pair(&Die, &NewCU));
return NewCU;
}
-// Construct subprogram DIE.
-void DwarfDebug::constructSubprogramDIE(DwarfCompileUnit *TheCU,
- const MDNode *N) {
- // FIXME: We should only call this routine once, however, during LTO if a
- // program is defined in multiple CUs we could end up calling it out of
- // beginModule as we walk the CUs.
-
- DwarfCompileUnit *&CURef = SPMap[N];
- if (CURef)
- return;
- CURef = TheCU;
-
- DISubprogram SP(N);
- if (!SP.isDefinition())
- // This is a method declaration which will be handled while constructing
- // class type.
- return;
-
- DIE *SubprogramDie = TheCU->getOrCreateSubprogramDIE(SP);
-
- // Expose as a global name.
- TheCU->addGlobalName(SP.getName(), SubprogramDie, resolve(SP.getContext()));
-}
-
-void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
+void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
const MDNode *N) {
DIImportedEntity Module(N);
assert(Module.Verify());
- if (DIE *D = TheCU->getOrCreateContextDIE(Module.getContext()))
- constructImportedEntityDIE(TheCU, Module, D);
+ if (DIE *D = TheCU.getOrCreateContextDIE(Module.getContext()))
+ constructImportedEntityDIE(TheCU, Module, *D);
}
-void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
- const MDNode *N, DIE *Context) {
+void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
+ const MDNode *N, DIE &Context) {
DIImportedEntity Module(N);
assert(Module.Verify());
return constructImportedEntityDIE(TheCU, Module, Context);
}
-void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit *TheCU,
+void DwarfDebug::constructImportedEntityDIE(DwarfCompileUnit &TheCU,
const DIImportedEntity &Module,
- DIE *Context) {
+ DIE &Context) {
assert(Module.Verify() &&
"Use one of the MDNode * overloads to handle invalid metadata");
- assert(Context && "Should always have a context for an imported_module");
- DIE *IMDie = new DIE(Module.getTag());
- TheCU->insertDIE(Module, IMDie);
+ DIE &IMDie = TheCU.createAndAddDIE(Module.getTag(), Context, Module);
DIE *EntityDie;
DIDescriptor Entity = resolve(Module.getEntity());
if (Entity.isNameSpace())
- EntityDie = TheCU->getOrCreateNameSpace(DINameSpace(Entity));
+ EntityDie = TheCU.getOrCreateNameSpace(DINameSpace(Entity));
else if (Entity.isSubprogram())
- EntityDie = TheCU->getOrCreateSubprogramDIE(DISubprogram(Entity));
+ EntityDie = TheCU.getOrCreateSubprogramDIE(DISubprogram(Entity));
else if (Entity.isType())
- EntityDie = TheCU->getOrCreateTypeDIE(DIType(Entity));
+ EntityDie = TheCU.getOrCreateTypeDIE(DIType(Entity));
else
- EntityDie = TheCU->getDIE(Entity);
- TheCU->addSourceLine(IMDie, Module.getLineNumber(),
- Module.getContext().getFilename(),
- Module.getContext().getDirectory());
- TheCU->addDIEEntry(IMDie, dwarf::DW_AT_import, EntityDie);
+ EntityDie = TheCU.getDIE(Entity);
+ TheCU.addSourceLine(IMDie, Module.getLineNumber(),
+ Module.getContext().getFilename(),
+ Module.getContext().getDirectory());
+ TheCU.addDIEEntry(IMDie, dwarf::DW_AT_import, *EntityDie);
StringRef Name = Module.getName();
if (!Name.empty())
- TheCU->addString(IMDie, dwarf::DW_AT_name, Name);
- Context->addChild(IMDie);
+ TheCU.addString(IMDie, dwarf::DW_AT_name, Name);
}
// Emit all Dwarf sections that should come prior to the content. Create
@@ -836,7 +746,7 @@ void DwarfDebug::beginModule() {
for (MDNode *N : CU_Nodes->operands()) {
DICompileUnit CUNode(N);
- DwarfCompileUnit *CU = constructDwarfCompileUnit(CUNode);
+ DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
DIArray ImportedEntities = CUNode.getImportedEntities();
for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i)
ScopesWithImportedEntities.push_back(std::make_pair(
@@ -846,20 +756,20 @@ void DwarfDebug::beginModule() {
ScopesWithImportedEntities.end(), less_first());
DIArray GVs = CUNode.getGlobalVariables();
for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i)
- CU->createGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i)));
+ CU.createGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i)));
DIArray SPs = CUNode.getSubprograms();
for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
- constructSubprogramDIE(CU, SPs.getElement(i));
+ SPMap.insert(std::make_pair(SPs.getElement(i), &CU));
DIArray EnumTypes = CUNode.getEnumTypes();
for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i)
- CU->getOrCreateTypeDIE(EnumTypes.getElement(i));
+ CU.getOrCreateTypeDIE(EnumTypes.getElement(i));
DIArray RetainedTypes = CUNode.getRetainedTypes();
for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) {
DIType Ty(RetainedTypes.getElement(i));
// The retained types array by design contains pointers to
// MDNodes rather than DIRefs. Unique them here.
DIType UniqueTy(resolve(Ty.getRef()));
- CU->getOrCreateTypeDIE(UniqueTy);
+ CU.getOrCreateTypeDIE(UniqueTy);
}
// Emit imported_modules last so that the relevant context is already
// available.
@@ -874,20 +784,41 @@ void DwarfDebug::beginModule() {
SectionMap[Asm->getObjFileLowering().getTextSection()];
}
-// Attach DW_AT_inline attribute with inlined subprogram DIEs.
-void DwarfDebug::computeInlinedDIEs() {
- // Attach DW_AT_inline attribute with inlined subprogram DIEs.
- for (DIE *ISP : InlinedSubprogramDIEs)
- FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
+void DwarfDebug::finishSubprogramDefinitions() {
+ const Module *M = MMI->getModule();
- for (const auto &AI : AbstractSPDies) {
- DIE *ISP = AI.second;
- if (InlinedSubprogramDIEs.count(ISP))
- continue;
- FirstCU->addUInt(ISP, dwarf::DW_AT_inline, None, dwarf::DW_INL_inlined);
+ NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu");
+ for (MDNode *N : CU_Nodes->operands()) {
+ DICompileUnit TheCU(N);
+ // Construct subprogram DIE and add variables DIEs.
+ DwarfCompileUnit *SPCU =
+ static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
+ DIArray Subprograms = TheCU.getSubprograms();
+ for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) {
+ DISubprogram SP(Subprograms.getElement(i));
+ // Perhaps the subprogram is in another CU (such as due to comdat
+ // folding, etc), in which case ignore it here.
+ if (SPMap[SP] != SPCU)
+ continue;
+ DIE *D = SPCU->getDIE(SP);
+ if (DIE *AbsSPDIE = AbstractSPDies.lookup(SP)) {
+ if (D)
+ // If this subprogram has an abstract definition, reference that
+ SPCU->addDIEEntry(*D, dwarf::DW_AT_abstract_origin, *AbsSPDIE);
+ } else {
+ if (!D)
+ // Lazily construct the subprogram if we didn't see either concrete or
+ // inlined versions during codegen.
+ D = SPCU->getOrCreateSubprogramDIE(SP);
+ // And attach the attributes
+ SPCU->applySubprogramAttributes(SP, *D);
+ SPCU->addGlobalName(SP.getName(), *D, resolve(SP.getContext()));
+ }
+ }
}
}
+
// Collect info for variables that were optimized out.
void DwarfDebug::collectDeadVariables() {
const Module *M = MMI->getModule();
@@ -895,34 +826,32 @@ void DwarfDebug::collectDeadVariables() {
if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {
for (MDNode *N : CU_Nodes->operands()) {
DICompileUnit TheCU(N);
+ // Construct subprogram DIE and add variables DIEs.
+ DwarfCompileUnit *SPCU =
+ static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
+ assert(SPCU && "Unable to find Compile Unit!");
DIArray Subprograms = TheCU.getSubprograms();
for (unsigned i = 0, e = Subprograms.getNumElements(); i != e; ++i) {
DISubprogram SP(Subprograms.getElement(i));
if (ProcessedSPNodes.count(SP) != 0)
continue;
- if (!SP.isSubprogram())
- continue;
- if (!SP.isDefinition())
- continue;
+ assert(SP.isSubprogram() &&
+ "CU's subprogram list contains a non-subprogram");
+ assert(SP.isDefinition() &&
+ "CU's subprogram list contains a subprogram declaration");
DIArray Variables = SP.getVariables();
if (Variables.getNumElements() == 0)
continue;
- // Construct subprogram DIE and add variables DIEs.
- DwarfCompileUnit *SPCU =
- static_cast<DwarfCompileUnit *>(CUMap.lookup(TheCU));
- assert(SPCU && "Unable to find Compile Unit!");
- // FIXME: See the comment in constructSubprogramDIE about duplicate
- // subprogram DIEs.
- constructSubprogramDIE(SPCU, SP);
- DIE *SPDIE = SPCU->getDIE(SP);
+ DIE *SPDIE = AbstractSPDies.lookup(SP);
+ if (!SPDIE)
+ SPDIE = SPCU->getDIE(SP);
+ assert(SPDIE);
for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {
DIVariable DV(Variables.getElement(vi));
- if (!DV.isVariable())
- continue;
- DbgVariable NewVar(DV, NULL, this);
- if (DIE *VariableDIE = SPCU->constructVariableDIE(NewVar, false))
- SPDIE->addChild(VariableDIE);
+ assert(DV.isVariable());
+ DbgVariable NewVar(DV, nullptr, this);
+ SPDIE->addChild(SPCU->constructVariableDIE(NewVar));
}
}
}
@@ -930,28 +859,27 @@ void DwarfDebug::collectDeadVariables() {
}
void DwarfDebug::finalizeModuleInfo() {
+ finishSubprogramDefinitions();
+
// Collect info for variables that were optimized out.
collectDeadVariables();
- // Attach DW_AT_inline attribute with inlined subprogram DIEs.
- computeInlinedDIEs();
-
// Handle anything that needs to be done on a per-unit basis after
// all other generation.
- for (DwarfUnit *TheU : getUnits()) {
+ for (const auto &TheU : getUnits()) {
// Emit DW_AT_containing_type attribute to connect types with their
// vtable holding type.
TheU->constructContainingTypeDIEs();
// Add CU specific attributes if we need to add any.
- if (TheU->getUnitDie()->getTag() == dwarf::DW_TAG_compile_unit) {
+ if (TheU->getUnitDie().getTag() == dwarf::DW_TAG_compile_unit) {
// If we're splitting the dwarf out now that we've got the entire
// CU then add the dwo id to it.
DwarfCompileUnit *SkCU =
static_cast<DwarfCompileUnit *>(TheU->getSkeleton());
if (useSplitDwarf()) {
// Emit a unique identifier for this CU.
- uint64_t ID = DIEHash(Asm).computeCUSignature(*TheU->getUnitDie());
+ uint64_t ID = DIEHash(Asm).computeCUSignature(TheU->getUnitDie());
TheU->addUInt(TheU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
dwarf::DW_FORM_data8, ID);
SkCU->addUInt(SkCU->getUnitDie(), dwarf::DW_AT_GNU_dwo_id,
@@ -959,12 +887,12 @@ void DwarfDebug::finalizeModuleInfo() {
// We don't keep track of which addresses are used in which CU so this
// is a bit pessimistic under LTO.
- if (!InfoHolder.getAddrPool()->empty())
- addSectionLabel(Asm, SkCU, SkCU->getUnitDie(),
+ if (!AddrPool.isEmpty())
+ addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(),
dwarf::DW_AT_GNU_addr_base, DwarfAddrSectionSym,
DwarfAddrSectionSym);
if (!TheU->getRangeLists().empty())
- addSectionLabel(Asm, SkCU, SkCU->getUnitDie(),
+ addSectionLabel(*Asm, *SkCU, SkCU->getUnitDie(),
dwarf::DW_AT_GNU_ranges_base,
DwarfDebugRangeSectionSym, DwarfDebugRangeSectionSym);
}
@@ -975,26 +903,27 @@ void DwarfDebug::finalizeModuleInfo() {
// FIXME: We should use ranges allow reordering of code ala
// .subsections_via_symbols in mach-o. This would mean turning on
// ranges for all subprogram DIEs for mach-o.
- DwarfCompileUnit *U = SkCU ? SkCU : static_cast<DwarfCompileUnit *>(TheU);
+ DwarfCompileUnit &U =
+ SkCU ? *SkCU : static_cast<DwarfCompileUnit &>(*TheU);
unsigned NumRanges = TheU->getRanges().size();
if (NumRanges) {
if (NumRanges > 1) {
- addSectionLabel(Asm, U, U->getUnitDie(), dwarf::DW_AT_ranges,
- Asm->GetTempSymbol("cu_ranges", U->getUniqueID()),
+ addSectionLabel(*Asm, U, U.getUnitDie(), dwarf::DW_AT_ranges,
+ Asm->GetTempSymbol("cu_ranges", U.getUniqueID()),
DwarfDebugRangeSectionSym);
// A DW_AT_low_pc attribute may also be specified in combination with
// DW_AT_ranges to specify the default base address for use in
// location lists (see Section 2.6.2) and range lists (see Section
// 2.17.3).
- U->addUInt(U->getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- 0);
+ U.addUInt(U.getUnitDie(), dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ 0);
} else {
RangeSpan &Range = TheU->getRanges().back();
- U->addLocalLabelAddress(U->getUnitDie(), dwarf::DW_AT_low_pc,
- Range.getStart());
- U->addLabelDelta(U->getUnitDie(), dwarf::DW_AT_high_pc,
- Range.getEnd(), Range.getStart());
+ U.addLocalLabelAddress(U.getUnitDie(), dwarf::DW_AT_low_pc,
+ Range.getStart());
+ U.addLabelDelta(U.getUnitDie(), dwarf::DW_AT_high_pc, Range.getEnd(),
+ Range.getStart());
}
}
}
@@ -1018,7 +947,7 @@ void DwarfDebug::endSections() {
// Some symbols (e.g. common/bss on mach-o) can have no section but still
// appear in the output. This sucks as we rely on sections to build
// arange spans. We can do it without, but it's icky.
- SectionMap[NULL].push_back(SCU);
+ SectionMap[nullptr].push_back(SCU);
}
}
@@ -1036,7 +965,7 @@ void DwarfDebug::endSections() {
// Add terminating symbols for each section.
for (unsigned ID = 0, E = Sections.size(); ID != E; ID++) {
const MCSection *Section = Sections[ID];
- MCSymbol *Sym = NULL;
+ MCSymbol *Sym = nullptr;
if (Section) {
// We can't call MCSection::getLabelEndName, as it's only safe to do so
@@ -1049,14 +978,14 @@ void DwarfDebug::endSections() {
}
// Insert a final terminator.
- SectionMap[Section].push_back(SymbolCU(NULL, Sym));
+ SectionMap[Section].push_back(SymbolCU(nullptr, Sym));
}
}
// Emit all Dwarf sections that should come after the content.
void DwarfDebug::endModule() {
- assert(CurFn == 0);
- assert(CurMI == 0);
+ assert(CurFn == nullptr);
+ assert(CurMI == nullptr);
if (!FirstCU)
return;
@@ -1089,7 +1018,7 @@ void DwarfDebug::endModule() {
emitDebugAbbrevDWO();
emitDebugLineDWO();
// Emit DWO addresses.
- InfoHolder.emitAddresses(Asm->getObjFileLowering().getDwarfAddrSection());
+ AddrPool.emit(*Asm, Asm->getObjFileLowering().getDwarfAddrSection());
emitDebugLocDWO();
} else
// Emit info into a debug loc section.
@@ -1111,29 +1040,34 @@ void DwarfDebug::endModule() {
// clean up.
SPMap.clear();
+ AbstractVariables.clear();
// Reset these for the next Module if we have one.
- FirstCU = NULL;
+ FirstCU = nullptr;
}
// Find abstract variable, if any, associated with Var.
DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
DebugLoc ScopeLoc) {
+ return findAbstractVariable(DV, ScopeLoc.getScope(DV->getContext()));
+}
+
+DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &DV,
+ const MDNode *ScopeNode) {
LLVMContext &Ctx = DV->getContext();
// More then one inlined variable corresponds to one abstract variable.
DIVariable Var = cleanseInlinedVariable(DV, Ctx);
- DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var);
- if (AbsDbgVariable)
- return AbsDbgVariable;
+ auto I = AbstractVariables.find(Var);
+ if (I != AbstractVariables.end())
+ return I->second.get();
- LexicalScope *Scope = LScopes.findAbstractScope(ScopeLoc.getScope(Ctx));
+ LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode);
if (!Scope)
- return NULL;
+ return nullptr;
- AbsDbgVariable = new DbgVariable(Var, NULL, this);
- addScopeVariable(Scope, AbsDbgVariable);
- AbstractVariables[Var] = AbsDbgVariable;
- return AbsDbgVariable;
+ auto AbsDbgVariable = make_unique<DbgVariable>(Var, nullptr, this);
+ addScopeVariable(Scope, AbsDbgVariable.get());
+ return (AbstractVariables[Var] = std::move(AbsDbgVariable)).get();
}
// If Var is a current function argument then add it to CurrentFnArguments list.
@@ -1169,7 +1103,7 @@ void DwarfDebug::collectVariableInfoFromMMITable(
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
// If variable scope is not found then skip this variable.
- if (Scope == 0)
+ if (!Scope)
continue;
DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VI.Loc);
@@ -1177,28 +1111,12 @@ void DwarfDebug::collectVariableInfoFromMMITable(
RegVar->setFrameIndex(VI.Slot);
if (!addCurrentFnArgument(RegVar, Scope))
addScopeVariable(Scope, RegVar);
- if (AbsDbgVariable)
- AbsDbgVariable->setFrameIndex(VI.Slot);
}
}
-// Return true if debug value, encoded by DBG_VALUE instruction, is in a
-// defined reg.
-static bool isDbgValueInDefinedReg(const MachineInstr *MI) {
- assert(MI->isDebugValue() && "Invalid DBG_VALUE machine instruction!");
- return MI->getNumOperands() == 3 && MI->getOperand(0).isReg() &&
- MI->getOperand(0).getReg() &&
- (MI->getOperand(1).isImm() ||
- (MI->getOperand(1).isReg() && MI->getOperand(1).getReg() == 0U));
-}
-
// Get .debug_loc entry for the instruction range starting at MI.
-static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
- const MCSymbol *FLabel,
- const MCSymbol *SLabel,
- const MachineInstr *MI,
- DwarfCompileUnit *Unit) {
- const MDNode *Var = MI->getOperand(MI->getNumOperands() - 1).getMetadata();
+static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
+ const MDNode *Var = MI->getDebugVariable();
assert(MI->getNumOperands() == 3);
if (MI->getOperand(0).isReg()) {
@@ -1209,14 +1127,14 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
MLoc.set(MI->getOperand(0).getReg());
else
MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
- return DebugLocEntry(FLabel, SLabel, MLoc, Var, Unit);
+ return DebugLocEntry::Value(Var, MLoc);
}
if (MI->getOperand(0).isImm())
- return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getImm(), Unit);
+ return DebugLocEntry::Value(Var, MI->getOperand(0).getImm());
if (MI->getOperand(0).isFPImm())
- return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getFPImm(), Unit);
+ return DebugLocEntry::Value(Var, MI->getOperand(0).getFPImm());
if (MI->getOperand(0).isCImm())
- return DebugLocEntry(FLabel, SLabel, MI->getOperand(0).getCImm(), Unit);
+ return DebugLocEntry::Value(Var, MI->getOperand(0).getCImm());
llvm_unreachable("Unexpected 3 operand DBG_VALUE instruction!");
}
@@ -1224,35 +1142,38 @@ static DebugLocEntry getDebugLocEntry(AsmPrinter *Asm,
// Find variables for each lexical scope.
void
DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
+ LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
+ DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMMITable(Processed);
- for (const MDNode *Var : UserVariables) {
- if (Processed.count(Var))
+ for (const auto &I : DbgValues) {
+ DIVariable DV(I.first);
+ if (Processed.count(DV))
continue;
- // History contains relevant DBG_VALUE instructions for Var and instructions
- // clobbering it.
- SmallVectorImpl<const MachineInstr *> &History = DbgValues[Var];
- if (History.empty())
+ // Instruction ranges, specifying where DV is accessible.
+ const auto &Ranges = I.second;
+ if (Ranges.empty())
continue;
- const MachineInstr *MInsn = History.front();
- DIVariable DV(Var);
- LexicalScope *Scope = NULL;
+ LexicalScope *Scope = nullptr;
if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
DISubprogram(DV.getContext()).describes(CurFn->getFunction()))
Scope = LScopes.getCurrentFunctionScope();
- else if (MDNode *IA = DV.getInlinedAt())
- Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA));
- else
- Scope = LScopes.findLexicalScope(cast<MDNode>(DV->getOperand(1)));
+ else if (MDNode *IA = DV.getInlinedAt()) {
+ DebugLoc DL = DebugLoc::getFromDILocation(IA);
+ Scope = LScopes.findInlinedScope(DebugLoc::get(
+ DL.getLine(), DL.getCol(), DV.getContext(), IA));
+ } else
+ Scope = LScopes.findLexicalScope(DV.getContext());
// If variable scope is not found then skip this variable.
if (!Scope)
continue;
Processed.insert(DV);
+ const MachineInstr *MInsn = Ranges.front().first;
assert(MInsn->isDebugValue() && "History must begin with debug value");
DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc());
DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this);
@@ -1261,9 +1182,8 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
if (AbsVar)
AbsVar->setMInsn(MInsn);
- // Simplify ranges that are fully coalesced.
- if (History.size() <= 1 ||
- (History.size() == 2 && MInsn->isIdenticalTo(History.back()))) {
+ // Check if the first DBG_VALUE is valid for the rest of the function.
+ if (Ranges.size() == 1 && Ranges.front().second == nullptr) {
RegVar->setMInsn(MInsn);
continue;
}
@@ -1276,58 +1196,48 @@ DwarfDebug::collectVariableInfo(SmallPtrSet<const MDNode *, 16> &Processed) {
LocList.Label =
Asm->GetTempSymbol("debug_loc", DotDebugLocEntries.size() - 1);
SmallVector<DebugLocEntry, 4> &DebugLoc = LocList.List;
- for (SmallVectorImpl<const MachineInstr *>::const_iterator
- HI = History.begin(),
- HE = History.end();
- HI != HE; ++HI) {
- const MachineInstr *Begin = *HI;
+ for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
+ const MachineInstr *Begin = I->first;
+ const MachineInstr *End = I->second;
assert(Begin->isDebugValue() && "Invalid History entry");
- // Check if DBG_VALUE is truncating a range.
+ // Check if a variable is unaccessible in this range.
if (Begin->getNumOperands() > 1 && Begin->getOperand(0).isReg() &&
!Begin->getOperand(0).getReg())
continue;
- // Compute the range for a register location.
- const MCSymbol *FLabel = getLabelBeforeInsn(Begin);
- const MCSymbol *SLabel = 0;
-
- if (HI + 1 == HE)
- // If Begin is the last instruction in History then its value is valid
- // until the end of the function.
- SLabel = FunctionEndSym;
- else {
- const MachineInstr *End = HI[1];
- DEBUG(dbgs() << "DotDebugLoc Pair:\n"
- << "\t" << *Begin << "\t" << *End << "\n");
- if (End->isDebugValue())
- SLabel = getLabelBeforeInsn(End);
- else {
- // End is a normal instruction clobbering the range.
- SLabel = getLabelAfterInsn(End);
- assert(SLabel && "Forgot label after clobber instruction");
- ++HI;
- }
- }
+ const MCSymbol *StartLabel = getLabelBeforeInsn(Begin);
+ assert(StartLabel && "Forgot label before DBG_VALUE starting a range!");
+
+ const MCSymbol *EndLabel;
+ if (End != nullptr)
+ EndLabel = getLabelAfterInsn(End);
+ else if (std::next(I) == Ranges.end())
+ EndLabel = FunctionEndSym;
+ else
+ EndLabel = getLabelBeforeInsn(std::next(I)->first);
+ assert(EndLabel && "Forgot label after instruction ending a range!");
- // The value is valid until the next DBG_VALUE or clobber.
- LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
- DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
- DebugLocEntry Loc = getDebugLocEntry(Asm, FLabel, SLabel, Begin, TheCU);
+ DEBUG(dbgs() << "DotDebugLoc Pair:\n"
+ << "\t" << *Begin << "\t" << *End << "\n");
+ DebugLocEntry Loc(StartLabel, EndLabel, getDebugLocValue(Begin), TheCU);
if (DebugLoc.empty() || !DebugLoc.back().Merge(Loc))
DebugLoc.push_back(std::move(Loc));
}
}
// Collect info for variables that were optimized out.
- LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
DIArray Variables = DISubprogram(FnScope->getScopeNode()).getVariables();
for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) {
DIVariable DV(Variables.getElement(i));
- if (!DV || !DV.isVariable() || !Processed.insert(DV))
+ assert(DV.isVariable());
+ if (!Processed.insert(DV))
continue;
if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext()))
- addScopeVariable(Scope, new DbgVariable(DV, NULL, this));
+ addScopeVariable(
+ Scope,
+ new DbgVariable(DV, findAbstractVariable(DV, Scope->getScopeNode()),
+ this));
}
}
@@ -1345,7 +1255,7 @@ MCSymbol *DwarfDebug::getLabelAfterInsn(const MachineInstr *MI) {
// Process beginning of an instruction.
void DwarfDebug::beginInstruction(const MachineInstr *MI) {
- assert(CurMI == 0);
+ assert(CurMI == nullptr);
CurMI = MI;
// Check if source location changes, but ignore DBG_VALUE locations.
if (!MI->isDebugValue()) {
@@ -1364,7 +1274,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
} else
- recordSourceLine(0, 0, 0, 0);
+ recordSourceLine(0, 0, nullptr, 0);
}
}
@@ -1389,15 +1299,15 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
// Process end of an instruction.
void DwarfDebug::endInstruction() {
- assert(CurMI != 0);
+ assert(CurMI != nullptr);
// Don't create a new label after DBG_VALUE instructions.
// They don't generate code.
if (!CurMI->isDebugValue())
- PrevLabel = 0;
+ PrevLabel = nullptr;
DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
LabelsAfterInsn.find(CurMI);
- CurMI = 0;
+ CurMI = nullptr;
// No label needed.
if (I == LabelsAfterInsn.end())
@@ -1441,6 +1351,17 @@ void DwarfDebug::identifyScopeMarkers() {
}
}
+static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
+ // First known non-DBG_VALUE and non-frame setup location marks
+ // the beginning of the function body.
+ for (const auto &MBB : *MF)
+ for (const auto &MI : MBB)
+ if (!MI.isDebugValue() && !MI.getFlag(MachineInstr::FrameSetup) &&
+ !MI.getDebugLoc().isUnknown())
+ return MI.getDebugLoc();
+ return DebugLoc();
+}
+
// Gather pre-function debug information. Assumes being called immediately
// after the function entry point has been emitted.
void DwarfDebug::beginFunction(const MachineFunction *MF) {
@@ -1456,7 +1377,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
if (LScopes.empty())
return;
- assert(UserVariables.empty() && DbgValues.empty() && "Maps weren't cleaned");
+ assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
// Make sure that each lexical scope will have a begin/end label.
identifyScopeMarkers();
@@ -1478,144 +1399,26 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
// Assumes in correct section after the entry point.
Asm->OutStreamer.EmitLabel(FunctionBeginSym);
- const TargetRegisterInfo *TRI = Asm->TM.getRegisterInfo();
- // LiveUserVar - Map physreg numbers to the MDNode they contain.
- std::vector<const MDNode *> LiveUserVar(TRI->getNumRegs());
-
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); I != E;
- ++I) {
- bool AtBlockEntry = true;
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- const MachineInstr *MI = II;
-
- if (MI->isDebugValue()) {
- assert(MI->getNumOperands() > 1 && "Invalid machine instruction!");
-
- // Keep track of user variables.
- const MDNode *Var =
- MI->getOperand(MI->getNumOperands() - 1).getMetadata();
-
- // Variable is in a register, we need to check for clobbers.
- if (isDbgValueInDefinedReg(MI))
- LiveUserVar[MI->getOperand(0).getReg()] = Var;
-
- // Check the history of this variable.
- SmallVectorImpl<const MachineInstr *> &History = DbgValues[Var];
- if (History.empty()) {
- UserVariables.push_back(Var);
- // The first mention of a function argument gets the FunctionBeginSym
- // label, so arguments are visible when breaking at function entry.
- DIVariable DV(Var);
- if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable &&
- getDISubprogram(DV.getContext()).describes(MF->getFunction()))
- LabelsBeforeInsn[MI] = FunctionBeginSym;
- } else {
- // We have seen this variable before. Try to coalesce DBG_VALUEs.
- const MachineInstr *Prev = History.back();
- if (Prev->isDebugValue()) {
- // Coalesce identical entries at the end of History.
- if (History.size() >= 2 &&
- Prev->isIdenticalTo(History[History.size() - 2])) {
- DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n"
- << "\t" << *Prev << "\t"
- << *History[History.size() - 2] << "\n");
- History.pop_back();
- }
-
- // Terminate old register assignments that don't reach MI;
- MachineFunction::const_iterator PrevMBB = Prev->getParent();
- if (PrevMBB != I && (!AtBlockEntry || std::next(PrevMBB) != I) &&
- isDbgValueInDefinedReg(Prev)) {
- // Previous register assignment needs to terminate at the end of
- // its basic block.
- MachineBasicBlock::const_iterator LastMI =
- PrevMBB->getLastNonDebugInstr();
- if (LastMI == PrevMBB->end()) {
- // Drop DBG_VALUE for empty range.
- DEBUG(dbgs() << "Dropping DBG_VALUE for empty range:\n"
- << "\t" << *Prev << "\n");
- History.pop_back();
- } else if (std::next(PrevMBB) != PrevMBB->getParent()->end())
- // Terminate after LastMI.
- History.push_back(LastMI);
- }
- }
- }
- History.push_back(MI);
- } else {
- // Not a DBG_VALUE instruction.
- if (!MI->isPosition())
- AtBlockEntry = false;
-
- // First known non-DBG_VALUE and non-frame setup location marks
- // the beginning of the function body.
- if (!MI->getFlag(MachineInstr::FrameSetup) &&
- (PrologEndLoc.isUnknown() && !MI->getDebugLoc().isUnknown()))
- PrologEndLoc = MI->getDebugLoc();
-
- // Check if the instruction clobbers any registers with debug vars.
- for (const MachineOperand &MO : MI->operands()) {
- if (!MO.isReg() || !MO.isDef() || !MO.getReg())
- continue;
- for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid();
- ++AI) {
- unsigned Reg = *AI;
- const MDNode *Var = LiveUserVar[Reg];
- if (!Var)
- continue;
- // Reg is now clobbered.
- LiveUserVar[Reg] = 0;
-
- // Was MD last defined by a DBG_VALUE referring to Reg?
- DbgValueHistoryMap::iterator HistI = DbgValues.find(Var);
- if (HistI == DbgValues.end())
- continue;
- SmallVectorImpl<const MachineInstr *> &History = HistI->second;
- if (History.empty())
- continue;
- const MachineInstr *Prev = History.back();
- // Sanity-check: Register assignments are terminated at the end of
- // their block.
- if (!Prev->isDebugValue() || Prev->getParent() != MI->getParent())
- continue;
- // Is the variable still in Reg?
- if (!isDbgValueInDefinedReg(Prev) ||
- Prev->getOperand(0).getReg() != Reg)
- continue;
- // Var is clobbered. Make sure the next instruction gets a label.
- History.push_back(MI);
- }
- }
- }
- }
- }
+ // Calculate history for local variables.
+ calculateDbgValueHistory(MF, Asm->TM.getRegisterInfo(), DbgValues);
- for (auto &I : DbgValues) {
- SmallVectorImpl<const MachineInstr *> &History = I.second;
- if (History.empty())
+ // Request labels for the full history.
+ for (const auto &I : DbgValues) {
+ const auto &Ranges = I.second;
+ if (Ranges.empty())
continue;
- // Make sure the final register assignments are terminated.
- const MachineInstr *Prev = History.back();
- if (Prev->isDebugValue() && isDbgValueInDefinedReg(Prev)) {
- const MachineBasicBlock *PrevMBB = Prev->getParent();
- MachineBasicBlock::const_iterator LastMI =
- PrevMBB->getLastNonDebugInstr();
- if (LastMI == PrevMBB->end())
- // Drop DBG_VALUE for empty range.
- History.pop_back();
- else if (PrevMBB != &PrevMBB->getParent()->back()) {
- // Terminate after LastMI.
- History.push_back(LastMI);
- }
- }
- // Request labels for the full history.
- for (const MachineInstr *MI : History) {
- if (MI->isDebugValue())
- requestLabelBeforeInsn(MI);
- else
- requestLabelAfterInsn(MI);
+ // The first mention of a function argument gets the FunctionBeginSym
+ // label, so arguments are visible when breaking at function entry.
+ DIVariable DV(I.first);
+ if (DV.isVariable() && DV.getTag() == dwarf::DW_TAG_arg_variable &&
+ getDISubprogram(DV.getContext()).describes(MF->getFunction()))
+ LabelsBeforeInsn[Ranges.front().first] = FunctionBeginSym;
+
+ for (const auto &Range : Ranges) {
+ requestLabelBeforeInsn(Range.first);
+ if (Range.second)
+ requestLabelAfterInsn(Range.second);
}
}
@@ -1623,6 +1426,7 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
PrevLabel = FunctionBeginSym;
// Record beginning of function.
+ PrologEndLoc = findPrologueEndLoc(MF);
if (!PrologEndLoc.isUnknown()) {
DebugLoc FnStartDL =
PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext());
@@ -1671,11 +1475,11 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
// Every beginFunction(MF) call should be followed by an endFunction(MF) call,
// though the beginFunction may not be called at all.
// We should handle both cases.
- if (CurFn == 0)
+ if (!CurFn)
CurFn = MF;
else
assert(CurFn == MF);
- assert(CurFn != 0);
+ assert(CurFn != nullptr);
if (!MMI->hasDebugInfo() || LScopes.empty()) {
// If we don't have a lexical scope for this function then there will
@@ -1683,7 +1487,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
// previously used section to nullptr.
PrevSection = nullptr;
PrevCU = nullptr;
- CurFn = 0;
+ CurFn = nullptr;
return;
}
@@ -1699,55 +1503,50 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
collectVariableInfo(ProcessedVars);
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
- DwarfCompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
- assert(TheCU && "Unable to find compile unit!");
+ DwarfCompileUnit &TheCU = *SPMap.lookup(FnScope->getScopeNode());
// Construct abstract scopes.
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
DISubprogram SP(AScope->getScopeNode());
- if (SP.isSubprogram()) {
- // Collect info for variables that were optimized out.
- DIArray Variables = SP.getVariables();
- for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) {
- DIVariable DV(Variables.getElement(i));
- if (!DV || !DV.isVariable() || !ProcessedVars.insert(DV))
- continue;
- // Check that DbgVariable for DV wasn't created earlier, when
- // findAbstractVariable() was called for inlined instance of DV.
- LLVMContext &Ctx = DV->getContext();
- DIVariable CleanDV = cleanseInlinedVariable(DV, Ctx);
- if (AbstractVariables.lookup(CleanDV))
- continue;
- if (LexicalScope *Scope = LScopes.findAbstractScope(DV.getContext()))
- addScopeVariable(Scope, new DbgVariable(DV, NULL, this));
- }
+ if (!SP.isSubprogram())
+ continue;
+ // Collect info for variables that were optimized out.
+ DIArray Variables = SP.getVariables();
+ for (unsigned i = 0, e = Variables.getNumElements(); i != e; ++i) {
+ DIVariable DV(Variables.getElement(i));
+ assert(DV && DV.isVariable());
+ if (!ProcessedVars.insert(DV))
+ continue;
+ findAbstractVariable(DV, DV.getContext());
}
- if (ProcessedSPNodes.count(AScope->getScopeNode()) == 0)
- constructScopeDIE(TheCU, AScope);
+ constructAbstractSubprogramScopeDIE(TheCU, AScope);
}
- DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope);
+ DIE &CurFnDIE = constructSubprogramScopeDIE(TheCU, FnScope);
if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn))
- TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
+ TheCU.addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
// Add the range of this function to the list of ranges for the CU.
RangeSpan Span(FunctionBeginSym, FunctionEndSym);
- TheCU->addRange(std::move(Span));
+ TheCU.addRange(std::move(Span));
PrevSection = Asm->getCurrentSection();
- PrevCU = TheCU;
+ PrevCU = &TheCU;
// Clear debug info
- for (auto &I : ScopeVariables)
- DeleteContainerPointers(I.second);
+ // Ownership of DbgVariables is a bit subtle - ScopeVariables owns all the
+ // DbgVariables except those that are also in AbstractVariables (since they
+ // can be used cross-function)
+ for (const auto &I : ScopeVariables)
+ for (const auto *Var : I.second)
+ if (!AbstractVariables.count(Var->getVariable()) || Var->getAbstractVariable())
+ delete Var;
ScopeVariables.clear();
DeleteContainerPointers(CurrentFnArguments);
- UserVariables.clear();
DbgValues.clear();
- AbstractVariables.clear();
LabelsBeforeInsn.clear();
LabelsAfterInsn.clear();
- PrevLabel = NULL;
- CurFn = 0;
+ PrevLabel = nullptr;
+ CurFn = nullptr;
}
// Register a source line with debug info. Returns the unique label that was
@@ -1758,36 +1557,16 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
StringRef Dir;
unsigned Src = 1;
unsigned Discriminator = 0;
- if (S) {
- DIDescriptor Scope(S);
-
- if (Scope.isCompileUnit()) {
- DICompileUnit CU(S);
- Fn = CU.getFilename();
- Dir = CU.getDirectory();
- } else if (Scope.isFile()) {
- DIFile F(S);
- Fn = F.getFilename();
- Dir = F.getDirectory();
- } else if (Scope.isSubprogram()) {
- DISubprogram SP(S);
- Fn = SP.getFilename();
- Dir = SP.getDirectory();
- } else if (Scope.isLexicalBlockFile()) {
- DILexicalBlockFile DBF(S);
- Fn = DBF.getFilename();
- Dir = DBF.getDirectory();
- } else if (Scope.isLexicalBlock()) {
- DILexicalBlock DB(S);
- Fn = DB.getFilename();
- Dir = DB.getDirectory();
- Discriminator = DB.getDiscriminator();
- } else
- llvm_unreachable("Unexpected scope info");
+ if (DIScope Scope = DIScope(S)) {
+ assert(Scope.isScope());
+ Fn = Scope.getFilename();
+ Dir = Scope.getDirectory();
+ if (Scope.isLexicalBlock())
+ Discriminator = DILexicalBlock(S).getDiscriminator();
unsigned CUID = Asm->OutStreamer.getContext().getDwarfCompileUnitID();
- Src = static_cast<DwarfCompileUnit *>(InfoHolder.getUnits()[CUID])
- ->getOrCreateSourceID(Fn, Dir);
+ Src = static_cast<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])
+ .getOrCreateSourceID(Fn, Dir);
}
Asm->OutStreamer.EmitDwarfLocDirective(Src, Line, Col, Flags, 0,
Discriminator, Fn);
@@ -1797,68 +1576,6 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
// Emit Methods
//===----------------------------------------------------------------------===//
-// Compute the size and offset of a DIE. The offset is relative to start of the
-// CU. It returns the offset after laying out the DIE.
-unsigned DwarfFile::computeSizeAndOffset(DIE *Die, unsigned Offset) {
- // Record the abbreviation.
- assignAbbrevNumber(Die->getAbbrev());
-
- // Get the abbreviation for this DIE.
- const DIEAbbrev &Abbrev = Die->getAbbrev();
-
- // Set DIE offset
- Die->setOffset(Offset);
-
- // Start the size with the size of abbreviation code.
- Offset += getULEB128Size(Die->getAbbrevNumber());
-
- const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
- const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
-
- // Size the DIE attribute values.
- for (unsigned i = 0, N = Values.size(); i < N; ++i)
- // Size attribute value.
- Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
-
- // Get the children.
- const std::vector<DIE *> &Children = Die->getChildren();
-
- // Size the DIE children if any.
- if (!Children.empty()) {
- assert(Abbrev.hasChildren() && "Children flag not set");
-
- for (DIE *Child : Children)
- Offset = computeSizeAndOffset(Child, Offset);
-
- // End of children marker.
- Offset += sizeof(int8_t);
- }
-
- Die->setSize(Offset - Die->getOffset());
- return Offset;
-}
-
-// Compute the size and offset for each DIE.
-void DwarfFile::computeSizeAndOffsets() {
- // Offset from the first CU in the debug info section is 0 initially.
- unsigned SecOffset = 0;
-
- // Iterate over each compile unit and set the size and offsets for each
- // DIE within each compile unit. All offsets are CU relative.
- for (DwarfUnit *TheU : CUs) {
- TheU->setDebugInfoOffset(SecOffset);
-
- // CU-relative offset is reset to 0 here.
- unsigned Offset = sizeof(int32_t) + // Length of Unit Info
- TheU->getHeaderSize(); // Unit-specific headers
-
- // EndOffset here is CU-relative, after laying out
- // all of the CU DIE.
- unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset);
- SecOffset += EndOffset;
- }
-}
-
// Emit initial Dwarf sections with a label at the start of each one.
void DwarfDebug::emitSectionLabels() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
@@ -1906,19 +1623,19 @@ void DwarfDebug::emitSectionLabels() {
}
// Recursively emits a debug information entry.
-void DwarfDebug::emitDIE(DIE *Die) {
+void DwarfDebug::emitDIE(DIE &Die) {
// Get the abbreviation for this DIE.
- const DIEAbbrev &Abbrev = Die->getAbbrev();
+ const DIEAbbrev &Abbrev = Die.getAbbrev();
// Emit the code (index) for the abbreviation.
if (Asm->isVerbose())
Asm->OutStreamer.AddComment("Abbrev [" + Twine(Abbrev.getNumber()) +
- "] 0x" + Twine::utohexstr(Die->getOffset()) +
- ":0x" + Twine::utohexstr(Die->getSize()) + " " +
+ "] 0x" + Twine::utohexstr(Die.getOffset()) +
+ ":0x" + Twine::utohexstr(Die.getSize()) + " " +
dwarf::TagString(Abbrev.getTag()));
Asm->EmitULEB128(Abbrev.getNumber());
- const SmallVectorImpl<DIEValue *> &Values = Die->getValues();
+ const SmallVectorImpl<DIEValue *> &Values = Die.getValues();
const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
// Emit the DIE attribute values.
@@ -1940,38 +1657,14 @@ void DwarfDebug::emitDIE(DIE *Die) {
// Emit the DIE children if any.
if (Abbrev.hasChildren()) {
- const std::vector<DIE *> &Children = Die->getChildren();
-
- for (DIE *Child : Children)
- emitDIE(Child);
+ for (auto &Child : Die.getChildren())
+ emitDIE(*Child);
Asm->OutStreamer.AddComment("End Of Children Mark");
Asm->EmitInt8(0);
}
}
-// Emit the various dwarf units to the unit section USection with
-// the abbreviations going into ASection.
-void DwarfFile::emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym) {
- for (DwarfUnit *TheU : CUs) {
- DIE *Die = TheU->getUnitDie();
- const MCSection *USection = TheU->getSection();
- Asm->OutStreamer.SwitchSection(USection);
-
- // Emit the compile units header.
- Asm->OutStreamer.EmitLabel(TheU->getLabelBegin());
-
- // Emit size of content not including length itself
- Asm->OutStreamer.AddComment("Length of Unit");
- Asm->EmitInt32(TheU->getHeaderSize() + Die->getSize());
-
- TheU->emitHeader(ASectionSym);
-
- DD->emitDIE(Die);
- Asm->OutStreamer.EmitLabel(TheU->getLabelEnd());
- }
-}
-
// Emit the debug info section.
void DwarfDebug::emitDebugInfo() {
DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
@@ -1986,26 +1679,6 @@ void DwarfDebug::emitAbbreviations() {
Holder.emitAbbrevs(Asm->getObjFileLowering().getDwarfAbbrevSection());
}
-void DwarfFile::emitAbbrevs(const MCSection *Section) {
- // Check to see if it is worth the effort.
- if (!Abbreviations.empty()) {
- // Start the debug abbrev section.
- Asm->OutStreamer.SwitchSection(Section);
-
- // For each abbrevation.
- for (const DIEAbbrev *Abbrev : Abbreviations) {
- // Emit the abbrevations code (base 1 index.)
- Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
-
- // Emit the abbreviations data.
- Abbrev->Emit(Asm);
- }
-
- // Mark end of abbreviations.
- Asm->EmitULEB128(0, "EOM(3)");
- }
-}
-
// Emit the last address of the section and the end of the line matrix.
void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
// Define last address of section.
@@ -2032,97 +1705,52 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
// Emit visible names into a hashed accelerator table section.
void DwarfDebug::emitAccelNames() {
- DwarfAccelTable AT(
- DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- for (DwarfUnit *TheU : getUnits()) {
- for (const auto &GI : TheU->getAccelNames()) {
- StringRef Name = GI.getKey();
- for (const DIE *D : GI.second)
- AT.AddName(Name, D);
- }
- }
-
- AT.FinalizeTable(Asm, "Names");
+ AccelNames.FinalizeTable(Asm, "Names");
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAccelNamesSection());
MCSymbol *SectionBegin = Asm->GetTempSymbol("names_begin");
Asm->OutStreamer.EmitLabel(SectionBegin);
// Emit the full data.
- AT.Emit(Asm, SectionBegin, &InfoHolder);
+ AccelNames.Emit(Asm, SectionBegin, &InfoHolder);
}
// Emit objective C classes and categories into a hashed accelerator table
// section.
void DwarfDebug::emitAccelObjC() {
- DwarfAccelTable AT(
- DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- for (DwarfUnit *TheU : getUnits()) {
- for (const auto &GI : TheU->getAccelObjC()) {
- StringRef Name = GI.getKey();
- for (const DIE *D : GI.second)
- AT.AddName(Name, D);
- }
- }
-
- AT.FinalizeTable(Asm, "ObjC");
+ AccelObjC.FinalizeTable(Asm, "ObjC");
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAccelObjCSection());
MCSymbol *SectionBegin = Asm->GetTempSymbol("objc_begin");
Asm->OutStreamer.EmitLabel(SectionBegin);
// Emit the full data.
- AT.Emit(Asm, SectionBegin, &InfoHolder);
+ AccelObjC.Emit(Asm, SectionBegin, &InfoHolder);
}
// Emit namespace dies into a hashed accelerator table.
void DwarfDebug::emitAccelNamespaces() {
- DwarfAccelTable AT(
- DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- for (DwarfUnit *TheU : getUnits()) {
- for (const auto &GI : TheU->getAccelNamespace()) {
- StringRef Name = GI.getKey();
- for (const DIE *D : GI.second)
- AT.AddName(Name, D);
- }
- }
-
- AT.FinalizeTable(Asm, "namespac");
+ AccelNamespace.FinalizeTable(Asm, "namespac");
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAccelNamespaceSection());
MCSymbol *SectionBegin = Asm->GetTempSymbol("namespac_begin");
Asm->OutStreamer.EmitLabel(SectionBegin);
// Emit the full data.
- AT.Emit(Asm, SectionBegin, &InfoHolder);
+ AccelNamespace.Emit(Asm, SectionBegin, &InfoHolder);
}
// Emit type dies into a hashed accelerator table.
void DwarfDebug::emitAccelTypes() {
- std::vector<DwarfAccelTable::Atom> Atoms;
- Atoms.push_back(
- DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4));
- Atoms.push_back(
- DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2));
- Atoms.push_back(
- DwarfAccelTable::Atom(dwarf::DW_ATOM_type_flags, dwarf::DW_FORM_data1));
- DwarfAccelTable AT(Atoms);
- for (DwarfUnit *TheU : getUnits()) {
- for (const auto &GI : TheU->getAccelTypes()) {
- StringRef Name = GI.getKey();
- for (const auto &DI : GI.second)
- AT.AddName(Name, DI.first, DI.second);
- }
- }
- AT.FinalizeTable(Asm, "types");
+ AccelTypes.FinalizeTable(Asm, "types");
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAccelTypesSection());
MCSymbol *SectionBegin = Asm->GetTempSymbol("types_begin");
Asm->OutStreamer.EmitLabel(SectionBegin);
// Emit the full data.
- AT.Emit(Asm, SectionBegin, &InfoHolder);
+ AccelTypes.Emit(Asm, SectionBegin, &InfoHolder);
}
// Public name handling.
@@ -2148,8 +1776,8 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,
// look for that now.
DIEValue *SpecVal = Die->findAttribute(dwarf::DW_AT_specification);
if (SpecVal) {
- DIE *SpecDIE = cast<DIEEntry>(SpecVal)->getEntry();
- if (SpecDIE->findAttribute(dwarf::DW_AT_external))
+ DIE &SpecDIE = cast<DIEEntry>(SpecVal)->getEntry();
+ if (SpecDIE.findAttribute(dwarf::DW_AT_external))
Linkage = dwarf::GIEL_EXTERNAL;
} else if (Die->findAttribute(dwarf::DW_AT_external))
Linkage = dwarf::GIEL_EXTERNAL;
@@ -2261,69 +1889,6 @@ void DwarfDebug::emitDebugPubTypes(bool GnuStyle) {
emitDebugPubSection(GnuStyle, PSec, "Types", &DwarfUnit::getGlobalTypes);
}
-// Emit strings into a string section.
-void DwarfFile::emitStrings(const MCSection *StrSection,
- const MCSection *OffsetSection = NULL,
- const MCSymbol *StrSecSym = NULL) {
-
- if (StringPool.empty())
- return;
-
- // Start the dwarf str section.
- Asm->OutStreamer.SwitchSection(StrSection);
-
- // Get all of the string pool entries and put them in an array by their ID so
- // we can sort them.
- SmallVector<std::pair<unsigned, const StrPool::value_type *>, 64 > Entries;
-
- for (const auto &I : StringPool)
- Entries.push_back(std::make_pair(I.second.second, &I));
-
- array_pod_sort(Entries.begin(), Entries.end());
-
- for (const auto &Entry : Entries) {
- // Emit a label for reference from debug information entries.
- Asm->OutStreamer.EmitLabel(Entry.second->getValue().first);
-
- // Emit the string itself with a terminating null byte.
- Asm->OutStreamer.EmitBytes(StringRef(Entry.second->getKeyData(),
- Entry.second->getKeyLength() + 1));
- }
-
- // If we've got an offset section go ahead and emit that now as well.
- if (OffsetSection) {
- Asm->OutStreamer.SwitchSection(OffsetSection);
- unsigned offset = 0;
- unsigned size = 4; // FIXME: DWARF64 is 8.
- for (const auto &Entry : Entries) {
- Asm->OutStreamer.EmitIntValue(offset, size);
- offset += Entry.second->getKeyLength() + 1;
- }
- }
-}
-
-// Emit addresses into the section given.
-void DwarfFile::emitAddresses(const MCSection *AddrSection) {
-
- if (AddressPool.empty())
- return;
-
- // Start the dwarf addr section.
- Asm->OutStreamer.SwitchSection(AddrSection);
-
- // Order the address pool entries by ID
- SmallVector<const MCExpr *, 64> Entries(AddressPool.size());
-
- for (const auto &I : AddressPool)
- Entries[I.second.Number] =
- I.second.TLS
- ? Asm->getObjFileLowering().getDebugThreadLocalSymbol(I.first)
- : MCSymbolRefExpr::Create(I.first, Asm->OutContext);
-
- for (const MCExpr *Entry : Entries)
- Asm->OutStreamer.EmitValue(Entry, Asm->getDataLayout().getPointerSize());
-}
-
// Emit visible names into a debug str section.
void DwarfDebug::emitDebugStr() {
DwarfFile &Holder = useSplitDwarf() ? SkeletonHolder : InfoHolder;
@@ -2332,19 +1897,22 @@ void DwarfDebug::emitDebugStr() {
void DwarfDebug::emitDebugLocEntry(ByteStreamer &Streamer,
const DebugLocEntry &Entry) {
- DIVariable DV(Entry.getVariable());
- if (Entry.isInt()) {
+ assert(Entry.getValues().size() == 1 &&
+ "multi-value entries are not supported yet.");
+ const DebugLocEntry::Value Value = Entry.getValues()[0];
+ DIVariable DV(Value.getVariable());
+ if (Value.isInt()) {
DIBasicType BTy(resolve(DV.getType()));
if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
BTy.getEncoding() == dwarf::DW_ATE_signed_char)) {
Streamer.EmitInt8(dwarf::DW_OP_consts, "DW_OP_consts");
- Streamer.EmitSLEB128(Entry.getInt());
+ Streamer.EmitSLEB128(Value.getInt());
} else {
Streamer.EmitInt8(dwarf::DW_OP_constu, "DW_OP_constu");
- Streamer.EmitULEB128(Entry.getInt());
+ Streamer.EmitULEB128(Value.getInt());
}
- } else if (Entry.isLocation()) {
- MachineLocation Loc = Entry.getLoc();
+ } else if (Value.isLocation()) {
+ MachineLocation Loc = Value.getLoc();
if (!DV.hasComplexAddress())
// Regular entry.
Asm->EmitDwarfRegOp(Streamer, Loc, DV.isIndirect());
@@ -2443,7 +2011,7 @@ void DwarfDebug::emitDebugLocDWO() {
// address we know we've emitted elsewhere (the start of the function?
// The start of the CU or CU subrange that encloses this range?)
Asm->EmitInt8(dwarf::DW_LLE_start_length_entry);
- unsigned idx = InfoHolder.getAddrPoolIndex(Entry.getBeginSym());
+ unsigned idx = AddrPool.getIndex(Entry.getBeginSym());
Asm->EmitULEB128(idx);
Asm->EmitLabelDifference(Entry.getEndSym(), Entry.getBeginSym(), 4);
@@ -2464,7 +2032,7 @@ void DwarfDebug::emitDebugARanges() {
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfARangesSection());
- typedef DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan> > SpansType;
+ typedef DenseMap<DwarfCompileUnit *, std::vector<ArangeSpan>> SpansType;
SpansType Spans;
@@ -2502,11 +2070,11 @@ void DwarfDebug::emitDebugARanges() {
// If we have no section (e.g. common), just write out
// individual spans for each symbol.
- if (Section == NULL) {
+ if (!Section) {
for (const SymbolCU &Cur : List) {
ArangeSpan Span;
Span.Start = Cur.Sym;
- Span.End = NULL;
+ Span.End = nullptr;
if (Cur.CU)
Spans[Cur.CU].push_back(Span);
}
@@ -2613,9 +2181,6 @@ void DwarfDebug::emitDebugRanges() {
for (const auto &I : CUMap) {
DwarfCompileUnit *TheCU = I.second;
- // Emit a symbol so we can find the beginning of our ranges.
- Asm->OutStreamer.EmitLabel(TheCU->getLabelRange());
-
// Iterate over the misc ranges for the compile units in the module.
for (const RangeSpanList &List : TheCU->getRangeLists()) {
// Emit our symbol so we can find the beginning of the range.
@@ -2626,8 +2191,15 @@ void DwarfDebug::emitDebugRanges() {
const MCSymbol *End = Range.getEnd();
assert(Begin && "Range without a begin symbol?");
assert(End && "Range without an end symbol?");
- Asm->OutStreamer.EmitSymbolValue(Begin, Size);
- Asm->OutStreamer.EmitSymbolValue(End, Size);
+ if (TheCU->getRanges().size() == 1) {
+ // Grab the begin symbol from the first range as our base.
+ const MCSymbol *Base = TheCU->getRanges()[0].getStart();
+ Asm->EmitLabelDifference(Begin, Base, Size);
+ Asm->EmitLabelDifference(End, Base, Size);
+ } else {
+ Asm->OutStreamer.EmitSymbolValue(Begin, Size);
+ Asm->OutStreamer.EmitSymbolValue(End, Size);
+ }
}
// And terminate the list with two 0 values.
@@ -2656,52 +2228,52 @@ void DwarfDebug::emitDebugRanges() {
// DWARF5 Experimental Separate Dwarf emitters.
-void DwarfDebug::initSkeletonUnit(const DwarfUnit *U, DIE *Die,
- DwarfUnit *NewU) {
+void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
+ std::unique_ptr<DwarfUnit> NewU) {
NewU->addLocalString(Die, dwarf::DW_AT_GNU_dwo_name,
- U->getCUNode().getSplitDebugFilename());
+ U.getCUNode().getSplitDebugFilename());
if (!CompilationDir.empty())
NewU->addLocalString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
- addGnuPubAttributes(NewU, Die);
+ addGnuPubAttributes(*NewU, Die);
- SkeletonHolder.addUnit(NewU);
+ SkeletonHolder.addUnit(std::move(NewU));
}
// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_stmt_list,
// DW_AT_low_pc, DW_AT_high_pc, DW_AT_ranges, DW_AT_dwo_name, DW_AT_dwo_id,
// DW_AT_addr_base, DW_AT_ranges_base.
-DwarfCompileUnit *DwarfDebug::constructSkeletonCU(const DwarfCompileUnit *CU) {
+DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {
- DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
- DwarfCompileUnit *NewCU = new DwarfCompileUnit(
- CU->getUniqueID(), Die, CU->getCUNode(), Asm, this, &SkeletonHolder);
- NewCU->initSection(Asm->getObjFileLowering().getDwarfInfoSection(),
- DwarfInfoSectionSym);
+ auto OwnedUnit = make_unique<DwarfCompileUnit>(
+ CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder);
+ DwarfCompileUnit &NewCU = *OwnedUnit;
+ NewCU.initSection(Asm->getObjFileLowering().getDwarfInfoSection(),
+ DwarfInfoSectionSym);
- NewCU->initStmtList(DwarfLineSectionSym);
+ NewCU.initStmtList(DwarfLineSectionSym);
- initSkeletonUnit(CU, Die, NewCU);
+ initSkeletonUnit(CU, NewCU.getUnitDie(), std::move(OwnedUnit));
return NewCU;
}
// This DIE has the following attributes: DW_AT_comp_dir, DW_AT_dwo_name,
// DW_AT_addr_base.
-DwarfTypeUnit *DwarfDebug::constructSkeletonTU(DwarfTypeUnit *TU) {
+DwarfTypeUnit &DwarfDebug::constructSkeletonTU(DwarfTypeUnit &TU) {
DwarfCompileUnit &CU = static_cast<DwarfCompileUnit &>(
- *SkeletonHolder.getUnits()[TU->getCU().getUniqueID()]);
+ *SkeletonHolder.getUnits()[TU.getCU().getUniqueID()]);
- DIE *Die = new DIE(dwarf::DW_TAG_type_unit);
- DwarfTypeUnit *NewTU =
- new DwarfTypeUnit(TU->getUniqueID(), Die, CU, Asm, this, &SkeletonHolder);
- NewTU->setTypeSignature(TU->getTypeSignature());
- NewTU->setType(NULL);
- NewTU->initSection(
- Asm->getObjFileLowering().getDwarfTypesSection(TU->getTypeSignature()));
+ auto OwnedUnit = make_unique<DwarfTypeUnit>(TU.getUniqueID(), CU, Asm, this,
+ &SkeletonHolder);
+ DwarfTypeUnit &NewTU = *OwnedUnit;
+ NewTU.setTypeSignature(TU.getTypeSignature());
+ NewTU.setType(nullptr);
+ NewTU.initSection(
+ Asm->getObjFileLowering().getDwarfTypesSection(TU.getTypeSignature()));
- initSkeletonUnit(TU, Die, NewTU);
+ initSkeletonUnit(TU, NewTU.getUnitDie(), std::move(OwnedUnit));
return NewTU;
}
@@ -2711,7 +2283,7 @@ void DwarfDebug::emitDebugInfoDWO() {
assert(useSplitDwarf() && "No split dwarf debug info?");
// Don't pass an abbrev symbol, using a constant zero instead so as not to
// emit relocations into the dwo file.
- InfoHolder.emitUnits(this, /* AbbrevSymbol */nullptr);
+ InfoHolder.emitUnits(this, /* AbbrevSymbol */ nullptr);
}
// Emit the .debug_abbrev.dwo section for separated dwarf. This contains the
@@ -2748,14 +2320,25 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
return &SplitTypeUnitFileTable;
}
+static uint64_t makeTypeSignature(StringRef Identifier) {
+ MD5 Hash;
+ Hash.update(Identifier);
+ // ... take the least significant 8 bytes and return those. Our MD5
+ // implementation always returns its results in little endian, swap bytes
+ // appropriately.
+ MD5::MD5Result Result;
+ Hash.final(Result);
+ return *reinterpret_cast<support::ulittle64_t *>(Result + 8);
+}
+
void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
- StringRef Identifier, DIE *RefDie,
+ StringRef Identifier, DIE &RefDie,
DICompositeType CTy) {
- // Flag the type unit reference as a declaration so that if it contains
- // members (implicit special members, static data member definitions, member
- // declarations for definitions in this CU, etc) consumers don't get confused
- // and think this is a full definition.
- CU.addFlag(RefDie, dwarf::DW_AT_declaration);
+ // Fast path if we're building some type units and one has already used the
+ // address pool we know we're going to throw away all this work anyway, so
+ // don't bother building dependent types.
+ if (!TypeUnitsUnderConstruction.empty() && AddrPool.hasBeenUsed())
+ return;
const DwarfTypeUnit *&TU = DwarfTypeUnits[CTy];
if (TU) {
@@ -2763,45 +2346,111 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
return;
}
- DIE *UnitDie = new DIE(dwarf::DW_TAG_type_unit);
- DwarfTypeUnit *NewTU =
- new DwarfTypeUnit(InfoHolder.getUnits().size(), UnitDie, CU, Asm, this,
- &InfoHolder, getDwoLineTable(CU));
- TU = NewTU;
- InfoHolder.addUnit(NewTU);
+ bool TopLevelType = TypeUnitsUnderConstruction.empty();
+ AddrPool.resetUsedFlag();
- NewTU->addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
- CU.getLanguage());
+ auto OwnedUnit =
+ make_unique<DwarfTypeUnit>(InfoHolder.getUnits().size(), CU, Asm, this,
+ &InfoHolder, getDwoLineTable(CU));
+ DwarfTypeUnit &NewTU = *OwnedUnit;
+ DIE &UnitDie = NewTU.getUnitDie();
+ TU = &NewTU;
+ TypeUnitsUnderConstruction.push_back(
+ std::make_pair(std::move(OwnedUnit), CTy));
- MD5 Hash;
- Hash.update(Identifier);
- // ... take the least significant 8 bytes and return those. Our MD5
- // implementation always returns its results in little endian, swap bytes
- // appropriately.
- MD5::MD5Result Result;
- Hash.final(Result);
- uint64_t Signature = *reinterpret_cast<support::ulittle64_t *>(Result + 8);
- NewTU->setTypeSignature(Signature);
- if (useSplitDwarf())
- NewTU->setSkeleton(constructSkeletonTU(NewTU));
- else
- CU.applyStmtList(*UnitDie);
+ NewTU.addUInt(UnitDie, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
+ CU.getLanguage());
- NewTU->setType(NewTU->createTypeDIE(CTy));
+ uint64_t Signature = makeTypeSignature(Identifier);
+ NewTU.setTypeSignature(Signature);
- NewTU->initSection(
+ if (!useSplitDwarf())
+ CU.applyStmtList(UnitDie);
+
+ // FIXME: Skip using COMDAT groups for type units in the .dwo file once tools
+ // such as DWP ( http://gcc.gnu.org/wiki/DebugFissionDWP ) can cope with it.
+ NewTU.initSection(
useSplitDwarf()
? Asm->getObjFileLowering().getDwarfTypesDWOSection(Signature)
: Asm->getObjFileLowering().getDwarfTypesSection(Signature));
- CU.addDIETypeSignature(RefDie, *NewTU);
+ NewTU.setType(NewTU.createTypeDIE(CTy));
+
+ if (TopLevelType) {
+ auto TypeUnitsToAdd = std::move(TypeUnitsUnderConstruction);
+ TypeUnitsUnderConstruction.clear();
+
+ // Types referencing entries in the address table cannot be placed in type
+ // units.
+ if (AddrPool.hasBeenUsed()) {
+
+ // Remove all the types built while building this type.
+ // This is pessimistic as some of these types might not be dependent on
+ // the type that used an address.
+ for (const auto &TU : TypeUnitsToAdd)
+ DwarfTypeUnits.erase(TU.second);
+
+ // Construct this type in the CU directly.
+ // This is inefficient because all the dependent types will be rebuilt
+ // from scratch, including building them in type units, discovering that
+ // they depend on addresses, throwing them out and rebuilding them.
+ CU.constructTypeDIE(RefDie, CTy);
+ return;
+ }
+
+ // If the type wasn't dependent on fission addresses, finish adding the type
+ // and all its dependent types.
+ for (auto &TU : TypeUnitsToAdd) {
+ if (useSplitDwarf())
+ TU.first->setSkeleton(constructSkeletonTU(*TU.first));
+ InfoHolder.addUnit(std::move(TU.first));
+ }
+ }
+ CU.addDIETypeSignature(RefDie, NewTU);
}
-void DwarfDebug::attachLowHighPC(DwarfCompileUnit *Unit, DIE *D,
+void DwarfDebug::attachLowHighPC(DwarfCompileUnit &Unit, DIE &D,
MCSymbol *Begin, MCSymbol *End) {
- Unit->addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
+ assert(Begin && "Begin label should not be null!");
+ assert(End && "End label should not be null!");
+ assert(Begin->isDefined() && "Invalid starting label");
+ assert(End->isDefined() && "Invalid end label");
+
+ Unit.addLabelAddress(D, dwarf::DW_AT_low_pc, Begin);
if (DwarfVersion < 4)
- Unit->addLabelAddress(D, dwarf::DW_AT_high_pc, End);
+ Unit.addLabelAddress(D, dwarf::DW_AT_high_pc, End);
else
- Unit->addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
+ Unit.addLabelDelta(D, dwarf::DW_AT_high_pc, End, Begin);
+}
+
+// Accelerator table mutators - add each name along with its companion
+// DIE to the proper table while ensuring that the name that we're going
+// to reference is in the string table. We do this since the names we
+// add may not only be identical to the names in the DIE.
+void DwarfDebug::addAccelName(StringRef Name, const DIE &Die) {
+ if (!useDwarfAccelTables())
+ return;
+ AccelNames.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
+ &Die);
+}
+
+void DwarfDebug::addAccelObjC(StringRef Name, const DIE &Die) {
+ if (!useDwarfAccelTables())
+ return;
+ AccelObjC.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
+ &Die);
+}
+
+void DwarfDebug::addAccelNamespace(StringRef Name, const DIE &Die) {
+ if (!useDwarfAccelTables())
+ return;
+ AccelNamespace.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
+ &Die);
+}
+
+void DwarfDebug::addAccelType(StringRef Name, const DIE &Die, char Flags) {
+ if (!useDwarfAccelTables())
+ return;
+ AccelTypes.AddName(Name, InfoHolder.getStringPool().getSymbol(*Asm, Name),
+ &Die);
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index da708f5..2f5abc8 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -14,10 +14,13 @@
#ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
+#include "DwarfFile.h"
#include "AsmPrinterHandler.h"
#include "DIE.h"
+#include "DbgValueHistoryCalculator.h"
#include "DebugLocEntry.h"
#include "DebugLocList.h"
+#include "DwarfAccelTable.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -30,6 +33,8 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/Support/Allocator.h"
+#include <memory>
+
namespace llvm {
class AsmPrinter;
@@ -74,12 +79,12 @@ class DbgVariable {
public:
// AbsVar may be NULL.
DbgVariable(DIVariable V, DbgVariable *AV, DwarfDebug *DD)
- : Var(V), TheDIE(0), DotDebugLocOffset(~0U), AbsVar(AV), MInsn(0),
- FrameIndex(~0), DD(DD) {}
+ : Var(V), TheDIE(nullptr), DotDebugLocOffset(~0U), AbsVar(AV),
+ MInsn(nullptr), FrameIndex(~0), DD(DD) {}
// Accessors.
DIVariable getVariable() const { return Var; }
- void setDIE(DIE *D) { TheDIE = D; }
+ void setDIE(DIE &D) { TheDIE = &D; }
DIE *getDIE() const { return TheDIE; }
void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; }
unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; }
@@ -90,7 +95,7 @@ public:
int getFrameIndex() const { return FrameIndex; }
void setFrameIndex(int FI) { FrameIndex = FI; }
// Translate tag to proper Dwarf tag.
- uint16_t getTag() const {
+ dwarf::Tag getTag() const {
if (Var.getTag() == dwarf::DW_TAG_arg_variable)
return dwarf::DW_TAG_formal_parameter;
@@ -131,99 +136,6 @@ private:
template <typename T> T resolve(DIRef<T> Ref) const;
};
-/// \brief Collects and handles information specific to a particular
-/// collection of units. This collection represents all of the units
-/// that will be ultimately output into a single object file.
-class DwarfFile {
- // Target of Dwarf emission, used for sizing of abbreviations.
- AsmPrinter *Asm;
-
- // Used to uniquely define abbreviations.
- FoldingSet<DIEAbbrev> AbbreviationsSet;
-
- // A list of all the unique abbreviations in use.
- std::vector<DIEAbbrev *> Abbreviations;
-
- // A pointer to all units in the section.
- SmallVector<DwarfUnit *, 1> CUs;
-
- // Collection of strings for this unit and assorted symbols.
- // A String->Symbol mapping of strings used by indirect
- // references.
- typedef StringMap<std::pair<MCSymbol *, unsigned>, BumpPtrAllocator &>
- StrPool;
- StrPool StringPool;
- unsigned NextStringPoolNumber;
- std::string StringPref;
-
- struct AddressPoolEntry {
- unsigned Number;
- bool TLS;
- AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
- };
- // Collection of addresses for this unit and assorted labels.
- // A Symbol->unsigned mapping of addresses used by indirect
- // references.
- typedef DenseMap<const MCSymbol *, AddressPoolEntry> AddrPool;
- AddrPool AddressPool;
- unsigned NextAddrPoolNumber;
-
-public:
- DwarfFile(AsmPrinter *AP, const char *Pref, BumpPtrAllocator &DA)
- : Asm(AP), StringPool(DA), NextStringPoolNumber(0), StringPref(Pref),
- AddressPool(), NextAddrPoolNumber(0) {}
-
- ~DwarfFile();
-
- const SmallVectorImpl<DwarfUnit *> &getUnits() { return CUs; }
-
- /// \brief Compute the size and offset of a DIE given an incoming Offset.
- unsigned computeSizeAndOffset(DIE *Die, unsigned Offset);
-
- /// \brief Compute the size and offset of all the DIEs.
- void computeSizeAndOffsets();
-
- /// \brief Define a unique number for the abbreviation.
- void assignAbbrevNumber(DIEAbbrev &Abbrev);
-
- /// \brief Add a unit to the list of CUs.
- void addUnit(DwarfUnit *CU) { CUs.push_back(CU); }
-
- /// \brief Emit all of the units to the section listed with the given
- /// abbreviation section.
- void emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym);
-
- /// \brief Emit a set of abbreviations to the specific section.
- void emitAbbrevs(const MCSection *);
-
- /// \brief Emit all of the strings to the section given.
- void emitStrings(const MCSection *StrSection, const MCSection *OffsetSection,
- const MCSymbol *StrSecSym);
-
- /// \brief Emit all of the addresses to the section given.
- void emitAddresses(const MCSection *AddrSection);
-
- /// \brief Returns the entry into the start of the pool.
- MCSymbol *getStringPoolSym();
-
- /// \brief Returns an entry into the string pool with the given
- /// string text.
- MCSymbol *getStringPoolEntry(StringRef Str);
-
- /// \brief Returns the index into the string pool with the given
- /// string text.
- unsigned getStringPoolIndex(StringRef Str);
-
- /// \brief Returns the string pool.
- StrPool *getStringPool() { return &StringPool; }
-
- /// \brief Returns the index into the address pool with the given
- /// label/symbol.
- unsigned getAddrPoolIndex(const MCSymbol *Sym, bool TLS = false);
-
- /// \brief Returns the address pool.
- AddrPool *getAddrPool() { return &AddressPool; }
-};
/// \brief Helper used to pair up a symbol and its DWARF compile unit.
struct SymbolCU {
@@ -287,7 +199,7 @@ class DwarfDebug : public AsmPrinterHandler {
ScopeVariablesMap ScopeVariables;
// Collection of abstract variables.
- DenseMap<const MDNode *, DbgVariable *> AbstractVariables;
+ DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
// Collection of DebugLocEntry. Stored in a linked list so that DIELocLists
// can refer to them in spite of insertions into this list.
@@ -307,15 +219,8 @@ class DwarfDebug : public AsmPrinterHandler {
// Maps instruction with label emitted after instruction.
DenseMap<const MachineInstr *, MCSymbol *> LabelsAfterInsn;
- // Every user variable mentioned by a DBG_VALUE instruction in order of
- // appearance.
- SmallVector<const MDNode *, 8> UserVariables;
-
- // For each user variable, keep a list of DBG_VALUE instructions in order.
- // The list can also contain normal instructions that clobber the previous
- // DBG_VALUE.
- typedef DenseMap<const MDNode *, SmallVector<const MachineInstr *, 4> >
- DbgValueHistoryMap;
+ // History of DBG_VALUE and clobber instructions for each user variable.
+ // Variables are listed in order of appearance.
DbgValueHistoryMap DbgValues;
// Previous instruction's location information. This is used to determine
@@ -373,6 +278,8 @@ class DwarfDebug : public AsmPrinterHandler {
// them.
DenseMap<const MDNode *, const DwarfTypeUnit *> DwarfTypeUnits;
+ SmallVector<std::pair<std::unique_ptr<DwarfTypeUnit>, DICompositeType>, 1> TypeUnitsUnderConstruction;
+
// Whether to emit the pubnames/pubtypes sections.
bool HasDwarfPubSections;
@@ -411,22 +318,30 @@ class DwarfDebug : public AsmPrinterHandler {
// True iff there are multiple CUs in this module.
bool SingleCU;
+ AddressPool AddrPool;
+
+ DwarfAccelTable AccelNames;
+ DwarfAccelTable AccelObjC;
+ DwarfAccelTable AccelNamespace;
+ DwarfAccelTable AccelTypes;
+
MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);
void addScopeVariable(LexicalScope *LS, DbgVariable *Var);
- const SmallVectorImpl<DwarfUnit *> &getUnits() {
+ const SmallVectorImpl<std::unique_ptr<DwarfUnit>> &getUnits() {
return InfoHolder.getUnits();
}
/// \brief Find abstract variable associated with Var.
DbgVariable *findAbstractVariable(DIVariable &Var, DebugLoc Loc);
+ DbgVariable *findAbstractVariable(DIVariable &Var, const MDNode *Scope);
/// \brief Find DIE for the given subprogram and attach appropriate
/// DW_AT_low_pc and DW_AT_high_pc attributes. If there are global
/// variables in this scope then create and insert DIEs for these
/// variables.
- DIE *updateSubprogramScopeDIE(DwarfCompileUnit *SPCU, DISubprogram SP);
+ DIE &updateSubprogramScopeDIE(DwarfCompileUnit &SPCU, DISubprogram SP);
/// \brief A helper function to check whether the DIE for a given Scope is
/// going to be null.
@@ -434,22 +349,33 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief A helper function to construct a RangeSpanList for a given
/// lexical scope.
- void addScopeRangeList(DwarfCompileUnit *TheCU, DIE *ScopeDIE,
+ void addScopeRangeList(DwarfCompileUnit &TheCU, DIE &ScopeDIE,
const SmallVectorImpl<InsnRange> &Range);
/// \brief Construct new DW_TAG_lexical_block for this scope and
/// attach DW_AT_low_pc/DW_AT_high_pc labels.
- DIE *constructLexicalScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope);
+ std::unique_ptr<DIE> constructLexicalScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
/// \brief This scope represents inlined body of a function. Construct
/// DIE to represent this concrete inlined copy of the function.
- DIE *constructInlinedScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope);
+ std::unique_ptr<DIE> constructInlinedScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
/// \brief Construct a DIE for this scope.
- DIE *constructScopeDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope);
+ std::unique_ptr<DIE> constructScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
+ void createAndAddScopeChildren(DwarfCompileUnit &TheCU, LexicalScope *Scope,
+ DIE &ScopeDIE);
+ /// \brief Construct a DIE for this abstract scope.
+ void constructAbstractSubprogramScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
+ /// \brief Construct a DIE for this subprogram scope.
+ DIE &constructSubprogramScopeDIE(DwarfCompileUnit &TheCU,
+ LexicalScope *Scope);
/// A helper function to create children of a Scope DIE.
- DIE *createScopeChildrenDIE(DwarfCompileUnit *TheCU, LexicalScope *Scope,
- SmallVectorImpl<DIE *> &Children);
+ DIE *createScopeChildrenDIE(DwarfCompileUnit &TheCU, LexicalScope *Scope,
+ SmallVectorImpl<std::unique_ptr<DIE>> &Children);
/// \brief Emit initial Dwarf sections with a label at the start of each one.
void emitSectionLabels();
@@ -460,12 +386,11 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Compute the size and offset of all the DIEs.
void computeSizeAndOffsets();
- /// \brief Attach DW_AT_inline attribute with inlined subprogram DIEs.
- void computeInlinedDIEs();
-
/// \brief Collect info for variables that were optimized out.
void collectDeadVariables();
+ void finishSubprogramDefinitions();
+
/// \brief Finish off debug information after all functions have been
/// processed.
void finalizeModuleInfo();
@@ -535,15 +460,16 @@ class DwarfDebug : public AsmPrinterHandler {
/// DWARF 5 Experimental Split Dwarf Emitters
/// \brief Initialize common features of skeleton units.
- void initSkeletonUnit(const DwarfUnit *U, DIE *Die, DwarfUnit *NewU);
+ void initSkeletonUnit(const DwarfUnit &U, DIE &Die,
+ std::unique_ptr<DwarfUnit> NewU);
/// \brief Construct the split debug info compile unit for the debug info
/// section.
- DwarfCompileUnit *constructSkeletonCU(const DwarfCompileUnit *CU);
+ DwarfCompileUnit &constructSkeletonCU(const DwarfCompileUnit &CU);
/// \brief Construct the split debug info compile unit for the debug info
/// section.
- DwarfTypeUnit *constructSkeletonTU(DwarfTypeUnit *TU);
+ DwarfTypeUnit &constructSkeletonTU(DwarfTypeUnit &TU);
/// \brief Emit the debug info dwo section.
void emitDebugInfoDWO();
@@ -559,25 +485,22 @@ class DwarfDebug : public AsmPrinterHandler {
/// Flags to let the linker know we have emitted new style pubnames. Only
/// emit it here if we don't have a skeleton CU for split dwarf.
- void addGnuPubAttributes(DwarfUnit *U, DIE *D) const;
+ void addGnuPubAttributes(DwarfUnit &U, DIE &D) const;
/// \brief Create new DwarfCompileUnit for the given metadata node with tag
/// DW_TAG_compile_unit.
- DwarfCompileUnit *constructDwarfCompileUnit(DICompileUnit DIUnit);
-
- /// \brief Construct subprogram DIE.
- void constructSubprogramDIE(DwarfCompileUnit *TheCU, const MDNode *N);
+ DwarfCompileUnit &constructDwarfCompileUnit(DICompileUnit DIUnit);
/// \brief Construct imported_module or imported_declaration DIE.
- void constructImportedEntityDIE(DwarfCompileUnit *TheCU, const MDNode *N);
+ void constructImportedEntityDIE(DwarfCompileUnit &TheCU, const MDNode *N);
/// \brief Construct import_module DIE.
- void constructImportedEntityDIE(DwarfCompileUnit *TheCU, const MDNode *N,
- DIE *Context);
+ void constructImportedEntityDIE(DwarfCompileUnit &TheCU, const MDNode *N,
+ DIE &Context);
/// \brief Construct import_module DIE.
- void constructImportedEntityDIE(DwarfCompileUnit *TheCU,
- const DIImportedEntity &Module, DIE *Context);
+ void constructImportedEntityDIE(DwarfCompileUnit &TheCU,
+ const DIImportedEntity &Module, DIE &Context);
/// \brief Register a source line with debug info. Returns the unique
/// label that was emitted and which provides correspondence to the
@@ -602,7 +525,7 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Ensure that a label will be emitted before MI.
void requestLabelBeforeInsn(const MachineInstr *MI) {
- LabelsBeforeInsn.insert(std::make_pair(MI, (MCSymbol *)0));
+ LabelsBeforeInsn.insert(std::make_pair(MI, nullptr));
}
/// \brief Return Label preceding the instruction.
@@ -610,13 +533,15 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Ensure that a label will be emitted after MI.
void requestLabelAfterInsn(const MachineInstr *MI) {
- LabelsAfterInsn.insert(std::make_pair(MI, (MCSymbol *)0));
+ LabelsAfterInsn.insert(std::make_pair(MI, nullptr));
}
/// \brief Return Label immediately following the instruction.
MCSymbol *getLabelAfterInsn(const MachineInstr *MI);
- void attachLowHighPC(DwarfCompileUnit *Unit, DIE *D, MCSymbol *Begin,
+ void attachRangesOrLowHighPC(DwarfCompileUnit &Unit, DIE &D,
+ const SmallVectorImpl<InsnRange> &Ranges);
+ void attachLowHighPC(DwarfCompileUnit &Unit, DIE &D, MCSymbol *Begin,
MCSymbol *End);
public:
@@ -625,6 +550,8 @@ public:
//
DwarfDebug(AsmPrinter *A, Module *M);
+ ~DwarfDebug() override;
+
void insertDIE(const MDNode *TypeMD, DIE *Die) {
MDTypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
}
@@ -654,7 +581,7 @@ public:
/// \brief Add a DIE to the set of types that we're going to pull into
/// type units.
void addDwarfTypeUnitType(DwarfCompileUnit &CU, StringRef Identifier,
- DIE *Die, DICompositeType CTy);
+ DIE &Die, DICompositeType CTy);
/// \brief Add a label so that arange data can be generated for it.
void addArangeLabel(SymbolCU SCU) { ArangeLabels.push_back(SCU); }
@@ -666,7 +593,7 @@ public:
}
/// \brief Recursively Emits a debug information entry.
- void emitDIE(DIE *Die);
+ void emitDIE(DIE &Die);
// Experimental DWARF5 features.
@@ -720,6 +647,18 @@ public:
/// isSubprogramContext - Return true if Context is either a subprogram
/// or another context nested inside a subprogram.
bool isSubprogramContext(const MDNode *Context);
+
+ void addSubprogramNames(DISubprogram SP, DIE &Die);
+
+ AddressPool &getAddressPool() { return AddrPool; }
+
+ void addAccelName(StringRef Name, const DIE &Die);
+
+ void addAccelObjC(StringRef Name, const DIE &Die);
+
+ void addAccelNamespace(StringRef Name, const DIE &Die);
+
+ void addAccelType(StringRef Name, const DIE &Die, char Flags);
};
} // End of namespace llvm
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 113a9e4..3a12c73 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -103,7 +103,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
int FirstAction = 0;
unsigned SizeActions = 0;
- const LandingPadInfo *PrevLPI = 0;
+ const LandingPadInfo *PrevLPI = nullptr;
for (SmallVectorImpl<const LandingPadInfo *>::const_iterator
I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) {
@@ -181,7 +181,7 @@ bool DwarfException::CallToNoUnwindFunction(const MachineInstr *MI) {
if (!MO.isGlobal()) continue;
const Function *F = dyn_cast<Function>(MO.getGlobal());
- if (F == 0) continue;
+ if (!F) continue;
if (SawFunc) {
// Be conservative. If we have more than one function operand for this
@@ -214,7 +214,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
const SmallVectorImpl<unsigned> &FirstActions) {
// The end label of the previous invoke or nounwind try-range.
- MCSymbol *LastLabel = 0;
+ MCSymbol *LastLabel = nullptr;
// Whether there is a potentially throwing instruction (currently this means
// an ordinary call) between the end of the previous try-range and now.
@@ -224,18 +224,16 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
bool PreviousIsInvoke = false;
// Visit all instructions in order of address.
- for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
- I != E; ++I) {
- for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
- MI != E; ++MI) {
- if (!MI->isEHLabel()) {
- if (MI->isCall())
- SawPotentiallyThrowing |= !CallToNoUnwindFunction(MI);
+ for (const auto &MBB : *Asm->MF) {
+ for (const auto &MI : MBB) {
+ if (!MI.isEHLabel()) {
+ if (MI.isCall())
+ SawPotentiallyThrowing |= !CallToNoUnwindFunction(&MI);
continue;
}
// End of the previous try-range?
- MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol();
+ MCSymbol *BeginLabel = MI.getOperand(0).getMCSymbol();
if (BeginLabel == LastLabel)
SawPotentiallyThrowing = false;
@@ -255,7 +253,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// create a call-site entry with no landing pad for the region between the
// try-ranges.
if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) {
- CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 };
+ CallSiteEntry Site = { LastLabel, BeginLabel, nullptr, 0 };
CallSites.push_back(Site);
PreviousIsInvoke = false;
}
@@ -305,7 +303,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// function may throw, create a call-site entry with no landing pad for the
// region following the try-range.
if (SawPotentiallyThrowing && Asm->MAI->isExceptionHandlingDwarf()) {
- CallSiteEntry Site = { LastLabel, 0, 0, 0 };
+ CallSiteEntry Site = { LastLabel, nullptr, nullptr, 0 };
CallSites.push_back(Site);
}
}
@@ -571,10 +569,10 @@ void DwarfException::EmitExceptionTable() {
Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
MCSymbol *BeginLabel = S.BeginLabel;
- if (BeginLabel == 0)
+ if (!BeginLabel)
BeginLabel = EHFuncBeginSym;
MCSymbol *EndLabel = S.EndLabel;
- if (EndLabel == 0)
+ if (!EndLabel)
EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());
diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/lib/CodeGen/AsmPrinter/DwarfFile.cpp
new file mode 100644
index 0000000..737ee54
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -0,0 +1,156 @@
+//===-- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfFile.h"
+
+#include "DwarfDebug.h"
+#include "DwarfUnit.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+
+namespace llvm {
+DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
+ : Asm(AP), StrPool(DA, *Asm, Pref) {}
+
+DwarfFile::~DwarfFile() {}
+
+// Define a unique number for the abbreviation.
+//
+void DwarfFile::assignAbbrevNumber(DIEAbbrev &Abbrev) {
+ // Check the set for priors.
+ DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
+
+ // If it's newly added.
+ if (InSet == &Abbrev) {
+ // Add to abbreviation list.
+ Abbreviations.push_back(&Abbrev);
+
+ // Assign the vector position + 1 as its number.
+ Abbrev.setNumber(Abbreviations.size());
+ } else {
+ // Assign existing abbreviation number.
+ Abbrev.setNumber(InSet->getNumber());
+ }
+}
+
+void DwarfFile::addUnit(std::unique_ptr<DwarfUnit> U) {
+ CUs.push_back(std::move(U));
+}
+
+// Emit the various dwarf units to the unit section USection with
+// the abbreviations going into ASection.
+void DwarfFile::emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym) {
+ for (const auto &TheU : CUs) {
+ DIE &Die = TheU->getUnitDie();
+ const MCSection *USection = TheU->getSection();
+ Asm->OutStreamer.SwitchSection(USection);
+
+ // Emit the compile units header.
+ Asm->OutStreamer.EmitLabel(TheU->getLabelBegin());
+
+ // Emit size of content not including length itself
+ Asm->OutStreamer.AddComment("Length of Unit");
+ Asm->EmitInt32(TheU->getHeaderSize() + Die.getSize());
+
+ TheU->emitHeader(ASectionSym);
+
+ DD->emitDIE(Die);
+ Asm->OutStreamer.EmitLabel(TheU->getLabelEnd());
+ }
+}
+// Compute the size and offset for each DIE.
+void DwarfFile::computeSizeAndOffsets() {
+ // Offset from the first CU in the debug info section is 0 initially.
+ unsigned SecOffset = 0;
+
+ // Iterate over each compile unit and set the size and offsets for each
+ // DIE within each compile unit. All offsets are CU relative.
+ for (const auto &TheU : CUs) {
+ TheU->setDebugInfoOffset(SecOffset);
+
+ // CU-relative offset is reset to 0 here.
+ unsigned Offset = sizeof(int32_t) + // Length of Unit Info
+ TheU->getHeaderSize(); // Unit-specific headers
+
+ // EndOffset here is CU-relative, after laying out
+ // all of the CU DIE.
+ unsigned EndOffset = computeSizeAndOffset(TheU->getUnitDie(), Offset);
+ SecOffset += EndOffset;
+ }
+}
+// Compute the size and offset of a DIE. The offset is relative to start of the
+// CU. It returns the offset after laying out the DIE.
+unsigned DwarfFile::computeSizeAndOffset(DIE &Die, unsigned Offset) {
+ // Record the abbreviation.
+ assignAbbrevNumber(Die.getAbbrev());
+
+ // Get the abbreviation for this DIE.
+ const DIEAbbrev &Abbrev = Die.getAbbrev();
+
+ // Set DIE offset
+ Die.setOffset(Offset);
+
+ // Start the size with the size of abbreviation code.
+ Offset += getULEB128Size(Die.getAbbrevNumber());
+
+ const SmallVectorImpl<DIEValue *> &Values = Die.getValues();
+ const SmallVectorImpl<DIEAbbrevData> &AbbrevData = Abbrev.getData();
+
+ // Size the DIE attribute values.
+ for (unsigned i = 0, N = Values.size(); i < N; ++i)
+ // Size attribute value.
+ Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
+
+ // Get the children.
+ const auto &Children = Die.getChildren();
+
+ // Size the DIE children if any.
+ if (!Children.empty()) {
+ assert(Abbrev.hasChildren() && "Children flag not set");
+
+ for (auto &Child : Children)
+ Offset = computeSizeAndOffset(*Child, Offset);
+
+ // End of children marker.
+ Offset += sizeof(int8_t);
+ }
+
+ Die.setSize(Offset - Die.getOffset());
+ return Offset;
+}
+void DwarfFile::emitAbbrevs(const MCSection *Section) {
+ // Check to see if it is worth the effort.
+ if (!Abbreviations.empty()) {
+ // Start the debug abbrev section.
+ Asm->OutStreamer.SwitchSection(Section);
+
+ // For each abbrevation.
+ for (const DIEAbbrev *Abbrev : Abbreviations) {
+ // Emit the abbrevations code (base 1 index.)
+ Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
+
+ // Emit the abbreviations data.
+ Abbrev->Emit(Asm);
+ }
+
+ // Mark end of abbreviations.
+ Asm->EmitULEB128(0, "EOM(3)");
+ }
+}
+
+// Emit strings into a string section.
+void DwarfFile::emitStrings(const MCSection *StrSection,
+ const MCSection *OffsetSection,
+ const MCSymbol *StrSecSym) {
+ StrPool.emit(*Asm, StrSection, OffsetSection, StrSecSym);
+}
+}
diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.h b/lib/CodeGen/AsmPrinter/DwarfFile.h
new file mode 100644
index 0000000..3985eb2
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfFile.h
@@ -0,0 +1,84 @@
+//===-- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework -------*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_ASMPRINTER_DWARFFILE_H__
+#define CODEGEN_ASMPRINTER_DWARFFILE_H__
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Allocator.h"
+#include "AddressPool.h"
+#include "DwarfStringPool.h"
+
+#include <vector>
+#include <string>
+#include <memory>
+
+namespace llvm {
+class AsmPrinter;
+class DwarfUnit;
+class DIEAbbrev;
+class MCSymbol;
+class DIE;
+class StringRef;
+class DwarfDebug;
+class MCSection;
+class DwarfFile {
+ // Target of Dwarf emission, used for sizing of abbreviations.
+ AsmPrinter *Asm;
+
+ // Used to uniquely define abbreviations.
+ FoldingSet<DIEAbbrev> AbbreviationsSet;
+
+ // A list of all the unique abbreviations in use.
+ std::vector<DIEAbbrev *> Abbreviations;
+
+ // A pointer to all units in the section.
+ SmallVector<std::unique_ptr<DwarfUnit>, 1> CUs;
+
+ DwarfStringPool StrPool;
+
+public:
+ DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA);
+
+ ~DwarfFile();
+
+ const SmallVectorImpl<std::unique_ptr<DwarfUnit>> &getUnits() { return CUs; }
+
+ /// \brief Compute the size and offset of a DIE given an incoming Offset.
+ unsigned computeSizeAndOffset(DIE &Die, unsigned Offset);
+
+ /// \brief Compute the size and offset of all the DIEs.
+ void computeSizeAndOffsets();
+
+ /// \brief Define a unique number for the abbreviation.
+ void assignAbbrevNumber(DIEAbbrev &Abbrev);
+
+ /// \brief Add a unit to the list of CUs.
+ void addUnit(std::unique_ptr<DwarfUnit> U);
+
+ /// \brief Emit all of the units to the section listed with the given
+ /// abbreviation section.
+ void emitUnits(DwarfDebug *DD, const MCSymbol *ASectionSym);
+
+ /// \brief Emit a set of abbreviations to the specific section.
+ void emitAbbrevs(const MCSection *);
+
+ /// \brief Emit all of the strings to the section given.
+ void emitStrings(const MCSection *StrSection,
+ const MCSection *OffsetSection = nullptr,
+ const MCSymbol *StrSecSym = nullptr);
+
+ /// \brief Returns the string pool.
+ DwarfStringPool &getStringPool() { return StrPool; }
+};
+}
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
new file mode 100644
index 0000000..72cab60
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
@@ -0,0 +1,74 @@
+//===-- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DwarfStringPool.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+MCSymbol *DwarfStringPool::getSectionSymbol() { return SectionSymbol; }
+
+static std::pair<MCSymbol *, unsigned> &
+getEntry(AsmPrinter &Asm,
+ StringMap<std::pair<MCSymbol *, unsigned>, BumpPtrAllocator &> &Pool,
+ StringRef Prefix, StringRef Str) {
+ std::pair<MCSymbol *, unsigned> &Entry =
+ Pool.GetOrCreateValue(Str).getValue();
+ if (!Entry.first) {
+ Entry.second = Pool.size() - 1;
+ Entry.first = Asm.GetTempSymbol(Prefix, Entry.second);
+ }
+ return Entry;
+}
+
+MCSymbol *DwarfStringPool::getSymbol(AsmPrinter &Asm, StringRef Str) {
+ return getEntry(Asm, Pool, Prefix, Str).first;
+}
+
+unsigned DwarfStringPool::getIndex(AsmPrinter &Asm, StringRef Str) {
+ return getEntry(Asm, Pool, Prefix, Str).second;
+}
+
+void DwarfStringPool::emit(AsmPrinter &Asm, const MCSection *StrSection,
+ const MCSection *OffsetSection,
+ const MCSymbol *StrSecSym) {
+ if (Pool.empty())
+ return;
+
+ // Start the dwarf str section.
+ Asm.OutStreamer.SwitchSection(StrSection);
+
+ // Get all of the string pool entries and put them in an array by their ID so
+ // we can sort them.
+ SmallVector<const StringMapEntry<std::pair<MCSymbol *, unsigned>> *, 64>
+ Entries(Pool.size());
+
+ for (const auto &E : Pool)
+ Entries[E.getValue().second] = &E;
+
+ for (const auto &Entry : Entries) {
+ // Emit a label for reference from debug information entries.
+ Asm.OutStreamer.EmitLabel(Entry->getValue().first);
+
+ // Emit the string itself with a terminating null byte.
+ Asm.OutStreamer.EmitBytes(
+ StringRef(Entry->getKeyData(), Entry->getKeyLength() + 1));
+ }
+
+ // If we've got an offset section go ahead and emit that now as well.
+ if (OffsetSection) {
+ Asm.OutStreamer.SwitchSection(OffsetSection);
+ unsigned offset = 0;
+ unsigned size = 4; // FIXME: DWARF64 is 8.
+ for (const auto &Entry : Entries) {
+ Asm.OutStreamer.EmitIntValue(offset, size);
+ offset += Entry->getKeyLength() + 1;
+ }
+ }
+}
diff --git a/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/lib/CodeGen/AsmPrinter/DwarfStringPool.h
new file mode 100644
index 0000000..c1615fb
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/DwarfStringPool.h
@@ -0,0 +1,55 @@
+//===-- llvm/CodeGen/DwarfStringPool.h - Dwarf Debug Framework -*- C++ -*--===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CODEGEN_ASMPRINTER_STRINGPOOL_H__
+#define CODEGEN_ASMPRINTER_STRINGPOOL_H__
+
+#include "llvm/ADT/StringMap.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/Support/Allocator.h"
+
+#include <utility>
+
+namespace llvm {
+
+class MCSymbol;
+class MCSection;
+class StringRef;
+
+// Collection of strings for this unit and assorted symbols.
+// A String->Symbol mapping of strings used by indirect
+// references.
+class DwarfStringPool {
+ StringMap<std::pair<MCSymbol *, unsigned>, BumpPtrAllocator &> Pool;
+ StringRef Prefix;
+ MCSymbol *SectionSymbol;
+
+public:
+ DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix)
+ : Pool(A), Prefix(Prefix), SectionSymbol(Asm.GetTempSymbol(Prefix)) {}
+
+ void emit(AsmPrinter &Asm, const MCSection *StrSection,
+ const MCSection *OffsetSection = nullptr,
+ const MCSymbol *StrSecSym = nullptr);
+
+ /// \brief Returns the entry into the start of the pool.
+ MCSymbol *getSectionSymbol();
+
+ /// \brief Returns an entry into the string pool with the given
+ /// string text.
+ MCSymbol *getSymbol(AsmPrinter &Asm, StringRef Str);
+
+ /// \brief Returns the index into the string pool with the given
+ /// string text.
+ unsigned getIndex(AsmPrinter &Asm, StringRef Str);
+
+ bool empty() const { return Pool.empty(); }
+};
+}
+#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 82e9bb0..a70c0f7 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -11,8 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "dwarfdebug"
-
#include "DwarfUnit.h"
#include "DwarfAccelTable.h"
#include "DwarfDebug.h"
@@ -35,33 +33,38 @@
using namespace llvm;
+#define DEBUG_TYPE "dwarfdebug"
+
static cl::opt<bool>
GenerateDwarfTypeUnits("generate-type-units", cl::Hidden,
cl::desc("Generate DWARF4 type units."),
cl::init(false));
/// Unit - Unit constructor.
-DwarfUnit::DwarfUnit(unsigned UID, DIE *D, DICompileUnit Node, AsmPrinter *A,
- DwarfDebug *DW, DwarfFile *DWU)
- : UniqueID(UID), CUNode(Node), UnitDie(D), DebugInfoOffset(0), Asm(A),
- DD(DW), DU(DWU), IndexTyDie(0), Section(0), Skeleton(0) {
+DwarfUnit::DwarfUnit(unsigned UID, dwarf::Tag UnitTag, DICompileUnit Node,
+ AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU)
+ : UniqueID(UID), CUNode(Node), UnitDie(UnitTag), DebugInfoOffset(0), Asm(A),
+ DD(DW), DU(DWU), IndexTyDie(nullptr), Section(nullptr),
+ Skeleton(nullptr) {
+ assert(UnitTag == dwarf::DW_TAG_compile_unit ||
+ UnitTag == dwarf::DW_TAG_type_unit);
DIEIntegerOne = new (DIEValueAllocator) DIEInteger(1);
}
-DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node,
+DwarfCompileUnit::DwarfCompileUnit(unsigned UID, DICompileUnit Node,
AsmPrinter *A, DwarfDebug *DW,
DwarfFile *DWU)
- : DwarfUnit(UID, D, Node, A, DW, DWU) {
- insertDIE(Node, D);
+ : DwarfUnit(UID, dwarf::DW_TAG_compile_unit, Node, A, DW, DWU) {
+ insertDIE(Node, &getUnitDie());
}
-DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DIE *D, DwarfCompileUnit &CU,
- AsmPrinter *A, DwarfDebug *DW, DwarfFile *DWU,
+DwarfTypeUnit::DwarfTypeUnit(unsigned UID, DwarfCompileUnit &CU, AsmPrinter *A,
+ DwarfDebug *DW, DwarfFile *DWU,
MCDwarfDwoLineTable *SplitLineTable)
- : DwarfUnit(UID, D, CU.getCUNode(), A, DW, DWU), CU(CU),
- SplitLineTable(SplitLineTable) {
+ : DwarfUnit(UID, dwarf::DW_TAG_type_unit, CU.getCUNode(), A, DW, DWU),
+ CU(CU), SplitLineTable(SplitLineTable) {
if (SplitLineTable)
- addSectionOffset(UnitDie.get(), dwarf::DW_AT_stmt_list, 0);
+ addSectionOffset(UnitDie, dwarf::DW_AT_stmt_list, 0);
}
/// ~Unit - Destructor for compile unit.
@@ -74,7 +77,7 @@ DwarfUnit::~DwarfUnit() {
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
/// information entry.
-DIEEntry *DwarfUnit::createDIEEntry(DIE *Entry) {
+DIEEntry *DwarfUnit::createDIEEntry(DIE &Entry) {
DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
return Value;
}
@@ -159,39 +162,39 @@ void DwarfUnit::insertDIE(DIDescriptor Desc, DIE *D) {
}
/// addFlag - Add a flag that is true.
-void DwarfUnit::addFlag(DIE *Die, dwarf::Attribute Attribute) {
+void DwarfUnit::addFlag(DIE &Die, dwarf::Attribute Attribute) {
if (DD->getDwarfVersion() >= 4)
- Die->addValue(Attribute, dwarf::DW_FORM_flag_present, DIEIntegerOne);
+ Die.addValue(Attribute, dwarf::DW_FORM_flag_present, DIEIntegerOne);
else
- Die->addValue(Attribute, dwarf::DW_FORM_flag, DIEIntegerOne);
+ Die.addValue(Attribute, dwarf::DW_FORM_flag, DIEIntegerOne);
}
/// addUInt - Add an unsigned integer attribute data and value.
///
-void DwarfUnit::addUInt(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addUInt(DIE &Die, dwarf::Attribute Attribute,
Optional<dwarf::Form> Form, uint64_t Integer) {
if (!Form)
Form = DIEInteger::BestForm(false, Integer);
DIEValue *Value = Integer == 1 ? DIEIntegerOne : new (DIEValueAllocator)
DIEInteger(Integer);
- Die->addValue(Attribute, *Form, Value);
+ Die.addValue(Attribute, *Form, Value);
}
-void DwarfUnit::addUInt(DIE *Block, dwarf::Form Form, uint64_t Integer) {
+void DwarfUnit::addUInt(DIE &Block, dwarf::Form Form, uint64_t Integer) {
addUInt(Block, (dwarf::Attribute)0, Form, Integer);
}
/// addSInt - Add an signed integer attribute data and value.
///
-void DwarfUnit::addSInt(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addSInt(DIE &Die, dwarf::Attribute Attribute,
Optional<dwarf::Form> Form, int64_t Integer) {
if (!Form)
Form = DIEInteger::BestForm(true, Integer);
DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
- Die->addValue(Attribute, *Form, Value);
+ Die.addValue(Attribute, *Form, Value);
}
-void DwarfUnit::addSInt(DIELoc *Die, Optional<dwarf::Form> Form,
+void DwarfUnit::addSInt(DIELoc &Die, Optional<dwarf::Form> Form,
int64_t Integer) {
addSInt(Die, (dwarf::Attribute)0, Form, Integer);
}
@@ -201,66 +204,66 @@ void DwarfUnit::addSInt(DIELoc *Die, Optional<dwarf::Form> Form,
/// more predictable sizes. In the case of split dwarf we emit an index
/// into another table which gets us the static offset into the string
/// table.
-void DwarfUnit::addString(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addString(DIE &Die, dwarf::Attribute Attribute,
StringRef String) {
if (!DD->useSplitDwarf())
return addLocalString(Die, Attribute, String);
- unsigned idx = DU->getStringPoolIndex(String);
+ unsigned idx = DU->getStringPool().getIndex(*Asm, String);
DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
DIEValue *Str = new (DIEValueAllocator) DIEString(Value, String);
- Die->addValue(Attribute, dwarf::DW_FORM_GNU_str_index, Str);
+ Die.addValue(Attribute, dwarf::DW_FORM_GNU_str_index, Str);
}
/// addLocalString - Add a string attribute data and value. This is guaranteed
/// to be in the local string pool instead of indirected.
-void DwarfUnit::addLocalString(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addLocalString(DIE &Die, dwarf::Attribute Attribute,
StringRef String) {
- MCSymbol *Symb = DU->getStringPoolEntry(String);
+ MCSymbol *Symb = DU->getStringPool().getSymbol(*Asm, String);
DIEValue *Value;
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
Value = new (DIEValueAllocator) DIELabel(Symb);
else {
- MCSymbol *StringPool = DU->getStringPoolSym();
+ MCSymbol *StringPool = DU->getStringPool().getSectionSymbol();
Value = new (DIEValueAllocator) DIEDelta(Symb, StringPool);
}
DIEValue *Str = new (DIEValueAllocator) DIEString(Value, String);
- Die->addValue(Attribute, dwarf::DW_FORM_strp, Str);
+ Die.addValue(Attribute, dwarf::DW_FORM_strp, Str);
}
/// addExpr - Add a Dwarf expression attribute data and value.
///
-void DwarfUnit::addExpr(DIELoc *Die, dwarf::Form Form, const MCExpr *Expr) {
+void DwarfUnit::addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr) {
DIEValue *Value = new (DIEValueAllocator) DIEExpr(Expr);
- Die->addValue((dwarf::Attribute)0, Form, Value);
+ Die.addValue((dwarf::Attribute)0, Form, Value);
}
/// addLocationList - Add a Dwarf loclistptr attribute data and value.
///
-void DwarfUnit::addLocationList(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addLocationList(DIE &Die, dwarf::Attribute Attribute,
unsigned Index) {
DIEValue *Value = new (DIEValueAllocator) DIELocList(Index);
dwarf::Form Form = DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
: dwarf::DW_FORM_data4;
- Die->addValue(Attribute, Form, Value);
+ Die.addValue(Attribute, Form, Value);
}
/// addLabel - Add a Dwarf label attribute data and value.
///
-void DwarfUnit::addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form,
+void DwarfUnit::addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form,
const MCSymbol *Label) {
DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
- Die->addValue(Attribute, Form, Value);
+ Die.addValue(Attribute, Form, Value);
}
-void DwarfUnit::addLabel(DIELoc *Die, dwarf::Form Form, const MCSymbol *Label) {
+void DwarfUnit::addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label) {
addLabel(Die, (dwarf::Attribute)0, Form, Label);
}
/// addSectionLabel - Add a Dwarf section label attribute data and value.
///
-void DwarfUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label) {
if (DD->getDwarfVersion() >= 4)
addLabel(Die, Attribute, dwarf::DW_FORM_sec_offset, Label);
@@ -270,7 +273,7 @@ void DwarfUnit::addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
/// addSectionOffset - Add an offset into a section attribute data and value.
///
-void DwarfUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addSectionOffset(DIE &Die, dwarf::Attribute Attribute,
uint64_t Integer) {
if (DD->getDwarfVersion() >= 4)
addUInt(Die, Attribute, dwarf::DW_FORM_sec_offset, Integer);
@@ -281,7 +284,7 @@ void DwarfUnit::addSectionOffset(DIE *Die, dwarf::Attribute Attribute,
/// addLabelAddress - Add a dwarf label attribute data and value using
/// DW_FORM_addr or DW_FORM_GNU_addr_index.
///
-void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
+void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label) {
if (!DD->useSplitDwarf())
@@ -290,24 +293,20 @@ void DwarfCompileUnit::addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
if (Label)
DD->addArangeLabel(SymbolCU(this, Label));
- unsigned idx = DU->getAddrPoolIndex(Label);
+ unsigned idx = DD->getAddressPool().getIndex(Label);
DIEValue *Value = new (DIEValueAllocator) DIEInteger(idx);
- Die->addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
+ Die.addValue(Attribute, dwarf::DW_FORM_GNU_addr_index, Value);
}
-void DwarfCompileUnit::addLocalLabelAddress(DIE *Die,
+void DwarfCompileUnit::addLocalLabelAddress(DIE &Die,
dwarf::Attribute Attribute,
const MCSymbol *Label) {
if (Label)
DD->addArangeLabel(SymbolCU(this, Label));
- if (Label) {
- DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
- Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
- } else {
- DIEValue *Value = new (DIEValueAllocator) DIEInteger(0);
- Die->addValue(Attribute, dwarf::DW_FORM_addr, Value);
- }
+ Die.addValue(Attribute, dwarf::DW_FORM_addr,
+ Label ? (DIEValue *)new (DIEValueAllocator) DIELabel(Label)
+ : new (DIEValueAllocator) DIEInteger(0));
}
unsigned DwarfCompileUnit::getOrCreateSourceID(StringRef FileName, StringRef DirName) {
@@ -329,86 +328,94 @@ unsigned DwarfTypeUnit::getOrCreateSourceID(StringRef FileName, StringRef DirNam
/// addOpAddress - Add a dwarf op address data and value using the
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
///
-void DwarfUnit::addOpAddress(DIELoc *Die, const MCSymbol *Sym) {
+void DwarfUnit::addOpAddress(DIELoc &Die, const MCSymbol *Sym) {
if (!DD->useSplitDwarf()) {
addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addLabel(Die, dwarf::DW_FORM_udata, Sym);
} else {
addUInt(Die, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_addr_index);
- addUInt(Die, dwarf::DW_FORM_GNU_addr_index, DU->getAddrPoolIndex(Sym));
+ addUInt(Die, dwarf::DW_FORM_GNU_addr_index,
+ DD->getAddressPool().getIndex(Sym));
}
}
/// addSectionDelta - Add a section label delta attribute data and value.
///
-void DwarfUnit::addSectionDelta(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addSectionDelta(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Hi, const MCSymbol *Lo) {
DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
- if (DD->getDwarfVersion() >= 4)
- Die->addValue(Attribute, dwarf::DW_FORM_sec_offset, Value);
- else
- Die->addValue(Attribute, dwarf::DW_FORM_data4, Value);
+ Die.addValue(Attribute, DD->getDwarfVersion() >= 4 ? dwarf::DW_FORM_sec_offset
+ : dwarf::DW_FORM_data4,
+ Value);
}
-void DwarfUnit::addLabelDelta(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addLabelDelta(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Hi, const MCSymbol *Lo) {
DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
- Die->addValue(Attribute, dwarf::DW_FORM_data4, Value);
+ Die.addValue(Attribute, dwarf::DW_FORM_data4, Value);
}
/// addDIEEntry - Add a DIE attribute data and value.
///
-void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry) {
+void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry) {
addDIEEntry(Die, Attribute, createDIEEntry(Entry));
}
-void DwarfUnit::addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type) {
- Die->addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,
- new (DIEValueAllocator) DIETypeSignature(Type));
+void DwarfUnit::addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type) {
+ // Flag the type unit reference as a declaration so that if it contains
+ // members (implicit special members, static data member definitions, member
+ // declarations for definitions in this CU, etc) consumers don't get confused
+ // and think this is a full definition.
+ addFlag(Die, dwarf::DW_AT_declaration);
+
+ Die.addValue(dwarf::DW_AT_signature, dwarf::DW_FORM_ref_sig8,
+ new (DIEValueAllocator) DIETypeSignature(Type));
}
-void DwarfUnit::addDIEEntry(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addDIEEntry(DIE &Die, dwarf::Attribute Attribute,
DIEEntry *Entry) {
- const DIE *DieCU = Die->getUnitOrNull();
- const DIE *EntryCU = Entry->getEntry()->getUnitOrNull();
+ const DIE *DieCU = Die.getUnitOrNull();
+ const DIE *EntryCU = Entry->getEntry().getUnitOrNull();
if (!DieCU)
// We assume that Die belongs to this CU, if it is not linked to any CU yet.
- DieCU = getUnitDie();
+ DieCU = &getUnitDie();
if (!EntryCU)
- EntryCU = getUnitDie();
- Die->addValue(Attribute, EntryCU == DieCU ? dwarf::DW_FORM_ref4
- : dwarf::DW_FORM_ref_addr,
- Entry);
+ EntryCU = &getUnitDie();
+ Die.addValue(Attribute,
+ EntryCU == DieCU ? dwarf::DW_FORM_ref4 : dwarf::DW_FORM_ref_addr,
+ Entry);
}
/// Create a DIE with the given Tag, add the DIE to its parent, and
/// call insertDIE if MD is not null.
-DIE *DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) {
- DIE *Die = new DIE(Tag);
- Parent.addChild(Die);
+DIE &DwarfUnit::createAndAddDIE(unsigned Tag, DIE &Parent, DIDescriptor N) {
+ assert(Tag != dwarf::DW_TAG_auto_variable &&
+ Tag != dwarf::DW_TAG_arg_variable);
+ Parent.addChild(make_unique<DIE>((dwarf::Tag)Tag));
+ DIE &Die = *Parent.getChildren().back();
if (N)
- insertDIE(N, Die);
+ insertDIE(N, &Die);
return Die;
}
/// addBlock - Add block data.
///
-void DwarfUnit::addBlock(DIE *Die, dwarf::Attribute Attribute, DIELoc *Loc) {
+void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Loc) {
Loc->ComputeSize(Asm);
DIELocs.push_back(Loc); // Memoize so we can call the destructor later on.
- Die->addValue(Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc);
+ Die.addValue(Attribute, Loc->BestForm(DD->getDwarfVersion()), Loc);
}
-void DwarfUnit::addBlock(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addBlock(DIE &Die, dwarf::Attribute Attribute,
DIEBlock *Block) {
Block->ComputeSize(Asm);
DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
- Die->addValue(Attribute, Block->BestForm(), Block);
+ Die.addValue(Attribute, Block->BestForm(), Block);
}
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, unsigned Line, StringRef File,
+void DwarfUnit::addSourceLine(DIE &Die, unsigned Line, StringRef File,
StringRef Directory) {
if (Line == 0)
return;
@@ -421,7 +428,7 @@ void DwarfUnit::addSourceLine(DIE *Die, unsigned Line, StringRef File,
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, DIVariable V) {
+void DwarfUnit::addSourceLine(DIE &Die, DIVariable V) {
assert(V.isVariable());
addSourceLine(Die, V.getLineNumber(), V.getContext().getFilename(),
@@ -430,7 +437,7 @@ void DwarfUnit::addSourceLine(DIE *Die, DIVariable V) {
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
+void DwarfUnit::addSourceLine(DIE &Die, DIGlobalVariable G) {
assert(G.isGlobalVariable());
addSourceLine(Die, G.getLineNumber(), G.getFilename(), G.getDirectory());
@@ -438,7 +445,7 @@ void DwarfUnit::addSourceLine(DIE *Die, DIGlobalVariable G) {
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, DISubprogram SP) {
+void DwarfUnit::addSourceLine(DIE &Die, DISubprogram SP) {
assert(SP.isSubprogram());
addSourceLine(Die, SP.getLineNumber(), SP.getFilename(), SP.getDirectory());
@@ -446,7 +453,7 @@ void DwarfUnit::addSourceLine(DIE *Die, DISubprogram SP) {
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, DIType Ty) {
+void DwarfUnit::addSourceLine(DIE &Die, DIType Ty) {
assert(Ty.isType());
addSourceLine(Die, Ty.getLineNumber(), Ty.getFilename(), Ty.getDirectory());
@@ -454,7 +461,7 @@ void DwarfUnit::addSourceLine(DIE *Die, DIType Ty) {
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, DIObjCProperty Ty) {
+void DwarfUnit::addSourceLine(DIE &Die, DIObjCProperty Ty) {
assert(Ty.isObjCProperty());
DIFile File = Ty.getFile();
@@ -464,7 +471,7 @@ void DwarfUnit::addSourceLine(DIE *Die, DIObjCProperty Ty) {
/// addSourceLine - Add location information to specified debug information
/// entry.
-void DwarfUnit::addSourceLine(DIE *Die, DINameSpace NS) {
+void DwarfUnit::addSourceLine(DIE &Die, DINameSpace NS) {
assert(NS.Verify());
addSourceLine(Die, NS.getLineNumber(), NS.getFilename(), NS.getDirectory());
@@ -472,7 +479,7 @@ void DwarfUnit::addSourceLine(DIE *Die, DINameSpace NS) {
/// addVariableAddress - Add DW_AT_location attribute for a
/// DbgVariable based on provided MachineLocation.
-void DwarfUnit::addVariableAddress(const DbgVariable &DV, DIE *Die,
+void DwarfUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
MachineLocation Location) {
if (DV.variableHasComplexAddress())
addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
@@ -484,7 +491,7 @@ void DwarfUnit::addVariableAddress(const DbgVariable &DV, DIE *Die,
}
/// addRegisterOp - Add register operand.
-void DwarfUnit::addRegisterOp(DIELoc *TheDie, unsigned Reg) {
+void DwarfUnit::addRegisterOp(DIELoc &TheDie, unsigned Reg) {
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
int DWReg = RI->getDwarfRegNum(Reg, false);
bool isSubRegister = DWReg < 0;
@@ -529,7 +536,7 @@ void DwarfUnit::addRegisterOp(DIELoc *TheDie, unsigned Reg) {
}
/// addRegisterOffset - Add register offset.
-void DwarfUnit::addRegisterOffset(DIELoc *TheDie, unsigned Reg,
+void DwarfUnit::addRegisterOffset(DIELoc &TheDie, unsigned Reg,
int64_t Offset) {
const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned DWReg = RI->getDwarfRegNum(Reg, false);
@@ -548,16 +555,16 @@ void DwarfUnit::addRegisterOffset(DIELoc *TheDie, unsigned Reg,
/// addAddress - Add an address attribute to a die based on the location
/// provided.
-void DwarfUnit::addAddress(DIE *Die, dwarf::Attribute Attribute,
+void DwarfUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
const MachineLocation &Location, bool Indirect) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
if (Location.isReg() && !Indirect)
- addRegisterOp(Loc, Location.getReg());
+ addRegisterOp(*Loc, Location.getReg());
else {
- addRegisterOffset(Loc, Location.getReg(), Location.getOffset());
+ addRegisterOffset(*Loc, Location.getReg(), Location.getOffset());
if (Indirect && !Location.isReg()) {
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
}
}
@@ -570,7 +577,7 @@ void DwarfUnit::addAddress(DIE *Die, dwarf::Attribute Attribute,
/// given the extra address information encoded in the DbgVariable, starting
/// from the starting location. Add the DWARF information to the die.
///
-void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE *Die,
+void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
dwarf::Attribute Attribute,
const MachineLocation &Location) {
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
@@ -580,21 +587,21 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE *Die,
if (N >= 2 && DV.getAddrElement(0) == DIBuilder::OpPlus) {
// If first address element is OpPlus then emit
// DW_OP_breg + Offset instead of DW_OP_reg + Offset.
- addRegisterOffset(Loc, Location.getReg(), DV.getAddrElement(1));
+ addRegisterOffset(*Loc, Location.getReg(), DV.getAddrElement(1));
i = 2;
} else
- addRegisterOp(Loc, Location.getReg());
+ addRegisterOp(*Loc, Location.getReg());
} else
- addRegisterOffset(Loc, Location.getReg(), Location.getOffset());
+ addRegisterOffset(*Loc, Location.getReg(), Location.getOffset());
for (; i < N; ++i) {
uint64_t Element = DV.getAddrElement(i);
if (Element == DIBuilder::OpPlus) {
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
- addUInt(Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i));
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+ addUInt(*Loc, dwarf::DW_FORM_udata, DV.getAddrElement(++i));
} else if (Element == DIBuilder::OpDeref) {
if (!Location.isReg())
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
} else
llvm_unreachable("unknown DIBuilder Opcode");
}
@@ -663,7 +670,7 @@ void DwarfUnit::addComplexAddress(const DbgVariable &DV, DIE *Die,
/// starting location. Add the DWARF information to the die. For
/// more information, read large comment just above here.
///
-void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die,
+void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
dwarf::Attribute Attribute,
const MachineLocation &Location) {
DIType Ty = DV.getType();
@@ -705,68 +712,78 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE *Die,
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
if (Location.isReg())
- addRegisterOp(Loc, Location.getReg());
+ addRegisterOp(*Loc, Location.getReg());
else
- addRegisterOffset(Loc, Location.getReg(), Location.getOffset());
+ addRegisterOffset(*Loc, Location.getReg(), Location.getOffset());
// If we started with a pointer to the __Block_byref... struct, then
// the first thing we need to do is dereference the pointer (DW_OP_deref).
if (isPointer)
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
// Next add the offset for the '__forwarding' field:
// DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
// adding the offset if it's 0.
if (forwardingFieldOffset > 0) {
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
- addUInt(Loc, dwarf::DW_FORM_udata, forwardingFieldOffset);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+ addUInt(*Loc, dwarf::DW_FORM_udata, forwardingFieldOffset);
}
// Now dereference the __forwarding field to get to the real __Block_byref
// struct: DW_OP_deref.
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
// Now that we've got the real __Block_byref... struct, add the offset
// for the variable's field to get to the location of the actual variable:
// DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
if (varFieldOffset > 0) {
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
- addUInt(Loc, dwarf::DW_FORM_udata, varFieldOffset);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+ addUInt(*Loc, dwarf::DW_FORM_udata, varFieldOffset);
}
// Now attach the location information to the DIE.
addBlock(Die, Attribute, Loc);
}
-/// isTypeSigned - Return true if the type is signed.
-static bool isTypeSigned(DwarfDebug *DD, DIType Ty, int *SizeInBits) {
- if (Ty.isDerivedType())
- return isTypeSigned(DD, DD->resolve(DIDerivedType(Ty).getTypeDerivedFrom()),
- SizeInBits);
- if (Ty.isBasicType())
- if (DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed ||
- DIBasicType(Ty).getEncoding() == dwarf::DW_ATE_signed_char) {
- *SizeInBits = Ty.getSizeInBits();
- return true;
- }
- return false;
-}
-
/// Return true if type encoding is unsigned.
static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
DIDerivedType DTy(Ty);
- if (DTy.isDerivedType())
- return isUnsignedDIType(DD, DD->resolve(DTy.getTypeDerivedFrom()));
-
- DIBasicType BTy(Ty);
- if (BTy.isBasicType()) {
- unsigned Encoding = BTy.getEncoding();
- if (Encoding == dwarf::DW_ATE_unsigned ||
- Encoding == dwarf::DW_ATE_unsigned_char ||
- Encoding == dwarf::DW_ATE_boolean)
+ if (DTy.isDerivedType()) {
+ dwarf::Tag T = (dwarf::Tag)Ty.getTag();
+ // Encode pointer constants as unsigned bytes. This is used at least for
+ // null pointer constant emission.
+ // FIXME: reference and rvalue_reference /probably/ shouldn't be allowed
+ // here, but accept them for now due to a bug in SROA producing bogus
+ // dbg.values.
+ if (T == dwarf::DW_TAG_pointer_type ||
+ T == dwarf::DW_TAG_ptr_to_member_type ||
+ T == dwarf::DW_TAG_reference_type ||
+ T == dwarf::DW_TAG_rvalue_reference_type)
return true;
+ assert(T == dwarf::DW_TAG_typedef || T == dwarf::DW_TAG_const_type ||
+ T == dwarf::DW_TAG_volatile_type ||
+ T == dwarf::DW_TAG_restrict_type ||
+ T == dwarf::DW_TAG_enumeration_type);
+ if (DITypeRef Deriv = DTy.getTypeDerivedFrom())
+ return isUnsignedDIType(DD, DD->resolve(Deriv));
+ // FIXME: Enums without a fixed underlying type have unknown signedness
+ // here, leading to incorrectly emitted constants.
+ assert(DTy.getTag() == dwarf::DW_TAG_enumeration_type);
+ return false;
}
- return false;
+
+ DIBasicType BTy(Ty);
+ assert(BTy.isBasicType());
+ unsigned Encoding = BTy.getEncoding();
+ assert((Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char ||
+ Encoding == dwarf::DW_ATE_signed ||
+ Encoding == dwarf::DW_ATE_signed_char ||
+ Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean) &&
+ "Unsupported encoding");
+ return (Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char ||
+ Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean);
}
/// If this type is derived from a base type then return base type size.
@@ -798,47 +815,8 @@ static uint64_t getBaseTypeSize(DwarfDebug *DD, DIDerivedType Ty) {
return BaseType.getSizeInBits();
}
-/// addConstantValue - Add constant value entry in variable DIE.
-void DwarfUnit::addConstantValue(DIE *Die, const MachineOperand &MO,
- DIType Ty) {
- // FIXME: This is a bit conservative/simple - it emits negative values at
- // their maximum bit width which is a bit unfortunate (& doesn't prefer
- // udata/sdata over dataN as suggested by the DWARF spec)
- assert(MO.isImm() && "Invalid machine operand!");
- int SizeInBits = -1;
- bool SignedConstant = isTypeSigned(DD, Ty, &SizeInBits);
- dwarf::Form Form;
-
- // If we're a signed constant definitely use sdata.
- if (SignedConstant) {
- addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, MO.getImm());
- return;
- }
-
- // Else use data for now unless it's larger than we can deal with.
- switch (SizeInBits) {
- case 8:
- Form = dwarf::DW_FORM_data1;
- break;
- case 16:
- Form = dwarf::DW_FORM_data2;
- break;
- case 32:
- Form = dwarf::DW_FORM_data4;
- break;
- case 64:
- Form = dwarf::DW_FORM_data8;
- break;
- default:
- Form = dwarf::DW_FORM_udata;
- addUInt(Die, dwarf::DW_AT_const_value, Form, MO.getImm());
- return;
- }
- addUInt(Die, dwarf::DW_AT_const_value, Form, MO.getImm());
-}
-
/// addConstantFPValue - Add constant value entry in variable DIE.
-void DwarfUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
+void DwarfUnit::addConstantFPValue(DIE &Die, const MachineOperand &MO) {
assert(MO.isFPImm() && "Invalid machine operand!");
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
APFloat FPImm = MO.getFPImm()->getValueAPF();
@@ -855,55 +833,47 @@ void DwarfUnit::addConstantFPValue(DIE *Die, const MachineOperand &MO) {
// Output the constant to DWARF one byte at a time.
for (; Start != Stop; Start += Incr)
- addUInt(Block, dwarf::DW_FORM_data1, (unsigned char)0xFF & FltPtr[Start]);
+ addUInt(*Block, dwarf::DW_FORM_data1, (unsigned char)0xFF & FltPtr[Start]);
addBlock(Die, dwarf::DW_AT_const_value, Block);
}
/// addConstantFPValue - Add constant value entry in variable DIE.
-void DwarfUnit::addConstantFPValue(DIE *Die, const ConstantFP *CFP) {
+void DwarfUnit::addConstantFPValue(DIE &Die, const ConstantFP *CFP) {
// Pass this down to addConstantValue as an unsigned bag of bits.
addConstantValue(Die, CFP->getValueAPF().bitcastToAPInt(), true);
}
/// addConstantValue - Add constant value entry in variable DIE.
-void DwarfUnit::addConstantValue(DIE *Die, const ConstantInt *CI,
- bool Unsigned) {
- addConstantValue(Die, CI->getValue(), Unsigned);
+void DwarfUnit::addConstantValue(DIE &Die, const ConstantInt *CI, DIType Ty) {
+ addConstantValue(Die, CI->getValue(), Ty);
+}
+
+/// addConstantValue - Add constant value entry in variable DIE.
+void DwarfUnit::addConstantValue(DIE &Die, const MachineOperand &MO,
+ DIType Ty) {
+ assert(MO.isImm() && "Invalid machine operand!");
+
+ addConstantValue(Die, isUnsignedDIType(DD, Ty), MO.getImm());
+}
+
+void DwarfUnit::addConstantValue(DIE &Die, bool Unsigned, uint64_t Val) {
+ // FIXME: This is a bit conservative/simple - it emits negative values always
+ // sign extended to 64 bits rather than minimizing the number of bytes.
+ addUInt(Die, dwarf::DW_AT_const_value,
+ Unsigned ? dwarf::DW_FORM_udata : dwarf::DW_FORM_sdata, Val);
+}
+
+void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, DIType Ty) {
+ addConstantValue(Die, Val, isUnsignedDIType(DD, Ty));
}
// addConstantValue - Add constant value entry in variable DIE.
-void DwarfUnit::addConstantValue(DIE *Die, const APInt &Val, bool Unsigned) {
+void DwarfUnit::addConstantValue(DIE &Die, const APInt &Val, bool Unsigned) {
unsigned CIBitWidth = Val.getBitWidth();
if (CIBitWidth <= 64) {
- // If we're a signed constant definitely use sdata.
- if (!Unsigned) {
- addSInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata,
- Val.getSExtValue());
- return;
- }
-
- // Else use data for now unless it's larger than we can deal with.
- dwarf::Form Form;
- switch (CIBitWidth) {
- case 8:
- Form = dwarf::DW_FORM_data1;
- break;
- case 16:
- Form = dwarf::DW_FORM_data2;
- break;
- case 32:
- Form = dwarf::DW_FORM_data4;
- break;
- case 64:
- Form = dwarf::DW_FORM_data8;
- break;
- default:
- addUInt(Die, dwarf::DW_AT_const_value, dwarf::DW_FORM_udata,
- Val.getZExtValue());
- return;
- }
- addUInt(Die, dwarf::DW_AT_const_value, Form, Val.getZExtValue());
+ addConstantValue(Die, Unsigned,
+ Unsigned ? Val.getZExtValue() : Val.getSExtValue());
return;
}
@@ -922,7 +892,7 @@ void DwarfUnit::addConstantValue(DIE *Die, const APInt &Val, bool Unsigned) {
c = Ptr64[i / 8] >> (8 * (i & 7));
else
c = Ptr64[(NumBytes - 1 - i) / 8] >> (8 * ((NumBytes - 1 - i) & 7));
- addUInt(Block, dwarf::DW_FORM_data1, c);
+ addUInt(*Block, dwarf::DW_FORM_data1, c);
}
addBlock(Die, dwarf::DW_AT_const_value, Block);
@@ -945,7 +915,7 @@ void DwarfUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
/// getOrCreateContextDIE - Get context owner's DIE.
DIE *DwarfUnit::getOrCreateContextDIE(DIScope Context) {
if (!Context || Context.isFile())
- return getUnitDie();
+ return &getUnitDie();
if (Context.isType())
return getOrCreateTypeDIE(DIType(Context));
if (Context.isNameSpace())
@@ -959,66 +929,68 @@ DIE *DwarfUnit::createTypeDIE(DICompositeType Ty) {
DIScope Context = resolve(Ty.getContext());
DIE *ContextDIE = getOrCreateContextDIE(Context);
- DIE *TyDIE = getDIE(Ty);
- if (TyDIE)
+ if (DIE *TyDIE = getDIE(Ty))
return TyDIE;
// Create new type.
- TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
+ DIE &TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
- constructTypeDIE(*TyDIE, Ty);
+ constructTypeDIE(TyDIE, Ty);
updateAcceleratorTables(Context, Ty, TyDIE);
- return TyDIE;
+ return &TyDIE;
}
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
if (!TyNode)
- return NULL;
+ return nullptr;
DIType Ty(TyNode);
assert(Ty.isType());
assert(Ty == resolve(Ty.getRef()) &&
"type was not uniqued, possible ODR violation.");
+ // DW_TAG_restrict_type is not supported in DWARF2
+ if (Ty.getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)
+ return getOrCreateTypeDIE(resolve(DIDerivedType(Ty).getTypeDerivedFrom()));
+
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
DIScope Context = resolve(Ty.getContext());
DIE *ContextDIE = getOrCreateContextDIE(Context);
assert(ContextDIE);
- DIE *TyDIE = getDIE(Ty);
- if (TyDIE)
+ if (DIE *TyDIE = getDIE(Ty))
return TyDIE;
// Create new type.
- TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
+ DIE &TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
updateAcceleratorTables(Context, Ty, TyDIE);
if (Ty.isBasicType())
- constructTypeDIE(*TyDIE, DIBasicType(Ty));
+ constructTypeDIE(TyDIE, DIBasicType(Ty));
else if (Ty.isCompositeType()) {
DICompositeType CTy(Ty);
if (GenerateDwarfTypeUnits && !Ty.isForwardDecl())
if (MDString *TypeId = CTy.getIdentifier()) {
DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy);
// Skip updating the accelerator tables since this is not the full type.
- return TyDIE;
+ return &TyDIE;
}
- constructTypeDIE(*TyDIE, CTy);
+ constructTypeDIE(TyDIE, CTy);
} else {
assert(Ty.isDerivedType() && "Unknown kind of DIType");
- constructTypeDIE(*TyDIE, DIDerivedType(Ty));
+ constructTypeDIE(TyDIE, DIDerivedType(Ty));
}
- return TyDIE;
+ return &TyDIE;
}
void DwarfUnit::updateAcceleratorTables(DIScope Context, DIType Ty,
- const DIE *TyDIE) {
+ const DIE &TyDIE) {
if (!Ty.getName().empty() && !Ty.isForwardDecl()) {
bool IsImplementation = 0;
if (Ty.isCompositeType()) {
@@ -1028,17 +1000,18 @@ void DwarfUnit::updateAcceleratorTables(DIScope Context, DIType Ty,
IsImplementation = (CT.getRunTimeLang() == 0) || CT.isObjcClassComplete();
}
unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
- addAccelType(Ty.getName(), std::make_pair(TyDIE, Flags));
+ DD->addAccelType(Ty.getName(), TyDIE, Flags);
if ((!Context || Context.isCompileUnit() || Context.isFile() ||
Context.isNameSpace()) &&
getCUNode().getEmissionKind() != DIBuilder::LineTablesOnly)
- GlobalTypes[getParentContextString(Context) + Ty.getName().str()] = TyDIE;
+ GlobalTypes[getParentContextString(Context) + Ty.getName().str()] =
+ &TyDIE;
}
}
/// addType - Add a new type attribute to the specified entity.
-void DwarfUnit::addType(DIE *Entity, DIType Ty, dwarf::Attribute Attribute) {
+void DwarfUnit::addType(DIE &Entity, DIType Ty, dwarf::Attribute Attribute) {
assert(Ty && "Trying to add a type that doesn't exist?");
// Check for pre-existence.
@@ -1053,54 +1026,17 @@ void DwarfUnit::addType(DIE *Entity, DIType Ty, dwarf::Attribute Attribute) {
DIE *Buffer = getOrCreateTypeDIE(Ty);
// Set up proxy.
- Entry = createDIEEntry(Buffer);
+ Entry = createDIEEntry(*Buffer);
insertDIEEntry(Ty, Entry);
addDIEEntry(Entity, Attribute, Entry);
}
-// Accelerator table mutators - add each name along with its companion
-// DIE to the proper table while ensuring that the name that we're going
-// to reference is in the string table. We do this since the names we
-// add may not only be identical to the names in the DIE.
-void DwarfUnit::addAccelName(StringRef Name, const DIE *Die) {
- if (!DD->useDwarfAccelTables())
- return;
- DU->getStringPoolEntry(Name);
- std::vector<const DIE *> &DIEs = AccelNames[Name];
- DIEs.push_back(Die);
-}
-
-void DwarfUnit::addAccelObjC(StringRef Name, const DIE *Die) {
- if (!DD->useDwarfAccelTables())
- return;
- DU->getStringPoolEntry(Name);
- std::vector<const DIE *> &DIEs = AccelObjC[Name];
- DIEs.push_back(Die);
-}
-
-void DwarfUnit::addAccelNamespace(StringRef Name, const DIE *Die) {
- if (!DD->useDwarfAccelTables())
- return;
- DU->getStringPoolEntry(Name);
- std::vector<const DIE *> &DIEs = AccelNamespace[Name];
- DIEs.push_back(Die);
-}
-
-void DwarfUnit::addAccelType(StringRef Name,
- std::pair<const DIE *, unsigned> Die) {
- if (!DD->useDwarfAccelTables())
- return;
- DU->getStringPoolEntry(Name);
- std::vector<std::pair<const DIE *, unsigned> > &DIEs = AccelTypes[Name];
- DIEs.push_back(Die);
-}
-
/// addGlobalName - Add a new global name to the compile unit.
-void DwarfUnit::addGlobalName(StringRef Name, DIE *Die, DIScope Context) {
+void DwarfUnit::addGlobalName(StringRef Name, DIE &Die, DIScope Context) {
if (getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly)
return;
std::string FullName = getParentContextString(Context) + Name.str();
- GlobalNames[FullName] = Die;
+ GlobalNames[FullName] = &Die;
}
/// getParentContextString - Walks the metadata parent chain in a language
@@ -1149,17 +1085,17 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
StringRef Name = BTy.getName();
// Add name if not anonymous or intermediate type.
if (!Name.empty())
- addString(&Buffer, dwarf::DW_AT_name, Name);
+ addString(Buffer, dwarf::DW_AT_name, Name);
// An unspecified type only has a name attribute.
if (BTy.getTag() == dwarf::DW_TAG_unspecified_type)
return;
- addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
+ addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
BTy.getEncoding());
uint64_t Size = BTy.getSizeInBits() >> 3;
- addUInt(&Buffer, dwarf::DW_AT_byte_size, None, Size);
+ addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
}
/// constructTypeDIE - Construct derived type die from DIDerivedType.
@@ -1172,22 +1108,22 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
// Map to main type, void will not have a type.
DIType FromTy = resolve(DTy.getTypeDerivedFrom());
if (FromTy)
- addType(&Buffer, FromTy);
+ addType(Buffer, FromTy);
// Add name if not anonymous or intermediate type.
if (!Name.empty())
- addString(&Buffer, dwarf::DW_AT_name, Name);
+ addString(Buffer, dwarf::DW_AT_name, Name);
// Add size if non-zero (derived types might be zero-sized.)
if (Size && Tag != dwarf::DW_TAG_pointer_type)
- addUInt(&Buffer, dwarf::DW_AT_byte_size, None, Size);
+ addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
if (Tag == dwarf::DW_TAG_ptr_to_member_type)
- addDIEEntry(&Buffer, dwarf::DW_AT_containing_type,
- getOrCreateTypeDIE(resolve(DTy.getClassType())));
+ addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
+ *getOrCreateTypeDIE(resolve(DTy.getClassType())));
// Add source line info if available and TyDesc is not a forward declaration.
if (!DTy.isForwardDecl())
- addSourceLine(&Buffer, DTy);
+ addSourceLine(Buffer, DTy);
}
/// constructSubprogramArguments - Construct function argument DIEs.
@@ -1198,7 +1134,7 @@ void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DIArray Args) {
assert(i == N-1 && "Unspecified parameter must be the last argument");
createAndAddDIE(dwarf::DW_TAG_unspecified_parameters, Buffer);
} else {
- DIE *Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
+ DIE &Arg = createAndAddDIE(dwarf::DW_TAG_formal_parameter, Buffer);
addType(Arg, DIType(Ty));
if (DIType(Ty).isArtificial())
addFlag(Arg, dwarf::DW_AT_artificial);
@@ -1226,7 +1162,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIArray Elements = CTy.getTypeArray();
DIType RTy(Elements.getElement(0));
if (RTy)
- addType(&Buffer, RTy);
+ addType(Buffer, RTy);
bool isPrototyped = true;
if (Elements.getNumElements() == 2 &&
@@ -1241,13 +1177,13 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (isPrototyped &&
(Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
Language == dwarf::DW_LANG_ObjC))
- addFlag(&Buffer, dwarf::DW_AT_prototyped);
+ addFlag(Buffer, dwarf::DW_AT_prototyped);
if (CTy.isLValueReference())
- addFlag(&Buffer, dwarf::DW_AT_reference);
+ addFlag(Buffer, dwarf::DW_AT_reference);
if (CTy.isRValueReference())
- addFlag(&Buffer, dwarf::DW_AT_rvalue_reference);
+ addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
} break;
case dwarf::DW_TAG_structure_type:
case dwarf::DW_TAG_union_type:
@@ -1256,13 +1192,12 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIArray Elements = CTy.getTypeArray();
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIDescriptor Element = Elements.getElement(i);
- DIE *ElemDie = NULL;
if (Element.isSubprogram())
- ElemDie = getOrCreateSubprogramDIE(DISubprogram(Element));
+ getOrCreateSubprogramDIE(DISubprogram(Element));
else if (Element.isDerivedType()) {
DIDerivedType DDTy(Element);
if (DDTy.getTag() == dwarf::DW_TAG_friend) {
- ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
+ DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
addType(ElemDie, resolve(DDTy.getTypeDerivedFrom()),
dwarf::DW_AT_friend);
} else if (DDTy.isStaticMember()) {
@@ -1272,7 +1207,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
}
} else if (Element.isObjCProperty()) {
DIObjCProperty Property(Element);
- ElemDie = createAndAddDIE(Property.getTag(), Buffer);
+ DIE &ElemDie = createAndAddDIE(Property.getTag(), Buffer);
StringRef PropertyName = Property.getObjCPropertyName();
addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
if (Property.getType())
@@ -1311,15 +1246,15 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
}
if (CTy.isAppleBlockExtension())
- addFlag(&Buffer, dwarf::DW_AT_APPLE_block);
+ addFlag(Buffer, dwarf::DW_AT_APPLE_block);
DICompositeType ContainingType(resolve(CTy.getContainingType()));
if (ContainingType)
- addDIEEntry(&Buffer, dwarf::DW_AT_containing_type,
- getOrCreateTypeDIE(ContainingType));
+ addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
+ *getOrCreateTypeDIE(ContainingType));
if (CTy.isObjcClassComplete())
- addFlag(&Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
+ addFlag(Buffer, dwarf::DW_AT_APPLE_objc_complete_type);
// Add template parameters to a class, structure or union types.
// FIXME: The support isn't in the metadata for this yet.
@@ -1335,7 +1270,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// Add name if not anonymous or intermediate type.
if (!Name.empty())
- addString(&Buffer, dwarf::DW_AT_name, Name);
+ addString(Buffer, dwarf::DW_AT_name, Name);
if (Tag == dwarf::DW_TAG_enumeration_type ||
Tag == dwarf::DW_TAG_class_type || Tag == dwarf::DW_TAG_structure_type ||
@@ -1343,23 +1278,23 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// Add size if non-zero (derived types might be zero-sized.)
// TODO: Do we care about size for enum forward declarations?
if (Size)
- addUInt(&Buffer, dwarf::DW_AT_byte_size, None, Size);
+ addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
else if (!CTy.isForwardDecl())
// Add zero size if it is not a forward declaration.
- addUInt(&Buffer, dwarf::DW_AT_byte_size, None, 0);
+ addUInt(Buffer, dwarf::DW_AT_byte_size, None, 0);
// If we're a forward decl, say so.
if (CTy.isForwardDecl())
- addFlag(&Buffer, dwarf::DW_AT_declaration);
+ addFlag(Buffer, dwarf::DW_AT_declaration);
// Add source line info if available.
if (!CTy.isForwardDecl())
- addSourceLine(&Buffer, CTy);
+ addSourceLine(Buffer, CTy);
// No harm in adding the runtime language to the declaration.
unsigned RLang = CTy.getRunTimeLang();
if (RLang)
- addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
+ addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
RLang);
}
}
@@ -1368,7 +1303,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
/// DITemplateTypeParameter.
void DwarfUnit::constructTemplateTypeParameterDIE(DIE &Buffer,
DITemplateTypeParameter TP) {
- DIE *ParamDIE =
+ DIE &ParamDIE =
createAndAddDIE(dwarf::DW_TAG_template_type_parameter, Buffer);
// Add the type if it exists, it could be void and therefore no type.
if (TP.getType())
@@ -1382,7 +1317,7 @@ void DwarfUnit::constructTemplateTypeParameterDIE(DIE &Buffer,
void
DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer,
DITemplateValueParameter VP) {
- DIE *ParamDIE = createAndAddDIE(VP.getTag(), Buffer);
+ DIE &ParamDIE = createAndAddDIE(VP.getTag(), Buffer);
// Add the type if there is one, template template and template parameter
// packs will not have a type.
@@ -1392,16 +1327,15 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer,
addString(ParamDIE, dwarf::DW_AT_name, VP.getName());
if (Value *Val = VP.getValue()) {
if (ConstantInt *CI = dyn_cast<ConstantInt>(Val))
- addConstantValue(ParamDIE, CI,
- isUnsignedDIType(DD, resolve(VP.getType())));
+ addConstantValue(ParamDIE, CI, resolve(VP.getType()));
else if (GlobalValue *GV = dyn_cast<GlobalValue>(Val)) {
// For declaration non-type template parameters (such as global values and
// functions)
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
- addOpAddress(Loc, Asm->getSymbol(GV));
+ addOpAddress(*Loc, Asm->getSymbol(GV));
// Emit DW_OP_stack_value to use the address as the immediate value of the
// parameter, rather than a pointer to it.
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_stack_value);
addBlock(ParamDIE, dwarf::DW_AT_location, Loc);
} else if (VP.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
assert(isa<MDString>(Val));
@@ -1410,7 +1344,7 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer,
} else if (VP.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
assert(isa<MDNode>(Val));
DIArray A(cast<MDNode>(Val));
- addTemplateParams(*ParamDIE, A);
+ addTemplateParams(ParamDIE, A);
}
}
}
@@ -1421,19 +1355,18 @@ DIE *DwarfUnit::getOrCreateNameSpace(DINameSpace NS) {
// such construction creates the DIE.
DIE *ContextDIE = getOrCreateContextDIE(NS.getContext());
- DIE *NDie = getDIE(NS);
- if (NDie)
+ if (DIE *NDie = getDIE(NS))
return NDie;
- NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);
+ DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);
if (!NS.getName().empty()) {
addString(NDie, dwarf::DW_AT_name, NS.getName());
- addAccelNamespace(NS.getName(), NDie);
+ DD->addAccelNamespace(NS.getName(), NDie);
addGlobalName(NS.getName(), NDie, NS.getContext());
} else
- addAccelNamespace("(anonymous namespace)", NDie);
+ DD->addAccelNamespace("(anonymous namespace)", NDie);
addSourceLine(NDie, NS);
- return NDie;
+ return &NDie;
}
/// getOrCreateSubprogramDIE - Create new DIE using SP.
@@ -1441,47 +1374,58 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE (as is the case for member function
// declarations).
- DIScope Context = resolve(SP.getContext());
- DIE *ContextDIE = getOrCreateContextDIE(Context);
+ DIE *ContextDIE = getOrCreateContextDIE(resolve(SP.getContext()));
- // Unique declarations based on the ODR, where applicable.
- SP = DISubprogram(DD->resolve(SP.getRef()));
- assert(SP.Verify());
-
- DIE *SPDie = getDIE(SP);
- if (SPDie)
+ if (DIE *SPDie = getDIE(SP))
return SPDie;
- DISubprogram SPDecl = SP.getFunctionDeclaration();
- if (SPDecl.isSubprogram())
+ if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
// Add subprogram definitions to the CU die directly.
- ContextDIE = UnitDie.get();
+ ContextDIE = &getUnitDie();
+ // Build the decl now to ensure it preceeds the definition.
+ getOrCreateSubprogramDIE(SPDecl);
+ }
// DW_TAG_inlined_subroutine may refer to this DIE.
- SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
-
- DIE *DeclDie = NULL;
- if (SPDecl.isSubprogram())
- DeclDie = getOrCreateSubprogramDIE(SPDecl);
+ DIE &SPDie = createAndAddDIE(dwarf::DW_TAG_subprogram, *ContextDIE, SP);
- // Add function template parameters.
- addTemplateParams(*SPDie, SP.getTemplateParams());
+ // Abort here and fill this in later, depending on whether or not this
+ // subprogram turns out to have inlined instances or not.
+ if (SP.isDefinition())
+ return &SPDie;
- // If this DIE is going to refer declaration info using AT_specification
- // then there is no need to add other attributes.
- if (DeclDie) {
- // Refer function declaration directly.
- addDIEEntry(SPDie, dwarf::DW_AT_specification, DeclDie);
+ applySubprogramAttributes(SP, SPDie);
+ return &SPDie;
+}
- return SPDie;
+void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie) {
+ DIE *DeclDie = nullptr;
+ StringRef DeclLinkageName;
+ if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+ DeclDie = getDIE(SPDecl);
+ assert(DeclDie);
+ DeclLinkageName = SPDecl.getLinkageName();
}
- // Add the linkage name if we have one.
+ // Add function template parameters.
+ addTemplateParams(SPDie, SP.getTemplateParams());
+
+ // Add the linkage name if we have one and it isn't in the Decl.
StringRef LinkageName = SP.getLinkageName();
- if (!LinkageName.empty())
+ assert(((LinkageName.empty() || DeclLinkageName.empty()) ||
+ LinkageName == DeclLinkageName) &&
+ "decl has a linkage name and it is different");
+ if (!LinkageName.empty() && DeclLinkageName.empty())
addString(SPDie, dwarf::DW_AT_MIPS_linkage_name,
GlobalValue::getRealLinkageName(LinkageName));
+ if (DeclDie) {
+ // Refer to the function declaration where all the other attributes will be
+ // found.
+ addDIEEntry(SPDie, dwarf::DW_AT_specification, *DeclDie);
+ return;
+ }
+
// Constructors and operators for anonymous aggregates do not have names.
if (!SP.getName().empty())
addString(SPDie, dwarf::DW_AT_name, SP.getName());
@@ -1510,11 +1454,11 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
if (VK) {
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1, VK);
DIELoc *Block = getDIELoc();
- addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
- addUInt(Block, dwarf::DW_FORM_udata, SP.getVirtualIndex());
+ addUInt(*Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
+ addUInt(*Block, dwarf::DW_FORM_udata, SP.getVirtualIndex());
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, Block);
ContainingTypeMap.insert(
- std::make_pair(SPDie, resolve(SP.getContainingType())));
+ std::make_pair(&SPDie, resolve(SP.getContainingType())));
}
if (!SP.isDefinition()) {
@@ -1522,7 +1466,7 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
// Add arguments. Do not add arguments for subprogram definition. They will
// be handled while processing variables.
- constructSubprogramArguments(*SPDie, Args);
+ constructSubprogramArguments(SPDie, Args);
}
if (SP.isArtificial())
@@ -1556,8 +1500,6 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP) {
if (SP.isExplicit())
addFlag(SPDie, dwarf::DW_AT_explicit);
-
- return SPDie;
}
// Return const expression if value is a GEP to access merged global
@@ -1567,22 +1509,22 @@ static const ConstantExpr *getMergedGlobalExpr(const Value *V) {
const ConstantExpr *CE = dyn_cast_or_null<ConstantExpr>(V);
if (!CE || CE->getNumOperands() != 3 ||
CE->getOpcode() != Instruction::GetElementPtr)
- return NULL;
+ return nullptr;
// First operand points to a global struct.
Value *Ptr = CE->getOperand(0);
if (!isa<GlobalValue>(Ptr) ||
!isa<StructType>(cast<PointerType>(Ptr->getType())->getElementType()))
- return NULL;
+ return nullptr;
// Second operand is zero.
const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(CE->getOperand(1));
if (!CI || !CI->isZero())
- return NULL;
+ return nullptr;
// Third operand is offset.
if (!isa<ConstantInt>(CE->getOperand(2)))
- return NULL;
+ return nullptr;
return CE;
}
@@ -1600,7 +1542,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
// If this is a static data member definition, some attributes belong
// to the declaration DIE.
- DIE *VariableDIE = NULL;
+ DIE *VariableDIE = nullptr;
bool IsStaticMember = false;
DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration();
if (SDMDecl.Verify()) {
@@ -1618,24 +1560,24 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
DIE *ContextDIE = getOrCreateContextDIE(GVContext);
// Add to map.
- VariableDIE = createAndAddDIE(GV.getTag(), *ContextDIE, GV);
+ VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV);
// Add name and type.
- addString(VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
- addType(VariableDIE, GTy);
+ addString(*VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
+ addType(*VariableDIE, GTy);
// Add scoping info.
if (!GV.isLocalToUnit())
- addFlag(VariableDIE, dwarf::DW_AT_external);
+ addFlag(*VariableDIE, dwarf::DW_AT_external);
// Add line number info.
- addSourceLine(VariableDIE, GV);
+ addSourceLine(*VariableDIE, GV);
}
// Add location.
bool addToAccelTable = false;
- DIE *VariableSpecDIE = NULL;
- bool isGlobalVariable = GV.getGlobal() != NULL;
+ DIE *VariableSpecDIE = nullptr;
+ bool isGlobalVariable = GV.getGlobal() != nullptr;
if (isGlobalVariable) {
addToAccelTable = true;
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
@@ -1648,36 +1590,36 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
// Based on GCC's support for TLS:
if (!DD->useSplitDwarf()) {
// 1) Start with a constNu of the appropriate pointer size
- addUInt(Loc, dwarf::DW_FORM_data1,
+ addUInt(*Loc, dwarf::DW_FORM_data1,
PointerSize == 4 ? dwarf::DW_OP_const4u : dwarf::DW_OP_const8u);
// 2) containing the (relocated) offset of the TLS variable
// within the module's TLS block.
- addExpr(Loc, dwarf::DW_FORM_udata,
+ addExpr(*Loc, dwarf::DW_FORM_udata,
Asm->getObjFileLowering().getDebugThreadLocalSymbol(Sym));
} else {
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
- addUInt(Loc, dwarf::DW_FORM_udata,
- DU->getAddrPoolIndex(Sym, /* TLS */ true));
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_const_index);
+ addUInt(*Loc, dwarf::DW_FORM_udata,
+ DD->getAddressPool().getIndex(Sym, /* TLS */ true));
}
// 3) followed by a custom OP to make the debugger do a TLS lookup.
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_GNU_push_tls_address);
} else {
DD->addArangeLabel(SymbolCU(this, Sym));
- addOpAddress(Loc, Sym);
+ addOpAddress(*Loc, Sym);
}
// Do not create specification DIE if context is either compile unit
// or a subprogram.
if (GVContext && GV.isDefinition() && !GVContext.isCompileUnit() &&
!GVContext.isFile() && !DD->isSubprogramContext(GVContext)) {
// Create specification DIE.
- VariableSpecDIE = createAndAddDIE(dwarf::DW_TAG_variable, *UnitDie);
- addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, VariableDIE);
- addBlock(VariableSpecDIE, dwarf::DW_AT_location, Loc);
+ VariableSpecDIE = &createAndAddDIE(dwarf::DW_TAG_variable, UnitDie);
+ addDIEEntry(*VariableSpecDIE, dwarf::DW_AT_specification, *VariableDIE);
+ addBlock(*VariableSpecDIE, dwarf::DW_AT_location, Loc);
// A static member's declaration is already flagged as such.
if (!SDMDecl.Verify())
- addFlag(VariableDIE, dwarf::DW_AT_declaration);
+ addFlag(*VariableDIE, dwarf::DW_AT_declaration);
} else {
- addBlock(VariableDIE, dwarf::DW_AT_location, Loc);
+ addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
}
// Add the linkage name.
StringRef LinkageName = GV.getLinkageName();
@@ -1685,8 +1627,8 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
// From DWARF4: DIEs to which DW_AT_linkage_name may apply include:
// TAG_common_block, TAG_constant, TAG_entry_point, TAG_subprogram and
// TAG_variable.
- addString(IsStaticMember && VariableSpecDIE ? VariableSpecDIE
- : VariableDIE,
+ addString(IsStaticMember && VariableSpecDIE ? *VariableSpecDIE
+ : *VariableDIE,
DD->getDwarfVersion() >= 4 ? dwarf::DW_AT_linkage_name
: dwarf::DW_AT_MIPS_linkage_name,
GlobalValue::getRealLinkageName(LinkageName));
@@ -1696,7 +1638,7 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
// emitting AT_const_value multiple times, we only add AT_const_value when
// it is not a static member.
if (!IsStaticMember)
- addConstantValue(VariableDIE, CI, isUnsignedDIType(DD, GTy));
+ addConstantValue(*VariableDIE, CI, GTy);
} else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getOperand(11))) {
addToAccelTable = true;
// GV is a merged global.
@@ -1704,34 +1646,35 @@ void DwarfCompileUnit::createGlobalVariableDIE(DIGlobalVariable GV) {
Value *Ptr = CE->getOperand(0);
MCSymbol *Sym = Asm->getSymbol(cast<GlobalValue>(Ptr));
DD->addArangeLabel(SymbolCU(this, Sym));
- addOpAddress(Loc, Sym);
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
+ addOpAddress(*Loc, Sym);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
SmallVector<Value *, 3> Idx(CE->op_begin() + 1, CE->op_end());
- addUInt(Loc, dwarf::DW_FORM_udata,
+ addUInt(*Loc, dwarf::DW_FORM_udata,
Asm->getDataLayout().getIndexedOffset(Ptr->getType(), Idx));
- addUInt(Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
- addBlock(VariableDIE, dwarf::DW_AT_location, Loc);
+ addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+ addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
}
if (addToAccelTable) {
- DIE *AddrDIE = VariableSpecDIE ? VariableSpecDIE : VariableDIE;
- addAccelName(GV.getName(), AddrDIE);
+ DIE &AddrDIE = VariableSpecDIE ? *VariableSpecDIE : *VariableDIE;
+ DD->addAccelName(GV.getName(), AddrDIE);
// If the linkage name is different than the name, go ahead and output
// that as well into the name table.
if (GV.getLinkageName() != "" && GV.getName() != GV.getLinkageName())
- addAccelName(GV.getLinkageName(), AddrDIE);
+ DD->addAccelName(GV.getLinkageName(), AddrDIE);
}
if (!GV.isLocalToUnit())
- addGlobalName(GV.getName(), VariableSpecDIE ? VariableSpecDIE : VariableDIE,
+ addGlobalName(GV.getName(),
+ VariableSpecDIE ? *VariableSpecDIE : *VariableDIE,
GV.getContext());
}
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
void DwarfUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy) {
- DIE *DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer);
- addDIEEntry(DW_Subrange, dwarf::DW_AT_type, IndexTy);
+ DIE &DW_Subrange = createAndAddDIE(dwarf::DW_TAG_subrange_type, Buffer);
+ addDIEEntry(DW_Subrange, dwarf::DW_AT_type, *IndexTy);
// The LowerBound value defines the lower bounds which is typically zero for
// C/C++. The Count value is the number of elements. Values are 64 bit. If
@@ -1756,10 +1699,10 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy) {
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
if (CTy.isVector())
- addFlag(&Buffer, dwarf::DW_AT_GNU_vector);
+ addFlag(Buffer, dwarf::DW_AT_GNU_vector);
// Emit the element type.
- addType(&Buffer, resolve(CTy.getTypeDerivedFrom()));
+ addType(Buffer, resolve(CTy.getTypeDerivedFrom()));
// Get an anonymous type for index type.
// FIXME: This type should be passed down from the front end
@@ -1767,10 +1710,10 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIE *IdxTy = getIndexTyDie();
if (!IdxTy) {
// Construct an integer type to use for indexes.
- IdxTy = createAndAddDIE(dwarf::DW_TAG_base_type, *UnitDie);
- addString(IdxTy, dwarf::DW_AT_name, "sizetype");
- addUInt(IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int64_t));
- addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
+ IdxTy = &createAndAddDIE(dwarf::DW_TAG_base_type, UnitDie);
+ addString(*IdxTy, dwarf::DW_AT_name, "sizetype");
+ addUInt(*IdxTy, dwarf::DW_AT_byte_size, None, sizeof(int64_t));
+ addUInt(*IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
dwarf::DW_ATE_unsigned);
setIndexTyDie(IdxTy);
}
@@ -1792,7 +1735,7 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) {
for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
DIEnumerator Enum(Elements.getElement(i));
if (Enum.isEnumerator()) {
- DIE *Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
+ DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
StringRef Name = Enum.getName();
addString(Enumerator, dwarf::DW_AT_name, Name);
int64_t Value = Enum.getEnumValue();
@@ -1802,8 +1745,8 @@ void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) {
}
DIType DTy = resolve(CTy.getTypeDerivedFrom());
if (DTy) {
- addType(&Buffer, DTy);
- addFlag(&Buffer, dwarf::DW_AT_enum_class);
+ addType(Buffer, DTy);
+ addFlag(Buffer, dwarf::DW_AT_enum_class);
}
}
@@ -1813,48 +1756,51 @@ void DwarfUnit::constructContainingTypeDIEs() {
for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
CE = ContainingTypeMap.end();
CI != CE; ++CI) {
- DIE *SPDie = CI->first;
+ DIE &SPDie = *CI->first;
DIDescriptor D(CI->second);
if (!D)
continue;
DIE *NDie = getDIE(D);
if (!NDie)
continue;
- addDIEEntry(SPDie, dwarf::DW_AT_containing_type, NDie);
+ addDIEEntry(SPDie, dwarf::DW_AT_containing_type, *NDie);
}
}
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
-DIE *DwarfUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) {
+std::unique_ptr<DIE> DwarfUnit::constructVariableDIE(DbgVariable &DV,
+ bool Abstract) {
+ auto D = constructVariableDIEImpl(DV, Abstract);
+ DV.setDIE(*D);
+ return D;
+}
+
+std::unique_ptr<DIE> DwarfUnit::constructVariableDIEImpl(const DbgVariable &DV,
+ bool Abstract) {
StringRef Name = DV.getName();
// Define variable debug information entry.
- DIE *VariableDie = new DIE(DV.getTag());
+ auto VariableDie = make_unique<DIE>(DV.getTag());
DbgVariable *AbsVar = DV.getAbstractVariable();
- DIE *AbsDIE = AbsVar ? AbsVar->getDIE() : NULL;
- if (AbsDIE)
- addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin, AbsDIE);
+ if (AbsVar && AbsVar->getDIE())
+ addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin, *AbsVar->getDIE());
else {
if (!Name.empty())
- addString(VariableDie, dwarf::DW_AT_name, Name);
- addSourceLine(VariableDie, DV.getVariable());
- addType(VariableDie, DV.getType());
+ addString(*VariableDie, dwarf::DW_AT_name, Name);
+ addSourceLine(*VariableDie, DV.getVariable());
+ addType(*VariableDie, DV.getType());
+ if (DV.isArtificial())
+ addFlag(*VariableDie, dwarf::DW_AT_artificial);
}
- if (DV.isArtificial())
- addFlag(VariableDie, dwarf::DW_AT_artificial);
-
- if (isScopeAbstract) {
- DV.setDIE(VariableDie);
+ if (Abstract)
return VariableDie;
- }
// Add variable address.
unsigned Offset = DV.getDotDebugLocOffset();
if (Offset != ~0U) {
- addLocationList(VariableDie, dwarf::DW_AT_location, Offset);
- DV.setDIE(VariableDie);
+ addLocationList(*VariableDie, dwarf::DW_AT_location, Offset);
return VariableDie;
}
@@ -1867,38 +1813,36 @@ DIE *DwarfUnit::constructVariableDIE(DbgVariable &DV, bool isScopeAbstract) {
if (DVInsn->getOperand(1).isImm()) {
MachineLocation Location(RegOp.getReg(),
DVInsn->getOperand(1).getImm());
- addVariableAddress(DV, VariableDie, Location);
+ addVariableAddress(DV, *VariableDie, Location);
} else if (RegOp.getReg())
- addVariableAddress(DV, VariableDie, MachineLocation(RegOp.getReg()));
+ addVariableAddress(DV, *VariableDie, MachineLocation(RegOp.getReg()));
} else if (DVInsn->getOperand(0).isImm())
- addConstantValue(VariableDie, DVInsn->getOperand(0), DV.getType());
+ addConstantValue(*VariableDie, DVInsn->getOperand(0), DV.getType());
else if (DVInsn->getOperand(0).isFPImm())
- addConstantFPValue(VariableDie, DVInsn->getOperand(0));
+ addConstantFPValue(*VariableDie, DVInsn->getOperand(0));
else if (DVInsn->getOperand(0).isCImm())
- addConstantValue(VariableDie, DVInsn->getOperand(0).getCImm(),
- isUnsignedDIType(DD, DV.getType()));
+ addConstantValue(*VariableDie, DVInsn->getOperand(0).getCImm(),
+ DV.getType());
- DV.setDIE(VariableDie);
return VariableDie;
- } else {
- // .. else use frame index.
- int FI = DV.getFrameIndex();
- if (FI != ~0) {
- unsigned FrameReg = 0;
- const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
- int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
- MachineLocation Location(FrameReg, Offset);
- addVariableAddress(DV, VariableDie, Location);
- }
}
- DV.setDIE(VariableDie);
+ // .. else use frame index.
+ int FI = DV.getFrameIndex();
+ if (FI != ~0) {
+ unsigned FrameReg = 0;
+ const TargetFrameLowering *TFI = Asm->TM.getFrameLowering();
+ int Offset = TFI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
+ MachineLocation Location(FrameReg, Offset);
+ addVariableAddress(DV, *VariableDie, Location);
+ }
+
return VariableDie;
}
/// constructMemberDIE - Construct member DIE from DIDerivedType.
void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
- DIE *MemberDie = createAndAddDIE(DT.getTag(), Buffer);
+ DIE &MemberDie = createAndAddDIE(DT.getTag(), Buffer);
StringRef Name = DT.getName();
if (!Name.empty())
addString(MemberDie, dwarf::DW_AT_name, Name);
@@ -1914,13 +1858,13 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
// BaseAddr = ObAddr + *((*ObAddr) - Offset)
DIELoc *VBaseLocationDie = new (DIEValueAllocator) DIELoc();
- addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
- addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
- addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
- addUInt(VBaseLocationDie, dwarf::DW_FORM_udata, DT.getOffsetInBits());
- addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
- addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
- addUInt(VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_udata, DT.getOffsetInBits());
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
+ addUInt(*VBaseLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
addBlock(MemberDie, dwarf::DW_AT_data_member_location, VBaseLocationDie);
} else {
@@ -1953,8 +1897,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
if (DD->getDwarfVersion() <= 2) {
DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc();
- addUInt(MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
- addUInt(MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
+ addUInt(*MemLocationDie, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
+ addUInt(*MemLocationDie, dwarf::DW_FORM_udata, OffsetInBytes);
addBlock(MemberDie, dwarf::DW_AT_data_member_location, MemLocationDie);
} else
addUInt(MemberDie, dwarf::DW_AT_data_member_location, None,
@@ -1978,8 +1922,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
// Objective-C properties.
if (MDNode *PNode = DT.getObjCProperty())
if (DIEEntry *PropertyDie = getDIEEntry(PNode))
- MemberDie->addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
- PropertyDie);
+ MemberDie.addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
+ PropertyDie);
if (DT.isArtificial())
addFlag(MemberDie, dwarf::DW_AT_artificial);
@@ -1988,7 +1932,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
/// getOrCreateStaticMemberDIE - Create new DIE for C++ static member.
DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) {
if (!DT.Verify())
- return NULL;
+ return nullptr;
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
@@ -1996,11 +1940,10 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) {
assert(dwarf::isType(ContextDIE->getTag()) &&
"Static member should belong to a type.");
- DIE *StaticMemberDIE = getDIE(DT);
- if (StaticMemberDIE)
+ if (DIE *StaticMemberDIE = getDIE(DT))
return StaticMemberDIE;
- StaticMemberDIE = createAndAddDIE(DT.getTag(), *ContextDIE, DT);
+ DIE &StaticMemberDIE = createAndAddDIE(DT.getTag(), *ContextDIE, DT);
DIType Ty = resolve(DT.getTypeDerivedFrom());
@@ -2023,11 +1966,11 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) {
dwarf::DW_ACCESS_public);
if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT.getConstant()))
- addConstantValue(StaticMemberDIE, CI, isUnsignedDIType(DD, Ty));
+ addConstantValue(StaticMemberDIE, CI, Ty);
if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT.getConstant()))
addConstantFPValue(StaticMemberDIE, CFP);
- return StaticMemberDIE;
+ return &StaticMemberDIE;
}
void DwarfUnit::emitHeader(const MCSymbol *ASectionSym) const {
@@ -2072,7 +2015,7 @@ void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) {
MCSymbol *LineTableStartSym =
Asm->OutStreamer.getDwarfLineTableSymbol(getUniqueID());
- stmtListIndex = UnitDie->getValues().size();
+ stmtListIndex = UnitDie.getValues().size();
// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section. For split dwarf this is
@@ -2080,16 +2023,16 @@ void DwarfCompileUnit::initStmtList(MCSymbol *DwarfLineSectionSym) {
// The line table entries are not always emitted in assembly, so it
// is not okay to use line_table_start here.
if (Asm->MAI->doesDwarfUseRelocationsAcrossSections())
- addSectionLabel(UnitDie.get(), dwarf::DW_AT_stmt_list, LineTableStartSym);
+ addSectionLabel(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym);
else
- addSectionDelta(UnitDie.get(), dwarf::DW_AT_stmt_list, LineTableStartSym,
+ addSectionDelta(UnitDie, dwarf::DW_AT_stmt_list, LineTableStartSym,
DwarfLineSectionSym);
}
void DwarfCompileUnit::applyStmtList(DIE &D) {
D.addValue(dwarf::DW_AT_stmt_list,
- UnitDie->getAbbrev().getData()[stmtListIndex].getForm(),
- UnitDie->getValues()[stmtListIndex]);
+ UnitDie.getAbbrev().getData()[stmtListIndex].getForm(),
+ UnitDie.getValues()[stmtListIndex]);
}
void DwarfTypeUnit::emitHeader(const MCSymbol *ASectionSym) const {
@@ -2114,5 +2057,4 @@ void DwarfTypeUnit::initSection(const MCSection *Section) {
Asm->GetTempSymbol(Section->getLabelBeginName(), getUniqueID());
this->LabelEnd =
Asm->GetTempSymbol(Section->getLabelEndName(), getUniqueID());
- this->LabelRange = Asm->GetTempSymbol("gnu_ranges", getUniqueID());
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h
index ef713f7..acb7528 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -73,7 +73,7 @@ protected:
DICompileUnit CUNode;
/// Unit debug information entry.
- const std::unique_ptr<DIE> UnitDie;
+ DIE UnitDie;
/// Offset of the UnitDie from beginning of debug info section.
unsigned DebugInfoOffset;
@@ -102,18 +102,6 @@ protected:
/// GlobalTypes - A map of globally visible types for this unit.
StringMap<const DIE *> GlobalTypes;
- /// AccelNames - A map of names for the name accelerator table.
- StringMap<std::vector<const DIE *> > AccelNames;
-
- /// AccelObjC - A map of objc spec for the objc accelerator table.
- StringMap<std::vector<const DIE *> > AccelObjC;
-
- /// AccelNamespace - A map of names for the namespace accelerator table.
- StringMap<std::vector<const DIE *> > AccelNamespace;
-
- /// AccelTypes - A map of names for the type accelerator table.
- StringMap<std::vector<std::pair<const DIE *, unsigned> > > AccelTypes;
-
/// DIEBlocks - A list of all the DIEBlocks in use.
std::vector<DIEBlock *> DIEBlocks;
@@ -150,20 +138,17 @@ protected:
/// The end of the unit within its section.
MCSymbol *LabelEnd;
- /// The label for the start of the range sets for the elements of this unit.
- MCSymbol *LabelRange;
-
/// Skeleton unit associated with this unit.
DwarfUnit *Skeleton;
- DwarfUnit(unsigned UID, DIE *D, DICompileUnit CU, AsmPrinter *A,
+ DwarfUnit(unsigned UID, dwarf::Tag, DICompileUnit CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
public:
virtual ~DwarfUnit();
/// Set the skeleton unit associated with this unit.
- void setSkeleton(DwarfUnit *Skel) { Skeleton = Skel; }
+ void setSkeleton(DwarfUnit &Skel) { Skeleton = &Skel; }
/// Get the skeleton unit associated with this unit.
DwarfUnit *getSkeleton() const { return Skeleton; }
@@ -179,7 +164,6 @@ public:
Asm->GetTempSymbol(Section->getLabelBeginName(), getUniqueID());
this->LabelEnd =
Asm->GetTempSymbol(Section->getLabelEndName(), getUniqueID());
- this->LabelRange = Asm->GetTempSymbol("gnu_ranges", getUniqueID());
}
const MCSection *getSection() const {
@@ -218,38 +202,19 @@ public:
return LabelEnd;
}
- MCSymbol *getLabelRange() const {
- assert(Section);
- return LabelRange;
- }
-
// Accessors.
unsigned getUniqueID() const { return UniqueID; }
uint16_t getLanguage() const { return CUNode.getLanguage(); }
DICompileUnit getCUNode() const { return CUNode; }
- DIE *getUnitDie() const { return UnitDie.get(); }
+ DIE &getUnitDie() { return UnitDie; }
const StringMap<const DIE *> &getGlobalNames() const { return GlobalNames; }
const StringMap<const DIE *> &getGlobalTypes() const { return GlobalTypes; }
- const StringMap<std::vector<const DIE *> > &getAccelNames() const {
- return AccelNames;
- }
- const StringMap<std::vector<const DIE *> > &getAccelObjC() const {
- return AccelObjC;
- }
- const StringMap<std::vector<const DIE *> > &getAccelNamespace() const {
- return AccelNamespace;
- }
- const StringMap<std::vector<std::pair<const DIE *, unsigned> > > &
- getAccelTypes() const {
- return AccelTypes;
- }
-
unsigned getDebugInfoOffset() const { return DebugInfoOffset; }
void setDebugInfoOffset(unsigned DbgInfoOff) { DebugInfoOffset = DbgInfoOff; }
/// hasContent - Return true if this compile unit has something to write out.
- bool hasContent() const { return !UnitDie->getChildren().empty(); }
+ bool hasContent() const { return !UnitDie.getChildren().empty(); }
/// addRange - Add an address range to the list of ranges for this unit.
void addRange(RangeSpan Range);
@@ -273,19 +238,10 @@ public:
/// addGlobalName - Add a new global entity to the compile unit.
///
- void addGlobalName(StringRef Name, DIE *Die, DIScope Context);
-
- /// addAccelName - Add a new name to the name accelerator table.
- void addAccelName(StringRef Name, const DIE *Die);
-
- /// addAccelObjC - Add a new name to the ObjC accelerator table.
- void addAccelObjC(StringRef Name, const DIE *Die);
+ void addGlobalName(StringRef Name, DIE &Die, DIScope Context);
/// addAccelNamespace - Add a new name to the namespace accelerator table.
- void addAccelNamespace(StringRef Name, const DIE *Die);
-
- /// addAccelType - Add a new type to the type accelerator table.
- void addAccelType(StringRef Name, std::pair<const DIE *, unsigned> Die);
+ void addAccelNamespace(StringRef Name, const DIE &Die);
/// getDIE - Returns the debug information entry map slot for the
/// specified debug variable. We delegate the request to DwarfDebug
@@ -303,118 +259,116 @@ public:
/// kept in DwarfDebug.
void insertDIE(DIDescriptor Desc, DIE *D);
- /// addDie - Adds or interns the DIE to the compile unit.
- ///
- void addDie(DIE *Buffer) { UnitDie->addChild(Buffer); }
-
/// addFlag - Add a flag that is true to the DIE.
- void addFlag(DIE *Die, dwarf::Attribute Attribute);
+ void addFlag(DIE &Die, dwarf::Attribute Attribute);
/// addUInt - Add an unsigned integer attribute data and value.
- void addUInt(DIE *Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
+ void addUInt(DIE &Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
uint64_t Integer);
- void addUInt(DIE *Block, dwarf::Form Form, uint64_t Integer);
+ void addUInt(DIE &Block, dwarf::Form Form, uint64_t Integer);
/// addSInt - Add an signed integer attribute data and value.
- void addSInt(DIE *Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
+ void addSInt(DIE &Die, dwarf::Attribute Attribute, Optional<dwarf::Form> Form,
int64_t Integer);
- void addSInt(DIELoc *Die, Optional<dwarf::Form> Form, int64_t Integer);
+ void addSInt(DIELoc &Die, Optional<dwarf::Form> Form, int64_t Integer);
/// addString - Add a string attribute data and value.
- void addString(DIE *Die, dwarf::Attribute Attribute, const StringRef Str);
+ void addString(DIE &Die, dwarf::Attribute Attribute, const StringRef Str);
/// addLocalString - Add a string attribute data and value.
- void addLocalString(DIE *Die, dwarf::Attribute Attribute,
+ void addLocalString(DIE &Die, dwarf::Attribute Attribute,
const StringRef Str);
/// addExpr - Add a Dwarf expression attribute data and value.
- void addExpr(DIELoc *Die, dwarf::Form Form, const MCExpr *Expr);
+ void addExpr(DIELoc &Die, dwarf::Form Form, const MCExpr *Expr);
/// addLabel - Add a Dwarf label attribute data and value.
- void addLabel(DIE *Die, dwarf::Attribute Attribute, dwarf::Form Form,
+ void addLabel(DIE &Die, dwarf::Attribute Attribute, dwarf::Form Form,
const MCSymbol *Label);
- void addLabel(DIELoc *Die, dwarf::Form Form, const MCSymbol *Label);
+ void addLabel(DIELoc &Die, dwarf::Form Form, const MCSymbol *Label);
/// addLocationList - Add a Dwarf loclistptr attribute data and value.
- void addLocationList(DIE *Die, dwarf::Attribute Attribute, unsigned Index);
+ void addLocationList(DIE &Die, dwarf::Attribute Attribute, unsigned Index);
/// addSectionLabel - Add a Dwarf section label attribute data and value.
///
- void addSectionLabel(DIE *Die, dwarf::Attribute Attribute,
+ void addSectionLabel(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label);
/// addSectionOffset - Add an offset into a section attribute data and value.
///
- void addSectionOffset(DIE *Die, dwarf::Attribute Attribute, uint64_t Integer);
+ void addSectionOffset(DIE &Die, dwarf::Attribute Attribute, uint64_t Integer);
/// addOpAddress - Add a dwarf op address data and value using the
/// form given and an op of either DW_FORM_addr or DW_FORM_GNU_addr_index.
- void addOpAddress(DIELoc *Die, const MCSymbol *Label);
+ void addOpAddress(DIELoc &Die, const MCSymbol *Label);
/// addSectionDelta - Add a label delta attribute data and value.
- void addSectionDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
+ void addSectionDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
const MCSymbol *Lo);
/// addLabelDelta - Add a label delta attribute data and value.
- void addLabelDelta(DIE *Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
+ void addLabelDelta(DIE &Die, dwarf::Attribute Attribute, const MCSymbol *Hi,
const MCSymbol *Lo);
/// addDIEEntry - Add a DIE attribute data and value.
- void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIE *Entry);
+ void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIE &Entry);
/// addDIEEntry - Add a DIE attribute data and value.
- void addDIEEntry(DIE *Die, dwarf::Attribute Attribute, DIEEntry *Entry);
+ void addDIEEntry(DIE &Die, dwarf::Attribute Attribute, DIEEntry *Entry);
- void addDIETypeSignature(DIE *Die, const DwarfTypeUnit &Type);
+ void addDIETypeSignature(DIE &Die, const DwarfTypeUnit &Type);
/// addBlock - Add block data.
- void addBlock(DIE *Die, dwarf::Attribute Attribute, DIELoc *Block);
+ void addBlock(DIE &Die, dwarf::Attribute Attribute, DIELoc *Block);
/// addBlock - Add block data.
- void addBlock(DIE *Die, dwarf::Attribute Attribute, DIEBlock *Block);
+ void addBlock(DIE &Die, dwarf::Attribute Attribute, DIEBlock *Block);
/// addSourceLine - Add location information to specified debug information
/// entry.
- void addSourceLine(DIE *Die, unsigned Line, StringRef File,
+ void addSourceLine(DIE &Die, unsigned Line, StringRef File,
StringRef Directory);
- void addSourceLine(DIE *Die, DIVariable V);
- void addSourceLine(DIE *Die, DIGlobalVariable G);
- void addSourceLine(DIE *Die, DISubprogram SP);
- void addSourceLine(DIE *Die, DIType Ty);
- void addSourceLine(DIE *Die, DINameSpace NS);
- void addSourceLine(DIE *Die, DIObjCProperty Ty);
+ void addSourceLine(DIE &Die, DIVariable V);
+ void addSourceLine(DIE &Die, DIGlobalVariable G);
+ void addSourceLine(DIE &Die, DISubprogram SP);
+ void addSourceLine(DIE &Die, DIType Ty);
+ void addSourceLine(DIE &Die, DINameSpace NS);
+ void addSourceLine(DIE &Die, DIObjCProperty Ty);
/// addAddress - Add an address attribute to a die based on the location
/// provided.
- void addAddress(DIE *Die, dwarf::Attribute Attribute,
+ void addAddress(DIE &Die, dwarf::Attribute Attribute,
const MachineLocation &Location, bool Indirect = false);
/// addConstantValue - Add constant value entry in variable DIE.
- void addConstantValue(DIE *Die, const MachineOperand &MO, DIType Ty);
- void addConstantValue(DIE *Die, const ConstantInt *CI, bool Unsigned);
- void addConstantValue(DIE *Die, const APInt &Val, bool Unsigned);
+ void addConstantValue(DIE &Die, const MachineOperand &MO, DIType Ty);
+ void addConstantValue(DIE &Die, const ConstantInt *CI, DIType Ty);
+ void addConstantValue(DIE &Die, const APInt &Val, DIType Ty);
+ void addConstantValue(DIE &Die, const APInt &Val, bool Unsigned);
+ void addConstantValue(DIE &Die, bool Unsigned, uint64_t Val);
/// addConstantFPValue - Add constant value entry in variable DIE.
- void addConstantFPValue(DIE *Die, const MachineOperand &MO);
- void addConstantFPValue(DIE *Die, const ConstantFP *CFP);
+ void addConstantFPValue(DIE &Die, const MachineOperand &MO);
+ void addConstantFPValue(DIE &Die, const ConstantFP *CFP);
/// addTemplateParams - Add template parameters in buffer.
void addTemplateParams(DIE &Buffer, DIArray TParams);
/// addRegisterOp - Add register operand.
- void addRegisterOp(DIELoc *TheDie, unsigned Reg);
+ void addRegisterOp(DIELoc &TheDie, unsigned Reg);
/// addRegisterOffset - Add register offset.
- void addRegisterOffset(DIELoc *TheDie, unsigned Reg, int64_t Offset);
+ void addRegisterOffset(DIELoc &TheDie, unsigned Reg, int64_t Offset);
/// addComplexAddress - Start with the address based on the location provided,
/// and generate the DWARF information necessary to find the actual variable
/// (navigating the extra location information encoded in the type) based on
/// the starting location. Add the DWARF information to the die.
- void addComplexAddress(const DbgVariable &DV, DIE *Die,
+ void addComplexAddress(const DbgVariable &DV, DIE &Die,
dwarf::Attribute Attribute,
const MachineLocation &Location);
@@ -424,19 +378,19 @@ public:
/// actual Block variable (navigating the Block struct) based on the
/// starting location. Add the DWARF information to the die. Obsolete,
/// please use addComplexAddress instead.
- void addBlockByrefAddress(const DbgVariable &DV, DIE *Die,
+ void addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
dwarf::Attribute Attribute,
const MachineLocation &Location);
/// addVariableAddress - Add DW_AT_location attribute for a
/// DbgVariable based on provided MachineLocation.
- void addVariableAddress(const DbgVariable &DV, DIE *Die,
+ void addVariableAddress(const DbgVariable &DV, DIE &Die,
MachineLocation Location);
/// addType - Add a new type attribute to the specified entity. This takes
/// and attribute parameter because DW_AT_friend attributes are also
/// type references.
- void addType(DIE *Entity, DIType Ty,
+ void addType(DIE &Entity, DIType Ty,
dwarf::Attribute Attribute = dwarf::DW_AT_type);
/// getOrCreateNameSpace - Create a DIE for DINameSpace.
@@ -445,6 +399,8 @@ public:
/// getOrCreateSubprogramDIE - Create new DIE using SP.
DIE *getOrCreateSubprogramDIE(DISubprogram SP);
+ void applySubprogramAttributes(DISubprogram SP, DIE &SPDie);
+
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *getOrCreateTypeDIE(const MDNode *N);
@@ -460,14 +416,15 @@ public:
void constructContainingTypeDIEs();
/// constructVariableDIE - Construct a DIE for the given DbgVariable.
- DIE *constructVariableDIE(DbgVariable &DV, bool isScopeAbstract);
+ std::unique_ptr<DIE> constructVariableDIE(DbgVariable &DV,
+ bool Abstract = false);
/// constructSubprogramArguments - Construct function argument DIEs.
void constructSubprogramArguments(DIE &Buffer, DIArray Args);
/// Create a DIE with the given Tag, add the DIE to its parent, and
/// call insertDIE if MD is not null.
- DIE *createAndAddDIE(unsigned Tag, DIE &Parent,
+ DIE &createAndAddDIE(unsigned Tag, DIE &Parent,
DIDescriptor N = DIDescriptor());
/// Compute the size of a header for this unit, not including the initial
@@ -483,6 +440,9 @@ public:
virtual DwarfCompileUnit &getCU() = 0;
+ /// constructTypeDIE - Construct type DIE from DICompositeType.
+ void constructTypeDIE(DIE &Buffer, DICompositeType CTy);
+
protected:
/// getOrCreateStaticMemberDIE - Create new static data member DIE.
DIE *getOrCreateStaticMemberDIE(DIDerivedType DT);
@@ -492,15 +452,17 @@ protected:
virtual unsigned getOrCreateSourceID(StringRef File, StringRef Directory) = 0;
private:
+ /// \brief Construct a DIE for the given DbgVariable without initializing the
+ /// DbgVariable's DIE reference.
+ std::unique_ptr<DIE> constructVariableDIEImpl(const DbgVariable &DV,
+ bool Abstract);
+
/// constructTypeDIE - Construct basic type die from DIBasicType.
void constructTypeDIE(DIE &Buffer, DIBasicType BTy);
/// constructTypeDIE - Construct derived type die from DIDerivedType.
void constructTypeDIE(DIE &Buffer, DIDerivedType DTy);
- /// constructTypeDIE - Construct type DIE from DICompositeType.
- void constructTypeDIE(DIE &Buffer, DICompositeType CTy);
-
/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
void constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy);
@@ -547,7 +509,7 @@ private:
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
/// information entry.
- DIEEntry *createDIEEntry(DIE *Entry);
+ DIEEntry *createDIEEntry(DIE &Entry);
/// resolve - Look in the DwarfDebug map for the MDNode that
/// corresponds to the reference.
@@ -557,7 +519,7 @@ private:
/// If this is a named finished type then include it in the list of types for
/// the accelerator tables.
- void updateAcceleratorTables(DIScope Context, DIType Ty, const DIE *TyDIE);
+ void updateAcceleratorTables(DIScope Context, DIType Ty, const DIE &TyDIE);
};
class DwarfCompileUnit : public DwarfUnit {
@@ -566,7 +528,7 @@ class DwarfCompileUnit : public DwarfUnit {
unsigned stmtListIndex;
public:
- DwarfCompileUnit(unsigned UID, DIE *D, DICompileUnit Node, AsmPrinter *A,
+ DwarfCompileUnit(unsigned UID, DICompileUnit Node, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU);
void initStmtList(MCSymbol *DwarfLineSectionSym);
@@ -579,12 +541,12 @@ public:
/// addLabelAddress - Add a dwarf label attribute data and value using
/// either DW_FORM_addr or DW_FORM_GNU_addr_index.
- void addLabelAddress(DIE *Die, dwarf::Attribute Attribute,
+ void addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label);
/// addLocalLabelAddress - Add a dwarf label attribute data and value using
/// DW_FORM_addr only.
- void addLocalLabelAddress(DIE *Die, dwarf::Attribute Attribute,
+ void addLocalLabelAddress(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label);
DwarfCompileUnit &getCU() override { return *this; }
@@ -600,7 +562,7 @@ private:
MCDwarfDwoLineTable *SplitLineTable;
public:
- DwarfTypeUnit(unsigned UID, DIE *D, DwarfCompileUnit &CU, AsmPrinter *A,
+ DwarfTypeUnit(unsigned UID, DwarfCompileUnit &CU, AsmPrinter *A,
DwarfDebug *DW, DwarfFile *DWU,
MCDwarfDwoLineTable *SplitLineTable = nullptr);
diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
index 50b2ca8..2212941 100644
--- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
+++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
@@ -29,7 +29,7 @@ StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) {
StringRef Dir = Scope.getDirectory(),
Filename = Scope.getFilename();
char *&Result = DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)];
- if (Result != 0)
+ if (Result)
return Result;
// Clang emits directory and relative filename info into the IR, but CodeView
@@ -102,7 +102,7 @@ void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL,
}
WinCodeViewLineTables::WinCodeViewLineTables(AsmPrinter *AP)
- : Asm(0), CurFn(0) {
+ : Asm(nullptr), CurFn(nullptr) {
MachineModuleInfo *MMI = AP->MMI;
// If module doesn't have named metadata anchors or COFF debug section
@@ -171,7 +171,7 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
EmitLabelDiff(Asm->OutStreamer, Fn, FI.End);
// PC-to-linenumber lookup table:
- MCSymbol *FileSegmentEnd = 0;
+ MCSymbol *FileSegmentEnd = nullptr;
for (size_t J = 0, F = FI.Instrs.size(); J != F; ++J) {
MCSymbol *Instr = FI.Instrs[J];
assert(InstrInfo.count(Instr));
@@ -216,7 +216,7 @@ void WinCodeViewLineTables::endModule() {
if (FnDebugInfo.empty())
return;
- assert(Asm != 0);
+ assert(Asm != nullptr);
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getCOFFDebugSymbolsSection());
Asm->EmitInt32(COFF::DEBUG_SECTION_MAGIC);
@@ -277,20 +277,19 @@ void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) {
// for the first instruction of the function, not the last of the prolog?
DebugLoc PrologEndLoc;
bool EmptyPrologue = true;
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
- I != E && PrologEndLoc.isUnknown(); ++I) {
- for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
- II != IE; ++II) {
- const MachineInstr *MI = II;
- if (MI->isDebugValue())
+ for (const auto &MBB : *MF) {
+ if (!PrologEndLoc.isUnknown())
+ break;
+ for (const auto &MI : MBB) {
+ if (MI.isDebugValue())
continue;
// First known non-DBG_VALUE and non-frame setup location marks
// the beginning of the function body.
// FIXME: do we need the first subcondition?
- if (!MI->getFlag(MachineInstr::FrameSetup) &&
- (!MI->getDebugLoc().isUnknown())) {
- PrologEndLoc = MI->getDebugLoc();
+ if (!MI.getFlag(MachineInstr::FrameSetup) &&
+ (!MI.getDebugLoc().isUnknown())) {
+ PrologEndLoc = MI.getDebugLoc();
break;
}
EmptyPrologue = false;
@@ -321,7 +320,7 @@ void WinCodeViewLineTables::endFunction(const MachineFunction *MF) {
Asm->OutStreamer.EmitLabel(FunctionEndSym);
CurFn->End = FunctionEndSym;
}
- CurFn = 0;
+ CurFn = nullptr;
}
void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) {
diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
index a7a6205..0734d97 100644
--- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
+++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
@@ -38,7 +38,7 @@ class WinCodeViewLineTables : public AsmPrinterHandler {
struct FunctionInfo {
SmallVector<MCSymbol *, 10> Instrs;
MCSymbol *End;
- FunctionInfo() : End(0) {}
+ FunctionInfo() : End(nullptr) {}
} *CurFn;
typedef DenseMap<const Function *, FunctionInfo> FnDebugInfoTy;
@@ -104,7 +104,7 @@ class WinCodeViewLineTables : public AsmPrinterHandler {
void maybeRecordLocation(DebugLoc DL, const MachineFunction *MF);
void clear() {
- assert(CurFn == 0);
+ assert(CurFn == nullptr);
FileNameRegistry.clear();
InstrInfo.clear();
}