diff options
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 66 |
1 files changed, 45 insertions, 21 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 59056b0ff5d..6d43143253e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1882,27 +1882,22 @@ TypeIndex CodeViewDebug::lowerTypeMemberFunction(const DISubroutineType *Ty, // Lower the containing class type. TypeIndex ClassType = getTypeIndex(ClassTy); - SmallVector<TypeIndex, 8> ReturnAndArgTypeIndices; - for (DITypeRef ArgTypeRef : Ty->getTypeArray()) - ReturnAndArgTypeIndices.push_back(getTypeIndex(ArgTypeRef)); + DITypeRefArray ReturnAndArgs = Ty->getTypeArray(); + + unsigned Index = 0; + SmallVector<TypeIndex, 8> ArgTypeIndices; + TypeIndex ReturnTypeIndex = getTypeIndex(ReturnAndArgs[Index++]); - // MSVC uses type none for variadic argument. - if (ReturnAndArgTypeIndices.size() > 1 && - ReturnAndArgTypeIndices.back() == TypeIndex::Void()) { - ReturnAndArgTypeIndices.back() = TypeIndex::None(); - } - TypeIndex ReturnTypeIndex = TypeIndex::Void(); - ArrayRef<TypeIndex> ArgTypeIndices = None; - if (!ReturnAndArgTypeIndices.empty()) { - auto ReturnAndArgTypesRef = makeArrayRef(ReturnAndArgTypeIndices); - ReturnTypeIndex = ReturnAndArgTypesRef.front(); - ArgTypeIndices = ReturnAndArgTypesRef.drop_front(); - } TypeIndex ThisTypeIndex; - if (!IsStaticMethod && !ArgTypeIndices.empty()) { - ThisTypeIndex = ArgTypeIndices.front(); - ArgTypeIndices = ArgTypeIndices.drop_front(); - } + if (!IsStaticMethod && ReturnAndArgs.size() > 1) + ThisTypeIndex = getTypeIndexForThisPtr(ReturnAndArgs[Index++], Ty); + + while (Index < ReturnAndArgs.size()) + ArgTypeIndices.push_back(getTypeIndex(ReturnAndArgs[Index++])); + + // MSVC uses type none for variadic argument. + if (!ArgTypeIndices.empty() && ArgTypeIndices.back() == TypeIndex::Void()) + ArgTypeIndices.back() = TypeIndex::None(); ArgListRecord ArgListRec(TypeRecordKind::ArgList, ArgTypeIndices); TypeIndex ArgListIndex = TypeTable.writeLeafType(ArgListRec); @@ -1992,8 +1987,8 @@ static ClassOptions getCommonClassOptions(const DICompositeType *Ty) { CO |= ClassOptions::Nested; // Put the Scoped flag on function-local types. MSVC puts this flag for enum - // type only when it has an immediate function scope. Clang never puts enums - // inside DILexicalBlock scopes. Enum types, as generated by clang, are + // type only when it has an immediate function scope. Clang never puts enums + // inside DILexicalBlock scopes. Enum types, as generated by clang, are // always in function, class, or file scopes. if (Ty->getTag() == dwarf::DW_TAG_enumeration_type) { if (ImmediateScope && isa<DISubprogram>(ImmediateScope)) @@ -2449,6 +2444,35 @@ TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) { return recordTypeIndexForDINode(Ty, TI, ClassTy); } +codeview::TypeIndex +CodeViewDebug::getTypeIndexForThisPtr(DITypeRef TypeRef, + const DISubroutineType *SubroutineTy) { + const DIType *Ty = TypeRef.resolve(); + + PointerOptions Options = PointerOptions::None; + if (SubroutineTy->getFlags() & DINode::DIFlags::FlagLValueReference) + Options = PointerOptions::LValueRefThisPointer; + else if (SubroutineTy->getFlags() & DINode::DIFlags::FlagRValueReference) + Options = PointerOptions::RValueRefThisPointer; + + // Check if we've already translated this type. If there is no ref qualifier + // on the function then we look up this pointer type with no associated class + // so that the TypeIndex for the this pointer can be shared with the type + // index for other pointers to this class type. If there is a ref qualifier + // then we lookup the pointer using the subroutine as the parent type. + const DIType *ParentTy = nullptr; + if (Options != PointerOptions::None) + ParentTy = SubroutineTy; + + auto I = TypeIndices.find({Ty, SubroutineTy}); + if (I != TypeIndices.end()) + return I->second; + + TypeLoweringScope S(*this); + TypeIndex TI = lowerTypePointer(cast<DIDerivedType>(Ty), Options); + return recordTypeIndexForDINode(Ty, TI, SubroutineTy); +} + TypeIndex CodeViewDebug::getTypeIndexForReferenceTo(DITypeRef TypeRef) { DIType *Ty = TypeRef.resolve(); PointerRecord PR(getTypeIndex(Ty), |