Revert "[codeview] support more DW_OPs for more complete debug info"

This reverts commit e160912f53f047bc97e572add179e08e33f4df48.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@311977 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bob Haarman 2017-08-29 04:08:31 +00:00
parent 4d4211ea3a
commit 66afa977d7
7 changed files with 103 additions and 515 deletions

View File

@ -949,103 +949,13 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
}
}
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.
DbgVariableLocation Location;
bool Supported =
DbgVariableLocation::extractFromMachineInstruction(Location, *DVInst);
// Because we cannot express DW_OP_deref in CodeView directly,
// we use a trick: we encode the type as a reference to the
// real type.
if (Var.Deref) {
// When we're encoding the type as a reference to the original type,
// we need to remove a level of indirection from incoming locations.
// E.g. [RSP+8] with DW_OP_deref becomes [RSP+8],
// and [RCX+0] without DW_OP_deref becomes RCX.
if (!Location.Deref) {
if (Location.InMemory)
Location.InMemory = false;
else
Supported = false;
}
} else if (Location.Deref) {
// We've encountered a Deref range when we had not applied the
// reference encoding. Start over using reference encoding.
Var.Deref = true;
Var.DefRanges.clear();
calculateRanges(Var, Ranges);
return;
}
// If we don't know how to handle this range, skip past it.
if (!Supported || (Location.Offset && !Location.InMemory))
continue;
// Handle the two cases we can handle: indirect in memory and in register.
{
LocalVarDefRange DR;
DR.CVRegister = TRI->getCodeViewRegNum(Location.Register);
DR.InMemory = Location.InMemory;
DR.DataOffset = Location.Offset;
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))
@ -1068,7 +978,89 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
LocalVariable Var;
Var.DIVar = DIVar;
calculateRanges(Var, Ranges);
// 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 InMemory = DVInst->getOperand(1).isImm();
bool IsSubfield = false;
unsigned StructOffset = 0;
// Recognize a +Offset expression.
int Offset = 0;
DIExpressionCursor Ops(DIExpr);
auto Op = Ops.peek();
if (Op && Op->getOp() == dwarf::DW_OP_plus_uconst) {
Offset = Op->getArg(0);
Ops.take();
}
// Handle fragments.
auto Fragment = Ops.getFragmentInfo();
if (Fragment) {
IsSubfield = true;
StructOffset = Fragment->OffsetInBits / 8;
}
// Ignore unrecognized exprs.
if (Ops.peek() && Ops.peek()->getOp() != dwarf::DW_OP_LLVM_fragment)
continue;
if (!InMemory && Offset)
continue;
// 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);
{
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.
}
recordLocalVariable(std::move(Var), InlinedAt);
}
}
@ -1995,16 +1987,6 @@ 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.writeKnownType(PR);
}
TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) {
const DIType *Ty = TypeRef.resolve();
@ -2112,8 +2094,7 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
Flags |= LocalSymFlags::IsOptimizedOut;
OS.AddComment("TypeIndex");
TypeIndex TI = Var.Deref ? getTypeIndexForReferenceTo(Var.DIVar->getType())
: getCompleteTypeIndex(Var.DIVar->getType());
TypeIndex TI = getCompleteTypeIndex(Var.DIVar->getType());
OS.EmitIntValue(TI.getIndex(), 4);
OS.AddComment("Flags");
OS.EmitIntValue(static_cast<uint16_t>(Flags), 2);

View File

@ -94,7 +94,6 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
struct LocalVariable {
const DILocalVariable *DIVar = nullptr;
SmallVector<LocalVarDefRange, 1> DefRanges;
bool Deref = false;
};
struct InlineSite {
@ -148,9 +147,6 @@ 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);
@ -263,8 +259,6 @@ 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);

View File

