Index: CodeGen/AsmPrinter/CodeViewDebug.h =================================================================== --- CodeGen/AsmPrinter/CodeViewDebug.h +++ CodeGen/AsmPrinter/CodeViewDebug.h @@ -335,10 +335,10 @@ codeview::TypeIndex lowerTypeModifier(const DIDerivedType *Ty); codeview::TypeIndex lowerTypeFunction(const DISubroutineType *Ty); codeview::TypeIndex lowerTypeVFTableShape(const DIDerivedType *Ty); - codeview::TypeIndex lowerTypeMemberFunction(const DISubroutineType *Ty, - const DIType *ClassTy, - int ThisAdjustment, - bool IsStaticMethod); + codeview::TypeIndex lowerTypeMemberFunction( + const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, + bool IsStaticMethod, + codeview::FunctionOptions FO = codeview::FunctionOptions::None); codeview::TypeIndex lowerTypeEnum(const DICompositeType *Ty); codeview::TypeIndex lowerTypeClass(const DICompositeType *Ty); codeview::TypeIndex lowerTypeUnion(const DICompositeType *Ty); Index: CodeGen/AsmPrinter/CodeViewDebug.cpp =================================================================== --- CodeGen/AsmPrinter/CodeViewDebug.cpp +++ CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -327,6 +327,58 @@ return recordTypeIndexForDINode(SP, TI); } +static bool isTrivial(const DICompositeType *DCTy) { + return ((DCTy->getFlags() & DINode::FlagTrivial) == DINode::FlagTrivial); +} + +static bool hasVirtualBase(const DICompositeType *DCTy) { + for (auto *Element : DCTy->getElements()) { + if (!Element) + continue; + + if (auto *DDTy = dyn_cast(Element)) { + if (DDTy->getTag() == dwarf::DW_TAG_inheritance) { + if (((DDTy->getFlags() & DINode::FlagVirtual) == DINode::FlagVirtual) || + ((DDTy->getFlags() & DINode::FlagIndirectVirtualBase) == + DINode::FlagIndirectVirtualBase)) + return true; + + if (auto *ElemDCTy = dyn_cast(DDTy)) { + if (hasVirtualBase(ElemDCTy)) + return true; + } + } + } + } + return false; +} + +static FunctionOptions +getFunctionOptions(const DISubroutineType *Ty, + const DICompositeType *ClassTy = nullptr, + StringRef SPName = StringRef("")) { + FunctionOptions FO = FunctionOptions::None; + const DIType *ReturnTy = nullptr; + if (auto TypeArray = Ty->getTypeArray()) { + if (TypeArray.size()) + ReturnTy = TypeArray[0].resolve(); + } + + if (auto *ReturnDCTy = dyn_cast_or_null(ReturnTy)) { + if (!isTrivial(ReturnDCTy)) + FO |= FunctionOptions::CxxReturnUdt; + } + + // DISubroutineType is unnamed. Use DISubprogram's i.e. SPName in comparison. + if (ClassTy && !isTrivial(ClassTy) && SPName == ClassTy->getName()) { + FO |= FunctionOptions::Constructor; + + if (hasVirtualBase(ClassTy)) + FO |= FunctionOptions::ConstructorWithVirtualBases; + } + return FO; +} + TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP, const DICompositeType *Class) { // Always use the method declaration as the key for the function type. The @@ -346,8 +398,10 @@ // member function type. TypeLoweringScope S(*this); const bool IsStaticMethod = (SP->getFlags() & DINode::FlagStaticMember) != 0; + + FunctionOptions FO = getFunctionOptions(SP->getType(), Class, SP->getName()); TypeIndex TI = lowerTypeMemberFunction( - SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod); + SP->getType(), Class, SP->getThisAdjustment(), IsStaticMethod, FO); return recordTypeIndexForDINode(SP, TI, Class); } @@ -1636,15 +1690,17 @@ CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); - ProcedureRecord Procedure(ReturnTypeIndex, CC, FunctionOptions::None, - ArgTypeIndices.size(), ArgListIndex); + FunctionOptions FO = getFunctionOptions(Ty); + ProcedureRecord Procedure(ReturnTypeIndex, CC, FO, ArgTypeIndices.size(), + ArgListIndex); return TypeTable.writeLeafType(Procedure); } TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, const DIType *ClassTy, int ThisAdjustment, - bool IsStaticMethod) { + bool IsStaticMethod, + FunctionOptions FO) { // Lower the containing class type. TypeIndex ClassType = getTypeIndex(ClassTy); @@ -1675,10 +1731,8 @@ CallingConvention CC = dwarfCCToCodeView(Ty->getCC()); - // TODO: Need to use the correct values for FunctionOptions. - MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC, - FunctionOptions::None, ArgTypeIndices.size(), - ArgListIndex, ThisAdjustment); + MemberFunctionRecord MFR(ReturnTypeIndex, ClassType, ThisTypeIndex, CC, FO, + ArgTypeIndices.size(), ArgListIndex, ThisAdjustment); return TypeTable.writeLeafType(MFR); } Index: DebugInfo/COFF/function-options.ll =================================================================== --- /dev/null +++ DebugInfo/COFF/function-options.ll @@ -0,0 +1,1190 @@ +; RUN: llc < %s -filetype=obj | llvm-readobj - -codeview | FileCheck %s + +; Command to generate function-options.ll +; $ clang++ function-options.cpp -S -emit-llvm -g -gcodeview -o function-options.ll +; +; +; +; // The following defines non-trivial and trivial class/struct/union. +; +; #define DEFINE_FUNCTION(T) \ +; T Func_##T(T &arg) { return arg; } +; +; class AClass {}; +; DEFINE_FUNCTION(AClass); // Expect: FO = None +; +; +; class BClass { +; private: +; explicit BClass(); // Expect ctor: FO = Constructor +; }; +; DEFINE_FUNCTION(BClass); // Expect: FO = CxxReturnUdt +; +; +; class C1Class { +; public: +; C1Class() = default; // FIXME: Clang generates defaulted ctor while MSVC doesn't. +; // We won't check what clang yields in this test. (though FO is correct) +; }; +; DEFINE_FUNCTION(C1Class); // Expect: FO = None +; +; +; class C2Class { // Note: MSVC-specific dtor, i.e. __vecDelDtor won't be verified in this case. +; public: +; ~C2Class() {} // Expect ~C2Class: FO = None +; }; +; DEFINE_FUNCTION(C2Class); // Expect: FO = CxxReturnUdt +; +; +; class DClass : public BClass { // FIXME: MSVC yields one compiler-generated ctor for DClass (MemberCount = 1), +; // but clang does not generate any member function. +; // In this sense, we won't verify FO for DClass member functions. +; }; +; DEFINE_FUNCTION(DClass); // Expect: FO = CxxReturnUdt +; +; +; class EClass { virtual void f(); }; // FIXME: There is diff in codegen. We will only verify what clang yields for now. +; // MSVC: +; // f(): FO = None +; // EClass move ctor: FO = Constructor +; // EClass copy ctor: FO = Constructor +; // EClass ctor: FO = Constructor +; // EClass move assign: FO = None +; // EClass copy assign: FO = None +; +; // Clang: (MemberCount = 2) +; // Expect f(): FO = None +; // Expect EClass copy ctor: FO = Constructor +; +; DEFINE_FUNCTION(EClass); // Expect FO = CxxReturnUdt +; +; +; class FClass { static int x; }; +; DEFINE_FUNCTION(FClass); // Expect FO = None +; +; +; struct AStruct {}; +; DEFINE_FUNCTION(AStruct); // Expect FO = None +; +; +; struct BStruct { BStruct(); }; // Expect ctor: FO = Constructor +; DEFINE_FUNCTION(BStruct); // Expect FO = CxxReturnUdt +; +; +; union AUnion {}; +; DEFINE_FUNCTION(AUnion); // Expect FO = None +; +; +; union BUnion { BUnion() = default; }; // FIXME: Clang generates defaulted ctor while MSVC does not. +; // We won't check what clang yields in this test. (though FO is correct) +; DEFINE_FUNCTION(BUnion); // Expect FO = None +; +; +; class BaseA {}; +; class BaseB : virtual public BaseA {}; // FIXME: There is diff in codegen. We will only verify what clang yields for now. +; // MSVC: +; // mov ctor: FO = Constructor | ConstructorWithVirtualBase +; // ctor: FO = Constructor | ConstructorWithVirtualBase +; // copy ctor: FO = Constructor | ConstructorWithVirtualBase +; // copy assign: FO = None +; // move assign: FO = None +; +; // Clang: (MemberCount = 1) +; // Expect copy ctor: FO = Constructor | ConstructorWithVirtualBase +; +; class DerivedClass : virtual public BaseA {}; // FIXME: There is diff in codegen. We will only verify what clang yields for now. +; // MSVC +; // cotr: FO = Constructor | ConstructorWithVirtualBase +; // copy ctor: FO = Constructor | ConstructorWithVirtualBase +; // move ctor: FO = Constructor | ConstructorWithVirtualBase +; // move assign: FO = None +; // copy assign: FO = None +; +; // Clang: (MemberCount = 1) +; // Expected copy ctor: FO = Constructor | ConstructorWithVirtualBase +; +; class ClassIVB : public BaseB {}; // FIXME: There is diff is codegen. We will only verify what clang yields for now. +; // MSVC: +; // ctor: FO = Constructor | ConstructorWithVirtualBase +; // copy ctor: FO = Constructor | ConstructorWithVirtualBase +; // move ctor: FO = Constructor | ConstructorWithVirtualBase +; // copy assign: FO = None +; // move assign: FO = None +; +; // Clang: (MemberCount = 1) +; // Expect copy ctor: FO = Constructor | ConstructorWithVirtualBase +; +; +; DEFINE_FUNCTION(DerivedClass); // Expect: FO = CxxReturnUdt +; +; BaseA Func_DerivedClass_RtBase(DerivedClass &arg) { // Expect: FO = None +; return arg; +; } +; +; DEFINE_FUNCTION(ClassIVB); // Expect:FO = CxxReturnUdt + +; CHECK: Format: COFF-x86-64 +; CHECK: Arch: x86_64 +; CHECK: AddressSize: 64bit +; CHECK: CodeViewTypes [ +; CHECK: Section: .debug$T (19) +; CHECK: Magic: 0x4 +; CHECK: Procedure ([[SP1:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: AClass ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (AClass&) ({{.*}}) +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: AClass (AClass&) ([[SP1]]) +; CHECK: Name: Func_AClass +; CHECK: } +; CHECK: Procedure ([[SP2:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: BClass ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (BClass&) ({{.*}}) +; CHECK: } +; CHECK: MemberFunction ([[MF1:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: BClass ({{.*}}) +; CHECK: ThisType: BClass* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x2) +; CHECK: Constructor (0x2) +; CHECK: ] +; CHECK: NumParameters: 0 +; CHECK: ArgListType: () ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: OneMethod { +; CHECK: TypeLeafKind: LF_ONEMETHOD (0x1511) +; CHECK: AccessSpecifier: Private (0x1) +; CHECK: Type: void BClass::() ([[MF1]]) +; CHECK: Name: BClass +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: BClass (BClass&) ([[SP2]]) +; CHECK: Name: Func_BClass +; CHECK: } +; CHECK: Procedure ([[SP3:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: C1Class ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (C1Class&) ({{.*}}) +; CHECK: } +; CHECK: MemberFunction ([[MF2:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: C1Class ({{.*}}) +; CHECK: ThisType: C1Class* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 0 +; CHECK: ArgListType: () ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: OneMethod { +; CHECK: TypeLeafKind: LF_ONEMETHOD (0x1511) +; CHECK: AccessSpecifier: Public (0x3) +; CHECK: Type: void C1Class::() ([[MF2]]) +; CHECK: Name: C1Class +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: C1Class (C1Class&) ([[SP3]]) +; CHECK: Name: Func_C1Class +; CHECK: } +; CHECK: Procedure ([[SP4:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: C2Class ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (C2Class&) ({{.*}}) +; CHECK: } +; CHECK: MemberFunction ([[MF3:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: C2Class ({{.*}}) +; CHECK: ThisType: C2Class* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 0 +; CHECK: ArgListType: () ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: OneMethod { +; CHECK: TypeLeafKind: LF_ONEMETHOD (0x1511) +; CHECK: AccessSpecifier: Public (0x3) +; CHECK: Type: void C2Class::() ([[MF3]]) +; CHECK: Name: ~C2Class +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: C2Class (C2Class&) ([[SP4]]) +; CHECK: Name: Func_C2Class +; CHECK: } +; CHECK: Procedure ([[SP5:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: DClass ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (DClass&) ({{.*}}) +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: BaseClass { +; CHECK: TypeLeafKind: LF_BCLASS (0x1400) +; CHECK: AccessSpecifier: Public (0x3) +; CHECK: BaseType: BClass ({{.*}}) +; CHECK: BaseOffset: 0x0 +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: DClass (DClass&) ([[SP5]]) +; CHECK: Name: Func_DClass +; CHECK: } +; CHECK: Procedure ([[SP6:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: EClass ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (EClass&) ({{.*}}) +; CHECK: } +; CHECK: MemberFunction ([[MF4:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: EClass ({{.*}}) +; CHECK: ThisType: EClass* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 0 +; CHECK: ArgListType: () ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: VFPtr { +; CHECK: TypeLeafKind: LF_VFUNCTAB (0x1409) +; CHECK: Type: * ({{.*}}) +; CHECK: } +; CHECK: OneMethod { +; CHECK: TypeLeafKind: LF_ONEMETHOD (0x1511) +; CHECK: AccessSpecifier: Private (0x1) +; CHECK: MethodKind: IntroducingVirtual (0x4) +; CHECK: Type: void EClass::() ([[MF4]]) +; CHECK: VFTableOffset: 0x0 +; CHECK: Name: f +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: EClass (EClass&) ([[SP6]]) +; CHECK: Name: Func_EClass +; CHECK: } +; CHECK: MemberFunction ([[MF5:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: EClass ({{.*}}) +; CHECK: ThisType: EClass* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x2) +; CHECK: Constructor (0x2) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (const EClass&) ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: MemberFuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_MFUNC_ID (0x1602) +; CHECK: ClassType: EClass ({{.*}}) +; CHECK: FunctionType: void EClass::(const EClass&) ([[MF5]]) +; CHECK: Name: EClass +; CHECK: } +; CHECK: Procedure ([[SP7:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: FClass ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (FClass&) ({{.*}}) +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: StaticDataMember { +; CHECK: TypeLeafKind: LF_STMEMBER (0x150E) +; CHECK: AccessSpecifier: Private (0x1) +; CHECK: Type: int (0x74) +; CHECK: Name: x +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: FClass (FClass&) ([[SP7]]) +; CHECK: Name: Func_FClass +; CHECK: } +; CHECK: Procedure ([[SP8:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: AStruct ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (AStruct&) ({{.*}}) +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: AStruct (AStruct&) ([[SP8]]) +; CHECK: Name: Func_AStruct +; CHECK: } +; CHECK: Procedure ([[SP9:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: BStruct ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (BStruct&) ({{.*}}) +; CHECK: } +; CHECK: MemberFunction ([[MF6:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: BStruct ({{.*}}) +; CHECK: ThisType: BStruct* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x2) +; CHECK: Constructor (0x2) +; CHECK: ] +; CHECK: NumParameters: 0 +; CHECK: ArgListType: () ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: OneMethod { +; CHECK: TypeLeafKind: LF_ONEMETHOD (0x1511) +; CHECK: AccessSpecifier: Public (0x3) +; CHECK: Type: void BStruct::() ([[MF6]]) +; CHECK: Name: BStruct +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: BStruct (BStruct&) ([[SP9]]) +; CHECK: Name: Func_BStruct +; CHECK: } +; CHECK: Procedure ([[SP10:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: AUnion ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (AUnion&) ({{.*}}) +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: AUnion (AUnion&) ([[SP10]]) +; CHECK: Name: Func_AUnion +; CHECK: } +; CHECK: Procedure ([[SP11:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: BUnion ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (BUnion&) ({{.*}}) +; CHECK: } +; CHECK: MemberFunction ([[MF7:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: BUnion ({{.*}}) +; CHECK: ThisType: BUnion* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 0 +; CHECK: ArgListType: () ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: FieldList ({{.*}}) { +; CHECK: TypeLeafKind: LF_FIELDLIST (0x1203) +; CHECK: OneMethod { +; CHECK: TypeLeafKind: LF_ONEMETHOD (0x1511) +; CHECK: AccessSpecifier: Public (0x3) +; CHECK: Type: void BUnion::() ([[MF7]]) +; CHECK: Name: BUnion +; CHECK: } +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: BUnion (BUnion&) ([[SP11]]) +; CHECK: Name: Func_BUnion +; CHECK: } +; CHECK: Procedure ([[SP12:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: DerivedClass ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (DerivedClass&) ({{.*}}) +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: DerivedClass (DerivedClass&) ([[SP12]]) +; CHECK: Name: Func_DerivedClass +; CHECK: } +; CHECK: MemberFunction ([[MF8:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: DerivedClass ({{.*}}) +; CHECK: ThisType: DerivedClass* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x6) +; CHECK: Constructor (0x2) +; CHECK: ConstructorWithVirtualBases (0x4) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (const DerivedClass&) ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: MemberFuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_MFUNC_ID (0x1602) +; CHECK: ClassType: DerivedClass ({{.*}}) +; CHECK: FunctionType: void DerivedClass::(const DerivedClass&) ([[MF8]]) +; CHECK: Name: DerivedClass +; CHECK: } +; CHECK: Procedure ([[SP13:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: BaseA ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x0) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (DerivedClass&) ({{.*}}) +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: BaseA (DerivedClass&) ([[SP13]]) +; CHECK: Name: Func_DerivedClass_RtBase +; CHECK: } +; CHECK: Procedure ([[SP14:.*]]) { +; CHECK: TypeLeafKind: LF_PROCEDURE (0x1008) +; CHECK: ReturnType: ClassIVB ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x1) +; CHECK: CxxReturnUdt (0x1) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (ClassIVB&) ({{.*}}) +; CHECK: } +; CHECK: FuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_FUNC_ID (0x1601) +; CHECK: ParentScope: 0x0 +; CHECK: FunctionType: ClassIVB (ClassIVB&) ([[SP14]]) +; CHECK: Name: Func_ClassIVB +; CHECK: } +; CHECK: MemberFunction ([[MF9:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: ClassIVB ({{.*}}) +; CHECK: ThisType: ClassIVB* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x6) +; CHECK: Constructor (0x2) +; CHECK: ConstructorWithVirtualBases (0x4) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (const ClassIVB&) ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: MemberFuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_MFUNC_ID (0x1602) +; CHECK: ClassType: ClassIVB ({{.*}}) +; CHECK: FunctionType: void ClassIVB::(const ClassIVB&) ([[MF9]]) +; CHECK: Name: ClassIVB +; CHECK: } +; CHECK: MemberFunction ([[MF10:.*]]) { +; CHECK: TypeLeafKind: LF_MFUNCTION (0x1009) +; CHECK: ReturnType: void (0x3) +; CHECK: ClassType: BaseB ({{.*}}) +; CHECK: ThisType: BaseB* ({{.*}}) +; CHECK: CallingConvention: NearC (0x0) +; CHECK: FunctionOptions [ (0x6) +; CHECK: Constructor (0x2) +; CHECK: ConstructorWithVirtualBases (0x4) +; CHECK: ] +; CHECK: NumParameters: 1 +; CHECK: ArgListType: (const BaseB&) ({{.*}}) +; CHECK: ThisAdjustment: 0 +; CHECK: } +; CHECK: MemberFuncId ({{.*}}) { +; CHECK: TypeLeafKind: LF_MFUNC_ID (0x1602) +; CHECK: ClassType: BaseB ({{.*}}) +; CHECK: FunctionType: void BaseB::(const BaseB&) ([[MF10]]) +; CHECK: Name: BaseB +; CHECK: } +; CHECK: ] + + +; ModuleID = 'function-options.cpp' +source_filename = "function-options.cpp" +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.11.25507" + +%rtti.CompleteObjectLocator = type { i32, i32, i32, i32, i32, i32 } +%rtti.TypeDescriptor12 = type { i8**, i8*, [13 x i8] } +%rtti.ClassHierarchyDescriptor = type { i32, i32, i32, i32 } +%rtti.BaseClassDescriptor = type { i32, i32, i32, i32, i32, i32, i32 } +%class.AClass = type { i8 } +%class.BClass = type { i8 } +%class.C1Class = type { i8 } +%class.C2Class = type { i8 } +%class.DClass = type { i8 } +%class.EClass = type { i32 (...)** } +%class.FClass = type { i8 } +%struct.AStruct = type { i8 } +%struct.BStruct = type { i8 } +%union.AUnion = type { i8 } +%union.BUnion = type { i8 } +%class.DerivedClass = type { i32* } +%class.BaseA = type { i8 } +%class.ClassIVB = type { %class.BaseB } +%class.BaseB = type { i32* } + +$"??0EClass@@QEAA@AEBV0@@Z" = comdat any + +$"??0DerivedClass@@QEAA@AEBV0@@Z" = comdat any + +$"??0ClassIVB@@QEAA@AEBV0@@Z" = comdat any + +$"??0BaseB@@QEAA@AEBV0@@Z" = comdat any + +$"??_7EClass@@6B@" = comdat largest + +$"??_R4EClass@@6B@" = comdat any + +$"??_R0?AVEClass@@@8" = comdat any + +$"??_R3EClass@@8" = comdat any + +$"??_R2EClass@@8" = comdat any + +$"??_R1A@?0A@EA@EClass@@8" = comdat any + +$"??_8DerivedClass@@7B@" = comdat any + +$"??_8ClassIVB@@7B@" = comdat any + +$"??_8BaseB@@7B@" = comdat any + +@0 = private unnamed_addr constant { [2 x i8*] } { [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"??_R4EClass@@6B@" to i8*), i8* bitcast (void (%class.EClass*)* @"?f@EClass@@EEAAXXZ" to i8*)] }, comdat($"??_7EClass@@6B@") +@"??_R4EClass@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor12* @"??_R0?AVEClass@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3EClass@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"??_R4EClass@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +@"??_7type_info@@6B@" = external constant i8* +@"??_R0?AVEClass@@@8" = linkonce_odr global %rtti.TypeDescriptor12 { i8** @"??_7type_info@@6B@", i8* null, [13 x i8] c".?AVEClass@@\00" }, comdat +@__ImageBase = external dso_local constant i8 +@"??_R3EClass@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"??_R2EClass@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +@"??_R2EClass@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"??_R1A@?0A@EA@EClass@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +@"??_R1A@?0A@EA@EClass@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor12* @"??_R0?AVEClass@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"??_R3EClass@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +@"??_8DerivedClass@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8], comdat +@"??_8ClassIVB@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8], comdat +@"??_8BaseB@@7B@" = linkonce_odr unnamed_addr constant [2 x i32] [i32 0, i32 8], comdat + +@"??_7EClass@@6B@" = unnamed_addr alias i8*, getelementptr inbounds ({ [2 x i8*] }, { [2 x i8*] }* @0, i32 0, i32 0, i32 1) + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8 @"?Func_AClass@@YA?AVAClass@@AEAV1@@Z"(%class.AClass* dereferenceable(1) %arg) #0 !dbg !8 { +entry: + %retval = alloca %class.AClass, align 1 + %arg.addr = alloca %class.AClass*, align 8 + store %class.AClass* %arg, %class.AClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.AClass** %arg.addr, metadata !14, metadata !DIExpression()), !dbg !15 + %0 = load %class.AClass*, %class.AClass** %arg.addr, align 8, !dbg !15 + %coerce.dive = getelementptr inbounds %class.AClass, %class.AClass* %retval, i32 0, i32 0, !dbg !15 + %1 = load i8, i8* %coerce.dive, align 1, !dbg !15 + ret i8 %1, !dbg !15 +} + +; Function Attrs: nounwind readnone speculatable +declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_BClass@@YA?AVBClass@@AEAV1@@Z"(%class.BClass* noalias sret %agg.result, %class.BClass* dereferenceable(1) %arg) #0 !dbg !16 { +entry: + %arg.addr = alloca %class.BClass*, align 8 + store %class.BClass* %arg, %class.BClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.BClass** %arg.addr, metadata !26, metadata !DIExpression()), !dbg !27 + %0 = load %class.BClass*, %class.BClass** %arg.addr, align 8, !dbg !27 + ret void, !dbg !27 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_C1Class@@YA?AVC1Class@@AEAV1@@Z"(%class.C1Class* noalias sret %agg.result, %class.C1Class* dereferenceable(1) %arg) #0 !dbg !28 { +entry: + %arg.addr = alloca %class.C1Class*, align 8 + store %class.C1Class* %arg, %class.C1Class** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.C1Class** %arg.addr, metadata !38, metadata !DIExpression()), !dbg !39 + %0 = load %class.C1Class*, %class.C1Class** %arg.addr, align 8, !dbg !39 + ret void, !dbg !39 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_C2Class@@YA?AVC2Class@@AEAV1@@Z"(%class.C2Class* noalias sret %agg.result, %class.C2Class* dereferenceable(1) %arg) #0 !dbg !40 { +entry: + %arg.addr = alloca %class.C2Class*, align 8 + store %class.C2Class* %arg, %class.C2Class** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.C2Class** %arg.addr, metadata !50, metadata !DIExpression()), !dbg !51 + %0 = load %class.C2Class*, %class.C2Class** %arg.addr, align 8, !dbg !51 + ret void, !dbg !51 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_DClass@@YA?AVDClass@@AEAV1@@Z"(%class.DClass* noalias sret %agg.result, %class.DClass* dereferenceable(1) %arg) #0 !dbg !52 { +entry: + %arg.addr = alloca %class.DClass*, align 8 + store %class.DClass* %arg, %class.DClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.DClass** %arg.addr, metadata !59, metadata !DIExpression()), !dbg !60 + %0 = load %class.DClass*, %class.DClass** %arg.addr, align 8, !dbg !60 + ret void, !dbg !60 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_EClass@@YA?AVEClass@@AEAV1@@Z"(%class.EClass* noalias sret %agg.result, %class.EClass* dereferenceable(8) %arg) #0 !dbg !61 { +entry: + %arg.addr = alloca %class.EClass*, align 8 + store %class.EClass* %arg, %class.EClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.EClass** %arg.addr, metadata !74, metadata !DIExpression()), !dbg !75 + %0 = load %class.EClass*, %class.EClass** %arg.addr, align 8, !dbg !75 + %call = call %class.EClass* @"??0EClass@@QEAA@AEBV0@@Z"(%class.EClass* %agg.result, %class.EClass* dereferenceable(8) %0) #3, !dbg !75 + ret void, !dbg !75 +} + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local %class.EClass* @"??0EClass@@QEAA@AEBV0@@Z"(%class.EClass* returned %this, %class.EClass* dereferenceable(8)) unnamed_addr #0 comdat align 2 !dbg !76 { +entry: + %.addr = alloca %class.EClass*, align 8 + %this.addr = alloca %class.EClass*, align 8 + store %class.EClass* %0, %class.EClass** %.addr, align 8 + call void @llvm.dbg.declare(metadata %class.EClass** %.addr, metadata !82, metadata !DIExpression()), !dbg !83 + store %class.EClass* %this, %class.EClass** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %class.EClass** %this.addr, metadata !84, metadata !DIExpression()), !dbg !83 + %this1 = load %class.EClass*, %class.EClass** %this.addr, align 8 + %1 = bitcast %class.EClass* %this1 to i32 (...)***, !dbg !86 + store i32 (...)** bitcast (i8** @"??_7EClass@@6B@" to i32 (...)**), i32 (...)*** %1, align 8, !dbg !86 + ret %class.EClass* %this1, !dbg !86 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8 @"?Func_FClass@@YA?AVFClass@@AEAV1@@Z"(%class.FClass* dereferenceable(1) %arg) #0 !dbg !87 { +entry: + %retval = alloca %class.FClass, align 1 + %arg.addr = alloca %class.FClass*, align 8 + store %class.FClass* %arg, %class.FClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.FClass** %arg.addr, metadata !95, metadata !DIExpression()), !dbg !96 + %0 = load %class.FClass*, %class.FClass** %arg.addr, align 8, !dbg !96 + %coerce.dive = getelementptr inbounds %class.FClass, %class.FClass* %retval, i32 0, i32 0, !dbg !96 + %1 = load i8, i8* %coerce.dive, align 1, !dbg !96 + ret i8 %1, !dbg !96 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8 @"?Func_AStruct@@YA?AUAStruct@@AEAU1@@Z"(%struct.AStruct* dereferenceable(1) %arg) #0 !dbg !97 { +entry: + %retval = alloca %struct.AStruct, align 1 + %arg.addr = alloca %struct.AStruct*, align 8 + store %struct.AStruct* %arg, %struct.AStruct** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.AStruct** %arg.addr, metadata !102, metadata !DIExpression()), !dbg !103 + %0 = load %struct.AStruct*, %struct.AStruct** %arg.addr, align 8, !dbg !103 + %coerce.dive = getelementptr inbounds %struct.AStruct, %struct.AStruct* %retval, i32 0, i32 0, !dbg !103 + %1 = load i8, i8* %coerce.dive, align 1, !dbg !103 + ret i8 %1, !dbg !103 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_BStruct@@YA?AUBStruct@@AEAU1@@Z"(%struct.BStruct* noalias sret %agg.result, %struct.BStruct* dereferenceable(1) %arg) #0 !dbg !104 { +entry: + %arg.addr = alloca %struct.BStruct*, align 8 + store %struct.BStruct* %arg, %struct.BStruct** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %struct.BStruct** %arg.addr, metadata !114, metadata !DIExpression()), !dbg !115 + %0 = load %struct.BStruct*, %struct.BStruct** %arg.addr, align 8, !dbg !115 + ret void, !dbg !115 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8 @"?Func_AUnion@@YA?ATAUnion@@AEAT1@@Z"(%union.AUnion* dereferenceable(1) %arg) #0 !dbg !116 { +entry: + %retval = alloca %union.AUnion, align 1 + %arg.addr = alloca %union.AUnion*, align 8 + store %union.AUnion* %arg, %union.AUnion** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %union.AUnion** %arg.addr, metadata !121, metadata !DIExpression()), !dbg !122 + %0 = load %union.AUnion*, %union.AUnion** %arg.addr, align 8, !dbg !122 + %coerce.dive = getelementptr inbounds %union.AUnion, %union.AUnion* %retval, i32 0, i32 0, !dbg !122 + %1 = load i8, i8* %coerce.dive, align 1, !dbg !122 + ret i8 %1, !dbg !122 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_BUnion@@YA?ATBUnion@@AEAT1@@Z"(%union.BUnion* noalias sret %agg.result, %union.BUnion* dereferenceable(1) %arg) #0 !dbg !123 { +entry: + %arg.addr = alloca %union.BUnion*, align 8 + store %union.BUnion* %arg, %union.BUnion** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %union.BUnion** %arg.addr, metadata !133, metadata !DIExpression()), !dbg !134 + %0 = load %union.BUnion*, %union.BUnion** %arg.addr, align 8, !dbg !134 + ret void, !dbg !134 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_DerivedClass@@YA?AVDerivedClass@@AEAV1@@Z"(%class.DerivedClass* noalias sret %agg.result, %class.DerivedClass* dereferenceable(8) %arg) #0 !dbg !135 { +entry: + %arg.addr = alloca %class.DerivedClass*, align 8 + store %class.DerivedClass* %arg, %class.DerivedClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.DerivedClass** %arg.addr, metadata !143, metadata !DIExpression()), !dbg !144 + %0 = load %class.DerivedClass*, %class.DerivedClass** %arg.addr, align 8, !dbg !144 + %call = call %class.DerivedClass* @"??0DerivedClass@@QEAA@AEBV0@@Z"(%class.DerivedClass* %agg.result, %class.DerivedClass* dereferenceable(8) %0, i32 1) #3, !dbg !144 + ret void, !dbg !144 +} + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local %class.DerivedClass* @"??0DerivedClass@@QEAA@AEBV0@@Z"(%class.DerivedClass* returned %this, %class.DerivedClass* dereferenceable(8), i32 %is_most_derived) unnamed_addr #0 comdat align 2 !dbg !145 { +entry: + %retval = alloca %class.DerivedClass*, align 8 + %is_most_derived.addr = alloca i32, align 4 + %.addr = alloca %class.DerivedClass*, align 8 + %this.addr = alloca %class.DerivedClass*, align 8 + store i32 %is_most_derived, i32* %is_most_derived.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %is_most_derived.addr, metadata !152, metadata !DIExpression()), !dbg !153 + store %class.DerivedClass* %0, %class.DerivedClass** %.addr, align 8 + call void @llvm.dbg.declare(metadata %class.DerivedClass** %.addr, metadata !154, metadata !DIExpression()), !dbg !153 + store %class.DerivedClass* %this, %class.DerivedClass** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %class.DerivedClass** %this.addr, metadata !155, metadata !DIExpression()), !dbg !153 + %this1 = load %class.DerivedClass*, %class.DerivedClass** %this.addr, align 8 + store %class.DerivedClass* %this1, %class.DerivedClass** %retval, align 8 + %is_most_derived2 = load i32, i32* %is_most_derived.addr, align 4 + %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !157 + br i1 %is_complete_object, label %ctor.init_vbases, label %ctor.skip_vbases, !dbg !157 + +ctor.init_vbases: ; preds = %entry + %this.int8 = bitcast %class.DerivedClass* %this1 to i8*, !dbg !157 + %1 = getelementptr inbounds i8, i8* %this.int8, i64 0, !dbg !157 + %vbptr.DerivedClass = bitcast i8* %1 to i32**, !dbg !157 + store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8DerivedClass@@7B@", i32 0, i32 0), i32** %vbptr.DerivedClass, align 8, !dbg !157 + %2 = bitcast %class.DerivedClass* %this1 to i8*, !dbg !157 + %3 = getelementptr inbounds i8, i8* %2, i64 8, !dbg !157 + %4 = bitcast i8* %3 to %class.BaseA*, !dbg !157 + %5 = load %class.DerivedClass*, %class.DerivedClass** %.addr, align 8, !dbg !157 + %6 = bitcast %class.DerivedClass* %5 to i8*, !dbg !157 + %vbptr = getelementptr inbounds i8, i8* %6, i64 0, !dbg !157 + %7 = bitcast i8* %vbptr to i32**, !dbg !157 + %vbtable = load i32*, i32** %7, align 8, !dbg !157 + %8 = getelementptr inbounds i32, i32* %vbtable, i32 1, !dbg !157 + %vbase_offs = load i32, i32* %8, align 4, !dbg !157 + %9 = sext i32 %vbase_offs to i64, !dbg !157 + %10 = add nsw i64 0, %9, !dbg !157 + %11 = bitcast %class.DerivedClass* %5 to i8*, !dbg !157 + %add.ptr = getelementptr inbounds i8, i8* %11, i64 %10, !dbg !157 + %12 = bitcast i8* %add.ptr to %class.BaseA*, !dbg !157 + br label %ctor.skip_vbases, !dbg !157 + +ctor.skip_vbases: ; preds = %ctor.init_vbases, %entry + %13 = load %class.DerivedClass*, %class.DerivedClass** %retval, align 8, !dbg !157 + ret %class.DerivedClass* %13, !dbg !157 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local i8 @"?Func_DerivedClass_RtBase@@YA?AVBaseA@@AEAVDerivedClass@@@Z"(%class.DerivedClass* dereferenceable(8) %arg) #0 !dbg !158 { +entry: + %retval = alloca %class.BaseA, align 1 + %arg.addr = alloca %class.DerivedClass*, align 8 + store %class.DerivedClass* %arg, %class.DerivedClass** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.DerivedClass** %arg.addr, metadata !161, metadata !DIExpression()), !dbg !162 + %0 = load %class.DerivedClass*, %class.DerivedClass** %arg.addr, align 8, !dbg !163 + %1 = bitcast %class.DerivedClass* %0 to i8*, !dbg !163 + %vbptr = getelementptr inbounds i8, i8* %1, i64 0, !dbg !163 + %2 = bitcast i8* %vbptr to i32**, !dbg !163 + %vbtable = load i32*, i32** %2, align 8, !dbg !163 + %3 = getelementptr inbounds i32, i32* %vbtable, i32 1, !dbg !163 + %vbase_offs = load i32, i32* %3, align 4, !dbg !163 + %4 = sext i32 %vbase_offs to i64, !dbg !163 + %5 = add nsw i64 0, %4, !dbg !163 + %6 = bitcast %class.DerivedClass* %0 to i8*, !dbg !163 + %add.ptr = getelementptr inbounds i8, i8* %6, i64 %5, !dbg !163 + %7 = bitcast i8* %add.ptr to %class.BaseA*, !dbg !163 + %coerce.dive = getelementptr inbounds %class.BaseA, %class.BaseA* %retval, i32 0, i32 0, !dbg !163 + %8 = load i8, i8* %coerce.dive, align 1, !dbg !163 + ret i8 %8, !dbg !163 +} + +; Function Attrs: noinline nounwind optnone uwtable +define dso_local void @"?Func_ClassIVB@@YA?AVClassIVB@@AEAV1@@Z"(%class.ClassIVB* noalias sret %agg.result, %class.ClassIVB* dereferenceable(8) %arg) #0 !dbg !164 { +entry: + %arg.addr = alloca %class.ClassIVB*, align 8 + store %class.ClassIVB* %arg, %class.ClassIVB** %arg.addr, align 8 + call void @llvm.dbg.declare(metadata %class.ClassIVB** %arg.addr, metadata !175, metadata !DIExpression()), !dbg !176 + %0 = load %class.ClassIVB*, %class.ClassIVB** %arg.addr, align 8, !dbg !176 + %call = call %class.ClassIVB* @"??0ClassIVB@@QEAA@AEBV0@@Z"(%class.ClassIVB* %agg.result, %class.ClassIVB* dereferenceable(8) %0, i32 1) #3, !dbg !176 + ret void, !dbg !176 +} + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local %class.ClassIVB* @"??0ClassIVB@@QEAA@AEBV0@@Z"(%class.ClassIVB* returned %this, %class.ClassIVB* dereferenceable(8), i32 %is_most_derived) unnamed_addr #0 comdat align 2 !dbg !177 { +entry: + %retval = alloca %class.ClassIVB*, align 8 + %is_most_derived.addr = alloca i32, align 4 + %.addr = alloca %class.ClassIVB*, align 8 + %this.addr = alloca %class.ClassIVB*, align 8 + store i32 %is_most_derived, i32* %is_most_derived.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %is_most_derived.addr, metadata !184, metadata !DIExpression()), !dbg !185 + store %class.ClassIVB* %0, %class.ClassIVB** %.addr, align 8 + call void @llvm.dbg.declare(metadata %class.ClassIVB** %.addr, metadata !186, metadata !DIExpression()), !dbg !185 + store %class.ClassIVB* %this, %class.ClassIVB** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %class.ClassIVB** %this.addr, metadata !187, metadata !DIExpression()), !dbg !185 + %this1 = load %class.ClassIVB*, %class.ClassIVB** %this.addr, align 8 + store %class.ClassIVB* %this1, %class.ClassIVB** %retval, align 8 + %is_most_derived2 = load i32, i32* %is_most_derived.addr, align 4 + %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !189 + br i1 %is_complete_object, label %ctor.init_vbases, label %ctor.skip_vbases, !dbg !189 + +ctor.init_vbases: ; preds = %entry + %this.int8 = bitcast %class.ClassIVB* %this1 to i8*, !dbg !189 + %1 = getelementptr inbounds i8, i8* %this.int8, i64 0, !dbg !189 + %vbptr.ClassIVB = bitcast i8* %1 to i32**, !dbg !189 + store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8ClassIVB@@7B@", i32 0, i32 0), i32** %vbptr.ClassIVB, align 8, !dbg !189 + %2 = bitcast %class.ClassIVB* %this1 to i8*, !dbg !189 + %3 = getelementptr inbounds i8, i8* %2, i64 8, !dbg !189 + %4 = bitcast i8* %3 to %class.BaseA*, !dbg !189 + %5 = load %class.ClassIVB*, %class.ClassIVB** %.addr, align 8, !dbg !189 + %6 = bitcast %class.ClassIVB* %5 to i8*, !dbg !189 + %vbptr = getelementptr inbounds i8, i8* %6, i64 0, !dbg !189 + %7 = bitcast i8* %vbptr to i32**, !dbg !189 + %vbtable = load i32*, i32** %7, align 8, !dbg !189 + %8 = getelementptr inbounds i32, i32* %vbtable, i32 1, !dbg !189 + %vbase_offs = load i32, i32* %8, align 4, !dbg !189 + %9 = sext i32 %vbase_offs to i64, !dbg !189 + %10 = add nsw i64 0, %9, !dbg !189 + %11 = bitcast %class.ClassIVB* %5 to i8*, !dbg !189 + %add.ptr = getelementptr inbounds i8, i8* %11, i64 %10, !dbg !189 + %12 = bitcast i8* %add.ptr to %class.BaseA*, !dbg !189 + br label %ctor.skip_vbases, !dbg !189 + +ctor.skip_vbases: ; preds = %ctor.init_vbases, %entry + %13 = bitcast %class.ClassIVB* %this1 to %class.BaseB*, !dbg !189 + %14 = load %class.ClassIVB*, %class.ClassIVB** %.addr, align 8, !dbg !189 + %15 = bitcast %class.ClassIVB* %14 to %class.BaseB*, !dbg !189 + %call = call %class.BaseB* @"??0BaseB@@QEAA@AEBV0@@Z"(%class.BaseB* %13, %class.BaseB* dereferenceable(8) %15, i32 0) #3, !dbg !189 + %16 = load %class.ClassIVB*, %class.ClassIVB** %retval, align 8, !dbg !189 + ret %class.ClassIVB* %16, !dbg !189 +} + +declare dso_local void @"?f@EClass@@EEAAXXZ"(%class.EClass*) unnamed_addr #2 + +; Function Attrs: noinline nounwind optnone uwtable +define linkonce_odr dso_local %class.BaseB* @"??0BaseB@@QEAA@AEBV0@@Z"(%class.BaseB* returned %this, %class.BaseB* dereferenceable(8), i32 %is_most_derived) unnamed_addr #0 comdat align 2 !dbg !190 { +entry: + %retval = alloca %class.BaseB*, align 8 + %is_most_derived.addr = alloca i32, align 4 + %.addr = alloca %class.BaseB*, align 8 + %this.addr = alloca %class.BaseB*, align 8 + store i32 %is_most_derived, i32* %is_most_derived.addr, align 4 + call void @llvm.dbg.declare(metadata i32* %is_most_derived.addr, metadata !197, metadata !DIExpression()), !dbg !198 + store %class.BaseB* %0, %class.BaseB** %.addr, align 8 + call void @llvm.dbg.declare(metadata %class.BaseB** %.addr, metadata !199, metadata !DIExpression()), !dbg !198 + store %class.BaseB* %this, %class.BaseB** %this.addr, align 8 + call void @llvm.dbg.declare(metadata %class.BaseB** %this.addr, metadata !200, metadata !DIExpression()), !dbg !198 + %this1 = load %class.BaseB*, %class.BaseB** %this.addr, align 8 + store %class.BaseB* %this1, %class.BaseB** %retval, align 8 + %is_most_derived2 = load i32, i32* %is_most_derived.addr, align 4 + %is_complete_object = icmp ne i32 %is_most_derived2, 0, !dbg !202 + br i1 %is_complete_object, label %ctor.init_vbases, label %ctor.skip_vbases, !dbg !202 + +ctor.init_vbases: ; preds = %entry + %this.int8 = bitcast %class.BaseB* %this1 to i8*, !dbg !202 + %1 = getelementptr inbounds i8, i8* %this.int8, i64 0, !dbg !202 + %vbptr.BaseB = bitcast i8* %1 to i32**, !dbg !202 + store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"??_8BaseB@@7B@", i32 0, i32 0), i32** %vbptr.BaseB, align 8, !dbg !202 + %2 = bitcast %class.BaseB* %this1 to i8*, !dbg !202 + %3 = getelementptr inbounds i8, i8* %2, i64 8, !dbg !202 + %4 = bitcast i8* %3 to %class.BaseA*, !dbg !202 + %5 = load %class.BaseB*, %class.BaseB** %.addr, align 8, !dbg !202 + %6 = bitcast %class.BaseB* %5 to i8*, !dbg !202 + %vbptr = getelementptr inbounds i8, i8* %6, i64 0, !dbg !202 + %7 = bitcast i8* %vbptr to i32**, !dbg !202 + %vbtable = load i32*, i32** %7, align 8, !dbg !202 + %8 = getelementptr inbounds i32, i32* %vbtable, i32 1, !dbg !202 + %vbase_offs = load i32, i32* %8, align 4, !dbg !202 + %9 = sext i32 %vbase_offs to i64, !dbg !202 + %10 = add nsw i64 0, %9, !dbg !202 + %11 = bitcast %class.BaseB* %5 to i8*, !dbg !202 + %add.ptr = getelementptr inbounds i8, i8* %11, i64 %10, !dbg !202 + %12 = bitcast i8* %add.ptr to %class.BaseA*, !dbg !202 + br label %ctor.skip_vbases, !dbg !202 + +ctor.skip_vbases: ; preds = %ctor.init_vbases, %entry + %13 = load %class.BaseB*, %class.BaseB** %retval, align 8, !dbg !202 + ret %class.BaseB* %13, !dbg !202 +} + +attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { nounwind readnone speculatable } +attributes #2 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind } + +!llvm.dbg.cu = !{!0} +!llvm.module.flags = !{!3, !4, !5, !6} +!llvm.ident = !{!7} + +!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 7.0.0 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) +!1 = !DIFile(filename: "function-options.cpp", directory: "D:\5Cupstream\5Cllvm\5Ctest\5CDebugInfo\5CCOFF", checksumkind: CSK_MD5, checksum: "e8425d05013ed339612ad99075d6091d") +!2 = !{} +!3 = !{i32 2, !"CodeView", i32 1} +!4 = !{i32 2, !"Debug Info Version", i32 3} +!5 = !{i32 1, !"wchar_size", i32 2} +!6 = !{i32 7, !"PIC Level", i32 2} +!7 = !{!"clang version 7.0.0 "} +!8 = distinct !DISubprogram(name: "Func_AClass", linkageName: "?Func_AClass@@YA?AVAClass@@AEAV1@@Z", scope: !9, file: !9, line: 7, type: !10, isLocal: false, isDefinition: true, scopeLine: 7, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!9 = !DIFile(filename: "function-options.cpp", directory: "D:\5Cupstream\5Cllvm\5Ctest\5CDebugInfo\5CCOFF") +!10 = !DISubroutineType(types: !11) +!11 = !{!12, !13} +!12 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "AClass", file: !9, line: 6, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?AVAClass@@") +!13 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !12, size: 64) +!14 = !DILocalVariable(name: "arg", arg: 1, scope: !8, file: !9, line: 7, type: !13) +!15 = !DILocation(line: 7, scope: !8) +!16 = distinct !DISubprogram(name: "Func_BClass", linkageName: "?Func_BClass@@YA?AVBClass@@AEAV1@@Z", scope: !9, file: !9, line: 14, type: !17, isLocal: false, isDefinition: true, scopeLine: 14, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!17 = !DISubroutineType(types: !18) +!18 = !{!19, !25} +!19 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "BClass", file: !9, line: 10, size: 8, flags: DIFlagTypePassByValue, elements: !20, identifier: ".?AVBClass@@") +!20 = !{!21} +!21 = !DISubprogram(name: "BClass", scope: !19, file: !9, line: 12, type: !22, isLocal: false, isDefinition: false, scopeLine: 12, flags: DIFlagExplicit | DIFlagPrototyped, isOptimized: false) +!22 = !DISubroutineType(types: !23) +!23 = !{null, !24} +!24 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !19, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!25 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !19, size: 64) +!26 = !DILocalVariable(name: "arg", arg: 1, scope: !16, file: !9, line: 14, type: !25) +!27 = !DILocation(line: 14, scope: !16) +!28 = distinct !DISubprogram(name: "Func_C1Class", linkageName: "?Func_C1Class@@YA?AVC1Class@@AEAV1@@Z", scope: !9, file: !9, line: 22, type: !29, isLocal: false, isDefinition: true, scopeLine: 22, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!29 = !DISubroutineType(types: !30) +!30 = !{!31, !37} +!31 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "C1Class", file: !9, line: 17, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !32, identifier: ".?AVC1Class@@") +!32 = !{!33} +!33 = !DISubprogram(name: "C1Class", scope: !31, file: !9, line: 19, type: !34, isLocal: false, isDefinition: false, scopeLine: 19, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false) +!34 = !DISubroutineType(types: !35) +!35 = !{null, !36} +!36 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !31, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!37 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !31, size: 64) +!38 = !DILocalVariable(name: "arg", arg: 1, scope: !28, file: !9, line: 22, type: !37) +!39 = !DILocation(line: 22, scope: !28) +!40 = distinct !DISubprogram(name: "Func_C2Class", linkageName: "?Func_C2Class@@YA?AVC2Class@@AEAV1@@Z", scope: !9, file: !9, line: 29, type: !41, isLocal: false, isDefinition: true, scopeLine: 29, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!41 = !DISubroutineType(types: !42) +!42 = !{!43, !49} +!43 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "C2Class", file: !9, line: 25, size: 8, flags: DIFlagTypePassByValue, elements: !44, identifier: ".?AVC2Class@@") +!44 = !{!45} +!45 = !DISubprogram(name: "~C2Class", scope: !43, file: !9, line: 27, type: !46, isLocal: false, isDefinition: false, scopeLine: 27, flags: DIFlagPublic | DIFlagPrototyped, isOptimized: false) +!46 = !DISubroutineType(types: !47) +!47 = !{null, !48} +!48 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !43, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!49 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !43, size: 64) +!50 = !DILocalVariable(name: "arg", arg: 1, scope: !40, file: !9, line: 29, type: !49) +!51 = !DILocation(line: 29, scope: !40) +!52 = distinct !DISubprogram(name: "Func_DClass", linkageName: "?Func_DClass@@YA?AVDClass@@AEAV1@@Z", scope: !9, file: !9, line: 36, type: !53, isLocal: false, isDefinition: true, scopeLine: 36, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!53 = !DISubroutineType(types: !54) +!54 = !{!55, !58} +!55 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "DClass", file: !9, line: 32, size: 8, flags: DIFlagTypePassByValue, elements: !56, identifier: ".?AVDClass@@") +!56 = !{!57} +!57 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !55, baseType: !19, flags: DIFlagPublic) +!58 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !55, size: 64) +!59 = !DILocalVariable(name: "arg", arg: 1, scope: !52, file: !9, line: 36, type: !58) +!60 = !DILocation(line: 36, scope: !52) +!61 = distinct !DISubprogram(name: "Func_EClass", linkageName: "?Func_EClass@@YA?AVEClass@@AEAV1@@Z", scope: !9, file: !9, line: 52, type: !62, isLocal: false, isDefinition: true, scopeLine: 52, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!62 = !DISubroutineType(types: !63) +!63 = !{!64, !73} +!64 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "EClass", file: !9, line: 39, size: 64, flags: DIFlagTypePassByReference, elements: !65, vtableHolder: !64, identifier: ".?AVEClass@@") +!65 = !{!66, !67, !69} +!66 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", baseType: null, size: 64) +!67 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$EClass", scope: !9, file: !9, baseType: !68, size: 64, flags: DIFlagArtificial) +!68 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !66, size: 64) +!69 = !DISubprogram(name: "f", linkageName: "?f@EClass@@EEAAXXZ", scope: !64, file: !9, line: 39, type: !70, isLocal: false, isDefinition: false, scopeLine: 39, containingType: !64, virtuality: DW_VIRTUALITY_virtual, virtualIndex: 0, flags: DIFlagPrototyped | DIFlagIntroducedVirtual, isOptimized: false) +!70 = !DISubroutineType(types: !71) +!71 = !{null, !72} +!72 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !64, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!73 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !64, size: 64) +!74 = !DILocalVariable(name: "arg", arg: 1, scope: !61, file: !9, line: 52, type: !73) +!75 = !DILocation(line: 52, scope: !61) +!76 = distinct !DISubprogram(name: "EClass", linkageName: "??0EClass@@QEAA@AEBV0@@Z", scope: !64, file: !9, line: 39, type: !77, isLocal: false, isDefinition: true, scopeLine: 39, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !81, variables: !2) +!77 = !DISubroutineType(types: !78) +!78 = !{null, !72, !79} +!79 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !80, size: 64) +!80 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !64) +!81 = !DISubprogram(name: "EClass", scope: !64, type: !77, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false) +!82 = !DILocalVariable(arg: 2, scope: !76, type: !79) +!83 = !DILocation(line: 0, scope: !76) +!84 = !DILocalVariable(name: "this", arg: 1, scope: !76, type: !85, flags: DIFlagArtificial | DIFlagObjectPointer) +!85 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !64, size: 64) +!86 = !DILocation(line: 39, scope: !76) +!87 = distinct !DISubprogram(name: "Func_FClass", linkageName: "?Func_FClass@@YA?AVFClass@@AEAV1@@Z", scope: !9, file: !9, line: 56, type: !88, isLocal: false, isDefinition: true, scopeLine: 56, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!88 = !DISubroutineType(types: !89) +!89 = !{!90, !94} +!90 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "FClass", file: !9, line: 55, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !91, identifier: ".?AVFClass@@") +!91 = !{!92} +!92 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !90, file: !9, line: 55, baseType: !93, flags: DIFlagStaticMember) +!93 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) +!94 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !90, size: 64) +!95 = !DILocalVariable(name: "arg", arg: 1, scope: !87, file: !9, line: 56, type: !94) +!96 = !DILocation(line: 56, scope: !87) +!97 = distinct !DISubprogram(name: "Func_AStruct", linkageName: "?Func_AStruct@@YA?AUAStruct@@AEAU1@@Z", scope: !9, file: !9, line: 60, type: !98, isLocal: false, isDefinition: true, scopeLine: 60, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!98 = !DISubroutineType(types: !99) +!99 = !{!100, !101} +!100 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "AStruct", file: !9, line: 59, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?AUAStruct@@") +!101 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !100, size: 64) +!102 = !DILocalVariable(name: "arg", arg: 1, scope: !97, file: !9, line: 60, type: !101) +!103 = !DILocation(line: 60, scope: !97) +!104 = distinct !DISubprogram(name: "Func_BStruct", linkageName: "?Func_BStruct@@YA?AUBStruct@@AEAU1@@Z", scope: !9, file: !9, line: 64, type: !105, isLocal: false, isDefinition: true, scopeLine: 64, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!105 = !DISubroutineType(types: !106) +!106 = !{!107, !113} +!107 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "BStruct", file: !9, line: 63, size: 8, flags: DIFlagTypePassByValue, elements: !108, identifier: ".?AUBStruct@@") +!108 = !{!109} +!109 = !DISubprogram(name: "BStruct", scope: !107, file: !9, line: 63, type: !110, isLocal: false, isDefinition: false, scopeLine: 63, flags: DIFlagPrototyped, isOptimized: false) +!110 = !DISubroutineType(types: !111) +!111 = !{null, !112} +!112 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !107, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!113 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !107, size: 64) +!114 = !DILocalVariable(name: "arg", arg: 1, scope: !104, file: !9, line: 64, type: !113) +!115 = !DILocation(line: 64, scope: !104) +!116 = distinct !DISubprogram(name: "Func_AUnion", linkageName: "?Func_AUnion@@YA?ATAUnion@@AEAT1@@Z", scope: !9, file: !9, line: 68, type: !117, isLocal: false, isDefinition: true, scopeLine: 68, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!117 = !DISubroutineType(types: !118) +!118 = !{!119, !120} +!119 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "AUnion", file: !9, line: 67, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?ATAUnion@@") +!120 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !119, size: 64) +!121 = !DILocalVariable(name: "arg", arg: 1, scope: !116, file: !9, line: 68, type: !120) +!122 = !DILocation(line: 68, scope: !116) +!123 = distinct !DISubprogram(name: "Func_BUnion", linkageName: "?Func_BUnion@@YA?ATBUnion@@AEAT1@@Z", scope: !9, file: !9, line: 73, type: !124, isLocal: false, isDefinition: true, scopeLine: 73, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!124 = !DISubroutineType(types: !125) +!125 = !{!126, !132} +!126 = distinct !DICompositeType(tag: DW_TAG_union_type, name: "BUnion", file: !9, line: 71, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !127, identifier: ".?ATBUnion@@") +!127 = !{!128} +!128 = !DISubprogram(name: "BUnion", scope: !126, file: !9, line: 71, type: !129, isLocal: false, isDefinition: false, scopeLine: 71, flags: DIFlagPrototyped, isOptimized: false) +!129 = !DISubroutineType(types: !130) +!130 = !{null, !131} +!131 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !126, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!132 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !126, size: 64) +!133 = !DILocalVariable(name: "arg", arg: 1, scope: !123, file: !9, line: 73, type: !132) +!134 = !DILocation(line: 73, scope: !123) +!135 = distinct !DISubprogram(name: "Func_DerivedClass", linkageName: "?Func_DerivedClass@@YA?AVDerivedClass@@AEAV1@@Z", scope: !9, file: !9, line: 111, type: !136, isLocal: false, isDefinition: true, scopeLine: 111, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!136 = !DISubroutineType(types: !137) +!137 = !{!138, !142} +!138 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "DerivedClass", file: !9, line: 88, size: 64, flags: DIFlagTypePassByReference, elements: !139, vtableHolder: !138, identifier: ".?AVDerivedClass@@") +!139 = !{!140} +!140 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !138, baseType: !141, offset: 4, flags: DIFlagPublic | DIFlagVirtual) +!141 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "BaseA", file: !9, line: 76, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !2, identifier: ".?AVBaseA@@") +!142 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !138, size: 64) +!143 = !DILocalVariable(name: "arg", arg: 1, scope: !135, file: !9, line: 111, type: !142) +!144 = !DILocation(line: 111, scope: !135) +!145 = distinct !DISubprogram(name: "DerivedClass", linkageName: "??0DerivedClass@@QEAA@AEBV0@@Z", scope: !138, file: !9, line: 88, type: !146, isLocal: false, isDefinition: true, scopeLine: 88, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !151, variables: !2) +!146 = !DISubroutineType(types: !147) +!147 = !{null, !148, !149} +!148 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !138, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!149 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !150, size: 64) +!150 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !138) +!151 = !DISubprogram(name: "DerivedClass", scope: !138, type: !146, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false) +!152 = !DILocalVariable(name: "is_most_derived", arg: 3, scope: !145, type: !93, flags: DIFlagArtificial) +!153 = !DILocation(line: 0, scope: !145) +!154 = !DILocalVariable(arg: 2, scope: !145, type: !149) +!155 = !DILocalVariable(name: "this", arg: 1, scope: !145, type: !156, flags: DIFlagArtificial | DIFlagObjectPointer) +!156 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !138, size: 64) +!157 = !DILocation(line: 88, scope: !145) +!158 = distinct !DISubprogram(name: "Func_DerivedClass_RtBase", linkageName: "?Func_DerivedClass_RtBase@@YA?AVBaseA@@AEAVDerivedClass@@@Z", scope: !9, file: !9, line: 113, type: !159, isLocal: false, isDefinition: true, scopeLine: 113, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!159 = !DISubroutineType(types: !160) +!160 = !{!141, !142} +!161 = !DILocalVariable(name: "arg", arg: 1, scope: !158, file: !9, line: 113, type: !142) +!162 = !DILocation(line: 113, scope: !158) +!163 = !DILocation(line: 114, scope: !158) +!164 = distinct !DISubprogram(name: "Func_ClassIVB", linkageName: "?Func_ClassIVB@@YA?AVClassIVB@@AEAV1@@Z", scope: !9, file: !9, line: 117, type: !165, isLocal: false, isDefinition: true, scopeLine: 117, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2) +!165 = !DISubroutineType(types: !166) +!166 = !{!167, !174} +!167 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "ClassIVB", file: !9, line: 99, size: 64, flags: DIFlagTypePassByReference, elements: !168, vtableHolder: !167, identifier: ".?AVClassIVB@@") +!168 = !{!169, !173} +!169 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !167, baseType: !170, flags: DIFlagPublic) +!170 = distinct !DICompositeType(tag: DW_TAG_class_type, name: "BaseB", file: !9, line: 77, size: 64, flags: DIFlagTypePassByReference, elements: !171, vtableHolder: !170, identifier: ".?AVBaseB@@") +!171 = !{!172} +!172 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !170, baseType: !141, offset: 4, flags: DIFlagPublic | DIFlagVirtual) +!173 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !167, baseType: !141, offset: 4, flags: DIFlagPublic | DIFlagIndirectVirtualBase) +!174 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !167, size: 64) +!175 = !DILocalVariable(name: "arg", arg: 1, scope: !164, file: !9, line: 117, type: !174) +!176 = !DILocation(line: 117, scope: !164) +!177 = distinct !DISubprogram(name: "ClassIVB", linkageName: "??0ClassIVB@@QEAA@AEBV0@@Z", scope: !167, file: !9, line: 99, type: !178, isLocal: false, isDefinition: true, scopeLine: 99, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !183, variables: !2) +!178 = !DISubroutineType(types: !179) +!179 = !{null, !180, !181} +!180 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !167, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!181 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !182, size: 64) +!182 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !167) +!183 = !DISubprogram(name: "ClassIVB", scope: !167, type: !178, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false) +!184 = !DILocalVariable(name: "is_most_derived", arg: 3, scope: !177, type: !93, flags: DIFlagArtificial) +!185 = !DILocation(line: 0, scope: !177) +!186 = !DILocalVariable(arg: 2, scope: !177, type: !181) +!187 = !DILocalVariable(name: "this", arg: 1, scope: !177, type: !188, flags: DIFlagArtificial | DIFlagObjectPointer) +!188 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !167, size: 64) +!189 = !DILocation(line: 99, scope: !177) +!190 = distinct !DISubprogram(name: "BaseB", linkageName: "??0BaseB@@QEAA@AEBV0@@Z", scope: !170, file: !9, line: 77, type: !191, isLocal: false, isDefinition: true, scopeLine: 77, flags: DIFlagArtificial | DIFlagPrototyped, isOptimized: false, unit: !0, declaration: !196, variables: !2) +!191 = !DISubroutineType(types: !192) +!192 = !{null, !193, !194} +!193 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !170, size: 64, flags: DIFlagArtificial | DIFlagObjectPointer) +!194 = !DIDerivedType(tag: DW_TAG_reference_type, baseType: !195, size: 64) +!195 = !DIDerivedType(tag: DW_TAG_const_type, baseType: !170) +!196 = !DISubprogram(name: "BaseB", scope: !170, type: !191, isLocal: false, isDefinition: false, flags: DIFlagPublic | DIFlagArtificial | DIFlagPrototyped, isOptimized: false) +!197 = !DILocalVariable(name: "is_most_derived", arg: 3, scope: !190, type: !93, flags: DIFlagArtificial) +!198 = !DILocation(line: 0, scope: !190) +!199 = !DILocalVariable(arg: 2, scope: !190, type: !194) +!200 = !DILocalVariable(name: "this", arg: 1, scope: !190, type: !201, flags: DIFlagArtificial | DIFlagObjectPointer) +!201 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !170, size: 64) +!202 = !DILocation(line: 77, scope: !190) Index: DebugInfo/COFF/global-type-hashes.ll =================================================================== --- DebugInfo/COFF/global-type-hashes.ll +++ DebugInfo/COFF/global-type-hashes.ll @@ -196,7 +196,7 @@ ; YAML: ClassType: 4100 ; YAML: ThisType: 4101 ; YAML: CallConv: ThisCall -; YAML: Options: [ None ] +; YAML: Options: [ None, Constructor ] ; YAML: ParameterCount: 2 ; YAML: ArgumentList: 4102 ; YAML: ThisPointerAdjustment: 0 @@ -282,14 +282,14 @@ ; YAML: - CF1B3AD4A96BA628E6556FD28A222FBBEBBE140E ; YAML: - EC50195BFE148C0DC6A87A59D49CA1D9B146DB86 ; YAML: - 123C8BA63AD23386897AB6D814A9932F03846156 -; YAML: - 0F135243878289B83835BC2DB9EE25A1D4D0DA2B +; YAML: - 988E6FAF4E502E209D2B245BBE9ED6E9283E07A5 ; YAML: - 9069CA78E7450A285173431B3E52C5C25299E473 ; YAML: - ADA6E11350E9F2069D4689E3646C90D67B28DA62 -; YAML: - BD535FA9877A4DD123840AF849F3B0110EEB1D7A -; YAML: - 8044F70193FE40B71867158C5E50F0467485FA99 +; YAML: - E5DEE15A41645460882F66F2DD27C31C966B0965 +; YAML: - A12A278EF27AEA3FDF0F57B1A9D3069ABCD7C7AC ; YAML: - 558606D57A76D125B705FC6DD18EEE3C1C0C4C09 -; YAML: - A64A018D9EB1EB8015917925662C8508D81CDA68 -; YAML: - 51E89AD9992AC6F11F9E3F1665F41C53BDA8AFC4 +; YAML: - 989CC70602F7966AE6B29B0342465C222311D023 +; YAML: - 356D00B76D8552CC712B44E9709E4F3E688BBC26 ; YAML: - 4F1C3BCA73099EF3466AAC99CC4951767DF890F5 ; ...