"Attach debug info with llvm instructions" mode was enabled a month ago. Now make it permanent and remove old way of inserting intrinsics to encode debug info for line number and scopes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@87014 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index f7c8d29..89daec85 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -1388,32 +1388,6 @@
return AScope;
}
-/// getOrCreateScope - Returns the scope associated with the given descriptor.
-/// FIXME - Remove this method.
-DbgScope *DwarfDebug::getOrCreateScope(MDNode *N) {
- DbgScope *&Slot = DbgScopeMap[N];
- if (Slot) return Slot;
-
- DbgScope *Parent = NULL;
- DILexicalBlock Block(N);
-
- if (!Block.isNull()) {
- DIDescriptor ParentDesc = Block.getContext();
- Parent =
- ParentDesc.isNull() ? NULL : getOrCreateScope(ParentDesc.getNode());
- }
-
- Slot = new DbgScope(Parent, DIDescriptor(N));
-
- if (Parent)
- Parent->AddScope(Slot);
- else
- // First function is top level function.
- CurrentFnDbgScope = Slot;
-
- return Slot;
-}
-
static DISubprogram getDISubprogram(MDNode *N) {
DIDescriptor D(N);
@@ -1644,129 +1618,6 @@
return ScopeDIE;
}
-/// ConstructDbgScope - Construct the components of a scope.
-/// FIXME: Remove
-void DwarfDebug::ConstructDbgScope(DbgScope *ParentScope,
- unsigned ParentStartID,
- unsigned ParentEndID,
- DIE *ParentDie, CompileUnit *Unit) {
- // Add variables to scope.
- SmallVector<DbgVariable *, 8> &Variables = ParentScope->getVariables();
- for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
- DIE *VariableDie = CreateDbgScopeVariable(Variables[i], Unit);
- if (VariableDie) ParentDie->AddChild(VariableDie);
- }
-
- // Add nested scopes.
- SmallVector<DbgScope *, 4> &Scopes = ParentScope->getScopes();
- for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
- // Define the Scope debug information entry.
- DbgScope *Scope = Scopes[j];
-
- unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID());
- unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID());
-
- // Ignore empty scopes.
- if (StartID == EndID && StartID != 0) continue;
-
- // Do not ignore inlined scopes even if they don't have any variables or
- // scopes.
- if (Scope->getScopes().empty() && Scope->getVariables().empty())
- continue;
-
- if (StartID == ParentStartID && EndID == ParentEndID) {
- // Just add stuff to the parent scope.
- ConstructDbgScope(Scope, ParentStartID, ParentEndID, ParentDie, Unit);
- } else {
- DIE *ScopeDie = new DIE(dwarf::DW_TAG_lexical_block);
-
- // Add the scope bounds.
- if (StartID)
- AddLabel(ScopeDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- DWLabel("label", StartID));
- else
- AddLabel(ScopeDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- DWLabel("func_begin", SubprogramCount));
-
- if (EndID)
- AddLabel(ScopeDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- DWLabel("label", EndID));
- else
- AddLabel(ScopeDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- DWLabel("func_end", SubprogramCount));
-
- // Add the scope's contents.
- ConstructDbgScope(Scope, StartID, EndID, ScopeDie, Unit);
- ParentDie->AddChild(ScopeDie);
- }
- }
-}
-
-/// ConstructCurrentFnDbgScope - Construct the scope for the subprogram.
-/// FIXME: Remove
-void DwarfDebug::ConstructCurrentFnDbgScope(DbgScope *RootScope,
- bool AbstractScope) {
- // Exit if there is no root scope.
- if (!RootScope) return;
- DIDescriptor Desc = RootScope->getDesc();
- if (Desc.isNull())
- return;
-
- // Get the subprogram debug information entry.
- DISubprogram SPD(Desc.getNode());
-
- // Get the subprogram die.
- DIE *SPDie = ModuleCU->getDieMapSlotFor(SPD.getNode());
- if (!SPDie) {
- ConstructSubprogram(SPD.getNode());
- SPDie = ModuleCU->getDieMapSlotFor(SPD.getNode());
- }
- assert(SPDie && "Missing subprogram descriptor");
-
- if (!AbstractScope) {
- // Add the function bounds.
- AddLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- DWLabel("func_begin", SubprogramCount));
- AddLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- DWLabel("func_end", SubprogramCount));
- MachineLocation Location(RI->getFrameRegister(*MF));
- AddAddress(SPDie, dwarf::DW_AT_frame_base, Location);
- }
-
- ConstructDbgScope(RootScope, 0, 0, SPDie, ModuleCU);
- // If there are global variables at this scope then add their dies.
- for (SmallVector<WeakVH, 4>::iterator SGI = ScopedGVs.begin(),
- SGE = ScopedGVs.end(); SGI != SGE; ++SGI) {
- MDNode *N = dyn_cast_or_null<MDNode>(*SGI);
- if (!N) continue;
- DIGlobalVariable GV(N);
- if (GV.getContext().getNode() == RootScope->getDesc().getNode()) {
- DIE *ScopedGVDie = CreateGlobalVariableDIE(ModuleCU, GV);
- if (ScopedGVDie)
- SPDie->AddChild(ScopedGVDie);
- }
- }
-}
-
-/// ConstructDefaultDbgScope - Construct a default scope for the subprogram.
-/// FIXME: Remove
-void DwarfDebug::ConstructDefaultDbgScope(MachineFunction *MF) {
- StringMap<DIE*> &Globals = ModuleCU->getGlobals();
- StringMap<DIE*>::iterator GI = Globals.find(MF->getFunction()->getName());
- if (GI != Globals.end()) {
- DIE *SPDie = GI->second;
-
- // Add the function bounds.
- AddLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- DWLabel("func_begin", SubprogramCount));
- AddLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- DWLabel("func_end", SubprogramCount));
-
- MachineLocation Location(RI->getFrameRegister(*MF));
- AddAddress(SPDie, dwarf::DW_AT_frame_base, Location);
- }
-}
-
/// GetOrCreateSourceID - Look up the source id with the given directory and
/// source file names. If none currently exists, create a new id and insert it
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
@@ -2241,11 +2092,9 @@
if (TimePassesIsEnabled)
DebugTimer->startTimer();
-#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
if (!ExtractScopeInformation(MF))
return;
CollectVariableInfo();
-#endif
// Begin accumulating function debug information.
MMI->BeginFunction(MF);
@@ -2255,7 +2104,6 @@
// Emit label for the implicitly defined dbg.stoppoint at the start of the
// function.
-#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
DebugLoc FDL = MF->getDefaultDebugLoc();
if (!FDL.isUnknown()) {
DebugLocTuple DLT = MF->getDebugLocTuple(FDL);
@@ -2268,15 +2116,6 @@
Asm->printLabel(LabelID);
O << '\n';
}
-#else
- DebugLoc FDL = MF->getDefaultDebugLoc();
- if (!FDL.isUnknown()) {
- DebugLocTuple DLT = MF->getDebugLocTuple(FDL);
- unsigned LabelID = RecordSourceLine(DLT.Line, DLT.Col, DLT.Scope);
- Asm->printLabel(LabelID);
- O << '\n';
- }
-#endif
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
}
@@ -2289,10 +2128,9 @@
if (TimePassesIsEnabled)
DebugTimer->startTimer();
-#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
if (DbgScopeMap.empty())
return;
-#endif
+
// Define end label for subprogram.
EmitLabel("func_end", SubprogramCount);
@@ -2307,28 +2145,13 @@
Lines.begin(), Lines.end());
}
-#ifndef ATTACH_DEBUG_INFO_TO_AN_INSN
- // Construct scopes for subprogram.
- if (CurrentFnDbgScope)
- ConstructCurrentFnDbgScope(CurrentFnDbgScope);
- else
- // FIXME: This is wrong. We are essentially getting past a problem with
- // debug information not being able to handle unreachable blocks that have
- // debug information in them. In particular, those unreachable blocks that
- // have "region end" info in them. That situation results in the "root
- // scope" not being created. If that's the case, then emit a "default"
- // scope, i.e., one that encompasses the whole function. This isn't
- // desirable. And a better way of handling this (and all of the debugging
- // information) needs to be explored.
- ConstructDefaultDbgScope(MF);
-#else
// Construct abstract scopes.
for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
AE = AbstractScopesList.end(); AI != AE; ++AI)
ConstructScopeDIE(*AI);
ConstructScopeDIE(CurrentFnDbgScope);
-#endif
+
DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
MMI->getFrameMoves()));
@@ -2406,59 +2229,6 @@
return SrcId;
}
-/// RecordRegionStart - Indicate the start of a region.
-unsigned DwarfDebug::RecordRegionStart(MDNode *N) {
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- DbgScope *Scope = getOrCreateScope(N);
- unsigned ID = MMI->NextLabelID();
- if (!Scope->getStartLabelID()) Scope->setStartLabelID(ID);
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-
- return ID;
-}
-
-/// RecordRegionEnd - Indicate the end of a region.
-unsigned DwarfDebug::RecordRegionEnd(MDNode *N) {
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- DbgScope *Scope = getOrCreateScope(N);
- unsigned ID = MMI->NextLabelID();
- Scope->setEndLabelID(ID);
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-
- return ID;
-}
-
-/// RecordVariable - Indicate the declaration of a local variable.
-void DwarfDebug::RecordVariable(MDNode *N, unsigned FrameIndex) {
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- DIDescriptor Desc(N);
- DbgScope *Scope = NULL;
-
- if (Desc.getTag() == dwarf::DW_TAG_variable)
- Scope = getOrCreateScope(DIGlobalVariable(N).getContext().getNode());
- else {
- MDNode *Context = DIVariable(N).getContext().getNode();
- Scope = getOrCreateScope(Context);
- }
-
- assert(Scope && "Unable to find the variable's scope");
- DbgVariable *DV = new DbgVariable(DIVariable(N), FrameIndex);
- Scope->AddVariable(DV);
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-}
-
//===----------------------------------------------------------------------===//
// Emit Methods
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 8694264..ec77245 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -367,7 +367,7 @@
/// createDbgScope - Create DbgScope for the scope.
void createDbgScope(MDNode *Scope, MDNode *InlinedAt);
- DbgScope *getOrCreateScope(MDNode *N);
+
DbgScope *getOrCreateAbstractScope(MDNode *N);
/// findAbstractVariable - Find abstract variable associated with Var.
@@ -386,15 +386,6 @@
unsigned ParentStartID, unsigned ParentEndID,
DIE *ParentDie, CompileUnit *Unit);
- /// ConstructCurrentFnDbgScope - Construct the scope for the subprogram.
- ///
- void ConstructCurrentFnDbgScope(DbgScope *RootScope,
- bool AbstractScope = false);
-
- /// ConstructDefaultDbgScope - Construct a default scope for the subprogram.
- ///
- void ConstructDefaultDbgScope(MachineFunction *MF);
-
/// EmitInitial - Emit initial Dwarf declarations. This is necessary for cc
/// tools to recognize the object file contains Dwarf information.
void EmitInitial();
@@ -549,15 +540,6 @@
unsigned getOrCreateSourceID(const std::string &DirName,
const std::string &FileName);
- /// RecordRegionStart - Indicate the start of a region.
- unsigned RecordRegionStart(MDNode *N);
-
- /// RecordRegionEnd - Indicate the end of a region.
- unsigned RecordRegionEnd(MDNode *N);
-
- /// RecordVariable - Indicate the declaration of a local variable.
- void RecordVariable(MDNode *N, unsigned FrameIndex);
-
/// ExtractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if atleast one scope was found.
bool ExtractScopeInformation(MachineFunction *MF);
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index 41da4df..63ae653 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -81,27 +81,11 @@
return DD->RecordSourceLine(Line, Col, Scope);
}
-/// RecordRegionStart - Indicate the start of a region.
-unsigned DwarfWriter::RecordRegionStart(MDNode *N) {
- return DD->RecordRegionStart(N);
-}
-
-/// RecordRegionEnd - Indicate the end of a region.
-unsigned DwarfWriter::RecordRegionEnd(MDNode *N) {
- return DD->RecordRegionEnd(N);
-}
-
/// getRecordSourceLineCount - Count source lines.
unsigned DwarfWriter::getRecordSourceLineCount() {
return DD->getRecordSourceLineCount();
}
-/// RecordVariable - Indicate the declaration of a local variable.
-///
-void DwarfWriter::RecordVariable(MDNode *N, unsigned FrameIndex) {
- DD->RecordVariable(N, FrameIndex);
-}
-
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
/// be emitted.
bool DwarfWriter::ShouldEmitDwarfDebug() const {
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index b62803f..4b067a0 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -76,9 +76,7 @@
FilterEnds.clear();
CallsEHReturn = 0;
CallsUnwindInit = 0;
-#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
VariableDbgInfo.clear();
-#endif
}
/// AnalyzeModule - Scan the module for global debug information.
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 72fa3a9..7dbc136 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -325,48 +325,12 @@
unsigned IID = F->getIntrinsicID();
switch (IID) {
default: break;
- case Intrinsic::dbg_stoppoint: {
- DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
- if (isValidDebugInfoIntrinsic(*SPI, CodeGenOpt::None))
- setCurDebugLoc(ExtractDebugLocation(*SPI, MF.getDebugLocInfo()));
+ case Intrinsic::dbg_stoppoint:
+ case Intrinsic::dbg_region_start:
+ case Intrinsic::dbg_region_end:
+ case Intrinsic::dbg_func_start:
+ // FIXME - Remove this instructions once the dust settles.
return true;
- }
- case Intrinsic::dbg_region_start: {
- DbgRegionStartInst *RSI = cast<DbgRegionStartInst>(I);
- if (isValidDebugInfoIntrinsic(*RSI, CodeGenOpt::None) && DW
- && DW->ShouldEmitDwarfDebug()) {
- unsigned ID =
- DW->RecordRegionStart(RSI->getContext());
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- BuildMI(MBB, DL, II).addImm(ID);
- }
- return true;
- }
- case Intrinsic::dbg_region_end: {
- DbgRegionEndInst *REI = cast<DbgRegionEndInst>(I);
- if (isValidDebugInfoIntrinsic(*REI, CodeGenOpt::None) && DW
- && DW->ShouldEmitDwarfDebug()) {
- unsigned ID = 0;
- DISubprogram Subprogram(REI->getContext());
- const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL);
- ID = DW->RecordRegionEnd(REI->getContext());
- BuildMI(MBB, DL, II).addImm(ID);
- }
- return true;
- }
- case Intrinsic::dbg_func_start: {
- DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
- if (!isValidDebugInfoIntrinsic(*FSI, CodeGenOpt::None) || !DW
- || !DW->ShouldEmitDwarfDebug())
- return true;
-
- // This is a beginning of a new function.
- MF.setDefaultDebugLoc(ExtractDebugLocation(*FSI, MF.getDebugLocInfo()));
-
- // llvm.dbg.func_start also defines beginning of function scope.
- DW->RecordRegionStart(FSI->getSubprogram());
- return true;
- }
case Intrinsic::dbg_declare: {
DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
if (!isValidDebugInfoIntrinsic(*DI, CodeGenOpt::None) || !DW
@@ -390,9 +354,6 @@
MDNode *Dbg = TheMetadata.getMD(MDDbgKind, DI);
MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
}
-#ifndef ATTACH_DEBUG_INFO_TO_AN_INSN
- DW->RecordVariable(DI->getVariable(), FI);
-#endif
return true;
}
case Intrinsic::eh_exception: {
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
index f74d6ae..612d28e 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
@@ -335,25 +335,6 @@
DebugLoc DL;
for (BasicBlock::iterator
I = BB->begin(), E = BB->end(); I != E; ++I) {
- if (CallInst *CI = dyn_cast<CallInst>(I)) {
- if (Function *F = CI->getCalledFunction()) {
- switch (F->getIntrinsicID()) {
- default: break;
- case Intrinsic::dbg_stoppoint: {
- DbgStopPointInst *SPI = cast<DbgStopPointInst>(I);
- if (isValidDebugInfoIntrinsic(*SPI, CodeGenOpt::Default))
- DL = ExtractDebugLocation(*SPI, MF->getDebugLocInfo());
- break;
- }
- case Intrinsic::dbg_func_start: {
- DbgFuncStartInst *FSI = cast<DbgFuncStartInst>(I);
- if (isValidDebugInfoIntrinsic(*FSI, CodeGenOpt::Default))
- DL = ExtractDebugLocation(*FSI, MF->getDebugLocInfo());
- break;
- }
- }
- }
- }
PN = dyn_cast<PHINode>(I);
if (!PN || PN->use_empty()) continue;
@@ -3930,64 +3911,12 @@
I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
- case Intrinsic::dbg_stoppoint: {
- DbgStopPointInst &SPI = cast<DbgStopPointInst>(I);
- if (isValidDebugInfoIntrinsic(SPI, CodeGenOpt::Default)) {
- MachineFunction &MF = DAG.getMachineFunction();
- DebugLoc Loc = ExtractDebugLocation(SPI, MF.getDebugLocInfo());
- setCurDebugLoc(Loc);
-
- if (OptLevel == CodeGenOpt::None)
- DAG.setRoot(DAG.getDbgStopPoint(Loc, getRoot(),
- SPI.getLine(),
- SPI.getColumn(),
- SPI.getContext()));
- }
+ case Intrinsic::dbg_stoppoint:
+ case Intrinsic::dbg_region_start:
+ case Intrinsic::dbg_region_end:
+ case Intrinsic::dbg_func_start:
+ // FIXME - Remove this instructions once the dust settles.
return 0;
- }
- case Intrinsic::dbg_region_start: {
- DwarfWriter *DW = DAG.getDwarfWriter();
- DbgRegionStartInst &RSI = cast<DbgRegionStartInst>(I);
- if (isValidDebugInfoIntrinsic(RSI, OptLevel) && DW
- && DW->ShouldEmitDwarfDebug()) {
- unsigned LabelID =
- DW->RecordRegionStart(RSI.getContext());
- DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
- getRoot(), LabelID));
- }
- return 0;
- }
- case Intrinsic::dbg_region_end: {
- DwarfWriter *DW = DAG.getDwarfWriter();
- DbgRegionEndInst &REI = cast<DbgRegionEndInst>(I);
-
- if (!isValidDebugInfoIntrinsic(REI, OptLevel) || !DW
- || !DW->ShouldEmitDwarfDebug())
- return 0;
-
- DISubprogram Subprogram(REI.getContext());
-
- unsigned LabelID =
- DW->RecordRegionEnd(REI.getContext());
- DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getCurDebugLoc(),
- getRoot(), LabelID));
- return 0;
- }
- case Intrinsic::dbg_func_start: {
- DwarfWriter *DW = DAG.getDwarfWriter();
- DbgFuncStartInst &FSI = cast<DbgFuncStartInst>(I);
- if (!isValidDebugInfoIntrinsic(FSI, CodeGenOpt::None))
- return 0;
-
- MachineFunction &MF = DAG.getMachineFunction();
- MF.setDefaultDebugLoc(ExtractDebugLocation(FSI, MF.getDebugLocInfo()));
-
- if (!DW || !DW->ShouldEmitDwarfDebug())
- return 0;
- // llvm.dbg.func_start also defines beginning of function scope.
- DW->RecordRegionStart(FSI.getSubprogram());
- return 0;
- }
case Intrinsic::dbg_declare: {
if (OptLevel != CodeGenOpt::None)
// FIXME: Variable debug info is not supported here.
@@ -4012,7 +3941,7 @@
if (SI == FuncInfo.StaticAllocaMap.end())
return 0; // VLAs.
int FI = SI->second;
-#ifdef ATTACH_DEBUG_INFO_TO_AN_INSN
+
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
if (MMI) {
MetadataContext &TheMetadata =
@@ -4021,9 +3950,6 @@
MDNode *Dbg = TheMetadata.getMD(MDDbgKind, &DI);
MMI->setVariableDbgInfo(Variable, FI, Dbg);
}
-#else
- DW->RecordVariable(Variable, FI);
-#endif
return 0;
}
case Intrinsic::eh_exception: {