aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/AsmPrinter
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r--lib/CodeGen/AsmPrinter/ARMException.cpp19
-rw-r--r--lib/CodeGen/AsmPrinter/AddressPool.cpp7
-rw-r--r--lib/CodeGen/AsmPrinter/AddressPool.h19
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp300
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp22
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp9
-rw-r--r--lib/CodeGen/AsmPrinter/CodeViewDebug.cpp539
-rw-r--r--lib/CodeGen/AsmPrinter/CodeViewDebug.h32
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp29
-rw-r--r--lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h20
-rw-r--r--lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp66
-rw-r--r--lib/CodeGen/AsmPrinter/DebugHandlerBase.h24
-rw-r--r--lib/CodeGen/AsmPrinter/DebugLocEntry.h2
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp52
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfAccelTable.h130
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCFIException.cpp21
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp132
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.h46
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp409
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h114
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfExpression.cpp25
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfExpression.h39
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfFile.cpp16
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfFile.h23
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfStringPool.cpp7
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfStringPool.h17
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfUnit.cpp17
-rw-r--r--lib/CodeGen/AsmPrinter/EHStreamer.cpp36
-rw-r--r--lib/CodeGen/AsmPrinter/EHStreamer.h21
-rw-r--r--lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp2
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/WinException.cpp61
33 files changed, 1365 insertions, 897 deletions
diff --git a/lib/CodeGen/AsmPrinter/ARMException.cpp b/lib/CodeGen/AsmPrinter/ARMException.cpp
index 8b1376ab363d..15cfbd5c40ff 100644
--- a/lib/CodeGen/AsmPrinter/ARMException.cpp
+++ b/lib/CodeGen/AsmPrinter/ARMException.cpp
@@ -12,26 +12,19 @@
//===----------------------------------------------------------------------===//
#include "DwarfException.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
-#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Target/TargetFrameLowering.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
ARMException::ARMException(AsmPrinter *A) : DwarfCFIExceptionBase(A) {}
@@ -67,16 +60,16 @@ void ARMException::beginFunction(const MachineFunction *MF) {
///
void ARMException::endFunction(const MachineFunction *MF) {
ARMTargetStreamer &ATS = getTargetStreamer();
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
const Function *Per = nullptr;
- if (F->hasPersonalityFn())
- Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ if (F.hasPersonalityFn())
+ Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
bool forceEmitPersonality =
- F->hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
- F->needsUnwindTableEntry();
+ F.hasPersonalityFn() && !isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
+ F.needsUnwindTableEntry();
bool shouldEmitPersonality = forceEmitPersonality ||
!MF->getLandingPads().empty();
- if (!Asm->MF->getFunction()->needsUnwindTableEntry() &&
+ if (!Asm->MF->getFunction().needsUnwindTableEntry() &&
!shouldEmitPersonality)
ATS.emitCantUnwind();
else if (shouldEmitPersonality) {
diff --git a/lib/CodeGen/AsmPrinter/AddressPool.cpp b/lib/CodeGen/AsmPrinter/AddressPool.cpp
index ec552e0640e9..59ed0324bdb0 100644
--- a/lib/CodeGen/AsmPrinter/AddressPool.cpp
+++ b/lib/CodeGen/AsmPrinter/AddressPool.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---*- C++ -*--===//
+//===- llvm/CodeGen/AddressPool.cpp - Dwarf Debug Framework ---------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,9 +8,12 @@
//===----------------------------------------------------------------------===//
#include "AddressPool.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include <utility>
using namespace llvm;
diff --git a/lib/CodeGen/AsmPrinter/AddressPool.h b/lib/CodeGen/AsmPrinter/AddressPool.h
index ba3e3b7c315d..990a158d87cd 100644
--- a/lib/CodeGen/AsmPrinter/AddressPool.h
+++ b/lib/CodeGen/AsmPrinter/AddressPool.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/AddressPool.h - Dwarf Debug Framework -----*- C++ -*--===//
+//===- llvm/CodeGen/AddressPool.h - Dwarf Debug Framework -------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,11 +11,13 @@
#define LLVM_LIB_CODEGEN_ASMPRINTER_ADDRESSPOOL_H
#include "llvm/ADT/DenseMap.h"
-#include "llvm/MC/MCSymbol.h"
namespace llvm {
-class MCSection;
+
class AsmPrinter;
+class MCSection;
+class MCSymbol;
+
// Collection of addresses for this unit and assorted labels.
// A Symbol->unsigned mapping of addresses used by indirect
// references.
@@ -23,6 +25,7 @@ class AddressPool {
struct AddressPoolEntry {
unsigned Number;
bool TLS;
+
AddressPoolEntry(unsigned Number, bool TLS) : Number(Number), TLS(TLS) {}
};
DenseMap<const MCSymbol *, AddressPoolEntry> Pool;
@@ -31,10 +34,10 @@ class AddressPool {
/// the last "resetUsedFlag" call. Used to implement type unit fallback - a
/// type that references addresses cannot be placed in a type unit when using
/// fission.
- bool HasBeenUsed;
+ bool HasBeenUsed = false;
public:
- AddressPool() : HasBeenUsed(false) {}
+ AddressPool() = default;
/// \brief Returns the index into the address pool with the given
/// label/symbol.
@@ -48,5 +51,7 @@ public:
void resetUsedFlag() { HasBeenUsed = false; }
};
-}
-#endif
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_ADDRESSPOOL_H
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index ff427c9a0d75..31037095aa2b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -1,4 +1,4 @@
-//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
+//===- AsmPrinter.cpp - Common AsmPrinter code ----------------------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -29,10 +29,11 @@
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/ObjectUtils.h"
+#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/BinaryFormat/ELF.h"
-#include "llvm/CodeGen/Analysis.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/GCStrategy.h"
@@ -46,10 +47,19 @@
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineMemOperand.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetOpcodes.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/BasicBlock.h"
+#include "llvm/IR/Comdat.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
@@ -62,14 +72,18 @@
#include "llvm/IR/GlobalObject.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instruction.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
+#include "llvm/IR/Type.h"
#include "llvm/IR/Value.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCCodePadder.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
+#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSection.h"
@@ -78,29 +92,28 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCSymbolELF.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/MCValue.h"
#include "llvm/MC/SectionKind.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetInstrInfo.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetOptions.h"
#include <algorithm>
#include <cassert>
#include <cinttypes>
#include <cstdint>
+#include <iterator>
#include <limits>
#include <memory>
#include <string>
@@ -129,7 +142,8 @@ static cl::opt<bool>
char AsmPrinter::ID = 0;
-typedef DenseMap<GCStrategy*, std::unique_ptr<GCMetadataPrinter>> gcp_map_type;
+using gcp_map_type = DenseMap<GCStrategy *, std::unique_ptr<GCMetadataPrinter>>;
+
static gcp_map_type &getGCMap(void *&P) {
if (!P)
P = new gcp_map_type();
@@ -184,7 +198,6 @@ bool AsmPrinter::isPositionIndependent() const {
}
/// getFunctionNumber - Return a unique ID for the current function.
-///
unsigned AsmPrinter::getFunctionNumber() const {
return MF->getFunctionNumber();
}
@@ -221,8 +234,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<MachineModuleInfo>();
AU.addRequired<MachineOptimizationRemarkEmitterPass>();
AU.addRequired<GCModuleInfo>();
- if (isVerbose())
- AU.addRequired<MachineLoopInfo>();
+ AU.addRequired<MachineLoopInfo>();
}
bool AsmPrinter::doInitialization(Module &M) {
@@ -242,28 +254,8 @@ bool AsmPrinter::doInitialization(Module &M) {
// alternative is duplicated code in each of the target asm printers that
// use the directive, where it would need the same conditionalization
// anyway.
- const Triple &TT = TM.getTargetTriple();
- // If there is a version specified, Major will be non-zero.
- if (TT.isOSDarwin() && TT.getOSMajorVersion() != 0) {
- unsigned Major, Minor, Update;
- MCVersionMinType VersionType;
- if (TT.isWatchOS()) {
- VersionType = MCVM_WatchOSVersionMin;
- TT.getWatchOSVersion(Major, Minor, Update);
- } else if (TT.isTvOS()) {
- VersionType = MCVM_TvOSVersionMin;
- TT.getiOSVersion(Major, Minor, Update);
- } else if (TT.isMacOSX()) {
- VersionType = MCVM_OSXVersionMin;
- if (!TT.getMacOSXVersion(Major, Minor, Update))
- Major = 0;
- } else {
- VersionType = MCVM_IOSVersionMin;
- TT.getiOSVersion(Major, Minor, Update);
- }
- if (Major != 0)
- OutStreamer->EmitVersionMin(VersionType, Major, Minor, Update);
- }
+ const Triple &Target = TM.getTargetTriple();
+ OutStreamer->EmitVersionForTarget(Target);
// Allow the target to emit any magic that it wants at the start of the file.
EmitStartOfAsmFile(M);
@@ -272,7 +264,8 @@ bool AsmPrinter::doInitialization(Module &M) {
// don't, this at least helps the user find where a global came from.
if (MAI->hasSingleParameterDotFile()) {
// .file "foo.c"
- OutStreamer->EmitFileDirective(M.getSourceFileName());
+ OutStreamer->EmitFileDirective(
+ llvm::sys::path::filename(M.getSourceFileName()));
}
GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
@@ -628,35 +621,35 @@ void AsmPrinter::EmitDebugThreadLocal(const MCExpr *Value,
/// EmitFunctionHeader - This method emits the header for the current
/// function.
void AsmPrinter::EmitFunctionHeader() {
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
if (isVerbose())
OutStreamer->GetCommentOS()
<< "-- Begin function "
- << GlobalValue::dropLLVMManglingEscape(F->getName()) << '\n';
+ << GlobalValue::dropLLVMManglingEscape(F.getName()) << '\n';
// Print out constants referenced by the function
EmitConstantPool();
// Print the 'header' of function.
- OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(F, TM));
- EmitVisibility(CurrentFnSym, F->getVisibility());
+ OutStreamer->SwitchSection(getObjFileLowering().SectionForGlobal(&F, TM));
+ EmitVisibility(CurrentFnSym, F.getVisibility());
- EmitLinkage(F, CurrentFnSym);
+ EmitLinkage(&F, CurrentFnSym);
if (MAI->hasFunctionAlignment())
- EmitAlignment(MF->getAlignment(), F);
+ EmitAlignment(MF->getAlignment(), &F);
if (MAI->hasDotTypeDotSizeDirective())
OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
if (isVerbose()) {
- F->printAsOperand(OutStreamer->GetCommentOS(),
- /*PrintType=*/false, F->getParent());
+ F.printAsOperand(OutStreamer->GetCommentOS(),
+ /*PrintType=*/false, F.getParent());
OutStreamer->GetCommentOS() << '\n';
}
// Emit the prefix data.
- if (F->hasPrefixData()) {
+ if (F.hasPrefixData()) {
if (MAI->hasSubsectionsViaSymbols()) {
// Preserving prefix data on platforms which use subsections-via-symbols
// is a bit tricky. Here we introduce a symbol for the prefix data
@@ -665,12 +658,12 @@ void AsmPrinter::EmitFunctionHeader() {
MCSymbol *PrefixSym = OutContext.createLinkerPrivateTempSymbol();
OutStreamer->EmitLabel(PrefixSym);
- EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData());
+ EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
// Emit an .alt_entry directive for the actual function symbol.
OutStreamer->EmitSymbolAttribute(CurrentFnSym, MCSA_AltEntry);
} else {
- EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrefixData());
+ EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrefixData());
}
}
@@ -682,7 +675,7 @@ void AsmPrinter::EmitFunctionHeader() {
// references to the dangling symbols. Emit them at the start of the function
// so that we don't get references to undefined symbols.
std::vector<MCSymbol*> DeadBlockSyms;
- MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms);
+ MMI->takeDeletedSymbolsForFunction(&F, DeadBlockSyms);
for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) {
OutStreamer->AddComment("Address taken block that was later removed");
OutStreamer->EmitLabel(DeadBlockSyms[i]);
@@ -707,8 +700,8 @@ void AsmPrinter::EmitFunctionHeader() {
}
// Emit the prologue data.
- if (F->hasPrologueData())
- EmitGlobalConstant(F->getParent()->getDataLayout(), F->getPrologueData());
+ if (F.hasPrologueData())
+ EmitGlobalConstant(F.getParent()->getDataLayout(), F.getPrologueData());
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
@@ -729,9 +722,11 @@ void AsmPrinter::EmitFunctionEntryLabel() {
}
/// emitComments - Pretty-print comments for instructions.
-static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS,
+/// It returns true iff the sched comment was emitted.
+/// Otherwise it returns false.
+static bool emitComments(const MachineInstr &MI, raw_ostream &CommentOS,
AsmPrinter *AP) {
- const MachineFunction *MF = MI.getParent()->getParent();
+ const MachineFunction *MF = MI.getMF();
const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
// Check for spills and reloads
@@ -773,12 +768,16 @@ static void emitComments(const MachineInstr &MI, raw_ostream &CommentOS,
CommentOS << " Reload Reuse";
}
- if (Commented && AP->EnablePrintSchedInfo)
- // If any comment was added above and we need sched info comment then
- // add this new comment just after the above comment w/o "\n" between them.
- CommentOS << " " << MF->getSubtarget().getSchedInfoStr(MI) << "\n";
- else if (Commented)
+ if (Commented) {
+ if (AP->EnablePrintSchedInfo) {
+ // If any comment was added above and we need sched info comment then add
+ // this new comment just after the above comment w/o "\n" between them.
+ CommentOS << " " << MF->getSubtarget().getSchedInfoStr(MI) << "\n";
+ return true;
+ }
CommentOS << "\n";
+ }
+ return false;
}
/// emitImplicitDef - This method emits the specified machine instruction
@@ -789,7 +788,7 @@ void AsmPrinter::emitImplicitDef(const MachineInstr *MI) const {
SmallString<128> Str;
raw_svector_ostream OS(Str);
OS << "implicit-def: "
- << PrintReg(RegNo, MF->getSubtarget().getRegisterInfo());
+ << printReg(RegNo, MF->getSubtarget().getRegisterInfo());
OutStreamer->AddComment(OS.str());
OutStreamer->AddBlankLine();
@@ -802,10 +801,8 @@ static void emitKill(const MachineInstr *MI, AsmPrinter &AP) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
const MachineOperand &Op = MI->getOperand(i);
assert(Op.isReg() && "KILL instruction must have only register operands");
- OS << ' '
- << PrintReg(Op.getReg(),
- AP.MF->getSubtarget().getRegisterInfo())
- << (Op.isDef() ? "<def>" : "<kill>");
+ OS << ' ' << (Op.isDef() ? "def " : "killed ")
+ << printReg(Op.getReg(), AP.MF->getSubtarget().getRegisterInfo());
}
AP.OutStreamer->AddComment(OS.str());
AP.OutStreamer->AddBlankLine();
@@ -890,7 +887,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
}
if (MemLoc)
OS << '[';
- OS << PrintReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
+ OS << printReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
}
if (MemLoc)
@@ -901,9 +898,9 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
return true;
}
-AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
+AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() const {
if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&
- MF->getFunction()->needsUnwindTableEntry())
+ MF->getFunction().needsUnwindTableEntry())
return CFI_M_EH;
if (MMI->hasDebugInfo())
@@ -913,7 +910,7 @@ AsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
}
bool AsmPrinter::needsSEHMoves() {
- return MAI->usesWindowsCFI() && MF->getFunction()->needsUnwindTableEntry();
+ return MAI->usesWindowsCFI() && MF->getFunction().needsUnwindTableEntry();
}
void AsmPrinter::emitCFIInstruction(const MachineInstr &MI) {
@@ -951,6 +948,31 @@ void AsmPrinter::emitFrameAlloc(const MachineInstr &MI) {
MCConstantExpr::create(FrameOffset, OutContext));
}
+void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
+ if (!MF.getTarget().Options.EmitStackSizeSection)
+ return;
+
+ MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection();
+ if (!StackSizeSection)
+ return;
+
+ const MachineFrameInfo &FrameInfo = MF.getFrameInfo();
+ // Don't emit functions with dynamic stack allocations.
+ if (FrameInfo.hasVarSizedObjects())
+ return;
+
+ OutStreamer->PushSection();
+ OutStreamer->SwitchSection(StackSizeSection);
+
+ const MCSymbol *FunctionSymbol = getSymbol(&MF.getFunction());
+ uint64_t StackSize = FrameInfo.getStackSize();
+ OutStreamer->EmitValue(MCSymbolRefExpr::create(FunctionSymbol, OutContext),
+ /* size = */ 8);
+ OutStreamer->EmitULEB128IntValue(StackSize);
+
+ OutStreamer->PopSection();
+}
+
static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
MachineModuleInfo *MMI) {
if (!MF.getLandingPads().empty() || MF.hasEHFunclets() || MMI->hasDebugInfo())
@@ -958,10 +980,10 @@ static bool needFuncLabelsForEHOrDebugInfo(const MachineFunction &MF,
// We might emit an EH table that uses function begin and end labels even if
// we don't have any landingpads.
- if (!MF.getFunction()->hasPersonalityFn())
+ if (!MF.getFunction().hasPersonalityFn())
return false;
return !isNoOpWithoutInvoke(
- classifyEHPersonality(MF.getFunction()->getPersonalityFn()));
+ classifyEHPersonality(MF.getFunction().getPersonalityFn()));
}
/// EmitFunctionBody - This method emits the body and trailer for a
@@ -981,7 +1003,6 @@ void AsmPrinter::EmitFunctionBody() {
// Print a label for the basic block.
EmitBasicBlockStart(MBB);
for (auto &MI : MBB) {
-
// Print the assembly for the instruction.
if (!MI.isPosition() && !MI.isImplicitDef() && !MI.isKill() &&
!MI.isDebugValue()) {
@@ -998,18 +1019,18 @@ void AsmPrinter::EmitFunctionBody() {
}
}
- if (isVerbose())
- emitComments(MI, OutStreamer->GetCommentOS(), this);
+ if (isVerbose() && emitComments(MI, OutStreamer->GetCommentOS(), this)) {
+ MachineInstr *MIP = const_cast<MachineInstr *>(&MI);
+ MIP->setAsmPrinterFlag(MachineInstr::NoSchedComment);
+ }
switch (MI.getOpcode()) {
case TargetOpcode::CFI_INSTRUCTION:
emitCFIInstruction(MI);
break;
-
case TargetOpcode::LOCAL_ESCAPE:
emitFrameAlloc(MI);
break;
-
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
OutStreamer->EmitLabel(MI.getOperand(0).getMCSymbol());
@@ -1049,7 +1070,7 @@ void AsmPrinter::EmitFunctionBody() {
EmittedInsts += NumInstsInFunction;
MachineOptimizationRemarkAnalysis R(DEBUG_TYPE, "InstructionCount",
- MF->getFunction()->getSubprogram(),
+ MF->getFunction().getSubprogram(),
&MF->front());
R << ore::NV("NumInstructions", NumInstsInFunction)
<< " instructions in function";
@@ -1077,8 +1098,8 @@ void AsmPrinter::EmitFunctionBody() {
}
}
- const Function *F = MF->getFunction();
- for (const auto &BB : *F) {
+ const Function &F = MF->getFunction();
+ for (const auto &BB : F) {
if (!BB.hasAddressTaken())
continue;
MCSymbol *Sym = GetBlockAddressSymbol(&BB);
@@ -1125,6 +1146,9 @@ void AsmPrinter::EmitFunctionBody() {
HI.Handler->endFunction(MF);
}
+ // Emit section containing stack size metadata.
+ emitStackSizeSection(*MF);
+
if (isVerbose())
OutStreamer->GetCommentOS() << "-- End function\n";
@@ -1380,6 +1404,16 @@ bool AsmPrinter::doFinalization(Module &M) {
PtrSize);
}
+ // Emit .note.GNU-split-stack and .note.GNU-no-split-stack sections if
+ // split-stack is used.
+ if (TM.getTargetTriple().isOSBinFormatELF() && MMI->hasSplitStack()) {
+ OutStreamer->SwitchSection(
+ OutContext.getELFSection(".note.GNU-split-stack", ELF::SHT_PROGBITS, 0));
+ if (MMI->hasNosplitStack())
+ OutStreamer->SwitchSection(
+ OutContext.getELFSection(".note.GNU-no-split-stack", ELF::SHT_PROGBITS, 0));
+ }
+
// If we don't have any trampolines, then we don't require stack memory
// to be executable. Some targets have a directive to declare this.
Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
@@ -1408,7 +1442,7 @@ MCSymbol *AsmPrinter::getCurExceptionSym() {
void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
this->MF = &MF;
// Get the function symbol.
- CurrentFnSym = getSymbol(MF.getFunction());
+ CurrentFnSym = getSymbol(&MF.getFunction());
CurrentFnSymForSize = CurrentFnSym;
CurrentFnBegin = nullptr;
CurExceptionSym = nullptr;
@@ -1420,8 +1454,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
}
ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
- if (isVerbose())
- LI = &getAnalysis<MachineLoopInfo>();
+ LI = &getAnalysis<MachineLoopInfo>();
const TargetSubtargetInfo &STI = MF.getSubtarget();
EnablePrintSchedInfo = PrintSchedule.getNumOccurrences()
@@ -1446,7 +1479,6 @@ namespace {
/// representations of the constants in the constant pool MCP. This is
/// used to print out constants which have been "spilled to memory" by
/// the code generator.
-///
void AsmPrinter::EmitConstantPool() {
const MachineConstantPool *MCP = MF->getConstantPool();
const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
@@ -1526,7 +1558,6 @@ void AsmPrinter::EmitConstantPool() {
/// EmitJumpTableInfo - Print assembly representations of the jump tables used
/// by the current function to the current output stream.
-///
void AsmPrinter::EmitJumpTableInfo() {
const DataLayout &DL = MF->getDataLayout();
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
@@ -1537,14 +1568,14 @@ void AsmPrinter::EmitJumpTableInfo() {
// Pick the directive to use to print the jump table entries, and switch to
// the appropriate section.
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
const TargetLoweringObjectFile &TLOF = getObjFileLowering();
bool JTInDiffSection = !TLOF.shouldPutJumpTableInFunctionSection(
MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32,
- *F);
+ F);
if (JTInDiffSection) {
// Drop it in the readonly section.
- MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(*F, TM);
+ MCSection *ReadOnlySection = TLOF.getSectionForJumpTable(F, TM);
OutStreamer->SwitchSection(ReadOnlySection);
}
@@ -1723,7 +1754,7 @@ struct Structor {
Structor() = default;
};
-} // end anonymous namespace
+} // end anonymous namespace
/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
/// priority.
@@ -1818,13 +1849,11 @@ void AsmPrinter::EmitInt8(int Value) const {
}
/// EmitInt16 - Emit a short directive and value.
-///
void AsmPrinter::EmitInt16(int Value) const {
OutStreamer->EmitIntValue(Value, 2);
}
/// EmitInt32 - Emit a long directive and value.
-///
void AsmPrinter::EmitInt32(int Value) const {
OutStreamer->EmitIntValue(Value, 4);
}
@@ -1866,7 +1895,6 @@ void AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
// byte alignment. If a global value is specified, and if that global has
// an explicit alignment requested, it will override the alignment request
// if required for correctness.
-//
void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalObject *GV) const {
if (GV)
NumBits = getGVAlignmentLog2(GV, GV->getParent()->getDataLayout(), NumBits);
@@ -1921,7 +1949,7 @@ const MCExpr *AsmPrinter::lowerConstant(const Constant *CV) {
raw_string_ostream OS(S);
OS << "Unsupported expression in static initializer: ";
CE->printAsOperand(OS, /*PrintType=*/false,
- !MF ? nullptr : MF->getFunction()->getParent());
+ !MF ? nullptr : MF->getFunction().getParent());
report_fatal_error(OS.str());
}
case Instruction::GetElementPtr: {
@@ -2317,7 +2345,6 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
//
// cstexpr := <gotequiv> - <foo> + gotpcrelcst, where
// gotpcrelcst := <offset from @foo base> + <cst>
- //
MCValue MV;
if (!(*ME)->evaluateAsRelocatable(MV, nullptr, nullptr) || MV.isAbsolute())
return;
@@ -2348,7 +2375,6 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
// If gotpcrelcst is positive it means that we can safely fold the pc rel
// displacement into the GOTPCREL. We can also can have an extra offset <cst>
// if the target knows how to encode it.
- //
int64_t GOTPCRelCst = Offset + MV.getConstant();
if (GOTPCRelCst < 0)
return;
@@ -2370,7 +2396,6 @@ static void handleIndirectSymViaGOTPCRel(AsmPrinter &AP, const MCExpr **ME,
// .long 42
// foo:
// .long bar@GOTPCREL+<gotpcrelcst>
- //
AsmPrinter::GOTEquivUsePair Result = AP.GlobalGOTEquivs[GOTEquivSym];
const GlobalVariable *GV = Result.first;
int NumUses = (int)Result.second;
@@ -2550,7 +2575,6 @@ static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,
<< " Depth=" << Loop->getLoopDepth() << '\n';
}
-
/// PrintChildLoopComment - Print comments about child loops within
/// the loop for this basic block, with nesting.
static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
@@ -2603,6 +2627,23 @@ static void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
}
+void AsmPrinter::setupCodePaddingContext(const MachineBasicBlock &MBB,
+ MCCodePaddingContext &Context) const {
+ assert(MF != nullptr && "Machine function must be valid");
+ assert(LI != nullptr && "Loop info must be valid");
+ Context.IsPaddingActive = !MF->hasInlineAsm() &&
+ !MF->getFunction().optForSize() &&
+ TM.getOptLevel() != CodeGenOpt::None;
+ const MachineLoop *CurrentLoop = LI->getLoopFor(&MBB);
+ Context.IsBasicBlockInsideInnermostLoop =
+ CurrentLoop != nullptr && CurrentLoop->getSubLoops().empty();
+ Context.IsBasicBlockReachableViaFallthrough =
+ std::find(MBB.pred_begin(), MBB.pred_end(), MBB.getPrevNode()) !=
+ MBB.pred_end();
+ Context.IsBasicBlockReachableViaBranch =
+ MBB.pred_size() > 0 && !isBlockOnlyReachableByFallthrough(&MBB);
+}
+
/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing
/// it if appropriate.
@@ -2618,6 +2659,9 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
// Emit an alignment directive for this block, if needed.
if (unsigned Align = MBB.getAlignment())
EmitAlignment(Align);
+ MCCodePaddingContext Context;
+ setupCodePaddingContext(MBB, Context);
+ OutStreamer->EmitCodePaddingBasicBlockStart(Context);
// If the block has its address taken, emit any labels that were used to
// reference the block. It is possible that there is more than one label
@@ -2652,13 +2696,20 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) const {
(isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry())) {
if (isVerbose()) {
// NOTE: Want this comment at start of line, don't emit with AddComment.
- OutStreamer->emitRawComment(" BB#" + Twine(MBB.getNumber()) + ":", false);
+ OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
+ false);
}
} else {
OutStreamer->EmitLabel(MBB.getSymbol());
}
}
+void AsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) {
+ MCCodePaddingContext Context;
+ setupCodePaddingContext(MBB, Context);
+ OutStreamer->EmitCodePaddingBasicBlockEnd(Context);
+}
+
void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
bool IsDefinition) const {
MCSymbolAttr Attr = MCSA_Invalid;
@@ -2765,10 +2816,13 @@ void AsmPrinter::XRayFunctionEntry::emit(int Bytes, MCStreamer *Out,
Out->EmitSymbolValue(Sled, Bytes);
Out->EmitSymbolValue(CurrentFnSym, Bytes);
auto Kind8 = static_cast<uint8_t>(Kind);
- Out->EmitBytes(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
- Out->EmitBytes(
+ Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Kind8), 1));
+ Out->EmitBinaryData(
StringRef(reinterpret_cast<const char *>(&AlwaysInstrument), 1));
- Out->EmitZeros(2 * Bytes - 2); // Pad the previous two entries
+ Out->EmitBinaryData(StringRef(reinterpret_cast<const char *>(&Version), 1));
+ auto Padding = (4 * Bytes) - ((2 * Bytes) + 3);
+ assert(Padding >= 0 && "Instrumentation map entry > 4 * Word Size");
+ Out->EmitZeros(Padding);
}
void AsmPrinter::emitXRayTable() {
@@ -2776,23 +2830,26 @@ void AsmPrinter::emitXRayTable() {
return;
auto PrevSection = OutStreamer->getCurrentSectionOnly();
- auto Fn = MF->getFunction();
+ const Function &F = MF->getFunction();
MCSection *InstMap = nullptr;
MCSection *FnSledIndex = nullptr;
if (MF->getSubtarget().getTargetTriple().isOSBinFormatELF()) {
- if (Fn->hasComdat()) {
- InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC | ELF::SHF_GROUP, 0,
- Fn->getComdat()->getName());
- FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC | ELF::SHF_GROUP, 0,
- Fn->getComdat()->getName());
- } else {
- InstMap = OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC);
- FnSledIndex = OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS,
- ELF::SHF_ALLOC);
+ auto Associated = dyn_cast<MCSymbolELF>(CurrentFnSym);
+ assert(Associated != nullptr);
+ auto Flags = ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_LINK_ORDER;
+ std::string GroupName;
+ if (F.hasComdat()) {
+ Flags |= ELF::SHF_GROUP;
+ GroupName = F.getComdat()->getName();
}
+
+ auto UniqueID = ++XRayFnUniqueID;
+ InstMap =
+ OutContext.getELFSection("xray_instr_map", ELF::SHT_PROGBITS, Flags, 0,
+ GroupName, UniqueID, Associated);
+ FnSledIndex =
+ OutContext.getELFSection("xray_fn_idx", ELF::SHT_PROGBITS, Flags, 0,
+ GroupName, UniqueID, Associated);
} else if (MF->getSubtarget().getTargetTriple().isOSBinFormatMachO()) {
InstMap = OutContext.getMachOSection("__DATA", "xray_instr_map", 0,
SectionKind::getReadOnlyWithRel());
@@ -2802,15 +2859,7 @@ void AsmPrinter::emitXRayTable() {
llvm_unreachable("Unsupported target");
}
- // Before we switch over, we force a reference to a label inside the
- // xray_fn_idx sections. This makes sure that the xray_fn_idx section is kept
- // live by the linker if the function is not garbage-collected. Since this
- // function is always called just before the function's end, we assume that
- // this is happening after the last return instruction.
auto WordSizeBytes = MAI->getCodePointerSize();
- MCSymbol *IdxRef = OutContext.createTempSymbol("xray_fn_idx_synth_", true);
- OutStreamer->EmitCodeAlignment(16);
- OutStreamer->EmitSymbolValue(IdxRef, WordSizeBytes, false);
// Now we switch to the instrumentation map section. Because this is done
// per-function, we are able to create an index entry that will represent the
@@ -2829,24 +2878,23 @@ void AsmPrinter::emitXRayTable() {
// pointers. This should work for both 32-bit and 64-bit platforms.
OutStreamer->SwitchSection(FnSledIndex);
OutStreamer->EmitCodeAlignment(2 * WordSizeBytes);
- OutStreamer->EmitLabel(IdxRef);
- OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes);
- OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes);
+ OutStreamer->EmitSymbolValue(SledsStart, WordSizeBytes, false);
+ OutStreamer->EmitSymbolValue(SledsEnd, WordSizeBytes, false);
OutStreamer->SwitchSection(PrevSection);
Sleds.clear();
}
void AsmPrinter::recordSled(MCSymbol *Sled, const MachineInstr &MI,
- SledKind Kind) {
- auto Fn = MI.getParent()->getParent()->getFunction();
- auto Attr = Fn->getFnAttribute("function-instrument");
- bool LogArgs = Fn->hasFnAttribute("xray-log-args");
+ SledKind Kind, uint8_t Version) {
+ const Function &F = MI.getMF()->getFunction();
+ auto Attr = F.getFnAttribute("function-instrument");
+ bool LogArgs = F.hasFnAttribute("xray-log-args");
bool AlwaysInstrument =
Attr.isStringAttribute() && Attr.getValueAsString() == "xray-always";
if (Kind == SledKind::FUNCTION_ENTER && LogArgs)
Kind = SledKind::LOG_ARGS_ENTER;
- Sleds.emplace_back(
- XRayFunctionEntry{ Sled, CurrentFnSym, Kind, AlwaysInstrument, Fn });
+ Sleds.emplace_back(XRayFunctionEntry{Sled, CurrentFnSym, Kind,
+ AlwaysInstrument, &F, Version});
}
uint16_t AsmPrinter::getDwarfVersion() const {
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
index 0edf9051d342..08eb14e242c5 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -12,14 +12,12 @@
//===----------------------------------------------------------------------===//
#include "ByteStreamer.h"
-#include "DwarfDebug.h"
-#include "DwarfExpression.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
@@ -28,9 +26,7 @@
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
@@ -48,12 +44,19 @@ void AsmPrinter::EmitSLEB128(int64_t Value, const char *Desc) const {
}
/// EmitULEB128 - emit the specified unsigned leb128 value.
-void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc,
- unsigned PadTo) const {
+void AsmPrinter::EmitPaddedULEB128(uint64_t Value, unsigned PadTo,
+ const char *Desc) const {
if (isVerbose() && Desc)
OutStreamer->AddComment(Desc);
- OutStreamer->EmitULEB128IntValue(Value, PadTo);
+ OutStreamer->EmitPaddedULEB128IntValue(Value, PadTo);
+}
+
+void AsmPrinter::EmitULEB128(uint64_t Value, const char *Desc) const {
+ if (isVerbose() && Desc)
+ OutStreamer->AddComment(Desc);
+
+ OutStreamer->EmitULEB128IntValue(Value);
}
static const char *DecodeDWARFEncoding(unsigned Encoding) {
@@ -212,6 +215,9 @@ void AsmPrinter::emitCFIInstruction(const MCCFIInstruction &Inst) const {
case MCCFIInstruction::OpEscape:
OutStreamer->EmitCFIEscape(Inst.getValues());
break;
+ case MCCFIInstruction::OpRestore:
+ OutStreamer->EmitCFIRestore(Inst.getRegister());
+ break;
}
}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
index eae79ad101d3..04a72ba3d738 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -17,6 +17,9 @@
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetInstrInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
@@ -32,10 +35,7 @@
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
#define DEBUG_TYPE "asm-printer"
@@ -144,6 +144,7 @@ void AsmPrinter::EmitInlineAsm(StringRef Str, const MCSubtargetInfo &STI,
" we don't have an asm parser for this target\n");
Parser->setAssemblerDialect(Dialect);
Parser->setTargetParser(*TAP.get());
+ Parser->setEnablePrintSchedInfo(EnablePrintSchedInfo);
if (Dialect == InlineAsm::AD_Intel)
// We need this flag to be able to parse numbers like "0bH"
Parser->setParsingInlineAsm(true);
@@ -513,7 +514,7 @@ void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
// Reset SanitizeAddress based on the function's attribute.
MCTargetOptions MCOptions = TM.Options.MCOptions;
MCOptions.SanitizeAddress =
- MF->getFunction()->hasFnAttribute(Attribute::SanitizeAddress);
+ MF->getFunction().hasFnAttribute(Attribute::SanitizeAddress);
EmitInlineAsm(OS.str(), getSubtargetInfo(), MCOptions, LocMD,
MI->getInlineAsmDialect());
diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index a81d56e9618b..1d0a003dc50a 100644
--- a/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "CodeViewDebug.h"
+#include "DwarfExpression.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
@@ -19,9 +20,9 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/ADT/Triple.h"
@@ -34,9 +35,14 @@
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/ContinuationRecordBuilder.h"
#include "llvm/DebugInfo/CodeView/DebugInlineeLinesSubsection.h"
#include "llvm/DebugInfo/CodeView/Line.h"
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
@@ -61,17 +67,15 @@
#include "llvm/Support/BinaryByteStream.h"
#include "llvm/Support/BinaryStreamReader.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/SMLoc.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Support/ScopedPrinter.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include <algorithm>
#include <cassert>
#include <cctype>
@@ -86,6 +90,9 @@
using namespace llvm;
using namespace llvm::codeview;
+static cl::opt<bool> EmitDebugGlobalHashes("emit-codeview-ghash-section",
+ cl::ReallyHidden, cl::init(false));
+
CodeViewDebug::CodeViewDebug(AsmPrinter *AP)
: DebugHandlerBase(AP), OS(*Asm->OutStreamer), TypeTable(Allocator) {
// If module doesn't have named metadata anchors or COFF debug section
@@ -153,12 +160,19 @@ StringRef CodeViewDebug::getFullFilepath(const DIFile *File) {
}
unsigned CodeViewDebug::maybeRecordFile(const DIFile *F) {
+ StringRef FullPath = getFullFilepath(F);
unsigned NextId = FileIdMap.size() + 1;
- auto Insertion = FileIdMap.insert(std::make_pair(F, NextId));
+ auto Insertion = FileIdMap.insert(std::make_pair(FullPath, NextId));
if (Insertion.second) {
// We have to compute the full filepath and emit a .cv_file directive.
- StringRef FullPath = getFullFilepath(F);
- bool Success = OS.EmitCVFileDirective(NextId, FullPath);
+ std::string Checksum = fromHex(F->getChecksum());
+ void *CKMem = OS.getContext().allocate(Checksum.size(), 1);
+ memcpy(CKMem, Checksum.data(), Checksum.size());
+ ArrayRef<uint8_t> ChecksumAsBytes(reinterpret_cast<const uint8_t *>(CKMem),
+ Checksum.size());
+ DIFile::ChecksumKind ChecksumKind = F->getChecksumKind();
+ bool Success = OS.EmitCVFileDirective(NextId, FullPath, ChecksumAsBytes,
+ static_cast<unsigned>(ChecksumKind));
(void)Success;
assert(Success && ".cv_file directive failed");
}
@@ -270,7 +284,7 @@ TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) {
// Build the fully qualified name of the scope.
std::string ScopeName = getFullyQualifiedName(Scope);
StringIdRecord SID(TypeIndex(), ScopeName);
- auto TI = TypeTable.writeKnownType(SID);
+ auto TI = TypeTable.writeLeafType(SID);
return recordTypeIndexForDINode(Scope, TI);
}
@@ -295,12 +309,12 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) {
TypeIndex ClassType = getTypeIndex(Class);
MemberFuncIdRecord MFuncId(ClassType, getMemberFunctionType(SP, Class),
DisplayName);
- TI = TypeTable.writeKnownType(MFuncId);
+ TI = TypeTable.writeLeafType(MFuncId);
} else {
// Otherwise, this must be a free function.
TypeIndex ParentScope = getScopeIndex(Scope);
FuncIdRecord FuncId(ParentScope, getTypeIndex(SP->getType()), DisplayName);
- TI = TypeTable.writeKnownType(FuncId);
+ TI = TypeTable.writeLeafType(FuncId);
}
return recordTypeIndexForDINode(SP, TI);
@@ -324,8 +338,9 @@ TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP,
// function type, as the complete class type is likely to reference this
// member function type.
TypeLoweringScope S(*this);
- TypeIndex TI =
- lowerTypeMemberFunction(SP->getType(), Class, SP->getThisAdjustment());
+ const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0;
+ TypeIndex TI = lowerTypeMemberFunction(
+ SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod);
return recordTypeIndexForDINode(SP, TI, Class);
}
@@ -476,10 +491,13 @@ void CodeViewDebug::endModule() {
OS.AddComment("String table");
OS.EmitCVStringTableDirective();
- // Emit type information last, so that any types we translate while emitting
- // function info are included.
+ // Emit type information and hashes last, so that any types we translate while
+ // emitting function info are included.
emitTypeInformation();
+ if (EmitDebugGlobalHashes)
+ emitTypeGlobalHashes();
+
clear();
}
@@ -496,11 +514,6 @@ static void emitNullTerminatedSymbolName(MCStreamer &OS, StringRef S) {
}
void CodeViewDebug::emitTypeInformation() {
- // Do nothing if we have no debug info or if no non-trivial types were emitted
- // to TypeTable during codegen.
- NamedMDNode *CU_Nodes = MMI->getModule()->getNamedMetadata("llvm.dbg.cu");
- if (!CU_Nodes)
- return;
if (TypeTable.empty())
return;
@@ -545,7 +558,39 @@ void CodeViewDebug::emitTypeInformation() {
}
}
-namespace {
+void CodeViewDebug::emitTypeGlobalHashes() {
+ if (TypeTable.empty())
+ return;
+
+ // Start the .debug$H section with the version and hash algorithm, currently
+ // hardcoded to version 0, SHA1.
+ OS.SwitchSection(Asm->getObjFileLowering().getCOFFGlobalTypeHashesSection());
+
+ OS.EmitValueToAlignment(4);
+ OS.AddComment("Magic");
+ OS.EmitIntValue(COFF::DEBUG_HASHES_SECTION_MAGIC, 4);
+ OS.AddComment("Section Version");
+ OS.EmitIntValue(0, 2);
+ OS.AddComment("Hash Algorithm");
+ OS.EmitIntValue(uint16_t(GlobalTypeHashAlg::SHA1), 2);
+
+ TypeIndex TI(TypeIndex::FirstNonSimpleIndex);
+ for (const auto &GHR : TypeTable.hashes()) {
+ if (OS.isVerboseAsm()) {
+ // Emit an EOL-comment describing which TypeIndex this hash corresponds
+ // to, as well as the stringified SHA1 hash.
+ SmallString<32> Comment;
+ raw_svector_ostream CommentOS(Comment);
+ CommentOS << formatv("{0:X+} [{1}]", TI.getIndex(), GHR);
+ OS.AddComment(Comment);
+ ++TI;
+ }
+ assert(GHR.Hash.size() % 20 == 0);
+ StringRef S(reinterpret_cast<const char *>(GHR.Hash.data()),
+ GHR.Hash.size());
+ OS.EmitBinaryData(S);
+ }
+}
static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
switch (DWLang) {
@@ -572,6 +617,8 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
return SourceLanguage::Cobol;
case dwarf::DW_LANG_Java:
return SourceLanguage::Java;
+ case dwarf::DW_LANG_D:
+ return SourceLanguage::D;
default:
// There's no CodeView representation for this language, and CV doesn't
// have an "unknown" option for the language field, so we'll use MASM,
@@ -580,9 +627,11 @@ static SourceLanguage MapDWLangToCVLang(unsigned DWLang) {
}
}
+namespace {
struct Version {
int Part[4];
};
+} // end anonymous namespace
// Takes a StringRef like "clang 4.0.0.0 (other nonsense 123)" and parses out
// the version number.
@@ -605,20 +654,19 @@ static Version parseVersion(StringRef Name) {
static CPUType mapArchToCVCPUType(Triple::ArchType Type) {
switch (Type) {
- case Triple::ArchType::x86:
- return CPUType::Pentium3;
- case Triple::ArchType::x86_64:
- return CPUType::X64;
- case Triple::ArchType::thumb:
- return CPUType::Thumb;
- default:
- report_fatal_error("target architecture doesn't map to a CodeView "
- "CPUType");
+ case Triple::ArchType::x86:
+ return CPUType::Pentium3;
+ case Triple::ArchType::x86_64:
+ return CPUType::X64;
+ case Triple::ArchType::thumb:
+ return CPUType::Thumb;
+ case Triple::ArchType::aarch64:
+ return CPUType::ARM64;
+ default:
+ report_fatal_error("target architecture doesn't map to a CodeView CPUType");
}
}
-} // end anonymous namespace
-
void CodeViewDebug::emitCompilerInformation() {
MCContext &Context = MMI->getContext();
MCSymbol *CompilerBegin = Context.createTempSymbol(),
@@ -678,8 +726,10 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
OS.AddComment("Inlinee lines subsection");
MCSymbol *InlineEnd = beginCVSubsection(DebugSubsectionKind::InlineeLines);
- // We don't provide any extra file info.
- // FIXME: Find out if debuggers use this info.
+ // We emit the checksum info for files. This is used by debuggers to
+ // determine if a pdb matches the source before loading it. Visual Studio,
+ // for instance, will display a warning that the breakpoints are not valid if
+ // the pdb does not match the source.
OS.AddComment("Inlinee lines signature");
OS.EmitIntValue(unsigned(InlineeLinesSignature::Normal), 4);
@@ -692,13 +742,10 @@ void CodeViewDebug::emitInlineeLinesSubsection() {
OS.AddComment("Inlined function " + SP->getName() + " starts at " +
SP->getFilename() + Twine(':') + Twine(SP->getLine()));
OS.AddBlankLine();
- // The filechecksum table uses 8 byte entries for now, and file ids start at
- // 1.
- unsigned FileOffset = (FileId - 1) * 8;
OS.AddComment("Type index of inlined function");
OS.EmitIntValue(InlineeIdx.getIndex(), 4);
OS.AddComment("Offset into filechecksum table");
- OS.EmitIntValue(FileOffset, 4);
+ OS.EmitCVFileChecksumOffsetDirective(FileId);
OS.AddComment("Starting line number");
OS.EmitIntValue(SP->getLine(), 4);
}
@@ -799,6 +846,10 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
if (FuncName.empty())
FuncName = GlobalValue::dropLLVMManglingEscape(GV->getName());
+ // Emit FPO data, but only on 32-bit x86. No other platforms use it.
+ if (Triple(MMI->getModule()->getTargetTriple()).getArch() == Triple::x86)
+ OS.EmitCVFPOData(Fn);
+
// Emit a symbol subsection, required by VS2012+ to find function boundaries.
OS.AddComment("Symbol subsection for " + Twine(FuncName));
MCSymbol *SymbolsEnd = beginCVSubsection(DebugSubsectionKind::Symbols);
@@ -858,6 +909,30 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
emitInlinedCallSite(FI, InlinedAt, I->second);
}
+ for (auto Annot : FI.Annotations) {
+ MCSymbol *Label = Annot.first;
+ MDTuple *Strs = cast<MDTuple>(Annot.second);
+ MCSymbol *AnnotBegin = MMI->getContext().createTempSymbol(),
+ *AnnotEnd = MMI->getContext().createTempSymbol();
+ OS.AddComment("Record length");
+ OS.emitAbsoluteSymbolDiff(AnnotEnd, AnnotBegin, 2);
+ OS.EmitLabel(AnnotBegin);
+ OS.AddComment("Record kind: S_ANNOTATION");
+ OS.EmitIntValue(SymbolKind::S_ANNOTATION, 2);
+ OS.EmitCOFFSecRel32(Label, /*Offset=*/0);
+ // FIXME: Make sure we don't overflow the max record size.
+ OS.EmitCOFFSectionIndex(Label);
+ OS.EmitIntValue(Strs->getNumOperands(), 2);
+ for (Metadata *MD : Strs->operands()) {
+ // MDStrings are null terminated, so we can do EmitBytes and get the
+ // nice .asciz directive.
+ StringRef Str = cast<MDString>(MD)->getString();
+ assert(Str.data()[Str.size()] == '\0' && "non-nullterminated MDString");
+ OS.EmitBytes(StringRef(Str.data(), Str.size() + 1));
+ }
+ OS.EmitLabel(AnnotEnd);
+ }
+
if (SP != nullptr)
emitDebugInfoForUDTs(LocalUDTs);
@@ -947,13 +1022,110 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
}
}
+static bool canUseReferenceType(const DbgVariableLocation &Loc) {
+ return !Loc.LoadChain.empty() && Loc.LoadChain.back() == 0;
+}
+
+static bool needsReferenceType(const DbgVariableLocation &Loc) {
+ return Loc.LoadChain.size() == 2 && Loc.LoadChain.back() == 0;
+}
+
+void CodeViewDebug::calculateRanges(
+ LocalVariable &Var, const DbgValueHistoryMap::InstrRanges &Ranges) {
+ const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();
+
+ // Calculate the definition ranges.
+ for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
+ const InsnRange &Range = *I;
+ const MachineInstr *DVInst = Range.first;
+ assert(DVInst->isDebugValue() && "Invalid History entry");
+ // FIXME: Find a way to represent constant variables, since they are
+ // relatively common.
+ Optional<DbgVariableLocation> Location =
+ DbgVariableLocation::extractFromMachineInstruction(*DVInst);
+ if (!Location)
+ continue;
+
+ // CodeView can only express variables in register and variables in memory
+ // at a constant offset from a register. However, for variables passed
+ // indirectly by pointer, it is common for that pointer to be spilled to a
+ // stack location. For the special case of one offseted load followed by a
+ // zero offset load (a pointer spilled to the stack), we change the type of
+ // the local variable from a value type to a reference type. This tricks the
+ // debugger into doing the load for us.
+ if (Var.UseReferenceType) {
+ // We're using a reference type. Drop the last zero offset load.
+ if (canUseReferenceType(*Location))
+ Location->LoadChain.pop_back();
+ else
+ continue;
+ } else if (needsReferenceType(*Location)) {
+ // This location can't be expressed without switching to a reference type.
+ // Start over using that.
+ Var.UseReferenceType = true;
+ Var.DefRanges.clear();
+ calculateRanges(Var, Ranges);
+ return;
+ }
+
+ // We can only handle a register or an offseted load of a register.
+ if (Location->Register == 0 || Location->LoadChain.size() > 1)
+ continue;
+ {
+ LocalVarDefRange DR;
+ DR.CVRegister = TRI->getCodeViewRegNum(Location->Register);
+ DR.InMemory = !Location->LoadChain.empty();
+ DR.DataOffset =
+ !Location->LoadChain.empty() ? Location->LoadChain.back() : 0;
+ if (Location->FragmentInfo) {
+ DR.IsSubfield = true;
+ DR.StructOffset = Location->FragmentInfo->OffsetInBits / 8;
+ } else {
+ DR.IsSubfield = false;
+ DR.StructOffset = 0;
+ }
+
+ if (Var.DefRanges.empty() ||
+ Var.DefRanges.back().isDifferentLocation(DR)) {
+ Var.DefRanges.emplace_back(std::move(DR));
+ }
+ }
+
+ // Compute the label range.
+ const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
+ const MCSymbol *End = getLabelAfterInsn(Range.second);
+ if (!End) {
+ // This range is valid until the next overlapping bitpiece. In the
+ // common case, ranges will not be bitpieces, so they will overlap.
+ auto J = std::next(I);
+ const DIExpression *DIExpr = DVInst->getDebugExpression();
+ while (J != E &&
+ !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))
+ ++J;
+ if (J != E)
+ End = getLabelBeforeInsn(J->first);
+ else
+ End = Asm->getFunctionEnd();
+ }
+
+ // If the last range end is our begin, just extend the last range.
+ // Otherwise make a new range.
+ SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &R =
+ Var.DefRanges.back().Ranges;
+ if (!R.empty() && R.back().second == Begin)
+ R.back().second = End;
+ else
+ R.emplace_back(Begin, End);
+
+ // FIXME: Do more range combining.
+ }
+}
+
void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
DenseSet<InlinedVariable> Processed;
// Grab the variable info that was squirreled away in the MMI side-table.
collectVariableInfoFromMFTable(Processed);
- const TargetRegisterInfo *TRI = Asm->MF->getSubtarget().getRegisterInfo();
-
for (const auto &I : DbgValues) {
InlinedVariable IV = I.first;
if (Processed.count(IV))
@@ -976,87 +1148,15 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
LocalVariable Var;
Var.DIVar = DIVar;
- // Calculate the definition ranges.
- for (auto I = Ranges.begin(), E = Ranges.end(); I != E; ++I) {
- const InsnRange &Range = *I;
- const MachineInstr *DVInst = Range.first;
- assert(DVInst->isDebugValue() && "Invalid History entry");
- const DIExpression *DIExpr = DVInst->getDebugExpression();
- bool IsSubfield = false;
- unsigned StructOffset = 0;
-
- // Handle fragments.
- auto Fragment = DIExpr->getFragmentInfo();
- if (Fragment) {
- IsSubfield = true;
- StructOffset = Fragment->OffsetInBits / 8;
- } else if (DIExpr->getNumElements() > 0) {
- continue; // Ignore unrecognized exprs.
- }
-
- // Bail if operand 0 is not a valid register. This means the variable is a
- // simple constant, or is described by a complex expression.
- // FIXME: Find a way to represent constant variables, since they are
- // relatively common.
- unsigned Reg =
- DVInst->getOperand(0).isReg() ? DVInst->getOperand(0).getReg() : 0;
- if (Reg == 0)
- continue;
-
- // Handle the two cases we can handle: indirect in memory and in register.
- unsigned CVReg = TRI->getCodeViewRegNum(Reg);
- bool InMemory = DVInst->getOperand(1).isImm();
- int Offset = InMemory ? DVInst->getOperand(1).getImm() : 0;
- {
- LocalVarDefRange DR;
- DR.CVRegister = CVReg;
- DR.InMemory = InMemory;
- DR.DataOffset = Offset;
- DR.IsSubfield = IsSubfield;
- DR.StructOffset = StructOffset;
-
- if (Var.DefRanges.empty() ||
- Var.DefRanges.back().isDifferentLocation(DR)) {
- Var.DefRanges.emplace_back(std::move(DR));
- }
- }
-
- // Compute the label range.
- const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
- const MCSymbol *End = getLabelAfterInsn(Range.second);
- if (!End) {
- // This range is valid until the next overlapping bitpiece. In the
- // common case, ranges will not be bitpieces, so they will overlap.
- auto J = std::next(I);
- while (J != E &&
- !fragmentsOverlap(DIExpr, J->first->getDebugExpression()))
- ++J;
- if (J != E)
- End = getLabelBeforeInsn(J->first);
- else
- End = Asm->getFunctionEnd();
- }
-
- // If the last range end is our begin, just extend the last range.
- // Otherwise make a new range.
- SmallVectorImpl<std::pair<const MCSymbol *, const MCSymbol *>> &Ranges =
- Var.DefRanges.back().Ranges;
- if (!Ranges.empty() && Ranges.back().second == Begin)
- Ranges.back().second = End;
- else
- Ranges.emplace_back(Begin, End);
-
- // FIXME: Do more range combining.
- }
-
+ calculateRanges(Var, Ranges);
recordLocalVariable(std::move(Var), InlinedAt);
}
}
void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
- const Function *GV = MF->getFunction();
- assert(FnDebugInfo.count(GV) == false);
- CurFn = &FnDebugInfo[GV];
+ const Function &GV = MF->getFunction();
+ assert(FnDebugInfo.count(&GV) == false);
+ CurFn = &FnDebugInfo[&GV];
CurFn->FuncId = NextFuncId++;
CurFn->Begin = Asm->getFunctionBegin();
@@ -1087,10 +1187,40 @@ void CodeViewDebug::beginFunctionImpl(const MachineFunction *MF) {
}
}
-void CodeViewDebug::addToUDTs(const DIType *Ty, TypeIndex TI) {
+static bool shouldEmitUdt(const DIType *T) {
+ if (!T)
+ return false;
+
+ // MSVC does not emit UDTs for typedefs that are scoped to classes.
+ if (T->getTag() == dwarf::DW_TAG_typedef) {
+ if (DIScope *Scope = T->getScope().resolve()) {
+ switch (Scope->getTag()) {
+ case dwarf::DW_TAG_structure_type:
+ case dwarf::DW_TAG_class_type:
+ case dwarf::DW_TAG_union_type:
+ return false;
+ }
+ }
+ }
+
+ while (true) {
+ if (!T || T->isForwardDecl())
+ return false;
+
+ const DIDerivedType *DT = dyn_cast<DIDerivedType>(T);
+ if (!DT)
+ return true;
+ T = DT->getBaseType().resolve();
+ }
+ return true;
+}
+
+void CodeViewDebug::addToUDTs(const DIType *Ty) {
// Don't record empty UDTs.
if (Ty->getName().empty())
return;
+ if (!shouldEmitUdt(Ty))
+ return;
SmallVector<StringRef, 5> QualifiedNameComponents;
const DISubprogram *ClosestSubprogram = getQualifiedNameComponents(
@@ -1099,10 +1229,11 @@ void CodeViewDebug::addToUDTs(const DIType *Ty, TypeIndex TI) {
std::string FullyQualifiedName =
getQualifiedName(QualifiedNameComponents, getPrettyScopeName(Ty));
- if (ClosestSubprogram == nullptr)
- GlobalUDTs.emplace_back(std::move(FullyQualifiedName), TI);
- else if (ClosestSubprogram == CurrentSubprogram)
- LocalUDTs.emplace_back(std::move(FullyQualifiedName), TI);
+ if (ClosestSubprogram == nullptr) {
+ GlobalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
+ } else if (ClosestSubprogram == CurrentSubprogram) {
+ LocalUDTs.emplace_back(std::move(FullyQualifiedName), Ty);
+ }
// TODO: What if the ClosestSubprogram is neither null or the current
// subprogram? Currently, the UDT just gets dropped on the floor.
@@ -1139,7 +1270,8 @@ TypeIndex CodeViewDebug::lowerType(const DIType *Ty, const DIType *ClassTy) {
// The member function type of a member function pointer has no
// ThisAdjustment.
return lowerTypeMemberFunction(cast<DISubroutineType>(Ty), ClassTy,
- /*ThisAdjustment=*/0);
+ /*ThisAdjustment=*/0,
+ /*IsStaticMethod=*/false);
}
return lowerTypeFunction(cast<DISubroutineType>(Ty));
case dwarf::DW_TAG_enumeration_type:
@@ -1160,7 +1292,7 @@ TypeIndex CodeViewDebug::lowerTypeAlias(const DIDerivedType *Ty) {
TypeIndex UnderlyingTypeIndex = getTypeIndex(UnderlyingTypeRef);
StringRef TypeName = Ty->getName();
- addToUDTs(Ty, UnderlyingTypeIndex);
+ addToUDTs(Ty);
if (UnderlyingTypeIndex == TypeIndex(SimpleTypeKind::Int32Long) &&
TypeName == "HRESULT")
@@ -1193,11 +1325,12 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
"codeview doesn't support subranges with lower bounds");
int64_t Count = Subrange->getCount();
- // Variable Length Array (VLA) has Count equal to '-1'.
- // Replace with Count '1', assume it is the minimum VLA length.
- // FIXME: Make front-end support VLA subrange and emit LF_DIMVARLU.
+ // Forward declarations of arrays without a size and VLAs use a count of -1.
+ // Emit a count of zero in these cases to match what MSVC does for arrays
+ // without a size. MSVC doesn't support VLAs, so it's not clear what we
+ // should do for them even if we could distinguish them.
if (Count == -1)
- Count = 1;
+ Count = 0;
// Update the element size and element type index for subsequent subranges.
ElementSize *= Count;
@@ -1209,7 +1342,7 @@ TypeIndex CodeViewDebug::lowerTypeArray(const DICompositeType *Ty) {
StringRef Name = (i == 0) ? Ty->getName() : "";
ArrayRecord AR(ElementTypeIndex, IndexType, ArraySize, Name);
- ElementTypeIndex = TypeTable.writeKnownType(AR);
+ ElementTypeIndex = TypeTable.writeLeafType(AR);
}
return ElementTypeIndex;
@@ -1342,7 +1475,7 @@ TypeIndex CodeViewDebug::lowerTypePointer(const DIDerivedType *Ty) {
// do.
PointerOptions PO = PointerOptions::None;
PointerRecord PR(PointeeTI, PK, PM, PO, Ty->getSizeInBits() / 8);
- return TypeTable.writeKnownType(PR);
+ return TypeTable.writeLeafType(PR);
}
static PointerToMemberRepresentation
@@ -1393,7 +1526,7 @@ TypeIndex CodeViewDebug::lowerTypeMemberPointer(const DIDerivedType *Ty) {
MemberPointerInfo MPI(
ClassTI, translatePtrToMemberRep(SizeInBytes, IsPMF, Ty->getFlags()));
PointerRecord PR(PointeeTI, PK, PM, PO, SizeInBytes, MPI);
- return TypeTable.writeKnownType(PR);
+ return TypeTable.writeLeafType(PR);
}
/// Given a DWARF calling convention, get the CodeView equivalent. If we don't
@@ -1432,7 +1565,7 @@ TypeIndex CodeViewDebug::lowerTypeModifier(const DIDerivedType *Ty) {
}
TypeIndex ModifiedTI = getTypeIndex(BaseTy);
ModifierRecord MR(ModifiedTI, Mods);
- return TypeTable.writeKnownType(MR);
+ return TypeTable.writeLeafType(MR);
}
TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {
@@ -1449,18 +1582,19 @@ TypeIndex CodeViewDebug::lowerTypeFunction(const DISubroutineType *Ty) {
}
ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
- TypeIndex ArgListIndex = TypeTable.writeKnownType(ArgListRec);
+ TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
CallingConvention CC = dwarfCCToCodeView(Ty->getCC());
ProcedureRecord Procedure(ReturnTypeIndex, CC, FunctionOptions::None,
ArgTypeIndices.size(), ArgListIndex);
- return TypeTable.writeKnownType(Procedure);
+ return TypeTable.writeLeafType(Procedure);
}
TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,
const DIType *ClassTy,
- int ThisAdjustment) {
+ int ThisAdjustment,
+ bool IsStaticMethod) {
// Lower the containing class type.
TypeIndex ClassType = getTypeIndex(ClassTy);
@@ -1475,26 +1609,22 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty,
ReturnTypeIndex = ReturnAndArgTypesRef.front();
ArgTypeIndices = ReturnAndArgTypesRef.drop_front();
}
- TypeIndex ThisTypeIndex = TypeIndex::Void();
- if (!ArgTypeIndices.empty()) {
+ TypeIndex ThisTypeIndex;
+ if (!IsStaticMethod && !ArgTypeIndices.empty()) {
ThisTypeIndex = ArgTypeIndices.front();
ArgTypeIndices = ArgTypeIndices.drop_front();
}
ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices);
- TypeIndex ArgListIndex = TypeTable.writeKnownType(ArgListRec);
+ TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec);
CallingConvention CC = dwarfCCToCodeView(Ty->getCC());
- // TODO: Need to use the correct values for:
- // FunctionOptions
- // ThisPointerAdjustment.
+ // TODO: Need to use the correct values for FunctionOptions.
MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC,
FunctionOptions::None, ArgTypeIndices.size(),
ArgListIndex, ThisAdjustment);
- TypeIndex TI = TypeTable.writeKnownType(MFR);
-
- return TI;
+ return TypeTable.writeLeafType(MFR);
}
TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) {
@@ -1503,7 +1633,7 @@ TypeIndex CodeViewDebug::lowerTypeVFTableShape(const DIDerivedType *Ty) {
SmallVector<VFTableSlotKind, 4> Slots(VSlotCount, VFTableSlotKind::Near);
VFTableShapeRecord VFTSR(Slots);
- return TypeTable.writeKnownType(VFTSR);
+ return TypeTable.writeLeafType(VFTSR);
}
static MemberAccess translateAccessFlags(unsigned RecordTag, unsigned Flags) {
@@ -1530,6 +1660,9 @@ static MethodOptions translateMethodOptionFlags(const DISubprogram *SP) {
static MethodKind translateMethodKindFlags(const DISubprogram *SP,
bool Introduced) {
+ if (SP->getFlags() & DINode::FlagStaticMember)
+ return MethodKind::Static;
+
switch (SP->getVirtuality()) {
case dwarf::DW_VIRTUALITY_none:
break;
@@ -1542,8 +1675,6 @@ static MethodKind translateMethodKindFlags(const DISubprogram *SP,
llvm_unreachable("unhandled virtuality case");
}
- // FIXME: Get Clang to mark DISubprogram as static and do something with it.
-
return MethodKind::Vanilla;
}
@@ -1593,9 +1724,8 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
if (Ty->isForwardDecl()) {
CO |= ClassOptions::ForwardReference;
} else {
- FieldListRecordBuilder FLRB(TypeTable);
-
- FLRB.begin();
+ ContinuationRecordBuilder ContinuationBuilder;
+ ContinuationBuilder.begin(ContinuationRecordKind::FieldList);
for (const DINode *Element : Ty->getElements()) {
// We assume that the frontend provides all members in source declaration
// order, which is what MSVC does.
@@ -1603,18 +1733,18 @@ TypeIndex CodeViewDebug::lowerTypeEnum(const DICompositeType *Ty) {
EnumeratorRecord ER(MemberAccess::Public,
APSInt::getUnsigned(Enumerator->getValue()),
Enumerator->getName());
- FLRB.writeMemberType(ER);
+ ContinuationBuilder.writeMemberType(ER);
EnumeratorCount++;
}
}
- FTI = FLRB.end(true);
+ FTI = TypeTable.insertRecord(ContinuationBuilder);
}
std::string FullName = getFullyQualifiedName(Ty);
EnumRecord ER(EnumeratorCount, CO, FTI, FullName, Ty->getIdentifier(),
getTypeIndex(Ty->getBaseType()));
- return TypeTable.writeKnownType(ER);
+ return TypeTable.writeLeafType(ER);
}
//===----------------------------------------------------------------------===//
@@ -1643,7 +1773,7 @@ struct llvm::ClassInfo {
TypeIndex VShapeTI;
- std::vector<const DICompositeType *> NestedClasses;
+ std::vector<const DIType *> NestedTypes;
};
void CodeViewDebug::clear() {
@@ -1694,12 +1824,14 @@ ClassInfo CodeViewDebug::collectClassInfo(const DICompositeType *Ty) {
} else if (DDTy->getTag() == dwarf::DW_TAG_pointer_type &&
DDTy->getName() == "__vtbl_ptr_type") {
Info.VShapeTI = getTypeIndex(DDTy);
+ } else if (DDTy->getTag() == dwarf::DW_TAG_typedef) {
+ Info.NestedTypes.push_back(DDTy);
} else if (DDTy->getTag() == dwarf::DW_TAG_friend) {
// Ignore friend members. It appears that MSVC emitted info about
// friends in the past, but modern versions do not.
}
} else if (auto *Composite = dyn_cast<DICompositeType>(Element)) {
- Info.NestedClasses.push_back(Composite);
+ Info.NestedTypes.push_back(Composite);
}
// Skip other unrecognized kinds of elements.
}
@@ -1715,7 +1847,7 @@ TypeIndex CodeViewDebug::lowerTypeClass(const DICompositeType *Ty) {
std::string FullName = getFullyQualifiedName(Ty);
ClassRecord CR(Kind, 0, CO, TypeIndex(), TypeIndex(), TypeIndex(), 0,
FullName, Ty->getIdentifier());
- TypeIndex FwdDeclTI = TypeTable.writeKnownType(CR);
+ TypeIndex FwdDeclTI = TypeTable.writeLeafType(CR);
if (!Ty->isForwardDecl())
DeferredCompleteTypes.push_back(Ty);
return FwdDeclTI;
@@ -1741,16 +1873,17 @@ TypeIndex CodeViewDebug::lowerCompleteTypeClass(const DICompositeType *Ty) {
ClassRecord CR(Kind, FieldCount, CO, FieldTI, TypeIndex(), VShapeTI,
SizeInBytes, FullName, Ty->getIdentifier());
- TypeIndex ClassTI = TypeTable.writeKnownType(CR);
+ TypeIndex ClassTI = TypeTable.writeLeafType(CR);
if (const auto *File = Ty->getFile()) {
StringIdRecord SIDR(TypeIndex(0x0), getFullFilepath(File));
- TypeIndex SIDI = TypeTable.writeKnownType(SIDR);
+ TypeIndex SIDI = TypeTable.writeLeafType(SIDR);
+
UdtSourceLineRecord USLR(ClassTI, SIDI, Ty->getLine());
- TypeTable.writeKnownType(USLR);
+ TypeTable.writeLeafType(USLR);
}
- addToUDTs(Ty, ClassTI);
+ addToUDTs(Ty);
return ClassTI;
}
@@ -1760,7 +1893,7 @@ TypeIndex CodeViewDebug::lowerTypeUnion(const DICompositeType *Ty) {
ClassOptions::ForwardReference | getCommonClassOptions(Ty);
std::string FullName = getFullyQualifiedName(Ty);
UnionRecord UR(0, CO, TypeIndex(), 0, FullName, Ty->getIdentifier());
- TypeIndex FwdDeclTI = TypeTable.writeKnownType(UR);
+ TypeIndex FwdDeclTI = TypeTable.writeLeafType(UR);
if (!Ty->isForwardDecl())
DeferredCompleteTypes.push_back(Ty);
return FwdDeclTI;
@@ -1782,14 +1915,15 @@ TypeIndex CodeViewDebug::lowerCompleteTypeUnion(const DICompositeType *Ty) {
UnionRecord UR(FieldCount, CO, FieldTI, SizeInBytes, FullName,
Ty->getIdentifier());
- TypeIndex UnionTI = TypeTable.writeKnownType(UR);
+ TypeIndex UnionTI = TypeTable.writeLeafType(UR);
StringIdRecord SIR(TypeIndex(0x0), getFullFilepath(Ty->getFile()));
- TypeIndex SIRI = TypeTable.writeKnownType(SIR);
+ TypeIndex SIRI = TypeTable.writeLeafType(SIR);
+
UdtSourceLineRecord USLR(UnionTI, SIRI, Ty->getLine());
- TypeTable.writeKnownType(USLR);
+ TypeTable.writeLeafType(USLR);
- addToUDTs(Ty, UnionTI);
+ addToUDTs(Ty);
return UnionTI;
}
@@ -1802,8 +1936,8 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
// list record.
unsigned MemberCount = 0;
ClassInfo Info = collectClassInfo(Ty);
- FieldListRecordBuilder FLBR(TypeTable);
- FLBR.begin();
+ ContinuationRecordBuilder ContinuationBuilder;
+ ContinuationBuilder.begin(ContinuationRecordKind::FieldList);
// Create base classes.
for (const DIDerivedType *I : Info.Inheritance) {
@@ -1821,14 +1955,14 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
getTypeIndex(I->getBaseType()), getVBPTypeIndex(), VBPtrOffset,
VBTableIndex);
- FLBR.writeMemberType(VBCR);
+ ContinuationBuilder.writeMemberType(VBCR);
} else {
assert(I->getOffsetInBits() % 8 == 0 &&
"bases must be on byte boundaries");
BaseClassRecord BCR(translateAccessFlags(Ty->getTag(), I->getFlags()),
getTypeIndex(I->getBaseType()),
I->getOffsetInBits() / 8);
- FLBR.writeMemberType(BCR);
+ ContinuationBuilder.writeMemberType(BCR);
}
}
@@ -1842,7 +1976,7 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
if (Member->isStaticMember()) {
StaticDataMemberRecord SDMR(Access, MemberBaseType, MemberName);
- FLBR.writeMemberType(SDMR);
+ ContinuationBuilder.writeMemberType(SDMR);
MemberCount++;
continue;
}
@@ -1851,7 +1985,7 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
if ((Member->getFlags() & DINode::FlagArtificial) &&
Member->getName().startswith("_vptr$")) {
VFPtrRecord VFPR(getTypeIndex(Member->getBaseType()));
- FLBR.writeMemberType(VFPR);
+ ContinuationBuilder.writeMemberType(VFPR);
MemberCount++;
continue;
}
@@ -1868,12 +2002,12 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
StartBitOffset -= MemberOffsetInBits;
BitFieldRecord BFR(MemberBaseType, Member->getSizeInBits(),
StartBitOffset);
- MemberBaseType = TypeTable.writeKnownType(BFR);
+ MemberBaseType = TypeTable.writeLeafType(BFR);
}
uint64_t MemberOffsetInBytes = MemberOffsetInBits / 8;
DataMemberRecord DMR(Access, MemberBaseType, MemberOffsetInBytes,
MemberName);
- FLBR.writeMemberType(DMR);
+ ContinuationBuilder.writeMemberType(DMR);
MemberCount++;
}
@@ -1898,40 +2032,42 @@ CodeViewDebug::lowerRecordFieldList(const DICompositeType *Ty) {
}
assert(!Methods.empty() && "Empty methods map entry");
if (Methods.size() == 1)
- FLBR.writeMemberType(Methods[0]);
+ ContinuationBuilder.writeMemberType(Methods[0]);
else {
+ // FIXME: Make this use its own ContinuationBuilder so that
+ // MethodOverloadList can be split correctly.
MethodOverloadListRecord MOLR(Methods);
- TypeIndex MethodList = TypeTable.writeKnownType(MOLR);
+ TypeIndex MethodList = TypeTable.writeLeafType(MOLR);
+
OverloadedMethodRecord OMR(Methods.size(), MethodList, Name);
- FLBR.writeMemberType(OMR);
+ ContinuationBuilder.writeMemberType(OMR);
}
}
// Create nested classes.
- for (const DICompositeType *Nested : Info.NestedClasses) {
+ for (const DIType *Nested : Info.NestedTypes) {
NestedTypeRecord R(getTypeIndex(DITypeRef(Nested)), Nested->getName());
- FLBR.writeMemberType(R);
+ ContinuationBuilder.writeMemberType(R);
MemberCount++;
}
- TypeIndex FieldTI = FLBR.end(true);
+ TypeIndex FieldTI = TypeTable.insertRecord(ContinuationBuilder);
return std::make_tuple(FieldTI, Info.VShapeTI, MemberCount,
- !Info.NestedClasses.empty());
+ !Info.NestedTypes.empty());
}
TypeIndex CodeViewDebug::getVBPTypeIndex() {
if (!VBPType.getIndex()) {
// Make a 'const int *' type.
ModifierRecord MR(TypeIndex::Int32(), ModifierOptions::Const);
- TypeIndex ModifiedTI = TypeTable.writeKnownType(MR);
+ TypeIndex ModifiedTI = TypeTable.writeLeafType(MR);
PointerKind PK = getPointerSizeInBytes() == 8 ? PointerKind::Near64
: PointerKind::Near32;
PointerMode PM = PointerMode::Pointer;
PointerOptions PO = PointerOptions::None;
PointerRecord PR(ModifiedTI, PK, PM, PO, getPointerSizeInBytes());
-
- VBPType = TypeTable.writeKnownType(PR);
+ VBPType = TypeTable.writeLeafType(PR);
}
return VBPType;
@@ -1957,6 +2093,16 @@ TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) {
return recordTypeIndexForDINode(Ty, TI, ClassTy);
}
+TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) {
+ DIType *Ty = TypeRef.resolve();
+ PointerRecord PR(getTypeIndex(Ty),
+ getPointerSizeInBytes() == 8 ? PointerKind::Near64
+ : PointerKind::Near32,
+ PointerMode::LValueReference, PointerOptions::None,
+ Ty->getSizeInBits() / 8);
+ return TypeTable.writeLeafType(PR);
+}
+
TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {
const DIType *Ty = TypeRef.resolve();
@@ -2064,7 +2210,9 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
Flags |= LocalSymFlags::IsOptimizedOut;
OS.AddComment("TypeIndex");
- TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType());
+ TypeIndex TI = Var.UseReferenceType
+ ? getTypeIndexForReferenceTo(Var.DIVar->getType())
+ : getCompleteTypeIndex(Var.DIVar->getType());
OS.EmitIntValue(TI.getIndex(), 4);
OS.AddComment("Flags");
OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);
@@ -2125,19 +2273,21 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
}
void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {
- const Function *GV = MF->getFunction();
- assert(FnDebugInfo.count(GV));
- assert(CurFn == &FnDebugInfo[GV]);
+ const Function &GV = MF->getFunction();
+ assert(FnDebugInfo.count(&GV));
+ assert(CurFn == &FnDebugInfo[&GV]);
- collectVariableInfo(GV->getSubprogram());
+ collectVariableInfo(GV.getSubprogram());
// Don't emit anything if we don't have any line tables.
if (!CurFn->HaveLineInfo) {
- FnDebugInfo.erase(GV);
+ FnDebugInfo.erase(&GV);
CurFn = nullptr;
return;
}
+ CurFn->Annotations = MF->getCodeViewAnnotations();
+
CurFn->End = Asm->getFunctionEnd();
CurFn = nullptr;
@@ -2156,6 +2306,8 @@ void CodeViewDebug::beginInstruction(const MachineInstr *MI) {
DebugLoc DL = MI->getDebugLoc();
if (!DL && MI->getParent() != PrevInstBB) {
for (const auto &NextMI : *MI->getParent()) {
+ if (NextMI.isDebugValue())
+ continue;
DL = NextMI.getDebugLoc();
if (DL)
break;
@@ -2187,8 +2339,11 @@ void CodeViewDebug::endCVSubsection(MCSymbol *EndLabel) {
}
void CodeViewDebug::emitDebugInfoForUDTs(
- ArrayRef<std::pair<std::string, TypeIndex>> UDTs) {
- for (const std::pair<std::string, codeview::TypeIndex> &UDT : UDTs) {
+ ArrayRef<std::pair<std::string, const DIType *>> UDTs) {
+ for (const auto &UDT : UDTs) {
+ const DIType *T = UDT.second;
+ assert(shouldEmitUdt(T));
+
MCSymbol *UDTRecordBegin = MMI->getContext().createTempSymbol(),
*UDTRecordEnd = MMI->getContext().createTempSymbol();
OS.AddComment("Record length");
@@ -2199,7 +2354,7 @@ void CodeViewDebug::emitDebugInfoForUDTs(
OS.EmitIntValue(unsigned(SymbolKind::S_UDT), 2);
OS.AddComment("Type");
- OS.EmitIntValue(UDT.second.getIndex(), 4);
+ OS.EmitIntValue(getCompleteTypeIndex(T).getIndex(), 4);
emitNullTerminatedSymbolName(OS, UDT.first);
OS.EmitLabel(UDTRecordEnd);
diff --git a/lib/CodeGen/AsmPrinter/CodeViewDebug.h b/lib/CodeGen/AsmPrinter/CodeViewDebug.h
index fd8f60425c24..69e93640d7ef 100644
--- a/lib/CodeGen/AsmPrinter/CodeViewDebug.h
+++ b/lib/CodeGen/AsmPrinter/CodeViewDebug.h
@@ -23,8 +23,8 @@
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
+#include "llvm/DebugInfo/CodeView/GlobalTypeTableBuilder.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
-#include "llvm/DebugInfo/CodeView/TypeTableBuilder.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
@@ -52,7 +52,7 @@ class MachineFunction;
class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
MCStreamer &OS;
BumpPtrAllocator Allocator;
- codeview::TypeTableBuilder TypeTable;
+ codeview::GlobalTypeTableBuilder TypeTable;
/// Represents the most general definition range.
struct LocalVarDefRange {
@@ -94,6 +94,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
struct LocalVariable {
const DILocalVariable *DIVar = nullptr;
SmallVector<LocalVarDefRange, 1> DefRanges;
+ bool UseReferenceType = false;
};
struct InlineSite {
@@ -118,6 +119,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
SmallVector<LocalVariable, 1> Locals;
+ std::vector<std::pair<MCSymbol *, MDNode *>> Annotations;
+
const MCSymbol *Begin = nullptr;
const MCSymbol *End = nullptr;
unsigned FuncId = 0;
@@ -147,6 +150,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex getFuncIdForSubprogram(const DISubprogram *SP);
+ void calculateRanges(LocalVariable &Var,
+ const DbgValueHistoryMap::InstrRanges &Ranges);
+
static void collectInlineSiteChildren(SmallVectorImpl<unsigned> &Children,
const FunctionInfo &FI,
const InlineSite &Site);
@@ -155,8 +161,9 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
/// emit at the end of the TU.
MapVector<const Function *, FunctionInfo> FnDebugInfo;
- /// Map from DIFile to .cv_file id.
- DenseMap<const DIFile *, unsigned> FileIdMap;
+ /// Map from full file path to .cv_file id. Full paths are built from DIFiles
+ /// and are stored in FileToFilepathMap;
+ DenseMap<StringRef, unsigned> FileIdMap;
/// All inlined subprograms in the order they should be emitted.
SmallSetVector<const DISubprogram *, 4> InlinedSubprograms;
@@ -187,8 +194,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
// The UDTs we have seen while processing types; each entry is a pair of type
// index and type name.
- std::vector<std::pair<std::string, codeview::TypeIndex>> LocalUDTs,
- GlobalUDTs;
+ std::vector<std::pair<std::string, const DIType *>> LocalUDTs;
+ std::vector<std::pair<std::string, const DIType *>> GlobalUDTs;
using FileToFilepathMapTy = std::map<const DIFile *, std::string>;
FileToFilepathMapTy FileToFilepathMap;
@@ -212,6 +219,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitTypeInformation();
+ void emitTypeGlobalHashes();
+
void emitCompilerInformation();
void emitInlineeLinesSubsection();
@@ -222,8 +231,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
void emitDebugInfoForRetainedTypes();
- void emitDebugInfoForUDTs(
- ArrayRef<std::pair<std::string, codeview::TypeIndex>> UDTs);
+ void
+ emitDebugInfoForUDTs(ArrayRef<std::pair<std::string, const DIType *>> UDTs);
void emitDebugInfoForGlobal(const DIGlobalVariable *DIGV,
const GlobalVariable *GV, MCSymbol *GVSym);
@@ -259,6 +268,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex getTypeIndex(DITypeRef TypeRef,
DITypeRef ClassTyRef = DITypeRef());
+ codeview::TypeIndex getTypeIndexForReferenceTo(DITypeRef TypeRef);
+
codeview::TypeIndex getMemberFunctionType(const DISubprogram *SP,
const DICompositeType *Class);
@@ -266,7 +277,7 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex getVBPTypeIndex();
- void addToUDTs(const DIType *Ty, codeview::TypeIndex TI);
+ void addToUDTs(const DIType *Ty);
codeview::TypeIndex lowerType(const DIType *Ty, const DIType *ClassTy);
codeview::TypeIndex lowerTypeAlias(const DIDerivedType *Ty);
@@ -279,7 +290,8 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty);
codeview::TypeIndex lowerTypeMemberFunction(const DISubroutineType *Ty,
const DIType *ClassTy,
- int ThisAdjustment);
+ int ThisAdjustment,
+ bool IsStaticMethod);
codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty);
codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty);
codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty);
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index 886e6e264b3e..b3148db30cd6 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -777,6 +777,7 @@ void DIEBlock::EmitValue(const AsmPrinter *Asm, dwarf::Form Form) const {
case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break;
case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break;
case dwarf::DW_FORM_block: Asm->EmitULEB128(Size); break;
+ case dwarf::DW_FORM_data16: break;
}
for (const auto &V : values())
@@ -791,6 +792,7 @@ unsigned DIEBlock::SizeOf(const AsmPrinter *AP, dwarf::Form Form) const {
case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
case dwarf::DW_FORM_block: return Size + getULEB128Size(Size);
+ case dwarf::DW_FORM_data16: return 16;
default: llvm_unreachable("Improper form for block");
}
}
diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
index c2ad9db81cfd..856758c8e4f6 100644
--- a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
+++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp -------------===//
+//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.cpp --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -9,17 +9,24 @@
#include "DbgValueHistoryCalculator.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
-#include <algorithm>
+#include <cassert>
#include <map>
+#include <utility>
+
using namespace llvm;
#define DEBUG_TYPE "dwarfdebug"
@@ -72,10 +79,12 @@ unsigned DbgValueHistoryMap::getRegisterForVar(InlinedVariable Var) const {
}
namespace {
+
// Maps physreg numbers to the variables they describe.
-typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
-typedef std::map<unsigned, SmallVector<InlinedVariable, 1>> RegDescribedVarsMap;
-}
+using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
+using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedVariable, 1>>;
+
+} // end anonymous namespace
// \brief Claim that @Var is not described by @RegNo anymore.
static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
@@ -83,7 +92,7 @@ static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo,
const auto &I = RegVars.find(RegNo);
assert(RegNo != 0U && I != RegVars.end());
auto &VarSet = I->second;
- const auto &VarPos = find(VarSet, Var);
+ const auto &VarPos = llvm::find(VarSet, Var);
assert(VarPos != VarSet.end());
VarSet.erase(VarPos);
// Don't keep empty sets in a map to keep it as small as possible.
diff --git a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
index 16d2d7fd7e99..a7b0562e8102 100644
--- a/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
+++ b/lib/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ----*- C++ -*--===//
+//===- llvm/CodeGen/AsmPrinter/DbgValueHistoryCalculator.h ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,9 +13,11 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/IR/DebugInfoMetadata.h"
+#include <utility>
namespace llvm {
+class DILocalVariable;
class MachineFunction;
class MachineInstr;
class TargetRegisterInfo;
@@ -29,11 +31,11 @@ class DbgValueHistoryMap {
// instruction of the next instruction range, or until the end of the
// function.
public:
- typedef std::pair<const MachineInstr *, const MachineInstr *> InstrRange;
- typedef SmallVector<InstrRange, 4> InstrRanges;
- typedef std::pair<const DILocalVariable *, const DILocation *>
- InlinedVariable;
- typedef MapVector<InlinedVariable, InstrRanges> InstrRangesMap;
+ using InstrRange = std::pair<const MachineInstr *, const MachineInstr *>;
+ using InstrRanges = SmallVector<InstrRange, 4>;
+ using InlinedVariable =
+ std::pair<const DILocalVariable *, const DILocation *>;
+ using InstrRangesMap = MapVector<InlinedVariable, InstrRanges>;
private:
InstrRangesMap VarInstrRanges;
@@ -41,6 +43,7 @@ private:
public:
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(InlinedVariable Var) const;
@@ -54,6 +57,7 @@ public:
void calculateDbgValueHistory(const MachineFunction *MF,
const TargetRegisterInfo *TRI,
DbgValueHistoryMap &Result);
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DBGVALUEHISTORYCALCULATOR_H
diff --git a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
index 0971c5942203..d94b0e5c2118 100644
--- a/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
+++ b/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp
@@ -13,16 +13,76 @@
//===----------------------------------------------------------------------===//
#include "DebugHandlerBase.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
+Optional<DbgVariableLocation>
+DbgVariableLocation::extractFromMachineInstruction(
+ const MachineInstr &Instruction) {
+ DbgVariableLocation Location;
+ if (!Instruction.isDebugValue())
+ return None;
+ if (!Instruction.getOperand(0).isReg())
+ return None;
+ Location.Register = Instruction.getOperand(0).getReg();
+ Location.FragmentInfo.reset();
+ // We only handle expressions generated by DIExpression::appendOffset,
+ // which doesn't require a full stack machine.
+ int64_t Offset = 0;
+ const DIExpression *DIExpr = Instruction.getDebugExpression();
+ auto Op = DIExpr->expr_op_begin();
+ while (Op != DIExpr->expr_op_end()) {
+ switch (Op->getOp()) {
+ case dwarf::DW_OP_constu: {
+ int Value = Op->getArg(0);
+ ++Op;
+ if (Op != DIExpr->expr_op_end()) {
+ switch (Op->getOp()) {
+ case dwarf::DW_OP_minus:
+ Offset -= Value;
+ break;
+ case dwarf::DW_OP_plus:
+ Offset += Value;
+ break;
+ default:
+ continue;
+ }
+ }
+ } break;
+ case dwarf::DW_OP_plus_uconst:
+ Offset += Op->getArg(0);
+ break;
+ case dwarf::DW_OP_LLVM_fragment:
+ Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
+ break;
+ case dwarf::DW_OP_deref:
+ Location.LoadChain.push_back(Offset);
+ Offset = 0;
+ break;
+ default:
+ return None;
+ }
+ ++Op;
+ }
+
+ // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE
+ // instruction.
+ // FIXME: Replace these with DIExpression.
+ if (Instruction.isIndirectDebugValue())
+ Location.LoadChain.push_back(Offset);
+
+ return Location;
+}
+
DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
// Each LexicalScope has first instruction and last instruction to mark
@@ -119,7 +179,7 @@ static bool hasDebugInfo(const MachineModuleInfo *MMI,
const MachineFunction *MF) {
if (!MMI->hasDebugInfo())
return false;
- auto *SP = MF->getFunction()->getSubprogram();
+ auto *SP = MF->getFunction().getSubprogram();
if (!SP)
return false;
assert(SP->getUnit());
@@ -163,7 +223,7 @@ void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
// label, so arguments are visible when breaking at function entry.
const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
if (DIVar->isParameter() &&
- getDISubprogram(DIVar->getScope())->describes(MF->getFunction())) {
+ getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
if (Ranges.front().first->getDebugExpression()->isFragment()) {
// Mark all non-overlapping initial fragments.
diff --git a/lib/CodeGen/AsmPrinter/DebugHandlerBase.h b/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
index 659a921e1fc5..245d70038de9 100644
--- a/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
+++ b/lib/CodeGen/AsmPrinter/DebugHandlerBase.h
@@ -17,14 +17,38 @@
#include "AsmPrinterHandler.h"
#include "DbgValueHistoryCalculator.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/IR/DebugInfoMetadata.h"
namespace llvm {
class AsmPrinter;
+class MachineInstr;
class MachineModuleInfo;
+/// Represents the location at which a variable is stored.
+struct DbgVariableLocation {
+ /// Base register.
+ unsigned Register;
+
+ /// Chain of offsetted loads necessary to load the value if it lives in
+ /// memory. Every load except for the last is pointer-sized.
+ SmallVector<int64_t, 1> LoadChain;
+
+ /// Present if the location is part of a larger variable.
+ llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo;
+
+ /// Extract a VariableLocation from a MachineInstr.
+ /// This will only work if Instruction is a debug value instruction
+ /// and the associated DIExpression is in one of the supported forms.
+ /// If these requirements are not met, the returned Optional will not
+ /// have a value.
+ static Optional<DbgVariableLocation>
+ extractFromMachineInstruction(const MachineInstr &Instruction);
+};
+
/// Base class for debug information backends. Common functionality related to
/// tracking which variables and scopes are alive at a given PC live here.
class DebugHandlerBase : public AsmPrinterHandler {
diff --git a/lib/CodeGen/AsmPrinter/DebugLocEntry.h b/lib/CodeGen/AsmPrinter/DebugLocEntry.h
index a68e8cc6b4b3..3d6d8a76529c 100644
--- a/lib/CodeGen/AsmPrinter/DebugLocEntry.h
+++ b/lib/CodeGen/AsmPrinter/DebugLocEntry.h
@@ -81,7 +81,7 @@ public:
if (isLocation()) {
llvm::dbgs() << "Loc = { reg=" << Loc.getReg() << " ";
if (Loc.isIndirect())
- llvm::dbgs() << '+' << Loc.getOffset();
+ llvm::dbgs() << "+0";
llvm::dbgs() << "} ";
}
else if (isConstantInt())
diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
index 9c324ea26ac8..c21b3d3451ad 100644
--- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.cpp
@@ -1,4 +1,4 @@
-//=-- llvm/CodeGen/DwarfAccelTable.cpp - Dwarf Accelerator Tables -*- C++ -*-=//
+//===- llvm/CodeGen/DwarfAccelTable.cpp - Dwarf Accelerator Tables --------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,16 +12,22 @@
//===----------------------------------------------------------------------===//
#include "DwarfAccelTable.h"
-#include "DwarfCompileUnit.h"
-#include "DwarfDebug.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/Twine.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <limits>
+#include <vector>
using namespace llvm;
@@ -142,13 +148,13 @@ void DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) {
unsigned index = 0;
for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
Asm->OutStreamer->AddComment("Bucket " + Twine(i));
- if (Buckets[i].size() != 0)
+ if (!Buckets[i].empty())
Asm->EmitInt32(index);
else
- Asm->EmitInt32(UINT32_MAX);
+ Asm->EmitInt32(std::numeric_limits<uint32_t>::max());
// Buckets point in the list of hashes, not to the data. Do not
// increment the index multiple times in case of hash collisions.
- uint64_t PrevHash = UINT64_MAX;
+ uint64_t PrevHash = std::numeric_limits<uint64_t>::max();
for (auto *HD : Buckets[i]) {
uint32_t HashValue = HD->HashValue;
if (PrevHash != HashValue)
@@ -161,7 +167,7 @@ void DwarfAccelTable::EmitBuckets(AsmPrinter *Asm) {
// Walk through the buckets and emit the individual hashes for each
// bucket.
void DwarfAccelTable::EmitHashes(AsmPrinter *Asm) {
- uint64_t PrevHash = UINT64_MAX;
+ uint64_t PrevHash = std::numeric_limits<uint64_t>::max();
for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
for (HashList::const_iterator HI = Buckets[i].begin(),
HE = Buckets[i].end();
@@ -181,7 +187,7 @@ void DwarfAccelTable::EmitHashes(AsmPrinter *Asm) {
// beginning of the section. The non-section symbol will be output later
// when we emit the actual data.
void DwarfAccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) {
- uint64_t PrevHash = UINT64_MAX;
+ uint64_t PrevHash = std::numeric_limits<uint64_t>::max();
for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
for (HashList::const_iterator HI = Buckets[i].begin(),
HE = Buckets[i].end();
@@ -205,13 +211,14 @@ void DwarfAccelTable::emitOffsets(AsmPrinter *Asm, const MCSymbol *SecBegin) {
// Terminate each HashData bucket with 0.
void DwarfAccelTable::EmitData(AsmPrinter *Asm, DwarfDebug *D) {
for (size_t i = 0, e = Buckets.size(); i < e; ++i) {
- uint64_t PrevHash = UINT64_MAX;
+ uint64_t PrevHash = std::numeric_limits<uint64_t>::max();
for (HashList::const_iterator HI = Buckets[i].begin(),
HE = Buckets[i].end();
HI != HE; ++HI) {
// Terminate the previous entry if there is no hash collision
// with the current one.
- if (PrevHash != UINT64_MAX && PrevHash != (*HI)->HashValue)
+ if (PrevHash != std::numeric_limits<uint64_t>::max() &&
+ PrevHash != (*HI)->HashValue)
Asm->EmitInt32(0);
// Remember to emit the label for our offset.
Asm->OutStreamer->EmitLabel((*HI)->Sym);
@@ -257,31 +264,30 @@ void DwarfAccelTable::emit(AsmPrinter *Asm, const MCSymbol *SecBegin,
}
#ifndef NDEBUG
-void DwarfAccelTable::print(raw_ostream &O) {
-
- Header.print(O);
- HeaderData.print(O);
+void DwarfAccelTable::print(raw_ostream &OS) {
+ Header.print(OS);
+ HeaderData.print(OS);
- O << "Entries: \n";
+ OS << "Entries: \n";
for (StringMap<DataArray>::const_iterator EI = Entries.begin(),
EE = Entries.end();
EI != EE; ++EI) {
- O << "Name: " << EI->getKeyData() << "\n";
+ OS << "Name: " << EI->getKeyData() << "\n";
for (HashDataContents *HD : EI->second.Values)
- HD->print(O);
+ HD->print(OS);
}
- O << "Buckets and Hashes: \n";
+ OS << "Buckets and Hashes: \n";
for (size_t i = 0, e = Buckets.size(); i < e; ++i)
for (HashList::const_iterator HI = Buckets[i].begin(),
HE = Buckets[i].end();
HI != HE; ++HI)
- (*HI)->print(O);
+ (*HI)->print(OS);
- O << "Data: \n";
+ OS << "Data: \n";
for (std::vector<HashData *>::const_iterator DI = Data.begin(),
DE = Data.end();
DI != DE; ++DI)
- (*DI)->print(O);
+ (*DI)->print(OS);
}
#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
index b1ef8cfe989d..f56199dc8e72 100644
--- a/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
+++ b/lib/CodeGen/AsmPrinter/DwarfAccelTable.h
@@ -1,4 +1,4 @@
-//==-- llvm/CodeGen/DwarfAccelTable.h - Dwarf Accelerator Tables -*- C++ -*-==//
+//==- llvm/CodeGen/DwarfAccelTable.h - Dwarf Accelerator Tables --*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
@@ -15,16 +15,19 @@
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFACCELTABLE_H
#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/DIE.h"
+#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Support/Compiler.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/raw_ostream.h"
+#include <cstddef>
+#include <cstdint>
#include <vector>
// The dwarf accelerator tables are an indirect hash table optimized
@@ -65,44 +68,35 @@ class AsmPrinter;
class DwarfDebug;
class DwarfAccelTable {
-
- static uint32_t HashDJB(StringRef Str) {
- uint32_t h = 5381;
- for (unsigned i = 0, e = Str.size(); i != e; ++i)
- h = ((h << 5) + h) + Str[i];
- return h;
- }
-
// Helper function to compute the number of buckets needed based on
// the number of unique hashes.
- void ComputeBucketCount(void);
+ void ComputeBucketCount();
struct TableHeader {
- uint32_t magic; // 'HASH' magic value to allow endian detection
- uint16_t version; // Version number.
- uint16_t hash_function; // The hash function enumeration that was used.
- uint32_t bucket_count; // The number of buckets in this hash table.
- uint32_t hashes_count; // The total number of unique hash values
- // and hash data offsets in this table.
- uint32_t header_data_len; // The bytes to skip to get to the hash
- // indexes (buckets) for correct alignment.
+ uint32_t magic = MagicHash; // 'HASH' magic value to allow endian detection
+ uint16_t version = 1; // Version number.
+ uint16_t hash_function = dwarf::DW_hash_function_djb;
+ // The hash function enumeration that was used.
+ uint32_t bucket_count = 0; // The number of buckets in this hash table.
+ uint32_t hashes_count = 0; // The total number of unique hash values
+ // and hash data offsets in this table.
+ uint32_t header_data_len; // The bytes to skip to get to the hash
+ // indexes (buckets) for correct alignment.
// Also written to disk is the implementation specific header data.
static const uint32_t MagicHash = 0x48415348;
- TableHeader(uint32_t data_len)
- : magic(MagicHash), version(1),
- hash_function(dwarf::DW_hash_function_djb), bucket_count(0),
- hashes_count(0), header_data_len(data_len) {}
+ TableHeader(uint32_t data_len) : header_data_len(data_len) {}
#ifndef NDEBUG
- void print(raw_ostream &O) {
- O << "Magic: " << format("0x%x", magic) << "\n"
- << "Version: " << version << "\n"
- << "Hash Function: " << hash_function << "\n"
- << "Bucket Count: " << bucket_count << "\n"
- << "Header Data Length: " << header_data_len << "\n";
+ void print(raw_ostream &OS) {
+ OS << "Magic: " << format("0x%x", magic) << "\n"
+ << "Version: " << version << "\n"
+ << "Hash Function: " << hash_function << "\n"
+ << "Bucket Count: " << bucket_count << "\n"
+ << "Header Data Length: " << header_data_len << "\n";
}
+
void dump() { print(dbgs()); }
#endif
};
@@ -127,11 +121,13 @@ public:
uint16_t form; // DWARF DW_FORM_ defines
constexpr Atom(uint16_t type, uint16_t form) : type(type), form(form) {}
+
#ifndef NDEBUG
- void print(raw_ostream &O) {
- O << "Type: " << dwarf::AtomTypeString(type) << "\n"
- << "Form: " << dwarf::FormEncodingString(form) << "\n";
+ void print(raw_ostream &OS) {
+ OS << "Type: " << dwarf::AtomTypeString(type) << "\n"
+ << "Form: " << dwarf::FormEncodingString(form) << "\n";
}
+
void dump() { print(dbgs()); }
#endif
};
@@ -145,11 +141,12 @@ private:
: die_offset_base(offset), Atoms(AtomList.begin(), AtomList.end()) {}
#ifndef NDEBUG
- void print(raw_ostream &O) {
- O << "die_offset_base: " << die_offset_base << "\n";
+ void print(raw_ostream &OS) {
+ OS << "die_offset_base: " << die_offset_base << "\n";
for (size_t i = 0; i < Atoms.size(); i++)
- Atoms[i].print(O);
+ Atoms[i].print(OS);
}
+
void dump() { print(dbgs()); }
#endif
};
@@ -168,11 +165,12 @@ public:
char Flags; // Specific flags to output
HashDataContents(const DIE *D, char Flags) : Die(D), Flags(Flags) {}
+
#ifndef NDEBUG
- void print(raw_ostream &O) const {
- O << " Offset: " << Die->getOffset() << "\n";
- O << " Tag: " << dwarf::TagString(Die->getTag()) << "\n";
- O << " Flags: " << Flags << "\n";
+ void print(raw_ostream &OS) const {
+ OS << " Offset: " << Die->getOffset() << "\n"
+ << " Tag: " << dwarf::TagString(Die->getTag()) << "\n"
+ << " Flags: " << Flags << "\n";
}
#endif
};
@@ -183,39 +181,41 @@ private:
DwarfStringPoolEntryRef Name;
std::vector<HashDataContents *> Values;
};
+
friend struct HashData;
+
struct HashData {
StringRef Str;
uint32_t HashValue;
MCSymbol *Sym;
DwarfAccelTable::DataArray &Data; // offsets
+
HashData(StringRef S, DwarfAccelTable::DataArray &Data)
: Str(S), Data(Data) {
- HashValue = DwarfAccelTable::HashDJB(S);
+ HashValue = dwarf::djbHash(S);
}
+
#ifndef NDEBUG
- void print(raw_ostream &O) {
- O << "Name: " << Str << "\n";
- O << " Hash Value: " << format("0x%x", HashValue) << "\n";
- O << " Symbol: ";
+ void print(raw_ostream &OS) {
+ OS << "Name: " << Str << "\n";
+ OS << " Hash Value: " << format("0x%x", HashValue) << "\n";
+ OS << " Symbol: ";
if (Sym)
- O << *Sym;
+ OS << *Sym;
else
- O << "<none>";
- O << "\n";
+ OS << "<none>";
+ OS << "\n";
for (HashDataContents *C : Data.Values) {
- O << " Offset: " << C->Die->getOffset() << "\n";
- O << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n";
- O << " Flags: " << C->Flags << "\n";
+ OS << " Offset: " << C->Die->getOffset() << "\n";
+ OS << " Tag: " << dwarf::TagString(C->Die->getTag()) << "\n";
+ OS << " Flags: " << C->Flags << "\n";
}
}
+
void dump() { print(dbgs()); }
#endif
};
- DwarfAccelTable(const DwarfAccelTable &) = delete;
- void operator=(const DwarfAccelTable &) = delete;
-
// Internal Functions
void EmitHeader(AsmPrinter *);
void EmitBuckets(AsmPrinter *);
@@ -231,25 +231,31 @@ private:
TableHeaderData HeaderData;
std::vector<HashData *> Data;
- typedef StringMap<DataArray, BumpPtrAllocator &> StringEntries;
+ using StringEntries = StringMap<DataArray, BumpPtrAllocator &>;
+
StringEntries Entries;
// Buckets/Hashes/Offsets
- typedef std::vector<HashData *> HashList;
- typedef std::vector<HashList> BucketList;
+ using HashList = std::vector<HashData *>;
+ using BucketList = std::vector<HashList>;
BucketList Buckets;
HashList Hashes;
// Public Implementation
public:
DwarfAccelTable(ArrayRef<DwarfAccelTable::Atom>);
+ DwarfAccelTable(const DwarfAccelTable &) = delete;
+ DwarfAccelTable &operator=(const DwarfAccelTable &) = delete;
+
void AddName(DwarfStringPoolEntryRef Name, const DIE *Die, char Flags = 0);
void FinalizeTable(AsmPrinter *, StringRef);
void emit(AsmPrinter *, const MCSymbol *, DwarfDebug *);
#ifndef NDEBUG
- void print(raw_ostream &O);
+ void print(raw_ostream &OS);
void dump() { print(dbgs()); }
#endif
};
-}
-#endif
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFACCELTABLE_H
diff --git a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
index dd7f7931b06b..cbb4c48b4d88 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
@@ -12,13 +12,12 @@
//===----------------------------------------------------------------------===//
#include "DwarfException.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
#include "llvm/IR/Module.h"
@@ -31,11 +30,7 @@
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
DwarfCFIExceptionBase::DwarfCFIExceptionBase(AsmPrinter *A)
@@ -92,7 +87,7 @@ static MCSymbol *getExceptionSym(AsmPrinter *Asm) {
void DwarfCFIException::beginFunction(const MachineFunction *MF) {
shouldEmitMoves = shouldEmitPersonality = shouldEmitLSDA = false;
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
// If any landing pads survive, we need an EH table.
bool hasLandingPads = !MF->getLandingPads().empty();
@@ -105,17 +100,17 @@ void DwarfCFIException::beginFunction(const MachineFunction *MF) {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
unsigned PerEncoding = TLOF.getPersonalityEncoding();
const Function *Per = nullptr;
- if (F->hasPersonalityFn())
- Per = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ if (F.hasPersonalityFn())
+ Per = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
// Emit a personality function even when there are no landing pads
forceEmitPersonality =
// ...if a personality function is explicitly specified
- F->hasPersonalityFn() &&
+ F.hasPersonalityFn() &&
// ... and it's not known to be a noop in the absence of invokes
!isNoOpWithoutInvoke(classifyEHPersonality(Per)) &&
// ... and we're not explicitly asked not to emit it
- F->needsUnwindTableEntry();
+ F.needsUnwindTableEntry();
shouldEmitPersonality =
(forceEmitPersonality ||
@@ -148,8 +143,8 @@ void DwarfCFIException::beginFragment(const MachineBasicBlock *MBB,
if (!shouldEmitPersonality)
return;
- auto *F = MBB->getParent()->getFunction();
- auto *P = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ auto &F = MBB->getParent()->getFunction();
+ auto *P = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
assert(P && "Expected personality function");
// If we are forced to emit this personality, make sure to record
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index 333d14a11af5..c8cd8eb8ffd3 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units -----------===//
+//===- llvm/CodeGen/DwarfCompileUnit.cpp - Dwarf Compile Units ------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,38 +12,58 @@
//===----------------------------------------------------------------------===//
#include "DwarfCompileUnit.h"
+#include "AddressPool.h"
+#include "DwarfDebug.h"
#include "DwarfExpression.h"
+#include "DwarfUnit.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/DIE.h"
+#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/IR/Constants.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/GlobalValue.h"
+#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/GlobalVariable.h"
-#include "llvm/IR/Instruction.h"
-#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/Target/TargetOptions.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <utility>
-namespace llvm {
+using namespace llvm;
DwarfCompileUnit::DwarfCompileUnit(unsigned UID, const DICompileUnit *Node,
AsmPrinter *A, DwarfDebug *DW,
DwarfFile *DWU)
- : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID),
- Skeleton(nullptr), BaseAddress(nullptr) {
+ : DwarfUnit(dwarf::DW_TAG_compile_unit, Node, A, DW, DWU), UniqueID(UID) {
insertDIE(Node, &getUnitDie());
MacroLabelBegin = Asm->createTempSymbol("cu_macro_begin");
}
/// addLabelAddress - Add a dwarf label attribute data and value using
/// DW_FORM_addr or DW_FORM_GNU_addr_index.
-///
void DwarfCompileUnit::addLabelAddress(DIE &Die, dwarf::Attribute Attribute,
const MCSymbol *Label) {
-
// Don't use the address pool in non-fission or in the skeleton unit itself.
// FIXME: Once GDB supports this, it's probably worthwhile using the address
// pool from the skeleton - maybe even in non-fission (possibly fewer
@@ -336,23 +356,15 @@ void DwarfCompileUnit::constructScopeDIE(
if (DD->isLexicalScopeDIENull(Scope))
return;
- unsigned ChildScopeCount;
+ bool HasNonScopeChildren = false;
// We create children here when we know the scope DIE is not going to be
// null and the children will be added to the scope DIE.
- createScopeChildrenDIE(Scope, Children, &ChildScopeCount);
-
- // Skip imported directives in gmlt-like data.
- if (!includeMinimalInlineScopes()) {
- // There is no need to emit empty lexical block DIE.
- for (const auto *IE : ImportedEntities[DS])
- Children.push_back(
- constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
- }
+ createScopeChildrenDIE(Scope, Children, &HasNonScopeChildren);
// If there are only other scopes as children, put them directly in the
// parent instead, as this scope would serve no purpose.
- if (Children.size() == ChildScopeCount) {
+ if (!HasNonScopeChildren) {
FinalChildren.insert(FinalChildren.end(),
std::make_move_iterator(Children.begin()),
std::make_move_iterator(Children.end()));
@@ -488,14 +500,12 @@ DIE *DwarfCompileUnit::constructVariableDIEImpl(const DbgVariable &DV,
if (const MachineInstr *DVInsn = DV.getMInsn()) {
assert(DVInsn->getNumOperands() == 4);
if (DVInsn->getOperand(0).isReg()) {
- const MachineOperand RegOp = DVInsn->getOperand(0);
+ auto RegOp = DVInsn->getOperand(0);
+ auto Op1 = DVInsn->getOperand(1);
// If the second operand is an immediate, this is an indirect value.
- if (DVInsn->getOperand(1).isImm()) {
- MachineLocation Location(RegOp.getReg(),
- DVInsn->getOperand(1).getImm());
- addVariableAddress(DV, *VariableDie, Location);
- } else if (RegOp.getReg())
- addVariableAddress(DV, *VariableDie, MachineLocation(RegOp.getReg()));
+ assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
+ MachineLocation Location(RegOp.getReg(), Op1.isImm());
+ addVariableAddress(DV, *VariableDie, Location);
} else if (DVInsn->getOperand(0).isImm()) {
// This variable is described by a single constant.
// Check whether it has a DIExpression.
@@ -557,20 +567,27 @@ DIE *DwarfCompileUnit::constructVariableDIE(DbgVariable &DV,
DIE *DwarfCompileUnit::createScopeChildrenDIE(LexicalScope *Scope,
SmallVectorImpl<DIE *> &Children,
- unsigned *ChildScopeCount) {
+ bool *HasNonScopeChildren) {
+ assert(Children.empty());
DIE *ObjectPointer = nullptr;
for (DbgVariable *DV : DU->getScopeVariables().lookup(Scope))
Children.push_back(constructVariableDIE(*DV, *Scope, ObjectPointer));
- unsigned ChildCountWithoutScopes = Children.size();
+ // Skip imported directives in gmlt-like data.
+ if (!includeMinimalInlineScopes()) {
+ // There is no need to emit empty lexical block DIE.
+ for (const auto *IE : ImportedEntities[Scope->getScopeNode()])
+ Children.push_back(
+ constructImportedEntityDIE(cast<DIImportedEntity>(IE)));
+ }
+
+ if (HasNonScopeChildren)
+ *HasNonScopeChildren = !Children.empty();
for (LexicalScope *LS : Scope->getChildren())
constructScopeDIE(LS, Children);
- if (ChildScopeCount)
- *ChildScopeCount = Children.size() - ChildCountWithoutScopes;
-
return ObjectPointer;
}
@@ -726,7 +743,7 @@ DbgVariable *DwarfCompileUnit::getExistingAbstractVariable(
void DwarfCompileUnit::createAbstractVariable(const DILocalVariable *Var,
LexicalScope *Scope) {
assert(Scope && Scope->isAbstractScope());
- auto AbsDbgVariable = make_unique<DbgVariable>(Var, /* IA */ nullptr);
+ auto AbsDbgVariable = llvm::make_unique<DbgVariable>(Var, /* IA */ nullptr);
DU->addScopeVariable(Scope, AbsDbgVariable.get());
getAbstractVariables()[Var] = std::move(AbsDbgVariable);
}
@@ -744,10 +761,19 @@ void DwarfCompileUnit::emitHeader(bool UseOffsets) {
DwarfUnit::emitCommonHeader(UseOffsets, UT);
}
+bool DwarfCompileUnit::hasDwarfPubSections() const {
+ // Opting in to GNU Pubnames/types overrides the default to ensure these are
+ // generated for things like Gold's gdb_index generation.
+ if (CUNode->getGnuPubnames())
+ return true;
+
+ return DD->tuneForGDB() && !includeMinimalInlineScopes();
+}
+
/// addGlobalName - Add a new global name to the compile unit.
void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
const DIScope *Context) {
- if (!DD->hasDwarfPubSections(includeMinimalInlineScopes()))
+ if (!hasDwarfPubSections())
return;
std::string FullName = getParentContextString(Context) + Name.str();
GlobalNames[FullName] = &Die;
@@ -755,7 +781,7 @@ void DwarfCompileUnit::addGlobalName(StringRef Name, const DIE &Die,
void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
const DIScope *Context) {
- if (!DD->hasDwarfPubSections(includeMinimalInlineScopes()))
+ if (!hasDwarfPubSections())
return;
std::string FullName = getParentContextString(Context) + Name.str();
// Insert, allowing the entry to remain as-is if it's already present
@@ -768,7 +794,7 @@ void DwarfCompileUnit::addGlobalNameForTypeUnit(StringRef Name,
/// Add a new global type to the unit.
void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
const DIScope *Context) {
- if (!DD->hasDwarfPubSections(includeMinimalInlineScopes()))
+ if (!hasDwarfPubSections())
return;
std::string FullName = getParentContextString(Context) + Ty->getName().str();
GlobalTypes[FullName] = &Die;
@@ -776,7 +802,7 @@ void DwarfCompileUnit::addGlobalType(const DIType *Ty, const DIE &Die,
void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
const DIScope *Context) {
- if (!DD->hasDwarfPubSections(includeMinimalInlineScopes()))
+ if (!hasDwarfPubSections())
return;
std::string FullName = getParentContextString(Context) + Ty->getName().str();
// Insert, allowing the entry to remain as-is if it's already present
@@ -790,6 +816,12 @@ void DwarfCompileUnit::addGlobalTypeUnitType(const DIType *Ty,
/// DbgVariable based on provided MachineLocation.
void DwarfCompileUnit::addVariableAddress(const DbgVariable &DV, DIE &Die,
MachineLocation Location) {
+ // addBlockByrefAddress is obsolete and will be removed soon.
+ // The clang frontend always generates block byref variables with a
+ // complex expression that encodes exactly what addBlockByrefAddress
+ // would do.
+ assert((!DV.isBlockByrefVariable() || DV.hasComplexAddress()) &&
+ "block byref variable without a complex expression");
if (DV.hasComplexAddress())
addComplexAddress(DV, Die, dwarf::DW_AT_location, Location);
else if (DV.isBlockByrefVariable())
@@ -806,12 +838,7 @@ void DwarfCompileUnit::addAddress(DIE &Die, dwarf::Attribute Attribute,
if (Location.isIndirect())
DwarfExpr.setMemoryLocationKind();
- SmallVector<uint64_t, 8> Ops;
- if (Location.isIndirect() && Location.getOffset()) {
- Ops.push_back(dwarf::DW_OP_plus_uconst);
- Ops.push_back(Location.getOffset());
- }
- DIExpressionCursor Cursor(Ops);
+ DIExpressionCursor Cursor({});
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
@@ -835,13 +862,7 @@ void DwarfCompileUnit::addComplexAddress(const DbgVariable &DV, DIE &Die,
if (Location.isIndirect())
DwarfExpr.setMemoryLocationKind();
- SmallVector<uint64_t, 8> Ops;
- if (Location.isIndirect() && Location.getOffset()) {
- Ops.push_back(dwarf::DW_OP_plus_uconst);
- Ops.push_back(Location.getOffset());
- }
- Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
- DIExpressionCursor Cursor(Ops);
+ DIExpressionCursor Cursor(DIExpr);
const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
@@ -898,4 +919,3 @@ bool DwarfCompileUnit::includeMinimalInlineScopes() const {
return getCUNode()->getEmissionKind() == DICompileUnit::LineTablesOnly ||
(DD->useSplitDwarf() && !Skeleton);
}
-} // end llvm namespace
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
index e38672792867..68482eb7e358 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit ---*- C++ -*--===//
+//===- llvm/CodeGen/DwarfCompileUnit.h - Dwarf Compile Unit -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,19 +14,32 @@
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
+#include "DbgValueHistoryCalculator.h"
+#include "DwarfDebug.h"
#include "DwarfUnit.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/CodeGen/DIE.h"
+#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/Support/Casting.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <memory>
namespace llvm {
-class StringRef;
class AsmPrinter;
-class DIE;
-class DwarfDebug;
class DwarfFile;
+class GlobalVariable;
+class MCExpr;
class MCSymbol;
-class LexicalScope;
+class MDNode;
class DwarfCompileUnit final : public DwarfUnit {
/// A numeric ID unique among all CUs in the module
@@ -37,7 +50,7 @@ class DwarfCompileUnit final : public DwarfUnit {
DIE::value_iterator StmtListValue;
/// Skeleton unit associated with this unit.
- DwarfCompileUnit *Skeleton;
+ DwarfCompileUnit *Skeleton = nullptr;
/// The start of the unit within its section.
MCSymbol *LabelBegin;
@@ -45,9 +58,8 @@ class DwarfCompileUnit final : public DwarfUnit {
/// The start of the unit macro info within macro section.
MCSymbol *MacroLabelBegin;
- typedef llvm::SmallVector<const MDNode *, 8> ImportedEntityList;
- typedef llvm::DenseMap<const MDNode *, ImportedEntityList>
- ImportedEntityMap;
+ using ImportedEntityList = SmallVector<const MDNode *, 8>;
+ using ImportedEntityMap = DenseMap<const MDNode *, ImportedEntityList>;
ImportedEntityMap ImportedEntities;
@@ -66,7 +78,7 @@ class DwarfCompileUnit final : public DwarfUnit {
// The base address of this unit, if any. Used for relative references in
// ranges/locs.
- const MCSymbol *BaseAddress;
+ const MCSymbol *BaseAddress = nullptr;
DenseMap<const MDNode *, DIE *> AbstractSPDies;
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> AbstractVariables;
@@ -164,6 +176,7 @@ public:
void attachRangesOrLowHighPC(DIE &D,
const SmallVectorImpl<InsnRange> &Ranges);
+
/// \brief This scope represents inlined body of a function. Construct
/// DIE to represent this concrete inlined copy of the function.
DIE *constructInlinedScopeDIE(LexicalScope *Scope);
@@ -181,7 +194,7 @@ public:
/// A helper function to create children of a Scope DIE.
DIE *createScopeChildrenDIE(LexicalScope *Scope,
SmallVectorImpl<DIE *> &Children,
- unsigned *ChildScopeCount = nullptr);
+ bool *HasNonScopeChildren = nullptr);
/// \brief Construct a DIE for this subprogram scope.
void constructSubprogramScopeDIE(const DISubprogram *Sub, LexicalScope *Scope);
@@ -195,8 +208,9 @@ public:
void finishSubprogramDefinition(const DISubprogram *SP);
void finishVariableDefinition(const DbgVariable &Var);
+
/// Find abstract variable associated with Var.
- typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
+ using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
DbgVariable *getExistingAbstractVariable(InlinedVariable IV,
const DILocalVariable *&Cleansed);
DbgVariable *getExistingAbstractVariable(InlinedVariable IV);
@@ -275,8 +289,10 @@ public:
void setBaseAddress(const MCSymbol *Base) { BaseAddress = Base; }
const MCSymbol *getBaseAddress() const { return BaseAddress; }
+
+ bool hasDwarfPubSections() const;
};
-} // end llvm namespace
+} // end namespace llvm
-#endif
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFCOMPILEUNIT_H
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f1b4d9f20ca9..2c9c7d4f3146 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ---------------===//
+//===- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -15,43 +15,67 @@
#include "ByteStreamer.h"
#include "DIEHash.h"
#include "DebugLocEntry.h"
+#include "DebugLocStream.h"
+#include "DwarfAccelTable.h"
#include "DwarfCompileUnit.h"
#include "DwarfExpression.h"
+#include "DwarfFile.h"
#include "DwarfUnit.h"
+#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/Dwarf.h"
+#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/DIE.h"
+#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Constants.h"
-#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/IR/Instructions.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Module.h"
-#include "llvm/IR/ValueHandle.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/MC/MachineLocation.h"
+#include "llvm/MC/SectionKind.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/LEB128.h"
#include "llvm/Support/MD5.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <iterator>
+#include <string>
+#include <utility>
+#include <vector>
using namespace llvm;
@@ -61,10 +85,9 @@ static cl::opt<bool>
DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
cl::desc("Disable debug info printing"));
-static cl::opt<bool>
-GenerateGnuPubSections("generate-gnu-dwarf-pub-sections", cl::Hidden,
- cl::desc("Generate GNU-style pubnames and pubtypes"),
- cl::init(false));
+static cl::opt<bool> UseDwarfRangesBaseAddressSpecifier(
+ "use-dwarf-ranges-base-address-specifier", cl::Hidden,
+ cl::desc("Use base address specifiers in debug_ranges"), cl::init(false));
static cl::opt<bool> GenerateARangeSection("generate-arange-section",
cl::Hidden,
@@ -75,9 +98,7 @@ static cl::opt<bool> SplitDwarfCrossCuReferences(
"split-dwarf-cross-cu-references", cl::Hidden,
cl::desc("Enable cross-cu references in DWO files"), cl::init(false));
-namespace {
enum DefaultOnOff { Default, Enable, Disable };
-}
static cl::opt<DefaultOnOff> UnknownLocations(
"use-unknown-locations", cl::Hidden,
@@ -94,19 +115,12 @@ DwarfAccelTables("dwarf-accel-tables", cl::Hidden,
clEnumVal(Disable, "Disabled")),
cl::init(Default));
-static cl::opt<DefaultOnOff>
-DwarfPubSections("generate-dwarf-pub-sections", cl::Hidden,
- cl::desc("Generate DWARF pubnames and pubtypes sections"),
- cl::values(clEnumVal(Default, "Default for platform"),
- clEnumVal(Enable, "Enabled"),
- clEnumVal(Disable, "Disabled")),
- cl::init(Default));
-
enum LinkageNameOption {
DefaultLinkageNames,
AllLinkageNames,
AbstractLinkageNames
};
+
static cl::opt<LinkageNameOption>
DwarfLinkageNames("dwarf-linkage-names", cl::Hidden,
cl::desc("Which DWARF linkage-name attributes to emit."),
@@ -142,8 +156,6 @@ bool DebugLocDwarfExpression::isFrameRegister(const TargetRegisterInfo &TRI,
return false;
}
-//===----------------------------------------------------------------------===//
-
bool DbgVariable::isBlockByrefVariable() const {
assert(Var && "Invalid complex DbgVariable!");
return Var->getType().resolve()->isBlockByrefStruct();
@@ -198,17 +210,54 @@ ArrayRef<DbgVariable::FrameIndexExpr> DbgVariable::getFrameIndexExprs() const {
if (FrameIndexExprs.size() == 1)
return FrameIndexExprs;
- assert(all_of(FrameIndexExprs,
- [](const FrameIndexExpr &A) { return A.Expr->isFragment(); }) &&
+ assert(llvm::all_of(FrameIndexExprs,
+ [](const FrameIndexExpr &A) {
+ return A.Expr->isFragment();
+ }) &&
"multiple FI expressions without DW_OP_LLVM_fragment");
std::sort(FrameIndexExprs.begin(), FrameIndexExprs.end(),
[](const FrameIndexExpr &A, const FrameIndexExpr &B) -> bool {
return A.Expr->getFragmentInfo()->OffsetInBits <
B.Expr->getFragmentInfo()->OffsetInBits;
});
+
return FrameIndexExprs;
}
+void DbgVariable::addMMIEntry(const DbgVariable &V) {
+ assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
+ assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
+ assert(V.Var == Var && "conflicting variable");
+ assert(V.IA == IA && "conflicting inlined-at location");
+
+ assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
+ assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
+
+ // FIXME: This logic should not be necessary anymore, as we now have proper
+ // deduplication. However, without it, we currently run into the assertion
+ // below, which means that we are likely dealing with broken input, i.e. two
+ // non-fragment entries for the same variable at different frame indices.
+ if (FrameIndexExprs.size()) {
+ auto *Expr = FrameIndexExprs.back().Expr;
+ if (!Expr || !Expr->isFragment())
+ return;
+ }
+
+ for (const auto &FIE : V.FrameIndexExprs)
+ // Ignore duplicate entries.
+ if (llvm::none_of(FrameIndexExprs, [&](const FrameIndexExpr &Other) {
+ return FIE.FI == Other.FI && FIE.Expr == Other.Expr;
+ }))
+ FrameIndexExprs.push_back(FIE);
+
+ assert((FrameIndexExprs.size() == 1 ||
+ llvm::all_of(FrameIndexExprs,
+ [](FrameIndexExpr &FIE) {
+ return FIE.Expr && FIE.Expr->isFragment();
+ })) &&
+ "conflicting locations for variable");
+}
+
static const DwarfAccelTable::Atom TypeAtoms[] = {
DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset, dwarf::DW_FORM_data4),
DwarfAccelTable::Atom(dwarf::DW_ATOM_die_tag, dwarf::DW_FORM_data2),
@@ -225,9 +274,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
dwarf::DW_FORM_data4)),
AccelNamespace(DwarfAccelTable::Atom(dwarf::DW_ATOM_die_offset,
dwarf::DW_FORM_data4)),
- AccelTypes(TypeAtoms), DebuggerTuning(DebuggerKind::Default) {
-
- CurFn = nullptr;
+ AccelTypes(TypeAtoms) {
const Triple &TT = Asm->TM.getTargetTriple();
// Make sure we know our "debugger tuning." The target option takes
@@ -278,7 +325,7 @@ DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
}
// Define out of line so we don't have to include DwarfUnit.h in DwarfDebug.h.
-DwarfDebug::~DwarfDebug() { }
+DwarfDebug::~DwarfDebug() = default;
static bool isObjCClass(StringRef Name) {
return Name.startswith("+") || Name.startswith("-");
@@ -389,20 +436,8 @@ void DwarfDebug::constructAbstractSubprogramScopeDIE(DwarfCompileUnit &SrcCU,
}
}
-bool DwarfDebug::hasDwarfPubSections(bool includeMinimalInlineScopes) const {
- // Opting in to GNU Pubnames/types overrides the default to ensure these are
- // generated for things like Gold's gdb_index generation.
- if (GenerateGnuPubSections)
- return true;
-
- if (DwarfPubSections == Default)
- return tuneForGDB() && !includeMinimalInlineScopes;
-
- return DwarfPubSections == Enable;
-}
-
void DwarfDebug::addGnuPubAttributes(DwarfCompileUnit &U, DIE &D) const {
- if (!hasDwarfPubSections(U.includeMinimalInlineScopes()))
+ if (!U.hasDwarfPubSections())
return;
U.addFlag(D, dwarf::DW_AT_GNU_pubnames);
@@ -417,7 +452,7 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
StringRef FN = DIUnit->getFilename();
CompilationDir = DIUnit->getDirectory();
- auto OwnedUnit = make_unique<DwarfCompileUnit>(
+ auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
InfoHolder.getUnits().size(), DIUnit, Asm, this, &InfoHolder);
DwarfCompileUnit &NewCU = *OwnedUnit;
DIE &Die = NewCU.getUnitDie();
@@ -428,6 +463,9 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
Asm->TM.Options.MCOptions.SplitDwarfFile);
}
+ for (auto *IE : DIUnit->getImportedEntities())
+ NewCU.addImportedEntity(IE);
+
// LTO with assembly output shares a single line table amongst multiple CUs.
// To avoid the compilation directory being ambiguous, let the line table
// explicitly describe the directory of all files, never relying on the
@@ -494,6 +532,8 @@ DwarfDebug::getOrCreateDwarfCompileUnit(const DICompileUnit *DIUnit) {
void DwarfDebug::constructAndAddImportedEntityDIE(DwarfCompileUnit &TheCU,
const DIImportedEntity *N) {
+ if (isa<DILocalScope>(N->getScope()))
+ return;
if (DIE *D = TheCU.getOrCreateContextDIE(N->getScope()))
D->addChild(TheCU.constructImportedEntityDIE(N));
}
@@ -503,13 +543,18 @@ static SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &
sortGlobalExprs(SmallVectorImpl<DwarfCompileUnit::GlobalExpr> &GVEs) {
std::sort(GVEs.begin(), GVEs.end(),
[](DwarfCompileUnit::GlobalExpr A, DwarfCompileUnit::GlobalExpr B) {
- if (A.Expr != B.Expr && A.Expr && B.Expr) {
- auto FragmentA = A.Expr->getFragmentInfo();
- auto FragmentB = B.Expr->getFragmentInfo();
- if (FragmentA && FragmentB)
- return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
- }
- return false;
+ // Sort order: first null exprs, then exprs without fragment
+ // info, then sort by fragment offset in bits.
+ // FIXME: Come up with a more comprehensive comparator so
+ // the sorting isn't non-deterministic, and so the following
+ // std::unique call works correctly.
+ if (!A.Expr || !B.Expr)
+ return !!B.Expr;
+ auto FragmentA = A.Expr->getFragmentInfo();
+ auto FragmentB = B.Expr->getFragmentInfo();
+ if (!FragmentA || !FragmentB)
+ return !!FragmentB;
+ return FragmentA->OffsetInBits < FragmentB->OffsetInBits;
});
GVEs.erase(std::unique(GVEs.begin(), GVEs.end(),
[](DwarfCompileUnit::GlobalExpr A,
@@ -546,18 +591,31 @@ void DwarfDebug::beginModule() {
}
for (DICompileUnit *CUNode : M->debug_compile_units()) {
- if (CUNode->getEnumTypes().empty() && CUNode->getRetainedTypes().empty() &&
- CUNode->getGlobalVariables().empty() &&
- CUNode->getImportedEntities().empty() && CUNode->getMacros().empty())
+ // FIXME: Move local imported entities into a list attached to the
+ // subprogram, then this search won't be needed and a
+ // getImportedEntities().empty() test should go below with the rest.
+ bool HasNonLocalImportedEntities = llvm::any_of(
+ CUNode->getImportedEntities(), [](const DIImportedEntity *IE) {
+ return !isa<DILocalScope>(IE->getScope());
+ });
+
+ if (!HasNonLocalImportedEntities && CUNode->getEnumTypes().empty() &&
+ CUNode->getRetainedTypes().empty() &&
+ CUNode->getGlobalVariables().empty() && CUNode->getMacros().empty())
continue;
DwarfCompileUnit &CU = getOrCreateDwarfCompileUnit(CUNode);
- for (auto *IE : CUNode->getImportedEntities())
- CU.addImportedEntity(IE);
// Global Variables.
- for (auto *GVE : CUNode->getGlobalVariables())
- GVMap[GVE->getVariable()].push_back({nullptr, GVE->getExpression()});
+ for (auto *GVE : CUNode->getGlobalVariables()) {
+ // Don't bother adding DIGlobalVariableExpressions listed in the CU if we
+ // already know about the variable and it isn't adding a constant
+ // expression.
+ auto &GVMapEntry = GVMap[GVE->getVariable()];
+ auto *Expr = GVE->getExpression();
+ if (!GVMapEntry.size() || (Expr && Expr->isConstant()))
+ GVMapEntry.push_back({nullptr, Expr});
+ }
DenseSet<DIGlobalVariable *> Processed;
for (auto *GVE : CUNode->getGlobalVariables()) {
DIGlobalVariable *GV = GVE->getVariable();
@@ -682,6 +740,11 @@ void DwarfDebug::finalizeModuleInfo() {
TLOF.getDwarfMacinfoSection()->getBeginSymbol());
}
+ // Emit all frontend-produced Skeleton CUs, i.e., Clang modules.
+ for (auto *CUNode : MMI->getModule()->debug_compile_units())
+ if (CUNode->getDWOId())
+ getOrCreateDwarfCompileUnit(CUNode);
+
// Compute DIE offsets and sizes.
InfoHolder.computeSizeAndOffsets();
if (useSplitDwarf())
@@ -744,12 +807,7 @@ void DwarfDebug::endModule() {
}
// Emit the pubnames and pubtypes sections if requested.
- // The condition is optimistically correct - any CU not using GMLT (&
- // implicit/default pubnames state) might still have pubnames.
- if (hasDwarfPubSections(/* gmlt */ false)) {
- emitDebugPubNames(GenerateGnuPubSections);
- emitDebugPubTypes(GenerateGnuPubSections);
- }
+ emitDebugPubSections();
// clean up.
// FIXME: AbstractVariables.clear();
@@ -775,9 +833,11 @@ void DwarfDebug::ensureAbstractVariableIsCreatedIfScoped(DwarfCompileUnit &CU,
LScopes.findAbstractScope(cast_or_null<DILocalScope>(ScopeNode)))
CU.createAbstractVariable(Cleansed, Scope);
}
+
// Collect variable information from side table maintained by MF.
void DwarfDebug::collectVariableInfoFromMFTable(
DwarfCompileUnit &TheCU, DenseSet<InlinedVariable> &Processed) {
+ SmallDenseMap<InlinedVariable, DbgVariable *> MFVars;
for (const auto &VI : Asm->MF->getVariableDbgInfo()) {
if (!VI.Var)
continue;
@@ -793,26 +853,28 @@ void DwarfDebug::collectVariableInfoFromMFTable(
continue;
ensureAbstractVariableIsCreatedIfScoped(TheCU, Var, Scope->getScopeNode());
- auto RegVar = make_unique<DbgVariable>(Var.first, Var.second);
+ auto RegVar = llvm::make_unique<DbgVariable>(Var.first, Var.second);
RegVar->initializeMMI(VI.Expr, VI.Slot);
- if (InfoHolder.addScopeVariable(Scope, RegVar.get()))
+ if (DbgVariable *DbgVar = MFVars.lookup(Var))
+ DbgVar->addMMIEntry(*RegVar);
+ else if (InfoHolder.addScopeVariable(Scope, RegVar.get())) {
+ MFVars.insert({Var, RegVar.get()});
ConcreteVariables.push_back(std::move(RegVar));
+ }
}
}
// Get .debug_loc entry for the instruction range starting at MI.
static DebugLocEntry::Value getDebugLocValue(const MachineInstr *MI) {
const DIExpression *Expr = MI->getDebugExpression();
-
assert(MI->getNumOperands() == 4);
if (MI->getOperand(0).isReg()) {
- MachineLocation MLoc;
+ auto RegOp = MI->getOperand(0);
+ auto Op1 = MI->getOperand(1);
// If the second operand is an immediate, this is a
// register-indirect address.
- if (!MI->getOperand(1).isImm())
- MLoc.set(MI->getOperand(0).getReg());
- else
- MLoc.set(MI->getOperand(0).getReg(), MI->getOperand(1).getImm());
+ assert((!Op1.isImm() || (Op1.getImm() == 0)) && "unexpected offset");
+ MachineLocation MLoc(RegOp.getReg(), Op1.isImm());
return DebugLocEntry::Value(Expr, MLoc);
}
if (MI->getOperand(0).isImm())
@@ -967,7 +1029,8 @@ DbgVariable *DwarfDebug::createConcreteVariable(DwarfCompileUnit &TheCU,
LexicalScope &Scope,
InlinedVariable IV) {
ensureAbstractVariableIsCreatedIfScoped(TheCU, IV, Scope.getScopeNode());
- ConcreteVariables.push_back(make_unique<DbgVariable>(IV.first, IV.second));
+ ConcreteVariables.push_back(
+ llvm::make_unique<DbgVariable>(IV.first, IV.second));
InfoHolder.addScopeVariable(&Scope, ConcreteVariables.back().get());
return ConcreteVariables.back().get();
}
@@ -1100,7 +1163,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
DebugHandlerBase::beginInstruction(MI);
assert(CurMI);
- const auto *SP = MI->getParent()->getParent()->getFunction()->getSubprogram();
+ const auto *SP = MI->getMF()->getFunction().getSubprogram();
if (!SP || SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug)
return;
@@ -1198,7 +1261,7 @@ static DebugLoc findPrologueEndLoc(const MachineFunction *MF) {
void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
CurFn = MF;
- auto *SP = MF->getFunction()->getSubprogram();
+ auto *SP = MF->getFunction().getSubprogram();
assert(LScopes.empty() || SP == LScopes.getCurrentFunctionScope()->getScopeNode());
if (SP->getUnit()->getEmissionKind() == DICompileUnit::NoDebug)
return;
@@ -1234,7 +1297,7 @@ void DwarfDebug::skippedNonDebugFunction() {
// Gather and emit post-function debug information.
void DwarfDebug::endFunctionImpl(const MachineFunction *MF) {
- const DISubprogram *SP = MF->getFunction()->getSubprogram();
+ const DISubprogram *SP = MF->getFunction().getSubprogram();
assert(CurFn == MF &&
"endFunction should be called with the same function as beginFunction");
@@ -1309,8 +1372,8 @@ void DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S,
if (auto *Scope = cast_or_null<DIScope>(S)) {
Fn = Scope->getFilename();
Dir = Scope->getDirectory();
- if (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
- if (getDwarfVersion() >= 4)
+ if (Line != 0 && getDwarfVersion() >= 4)
+ if (auto *LBF = dyn_cast<DILexicalBlockFile>(Scope))
Discriminator = LBF->getDiscriminator();
unsigned CUID = Asm->OutStreamer->getContext().getDwarfCompileUnitID();
@@ -1440,84 +1503,74 @@ static dwarf::PubIndexEntryDescriptor computeIndexValue(DwarfUnit *CU,
}
}
-/// emitDebugPubNames - Emit visible names into a debug pubnames section.
-///
-void DwarfDebug::emitDebugPubNames(bool GnuStyle) {
- MCSection *PSec = GnuStyle
- ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
- : Asm->getObjFileLowering().getDwarfPubNamesSection();
-
- emitDebugPubSection(GnuStyle, PSec, "Names",
- &DwarfCompileUnit::getGlobalNames);
-}
-
-void DwarfDebug::emitDebugPubSection(
- bool GnuStyle, MCSection *PSec, StringRef Name,
- const StringMap<const DIE *> &(DwarfCompileUnit::*Accessor)() const) {
+/// emitDebugPubSections - Emit visible names and types into debug pubnames and
+/// pubtypes sections.
+void DwarfDebug::emitDebugPubSections() {
for (const auto &NU : CUMap) {
DwarfCompileUnit *TheU = NU.second;
-
- const auto &Globals = (TheU->*Accessor)();
-
- if (!hasDwarfPubSections(TheU->includeMinimalInlineScopes()))
+ if (!TheU->hasDwarfPubSections())
continue;
- if (auto *Skeleton = TheU->getSkeleton())
- TheU = Skeleton;
+ bool GnuStyle = TheU->getCUNode()->getGnuPubnames();
- // Start the dwarf pubnames section.
- Asm->OutStreamer->SwitchSection(PSec);
+ Asm->OutStreamer->SwitchSection(
+ GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubNamesSection()
+ : Asm->getObjFileLowering().getDwarfPubNamesSection());
+ emitDebugPubSection(GnuStyle, "Names", TheU, TheU->getGlobalNames());
- // Emit the header.
- Asm->OutStreamer->AddComment("Length of Public " + Name + " Info");
- MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin");
- MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end");
- Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
+ Asm->OutStreamer->SwitchSection(
+ GnuStyle ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
+ : Asm->getObjFileLowering().getDwarfPubTypesSection());
+ emitDebugPubSection(GnuStyle, "Types", TheU, TheU->getGlobalTypes());
+ }
+}
- Asm->OutStreamer->EmitLabel(BeginLabel);
+void DwarfDebug::emitDebugPubSection(bool GnuStyle, StringRef Name,
+ DwarfCompileUnit *TheU,
+ const StringMap<const DIE *> &Globals) {
+ if (auto *Skeleton = TheU->getSkeleton())
+ TheU = Skeleton;
- Asm->OutStreamer->AddComment("DWARF Version");
- Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION);
+ // Emit the header.
+ Asm->OutStreamer->AddComment("Length of Public " + Name + " Info");
+ MCSymbol *BeginLabel = Asm->createTempSymbol("pub" + Name + "_begin");
+ MCSymbol *EndLabel = Asm->createTempSymbol("pub" + Name + "_end");
+ Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
- Asm->OutStreamer->AddComment("Offset of Compilation Unit Info");
- Asm->emitDwarfSymbolReference(TheU->getLabelBegin());
+ Asm->OutStreamer->EmitLabel(BeginLabel);
- Asm->OutStreamer->AddComment("Compilation Unit Length");
- Asm->EmitInt32(TheU->getLength());
+ Asm->OutStreamer->AddComment("DWARF Version");
+ Asm->EmitInt16(dwarf::DW_PUBNAMES_VERSION);
- // Emit the pubnames for this compilation unit.
- for (const auto &GI : Globals) {
- const char *Name = GI.getKeyData();
- const DIE *Entity = GI.second;
+ Asm->OutStreamer->AddComment("Offset of Compilation Unit Info");
+ Asm->emitDwarfSymbolReference(TheU->getLabelBegin());
- Asm->OutStreamer->AddComment("DIE offset");
- Asm->EmitInt32(Entity->getOffset());
+ Asm->OutStreamer->AddComment("Compilation Unit Length");
+ Asm->EmitInt32(TheU->getLength());
- if (GnuStyle) {
- dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity);
- Asm->OutStreamer->AddComment(
- Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " +
- dwarf::GDBIndexEntryLinkageString(Desc.Linkage));
- Asm->EmitInt8(Desc.toBits());
- }
+ // Emit the pubnames for this compilation unit.
+ for (const auto &GI : Globals) {
+ const char *Name = GI.getKeyData();
+ const DIE *Entity = GI.second;
+
+ Asm->OutStreamer->AddComment("DIE offset");
+ Asm->EmitInt32(Entity->getOffset());
- Asm->OutStreamer->AddComment("External Name");
- Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1));
+ if (GnuStyle) {
+ dwarf::PubIndexEntryDescriptor Desc = computeIndexValue(TheU, Entity);
+ Asm->OutStreamer->AddComment(
+ Twine("Kind: ") + dwarf::GDBIndexEntryKindString(Desc.Kind) + ", " +
+ dwarf::GDBIndexEntryLinkageString(Desc.Linkage));
+ Asm->EmitInt8(Desc.toBits());
}
- Asm->OutStreamer->AddComment("End Mark");
- Asm->EmitInt32(0);
- Asm->OutStreamer->EmitLabel(EndLabel);
+ Asm->OutStreamer->AddComment("External Name");
+ Asm->OutStreamer->EmitBytes(StringRef(Name, GI.getKeyLength() + 1));
}
-}
-
-void DwarfDebug::emitDebugPubTypes(bool GnuStyle) {
- MCSection *PSec = GnuStyle
- ? Asm->getObjFileLowering().getDwarfGnuPubTypesSection()
- : Asm->getObjFileLowering().getDwarfPubTypesSection();
- emitDebugPubSection(GnuStyle, PSec, "Types",
- &DwarfCompileUnit::getGlobalTypes);
+ Asm->OutStreamer->AddComment("End Mark");
+ Asm->EmitInt32(0);
+ Asm->OutStreamer->EmitLabel(EndLabel);
}
/// Emit null-terminated strings into a debug str section.
@@ -1553,13 +1606,7 @@ static void emitDebugLocValue(const AsmPrinter &AP, const DIBasicType *BT,
MachineLocation Location = Value.getLoc();
if (Location.isIndirect())
DwarfExpr.setMemoryLocationKind();
- SmallVector<uint64_t, 8> Ops;
- if (Location.isIndirect() && Location.getOffset()) {
- Ops.push_back(dwarf::DW_OP_plus_uconst);
- Ops.push_back(Location.getOffset());
- }
- Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
- DIExpressionCursor Cursor(Ops);
+ DIExpressionCursor Cursor(DIExpr);
const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
return;
@@ -1580,7 +1627,7 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
const DebugLocEntry::Value &Value = Values[0];
if (Value.isFragment()) {
// Emit all fragments that belong to the same variable and range.
- assert(all_of(Values, [](DebugLocEntry::Value P) {
+ assert(llvm::all_of(Values, [](DebugLocEntry::Value P) {
return P.isFragment();
}) && "all values are expected to be fragments");
assert(std::is_sorted(Values.begin(), Values.end()) &&
@@ -1844,17 +1891,49 @@ void DwarfDebug::emitDebugRanges() {
// Emit our symbol so we can find the beginning of the range.
Asm->OutStreamer->EmitLabel(List.getSym());
+ // Gather all the ranges that apply to the same section so they can share
+ // a base address entry.
+ MapVector<const MCSection *, std::vector<const RangeSpan *>> MV;
for (const RangeSpan &Range : List.getRanges()) {
- const MCSymbol *Begin = Range.getStart();
- const MCSymbol *End = Range.getEnd();
- assert(Begin && "Range without a begin symbol?");
- assert(End && "Range without an end symbol?");
- if (auto *Base = TheCU->getBaseAddress()) {
- Asm->EmitLabelDifference(Begin, Base, Size);
- Asm->EmitLabelDifference(End, Base, Size);
- } else {
- Asm->OutStreamer->EmitSymbolValue(Begin, Size);
- Asm->OutStreamer->EmitSymbolValue(End, Size);
+ MV[&Range.getStart()->getSection()].push_back(&Range);
+ }
+
+ auto *CUBase = TheCU->getBaseAddress();
+ bool BaseIsSet = false;
+ for (const auto &P : MV) {
+ // Don't bother with a base address entry if there's only one range in
+ // this section in this range list - for example ranges for a CU will
+ // usually consist of single regions from each of many sections
+ // (-ffunction-sections, or just C++ inline functions) except under LTO
+ // or optnone where there may be holes in a single CU's section
+ // contrubutions.
+ auto *Base = CUBase;
+ if (!Base && P.second.size() > 1 &&
+ UseDwarfRangesBaseAddressSpecifier) {
+ BaseIsSet = true;
+ // FIXME/use care: This may not be a useful base address if it's not
+ // the lowest address/range in this object.
+ Base = P.second.front()->getStart();
+ Asm->OutStreamer->EmitIntValue(-1, Size);
+ Asm->OutStreamer->EmitSymbolValue(Base, Size);
+ } else if (BaseIsSet) {
+ BaseIsSet = false;
+ Asm->OutStreamer->EmitIntValue(-1, Size);
+ Asm->OutStreamer->EmitIntValue(0, Size);
+ }
+
+ for (const auto *RS : P.second) {
+ const MCSymbol *Begin = RS->getStart();
+ const MCSymbol *End = RS->getEnd();
+ assert(Begin && "Range without a begin symbol?");
+ assert(End && "Range without an end symbol?");
+ if (Base) {
+ Asm->EmitLabelDifference(Begin, Base, Size);
+ Asm->EmitLabelDifference(End, Base, Size);
+ } else {
+ Asm->OutStreamer->EmitSymbolValue(Begin, Size);
+ Asm->OutStreamer->EmitSymbolValue(End, Size);
+ }
}
}
@@ -1943,7 +2022,7 @@ void DwarfDebug::initSkeletonUnit(const DwarfUnit &U, DIE &Die,
// DW_AT_addr_base, DW_AT_ranges_base.
DwarfCompileUnit &DwarfDebug::constructSkeletonCU(const DwarfCompileUnit &CU) {
- auto OwnedUnit = make_unique<DwarfCompileUnit>(
+ auto OwnedUnit = llvm::make_unique<DwarfCompileUnit>(
CU.getUniqueID(), CU.getCUNode(), Asm, this, &SkeletonHolder);
DwarfCompileUnit &NewCU = *OwnedUnit;
NewCU.setSection(Asm->getObjFileLowering().getDwarfInfoSection());
@@ -2024,8 +2103,8 @@ void DwarfDebug::addDwarfTypeUnitType(DwarfCompileUnit &CU,
bool TopLevelType = TypeUnitsUnderConstruction.empty();
AddrPool.resetUsedFlag();
- auto OwnedUnit = make_unique<DwarfTypeUnit>(CU, Asm, this, &InfoHolder,
- getDwoLineTable(CU));
+ auto OwnedUnit = llvm::make_unique<DwarfTypeUnit>(CU, Asm, this, &InfoHolder,
+ getDwoLineTable(CU));
DwarfTypeUnit &NewTU = *OwnedUnit;
DIE &UnitDie = NewTU.getUnitDie();
TypeUnitsUnderConstruction.emplace_back(std::move(OwnedUnit), CTy);
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 78ee9a162029..2ae0b418a91e 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework ------*- C++ -*--===//
+//===- llvm/CodeGen/DwarfDebug.h - Dwarf Debug Framework --------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,40 +14,52 @@
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
+#include "AddressPool.h"
#include "DbgValueHistoryCalculator.h"
#include "DebugHandlerBase.h"
#include "DebugLocStream.h"
#include "DwarfAccelTable.h"
#include "DwarfFile.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
-#include "llvm/CodeGen/DIE.h"
-#include "llvm/CodeGen/LexicalScopes.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DebugLoc.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/MC/MCDwarf.h"
-#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Target/TargetOptions.h"
+#include <cassert>
+#include <cstdint>
+#include <limits>
#include <memory>
+#include <utility>
+#include <vector>
namespace llvm {
class AsmPrinter;
class ByteStreamer;
-class ConstantInt;
-class ConstantFP;
class DebugLocEntry;
+class DIE;
class DwarfCompileUnit;
-class DwarfDebug;
class DwarfTypeUnit;
class DwarfUnit;
-class MachineModuleInfo;
+class LexicalScope;
+class MachineFunction;
+class MCSection;
+class MCSymbol;
+class MDNode;
+class Module;
//===----------------------------------------------------------------------===//
/// This class is used to track local variable information.
@@ -89,7 +101,7 @@ public:
assert(!MInsn && "Already initialized?");
assert((!E || E->isValid()) && "Expected valid expression");
- assert(FI != INT_MAX && "Expected valid index");
+ assert(FI != std::numeric_limits<int>::max() && "Expected valid index");
FrameIndexExprs.push_back({FI, E});
}
@@ -111,10 +123,12 @@ public:
// Accessors.
const DILocalVariable *getVariable() const { return Var; }
const DILocation *getInlinedAt() const { return IA; }
+
const DIExpression *getSingleExpression() const {
assert(MInsn && FrameIndexExprs.size() <= 1);
return FrameIndexExprs.size() ? FrameIndexExprs[0].Expr : nullptr;
}
+
void setDIE(DIE &D) { TheDIE = &D; }
DIE *getDIE() const { return TheDIE; }
void setDebugLocListIndex(unsigned O) { DebugLocListIndex = O; }
@@ -124,30 +138,7 @@ public:
/// Get the FI entries, sorted by fragment offset.
ArrayRef<FrameIndexExpr> getFrameIndexExprs() const;
bool hasFrameIndexExprs() const { return !FrameIndexExprs.empty(); }
-
- void addMMIEntry(const DbgVariable &V) {
- assert(DebugLocListIndex == ~0U && !MInsn && "not an MMI entry");
- assert(V.DebugLocListIndex == ~0U && !V.MInsn && "not an MMI entry");
- assert(V.Var == Var && "conflicting variable");
- assert(V.IA == IA && "conflicting inlined-at location");
-
- assert(!FrameIndexExprs.empty() && "Expected an MMI entry");
- assert(!V.FrameIndexExprs.empty() && "Expected an MMI entry");
-
- if (FrameIndexExprs.size()) {
- auto *Expr = FrameIndexExprs.back().Expr;
- // Get rid of duplicate non-fragment entries. More than one non-fragment
- // dbg.declare makes no sense so ignore all but the first.
- if (!Expr || !Expr->isFragment())
- return;
- }
- FrameIndexExprs.append(V.FrameIndexExprs.begin(), V.FrameIndexExprs.end());
- assert(all_of(FrameIndexExprs,
- [](FrameIndexExpr &FIE) {
- return FIE.Expr && FIE.Expr->isFragment();
- }) &&
- "conflicting locations for variable");
- }
+ void addMMIEntry(const DbgVariable &V);
// Translate tag to proper Dwarf tag.
dwarf::Tag getTag() const {
@@ -157,6 +148,7 @@ public:
return dwarf::DW_TAG_variable;
}
+
/// Return true if DbgVariable is artificial.
bool isArtificial() const {
if (Var->isArtificial())
@@ -182,6 +174,7 @@ public:
"Invalid Expr for DBG_VALUE");
return !FrameIndexExprs.empty();
}
+
bool isBlockByrefVariable() const;
const DIType *getType() const;
@@ -191,10 +184,10 @@ private:
}
};
-
/// Helper used to pair up a symbol and its DWARF compile unit.
struct SymbolCU {
SymbolCU(DwarfCompileUnit *CU, const MCSymbol *Sym) : Sym(Sym), CU(CU) {}
+
const MCSymbol *Sym;
DwarfCompileUnit *CU;
};
@@ -230,7 +223,7 @@ class DwarfDebug : public DebugHandlerBase {
ProcessedSPNodes;
/// If nonnull, stores the current machine function we're processing.
- const MachineFunction *CurFn;
+ const MachineFunction *CurFn = nullptr;
/// If nonnull, stores the CU in which the previous subprogram was contained.
const DwarfCompileUnit *PrevCU;
@@ -296,17 +289,7 @@ class DwarfDebug : public DebugHandlerBase {
DwarfAccelTable AccelTypes;
// Identify a debugger for "tuning" the debug info.
- DebuggerKind DebuggerTuning;
-
- /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger.
- ///
- /// Returns whether we are "tuning" for a given debugger.
- /// Should be used only within the constructor, to set feature flags.
- /// @{
- bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; }
- bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; }
- bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; }
- /// @}
+ DebuggerKind DebuggerTuning = DebuggerKind::Default;
MCDwarfDwoLineTable *getDwoLineTable(const DwarfCompileUnit &);
@@ -314,7 +297,7 @@ class DwarfDebug : public DebugHandlerBase {
return InfoHolder.getUnits();
}
- typedef DbgValueHistoryMap::InlinedVariable InlinedVariable;
+ using InlinedVariable = DbgValueHistoryMap::InlinedVariable;
void ensureAbstractVariableIsCreated(DwarfCompileUnit &CU, InlinedVariable Var,
const MDNode *Scope);
@@ -358,21 +341,12 @@ class DwarfDebug : public DebugHandlerBase {
/// Emit type dies into a hashed accelerator table.
void emitAccelTypes();
- /// Emit visible names into a debug pubnames section.
- /// \param GnuStyle determines whether or not we want to emit
- /// additional information into the table ala newer gcc for gdb
- /// index.
- void emitDebugPubNames(bool GnuStyle = false);
+ /// Emit visible names and types into debug pubnames and pubtypes sections.
+ void emitDebugPubSections();
- /// Emit visible types into a debug pubtypes section.
- /// \param GnuStyle determines whether or not we want to emit
- /// additional information into the table ala newer gcc for gdb
- /// index.
- void emitDebugPubTypes(bool GnuStyle = false);
-
- void emitDebugPubSection(
- bool GnuStyle, MCSection *PSec, StringRef Name,
- const StringMap<const DIE *> &(DwarfCompileUnit::*Accessor)() const);
+ void emitDebugPubSection(bool GnuStyle, StringRef Name,
+ DwarfCompileUnit *TheU,
+ const StringMap<const DIE *> &Globals);
/// Emit null-terminated strings into a debug str section.
void emitDebugStr();
@@ -561,11 +535,19 @@ public:
/// going to be null.
bool isLexicalScopeDIENull(LexicalScope *Scope);
- bool hasDwarfPubSections(bool includeMinimalInlineScopes) const;
-
/// Find the matching DwarfCompileUnit for the given CU DIE.
DwarfCompileUnit *lookupCU(const DIE *Die) { return CUDieMap.lookup(Die); }
+
+ /// \defgroup DebuggerTuning Predicates to tune DWARF for a given debugger.
+ ///
+ /// Returns whether we are "tuning" for a given debugger.
+ /// @{
+ bool tuneForGDB() const { return DebuggerTuning == DebuggerKind::GDB; }
+ bool tuneForLLDB() const { return DebuggerTuning == DebuggerKind::LLDB; }
+ bool tuneForSCE() const { return DebuggerTuning == DebuggerKind::SCE; }
+ /// @}
};
-} // End of namespace llvm
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFDEBUG_H
diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
index 3a8568cf39ae..68d25fe37b43 100644
--- a/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework ----------===//
+//===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,13 +12,15 @@
//===----------------------------------------------------------------------===//
#include "DwarfExpression.h"
-#include "DwarfDebug.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/BinaryFormat/Dwarf.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include "llvm/Support/ErrorHandling.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
using namespace llvm;
@@ -128,6 +130,8 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
unsigned Size = TRI.getSubRegIdxSize(Idx);
unsigned Offset = TRI.getSubRegIdxOffset(Idx);
Reg = TRI.getDwarfRegNum(*SR, false);
+ if (Reg < 0)
+ continue;
// Intersection between the bits we already emitted and the bits
// covered by this subregister.
@@ -136,14 +140,14 @@ bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
// If this sub-register has a DWARF number and we haven't covered
// its range, emit a DWARF piece for it.
- if (Reg >= 0 && CurSubReg.test(Coverage)) {
+ if (CurSubReg.test(Coverage)) {
// Emit a piece for any gap in the coverage.
if (Offset > CurPos)
DwarfRegs.push_back({-1, Offset - CurPos, nullptr});
DwarfRegs.push_back(
{Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
if (Offset >= MaxSize)
- break;
+ break;
// Mark it as emitted.
Coverage.set(Offset, Offset + Size);
@@ -336,9 +340,10 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
break;
case dwarf::DW_OP_plus:
case dwarf::DW_OP_minus:
+ case dwarf::DW_OP_mul:
emitOp(Op->getOp());
break;
- case dwarf::DW_OP_deref: {
+ case dwarf::DW_OP_deref:
assert(LocationKind != Register);
if (LocationKind != Memory && isMemoryLocation(ExprCursor))
// Turning this into a memory location description makes the deref
@@ -347,7 +352,6 @@ void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
else
emitOp(dwarf::DW_OP_deref);
break;
- }
case dwarf::DW_OP_constu:
assert(LocationKind != Register);
emitOp(dwarf::DW_OP_constu);
@@ -383,7 +387,6 @@ void DwarfExpression::maskSubRegister() {
addAnd(Mask);
}
-
void DwarfExpression::finalize() {
assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
// Emit any outstanding DW_OP_piece operations to mask out subregisters.
diff --git a/lib/CodeGen/AsmPrinter/DwarfExpression.h b/lib/CodeGen/AsmPrinter/DwarfExpression.h
index 728f8ad9225b..ea5cbc40ba35 100644
--- a/lib/CodeGen/AsmPrinter/DwarfExpression.h
+++ b/lib/CodeGen/AsmPrinter/DwarfExpression.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ---*- C++ -*--===//
+//===- llvm/CodeGen/DwarfExpression.h - Dwarf Compile Unit ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -14,21 +14,29 @@
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
-#include "llvm/IR/DebugInfo.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/IR/DebugInfoMetadata.h"
+#include <cassert>
+#include <cstdint>
+#include <iterator>
namespace llvm {
class AsmPrinter;
+class APInt;
class ByteStreamer;
-class TargetRegisterInfo;
class DwarfUnit;
class DIELoc;
+class TargetRegisterInfo;
/// Holds a DIExpression and keeps track of how many operands have been consumed
/// so far.
class DIExpressionCursor {
DIExpression::expr_op_iterator Start, End;
+
public:
DIExpressionCursor(const DIExpression *Expr) {
if (!Expr) {
@@ -42,8 +50,7 @@ public:
DIExpressionCursor(ArrayRef<uint64_t> Expr)
: Start(Expr.begin()), End(Expr.end()) {}
- DIExpressionCursor(const DIExpressionCursor &C)
- : Start(C.Start), End(C.End) {}
+ DIExpressionCursor(const DIExpressionCursor &) = default;
/// Consume one operation.
Optional<DIExpression::ExprOperand> take() {
@@ -73,8 +80,10 @@ public:
return *Next;
}
+
/// Determine whether there are any operations left in this expression.
operator bool() const { return Start != End; }
+
DIExpression::expr_op_iterator begin() const { return Start; }
DIExpression::expr_op_iterator end() const { return End; }
@@ -122,10 +131,13 @@ protected:
/// Output a dwarf operand and an optional assembler comment.
virtual void emitOp(uint8_t Op, const char *Comment = nullptr) = 0;
+
/// Emit a raw signed value.
virtual void emitSigned(int64_t Value) = 0;
+
/// Emit a raw unsigned value.
virtual void emitUnsigned(uint64_t Value) = 0;
+
/// Return whether the given machine register is the frame register in the
/// current function.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
@@ -133,8 +145,10 @@ protected:
/// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
/// register location description.
void addReg(int DwarfReg, const char *Comment = nullptr);
+
/// Emit a DW_OP_breg operation.
void addBReg(int DwarfReg, int Offset);
+
/// Emit DW_OP_fbreg <Offset>.
void addFBReg(int Offset);
@@ -156,7 +170,6 @@ protected:
bool addMachineReg(const TargetRegisterInfo &TRI, unsigned MachineReg,
unsigned MaxSize = ~1U);
-
/// Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
/// \param OffsetInBits This is an optional offset into the location that
/// is at the top of the DWARF stack.
@@ -164,6 +177,7 @@ protected:
/// Emit a shift-right dwarf operation.
void addShr(unsigned ShiftBy);
+
/// Emit a bitwise and dwarf operation.
void addAnd(unsigned Mask);
@@ -181,6 +195,7 @@ protected:
void addStackValue();
~DwarfExpression() = default;
+
public:
DwarfExpression(unsigned DwarfVersion) : DwarfVersion(DwarfVersion) {}
@@ -189,8 +204,10 @@ public:
/// Emit a signed constant.
void addSignedConstant(int64_t Value);
+
/// Emit an unsigned constant.
void addUnsignedConstant(uint64_t Value);
+
/// Emit an unsigned constant.
void addUnsignedConstant(const APInt &Value);
@@ -213,6 +230,7 @@ public:
bool addMachineRegExpression(const TargetRegisterInfo &TRI,
DIExpressionCursor &Expr, unsigned MachineReg,
unsigned FragmentOffsetInBits = 0);
+
/// Emit all remaining operations in the DIExpressionCursor.
///
/// \param FragmentOffsetInBits If this is one fragment out of multiple
@@ -235,6 +253,7 @@ class DebugLocDwarfExpression final : public DwarfExpression {
void emitUnsigned(uint64_t Value) override;
bool isFrameRegister(const TargetRegisterInfo &TRI,
unsigned MachineReg) override;
+
public:
DebugLocDwarfExpression(unsigned DwarfVersion, ByteStreamer &BS)
: DwarfExpression(DwarfVersion), BS(BS) {}
@@ -253,11 +272,13 @@ const AsmPrinter &AP;
unsigned MachineReg) override;
public:
DIEDwarfExpression(const AsmPrinter &AP, DwarfUnit &DU, DIELoc &DIE);
+
DIELoc *finalize() {
DwarfExpression::finalize();
return &DIE;
}
};
-}
-#endif
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFEXPRESSION_H
diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.cpp b/lib/CodeGen/AsmPrinter/DwarfFile.cpp
index 595f1d91c4bf..3c04c969192d 100644
--- a/lib/CodeGen/AsmPrinter/DwarfFile.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfFile.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework ----------------===//
+//===- llvm/CodeGen/DwarfFile.cpp - Dwarf Debug Framework -----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,13 +11,16 @@
#include "DwarfCompileUnit.h"
#include "DwarfDebug.h"
#include "DwarfUnit.h"
-#include "llvm/ADT/STLExtras.h"
-#include "llvm/IR/DataLayout.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/DIE.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/MC/MCStreamer.h"
-#include "llvm/Support/LEB128.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include <algorithm>
+#include <cstdint>
+
+using namespace llvm;
-namespace llvm {
DwarfFile::DwarfFile(AsmPrinter *AP, StringRef Pref, BumpPtrAllocator &DA)
: Asm(AP), Abbrevs(AbbrevAllocator), StrPool(DA, *Asm, Pref) {}
@@ -113,4 +116,3 @@ bool DwarfFile::addScopeVariable(LexicalScope *LS, DbgVariable *Var) {
Vars.push_back(Var);
return true;
}
-}
diff --git a/lib/CodeGen/AsmPrinter/DwarfFile.h b/lib/CodeGen/AsmPrinter/DwarfFile.h
index 54924e9806ed..167ca13c19c1 100644
--- a/lib/CodeGen/AsmPrinter/DwarfFile.h
+++ b/lib/CodeGen/AsmPrinter/DwarfFile.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework -------*- C++ -*--===//
+//===- llvm/CodeGen/DwarfFile.h - Dwarf Debug Framework ---------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -10,30 +10,25 @@
#ifndef LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H
-#include "AddressPool.h"
#include "DwarfStringPool.h"
#include "llvm/ADT/DenseMap.h"
-#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/IR/Metadata.h"
#include "llvm/Support/Allocator.h"
#include <memory>
+#include <utility>
namespace llvm {
+
class AsmPrinter;
class DbgVariable;
class DwarfCompileUnit;
class DwarfUnit;
-class DIEAbbrev;
-class MCSymbol;
-class DIE;
class LexicalScope;
-class StringRef;
-class DwarfDebug;
class MCSection;
-class MDNode;
+
class DwarfFile {
// Target of Dwarf emission, used for sizing of abbreviations.
AsmPrinter *Asm;
@@ -106,6 +101,7 @@ public:
DenseMap<const MDNode *, DIE *> &getAbstractSPDies() {
return AbstractSPDies;
}
+
DenseMap<const MDNode *, std::unique_ptr<DbgVariable>> &getAbstractVariables() {
return AbstractVariables;
}
@@ -113,9 +109,12 @@ public:
void insertDIE(const MDNode *TypeMD, DIE *Die) {
DITypeNodeToDieMap.insert(std::make_pair(TypeMD, Die));
}
+
DIE *getDIE(const MDNode *TypeMD) {
return DITypeNodeToDieMap.lookup(TypeMD);
}
};
-}
-#endif
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFFILE_H
diff --git a/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp b/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
index 2066f745e318..aa5f01e88933 100644
--- a/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfStringPool.cpp
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework ----------===//
+//===- llvm/CodeGen/DwarfStringPool.cpp - Dwarf Debug Framework -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -8,9 +8,14 @@
//===----------------------------------------------------------------------===//
#include "DwarfStringPool.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCStreamer.h"
+#include <cassert>
+#include <utility>
using namespace llvm;
diff --git a/lib/CodeGen/AsmPrinter/DwarfStringPool.h b/lib/CodeGen/AsmPrinter/DwarfStringPool.h
index 93a168485a54..1cac3b7c8432 100644
--- a/lib/CodeGen/AsmPrinter/DwarfStringPool.h
+++ b/lib/CodeGen/AsmPrinter/DwarfStringPool.h
@@ -1,4 +1,4 @@
-//===-- llvm/CodeGen/DwarfStringPool.h - Dwarf Debug Framework -*- C++ -*--===//
+//===- llvm/CodeGen/DwarfStringPool.h - Dwarf Debug Framework ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -11,29 +11,28 @@
#define LLVM_LIB_CODEGEN_ASMPRINTER_DWARFSTRINGPOOL_H
#include "llvm/ADT/StringMap.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
#include "llvm/Support/Allocator.h"
-#include <utility>
namespace llvm {
class AsmPrinter;
-class MCSymbol;
class MCSection;
-class StringRef;
// Collection of strings for this unit and assorted symbols.
// A String->Symbol mapping of strings used by indirect
// references.
class DwarfStringPool {
- typedef DwarfStringPoolEntry EntryTy;
+ using EntryTy = DwarfStringPoolEntry;
+
StringMap<EntryTy, BumpPtrAllocator &> Pool;
StringRef Prefix;
unsigned NumBytes = 0;
bool ShouldCreateSymbols;
public:
- typedef DwarfStringPoolEntryRef EntryRef;
+ using EntryRef = DwarfStringPoolEntryRef;
DwarfStringPool(BumpPtrAllocator &A, AsmPrinter &Asm, StringRef Prefix);
@@ -45,5 +44,7 @@ public:
/// Get a reference to an entry in the string pool.
EntryRef getEntry(AsmPrinter &Asm, StringRef Str);
};
-}
-#endif
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_DWARFSTRINGPOOL_H
diff --git a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 4f4ebfc56297..911e46235781 100644
--- a/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -22,6 +22,9 @@
#include "llvm/ADT/iterator_range.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetRegisterInfo.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/GlobalValue.h"
@@ -33,9 +36,6 @@
#include "llvm/MC/MachineLocation.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
#include <cassert>
#include <cstdint>
#include <string>
@@ -473,11 +473,7 @@ void DwarfUnit::addBlockByrefAddress(const DbgVariable &DV, DIE &Die,
if (Location.isIndirect())
DwarfExpr.setMemoryLocationKind();
- SmallVector<uint64_t, 9> Ops;
- if (Location.isIndirect() && Location.getOffset()) {
- Ops.push_back(dwarf::DW_OP_plus_uconst);
- Ops.push_back(Location.getOffset());
- }
+ SmallVector<uint64_t, 6> Ops;
// If we started with a pointer to the __Block_byref... struct, then
// the first thing we need to do is dereference the pointer (DW_OP_deref).
if (isPointer)
@@ -964,8 +960,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
// 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.
- if (auto *ContainingType =
- dyn_cast_or_null<DICompositeType>(resolve(CTy->getVTableHolder())))
+ // Rust uses DW_AT_containing_type to link a vtable to the type
+ // for which it was created.
+ if (auto *ContainingType = resolve(CTy->getVTableHolder()))
addDIEEntry(Buffer, dwarf::DW_AT_containing_type,
*getOrCreateTypeDIE(ContainingType));
diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.cpp b/lib/CodeGen/AsmPrinter/EHStreamer.cpp
index e14d5be1177a..3cdab57bca70 100644
--- a/lib/CodeGen/AsmPrinter/EHStreamer.cpp
+++ b/lib/CodeGen/AsmPrinter/EHStreamer.cpp
@@ -1,4 +1,4 @@
-//===-- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer --===//
+//===- CodeGen/AsmPrinter/EHStreamer.cpp - Exception Directive Streamer ---===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,22 +12,34 @@
//===----------------------------------------------------------------------===//
#include "EHStreamer.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/BinaryFormat/Dwarf.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/MachineOperand.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCTargetOptions.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <vector>
using namespace llvm;
EHStreamer::EHStreamer(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
-EHStreamer::~EHStreamer() {}
+EHStreamer::~EHStreamer() = default;
/// How many leading type ids two landing pads have in common.
unsigned EHStreamer::sharedTypeIDs(const LandingPadInfo *L,
@@ -50,7 +62,6 @@ unsigned EHStreamer::
computeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
SmallVectorImpl<ActionEntry> &Actions,
SmallVectorImpl<unsigned> &FirstActions) {
-
// The action table follows the call-site table in the LSDA. The individual
// records are of two types:
//
@@ -478,13 +489,14 @@ void EHStreamer::emitExceptionTable() {
sizeof(int8_t) + // TType format
(HaveTTData ? TTypeBaseOffsetSize : 0) + // TType base offset size
TTypeBaseOffset; // TType base offset
- unsigned SizeAlign = (4 - TotalSize) & 3;
+ unsigned PadBytes = (4 - TotalSize) & 3;
if (HaveTTData) {
// Account for any extra padding that will be added to the call site table
// length.
- Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
- SizeAlign = 0;
+ Asm->EmitPaddedULEB128(TTypeBaseOffset, TTypeBaseOffsetSize + PadBytes,
+ "@TType base offset");
+ PadBytes = 0;
}
bool VerboseAsm = Asm->OutStreamer->isVerboseAsm();
@@ -494,7 +506,9 @@ void EHStreamer::emitExceptionTable() {
Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
// Add extra padding if it wasn't added to the TType base offset.
- Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
+ Asm->EmitPaddedULEB128(CallSiteTableLength,
+ CallSiteTableLengthSize + PadBytes,
+ "Call site table length");
// Emit the landing pad site information.
unsigned idx = 0;
@@ -547,7 +561,9 @@ void EHStreamer::emitExceptionTable() {
Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
// Add extra padding if it wasn't added to the TType base offset.
- Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
+ Asm->EmitPaddedULEB128(CallSiteTableLength,
+ CallSiteTableLengthSize + PadBytes,
+ "Call site table length");
unsigned Entry = 0;
for (SmallVectorImpl<CallSiteEntry>::const_iterator
diff --git a/lib/CodeGen/AsmPrinter/EHStreamer.h b/lib/CodeGen/AsmPrinter/EHStreamer.h
index 080fdd14b467..7962b761d8de 100644
--- a/lib/CodeGen/AsmPrinter/EHStreamer.h
+++ b/lib/CodeGen/AsmPrinter/EHStreamer.h
@@ -1,4 +1,4 @@
-//===-- EHStreamer.h - Exception Handling Directive Streamer ---*- C++ -*--===//
+//===- EHStreamer.h - Exception Handling Directive Streamer -----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -16,17 +16,16 @@
#include "AsmPrinterHandler.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/Support/Compiler.h"
namespace llvm {
+
+class AsmPrinter;
struct LandingPadInfo;
-class MachineModuleInfo;
class MachineInstr;
-class MachineFunction;
+class MachineModuleInfo;
class MCSymbol;
-class MCSymbolRefExpr;
-
-template <typename T>
-class SmallVectorImpl;
+template <typename T> class SmallVectorImpl;
/// Emits exception handling directives.
class LLVM_LIBRARY_VISIBILITY EHStreamer : public AsmPrinterHandler {
@@ -45,11 +44,12 @@ protected:
struct PadRange {
// The index of the landing pad.
unsigned PadIndex;
+
// The index of the begin and end labels in the landing pad's label lists.
unsigned RangeIndex;
};
- typedef DenseMap<MCSymbol *, PadRange> RangeMapType;
+ using RangeMapType = DenseMap<MCSymbol *, PadRange>;
/// Structure describing an entry in the actions table.
struct ActionEntry {
@@ -66,6 +66,7 @@ protected:
// LPad contains the landing pad start labels.
const LandingPadInfo *LPad; // Null indicates that there is no landing pad.
+
unsigned Action;
};
@@ -131,7 +132,7 @@ public:
/// `false' otherwise.
static bool callToNoUnwindFunction(const MachineInstr *MI);
};
-}
-#endif
+} // end namespace llvm
+#endif // LLVM_LIB_CODEGEN_ASMPRINTER_EHSTREAMER_H
diff --git a/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp b/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
index c5795559fb7d..e459c02c9a6e 100644
--- a/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/ErlangGCPrinter.cpp
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/GCStrategy.h"
#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Module.h"
@@ -26,7 +27,6 @@
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
using namespace llvm;
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index 035f1a0063aa..e0cc241dd23f 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -11,13 +11,14 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/CodeGen/GCs.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Mangler.h"
@@ -26,7 +27,6 @@
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include <cctype>
#include <cstddef>
#include <cstdint>
diff --git a/lib/CodeGen/AsmPrinter/WinException.cpp b/lib/CodeGen/AsmPrinter/WinException.cpp
index 5d485f213573..a6a8e84a949f 100644
--- a/lib/CodeGen/AsmPrinter/WinException.cpp
+++ b/lib/CodeGen/AsmPrinter/WinException.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "WinException.h"
-#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Twine.h"
#include "llvm/BinaryFormat/COFF.h"
#include "llvm/BinaryFormat/Dwarf.h"
@@ -20,6 +19,10 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/CodeGen/TargetFrameLowering.h"
+#include "llvm/CodeGen/TargetLowering.h"
+#include "llvm/CodeGen/TargetLoweringObjectFile.h"
+#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/WinEHFuncInfo.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Mangler.h"
@@ -30,15 +33,9 @@
#include "llvm/MC/MCSection.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
-#include "llvm/MC/MCWin64EH.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Target/TargetFrameLowering.h"
-#include "llvm/Target/TargetLowering.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm;
WinException::WinException(AsmPrinter *A) : EHStreamer(A) {
@@ -66,7 +63,7 @@ void WinException::beginFunction(const MachineFunction *MF) {
bool hasLandingPads = !MF->getLandingPads().empty();
bool hasEHFunclets = MF->hasEHFunclets();
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
shouldEmitMoves = Asm->needsSEHMoves() && MF->hasWinCFI();
@@ -75,14 +72,14 @@ void WinException::beginFunction(const MachineFunction *MF) {
EHPersonality Per = EHPersonality::Unknown;
const Function *PerFn = nullptr;
- if (F->hasPersonalityFn()) {
- PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ if (F.hasPersonalityFn()) {
+ PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
Per = classifyEHPersonality(PerFn);
}
- bool forceEmitPersonality = F->hasPersonalityFn() &&
+ bool forceEmitPersonality = F.hasPersonalityFn() &&
!isNoOpWithoutInvoke(Per) &&
- F->needsUnwindTableEntry();
+ F.needsUnwindTableEntry();
shouldEmitPersonality =
forceEmitPersonality || ((hasLandingPads || hasEHFunclets) &&
@@ -101,7 +98,7 @@ void WinException::beginFunction(const MachineFunction *MF) {
// functions may still refer to it.
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
StringRef FLinkageName =
- GlobalValue::dropLLVMManglingEscape(MF->getFunction()->getName());
+ GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName());
emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
}
shouldEmitLSDA = hasEHFunclets;
@@ -118,10 +115,10 @@ void WinException::endFunction(const MachineFunction *MF) {
if (!shouldEmitPersonality && !shouldEmitMoves && !shouldEmitLSDA)
return;
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
EHPersonality Per = EHPersonality::Unknown;
- if (F->hasPersonalityFn())
- Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts());
+ if (F.hasPersonalityFn())
+ Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
// Get rid of any dead landing pads if we're not using funclets. In funclet
// schemes, the landing pad is not actually reachable. It only exists so
@@ -173,8 +170,8 @@ static MCSymbol *getMCSymbolForMBB(AsmPrinter *Asm,
// Give catches and cleanups a name based off of their parent function and
// their funclet entry block's number.
const MachineFunction *MF = MBB->getParent();
- const Function *F = MF->getFunction();
- StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName());
+ const Function &F = MF->getFunction();
+ StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
MCContext &Ctx = MF->getContext();
StringRef HandlerPrefix = MBB->isCleanupFuncletEntry() ? "dtor" : "catch";
return Ctx.getOrCreateSymbol("?" + HandlerPrefix + "$" +
@@ -186,7 +183,7 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB,
MCSymbol *Sym) {
CurrentFuncletEntry = &MBB;
- const Function *F = Asm->MF->getFunction();
+ const Function &F = Asm->MF->getFunction();
// If a symbol was not provided for the funclet, invent one.
if (!Sym) {
Sym = getMCSymbolForMBB(Asm, &MBB);
@@ -201,7 +198,7 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB,
// We want our funclet's entry point to be aligned such that no nops will be
// present after the label.
Asm->EmitAlignment(std::max(Asm->MF->getAlignment(), MBB.getAlignment()),
- F);
+ &F);
// Now that we've emitted the alignment directive, point at our funclet.
Asm->OutStreamer->EmitLabel(Sym);
@@ -218,8 +215,8 @@ void WinException::beginFunclet(const MachineBasicBlock &MBB,
const Function *PerFn = nullptr;
// Determine which personality routine we are using for this funclet.
- if (F->hasPersonalityFn())
- PerFn = dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ if (F.hasPersonalityFn())
+ PerFn = dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
const MCSymbol *PersHandlerSym =
TLOF.getCFIPersonalitySymbol(PerFn, Asm->TM, MMI);
@@ -240,10 +237,10 @@ void WinException::endFunclet() {
const MachineFunction *MF = Asm->MF;
if (shouldEmitMoves || shouldEmitPersonality) {
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
EHPersonality Per = EHPersonality::Unknown;
- if (F->hasPersonalityFn())
- Per = classifyEHPersonality(F->getPersonalityFn()->stripPointerCasts());
+ if (F.hasPersonalityFn())
+ Per = classifyEHPersonality(F.getPersonalityFn()->stripPointerCasts());
// Emit an UNWIND_INFO struct describing the prologue.
Asm->OutStreamer->EmitWinEHHandlerData();
@@ -252,7 +249,7 @@ void WinException::endFunclet() {
!CurrentFuncletEntry->isCleanupFuncletEntry()) {
// If this is a C++ catch funclet (or the parent function),
// emit a reference to the LSDA for the parent function.
- StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName());
+ StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
MCSymbol *FuncInfoXData = Asm->OutContext.getOrCreateSymbol(
Twine("$cppxdata$", FuncLinkageName));
Asm->OutStreamer->EmitValue(create32bitRef(FuncInfoXData), 4);
@@ -536,7 +533,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
// Emit a label assignment with the SEH frame offset so we can use it for
// llvm.x86.seh.recoverfp.
StringRef FLinkageName =
- GlobalValue::dropLLVMManglingEscape(MF->getFunction()->getName());
+ GlobalValue::dropLLVMManglingEscape(MF->getFunction().getName());
MCSymbol *ParentFrameOffset =
Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
const MCExpr *MCOffset =
@@ -631,11 +628,11 @@ void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
}
void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
- const Function *F = MF->getFunction();
+ const Function &F = MF->getFunction();
auto &OS = *Asm->OutStreamer;
const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
- StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName());
+ StringRef FuncLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
SmallVector<std::pair<const MCExpr *, int>, 4> IPToStateTable;
MCSymbol *FuncInfoXData = nullptr;
@@ -941,8 +938,8 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
/// indexed by state number instead of IP.
void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
MCStreamer &OS = *Asm->OutStreamer;
- const Function *F = MF->getFunction();
- StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F->getName());
+ const Function &F = MF->getFunction();
+ StringRef FLinkageName = GlobalValue::dropLLVMManglingEscape(F.getName());
bool VerboseAsm = OS.isVerboseAsm();
auto AddComment = [&](const Twine &Comment) {
@@ -959,7 +956,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
OS.EmitLabel(LSDALabel);
const Function *Per =
- dyn_cast<Function>(F->getPersonalityFn()->stripPointerCasts());
+ dyn_cast<Function>(F.getPersonalityFn()->stripPointerCasts());
StringRef PerName = Per->getName();
int BaseState = -1;
if (PerName == "_except_handler4") {