aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
authorPirama Arumuga Nainar <pirama@google.com>2015-05-06 11:46:36 -0700
committerPirama Arumuga Nainar <pirama@google.com>2015-05-18 10:52:30 -0700
commit2c3e0051c31c3f5b2328b447eadf1cf9c4427442 (patch)
treec0104029af14e9f47c2ef58ca60e6137691f3c9b /lib/CodeGen/AsmPrinter
parente1bc145815f4334641be19f1c45ecf85d25b6e5a (diff)
downloadexternal_llvm-2c3e0051c31c3f5b2328b447eadf1cf9c4427442.zip
external_llvm-2c3e0051c31c3f5b2328b447eadf1cf9c4427442.tar.gz
external_llvm-2c3e0051c31c3f5b2328b447eadf1cf9c4427442.tar.bz2
Update aosp/master LLVM for rebase to r235153
Change-Id: I9bf53792f9fc30570e81a8d80d296c681d005ea7 (cherry picked from commit 0c7f116bb6950ef819323d855415b2f2b0aad987)
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp38
-rw-r--r--lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp22
-rw-r--r--lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h14
-rw-r--r--lib/CodeGen/AsmPrinter/DebugLocEntry.h29
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp130
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp299
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h55
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h4
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfExpression.cpp28
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfExpression.h3
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfFile.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.cpp492
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.h4
-rw-r--r--lib/CodeGen/AsmPrinter/EHStreamer.cpp28
-rw-r--r--lib/CodeGen/AsmPrinter/EHStreamer.h6
-rw-r--r--lib/CodeGen/AsmPrinter/Win64Exception.cpp274
-rw-r--r--lib/CodeGen/AsmPrinter/Win64Exception.h9
-rw-r--r--lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp29
-rw-r--r--lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h2
19 files changed, 862 insertions, 608 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 07d6731..43d7a38 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -28,7 +28,7 @@
#include "llvm/CodeGen/MachineInstrBundle.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Mangler.h"
@@ -671,17 +671,17 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
OS << "DEBUG_VALUE: ";
DIVariable V = MI->getDebugVariable();
- if (V.getContext().isSubprogram()) {
- StringRef Name = DISubprogram(V.getContext()).getDisplayName();
+ if (auto *SP = dyn_cast<MDSubprogram>(V->getScope())) {
+ StringRef Name = SP->getDisplayName();
if (!Name.empty())
OS << Name << ":";
}
- OS << V.getName();
+ OS << V->getName();
DIExpression Expr = MI->getDebugExpression();
- if (Expr.isBitPiece())
- OS << " [bit_piece offset=" << Expr.getBitPieceOffset()
- << " size=" << Expr.getBitPieceSize() << "]";
+ if (Expr->isBitPiece())
+ OS << " [bit_piece offset=" << Expr->getBitPieceOffset()
+ << " size=" << Expr->getBitPieceSize() << "]";
OS << " <- ";
// The second operand is only an offset if it's an immediate.
@@ -1034,11 +1034,31 @@ bool AsmPrinter::doFinalization(Module &M) {
EmitVisibility(Name, V, false);
}
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+
// Emit module flags.
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
M.getModuleFlagsMetadata(ModuleFlags);
if (!ModuleFlags.empty())
- getObjFileLowering().emitModuleFlags(OutStreamer, ModuleFlags, *Mang, TM);
+ TLOF.emitModuleFlags(OutStreamer, ModuleFlags, *Mang, TM);
+
+ Triple TT(TM.getTargetTriple());
+ if (TT.isOSBinFormatELF()) {
+ MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
+
+ // Output stubs for external and common global variables.
+ MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
+ if (!Stubs.empty()) {
+ OutStreamer.SwitchSection(TLOF.getDataRelSection());
+ const DataLayout *DL = TM.getDataLayout();
+
+ for (const auto &Stub : Stubs) {
+ OutStreamer.EmitLabel(Stub.first);
+ OutStreamer.EmitSymbolValue(Stub.second.getPointer(),
+ DL->getPointerSize());
+ }
+ }
+ }
// Make sure we wrote out everything we need.
OutStreamer.Flush();
@@ -2302,7 +2322,7 @@ MCSymbol *AsmPrinter::getSymbolWithGlobalValueBase(const GlobalValue *GV,
MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const {
SmallString<60> NameStr;
Mang->getNameWithPrefix(NameStr, Sym);
- return OutContext.GetOrCreateSymbol(NameStr.str());
+ return OutContext.GetOrCreateSymbol(NameStr);
}
diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
index bbdf237..1e3c5d7 100644
--- a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
+++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
@@ -33,7 +33,7 @@ static unsigned isDescribedByReg(const MachineInstr &MI) {
return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : 0;
}
-void DbgValueHistoryMap::startInstrRange(const MDNode *Var,
+void DbgValueHistoryMap::startInstrRange(InlinedVariable Var,
const MachineInstr &MI) {
// Instruction range should start with a DBG_VALUE instruction for the
// variable.
@@ -48,7 +48,7 @@ void DbgValueHistoryMap::startInstrRange(const MDNode *Var,
Ranges.push_back(std::make_pair(&MI, nullptr));
}
-void DbgValueHistoryMap::endInstrRange(const MDNode *Var,
+void DbgValueHistoryMap::endInstrRange(InlinedVariable Var,
const MachineInstr &MI) {
auto &Ranges = VarInstrRanges[Var];
// Verify that the current instruction range is not yet closed.
@@ -59,7 +59,7 @@ void DbgValueHistoryMap::endInstrRange(const MDNode *Var,
Ranges.back().second = &MI;
}
-unsigned DbgValueHistoryMap::getRegisterForVar(const MDNode *Var) const {
+unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
const auto &I = VarInstrRanges.find(Var);
if (I == VarInstrRanges.end())
return 0;
@@ -71,12 +71,13 @@ unsigned DbgValueHistoryMap::getRegisterForVar(const MDNode *Var) const {
namespace {
// Maps physreg numbers to the variables they describe.
-typedef std::map<unsigned, SmallVector<const MDNode *, 1>> RegDescribedVarsMap;
+typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
+typedef std::map<unsigned, SmallVector<InlinedVariable, 1>> RegDescribedVarsMap;
}
// \brief Claim that @Var is not described by @RegNo anymore.
-static void dropRegDescribedVar(RegDescribedVarsMap &RegVars,
- unsigned RegNo, const MDNode *Var) {
+static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
+ InlinedVariable Var) {
const auto &I = RegVars.find(RegNo);
assert(RegNo != 0U && I != RegVars.end());
auto &VarSet = I->second;
@@ -89,8 +90,8 @@ static void dropRegDescribedVar(RegDescribedVarsMap &RegVars,
}
// \brief Claim that @Var is now described by @RegNo.
-static void addRegDescribedVar(RegDescribedVarsMap &RegVars,
- unsigned RegNo, const MDNode *Var) {
+static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
+ InlinedVariable Var) {
assert(RegNo != 0U);
auto &VarSet = RegVars[RegNo];
assert(std::find(VarSet.begin(), VarSet.end(), Var) == VarSet.end());
@@ -203,7 +204,10 @@ void llvm::calculateDbgValueHistory(const MachineFunction *MF,
// Use the base variable (without any DW_OP_piece expressions)
// as index into History. The full variables including the
// piece expressions are attached to the MI.
- DIVariable Var = MI.getDebugVariable();
+ MDLocalVariable *RawVar = MI.getDebugVariable();
+ assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) &&
+ "Expected inlined-at fields to agree");
+ InlinedVariable Var(RawVar, MI.getDebugLoc()->getInlinedAt());
if (unsigned PrevReg = Result.getRegisterForVar(Var))
dropRegDescribedVar(RegVars, PrevReg, Var);
diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
index 4b62007..c25aaff 100644
--- a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
+++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
@@ -17,7 +17,8 @@ namespace llvm {
class MachineFunction;
class MachineInstr;
-class MDNode;
+class MDLocalVariable;
+class MDLocation;
class TargetRegisterInfo;
// For each user variable, keep a list of instruction ranges where this variable
@@ -31,16 +32,19 @@ class DbgValueHistoryMap {
public:
typedef std::pair<const MachineInstr *, const MachineInstr *> InstrRange;
typedef SmallVector<InstrRange, 4> InstrRanges;
- typedef MapVector<const MDNode *, InstrRanges> InstrRangesMap;
+ typedef std::pair<const MDLocalVariable *, const MDLocation *>
+ InlinedVariable;
+ typedef MapVector<InlinedVariable, InstrRanges> InstrRangesMap;
+
private:
InstrRangesMap VarInstrRanges;
public:
- void startInstrRange(const MDNode *Var, const MachineInstr &MI);
- void endInstrRange(const MDNode *Var, const MachineInstr &MI);
+ void startInstrRange(InlinedVariable Var, const MachineInstr &MI);
+ void endInstrRange(InlinedVariable 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;
+ unsigned getRegisterForVar(InlinedVariable Var) const;
bool empty() const { return VarInstrRanges.empty(); }
void clear() { VarInstrRanges.clear(); }
diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index 6914bbe..4f6714e 100644
--- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -42,8 +42,8 @@ public:
}
Value(const MDNode *Var, const MDNode *Expr, MachineLocation Loc)
: Variable(Var), Expression(Expr), EntryKind(E_Location), Loc(Loc) {
- assert(DIVariable(Var).Verify());
- assert(DIExpression(Expr)->isValid());
+ assert(isa<MDLocalVariable>(Var));
+ assert(cast<MDExpression>(Expr)->isValid());
}
/// The variable to which this location entry corresponds.
@@ -74,10 +74,11 @@ public:
const ConstantFP *getConstantFP() const { return Constant.CFP; }
const ConstantInt *getConstantInt() const { return Constant.CIP; }
MachineLocation getLoc() const { return Loc; }
- const MDNode *getVariableNode() const { return Variable; }
- DIVariable getVariable() const { return DIVariable(Variable); }
- bool isBitPiece() const { return getExpression().isBitPiece(); }
- DIExpression getExpression() const { return DIExpression(Expression); }
+ DIVariable getVariable() const { return cast<MDLocalVariable>(Variable); }
+ bool isBitPiece() const { return getExpression()->isBitPiece(); }
+ DIExpression getExpression() const {
+ return cast_or_null<MDExpression>(Expression);
+ }
friend bool operator==(const Value &, const Value &);
friend bool operator<(const Value &, const Value &);
};
@@ -101,12 +102,12 @@ public:
/// Return true if the merge was successful.
bool MergeValues(const DebugLocEntry &Next) {
if (Begin == Next.Begin) {
- DIExpression Expr(Values[0].Expression);
- DIVariable Var(Values[0].Variable);
- DIExpression NextExpr(Next.Values[0].Expression);
- DIVariable NextVar(Next.Values[0].Variable);
- if (Var == NextVar && Expr.isBitPiece() &&
- NextExpr.isBitPiece()) {
+ DIExpression Expr = cast_or_null<MDExpression>(Values[0].Expression);
+ DIVariable Var = cast_or_null<MDLocalVariable>(Values[0].Variable);
+ DIExpression NextExpr =
+ cast_or_null<MDExpression>(Next.Values[0].Expression);
+ DIVariable NextVar = cast_or_null<MDLocalVariable>(Next.Values[0].Variable);
+ if (Var == NextVar && Expr->isBitPiece() && NextExpr->isBitPiece()) {
addValues(Next.Values);
End = Next.End;
return true;
@@ -189,8 +190,8 @@ inline bool operator==(const DebugLocEntry::Value &A,
/// \brief Compare two pieces based on their offset.
inline bool operator<(const DebugLocEntry::Value &A,
const DebugLocEntry::Value &B) {
- return A.getExpression().getBitPieceOffset() <
- B.getExpression().getBitPieceOffset();
+ return A.getExpression()->getBitPieceOffset() <
+ B.getExpression()->getBitPieceOffset();
}
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index eee5fc5..75d3b68 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -101,51 +101,52 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) {
if (DIE *Die = getDIE(GV))
return Die;
- assert(GV.isGlobalVariable());
+ assert(GV);
- DIScope GVContext = GV.getContext();
- DIType GTy = DD->resolve(GV.getType());
+ DIScope GVContext = GV->getScope();
+ DIType GTy = DD->resolve(GV->getType());
// Construct the context before querying for the existence of the DIE in
// case such construction creates the DIE.
DIE *ContextDIE = getOrCreateContextDIE(GVContext);
// Add to map.
- DIE *VariableDIE = &createAndAddDIE(GV.getTag(), *ContextDIE, GV);
+ DIE *VariableDIE = &createAndAddDIE(GV->getTag(), *ContextDIE, GV);
DIScope DeclContext;
- if (DIDerivedType SDMDecl = GV.getStaticDataMemberDeclaration()) {
- DeclContext = resolve(SDMDecl.getContext());
- assert(SDMDecl.isStaticMember() && "Expected static member decl");
- assert(GV.isDefinition());
+ if (auto *SDMDecl = GV->getStaticDataMemberDeclaration()) {
+ DeclContext = resolve(SDMDecl->getScope());
+ assert(SDMDecl->isStaticMember() && "Expected static member decl");
+ assert(GV->isDefinition());
// We need the declaration DIE that is in the static member's class.
DIE *VariableSpecDIE = getOrCreateStaticMemberDIE(SDMDecl);
addDIEEntry(*VariableDIE, dwarf::DW_AT_specification, *VariableSpecDIE);
} else {
- DeclContext = GV.getContext();
+ DeclContext = GV->getScope();
// Add name and type.
- addString(*VariableDIE, dwarf::DW_AT_name, GV.getDisplayName());
+ addString(*VariableDIE, dwarf::DW_AT_name, GV->getDisplayName());
addType(*VariableDIE, GTy);
// Add scoping info.
- if (!GV.isLocalToUnit())
+ if (!GV->isLocalToUnit())
addFlag(*VariableDIE, dwarf::DW_AT_external);
// Add line number info.
addSourceLine(*VariableDIE, GV);
}
- if (!GV.isDefinition())
+ if (!GV->isDefinition())
addFlag(*VariableDIE, dwarf::DW_AT_declaration);
+ else
+ addGlobalName(GV->getName(), *VariableDIE, DeclContext);
// Add location.
bool addToAccelTable = false;
- bool isGlobalVariable = GV.getGlobal() != nullptr;
- if (isGlobalVariable) {
+ if (auto *Global = dyn_cast_or_null<GlobalVariable>(GV->getVariable())) {
addToAccelTable = true;
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
- const MCSymbol *Sym = Asm->getSymbol(GV.getGlobal());
- if (GV.getGlobal()->isThreadLocal()) {
+ const MCSymbol *Sym = Asm->getSymbol(Global);
+ if (Global->isThreadLocal()) {
// FIXME: Make this work with -gsplit-dwarf.
unsigned PointerSize = Asm->getDataLayout().getPointerSize();
assert((PointerSize == 4 || PointerSize == 8) &&
@@ -174,11 +175,11 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) {
}
addBlock(*VariableDIE, dwarf::DW_AT_location, Loc);
- addLinkageName(*VariableDIE, GV.getLinkageName());
+ addLinkageName(*VariableDIE, GV->getLinkageName());
} else if (const ConstantInt *CI =
- dyn_cast_or_null<ConstantInt>(GV.getConstant())) {
+ dyn_cast_or_null<ConstantInt>(GV->getVariable())) {
addConstantValue(*VariableDIE, CI, GTy);
- } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV.getConstant())) {
+ } else if (const ConstantExpr *CE = getMergedGlobalExpr(GV->getVariable())) {
addToAccelTable = true;
// GV is a merged global.
DIELoc *Loc = new (DIEValueAllocator) DIELoc();
@@ -195,15 +196,14 @@ DIE *DwarfCompileUnit::getOrCreateGlobalVariableDIE(DIGlobalVariable GV) {
}
if (addToAccelTable) {
- DD->addAccelName(GV.getName(), *VariableDIE);
+ DD->addAccelName(GV->getName(), *VariableDIE);
// 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())
- DD->addAccelName(GV.getLinkageName(), *VariableDIE);
+ if (GV->getLinkageName() != "" && GV->getName() != GV->getLinkageName())
+ DD->addAccelName(GV->getLinkageName(), *VariableDIE);
}
- addGlobalName(GV.getName(), *VariableDIE, DeclContext);
return VariableDIE;
}
@@ -307,7 +307,7 @@ void DwarfCompileUnit::constructScopeDIE(
DIScope DS(Scope->getScopeNode());
- assert((Scope->getInlinedAt() || !DS.isSubprogram()) &&
+ assert((Scope->getInlinedAt() || !isa<MDSubprogram>(DS)) &&
"Only handle inlined subprograms here, use "
"constructSubprogramScopeDIE for non-inlined "
"subprograms");
@@ -318,7 +318,7 @@ void DwarfCompileUnit::constructScopeDIE(
// avoid creating un-used children then removing them later when we find out
// the scope DIE is null.
std::unique_ptr<DIE> ScopeDIE;
- if (Scope->getParent() && DS.isSubprogram()) {
+ if (Scope->getParent() && isa<MDSubprogram>(DS)) {
ScopeDIE = constructInlinedScopeDIE(Scope);
if (!ScopeDIE)
return;
@@ -340,7 +340,7 @@ void DwarfCompileUnit::constructScopeDIE(
// There is no need to emit empty lexical block DIE.
for (const auto &E : DD->findImportedEntitiesForScope(DS))
Children.push_back(
- constructImportedEntityDIE(DIImportedEntity(E.second)));
+ constructImportedEntityDIE(cast<MDImportedEntity>(E.second)));
}
// If there are only other scopes as children, put them directly in the
@@ -431,10 +431,10 @@ DwarfCompileUnit::constructInlinedScopeDIE(LexicalScope *Scope) {
attachRangesOrLowHighPC(*ScopeDIE, Scope->getRanges());
// Add the call site information to the DIE.
- DILocation DL(Scope->getInlinedAt());
+ const MDLocation *IA = Scope->getInlinedAt();
addUInt(*ScopeDIE, dwarf::DW_AT_call_file, None,
- getOrCreateSourceID(DL.getFilename(), DL.getDirectory()));
- addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, DL.getLineNumber());
+ getOrCreateSourceID(IA->getFilename(), IA->getDirectory()));
+ addUInt(*ScopeDIE, dwarf::DW_AT_call_line, None, IA->getLine());
// 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.
@@ -523,7 +523,7 @@ DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
assert(Expr != DV.getExpression().end() &&
"Wrong number of expressions");
DwarfExpr.AddMachineRegIndirect(FrameReg, Offset);
- DwarfExpr.AddExpression(Expr->begin(), Expr->end());
+ DwarfExpr.AddExpression((*Expr)->expr_op_begin(), (*Expr)->expr_op_end());
++Expr;
}
addBlock(*VariableDie, dwarf::DW_AT_location, Loc);
@@ -562,16 +562,14 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
assert(Scope && Scope->getScopeNode());
assert(!Scope->getInlinedAt());
assert(!Scope->isAbstractScope());
- DISubprogram Sub(Scope->getScopeNode());
-
- assert(Sub.isSubprogram());
+ DISubprogram Sub = cast<MDSubprogram>(Scope->getScopeNode());
DD->getProcessedSPNodes().insert(Sub);
DIE &ScopeDIE = updateSubprogramScopeDIE(Sub);
// If this is a variadic function, add an unspecified parameter.
- DITypeArray FnArgs = Sub.getType().getTypeArray();
+ DITypeArray FnArgs = Sub->getType()->getTypeArray();
// Collect lexical scope children first.
// ObjectPointer might be a local (non-argument) local variable if it's a
@@ -582,8 +580,7 @@ void DwarfCompileUnit::constructSubprogramScopeDIE(LexicalScope *Scope) {
// If we have a single element of null, it is a function that returns void.
// If we have more than one elements and the last one is null, it is a
// variadic function.
- if (FnArgs.getNumElements() > 1 &&
- !FnArgs.getElement(FnArgs.getNumElements() - 1) &&
+ if (FnArgs.size() > 1 && !FnArgs[FnArgs.size() - 1] &&
!includeMinimalInlineScopes())
ScopeDIE.addChild(make_unique<DIE>(dwarf::DW_TAG_unspecified_parameters));
}
@@ -607,7 +604,7 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
if (AbsDef)
return;
- DISubprogram SP(Scope->getScopeNode());
+ DISubprogram SP = cast<MDSubprogram>(Scope->getScopeNode());
DIE *ContextDIE;
@@ -617,11 +614,11 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
// 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.
- else if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+ else if (auto *SPDecl = SP->getDeclaration()) {
ContextDIE = &getUnitDie();
getOrCreateSubprogramDIE(SPDecl);
} else
- ContextDIE = getOrCreateContextDIE(resolve(SP.getContext()));
+ ContextDIE = getOrCreateContextDIE(resolve(SP->getScope()));
// Passing null as the associated DIDescriptor because the abstract definition
// shouldn't be found by lookup.
@@ -637,28 +634,25 @@ DwarfCompileUnit::constructAbstractSubprogramScopeDIE(LexicalScope *Scope) {
std::unique_ptr<DIE>
DwarfCompileUnit::constructImportedEntityDIE(const DIImportedEntity &Module) {
- assert(Module.Verify() &&
- "Use one of the MDNode * overloads to handle invalid metadata");
- std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module.getTag());
+ std::unique_ptr<DIE> IMDie = make_unique<DIE>((dwarf::Tag)Module->getTag());
insertDIE(Module, IMDie.get());
DIE *EntityDie;
- DIDescriptor Entity = resolve(Module.getEntity());
- if (Entity.isNameSpace())
- EntityDie = getOrCreateNameSpace(DINameSpace(Entity));
- else if (Entity.isSubprogram())
- EntityDie = getOrCreateSubprogramDIE(DISubprogram(Entity));
- else if (Entity.isType())
- EntityDie = getOrCreateTypeDIE(DIType(Entity));
- else if (Entity.isGlobalVariable())
- EntityDie = getOrCreateGlobalVariableDIE(DIGlobalVariable(Entity));
+ auto *Entity = resolve(Module->getEntity());
+ if (auto *NS = dyn_cast<MDNamespace>(Entity))
+ EntityDie = getOrCreateNameSpace(NS);
+ else if (auto *SP = dyn_cast<MDSubprogram>(Entity))
+ EntityDie = getOrCreateSubprogramDIE(SP);
+ else if (auto *T = dyn_cast<MDType>(Entity))
+ EntityDie = getOrCreateTypeDIE(T);
+ else if (auto *GV = dyn_cast<MDGlobalVariable>(Entity))
+ EntityDie = getOrCreateGlobalVariableDIE(GV);
else
EntityDie = getDIE(Entity);
assert(EntityDie);
- addSourceLine(*IMDie, Module.getLineNumber(),
- Module.getContext().getFilename(),
- Module.getContext().getDirectory());
+ addSourceLine(*IMDie, Module->getLine(), Module->getScope()->getFilename(),
+ Module->getScope()->getDirectory());
addDIEEntry(*IMDie, dwarf::DW_AT_import, *EntityDie);
- StringRef Name = Module.getName();
+ StringRef Name = Module->getName();
if (!Name.empty())
addString(*IMDie, dwarf::DW_AT_name, Name);
@@ -683,21 +677,19 @@ void DwarfCompileUnit::finishSubprogramDefinition(DISubprogram SP) {
}
}
void DwarfCompileUnit::collectDeadVariables(DISubprogram SP) {
- assert(SP.isSubprogram() && "CU's subprogram list contains a non-subprogram");
- assert(SP.isDefinition() &&
+ assert(SP && "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)
+ auto Variables = SP->getVariables();
+ if (Variables.size() == 0)
return;
DIE *SPDIE = DU->getAbstractSPDies().lookup(SP);
if (!SPDIE)
SPDIE = getDIE(SP);
assert(SPDIE);
- for (unsigned vi = 0, ve = Variables.getNumElements(); vi != ve; ++vi) {
- DIVariable DV(Variables.getElement(vi));
- assert(DV.isVariable());
- DbgVariable NewVar(DV, DIExpression(), DD);
+ for (DIVariable DV : Variables) {
+ DbgVariable NewVar(DV, nullptr, DIExpression(), DD);
auto VariableDie = constructVariableDIE(NewVar);
applyVariableAttributes(NewVar, *VariableDie);
SPDIE->addChild(std::move(VariableDie));
@@ -728,7 +720,7 @@ void DwarfCompileUnit::addGlobalType(DIType Ty, const DIE &Die,
DIScope Context) {
if (includeMinimalInlineScopes())
return;
- std::string FullName = getParentContextString(Context) + Ty.getName().str();
+ std::string FullName = getParentContextString(Context) + Ty->getName().str();
GlobalTypes[FullName] = &Die;
}
@@ -778,7 +770,7 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
ValidReg = DwarfExpr.AddMachineRegIndirect(Location.getReg(),
Location.getOffset());
if (ValidReg)
- DwarfExpr.AddExpression(Expr.begin(), Expr.end());
+ DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end());
} else
ValidReg = DwarfExpr.AddMachineRegExpression(Expr, Location.getReg());
@@ -816,10 +808,10 @@ void DwarfCompileUnit::addExpr(DIELoc &Die, dwarf::Form Form,
void DwarfCompileUnit::applySubprogramAttributesToDefinition(DISubprogram SP,
DIE &SPDie) {
- DISubprogram SPDecl = SP.getFunctionDeclaration();
- DIScope Context = resolve(SPDecl ? SPDecl.getContext() : SP.getContext());
+ auto *SPDecl = SP->getDeclaration();
+ DIScope Context = resolve(SPDecl ? SPDecl->getScope() : SP->getScope());
applySubprogramAttributes(SP, SPDie, includeMinimalInlineScopes());
- addGlobalName(SP.getName(), SPDie, Context);
+ addGlobalName(SP->getName(), SPDie, Context);
}
bool DwarfCompileUnit::isDwoUnit() const {
@@ -827,7 +819,7 @@ bool DwarfCompileUnit::isDwoUnit() const {
}
bool DwarfCompileUnit::includeMinimalInlineScopes() const {
- return getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly ||
+ return getCUNode()->getEmissionKind() == DIBuilder::LineTablesOnly ||
(DD->useSplitDwarf() && !Skeleton);
}
} // end llvm namespace
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index e9ebd97..fb8fc6e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -129,20 +129,22 @@ bool DebugLocDwarfExpression::isFrameRegister(unsigned MachineReg) {
/// resolve - Look in the DwarfDebug map for the MDNode that
/// corresponds to the reference.
-template <typename T> T DbgVariable::resolve(DIRef<T> Ref) const {
+template <typename T> T *DbgVariable::resolve(TypedDebugNodeRef<T> Ref) const {
return DD->resolve(Ref);
}
bool DbgVariable::isBlockByrefVariable() const {
- assert(Var.isVariable() && "Invalid complex DbgVariable!");
- return Var.isBlockByrefVariable(DD->getTypeIdentifierMap());
+ assert(Var && "Invalid complex DbgVariable!");
+ return Var->getType()
+ .resolve(DD->getTypeIdentifierMap())
+ ->isBlockByrefStruct();
}
DIType DbgVariable::getType() const {
- DIType Ty = Var.getType().resolve(DD->getTypeIdentifierMap());
+ MDType *Ty = Var->getType().resolve(DD->getTypeIdentifierMap());
// FIXME: isBlockByrefVariable should be reformulated in terms of complex
// addresses instead.
- if (Var.isBlockByrefVariable(DD->getTypeIdentifierMap())) {
+ if (Ty->isBlockByrefStruct()) {
/* Byref variables, in Blocks, are declared by the programmer as
"SomeType VarName;", but the compiler creates a
__Block_byref_x_VarName struct, and gives the variable VarName
@@ -167,17 +169,17 @@ DIType DbgVariable::getType() const {
have a DW_AT_location that tells the debugger how to unwind through
the pointers and __Block_byref_x_VarName struct to find the actual
value of the variable. The function addBlockByrefType does this. */
- DIType subType = Ty;
- uint16_t tag = Ty.getTag();
+ MDType *subType = Ty;
+ uint16_t tag = Ty->getTag();
if (tag == dwarf::DW_TAG_pointer_type)
- subType = resolve(DIDerivedType(Ty).getTypeDerivedFrom());
+ subType = resolve(DITypeRef(cast<MDDerivedType>(Ty)->getBaseType()));
- DIArray Elements = DICompositeType(subType).getElements();
- for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
- DIDerivedType DT(Elements.getElement(i));
- if (getName() == DT.getName())
- return (resolve(DT.getTypeDerivedFrom()));
+ auto Elements = cast<MDCompositeTypeBase>(subType)->getElements();
+ for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
+ auto *DT = cast<MDDerivedTypeBase>(Elements[i]);
+ if (getName() == DT->getName())
+ return resolve(DITypeRef(DT->getBaseType()));
}
}
return Ty;
@@ -275,25 +277,25 @@ static StringRef getObjCMethodName(StringRef In) {
// 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.
void DwarfDebug::addSubprogramNames(DISubprogram SP, DIE &Die) {
- if (!SP.isDefinition())
+ if (!SP->isDefinition())
return;
- 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())
- addAccelName(SP.getLinkageName(), Die);
+ if (SP->getLinkageName() != "" && SP->getName() != SP->getLinkageName())
+ addAccelName(SP->getLinkageName(), Die);
// If this is an Objective-C selector name add it to the ObjC accelerator
// too.
- if (isObjCClass(SP.getName())) {
+ if (isObjCClass(SP->getName())) {
StringRef Class, Category;
- getObjCClassCategory(SP.getName(), Class, Category);
+ getObjCClassCategory(SP->getName(), Class, Category);
addAccelObjC(Class, Die);
if (Category != "")
addAccelObjC(Category, Die);
// Also add the base method name to the name table.
- addAccelName(getObjCMethodName(SP.getName()), Die);
+ addAccelName(getObjCMethodName(SP->getName()), Die);
}
}
@@ -302,11 +304,10 @@ void DwarfDebug::addSubprogramNames(DISubprogram SP, DIE &Die) {
bool DwarfDebug::isSubprogramContext(const MDNode *Context) {
if (!Context)
return false;
- DIDescriptor D(Context);
- if (D.isSubprogram())
+ if (isa<MDSubprogram>(Context))
return true;
- if (D.isType())
- return isSubprogramContext(resolve(DIType(Context).getContext()));
+ if (auto *T = dyn_cast<MDType>(Context))
+ return isSubprogramContext(resolve(T->getScope()));
return false;
}
@@ -362,8 +363,8 @@ void DwarfDebug::addGnuPubAttributes(DwarfUnit &U, DIE &D) const {
// Create new DwarfCompileUnit for the given metadata node with tag
// DW_TAG_compile_unit.
DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
- StringRef FN = DIUnit.getFilename();
- CompilationDir = DIUnit.getDirectory();
+ StringRef FN = DIUnit->getFilename();
+ CompilationDir = DIUnit->getDirectory();
auto OwnedUnit = make_unique<DwarfCompileUnit>(
InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
@@ -381,9 +382,9 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
Asm->OutStreamer.getContext().setMCLineTableCompilationDir(
NewCU.getUniqueID(), CompilationDir);
- NewCU.addString(Die, dwarf::DW_AT_producer, DIUnit.getProducer());
+ NewCU.addString(Die, dwarf::DW_AT_producer, DIUnit->getProducer());
NewCU.addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data2,
- DIUnit.getLanguage());
+ DIUnit->getSourceLanguage());
NewCU.addString(Die, dwarf::DW_AT_name, FN);
if (!useSplitDwarf()) {
@@ -397,14 +398,14 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
addGnuPubAttributes(NewCU, Die);
}
- if (DIUnit.isOptimized())
+ if (DIUnit->isOptimized())
NewCU.addFlag(Die, dwarf::DW_AT_APPLE_optimized);
- StringRef Flags = DIUnit.getFlags();
+ StringRef Flags = DIUnit->getFlags();
if (!Flags.empty())
NewCU.addString(Die, dwarf::DW_AT_APPLE_flags, Flags);
- if (unsigned RVer = DIUnit.getRunTimeVersion())
+ if (unsigned RVer = DIUnit->getRuntimeVersion())
NewCU.addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
dwarf::DW_FORM_data1, RVer);
@@ -420,9 +421,8 @@ DwarfCompileUnit &DwarfDebug::constructDwarfCompileUnit(DICompileUnit DIUnit) {
void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
const MDNode *N) {
- DIImportedEntity Module(N);
- assert(Module.Verify());
- if (DIE *D = TheCU.getOrCreateContextDIE(Module.getContext()))
+ DIImportedEntity Module = cast<MDImportedEntity>(N);
+ if (DIE *D = TheCU.getOrCreateContextDIE(Module->getScope()))
D->addChild(TheCU.constructImportedEntityDIE(Module));
}
@@ -445,44 +445,35 @@ void DwarfDebug::beginModule() {
SingleCU = CU_Nodes->getNumOperands() == 1;
for (MDNode *N : CU_Nodes->operands()) {
- DICompileUnit CUNode(N);
+ DICompileUnit CUNode = cast<MDCompileUnit>(N);
DwarfCompileUnit &CU = constructDwarfCompileUnit(CUNode);
- DIArray ImportedEntities = CUNode.getImportedEntities();
- for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i)
- ScopesWithImportedEntities.push_back(std::make_pair(
- DIImportedEntity(ImportedEntities.getElement(i)).getContext(),
- ImportedEntities.getElement(i)));
+ for (auto *IE : CUNode->getImportedEntities())
+ ScopesWithImportedEntities.push_back(std::make_pair(IE->getScope(), IE));
// Stable sort to preserve the order of appearance of imported entities.
// This is to avoid out-of-order processing of interdependent declarations
// within the same scope, e.g. { namespace A = base; namespace B = A; }
std::stable_sort(ScopesWithImportedEntities.begin(),
ScopesWithImportedEntities.end(), less_first());
- DIArray GVs = CUNode.getGlobalVariables();
- for (unsigned i = 0, e = GVs.getNumElements(); i != e; ++i)
- CU.getOrCreateGlobalVariableDIE(DIGlobalVariable(GVs.getElement(i)));
- DIArray SPs = CUNode.getSubprograms();
- for (unsigned i = 0, e = SPs.getNumElements(); i != e; ++i)
- SPMap.insert(std::make_pair(SPs.getElement(i), &CU));
- DIArray EnumTypes = CUNode.getEnumTypes();
- for (unsigned i = 0, e = EnumTypes.getNumElements(); i != e; ++i) {
- DIType Ty(EnumTypes.getElement(i));
+ for (auto *GV : CUNode->getGlobalVariables())
+ CU.getOrCreateGlobalVariableDIE(GV);
+ for (auto *SP : CUNode->getSubprograms())
+ SPMap.insert(std::make_pair(SP, &CU));
+ for (DIType Ty : CUNode->getEnumTypes()) {
// The enum types array by design contains pointers to
// MDNodes rather than DIRefs. Unique them here.
- DIType UniqueTy(resolve(Ty.getRef()));
+ DIType UniqueTy = cast<MDType>(resolve(Ty->getRef()));
CU.getOrCreateTypeDIE(UniqueTy);
}
- DIArray RetainedTypes = CUNode.getRetainedTypes();
- for (unsigned i = 0, e = RetainedTypes.getNumElements(); i != e; ++i) {
- DIType Ty(RetainedTypes.getElement(i));
+ for (DIType Ty : CUNode->getRetainedTypes()) {
// The retained types array by design contains pointers to
// MDNodes rather than DIRefs. Unique them here.
- DIType UniqueTy(resolve(Ty.getRef()));
+ DIType UniqueTy = cast<MDType>(resolve(Ty->getRef()));
CU.getOrCreateTypeDIE(UniqueTy);
}
// Emit imported_modules last so that the relevant context is already
// available.
- for (unsigned i = 0, e = ImportedEntities.getNumElements(); i != e; ++i)
- constructAndAddImportedEntityDIE(CU, ImportedEntities.getElement(i));
+ for (auto *IE : CUNode->getImportedEntities())
+ constructAndAddImportedEntityDIE(CU, IE);
}
// Tell MMI that we have debug info.
@@ -498,7 +489,8 @@ void DwarfDebug::finishVariableDefinitions() {
// DIE::getUnit isn't simple - it walks parent pointers, etc.
DwarfCompileUnit *Unit = lookupUnit(VariableDie->getUnit());
assert(Unit);
- DbgVariable *AbsVar = getExistingAbstractVariable(Var->getVariable());
+ DbgVariable *AbsVar = getExistingAbstractVariable(
+ InlinedVariable(Var->getVariable(), Var->getInlinedAt()));
if (AbsVar && AbsVar->getDIE()) {
Unit->addDIEEntry(*VariableDie, dwarf::DW_AT_abstract_origin,
*AbsVar->getDIE());
@@ -510,7 +502,7 @@ void DwarfDebug::finishVariableDefinitions() {
void DwarfDebug::finishSubprogramDefinitions() {
for (const auto &P : SPMap)
forBothCUs(*P.second, [&](DwarfCompileUnit &CU) {
- CU.finishSubprogramDefinition(DISubprogram(P.first));
+ CU.finishSubprogramDefinition(cast<MDSubprogram>(P.first));
});
}
@@ -521,14 +513,12 @@ void DwarfDebug::collectDeadVariables() {
if (NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu")) {
for (MDNode *N : CU_Nodes->operands()) {
- DICompileUnit TheCU(N);
+ DICompileUnit TheCU = cast<MDCompileUnit>(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));
+ for (auto *SP : TheCU->getSubprograms()) {
if (ProcessedSPNodes.count(SP) != 0)
continue;
SPCU->collectDeadVariables(SP);
@@ -671,70 +661,71 @@ void DwarfDebug::endModule() {
}
// Find abstract variable, if any, associated with Var.
-DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV,
+DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV,
DIVariable &Cleansed) {
- LLVMContext &Ctx = DV->getContext();
// More then one inlined variable corresponds to one abstract variable.
- // FIXME: This duplication of variables when inlining should probably be
- // removed. It's done to allow each DIVariable to describe its location
- // because the DebugLoc on the dbg.value/declare isn't accurate. We should
- // make it accurate then remove this duplication/cleansing stuff.
- Cleansed = cleanseInlinedVariable(DV, Ctx);
+ Cleansed = IV.first;
auto I = AbstractVariables.find(Cleansed);
if (I != AbstractVariables.end())
return I->second.get();
return nullptr;
}
-DbgVariable *DwarfDebug::getExistingAbstractVariable(const DIVariable &DV) {
+DbgVariable *DwarfDebug::getExistingAbstractVariable(InlinedVariable IV) {
DIVariable Cleansed;
- return getExistingAbstractVariable(DV, Cleansed);
+ return getExistingAbstractVariable(IV, Cleansed);
}
void DwarfDebug::createAbstractVariable(const DIVariable &Var,
LexicalScope *Scope) {
- auto AbsDbgVariable = make_unique<DbgVariable>(Var, DIExpression(), this);
+ auto AbsDbgVariable =
+ make_unique<DbgVariable>(Var, nullptr, DIExpression(), this);
InfoHolder.addScopeVariable(Scope, AbsDbgVariable.get());
AbstractVariables[Var] = std::move(AbsDbgVariable);
}
-void DwarfDebug::ensureAbstractVariableIsCreated(const DIVariable &DV,
+void DwarfDebug::ensureAbstractVariableIsCreated(InlinedVariable IV,
const MDNode *ScopeNode) {
- DIVariable Cleansed = DV;
- if (getExistingAbstractVariable(DV, Cleansed))
+ DIVariable Cleansed;
+ if (getExistingAbstractVariable(IV, Cleansed))
return;
- createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(ScopeNode));
+ createAbstractVariable(Cleansed, LScopes.getOrCreateAbstractScope(
+ cast<MDLocalScope>(ScopeNode)));
}
-void
-DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(const DIVariable &DV,
- const MDNode *ScopeNode) {
- DIVariable Cleansed = DV;
- if (getExistingAbstractVariable(DV, Cleansed))
+void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(
+ InlinedVariable IV, const MDNode *ScopeNode) {
+ DIVariable Cleansed;
+ if (getExistingAbstractVariable(IV, Cleansed))
return;
- if (LexicalScope *Scope = LScopes.findAbstractScope(ScopeNode))
+ if (LexicalScope *Scope =
+ LScopes.findAbstractScope(cast_or_null<MDLocalScope>(ScopeNode)))
createAbstractVariable(Cleansed, Scope);
}
// Collect variable information from side table maintained by MMI.
void DwarfDebug::collectVariableInfoFromMMITable(
- SmallPtrSetImpl<const MDNode *> &Processed) {
+ DenseSet<InlinedVariable> &Processed) {
for (const auto &VI : MMI->getVariableDbgInfo()) {
if (!VI.Var)
continue;
- Processed.insert(VI.Var);
+ assert(VI.Var->isValidLocationForIntrinsic(VI.Loc) &&
+ "Expected inlined-at fields to agree");
+
+ InlinedVariable Var(VI.Var, VI.Loc->getInlinedAt());
+ Processed.insert(Var);
LexicalScope *Scope = LScopes.findLexicalScope(VI.Loc);
// If variable scope is not found then skip this variable.
if (!Scope)
continue;
- DIVariable DV(VI.Var);
- DIExpression Expr(VI.Expr);
- ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
- auto RegVar = make_unique<DbgVariable>(DV, Expr, this, VI.Slot);
+ DIExpression Expr = cast_or_null<MDExpression>(VI.Expr);
+ ensureAbstractVariableIsCreatedIfScoped(Var, Scope->getScopeNode());
+ auto RegVar =
+ make_unique<DbgVariable>(Var.first, Var.second, Expr, this, VI.Slot);
if (InfoHolder.addScopeVariable(Scope, RegVar.get()))
ConcreteVariables.push_back(std::move(RegVar));
}
@@ -768,12 +759,12 @@ static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
/// Determine whether two variable pieces overlap.
static bool piecesOverlap(DIExpression P1, DIExpression P2) {
- if (!P1.isBitPiece() || !P2.isBitPiece())
+ if (!P1->isBitPiece() || !P2->isBitPiece())
return true;
- unsigned l1 = P1.getBitPieceOffset();
- unsigned l2 = P2.getBitPieceOffset();
- unsigned r1 = l1 + P1.getBitPieceSize();
- unsigned r2 = l2 + P2.getBitPieceSize();
+ unsigned l1 = P1->getBitPieceOffset();
+ unsigned l2 = P2->getBitPieceOffset();
+ unsigned r1 = l1 + P1->getBitPieceSize();
+ unsigned r2 = l2 + P2->getBitPieceSize();
// True where [l1,r1[ and [r1,r2[ overlap.
return (l1 < r2) && (l2 < r1);
}
@@ -845,7 +836,7 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
bool couldMerge = false;
// If this is a piece, it may belong to the current DebugLocEntry.
- if (DIExpr.isBitPiece()) {
+ if (DIExpr->isBitPiece()) {
// Add this value to the list of open ranges.
OpenRanges.push_back(Value);
@@ -884,35 +875,34 @@ DwarfDebug::buildLocationList(SmallVectorImpl<DebugLocEntry> &DebugLoc,
// Find variables for each lexical scope.
-void
-DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
- SmallPtrSetImpl<const MDNode *> &Processed) {
+void DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
+ DenseSet<InlinedVariable> &Processed) {
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMMITable(Processed);
for (const auto &I : DbgValues) {
- DIVariable DV(I.first);
- if (Processed.count(DV))
+ InlinedVariable IV = I.first;
+ if (Processed.count(IV))
continue;
- // Instruction ranges, specifying where DV is accessible.
+ // Instruction ranges, specifying where IV is accessible.
const auto &Ranges = I.second;
if (Ranges.empty())
continue;
LexicalScope *Scope = nullptr;
- if (MDNode *IA = DV.getInlinedAt())
- Scope = LScopes.findInlinedScope(DV.getContext(), IA);
+ if (const MDLocation *IA = IV.second)
+ Scope = LScopes.findInlinedScope(IV.first->getScope(), IA);
else
- Scope = LScopes.findLexicalScope(DV.getContext());
+ Scope = LScopes.findLexicalScope(IV.first->getScope());
// If variable scope is not found then skip this variable.
if (!Scope)
continue;
- Processed.insert(DV);
+ Processed.insert(IV);
const MachineInstr *MInsn = Ranges.front().first;
assert(MInsn->isDebugValue() && "History must begin with debug value");
- ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
+ ensureAbstractVariableIsCreatedIfScoped(IV, Scope->getScopeNode());
ConcreteVariables.push_back(make_unique<DbgVariable>(MInsn, this));
DbgVariable *RegVar = ConcreteVariables.back().get();
InfoHolder.addScopeVariable(Scope, RegVar);
@@ -937,16 +927,15 @@ DwarfDebug::collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
}
// 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.isVariable());
- if (!Processed.insert(DV).second)
+ for (DIVariable DV : SP->getVariables()) {
+ if (!Processed.insert(InlinedVariable(DV, nullptr)).second)
continue;
- if (LexicalScope *Scope = LScopes.findLexicalScope(DV.getContext())) {
- ensureAbstractVariableIsCreatedIfScoped(DV, Scope->getScopeNode());
+ if (LexicalScope *Scope = LScopes.findLexicalScope(DV->getScope())) {
+ ensureAbstractVariableIsCreatedIfScoped(InlinedVariable(DV, nullptr),
+ Scope->getScopeNode());
DIExpression NoExpr;
- ConcreteVariables.push_back(make_unique<DbgVariable>(DV, NoExpr, this));
+ ConcreteVariables.push_back(
+ make_unique<DbgVariable>(DV, nullptr, NoExpr, this));
InfoHolder.addScopeVariable(Scope, ConcreteVariables.back().get());
}
}
@@ -972,7 +961,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
if (!MI->isDebugValue()) {
DebugLoc DL = MI->getDebugLoc();
if (DL != PrevInstLoc) {
- if (!DL.isUnknown()) {
+ if (DL) {
unsigned Flags = 0;
PrevInstLoc = DL;
if (DL == PrologEndLoc) {
@@ -984,7 +973,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
Asm->OutStreamer.getContext().getCurrentDwarfLoc().getLine())
Flags |= DWARF2_FLAG_IS_STMT;
- const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
+ const MDNode *Scope = DL.getScope();
recordSourceLine(DL.getLine(), DL.getCol(), Scope, Flags);
} else if (UnknownLocations) {
PrevInstLoc = DL;
@@ -1072,7 +1061,7 @@ static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
for (const auto &MBB : *MF)
for (const auto &MI : MBB)
if (!MI.isDebugValue() && !MI.getFlag(MachineInstr::FrameSetup) &&
- !MI.getDebugLoc().isUnknown()) {
+ MI.getDebugLoc()) {
// Did the target forget to set the FrameSetup flag for CFI insns?
assert(!MI.isCFIInstruction() &&
"First non-frame-setup instruction is a CFI instruction.");
@@ -1137,11 +1126,11 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
// The first mention of a function argument gets the CurrentFnBegin
// label, so arguments are visible when breaking at function entry.
- DIVariable DIVar(Ranges.front().first->getDebugVariable());
- if (DIVar.isVariable() && DIVar.getTag() == dwarf::DW_TAG_arg_variable &&
- getDISubprogram(DIVar.getContext()).describes(MF->getFunction())) {
+ DIVariable DIVar = Ranges.front().first->getDebugVariable();
+ if (DIVar->getTag() == dwarf::DW_TAG_arg_variable &&
+ getDISubprogram(DIVar->getScope())->describes(MF->getFunction())) {
LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
- if (Ranges.front().first->getDebugExpression().isBitPiece()) {
+ if (Ranges.front().first->getDebugExpression()->isBitPiece()) {
// Mark all non-overlapping initial pieces.
for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
DIExpression Piece = I->first->getDebugExpression();
@@ -1168,15 +1157,11 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
// Record beginning of function.
PrologEndLoc = findPrologueEndLoc(MF);
- if (!PrologEndLoc.isUnknown()) {
- DebugLoc FnStartDL =
- PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext());
-
+ if (MDLocation *L = PrologEndLoc) {
// We'd like to list the prologue as "not statements" but GDB behaves
// poorly if we do that. Revisit this with caution/GDB (7.5+) testing.
- recordSourceLine(FnStartDL.getLine(), FnStartDL.getCol(),
- FnStartDL.getScope(MF->getFunction()->getContext()),
- DWARF2_FLAG_IS_STMT);
+ auto *SP = L->getInlinedAtScope()->getSubprogram();
+ recordSourceLine(SP->getScopeLine(), 0, SP, DWARF2_FLAG_IS_STMT);
}
}
@@ -1199,10 +1184,10 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
- DISubprogram SP(FnScope->getScopeNode());
+ DISubprogram SP = cast<MDSubprogram>(FnScope->getScopeNode());
DwarfCompileUnit &TheCU = *SPMap.lookup(SP);
- SmallPtrSet<const MDNode *, 16> ProcessedVars;
+ DenseSet<InlinedVariable> ProcessedVars;
collectVariableInfo(TheCU, SP, ProcessedVars);
// Add the range of this function to the list of ranges for the CU.
@@ -1210,7 +1195,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
// Under -gmlt, skip building the subprogram if there are no inlined
// subroutines inside it.
- if (TheCU.getCUNode().getEmissionKind() == DIBuilder::LineTablesOnly &&
+ if (TheCU.getCUNode()->getEmissionKind() == DIBuilder::LineTablesOnly &&
LScopes.getAbstractScopesList().empty() && !IsDarwin) {
assert(InfoHolder.getScopeVariables().empty());
assert(DbgValues.empty());
@@ -1229,16 +1214,13 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
#endif
// Construct abstract scopes.
for (LexicalScope *AScope : LScopes.getAbstractScopesList()) {
- DISubprogram SP(AScope->getScopeNode());
- assert(SP.isSubprogram());
+ DISubprogram SP = cast<MDSubprogram>(AScope->getScopeNode());
// 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).second)
+ for (DIVariable DV : SP->getVariables()) {
+ if (!ProcessedVars.insert(InlinedVariable(DV, nullptr)).second)
continue;
- ensureAbstractVariableIsCreated(DV, DV.getContext());
+ ensureAbstractVariableIsCreated(InlinedVariable(DV, nullptr),
+ DV->getScope());
assert(LScopes.getAbstractScopesList().size() == NumAbstractScopes
&& "ensureAbstractVariableIsCreated inserted abstract scopes");
}
@@ -1270,12 +1252,11 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
StringRef Dir;
unsigned Src = 1;
unsigned Discriminator = 0;
- if (DIScope Scope = DIScope(S)) {
- assert(Scope.isScope());
- Fn = Scope.getFilename();
- Dir = Scope.getDirectory();
- if (Scope.isLexicalBlockFile())
- Discriminator = DILexicalBlockFile(S).getDiscriminator();
+ if (auto *Scope = cast_or_null<MDScope>(S)) {
+ Fn = Scope->getFilename();
+ Dir = Scope->getDirectory();
+ if (auto *LBF = dyn_cast<MDLexicalBlockFile>(Scope))
+ Discriminator = LBF->getDiscriminator();
unsigned CUID = Asm->OutStreamer.getContext().getDwarfCompileUnitID();
Src = static_cast<DwarfCompileUnit &>(*InfoHolder.getUnits()[CUID])
@@ -1499,23 +1480,25 @@ static void emitDebugLocValue(const AsmPrinter &AP,
Streamer);
// Regular entry.
if (Value.isInt()) {
- DIBasicType BTy(DV.getType().resolve(TypeIdentifierMap));
- if (BTy.Verify() && (BTy.getEncoding() == dwarf::DW_ATE_signed ||
- BTy.getEncoding() == dwarf::DW_ATE_signed_char))
+ MDType *T = DV->getType().resolve(TypeIdentifierMap);
+ auto *B = dyn_cast<MDBasicType>(T);
+ if (B && (B->getEncoding() == dwarf::DW_ATE_signed ||
+ B->getEncoding() == dwarf::DW_ATE_signed_char))
DwarfExpr.AddSignedConstant(Value.getInt());
else
DwarfExpr.AddUnsignedConstant(Value.getInt());
} else if (Value.isLocation()) {
MachineLocation Loc = Value.getLoc();
DIExpression Expr = Value.getExpression();
- if (!Expr || (Expr.getNumElements() == 0))
+ if (!Expr || !Expr->getNumElements())
// Regular entry.
AP.EmitDwarfRegOp(Streamer, Loc);
else {
// Complex address entry.
if (Loc.getOffset()) {
DwarfExpr.AddMachineRegIndirect(Loc.getReg(), Loc.getOffset());
- DwarfExpr.AddExpression(Expr.begin(), Expr.end(), PieceOffsetInBits);
+ DwarfExpr.AddExpression(Expr->expr_op_begin(), Expr->expr_op_end(),
+ PieceOffsetInBits);
} else
DwarfExpr.AddMachineRegExpression(Expr, Loc.getReg(),
PieceOffsetInBits);
@@ -1542,8 +1525,8 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
unsigned Offset = 0;
for (auto Piece : Values) {
DIExpression Expr = Piece.getExpression();
- unsigned PieceOffset = Expr.getBitPieceOffset();
- unsigned PieceSize = Expr.getBitPieceSize();
+ unsigned PieceOffset = Expr->getBitPieceOffset();
+ unsigned PieceSize = Expr->getBitPieceSize();
assert(Offset <= PieceOffset && "overlapping or duplicate pieces");
if (Offset < PieceOffset) {
// The DWARF spec seriously mandates pieces with no locations for gaps.
@@ -1554,15 +1537,7 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
Offset += PieceOffset-Offset;
}
Offset += PieceSize;
-
-#ifndef NDEBUG
- DIVariable Var = Piece.getVariable();
- unsigned VarSize = Var.getSizeInBits(TypeIdentifierMap);
- assert(PieceSize+PieceOffset <= VarSize
- && "piece is larger than or outside of variable");
- assert(PieceSize != VarSize
- && "piece covers entire variable");
-#endif
+
emitDebugLocValue(AP, TypeIdentifierMap, Streamer, Piece, PieceOffset);
}
} else {
@@ -1850,7 +1825,7 @@ void DwarfDebug::emitDebugRanges() {
void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
std::unique_ptr<DwarfUnit> NewU) {
NewU->addString(Die, dwarf::DW_AT_GNU_dwo_name,
- U.getCUNode().getSplitDebugFilename());
+ U.getCUNode()->getSplitDebugFilename());
if (!CompilationDir.empty())
NewU->addString(Die, dwarf::DW_AT_comp_dir, CompilationDir);
@@ -1914,7 +1889,7 @@ MCDwarfDwoLineTable *DwarfDebug::getDwoLineTable(const DwarfCompileUnit &CU) {
if (!useSplitDwarf())
return nullptr;
if (SingleCU)
- SplitTypeUnitFileTable.setCompilationDir(CU.getCUNode().getDirectory());
+ SplitTypeUnitFileTable.setCompilationDir(CU.getCUNode()->getDirectory());
return &SplitTypeUnitFileTable;
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 74db3ef..e067f41 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -21,6 +21,7 @@
#include "DwarfAccelTable.h"
#include "DwarfFile.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallPtrSet.h"
@@ -74,7 +75,8 @@ public:
/// - Variables that are described by multiple MMI table entries have multiple
/// expressions and frame indices.
class DbgVariable {
- DIVariable Var; /// Variable Descriptor.
+ DIVariable Var; /// Variable Descriptor.
+ DILocation IA; /// Inlined at location.
SmallVector<DIExpression, 1> Expr; /// Complex address location expression.
DIE *TheDIE; /// Variable DIE.
unsigned DotDebugLocOffset; /// Offset in DotDebugLocEntries.
@@ -84,11 +86,11 @@ class DbgVariable {
public:
/// Construct a DbgVariable from a DIVariable.
- DbgVariable(DIVariable V, DIExpression E, DwarfDebug *DD, int FI = ~0)
- : Var(V), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U),
- MInsn(nullptr), DD(DD) {
+ DbgVariable(DIVariable V, DILocation IA, DIExpression E, DwarfDebug *DD,
+ int FI = ~0)
+ : Var(V), IA(IA), Expr(1, E), TheDIE(nullptr), DotDebugLocOffset(~0U),
+ MInsn(nullptr), DD(DD) {
FrameIndex.push_back(FI);
- assert(Var.Verify());
assert(!E || E->isValid());
}
@@ -96,6 +98,7 @@ public:
/// AbstractVar may be NULL.
DbgVariable(const MachineInstr *DbgValue, DwarfDebug *DD)
: Var(DbgValue->getDebugVariable()),
+ IA(DbgValue->getDebugLoc()->getInlinedAt()),
Expr(1, DbgValue->getDebugExpression()), TheDIE(nullptr),
DotDebugLocOffset(~0U), MInsn(DbgValue), DD(DD) {
FrameIndex.push_back(~0);
@@ -103,12 +106,13 @@ public:
// Accessors.
DIVariable getVariable() const { return Var; }
+ DILocation getInlinedAt() const { return IA; }
const ArrayRef<DIExpression> getExpression() const { return Expr; }
void setDIE(DIE &D) { TheDIE = &D; }
DIE *getDIE() const { return TheDIE; }
void setDotDebugLocOffset(unsigned O) { DotDebugLocOffset = O; }
unsigned getDotDebugLocOffset() const { return DotDebugLocOffset; }
- StringRef getName() const { return Var.getName(); }
+ StringRef getName() const { return Var->getName(); }
const MachineInstr *getMInsn() const { return MInsn; }
const ArrayRef<int> getFrameIndex() const { return FrameIndex; }
@@ -116,6 +120,7 @@ public:
assert( DotDebugLocOffset == ~0U && !MInsn && "not an MMI entry");
assert(V.DotDebugLocOffset == ~0U && !V.MInsn && "not an MMI entry");
assert(V.Var == Var && "conflicting DIVariable");
+ assert(V.IA == IA && "conflicting inlined-at location");
if (V.getFrameIndex().back() != ~0) {
auto E = V.getExpression();
@@ -124,40 +129,40 @@ public:
FrameIndex.append(FI.begin(), FI.end());
}
assert(Expr.size() > 1
- ? std::all_of(Expr.begin(), Expr.end(),
- [](DIExpression &E) { return E.isBitPiece(); })
- : (true && "conflicting locations for variable"));
+ ? std::all_of(Expr.begin(), Expr.end(),
+ [](DIExpression &E) { return E->isBitPiece(); })
+ : (true && "conflicting locations for variable"));
}
// Translate tag to proper Dwarf tag.
dwarf::Tag getTag() const {
- if (Var.getTag() == dwarf::DW_TAG_arg_variable)
+ if (Var->getTag() == dwarf::DW_TAG_arg_variable)
return dwarf::DW_TAG_formal_parameter;
return dwarf::DW_TAG_variable;
}
/// \brief Return true if DbgVariable is artificial.
bool isArtificial() const {
- if (Var.isArtificial())
+ if (Var->isArtificial())
return true;
- if (getType().isArtificial())
+ if (getType()->isArtificial())
return true;
return false;
}
bool isObjectPointer() const {
- if (Var.isObjectPointer())
+ if (Var->isObjectPointer())
return true;
- if (getType().isObjectPointer())
+ if (getType()->isObjectPointer())
return true;
return false;
}
bool variableHasComplexAddress() const {
- assert(Var.isVariable() && "Invalid complex DbgVariable!");
+ assert(Var && "Invalid complex DbgVariable!");
assert(Expr.size() == 1 &&
"variableHasComplexAddress() invoked on multi-FI variable");
- return Expr.back().getNumElements() > 0;
+ return Expr.back()->getNumElements() > 0;
}
bool isBlockByrefVariable() const;
DIType getType() const;
@@ -165,7 +170,7 @@ public:
private:
/// resolve - Look in the DwarfDebug map for the MDNode that
/// corresponds to the reference.
- template <typename T> T resolve(DIRef<T> Ref) const;
+ template <typename T> T *resolve(TypedDebugNodeRef<T> Ref) const;
};
@@ -324,14 +329,16 @@ class DwarfDebug : public AsmPrinterHandler {
return InfoHolder.getUnits();
}
+ typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
+
/// \brief Find abstract variable associated with Var.
- DbgVariable *getExistingAbstractVariable(const DIVariable &DV,
+ DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
DIVariable &Cleansed);
- DbgVariable *getExistingAbstractVariable(const DIVariable &DV);
+ DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
void createAbstractVariable(const DIVariable &DV, LexicalScope *Scope);
- void ensureAbstractVariableIsCreated(const DIVariable &Var,
+ void ensureAbstractVariableIsCreated(InlinedVariable Var,
const MDNode *Scope);
- void ensureAbstractVariableIsCreatedIfScoped(const DIVariable &Var,
+ void ensureAbstractVariableIsCreatedIfScoped(InlinedVariable Var,
const MDNode *Scope);
/// \brief Construct a DIE for this abstract scope.
@@ -461,7 +468,7 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Populate LexicalScope entries with variables' info.
void collectVariableInfo(DwarfCompileUnit &TheCU, DISubprogram SP,
- SmallPtrSetImpl<const MDNode *> &ProcessedVars);
+ DenseSet<InlinedVariable> &ProcessedVars);
/// \brief Build the location list for all DBG_VALUEs in the
/// function that describe the same variable.
@@ -470,7 +477,7 @@ class DwarfDebug : public AsmPrinterHandler {
/// \brief Collect variable information from the side table maintained
/// by MMI.
- void collectVariableInfoFromMMITable(SmallPtrSetImpl<const MDNode *> &P);
+ void collectVariableInfoFromMMITable(DenseSet<InlinedVariable> &P);
/// \brief Ensure that a label will be emitted before MI.
void requestLabelBeforeInsn(const MachineInstr *MI) {
@@ -567,7 +574,7 @@ public:
void emitDebugLocEntryLocation(const DebugLocEntry &Entry);
/// Find the MDNode for the given reference.
- template <typename T> T resolve(DIRef<T> Ref) const {
+ template <typename T> T *resolve(TypedDebugNodeRef<T> Ref) const {
return Ref.resolve(TypeIdentifierMap);
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 6eaf707..a4fd36f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -48,7 +48,7 @@ public:
// Main entry points.
//
DwarfCFIException(AsmPrinter *A);
- virtual ~DwarfCFIException();
+ ~DwarfCFIException() override;
/// Emit all exception information that should come after the content.
void endModule() override;
@@ -70,7 +70,7 @@ public:
// Main entry points.
//
ARMException(AsmPrinter *A);
- virtual ~ARMException();
+ ~ARMException() override;
/// Emit all exception information that should come after the content.
void endModule() override;
diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 489e455..e576c93 100644
--- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -195,27 +195,27 @@ static unsigned getOffsetOrZero(unsigned OffsetInBits,
bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
unsigned MachineReg,
unsigned PieceOffsetInBits) {
- auto I = Expr.begin();
- auto E = Expr.end();
+ auto I = Expr->expr_op_begin();
+ auto E = Expr->expr_op_end();
if (I == E)
return AddMachineRegPiece(MachineReg);
// Pattern-match combinations for which more efficient representations exist
// first.
bool ValidReg = false;
- switch (*I) {
+ switch (I->getOp()) {
case dwarf::DW_OP_bit_piece: {
- unsigned OffsetInBits = I->getArg(1);
- unsigned SizeInBits = I->getArg(2);
+ unsigned OffsetInBits = I->getArg(0);
+ unsigned SizeInBits = I->getArg(1);
// Piece always comes at the end of the expression.
return AddMachineRegPiece(MachineReg, SizeInBits,
getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
}
case dwarf::DW_OP_plus: {
// [DW_OP_reg,Offset,DW_OP_plus,DW_OP_deref] --> [DW_OP_breg,Offset].
- auto N = I->getNext();
- if ((N != E) && (*N == dwarf::DW_OP_deref)) {
- unsigned Offset = I->getArg(1);
+ auto N = I.getNext();
+ if (N != E && N->getOp() == dwarf::DW_OP_deref) {
+ unsigned Offset = I->getArg(0);
ValidReg = AddMachineRegIndirect(MachineReg, Offset);
std::advance(I, 2);
break;
@@ -240,20 +240,20 @@ bool DwarfExpression::AddMachineRegExpression(DIExpression Expr,
return true;
}
-void DwarfExpression::AddExpression(DIExpression::iterator I,
- DIExpression::iterator E,
+void DwarfExpression::AddExpression(MDExpression::expr_op_iterator I,
+ MDExpression::expr_op_iterator E,
unsigned PieceOffsetInBits) {
for (; I != E; ++I) {
- switch (*I) {
+ switch (I->getOp()) {
case dwarf::DW_OP_bit_piece: {
- unsigned OffsetInBits = I->getArg(1);
- unsigned SizeInBits = I->getArg(2);
+ unsigned OffsetInBits = I->getArg(0);
+ unsigned SizeInBits = I->getArg(1);
AddOpPiece(SizeInBits, getOffsetOrZero(OffsetInBits, PieceOffsetInBits));
break;
}
case dwarf::DW_OP_plus:
EmitOp(dwarf::DW_OP_plus_uconst);
- EmitUnsigned(I->getArg(1));
+ EmitUnsigned(I->getArg(0));
break;
case dwarf::DW_OP_deref:
EmitOp(dwarf::DW_OP_deref);
diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 985d52c..a8b65f5 100644
--- a/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -97,7 +97,8 @@ public:
/// Emit a the operations remaining the DIExpressionIterator I.
/// \param PieceOffsetInBits If this is one piece out of a fragmented
/// location, this is the offset of the piece inside the entire variable.
- void AddExpression(DIExpression::iterator I, DIExpression::iterator E,
+ void AddExpression(MDExpression::expr_op_iterator I,
+ MDExpression::expr_op_iterator E,
unsigned PieceOffsetInBits = 0);
};
diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/lib/CodeGen/AsmPrinter/DwarfFile.cpp
index 60acc58e..32adb40 100644
--- a/lib/CodeGen/AsmPrinter/DwarfFile.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -139,7 +139,7 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
SmallVectorImpl<DbgVariable *> &Vars = ScopeVariables[LS];
DIVariable DV = Var->getVariable();
// Variables with positive arg numbers are parameters.
- if (unsigned ArgNum = DV.getArgNumber()) {
+ if (unsigned ArgNum = DV->getArg()) {
// Keep all parameters in order at the start of the variable list to ensure
// function types are correct (no out-of-order parameters)
//
@@ -149,7 +149,7 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
// rather than linear search.
auto I = Vars.begin();
while (I != Vars.end()) {
- unsigned CurNum = (*I)->getVariable().getArgNumber();
+ unsigned CurNum = (*I)->getVariable()->getArg();
// A local (non-parameter) variable has been found, insert immediately
// before it.
if (CurNum == 0)
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index f6af73f..9154652 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -175,8 +175,8 @@ static bool isShareableAcrossCUs(DIDescriptor D) {
// level already) but may be implementable for some value in projects
// building multiple independent libraries with LTO and then linking those
// together.
- return (D.isType() ||
- (D.isSubprogram() && !DISubprogram(D).isDefinition())) &&
+ return (isa<MDType>(D) ||
+ (isa<MDSubprogram>(D) && !cast<MDSubprogram>(D)->isDefinition())) &&
!GenerateDwarfTypeUnits;
}
@@ -397,52 +397,48 @@ 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) {
- assert(V.isVariable());
+ assert(V);
- addSourceLine(Die, V.getLineNumber(), V.getContext().getFilename(),
- V.getContext().getDirectory());
+ addSourceLine(Die, V->getLine(), V->getScope()->getFilename(),
+ V->getScope()->getDirectory());
}
/// addSourceLine - Add location information to specified debug information
/// entry.
void DwarfUnit::addSourceLine(DIE &Die, DIGlobalVariable G) {
- assert(G.isGlobalVariable());
+ assert(G);
- addSourceLine(Die, G.getLineNumber(), G.getFilename(), G.getDirectory());
+ addSourceLine(Die, G->getLine(), G->getFilename(), G->getDirectory());
}
/// addSourceLine - Add location information to specified debug information
/// entry.
void DwarfUnit::addSourceLine(DIE &Die, DISubprogram SP) {
- assert(SP.isSubprogram());
+ assert(SP);
- addSourceLine(Die, SP.getLineNumber(), SP.getFilename(), SP.getDirectory());
+ addSourceLine(Die, SP->getLine(), SP->getFilename(), SP->getDirectory());
}
/// addSourceLine - Add location information to specified debug information
/// entry.
void DwarfUnit::addSourceLine(DIE &Die, DIType Ty) {
- assert(Ty.isType());
+ assert(Ty);
- addSourceLine(Die, Ty.getLineNumber(), Ty.getFilename(), Ty.getDirectory());
+ addSourceLine(Die, Ty->getLine(), Ty->getFilename(), Ty->getDirectory());
}
/// addSourceLine - Add location information to specified debug information
/// entry.
void DwarfUnit::addSourceLine(DIE &Die, DIObjCProperty Ty) {
- assert(Ty.isObjCProperty());
+ assert(Ty);
- DIFile File = Ty.getFile();
- addSourceLine(Die, Ty.getLineNumber(), File.getFilename(),
- File.getDirectory());
+ addSourceLine(Die, Ty->getLine(), Ty->getFilename(), Ty->getDirectory());
}
/// addSourceLine - Add location information to specified debug information
/// entry.
void DwarfUnit::addSourceLine(DIE &Die, DINameSpace NS) {
- assert(NS.Verify());
-
- addSourceLine(Die, NS.getLineNumber(), NS.getFilename(), NS.getDirectory());
+ addSourceLine(Die, NS->getLine(), NS->getFilename(), NS->getDirectory());
}
/// addRegisterOp - Add register operand.
@@ -525,28 +521,26 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
const MachineLocation &Location) {
DIType Ty = DV.getType();
DIType TmpTy = Ty;
- uint16_t Tag = Ty.getTag();
+ uint16_t Tag = Ty->getTag();
bool isPointer = false;
StringRef varName = DV.getName();
if (Tag == dwarf::DW_TAG_pointer_type) {
- DIDerivedType DTy(Ty);
- TmpTy = resolve(DTy.getTypeDerivedFrom());
+ DIDerivedType DTy = cast<MDDerivedType>(Ty);
+ TmpTy = resolve(DTy->getBaseType());
isPointer = true;
}
- DICompositeType blockStruct(TmpTy);
-
// Find the __forwarding field and the variable field in the __Block_byref
// struct.
- DIArray Fields = blockStruct.getElements();
+ DIArray Fields = cast<MDCompositeTypeBase>(TmpTy)->getElements();
DIDerivedType varField;
DIDerivedType forwardingField;
- for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
- DIDerivedType DT(Fields.getElement(i));
- StringRef fieldName = DT.getName();
+ for (unsigned i = 0, N = Fields.size(); i < N; ++i) {
+ DIDerivedType DT = cast<MDDerivedTypeBase>(Fields[i]);
+ StringRef fieldName = DT->getName();
if (fieldName == "__forwarding")
forwardingField = DT;
else if (fieldName == varName)
@@ -554,8 +548,8 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
}
// Get the offsets for the forwarding field and the variable field.
- unsigned forwardingFieldOffset = forwardingField.getOffsetInBits() >> 3;
- unsigned varFieldOffset = varField.getOffsetInBits() >> 2;
+ unsigned forwardingFieldOffset = forwardingField->getOffsetInBits() >> 3;
+ unsigned varFieldOffset = varField->getOffsetInBits() >> 2;
// Decode the original location, and use that as the start of the byref
// variable's location.
@@ -601,9 +595,8 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
/// Return true if type encoding is unsigned.
static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
- DIDerivedType DTy(Ty);
- if (DTy.isDerivedType()) {
- dwarf::Tag T = (dwarf::Tag)Ty.getTag();
+ if (DIDerivedType DTy = dyn_cast<MDDerivedTypeBase>(Ty)) {
+ dwarf::Tag T = (dwarf::Tag)Ty->getTag();
// Encode pointer constants as unsigned bytes. This is used at least for
// null pointer constant emission.
// (Pieces of) aggregate types that get hacked apart by SROA may also be
@@ -624,56 +617,55 @@ static bool isUnsignedDIType(DwarfDebug *DD, DIType Ty) {
T == dwarf::DW_TAG_volatile_type ||
T == dwarf::DW_TAG_restrict_type ||
T == dwarf::DW_TAG_enumeration_type);
- if (DITypeRef Deriv = DTy.getTypeDerivedFrom())
+ if (DITypeRef Deriv = DTy->getBaseType())
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);
+ assert(DTy->getTag() == dwarf::DW_TAG_enumeration_type);
return false;
}
- DIBasicType BTy(Ty);
- assert(BTy.isBasicType());
- unsigned Encoding = BTy.getEncoding();
+ DIBasicType BTy = cast<MDBasicType>(Ty);
+ 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_float ||
- Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
- (Ty.getTag() == dwarf::DW_TAG_unspecified_type &&
- Ty.getName() == "decltype(nullptr)")) &&
+ Encoding == dwarf::DW_ATE_float || Encoding == dwarf::DW_ATE_UTF ||
+ Encoding == dwarf::DW_ATE_boolean ||
+ (Ty->getTag() == dwarf::DW_TAG_unspecified_type &&
+ Ty->getName() == "decltype(nullptr)")) &&
"Unsupported encoding");
- return (Encoding == dwarf::DW_ATE_unsigned ||
- Encoding == dwarf::DW_ATE_unsigned_char ||
- Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
- Ty.getTag() == dwarf::DW_TAG_unspecified_type);
+ return Encoding == dwarf::DW_ATE_unsigned ||
+ Encoding == dwarf::DW_ATE_unsigned_char ||
+ Encoding == dwarf::DW_ATE_UTF || Encoding == dwarf::DW_ATE_boolean ||
+ Ty->getTag() == dwarf::DW_TAG_unspecified_type;
}
/// If this type is derived from a base type then return base type size.
static uint64_t getBaseTypeSize(DwarfDebug *DD, DIDerivedType Ty) {
- unsigned Tag = Ty.getTag();
+ unsigned Tag = Ty->getTag();
if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
Tag != dwarf::DW_TAG_restrict_type)
- return Ty.getSizeInBits();
+ return Ty->getSizeInBits();
- DIType BaseType = DD->resolve(Ty.getTypeDerivedFrom());
+ auto *BaseType = DD->resolve(Ty->getBaseType());
- assert(BaseType.isValid() && "Unexpected invalid base type");
+ assert(BaseType && "Unexpected invalid base type");
// If this is a derived type, go ahead and get the base type, unless it's a
// reference then it's just the size of the field. Pointer types have no need
// of this since they're a different type of qualification on the type.
- if (BaseType.getTag() == dwarf::DW_TAG_reference_type ||
- BaseType.getTag() == dwarf::DW_TAG_rvalue_reference_type)
- return Ty.getSizeInBits();
+ if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
+ BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
+ return Ty->getSizeInBits();
- if (BaseType.isDerivedType())
- return getBaseTypeSize(DD, DIDerivedType(BaseType));
+ if (auto *DT = dyn_cast<MDDerivedTypeBase>(BaseType))
+ return getBaseTypeSize(DD, DT);
- return BaseType.getSizeInBits();
+ return BaseType->getSizeInBits();
}
/// addConstantFPValue - Add constant value entry in variable DIE.
@@ -771,39 +763,37 @@ void DwarfUnit::addLinkageName(DIE &Die, StringRef LinkageName) {
/// addTemplateParams - Add template parameters into buffer.
void DwarfUnit::addTemplateParams(DIE &Buffer, DIArray TParams) {
// Add template parameters.
- for (unsigned i = 0, e = TParams.getNumElements(); i != e; ++i) {
- DIDescriptor Element = TParams.getElement(i);
- if (Element.isTemplateTypeParameter())
- constructTemplateTypeParameterDIE(Buffer,
- DITemplateTypeParameter(Element));
- else if (Element.isTemplateValueParameter())
- constructTemplateValueParameterDIE(Buffer,
- DITemplateValueParameter(Element));
+ for (unsigned i = 0, e = TParams.size(); i != e; ++i) {
+ DIDescriptor Element = TParams[i];
+ if (auto *TTP = dyn_cast<MDTemplateTypeParameter>(Element))
+ constructTemplateTypeParameterDIE(Buffer, TTP);
+ else if (auto *TVP = dyn_cast<MDTemplateValueParameter>(Element))
+ constructTemplateValueParameterDIE(Buffer, TVP);
}
}
/// getOrCreateContextDIE - Get context owner's DIE.
DIE *DwarfUnit::getOrCreateContextDIE(DIScope Context) {
- if (!Context || Context.isFile())
+ if (!Context || isa<MDFile>(Context))
return &getUnitDie();
- if (Context.isType())
- return getOrCreateTypeDIE(DIType(Context));
- if (Context.isNameSpace())
- return getOrCreateNameSpace(DINameSpace(Context));
- if (Context.isSubprogram())
- return getOrCreateSubprogramDIE(DISubprogram(Context));
+ if (auto *T = dyn_cast<MDType>(Context))
+ return getOrCreateTypeDIE(T);
+ if (auto *NS = dyn_cast<MDNamespace>(Context))
+ return getOrCreateNameSpace(NS);
+ if (auto *SP = dyn_cast<MDSubprogram>(Context))
+ return getOrCreateSubprogramDIE(SP);
return getDIE(Context);
}
DIE *DwarfUnit::createTypeDIE(DICompositeType Ty) {
- DIScope Context = resolve(Ty.getContext());
+ DIScope Context = resolve(Ty->getScope());
DIE *ContextDIE = getOrCreateContextDIE(Context);
if (DIE *TyDIE = getDIE(Ty))
return TyDIE;
// Create new type.
- DIE &TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
+ DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty);
constructTypeDIE(TyDIE, Ty);
@@ -817,18 +807,18 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
if (!TyNode)
return nullptr;
- DIType Ty(TyNode);
- assert(Ty.isType());
- assert(Ty == resolve(Ty.getRef()) &&
+ auto *Ty = cast<MDType>(TyNode);
+ 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()));
+ if (Ty->getTag() == dwarf::DW_TAG_restrict_type && DD->getDwarfVersion() <= 2)
+ return getOrCreateTypeDIE(
+ resolve(DITypeRef(cast<MDDerivedType>(Ty)->getBaseType())));
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
- DIScope Context = resolve(Ty.getContext());
+ DIScope Context = resolve(Ty->getScope());
DIE *ContextDIE = getOrCreateContextDIE(Context);
assert(ContextDIE);
@@ -836,24 +826,22 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
return TyDIE;
// Create new type.
- DIE &TyDIE = createAndAddDIE(Ty.getTag(), *ContextDIE, Ty);
+ DIE &TyDIE = createAndAddDIE(Ty->getTag(), *ContextDIE, Ty);
updateAcceleratorTables(Context, Ty, TyDIE);
- if (Ty.isBasicType())
- constructTypeDIE(TyDIE, DIBasicType(Ty));
- else if (Ty.isCompositeType()) {
- DICompositeType CTy(Ty);
- if (GenerateDwarfTypeUnits && !Ty.isForwardDecl())
- if (MDString *TypeId = CTy.getIdentifier()) {
+ if (auto *BT = dyn_cast<MDBasicType>(Ty))
+ constructTypeDIE(TyDIE, BT);
+ else if (DICompositeType CTy = dyn_cast<MDCompositeTypeBase>(Ty)) {
+ if (GenerateDwarfTypeUnits && !Ty->isForwardDecl())
+ if (MDString *TypeId = CTy->getRawIdentifier()) {
DD->addDwarfTypeUnitType(getCU(), TypeId->getString(), TyDIE, CTy);
// Skip updating the accelerator tables since this is not the full type.
return &TyDIE;
}
constructTypeDIE(TyDIE, CTy);
} else {
- assert(Ty.isDerivedType() && "Unknown kind of DIType");
- constructTypeDIE(TyDIE, DIDerivedType(Ty));
+ constructTypeDIE(TyDIE, cast<MDDerivedType>(Ty));
}
return &TyDIE;
@@ -861,19 +849,18 @@ DIE *DwarfUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
void DwarfUnit::updateAcceleratorTables(DIScope Context, DIType Ty,
const DIE &TyDIE) {
- if (!Ty.getName().empty() && !Ty.isForwardDecl()) {
+ if (!Ty->getName().empty() && !Ty->isForwardDecl()) {
bool IsImplementation = 0;
- if (Ty.isCompositeType()) {
- DICompositeType CT(Ty);
+ if (auto *CT = dyn_cast<MDCompositeTypeBase>(Ty)) {
// A runtime language of 0 actually means C/C++ and that any
// non-negative value is some version of Objective-C/C++.
- IsImplementation = (CT.getRunTimeLang() == 0) || CT.isObjcClassComplete();
+ IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
}
unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
- DD->addAccelType(Ty.getName(), TyDIE, Flags);
+ DD->addAccelType(Ty->getName(), TyDIE, Flags);
- if (!Context || Context.isCompileUnit() || Context.isFile() ||
- Context.isNameSpace())
+ if (!Context || isa<MDCompileUnit>(Context) || isa<MDFile>(Context) ||
+ isa<MDNamespace>(Context))
addGlobalType(Ty, TyDIE, Context);
}
}
@@ -914,10 +901,10 @@ std::string DwarfUnit::getParentContextString(DIScope Context) const {
std::string CS;
SmallVector<DIScope, 1> Parents;
- while (!Context.isCompileUnit()) {
+ while (!isa<MDCompileUnit>(Context)) {
Parents.push_back(Context);
- if (Context.getContext())
- Context = resolve(Context.getContext());
+ if (Context->getScope())
+ Context = resolve(Context->getScope());
else
// Structure, etc types will have a NULL context if they're at the top
// level.
@@ -929,9 +916,9 @@ std::string DwarfUnit::getParentContextString(DIScope Context) const {
for (SmallVectorImpl<DIScope>::reverse_iterator I = Parents.rbegin(),
E = Parents.rend();
I != E; ++I) {
- DIScope Ctx = *I;
- StringRef Name = Ctx.getName();
- if (Name.empty() && Ctx.isNameSpace())
+ const MDScope *Ctx = *I;
+ StringRef Name = Ctx->getName();
+ if (Name.empty() && isa<MDNamespace>(Ctx))
Name = "(anonymous namespace)";
if (!Name.empty()) {
CS += Name;
@@ -944,31 +931,31 @@ std::string DwarfUnit::getParentContextString(DIScope Context) const {
/// constructTypeDIE - Construct basic type die from DIBasicType.
void DwarfUnit::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
// Get core information.
- StringRef Name = BTy.getName();
+ StringRef Name = BTy->getName();
// Add name if not anonymous or intermediate type.
if (!Name.empty())
addString(Buffer, dwarf::DW_AT_name, Name);
// An unspecified type only has a name attribute.
- if (BTy.getTag() == dwarf::DW_TAG_unspecified_type)
+ if (BTy->getTag() == dwarf::DW_TAG_unspecified_type)
return;
addUInt(Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
- BTy.getEncoding());
+ BTy->getEncoding());
- uint64_t Size = BTy.getSizeInBits() >> 3;
+ uint64_t Size = BTy->getSizeInBits() >> 3;
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
}
/// constructTypeDIE - Construct derived type die from DIDerivedType.
void DwarfUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
// Get core information.
- StringRef Name = DTy.getName();
- uint64_t Size = DTy.getSizeInBits() >> 3;
+ StringRef Name = DTy->getName();
+ uint64_t Size = DTy->getSizeInBits() >> 3;
uint16_t Tag = Buffer.getTag();
// Map to main type, void will not have a type.
- DIType FromTy = resolve(DTy.getTypeDerivedFrom());
+ DIType FromTy = resolve(DTy->getBaseType());
if (FromTy)
addType(Buffer, FromTy);
@@ -982,24 +969,25 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
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(cast<MDDerivedType>(DTy)->getClassType())));
// Add source line info if available and TyDesc is not a forward declaration.
- if (!DTy.isForwardDecl())
+ if (!DTy->isForwardDecl())
addSourceLine(Buffer, DTy);
}
/// constructSubprogramArguments - Construct function argument DIEs.
void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeArray Args) {
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIType Ty = resolve(Args.getElement(i));
+ for (unsigned i = 1, N = Args.size(); i < N; ++i) {
+ DIType Ty = resolve(Args[i]);
if (!Ty) {
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);
addType(Arg, Ty);
- if (Ty.isArtificial())
+ if (Ty->isArtificial())
addFlag(Arg, dwarf::DW_AT_artificial);
}
}
@@ -1008,9 +996,9 @@ void DwarfUnit::constructSubprogramArguments(DIE &Buffer, DITypeArray Args) {
/// constructTypeDIE - Construct type DIE from DICompositeType.
void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// Add name if not anonymous or intermediate type.
- StringRef Name = CTy.getName();
+ StringRef Name = CTy->getName();
- uint64_t Size = CTy.getSizeInBits() >> 3;
+ uint64_t Size = CTy->getSizeInBits() >> 3;
uint16_t Tag = Buffer.getTag();
switch (Tag) {
@@ -1022,14 +1010,13 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
break;
case dwarf::DW_TAG_subroutine_type: {
// Add return type. A void return won't have a type.
- DITypeArray Elements = DISubroutineType(CTy).getTypeArray();
- DIType RTy(resolve(Elements.getElement(0)));
- if (RTy)
- addType(Buffer, RTy);
+ auto Elements = cast<MDSubroutineType>(CTy)->getTypeArray();
+ if (Elements.size())
+ if (auto RTy = resolve(Elements[0]))
+ addType(Buffer, RTy);
bool isPrototyped = true;
- if (Elements.getNumElements() == 2 &&
- !Elements.getElement(1))
+ if (Elements.size() == 2 && !Elements[1])
isPrototyped = false;
constructSubprogramArguments(Buffer, Elements);
@@ -1042,60 +1029,46 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Language == dwarf::DW_LANG_ObjC))
addFlag(Buffer, dwarf::DW_AT_prototyped);
- if (CTy.isLValueReference())
+ if (CTy->isLValueReference())
addFlag(Buffer, dwarf::DW_AT_reference);
- if (CTy.isRValueReference())
+ if (CTy->isRValueReference())
addFlag(Buffer, dwarf::DW_AT_rvalue_reference);
} break;
case dwarf::DW_TAG_structure_type:
case dwarf::DW_TAG_union_type:
case dwarf::DW_TAG_class_type: {
// Add elements to structure type.
- DIArray Elements = CTy.getElements();
- for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
- DIDescriptor Element = Elements.getElement(i);
- if (Element.isSubprogram())
- getOrCreateSubprogramDIE(DISubprogram(Element));
- else if (Element.isDerivedType()) {
- DIDerivedType DDTy(Element);
- if (DDTy.getTag() == dwarf::DW_TAG_friend) {
+ DIArray Elements = CTy->getElements();
+ for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
+ DIDescriptor Element = Elements[i];
+ if (!Element)
+ continue;
+ if (auto *SP = dyn_cast<MDSubprogram>(Element))
+ getOrCreateSubprogramDIE(SP);
+ else if (DIDerivedType DDTy = dyn_cast<MDDerivedTypeBase>(Element)) {
+ if (DDTy->getTag() == dwarf::DW_TAG_friend) {
DIE &ElemDie = createAndAddDIE(dwarf::DW_TAG_friend, Buffer);
- addType(ElemDie, resolve(DDTy.getTypeDerivedFrom()),
- dwarf::DW_AT_friend);
- } else if (DDTy.isStaticMember()) {
+ addType(ElemDie, resolve(DDTy->getBaseType()), dwarf::DW_AT_friend);
+ } else if (DDTy->isStaticMember()) {
getOrCreateStaticMemberDIE(DDTy);
} else {
constructMemberDIE(Buffer, DDTy);
}
- } else if (Element.isObjCProperty()) {
- DIObjCProperty Property(Element);
- DIE &ElemDie = createAndAddDIE(Property.getTag(), Buffer);
- StringRef PropertyName = Property.getObjCPropertyName();
+ } else if (DIObjCProperty Property = dyn_cast<MDObjCProperty>(Element)) {
+ DIE &ElemDie = createAndAddDIE(Property->getTag(), Buffer);
+ StringRef PropertyName = Property->getName();
addString(ElemDie, dwarf::DW_AT_APPLE_property_name, PropertyName);
- if (Property.getType())
- addType(ElemDie, Property.getType());
+ if (Property->getType())
+ addType(ElemDie, Property->getType());
addSourceLine(ElemDie, Property);
- StringRef GetterName = Property.getObjCPropertyGetterName();
+ StringRef GetterName = Property->getGetterName();
if (!GetterName.empty())
addString(ElemDie, dwarf::DW_AT_APPLE_property_getter, GetterName);
- StringRef SetterName = Property.getObjCPropertySetterName();
+ StringRef SetterName = Property->getSetterName();
if (!SetterName.empty())
addString(ElemDie, dwarf::DW_AT_APPLE_property_setter, SetterName);
- unsigned PropertyAttributes = 0;
- if (Property.isReadOnlyObjCProperty())
- PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readonly;
- if (Property.isReadWriteObjCProperty())
- PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_readwrite;
- if (Property.isAssignObjCProperty())
- PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_assign;
- if (Property.isRetainObjCProperty())
- PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_retain;
- if (Property.isCopyObjCProperty())
- PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_copy;
- if (Property.isNonAtomicObjCProperty())
- PropertyAttributes |= dwarf::DW_APPLE_PROPERTY_nonatomic;
- if (PropertyAttributes)
+ if (unsigned PropertyAttributes = Property->getAttributes())
addUInt(ElemDie, dwarf::DW_AT_APPLE_property_attribute, None,
PropertyAttributes);
@@ -1104,28 +1077,27 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Entry = createDIEEntry(ElemDie);
insertDIEEntry(Element, Entry);
}
- } else
- continue;
+ }
}
- if (CTy.isAppleBlockExtension())
+ if (CTy->isAppleBlockExtension())
addFlag(Buffer, dwarf::DW_AT_APPLE_block);
// This is outside the DWARF spec, but GDB expects a DW_AT_containing_type
// inside C++ composite types to point to the base class with the vtable.
- DICompositeType ContainingType(resolve(CTy.getContainingType()));
- if (ContainingType)
+ if (DICompositeType ContainingType =
+ dyn_cast_or_null<MDCompositeType>(resolve(CTy->getVTableHolder())))
addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
*getOrCreateTypeDIE(ContainingType));
- if (CTy.isObjcClassComplete())
+ if (CTy->isObjcClassComplete())
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.
if (Tag == dwarf::DW_TAG_class_type ||
Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type)
- addTemplateParams(Buffer, CTy.getTemplateParams());
+ addTemplateParams(Buffer, CTy->getTemplateParams());
break;
}
@@ -1144,20 +1116,20 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// TODO: Do we care about size for enum forward declarations?
if (Size)
addUInt(Buffer, dwarf::DW_AT_byte_size, None, Size);
- else if (!CTy.isForwardDecl())
+ else if (!CTy->isForwardDecl())
// Add zero size if it is not a forward declaration.
addUInt(Buffer, dwarf::DW_AT_byte_size, None, 0);
// If we're a forward decl, say so.
- if (CTy.isForwardDecl())
+ if (CTy->isForwardDecl())
addFlag(Buffer, dwarf::DW_AT_declaration);
// Add source line info if available.
- if (!CTy.isForwardDecl())
+ if (!CTy->isForwardDecl())
addSourceLine(Buffer, CTy);
// No harm in adding the runtime language to the declaration.
- unsigned RLang = CTy.getRunTimeLang();
+ unsigned RLang = CTy->getRuntimeLang();
if (RLang)
addUInt(Buffer, dwarf::DW_AT_APPLE_runtime_class, dwarf::DW_FORM_data1,
RLang);
@@ -1171,10 +1143,10 @@ void DwarfUnit::constructTemplateTypeParameterDIE(DIE &Buffer,
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())
- addType(ParamDIE, resolve(TP.getType()));
- if (!TP.getName().empty())
- addString(ParamDIE, dwarf::DW_AT_name, TP.getName());
+ if (TP->getType())
+ addType(ParamDIE, resolve(TP->getType()));
+ if (!TP->getName().empty())
+ addString(ParamDIE, dwarf::DW_AT_name, TP->getName());
}
/// constructTemplateValueParameterDIE - Construct new DIE for the given
@@ -1182,17 +1154,17 @@ 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.
- if (VP.getTag() == dwarf::DW_TAG_template_value_parameter)
- addType(ParamDIE, resolve(VP.getType()));
- if (!VP.getName().empty())
- addString(ParamDIE, dwarf::DW_AT_name, VP.getName());
- if (Metadata *Val = VP.getValue()) {
+ if (VP->getTag() == dwarf::DW_TAG_template_value_parameter)
+ addType(ParamDIE, resolve(VP->getType()));
+ if (!VP->getName().empty())
+ addString(ParamDIE, dwarf::DW_AT_name, VP->getName());
+ if (Metadata *Val = VP->getValue()) {
if (ConstantInt *CI = mdconst::dyn_extract<ConstantInt>(Val))
- addConstantValue(ParamDIE, CI, resolve(VP.getType()));
+ addConstantValue(ParamDIE, CI, resolve(VP->getType()));
else if (GlobalValue *GV = mdconst::dyn_extract<GlobalValue>(Val)) {
// For declaration non-type template parameters (such as global values and
// functions)
@@ -1202,14 +1174,12 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer,
// parameter, rather than a pointer to it.
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) {
+ } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_template_param) {
assert(isa<MDString>(Val));
addString(ParamDIE, dwarf::DW_AT_GNU_template_name,
cast<MDString>(Val)->getString());
- } else if (VP.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
- assert(isa<MDNode>(Val));
- DIArray A(cast<MDNode>(Val));
- addTemplateParams(ParamDIE, A);
+ } else if (VP->getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
+ addTemplateParams(ParamDIE, cast<MDTuple>(Val));
}
}
}
@@ -1218,19 +1188,19 @@ DwarfUnit::constructTemplateValueParameterDIE(DIE &Buffer,
DIE *DwarfUnit::getOrCreateNameSpace(DINameSpace NS) {
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
- DIE *ContextDIE = getOrCreateContextDIE(NS.getContext());
+ DIE *ContextDIE = getOrCreateContextDIE(NS->getScope());
if (DIE *NDie = getDIE(NS))
return NDie;
DIE &NDie = createAndAddDIE(dwarf::DW_TAG_namespace, *ContextDIE, NS);
- StringRef Name = NS.getName();
+ StringRef Name = NS->getName();
if (!Name.empty())
- addString(NDie, dwarf::DW_AT_name, NS.getName());
+ addString(NDie, dwarf::DW_AT_name, NS->getName());
else
Name = "(anonymous namespace)";
DD->addAccelNamespace(Name, NDie);
- addGlobalName(Name, NDie, NS.getContext());
+ addGlobalName(Name, NDie, NS->getScope());
addSourceLine(NDie, NS);
return &NDie;
}
@@ -1241,12 +1211,12 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP, bool Minimal) {
// such construction creates the DIE (as is the case for member function
// declarations).
DIE *ContextDIE =
- Minimal ? &getUnitDie() : getOrCreateContextDIE(resolve(SP.getContext()));
+ Minimal ? &getUnitDie() : getOrCreateContextDIE(resolve(SP->getScope()));
if (DIE *SPDie = getDIE(SP))
return SPDie;
- if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+ if (auto *SPDecl = SP->getDeclaration()) {
if (!Minimal) {
// Add subprogram definitions to the CU die directly.
ContextDIE = &getUnitDie();
@@ -1260,7 +1230,7 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(DISubprogram SP, bool Minimal) {
// Stop here and fill this in later, depending on whether or not this
// subprogram turns out to have inlined instances or not.
- if (SP.isDefinition())
+ if (SP->isDefinition())
return &SPDie;
applySubprogramAttributes(SP, SPDie);
@@ -1271,19 +1241,19 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(DISubprogram SP,
DIE &SPDie) {
DIE *DeclDie = nullptr;
StringRef DeclLinkageName;
- if (DISubprogram SPDecl = SP.getFunctionDeclaration()) {
+ if (auto *SPDecl = SP->getDeclaration()) {
DeclDie = getDIE(SPDecl);
assert(DeclDie && "This DIE should've already been constructed when the "
"definition DIE was created in "
"getOrCreateSubprogramDIE");
- DeclLinkageName = SPDecl.getLinkageName();
+ DeclLinkageName = SPDecl->getLinkageName();
}
// Add function template parameters.
- addTemplateParams(SPDie, SP.getTemplateParams());
+ addTemplateParams(SPDie, SP->getTemplateParams());
// Add the linkage name if we have one and it isn't in the Decl.
- StringRef LinkageName = SP.getLinkageName();
+ StringRef LinkageName = SP->getLinkageName();
assert(((LinkageName.empty() || DeclLinkageName.empty()) ||
LinkageName == DeclLinkageName) &&
"decl has a linkage name and it is different");
@@ -1306,8 +1276,8 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
return;
// Constructors and operators for anonymous aggregates do not have names.
- if (!SP.getName().empty())
- addString(SPDie, dwarf::DW_AT_name, SP.getName());
+ if (!SP->getName().empty())
+ addString(SPDie, dwarf::DW_AT_name, SP->getName());
// Skip the rest of the attributes under -gmlt to save space.
if (Minimal)
@@ -1318,33 +1288,34 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
// Add the prototype if we have a prototype and we have a C like
// language.
uint16_t Language = getLanguage();
- if (SP.isPrototyped() &&
+ if (SP->isPrototyped() &&
(Language == dwarf::DW_LANG_C89 || Language == dwarf::DW_LANG_C99 ||
Language == dwarf::DW_LANG_ObjC))
addFlag(SPDie, dwarf::DW_AT_prototyped);
- DISubroutineType SPTy = SP.getType();
- assert(SPTy.getTag() == dwarf::DW_TAG_subroutine_type &&
+ DISubroutineType SPTy = SP->getType();
+ assert(SPTy->getTag() == dwarf::DW_TAG_subroutine_type &&
"the type of a subprogram should be a subroutine");
- DITypeArray Args = SPTy.getTypeArray();
+ auto Args = SPTy->getTypeArray();
// Add a return type. If this is a type like a C/C++ void type we don't add a
// return type.
- if (resolve(Args.getElement(0)))
- addType(SPDie, DIType(resolve(Args.getElement(0))));
+ if (Args.size())
+ if (auto Ty = resolve(Args[0]))
+ addType(SPDie, Ty);
- unsigned VK = SP.getVirtuality();
+ unsigned VK = SP->getVirtuality();
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_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()) {
+ if (!SP->isDefinition()) {
addFlag(SPDie, dwarf::DW_AT_declaration);
// Add arguments. Do not add arguments for subprogram definition. They will
@@ -1352,35 +1323,35 @@ void DwarfUnit::applySubprogramAttributes(DISubprogram SP, DIE &SPDie,
constructSubprogramArguments(SPDie, Args);
}
- if (SP.isArtificial())
+ if (SP->isArtificial())
addFlag(SPDie, dwarf::DW_AT_artificial);
- if (!SP.isLocalToUnit())
+ if (!SP->isLocalToUnit())
addFlag(SPDie, dwarf::DW_AT_external);
- if (SP.isOptimized())
+ if (SP->isOptimized())
addFlag(SPDie, dwarf::DW_AT_APPLE_optimized);
if (unsigned isa = Asm->getISAEncoding())
addUInt(SPDie, dwarf::DW_AT_APPLE_isa, dwarf::DW_FORM_flag, isa);
- if (SP.isLValueReference())
+ if (SP->isLValueReference())
addFlag(SPDie, dwarf::DW_AT_reference);
- if (SP.isRValueReference())
+ if (SP->isRValueReference())
addFlag(SPDie, dwarf::DW_AT_rvalue_reference);
- if (SP.isProtected())
+ if (SP->isProtected())
addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_protected);
- else if (SP.isPrivate())
+ else if (SP->isPrivate())
addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_private);
- else if (SP.isPublic())
+ else if (SP->isPublic())
addUInt(SPDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_public);
- if (SP.isExplicit())
+ if (SP->isExplicit())
addFlag(SPDie, dwarf::DW_AT_explicit);
}
@@ -1393,9 +1364,9 @@ void DwarfUnit::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy) {
// C/C++. The Count value is the number of elements. Values are 64 bit. If
// Count == -1 then the array is unbounded and we do not emit
// DW_AT_lower_bound and DW_AT_count attributes.
- int64_t LowerBound = SR.getLo();
+ int64_t LowerBound = SR->getLowerBound();
int64_t DefaultLowerBound = getDefaultLowerBound();
- int64_t Count = SR.getCount();
+ int64_t Count = SR->getCount();
if (DefaultLowerBound == -1 || LowerBound != DefaultLowerBound)
addUInt(DW_Subrange, dwarf::DW_AT_lower_bound, None, LowerBound);
@@ -1420,11 +1391,11 @@ DIE *DwarfUnit::getIndexTyDie() {
/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
- if (CTy.isVector())
+ if (CTy->isVector())
addFlag(Buffer, dwarf::DW_AT_GNU_vector);
// Emit the element type.
- addType(Buffer, resolve(CTy.getTypeDerivedFrom()));
+ addType(Buffer, resolve(CTy->getBaseType()));
// Get an anonymous type for index type.
// FIXME: This type should be passed down from the front end
@@ -1432,31 +1403,32 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, DICompositeType CTy) {
DIE *IdxTy = getIndexTyDie();
// Add subranges to array type.
- DIArray Elements = CTy.getElements();
- for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
- DIDescriptor Element = Elements.getElement(i);
- if (Element.getTag() == dwarf::DW_TAG_subrange_type)
- constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
+ DIArray Elements = CTy->getElements();
+ for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
+ // FIXME: Should this really be such a loose cast?
+ if (auto *Element = dyn_cast_or_null<DebugNode>(Elements[i]))
+ if (Element->getTag() == dwarf::DW_TAG_subrange_type)
+ constructSubrangeDIE(Buffer, cast<MDSubrange>(Element), IdxTy);
}
}
/// constructEnumTypeDIE - Construct an enum type DIE from DICompositeType.
void DwarfUnit::constructEnumTypeDIE(DIE &Buffer, DICompositeType CTy) {
- DIArray Elements = CTy.getElements();
+ DIArray Elements = CTy->getElements();
// Add enumerators to enumeration type.
- for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
- DIEnumerator Enum(Elements.getElement(i));
- if (Enum.isEnumerator()) {
+ for (unsigned i = 0, N = Elements.size(); i < N; ++i) {
+ auto *Enum = dyn_cast_or_null<MDEnumerator>(Elements[i]);
+ if (Enum) {
DIE &Enumerator = createAndAddDIE(dwarf::DW_TAG_enumerator, Buffer);
- StringRef Name = Enum.getName();
+ StringRef Name = Enum->getName();
addString(Enumerator, dwarf::DW_AT_name, Name);
- int64_t Value = Enum.getEnumValue();
+ int64_t Value = Enum->getValue();
addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata,
Value);
}
}
- DIType DTy = resolve(CTy.getTypeDerivedFrom());
+ DIType DTy = resolve(CTy->getBaseType());
if (DTy) {
addType(Buffer, DTy);
addFlag(Buffer, dwarf::DW_AT_enum_class);
@@ -1481,17 +1453,20 @@ void DwarfUnit::constructContainingTypeDIEs() {
}
/// constructMemberDIE - Construct member DIE from DIDerivedType.
-void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
- DIE &MemberDie = createAndAddDIE(DT.getTag(), Buffer);
- StringRef Name = DT.getName();
+void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT_) {
+ // Downcast to MDDerivedType.
+ const MDDerivedType *DT = cast<MDDerivedType>(DT_);
+
+ DIE &MemberDie = createAndAddDIE(DT->getTag(), Buffer);
+ StringRef Name = DT->getName();
if (!Name.empty())
addString(MemberDie, dwarf::DW_AT_name, Name);
- addType(MemberDie, resolve(DT.getTypeDerivedFrom()));
+ addType(MemberDie, resolve(DT->getBaseType()));
addSourceLine(MemberDie, DT);
- if (DT.getTag() == dwarf::DW_TAG_inheritance && DT.isVirtual()) {
+ if (DT->getTag() == dwarf::DW_TAG_inheritance && DT->isVirtual()) {
// For C++, virtual base classes are not at fixed offset. Use following
// expression to extract appropriate offset from vtable.
@@ -1501,14 +1476,14 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
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_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 {
- uint64_t Size = DT.getSizeInBits();
+ uint64_t Size = DT->getSizeInBits();
uint64_t FieldSize = getBaseTypeSize(DD, DT);
uint64_t OffsetInBytes;
@@ -1517,8 +1492,8 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
addUInt(MemberDie, dwarf::DW_AT_byte_size, None, FieldSize/8);
addUInt(MemberDie, dwarf::DW_AT_bit_size, None, Size);
- uint64_t Offset = DT.getOffsetInBits();
- uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
+ uint64_t Offset = DT->getOffsetInBits();
+ uint64_t AlignMask = ~(DT->getAlignInBits() - 1);
uint64_t HiMark = (Offset + FieldSize) & AlignMask;
uint64_t FieldOffset = (HiMark - FieldSize);
Offset -= FieldOffset;
@@ -1533,7 +1508,7 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
OffsetInBytes = FieldOffset >> 3;
} else
// This is not a bitfield.
- OffsetInBytes = DT.getOffsetInBits() >> 3;
+ OffsetInBytes = DT->getOffsetInBits() >> 3;
if (DD->getDwarfVersion() <= 2) {
DIELoc *MemLocationDie = new (DIEValueAllocator) DIELoc();
@@ -1545,49 +1520,50 @@ void DwarfUnit::constructMemberDIE(DIE &Buffer, DIDerivedType DT) {
OffsetInBytes);
}
- if (DT.isProtected())
+ if (DT->isProtected())
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_protected);
- else if (DT.isPrivate())
+ else if (DT->isPrivate())
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_private);
// Otherwise C++ member and base classes are considered public.
- else if (DT.isPublic())
+ else if (DT->isPublic())
addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_public);
- if (DT.isVirtual())
+ if (DT->isVirtual())
addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_data1,
dwarf::DW_VIRTUALITY_virtual);
// Objective-C properties.
- if (MDNode *PNode = DT.getObjCProperty())
+ if (MDNode *PNode = DT->getObjCProperty())
if (DIEEntry *PropertyDie = getDIEEntry(PNode))
MemberDie.addValue(dwarf::DW_AT_APPLE_property, dwarf::DW_FORM_ref4,
PropertyDie);
- if (DT.isArtificial())
+ if (DT->isArtificial())
addFlag(MemberDie, dwarf::DW_AT_artificial);
}
/// getOrCreateStaticMemberDIE - Create new DIE for C++ static member.
-DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) {
- if (!DT.Verify())
+DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT_) {
+ const MDDerivedType *DT = cast_or_null<MDDerivedType>(DT_);
+ if (!DT)
return nullptr;
// Construct the context before querying for the existence of the DIE in case
// such construction creates the DIE.
- DIE *ContextDIE = getOrCreateContextDIE(resolve(DT.getContext()));
+ DIE *ContextDIE = getOrCreateContextDIE(resolve(DT->getScope()));
assert(dwarf::isType(ContextDIE->getTag()) &&
"Static member should belong to a type.");
if (DIE *StaticMemberDIE = getDIE(DT))
return StaticMemberDIE;
- DIE &StaticMemberDIE = createAndAddDIE(DT.getTag(), *ContextDIE, DT);
+ DIE &StaticMemberDIE = createAndAddDIE(DT->getTag(), *ContextDIE, DT);
- DIType Ty = resolve(DT.getTypeDerivedFrom());
+ DIType Ty = resolve(DT->getBaseType());
- addString(StaticMemberDIE, dwarf::DW_AT_name, DT.getName());
+ addString(StaticMemberDIE, dwarf::DW_AT_name, DT->getName());
addType(StaticMemberDIE, Ty);
addSourceLine(StaticMemberDIE, DT);
addFlag(StaticMemberDIE, dwarf::DW_AT_external);
@@ -1595,19 +1571,19 @@ DIE *DwarfUnit::getOrCreateStaticMemberDIE(DIDerivedType DT) {
// FIXME: We could omit private if the parent is a class_type, and
// public if the parent is something else.
- if (DT.isProtected())
+ if (DT->isProtected())
addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_protected);
- else if (DT.isPrivate())
+ else if (DT->isPrivate())
addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_private);
- else if (DT.isPublic())
+ else if (DT->isPublic())
addUInt(StaticMemberDIE, dwarf::DW_AT_accessibility, dwarf::DW_FORM_data1,
dwarf::DW_ACCESS_public);
- if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT.getConstant()))
+ if (const ConstantInt *CI = dyn_cast_or_null<ConstantInt>(DT->getConstant()))
addConstantValue(StaticMemberDIE, CI, Ty);
- if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT.getConstant()))
+ if (const ConstantFP *CFP = dyn_cast_or_null<ConstantFP>(DT->getConstant()))
addConstantFPValue(StaticMemberDIE, CFP);
return &StaticMemberDIE;
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.h b/lib/CodeGen/AsmPrinter/DwarfUnit.h
index 81c5821..b354255 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -141,7 +141,7 @@ public:
// Accessors.
AsmPrinter* getAsmPrinter() const { return Asm; }
unsigned getUniqueID() const { return UniqueID; }
- uint16_t getLanguage() const { return CUNode.getLanguage(); }
+ uint16_t getLanguage() const { return CUNode->getSourceLanguage(); }
DICompileUnit getCUNode() const { return CUNode; }
DIE &getUnitDie() { return UnitDie; }
@@ -342,7 +342,7 @@ protected:
/// resolve - Look in the DwarfDebug map for the MDNode that
/// corresponds to the reference.
- template <typename T> T resolve(DIRef<T> Ref) const {
+ template <typename T> T *resolve(TypedDebugNodeRef<T> Ref) const {
return DD->resolve(Ref);
}
diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index 14df4c9..6f64d8f 100644
--- a/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -188,20 +188,12 @@ bool EHStreamer::callToNoUnwindFunction(const MachineInstr *MI) {
return MarkedNoUnwind;
}
-/// Compute the call-site table. The entry for an invoke has a try-range
-/// containing the call, a non-zero landing pad, and an appropriate action. The
-/// entry for an ordinary call has a try-range containing the call and zero for
-/// the landing pad and the action. Calls marked 'nounwind' have no entry and
-/// must not be contained in the try-range of any entry - they form gaps in the
-/// table. Entries must be ordered by try-range address.
-void EHStreamer::
-computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
- const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
- const SmallVectorImpl<unsigned> &FirstActions) {
+void EHStreamer::computePadMap(
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ RangeMapType &PadMap) {
// Invokes and nounwind calls have entries in PadMap (due to being bracketed
// by try-range labels when lowered). Ordinary calls do not, so appropriate
// try-ranges for them need be deduced so we can put them in the LSDA.
- RangeMapType PadMap;
for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) {
const LandingPadInfo *LandingPad = LandingPads[i];
for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) {
@@ -211,6 +203,20 @@ computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
PadMap[BeginLabel] = P;
}
}
+}
+
+/// Compute the call-site table. The entry for an invoke has a try-range
+/// containing the call, a non-zero landing pad, and an appropriate action. The
+/// entry for an ordinary call has a try-range containing the call and zero for
+/// the landing pad and the action. Calls marked 'nounwind' have no entry and
+/// must not be contained in the try-range of any entry - they form gaps in the
+/// table. Entries must be ordered by try-range address.
+void EHStreamer::
+computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
+ const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ const SmallVectorImpl<unsigned> &FirstActions) {
+ RangeMapType PadMap;
+ computePadMap(LandingPads, PadMap);
// The end label of the previous invoke or nounwind try-range.
MCSymbol *LastLabel = nullptr;
diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.h b/lib/CodeGen/AsmPrinter/EHStreamer.h
index 94d0585..65973fa 100644
--- a/lib/CodeGen/AsmPrinter/EHStreamer.h
+++ b/lib/CodeGen/AsmPrinter/EHStreamer.h
@@ -80,13 +80,15 @@ protected:
/// `false' otherwise.
bool callToNoUnwindFunction(const MachineInstr *MI);
+ void computePadMap(const SmallVectorImpl<const LandingPadInfo *> &LandingPads,
+ RangeMapType &PadMap);
+
/// Compute the call-site table. The entry for an invoke has a try-range
/// containing the call, a non-zero landing pad and an appropriate action.
/// The entry for an ordinary call has a try-range containing the call and
/// zero for the landing pad and the action. Calls marked 'nounwind' have
/// no entry and must not be contained in the try-range of any entry - they
/// form gaps in the table. Entries must be ordered by try-range address.
-
void computeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
const SmallVectorImpl<const LandingPadInfo *> &LPs,
const SmallVectorImpl<unsigned> &FirstActions);
@@ -123,7 +125,7 @@ protected:
public:
EHStreamer(AsmPrinter *A);
- virtual ~EHStreamer();
+ ~EHStreamer() override;
// Unused.
void setSymbolSize(const MCSymbol *Sym, uint64_t Size) override {}
diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.cpp b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
index 7d76ead..f89d364 100644
--- a/lib/CodeGen/AsmPrinter/Win64Exception.cpp
+++ b/lib/CodeGen/AsmPrinter/Win64Exception.cpp
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
@@ -67,6 +68,27 @@ void Win64Exception::beginFunction(const MachineFunction *MF) {
shouldEmitLSDA = shouldEmitPersonality &&
LSDAEncoding != dwarf::DW_EH_PE_omit;
+
+ // If this was an outlined handler, we need to define the label corresponding
+ // to the offset of the parent frame relative to the stack pointer after the
+ // prologue.
+ const Function *F = MF->getFunction();
+ const Function *ParentF = MMI->getWinEHParent(F);
+ if (F != ParentF) {
+ WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF);
+ auto I = FuncInfo.CatchHandlerParentFrameObjOffset.find(F);
+ if (I != FuncInfo.CatchHandlerParentFrameObjOffset.end()) {
+ MCSymbol *HandlerTypeParentFrameOffset =
+ Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
+ GlobalValue::getRealLinkageName(F->getName()));
+
+ // Emit a symbol assignment.
+ Asm->OutStreamer.EmitAssignment(
+ HandlerTypeParentFrameOffset,
+ MCConstantExpr::Create(I->second, Asm->OutContext));
+ }
+ }
+
if (!shouldEmitPersonality && !shouldEmitMoves)
return;
@@ -82,12 +104,17 @@ void Win64Exception::beginFunction(const MachineFunction *MF) {
/// endFunction - Gather and emit post-function exception information.
///
-void Win64Exception::endFunction(const MachineFunction *) {
+void Win64Exception::endFunction(const MachineFunction *MF) {
if (!shouldEmitPersonality && !shouldEmitMoves)
return;
- // Map all labels and get rid of any dead landing pads.
- MMI->TidyLandingPads();
+ EHPersonality Per = MMI->getPersonalityType();
+
+ // Get rid of any dead landing pads if we're not using a Windows EH scheme. In
+ // Windows EH schemes, the landing pad is not actually reachable. It only
+ // exists so that we can emit the right table data.
+ if (!isMSVCEHPersonality(Per))
+ MMI->TidyLandingPads();
if (shouldEmitPersonality) {
Asm->OutStreamer.PushSection();
@@ -97,9 +124,10 @@ void Win64Exception::endFunction(const MachineFunction *) {
// Emit the tables appropriate to the personality function in use. If we
// don't recognize the personality, assume it uses an Itanium-style LSDA.
- EHPersonality Per = MMI->getPersonalityType();
if (Per == EHPersonality::MSVC_Win64SEH)
emitCSpecificHandlerTable();
+ else if (Per == EHPersonality::MSVC_CXX)
+ emitCXXFrameHandler3Table(MF);
else
emitExceptionTable();
@@ -108,11 +136,19 @@ void Win64Exception::endFunction(const MachineFunction *) {
Asm->OutStreamer.EmitWinCFIEndProc();
}
-const MCSymbolRefExpr *Win64Exception::createImageRel32(const MCSymbol *Value) {
+const MCExpr *Win64Exception::createImageRel32(const MCSymbol *Value) {
+ if (!Value)
+ return MCConstantExpr::Create(0, Asm->OutContext);
return MCSymbolRefExpr::Create(Value, MCSymbolRefExpr::VK_COFF_IMGREL32,
Asm->OutContext);
}
+const MCExpr *Win64Exception::createImageRel32(const GlobalValue *GV) {
+ if (!GV)
+ return MCConstantExpr::Create(0, Asm->OutContext);
+ return createImageRel32(Asm->getSymbol(GV));
+}
+
/// Emit the language-specific data that __C_specific_handler expects. This
/// handler lives in the x64 Microsoft C runtime and allows catching or cleaning
/// up after faults with __try, __except, and __finally. The typeinfo values
@@ -237,3 +273,231 @@ void Win64Exception::emitCSpecificHandlerTable() {
}
}
}
+
+void Win64Exception::emitCXXFrameHandler3Table(const MachineFunction *MF) {
+ const Function *F = MF->getFunction();
+ const Function *ParentF = MMI->getWinEHParent(F);
+ auto &OS = Asm->OutStreamer;
+ WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(ParentF);
+
+ StringRef ParentLinkageName =
+ GlobalValue::getRealLinkageName(ParentF->getName());
+
+ MCSymbol *FuncInfoXData =
+ Asm->OutContext.GetOrCreateSymbol(Twine("$cppxdata$", ParentLinkageName));
+ OS.EmitValue(createImageRel32(FuncInfoXData), 4);
+
+ // The Itanium LSDA table sorts similar landing pads together to simplify the
+ // actions table, but we don't need that.
+ SmallVector<const LandingPadInfo *, 64> LandingPads;
+ const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads();
+ LandingPads.reserve(PadInfos.size());
+ for (const auto &LP : PadInfos)
+ LandingPads.push_back(&LP);
+
+ RangeMapType PadMap;
+ computePadMap(LandingPads, PadMap);
+
+ // The end label of the previous invoke or nounwind try-range.
+ MCSymbol *LastLabel = Asm->getFunctionBegin();
+
+ // Whether there is a potentially throwing instruction (currently this means
+ // an ordinary call) between the end of the previous try-range and now.
+ bool SawPotentiallyThrowing = false;
+
+ int LastEHState = -2;
+
+ // The parent function and the catch handlers contribute to the 'ip2state'
+ // table.
+ for (const auto &MBB : *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();
+ if (BeginLabel == LastLabel)
+ SawPotentiallyThrowing = false;
+
+ // Beginning of a new try-range?
+ RangeMapType::const_iterator L = PadMap.find(BeginLabel);
+ if (L == PadMap.end())
+ // Nope, it was just some random label.
+ continue;
+
+ const PadRange &P = L->second;
+ const LandingPadInfo *LandingPad = LandingPads[P.PadIndex];
+ assert(BeginLabel == LandingPad->BeginLabels[P.RangeIndex] &&
+ "Inconsistent landing pad map!");
+
+ if (SawPotentiallyThrowing) {
+ FuncInfo.IPToStateList.push_back(std::make_pair(LastLabel, -1));
+ SawPotentiallyThrowing = false;
+ LastEHState = -1;
+ }
+
+ if (LandingPad->WinEHState != LastEHState)
+ FuncInfo.IPToStateList.push_back(
+ std::make_pair(BeginLabel, LandingPad->WinEHState));
+ LastEHState = LandingPad->WinEHState;
+ LastLabel = LandingPad->EndLabels[P.RangeIndex];
+ }
+ }
+
+ // Defer emission until we've visited the parent function and all the catch
+ // handlers. Cleanups don't contribute to the ip2state table yet, so don't
+ // count them.
+ if (ParentF != F && !FuncInfo.CatchHandlerMaxState.count(F))
+ return;
+ ++FuncInfo.NumIPToStateFuncsVisited;
+ if (FuncInfo.NumIPToStateFuncsVisited != FuncInfo.CatchHandlerMaxState.size())
+ return;
+
+ MCSymbol *UnwindMapXData = nullptr;
+ MCSymbol *TryBlockMapXData = nullptr;
+ MCSymbol *IPToStateXData = nullptr;
+ if (!FuncInfo.UnwindMap.empty())
+ UnwindMapXData = Asm->OutContext.GetOrCreateSymbol(
+ Twine("$stateUnwindMap$", ParentLinkageName));
+ if (!FuncInfo.TryBlockMap.empty())
+ TryBlockMapXData = Asm->OutContext.GetOrCreateSymbol(
+ Twine("$tryMap$", ParentLinkageName));
+ if (!FuncInfo.IPToStateList.empty())
+ IPToStateXData = Asm->OutContext.GetOrCreateSymbol(
+ Twine("$ip2state$", ParentLinkageName));
+
+ // FuncInfo {
+ // uint32_t MagicNumber
+ // int32_t MaxState;
+ // UnwindMapEntry *UnwindMap;
+ // uint32_t NumTryBlocks;
+ // TryBlockMapEntry *TryBlockMap;
+ // uint32_t IPMapEntries;
+ // IPToStateMapEntry *IPToStateMap;
+ // uint32_t UnwindHelp; // (x64/ARM only)
+ // ESTypeList *ESTypeList;
+ // int32_t EHFlags;
+ // }
+ // EHFlags & 1 -> Synchronous exceptions only, no async exceptions.
+ // EHFlags & 2 -> ???
+ // EHFlags & 4 -> The function is noexcept(true), unwinding can't continue.
+ OS.EmitLabel(FuncInfoXData);
+ OS.EmitIntValue(0x19930522, 4); // MagicNumber
+ OS.EmitIntValue(FuncInfo.UnwindMap.size(), 4); // MaxState
+ OS.EmitValue(createImageRel32(UnwindMapXData), 4); // UnwindMap
+ OS.EmitIntValue(FuncInfo.TryBlockMap.size(), 4); // NumTryBlocks
+ OS.EmitValue(createImageRel32(TryBlockMapXData), 4); // TryBlockMap
+ OS.EmitIntValue(FuncInfo.IPToStateList.size(), 4); // IPMapEntries
+ OS.EmitValue(createImageRel32(IPToStateXData), 4); // IPToStateMap
+ OS.EmitIntValue(FuncInfo.UnwindHelpFrameOffset, 4); // UnwindHelp
+ OS.EmitIntValue(0, 4); // ESTypeList
+ OS.EmitIntValue(1, 4); // EHFlags
+
+ // UnwindMapEntry {
+ // int32_t ToState;
+ // void (*Action)();
+ // };
+ if (UnwindMapXData) {
+ OS.EmitLabel(UnwindMapXData);
+ for (const WinEHUnwindMapEntry &UME : FuncInfo.UnwindMap) {
+ OS.EmitIntValue(UME.ToState, 4); // ToState
+ OS.EmitValue(createImageRel32(UME.Cleanup), 4); // Action
+ }
+ }
+
+ // TryBlockMap {
+ // int32_t TryLow;
+ // int32_t TryHigh;
+ // int32_t CatchHigh;
+ // int32_t NumCatches;
+ // HandlerType *HandlerArray;
+ // };
+ if (TryBlockMapXData) {
+ OS.EmitLabel(TryBlockMapXData);
+ SmallVector<MCSymbol *, 1> HandlerMaps;
+ for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
+ WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
+ MCSymbol *HandlerMapXData = nullptr;
+
+ if (!TBME.HandlerArray.empty())
+ HandlerMapXData =
+ Asm->OutContext.GetOrCreateSymbol(Twine("$handlerMap$")
+ .concat(Twine(I))
+ .concat("$")
+ .concat(ParentLinkageName));
+
+ HandlerMaps.push_back(HandlerMapXData);
+
+ int CatchHigh = -1;
+ for (WinEHHandlerType &HT : TBME.HandlerArray)
+ CatchHigh =
+ std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[HT.Handler]);
+
+ assert(TBME.TryLow <= TBME.TryHigh);
+ assert(CatchHigh > TBME.TryHigh);
+ OS.EmitIntValue(TBME.TryLow, 4); // TryLow
+ OS.EmitIntValue(TBME.TryHigh, 4); // TryHigh
+ OS.EmitIntValue(CatchHigh, 4); // CatchHigh
+ OS.EmitIntValue(TBME.HandlerArray.size(), 4); // NumCatches
+ OS.EmitValue(createImageRel32(HandlerMapXData), 4); // HandlerArray
+ }
+
+ for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
+ WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
+ MCSymbol *HandlerMapXData = HandlerMaps[I];
+ if (!HandlerMapXData)
+ continue;
+ // HandlerType {
+ // int32_t Adjectives;
+ // TypeDescriptor *Type;
+ // int32_t CatchObjOffset;
+ // void (*Handler)();
+ // int32_t ParentFrameOffset; // x64 only
+ // };
+ OS.EmitLabel(HandlerMapXData);
+ for (const WinEHHandlerType &HT : TBME.HandlerArray) {
+ MCSymbol *ParentFrameOffset =
+ Asm->OutContext.getOrCreateParentFrameOffsetSymbol(
+ GlobalValue::getRealLinkageName(HT.Handler->getName()));
+ const MCSymbolRefExpr *ParentFrameOffsetRef = MCSymbolRefExpr::Create(
+ ParentFrameOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
+
+ // Get the frame escape label with the offset of the catch object. If
+ // the index is -1, then there is no catch object, and we should emit an
+ // offset of zero, indicating that no copy will occur.
+ const MCExpr *FrameAllocOffsetRef = nullptr;
+ if (HT.CatchObjRecoverIdx >= 0) {
+ MCSymbol *FrameAllocOffset =
+ Asm->OutContext.getOrCreateFrameAllocSymbol(
+ GlobalValue::getRealLinkageName(ParentF->getName()),
+ HT.CatchObjRecoverIdx);
+ FrameAllocOffsetRef = MCSymbolRefExpr::Create(
+ FrameAllocOffset, MCSymbolRefExpr::VK_None, Asm->OutContext);
+ } else {
+ FrameAllocOffsetRef = MCConstantExpr::Create(0, Asm->OutContext);
+ }
+
+ OS.EmitIntValue(HT.Adjectives, 4); // Adjectives
+ OS.EmitValue(createImageRel32(HT.TypeDescriptor), 4); // Type
+ OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset
+ OS.EmitValue(createImageRel32(HT.Handler), 4); // Handler
+ OS.EmitValue(ParentFrameOffsetRef, 4); // ParentFrameOffset
+ }
+ }
+ }
+
+ // IPToStateMapEntry {
+ // void *IP;
+ // int32_t State;
+ // };
+ if (IPToStateXData) {
+ OS.EmitLabel(IPToStateXData);
+ for (auto &IPStatePair : FuncInfo.IPToStateList) {
+ OS.EmitValue(createImageRel32(IPStatePair.first), 4); // IP
+ OS.EmitIntValue(IPStatePair.second, 4); // State
+ }
+ }
+}
diff --git a/lib/CodeGen/AsmPrinter/Win64Exception.h b/lib/CodeGen/AsmPrinter/Win64Exception.h
index b2d5d1b..5f4237f 100644
--- a/lib/CodeGen/AsmPrinter/Win64Exception.h
+++ b/lib/CodeGen/AsmPrinter/Win64Exception.h
@@ -17,7 +17,9 @@
#include "EHStreamer.h"
namespace llvm {
+class GlobalValue;
class MachineFunction;
+class MCExpr;
class Win64Exception : public EHStreamer {
/// Per-function flag to indicate if personality info should be emitted.
@@ -31,14 +33,17 @@ class Win64Exception : public EHStreamer {
void emitCSpecificHandlerTable();
- const MCSymbolRefExpr *createImageRel32(const MCSymbol *Value);
+ void emitCXXFrameHandler3Table(const MachineFunction *MF);
+
+ const MCExpr *createImageRel32(const MCSymbol *Value);
+ const MCExpr *createImageRel32(const GlobalValue *GV);
public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
Win64Exception(AsmPrinter *A);
- virtual ~Win64Exception();
+ ~Win64Exception() override;
/// Emit all exception information that should come after the content.
void endModule() override;
diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
index d2b4eec..276e7df 100644
--- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
+++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.cpp
@@ -20,14 +20,13 @@ namespace llvm {
StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) {
assert(S);
- DIDescriptor D(S);
- assert((D.isCompileUnit() || D.isFile() || D.isSubprogram() ||
- D.isLexicalBlockFile() || D.isLexicalBlock()) &&
+ assert((isa<MDCompileUnit>(S) || isa<MDFile>(S) || isa<MDSubprogram>(S) ||
+ isa<MDLexicalBlockBase>(S)) &&
"Unexpected scope info");
- DIScope Scope(S);
- StringRef Dir = Scope.getDirectory(),
- Filename = Scope.getFilename();
+ auto *Scope = cast<MDScope>(S);
+ StringRef Dir = Scope->getDirectory(),
+ Filename = Scope->getFilename();
char *&Result = DirAndFilenameToFilepathMap[std::make_pair(Dir, Filename)];
if (Result)
return Result;
@@ -40,7 +39,7 @@ StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) {
if (Filename.find(':') == 1)
Filepath = Filename;
else
- Filepath = (Dir + Twine("\\") + Filename).str();
+ Filepath = (Dir + "\\" + Filename).str();
// Canonicalize the path. We have to do it textually because we may no longer
// have access the file in the filesystem.
@@ -81,7 +80,7 @@ StringRef WinCodeViewLineTables::getFullFilepath(const MDNode *S) {
void WinCodeViewLineTables::maybeRecordLocation(DebugLoc DL,
const MachineFunction *MF) {
- const MDNode *Scope = DL.getScope(MF->getFunction()->getContext());
+ const MDNode *Scope = DL.getScope();
if (!Scope)
return;
StringRef Filename = getFullFilepath(Scope);
@@ -193,7 +192,7 @@ void WinCodeViewLineTables::emitDebugInfoForFunction(const Function *GV) {
StringRef GVName = GV->getName();
StringRef FuncName;
if (DISubprogram SP = getDISubprogram(GV))
- FuncName = SP.getDisplayName();
+ FuncName = SP->getDisplayName();
// FIXME Clang currently sets DisplayName to "bar" for a C++
// "namespace_foo::bar" function, see PR21528. Luckily, dbghelp.dll is trying
@@ -330,7 +329,7 @@ void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) {
DebugLoc PrologEndLoc;
bool EmptyPrologue = true;
for (const auto &MBB : *MF) {
- if (!PrologEndLoc.isUnknown())
+ if (PrologEndLoc)
break;
for (const auto &MI : MBB) {
if (MI.isDebugValue())
@@ -339,8 +338,7 @@ void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) {
// 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())) {
+ if (!MI.getFlag(MachineInstr::FrameSetup) && MI.getDebugLoc()) {
PrologEndLoc = MI.getDebugLoc();
break;
}
@@ -348,9 +346,8 @@ void WinCodeViewLineTables::beginFunction(const MachineFunction *MF) {
}
}
// Record beginning of function if we have a non-empty prologue.
- if (!PrologEndLoc.isUnknown() && !EmptyPrologue) {
- DebugLoc FnStartDL =
- PrologEndLoc.getFnDebugLoc(MF->getFunction()->getContext());
+ if (PrologEndLoc && !EmptyPrologue) {
+ DebugLoc FnStartDL = PrologEndLoc.getFnDebugLoc();
maybeRecordLocation(FnStartDL, MF);
}
}
@@ -377,7 +374,7 @@ void WinCodeViewLineTables::beginInstruction(const MachineInstr *MI) {
if (!Asm || MI->isDebugValue() || MI->getFlag(MachineInstr::FrameSetup))
return;
DebugLoc DL = MI->getDebugLoc();
- if (DL == PrevInstLoc || DL.isUnknown())
+ if (DL == PrevInstLoc || !DL)
return;
maybeRecordLocation(DL, Asm->MF);
}
diff --git a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
index 8492eac..c66d141 100644
--- a/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
+++ b/lib/CodeGen/AsmPrinter/WinCodeViewLineTables.h
@@ -114,7 +114,7 @@ class WinCodeViewLineTables : public AsmPrinterHandler {
public:
WinCodeViewLineTables(AsmPrinter *Asm);
- ~WinCodeViewLineTables() {
+ ~WinCodeViewLineTables() override {
for (DirAndFilenameToFilepathMapTy::iterator
I = DirAndFilenameToFilepathMap.begin(),
E = DirAndFilenameToFilepathMap.end();