@ -23,57 +23,6 @@
using namespace llvm;
bool DbgVariableLocation::extractFromMachineInstruction(
DbgVariableLocation &Location, const MachineInstr &Instruction) {
if (!Instruction.isDebugValue())
return false;
if (!Instruction.getOperand(0).isReg())
return false;
Location.Register = Instruction.getOperand(0).getReg();
Location.InMemory = Instruction.getOperand(1).isImm();
Location.Deref = false;
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;
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.Deref = true;
break;
default:
return false;
}
++Op;
}
Location.Offset = Offset;
return true;
}
DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
// Each LexicalScope has first instruction and last instruction to mark

View File

@ -17,44 +17,14 @@
#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 {
/// Offset relative to base register.
int64_t Offset;
/// Base register.
unsigned Register;
/// If false, Register is the location. If true,
/// Register+Offset point at the location.
unsigned InMemory : 1;
/// If false, the location holds the variable's value.
/// If true, the location holds the variable's address.
unsigned Deref : 1;
/// Present if the location is part of a larger variable.
llvm::Optional<llvm::DIExpression::FragmentInfo> FragmentInfo;
/// Extract a VariableLocation from a MachineInstr. The struct passed in as
/// Location is populated. The MachineInstr must be a debug value
/// instruction.
/// @return true if successful and false if not.
static bool extractFromMachineInstruction(DbgVariableLocation &Location,
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 {

View File

@ -1,253 +0,0 @@
# RUN: llc -filetype=obj -O0 %s -o - | llvm-readobj -codeview | FileCheck %s
#
# (DW_OP_plus_uconst 12)
# CHECK: LocalSym {
# CHECK-NEXT: Kind: S_LOCAL (0x113E)
# CHECK-NEXT: Type: string* (0x
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: VarName: Str
# CHECK-NEXT: }
# CHECK-NEXT: DefRangeRegisterRelSym {
# CHECK-NEXT: Kind: S_DEFRANGE_REGISTER_REL (0x1145)
# CHECK-NEXT: BaseRegister:
# CHECK-NEXT: HasSpilledUDTMember: No
# CHECK-NEXT: OffsetInParent: 0
# CHECK-NEXT: BasePointerOffset: 12
# CHECK-NEXT: LocalVariableAddrRange {
# CHECK-NEXT: OffsetStart:
# CHECK-NEXT: ISectStart:
# CHECK-NEXT: Range:
# CHECK-NEXT: }
# CHECK-NEXT: }
# (DW_OP_plus_uconst, 8, DW_OP_deref)
# CHECK: LocalSym {
# CHECK-NEXT: Kind: S_LOCAL (0x113E)
# CHECK-NEXT: Type: string& (0x
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: VarName: Result
# CHECK-NEXT: }
# CHECK-NEXT: DefRangeRegisterRelSym {
# CHECK-NEXT: Kind: S_DEFRANGE_REGISTER_REL (0x1145)
# CHECK-NEXT: BaseRegister:
# CHECK-NEXT: HasSpilledUDTMember: No
# CHECK-NEXT: OffsetInParent: 0
# CHECK-NEXT: BasePointerOffset: 8
# CHECK-NEXT: LocalVariableAddrRange {
# CHECK-NEXT: OffsetStart:
# CHECK-NEXT: ISectStart:
# CHECK-NEXT: Range:
# CHECK-NEXT: }
# CHECK-NEXT: }
# (DW_OP_constu, 4, DW_OP_minus)
# CHECK: LocalSym {
# CHECK-NEXT: Kind: S_LOCAL (0x113E)
# CHECK-NEXT: Type: long (0x12)
# CHECK-NEXT: Flags [ (0x0)
# CHECK-NEXT: ]
# CHECK-NEXT: VarName: Bytes
# CHECK-NEXT: }
# CHECK-NEXT: DefRangeRegisterRelSym {
# CHECK-NEXT: Kind: S_DEFRANGE_REGISTER_REL (0x1145)
# CHECK-NEXT: BaseRegister:
# CHECK-NEXT: HasSpilledUDTMember: No
# CHECK-NEXT: OffsetInParent: 0
# CHECK-NEXT: BasePointerOffset: -4
# CHECK-NEXT: LocalVariableAddrRange {
# CHECK-NEXT: OffsetStart:
# CHECK-NEXT: ISectStart:
# CHECK-NEXT: Range:
# CHECK-NEXT: }
# CHECK-NEXT: }
--- |
; ModuleID = '<stdin>'
source_filename = "<stdin>"
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i386-pc-windows-msvc19.0.24215"
%struct.string = type { i32, i32, i8* }
define void @fun(%struct.string* noalias sret %agg.result, %struct.string* noalias %str) !dbg !12 {
entry:
call void @llvm.dbg.value(metadata %struct.string* %agg.result, metadata !23, metadata !24), !dbg !25
call void @llvm.dbg.value(metadata %struct.string* %str, metadata !26, metadata !28), !dbg !25
%call = call dereferenceable(12) %struct.string* @getString(), !dbg !29
%0 = bitcast %struct.string* %agg.result to i8*, !dbg !29
%1 = bitcast %struct.string* %call to i8*, !dbg !29
call void @llvm.memcpy.p0i8.p0i8.i32(i8* %0, i8* %1, i32 12, i32 4, i1 false), !dbg !29
ret void, !dbg !30
}
define i32 @len(%struct.string* %s, i32 %acc) !dbg !31 {
entry:
%0 = bitcast %struct.string* %s to i32*
%bytes = load i32, i32* %0, !dbg !34
call void @llvm.dbg.declare(metadata i32 %bytes, metadata !35, metadata !28), !dbg !34
%1 = add i32 %bytes, %acc, !dbg !36
ret i32 %1, !dbg !36
}
; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.declare(metadata, metadata, metadata) #0
; Function Attrs: nounwind readnone speculatable
declare void @llvm.dbg.value(metadata, metadata, metadata) #0
declare dereferenceable(12) %struct.string* @getString()
; Function Attrs: argmemonly nounwind
declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture writeonly, i8* nocapture readonly, i32, i32, i1) #1
; Function Attrs: nounwind
declare void @llvm.stackprotector(i8*, i8**) #2
attributes #0 = { nounwind readnone speculatable }
attributes #1 = { argmemonly nounwind }
attributes #2 = { nounwind }
!llvm.dbg.cu = !{!0}
!llvm.linker.options = !{!3, !4}
!llvm.module.flags = !{!5, !6, !7, !8}
!llvm.ident = !{!9}
!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "diexpr.ll", directory: "C:\5Csrc", checksumkind: CSK_MD5, checksum: "c547c362c610fa79e7abaddc76e1efe7")
!2 = !{}
!3 = !{!"/DEFAULTLIB:libcmt.lib"}
!4 = !{!"/DEFAULTLIB:oldnames.lib"}
!5 = !{i32 1, !"NumRegisterParameters", i32 0}
!6 = !{i32 2, !"CodeView", i32 1}
!7 = !{i32 2, !"Debug Info Version", i32 3}
!8 = !{i32 1, !"wchar_size", i32 2}
!9 = !{!"clang version 6.0.0 "}
!10 = !DIExpression(DW_OP_plus_uconst, 12)
!11 = !DIExpression(DW_OP_plus_uconst, 8, DW_OP_deref)
!12 = distinct !DISubprogram(name: "fun", linkageName: "fun", scope: !1, file: !1, line: 9, type: !13, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
!13 = !DISubroutineType(types: !14)
!14 = !{!15}
!15 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "string", file: !1, line: 1, size: 96, elements: !16, identifier: ".?AUstring@@")
!16 = !{!17, !19, !20}
!17 = !DIDerivedType(tag: DW_TAG_member, name: "length", scope: !15, file: !1, line: 2, baseType: !18, size: 32)
!18 = !DIBasicType(name: "long int", size: 32, encoding: DW_ATE_signed)
!19 = !DIDerivedType(tag: DW_TAG_member, name: "size", scope: !15, file: !1, line: 3, baseType: !18, size: 32, offset: 32)
!20 = !DIDerivedType(tag: DW_TAG_member, name: "data", scope: !15, file: !1, line: 4, baseType: !21, size: 32, offset: 64)
!21 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !22, size: 32)
!22 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char)
!23 = !DILocalVariable(name: "Result", scope: !12, file: !1, line: 10, type: !15)
!24 = !DIExpression(DW_OP_deref)
!25 = !DILocation(line: 10, scope: !12)
!26 = !DILocalVariable(name: "Str", scope: !12, file: !1, line: 10, type: !27)
!27 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !15, size: 32)
!28 = !DIExpression(DW_OP_constu, 4, DW_OP_minus)
!29 = !DILocation(line: 11, scope: !12)
!30 = !DILocation(line: 12, scope: !12)
!31 = distinct !DISubprogram(name: "len", linkageName: "len", scope: !1, file: !1, line: 14, type: !32, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
!32 = !DISubroutineType(types: !33)
!33 = !{!18}
!34 = !DILocation(line: 15, scope: !31)
!35 = !DILocalVariable(name: "Bytes", scope: !31, file: !1, line: 15, type: !18)
!36 = !DILocation(line: 16, scope: !31)
...
---
name: fun
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
liveins:
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 4
offsetAdjustment: 0
maxAlignment: 4
adjustsStack: true
hasCalls: true
stackProtector: ''
maxCallFrameSize: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
- { id: 0, type: spill-slot, offset: -8, size: 4, alignment: 4, stack-id: 0,
callee-saved-register: '%esi' }
- { id: 1, type: default, offset: 4, size: 4, alignment: 4, stack-id: 0,
isImmutable: true, isAliased: false, callee-saved-register: '' }
- { id: 2, type: default, offset: 0, size: 4, alignment: 4, stack-id: 0,
isImmutable: true, isAliased: false, callee-saved-register: '' }
stack:
constants:
body: |
bb.0.entry:
liveins: %esi
frame-setup PUSH32r killed %esi, implicit-def %esp, implicit %esp
CFI_INSTRUCTION def_cfa_offset 8
CFI_INSTRUCTION offset %esi, -8
%esi = MOV32rm %esp, 1, _, 8, _ :: (load 4 from %fixed-stack.2)
DBG_VALUE %esp, 0, !26, !10, debug-location !25
DBG_VALUE %esp, 0, !23, !11, debug-location !25
CALLpcrel32 @getString, csr_32, implicit %esp, implicit-def %esp, implicit-def %eax, debug-location !29
%ecx = MOV32rm %eax, 1, _, 0, _, debug-location !29 :: (dereferenceable load 4 from %ir.1)
%edx = MOV32rm %eax, 1, _, 4, _, debug-location !29 :: (dereferenceable load 4 from %ir.1 + 4)
MOV32mr %esi, 1, _, 0, _, killed %ecx, debug-location !29 :: (store 4 into %ir.0)
MOV32mr %esi, 1, _, 4, _, killed %edx, debug-location !29 :: (store 4 into %ir.0 + 4)
%eax = MOV32rm killed %eax, 1, _, 8, _, debug-location !29 :: (dereferenceable load 4 from %ir.1 + 8)
MOV32mr %esi, 1, _, 8, _, killed %eax, debug-location !29 :: (store 4 into %ir.0 + 8)
%eax = COPY killed %esi, debug-location !30
%esi = POP32r implicit-def %esp, implicit %esp, debug-location !30
RET 0, %eax, debug-location !30
...
---
name: len
alignment: 4
exposesReturnsTwice: false
legalized: false
regBankSelected: false
selected: false
tracksRegLiveness: true
registers:
liveins:
frameInfo:
isFrameAddressTaken: false
isReturnAddressTaken: false
hasStackMap: false
hasPatchPoint: false
stackSize: 0
offsetAdjustment: 0
maxAlignment: 4
adjustsStack: false
hasCalls: false
stackProtector: ''
maxCallFrameSize: 0
hasOpaqueSPAdjustment: false
hasVAStart: false
hasMustTailInVarArgFunc: false
savePoint: ''
restorePoint: ''
fixedStack:
- { id: 0, type: default, offset: 4, size: 4, alignment: 4, stack-id: 0,
isImmutable: true, isAliased: false, callee-saved-register: '' }
- { id: 1, type: default, offset: 0, size: 4, alignment: 4, stack-id: 0,
isImmutable: true, isAliased: false, callee-saved-register: '' }
stack:
constants:
body: |
bb.0.entry:
%eax = MOV32rm %esp, 1, _, 4, _ :: (load 4 from %fixed-stack.1)
%eax = MOV32rm killed %eax, 1, _, 0, _, debug-location !34 :: (load 4 from %ir.0)
DBG_VALUE debug-use %eax, 0, !35, !28, debug-location !34
%eax = ADD32rm killed %eax, %esp, 1, _, 8, _, implicit-def dead %eflags, debug-location !36 :: (load 4 from %fixed-stack.0)
RET 0, %eax, debug-location !36
...

View File

@ -179,7 +179,8 @@
; ASM: .asciz "nested" # Function name
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .asciz "o"
; ASM: .cv_def_range .Lfunc_begin3 .Lfunc_end3, "E\021J\001\000\000\000\000\000\000"
; FIXME: We should have a .cv_def_range for 'o', but we don't yet.
; ASM-NOT: .cv_def_range
; ASM: .short 4414 # Record kind: S_LOCAL
; ASM: .asciz "p"
; ASM: .cv_def_range [[p_start]] .Lfunc_end3, "C\021\021\000\000\000\004\000\000\000"
@ -189,17 +190,8 @@
; OBJ: DisplayName: nested
; OBJ: }
; OBJ: LocalSym {
; OBJ: Type: Nested&
; OBJ: VarName: o
; OBJ: }
; OBJ: DefRangeRegisterRelSym {
; OBJ: BaseRegister: 330
; OBJ: HasSpilledUDTMember: No
; OBJ: OffsetInParent: 0
; OBJ: BasePointerOffset: 0
; OBJ: LocalVariableAddrRange {
; OBJ: }
; OBJ: }
; OBJ: LocalSym {
; OBJ: VarName: p
; OBJ: }

View File

@ -50,40 +50,28 @@
; CHECK: SizeOf: 4
; CHECK: Name:
; CHECK: }
; CHECK: Pointer (0x1004) {
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
; CHECK: PointeeType: 0x1003
; CHECK: PointerAttributes: 0x2A
; CHECK: PtrType: Near32 (0xA)
; CHECK: PtrMode: LValueReference (0x1)
; CHECK: IsFlat: 0
; CHECK: IsConst: 0
; CHECK: IsVolatile: 0
; CHECK: IsUnaligned: 0
; CHECK: SizeOf: 0
; CHECK: }
; CHECK: Array (0x1005) {
; CHECK: Array (0x1004) {
; CHECK: TypeLeafKind: LF_ARRAY (0x1503)
; CHECK: ElementType: char (0x70)
; CHECK: IndexType: unsigned long (0x22)
; CHECK: SizeOf: 7
; CHECK: Name:
; CHECK: }
; CHECK: Array (0x1006) {
; CHECK: Array (0x1005) {
; CHECK: TypeLeafKind: LF_ARRAY (0x1503)
; CHECK: ElementType: 0x1005
; CHECK: ElementType: 0x1004
; CHECK: IndexType: unsigned long (0x22)
; CHECK: SizeOf: 35
; CHECK: Name:
; CHECK: }
; CHECK: Array (0x1007) {
; CHECK: Array (0x1006) {
; CHECK: TypeLeafKind: LF_ARRAY (0x1503)
; CHECK: ElementType: 0x1006
; CHECK: ElementType: 0x1005
; CHECK: IndexType: unsigned long (0x22)
; CHECK: SizeOf: 70
; CHECK: Name:
; CHECK: }
; CHECK: Struct (0x1008) {
; CHECK: Struct (0x1007) {
; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505)
; CHECK: MemberCount: 0
; CHECK: Properties [ (0x280)
@ -97,16 +85,16 @@
; CHECK: Name: incomplete_struct
; CHECK: LinkageName: .?AUincomplete_struct@@
; CHECK: }
; CHECK: Array (0x1009) {
; CHECK: Array (0x1008) {
; CHECK: TypeLeafKind: LF_ARRAY (0x1503)
; CHECK: ElementType: incomplete_struct (0x1008)
; CHECK: ElementType: incomplete_struct (0x1007)
; CHECK: IndexType: unsigned long (0x22)
; CHECK: SizeOf: 12
; CHECK: Name:
; CHECK: }
; CHECK: Pointer (0x100A) {
; CHECK: Pointer (0x1009) {
; CHECK: TypeLeafKind: LF_POINTER (0x1002)
; CHECK: PointeeType: 0x1009
; CHECK: PointeeType: 0x1008
; CHECK: PointerAttributes: 0x800A
; CHECK: PtrType: Near32 (0xA)
; CHECK: PtrMode: Pointer (0x0)
@ -116,41 +104,8 @@
; CHECK: IsUnaligned: 0
; CHECK: SizeOf: 4
; CHECK: }
; CHECK: FieldList (0x100B) {
; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203)
; CHECK: DataMember {
; CHECK: TypeLeafKind: LF_MEMBER (0x150D)
; CHECK: AccessSpecifier: Public (0x3)
; CHECK: Type: int (0x74)
; CHECK: FieldOffset: 0x0
; CHECK: Name: s1
; CHECK: }
; CHECK: }
; CHECK: Struct (0x100C) {
; CHECK: TypeLeafKind: LF_STRUCTURE (0x1505)
; CHECK: MemberCount: 1
; CHECK: Properties [ (0x200)
; CHECK: HasUniqueName (0x200)
; CHECK: ]
; CHECK: FieldList: <field list> (0x100B)
; CHECK: DerivedFrom: 0x0
; CHECK: VShape: 0x0
; CHECK: SizeOf: 4
; CHECK: Name: incomplete_struct
; CHECK: LinkageName: .?AUincomplete_struct@@
; CHECK: }
; CHECK: StringId (0x100D) {
; CHECK: TypeLeafKind: LF_STRING_ID (0x1605)
; CHECK: Id: 0x0
; CHECK: StringData: \t.cpp
; CHECK: }
; CHECK: UdtSourceLine (0x100E) {
; CHECK: TypeLeafKind: LF_UDT_SRC_LINE (0x1606)
; CHECK: UDT: incomplete_struct (0x100C)
; CHECK: SourceFile: \t.cpp (0x100D)
; CHECK: LineNumber: 4
; CHECK: }
; CHECK: Modifier (0x100F) {
;
; CHECK: Modifier (0x100E) {
; CHECK: TypeLeafKind: LF_MODIFIER (0x1001)
; CHECK: ModifiedType: int (0x74)
; CHECK: Modifiers [ (0x3)
@ -158,9 +113,9 @@
; CHECK: Volatile (0x2)
; CHECK: ]
; CHECK: }
; CHECK: Array (0x1010) {
; CHECK: Array (0x100F) {
; CHECK: TypeLeafKind: LF_ARRAY (0x1503)
; CHECK: ElementType: const volatile int (0x100F)
; CHECK: ElementType: const volatile int (0x100E)
; CHECK: IndexType: unsigned long (0x22)
; CHECK: SizeOf: 16
; CHECK: Name: