diff options
author | Reid Kleckner <rnk@google.com> | 2016-07-01 02:41:21 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2016-07-01 02:41:21 +0000 |
commit | b5af11dfa3474363ff04494ad6cfb18ef8d067b5 (patch) | |
tree | 1fb8861cbe7618e77ad95a5a372c1318ee055de4 /llvm/lib | |
parent | a8576706e378ef10ea79ed381eddea0238a21353 (diff) | |
download | bcm5719-llvm-b5af11dfa3474363ff04494ad6cfb18ef8d067b5.tar.gz bcm5719-llvm-b5af11dfa3474363ff04494ad6cfb18ef8d067b5.zip |
[codeview] Add DISubprogram::ThisAdjustment
Summary:
This represents the adjustment applied to the implicit 'this' parameter
in the prologue of a virtual method in the MS C++ ABI. The adjustment is
always zero unless multiple inheritance is involved.
This increases the size of DISubprogram by 8 bytes, unfortunately. The
adjustment really is a signed 32-bit integer. If this size increase is
too much, we could probably win it back by splitting out a subclass with
info specific to virtual methods (virtuality, vindex, thisadjustment,
containingType).
Reviewers: aprantl, dexonsmith
Subscribers: aaboud, amccarth, llvm-commits
Differential Revision: http://reviews.llvm.org/D21614
llvm-svn: 274325
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 8 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 37 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 51 | ||||
-rw-r--r-- | llvm/lib/IR/AsmWriter.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/IR/DIBuilder.cpp | 15 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 22 | ||||
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 23 |
8 files changed, 93 insertions, 65 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index bf4934c4f73..c5216a2ad6d 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3983,7 +3983,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) { /// file: !1, line: 7, type: !2, isLocal: false, /// isDefinition: true, scopeLine: 8, containingType: !3, /// virtuality: DW_VIRTUALTIY_pure_virtual, -/// virtualIndex: 10, flags: 11, +/// virtualIndex: 10, thisAdjustment: 4, flags: 11, /// isOptimized: false, templateParams: !4, declaration: !5, /// variables: !6) bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { @@ -4001,6 +4001,7 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { OPTIONAL(containingType, MDField, ); \ OPTIONAL(virtuality, DwarfVirtualityField, ); \ OPTIONAL(virtualIndex, MDUnsignedField, (0, UINT32_MAX)); \ + OPTIONAL(thisAdjustment, MDSignedField, (0, INT32_MIN, INT32_MAX)); \ OPTIONAL(flags, DIFlagField, ); \ OPTIONAL(isOptimized, MDBoolField, ); \ OPTIONAL(unit, MDField, ); \ @@ -4019,8 +4020,9 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) { DISubprogram, (Context, scope.Val, name.Val, linkageName.Val, file.Val, line.Val, type.Val, isLocal.Val, isDefinition.Val, scopeLine.Val, containingType.Val, virtuality.Val, - virtualIndex.Val, flags.Val, isOptimized.Val, unit.Val, - templateParams.Val, declaration.Val, variables.Val)); + virtualIndex.Val, thisAdjustment.Val, flags.Val, + isOptimized.Val, unit.Val, templateParams.Val, + declaration.Val, variables.Val)); return false; } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index cdb6a1f30bf..4689d37b1b8 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2466,7 +2466,7 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { break; } case bitc::METADATA_SUBPROGRAM: { - if (Record.size() != 18 && Record.size() != 19) + if (Record.size() < 18 || Record.size() > 20) return error("Invalid record"); IsDistinct = @@ -2474,21 +2474,36 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) { // Version 1 has a Function as Record[15]. // Version 2 has removed Record[15]. // Version 3 has the Unit as Record[15]. + // Version 4 added thisAdjustment. bool HasUnit = Record[0] >= 2; - if (HasUnit && Record.size() != 19) + if (HasUnit && Record.size() < 19) return error("Invalid record"); Metadata *CUorFn = getMDOrNull(Record[15]); - unsigned Offset = Record.size() == 19 ? 1 : 0; + unsigned Offset = Record.size() >= 19 ? 1 : 0; bool HasFn = Offset && !HasUnit; + bool HasThisAdj = Record.size() >= 20; DISubprogram *SP = GET_OR_DISTINCT( - DISubprogram, - (Context, getDITypeRefOrNull(Record[1]), getMDString(Record[2]), - getMDString(Record[3]), getMDOrNull(Record[4]), Record[5], - getMDOrNull(Record[6]), Record[7], Record[8], Record[9], - getDITypeRefOrNull(Record[10]), Record[11], Record[12], Record[13], - Record[14], HasUnit ? CUorFn : nullptr, - getMDOrNull(Record[15 + Offset]), getMDOrNull(Record[16 + Offset]), - getMDOrNull(Record[17 + Offset]))); + DISubprogram, (Context, + getDITypeRefOrNull(Record[1]), // scope + getMDString(Record[2]), // name + getMDString(Record[3]), // linkageName + getMDOrNull(Record[4]), // file + Record[5], // line + getMDOrNull(Record[6]), // type + Record[7], // isLocal + Record[8], // isDefinition + Record[9], // scopeLine + getDITypeRefOrNull(Record[10]), // containingType + Record[11], // virtuality + Record[12], // virtualIndex + HasThisAdj ? Record[19] : 0, // thisAdjustment + Record[13], // flags + Record[14], // isOptimized + HasUnit ? CUorFn : nullptr, // unit + getMDOrNull(Record[15 + Offset]), // templateParams + getMDOrNull(Record[16 + Offset]), // declaration + getMDOrNull(Record[17 + Offset]) // variables + )); MetadataList.assignValue(SP, NextMetadataNo++); // Upgrade sp->function mapping to function->sp mapping. diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 971d21ecc2f..d3174fd504c 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1543,6 +1543,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N, Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get())); Record.push_back(VE.getMetadataOrNullID(N->getDeclaration())); Record.push_back(VE.getMetadataOrNullID(N->getVariables().get())); + Record.push_back(N->getThisAdjustment()); Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev); Record.clear(); diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index a6bcf9e848d..598957fcab4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -156,6 +156,18 @@ static std::string getFullyQualifiedName(const DIScope *Scope, StringRef Name) { return getQualifiedName(QualifiedNameComponents, Name); } +struct CodeViewDebug::TypeLoweringScope { + TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; } + ~TypeLoweringScope() { + // Don't decrement TypeEmissionLevel until after emitting deferred types, so + // inner TypeLoweringScopes don't attempt to emit deferred types. + if (CVD.TypeEmissionLevel == 1) + CVD.emitDeferredCompleteTypes(); + --CVD.TypeEmissionLevel; + } + CodeViewDebug &CVD; +}; + TypeIndex CodeViewDebug::getScopeIndex(const DIScope *Scope) { // No scope means global scope and that uses the zero index. if (!Scope || isa<DIFile>(Scope)) @@ -213,16 +225,24 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) { TypeIndex CodeViewDebug::getMemberFunctionType(const DISubprogram *SP, const DICompositeType *Class) { + // Always use the method declaration as the key for the function type. The + // method declaration contains the this adjustment. + if (SP->getDeclaration()) + SP = SP->getDeclaration(); + assert(!SP->getDeclaration() && "should use declaration as key"); + // Key the MemberFunctionRecord into the map as {SP, Class}. It won't collide // with the MemberFuncIdRecord, which is keyed in as {SP, nullptr}. - auto I = TypeIndices.find({SP, nullptr}); + auto I = TypeIndices.find({SP, Class}); if (I != TypeIndices.end()) return I->second; - // FIXME: Get the ThisAdjustment off of SP when it is available. + // Make sure complete type info for the class is emitted *after* the member + // function type, as the complete class type is likely to reference this + // member function type. + TypeLoweringScope S(*this); TypeIndex TI = - lowerTypeMemberFunction(SP->getType(), Class, /*ThisAdjustment=*/0); - + lowerTypeMemberFunction(SP->getType(), Class, SP->getThisAdjustment()); return recordTypeIndexForDINode(SP, TI, Class); } @@ -1582,18 +1602,6 @@ TypeIndex CodeViewDebug::getVBPTypeIndex() { return VBPType; } -struct CodeViewDebug::TypeLoweringScope { - TypeLoweringScope(CodeViewDebug &CVD) : CVD(CVD) { ++CVD.TypeEmissionLevel; } - ~TypeLoweringScope() { - // Don't decrement TypeEmissionLevel until after emitting deferred types, so - // inner TypeLoweringScopes don't attempt to emit deferred types. - if (CVD.TypeEmissionLevel == 1) - CVD.emitDeferredCompleteTypes(); - --CVD.TypeEmissionLevel; - } - CodeViewDebug &CVD; -}; - TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) { const DIType *Ty = TypeRef.resolve(); const DIType *ClassTy = ClassTyRef.resolve(); @@ -1609,14 +1617,9 @@ TypeIndex CodeViewDebug::getTypeIndex(DITypeRef TypeRef, DITypeRef ClassTyRef) { if (I != TypeIndices.end()) return I->second; - TypeIndex TI; - { - TypeLoweringScope S(*this); - TI = lowerType(Ty, ClassTy); - recordTypeIndexForDINode(Ty, TI, ClassTy); - } - - return TI; + TypeLoweringScope S(*this); + TypeIndex TI = lowerType(Ty, ClassTy); + return recordTypeIndexForDINode(Ty, TI, ClassTy); } TypeIndex CodeViewDebug::getCompleteTypeIndex(DITypeRef TypeRef) { diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp index b0c6984943e..9b2399dd880 100644 --- a/llvm/lib/IR/AsmWriter.cpp +++ b/llvm/lib/IR/AsmWriter.cpp @@ -1720,6 +1720,7 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N, if (N->getVirtuality() != dwarf::DW_VIRTUALITY_none || N->getVirtualIndex() != 0) Printer.printInt("virtualIndex", N->getVirtualIndex(), false); + Printer.printInt("thisAdjustment", N->getThisAdjustment()); Printer.printDIFlags("flags", N->getFlags()); Printer.printBool("isOptimized", N->isOptimized()); Printer.printMetadata("unit", N->getRawUnit()); diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp index ce16fdd6894..faf6bf753a9 100644 --- a/llvm/lib/IR/DIBuilder.cpp +++ b/llvm/lib/IR/DIBuilder.cpp @@ -667,8 +667,8 @@ DISubprogram *DIBuilder::createFunction( auto *Node = getSubprogram( /* IsDistinct = */ isDefinition, VMContext, getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty, - isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, Flags, isOptimized, - isDefinition ? CUNode : nullptr, TParams, Decl, + isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, 0, Flags, + isOptimized, isDefinition ? CUNode : nullptr, TParams, Decl, MDTuple::getTemporary(VMContext, None).release()); if (isDefinition) @@ -685,8 +685,8 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl( return DISubprogram::getTemporary( VMContext, getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, nullptr, - 0, 0, Flags, isOptimized, isDefinition ? CUNode : nullptr, TParams, - Decl, nullptr) + 0, 0, 0, Flags, isOptimized, isDefinition ? CUNode : nullptr, + TParams, Decl, nullptr) .release(); } @@ -694,8 +694,9 @@ DISubprogram * DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F, unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit, bool isDefinition, unsigned VK, - unsigned VIndex, DIType *VTableHolder, unsigned Flags, - bool isOptimized, DITemplateParameterArray TParams) { + unsigned VIndex, int ThisAdjustment, + DIType *VTableHolder, unsigned Flags, bool isOptimized, + DITemplateParameterArray TParams) { assert(getNonCompileUnitScope(Context) && "Methods should have both a Context and a context that isn't " "the compile unit."); @@ -703,7 +704,7 @@ DIBuilder::createMethod(DIScope *Context, StringRef Name, StringRef LinkageName, auto *SP = getSubprogram( /* IsDistinct = */ isDefinition, VMContext, cast<DIScope>(Context), Name, LinkageName, F, LineNo, Ty, isLocalToUnit, isDefinition, LineNo, - VTableHolder, VK, VIndex, Flags, isOptimized, + VTableHolder, VK, VIndex, ThisAdjustment, Flags, isOptimized, isDefinition ? CUNode : nullptr, TParams, nullptr, nullptr); if (isDefinition) diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index ea4ebf088c1..c58e3685b3c 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -412,22 +412,22 @@ DISubprogram *DISubprogram::getImpl( MDString *LinkageName, Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex, - unsigned Flags, bool IsOptimized, Metadata *Unit, Metadata *TemplateParams, - Metadata *Declaration, Metadata *Variables, StorageType Storage, - bool ShouldCreate) { + int ThisAdjustment, unsigned Flags, bool IsOptimized, Metadata *Unit, + Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables, + StorageType Storage, bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); assert(isCanonical(LinkageName) && "Expected canonical MDString"); - DEFINE_GETIMPL_LOOKUP(DISubprogram, - (Scope, Name, LinkageName, File, Line, Type, - IsLocalToUnit, IsDefinition, ScopeLine, ContainingType, - Virtuality, VirtualIndex, Flags, IsOptimized, Unit, - TemplateParams, Declaration, Variables)); + DEFINE_GETIMPL_LOOKUP( + DISubprogram, + (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition, + ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, + Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables)); Metadata *Ops[] = {File, Scope, Name, Name, LinkageName, Type, ContainingType, Unit, TemplateParams, Declaration, Variables}; - DEFINE_GETIMPL_STORE(DISubprogram, - (Line, ScopeLine, Virtuality, VirtualIndex, Flags, - IsLocalToUnit, IsDefinition, IsOptimized), + DEFINE_GETIMPL_STORE(DISubprogram, (Line, ScopeLine, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsLocalToUnit, + IsDefinition, IsOptimized), Ops); } diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index b1c91c6bcdb..cb4e79ac74e 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -528,6 +528,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> { Metadata *ContainingType; unsigned Virtuality; unsigned VirtualIndex; + int ThisAdjustment; unsigned Flags; bool IsOptimized; Metadata *Unit; @@ -539,15 +540,16 @@ template <> struct MDNodeKeyImpl<DISubprogram> { Metadata *File, unsigned Line, Metadata *Type, bool IsLocalToUnit, bool IsDefinition, unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality, - unsigned VirtualIndex, unsigned Flags, bool IsOptimized, - Metadata *Unit, Metadata *TemplateParams, Metadata *Declaration, - Metadata *Variables) + unsigned VirtualIndex, int ThisAdjustment, unsigned Flags, + bool IsOptimized, Metadata *Unit, Metadata *TemplateParams, + Metadata *Declaration, Metadata *Variables) : Scope(Scope), Name(Name), LinkageName(LinkageName), File(File), Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit), IsDefinition(IsDefinition), ScopeLine(ScopeLine), ContainingType(ContainingType), Virtuality(Virtuality), - VirtualIndex(VirtualIndex), Flags(Flags), IsOptimized(IsOptimized), - Unit(Unit), TemplateParams(TemplateParams), Declaration(Declaration), + VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment), + Flags(Flags), IsOptimized(IsOptimized), Unit(Unit), + TemplateParams(TemplateParams), Declaration(Declaration), Variables(Variables) {} MDNodeKeyImpl(const DISubprogram *N) : Scope(N->getRawScope()), Name(N->getRawName()), @@ -556,8 +558,9 @@ template <> struct MDNodeKeyImpl<DISubprogram> { IsLocalToUnit(N->isLocalToUnit()), IsDefinition(N->isDefinition()), ScopeLine(N->getScopeLine()), ContainingType(N->getRawContainingType()), Virtuality(N->getVirtuality()), VirtualIndex(N->getVirtualIndex()), - Flags(N->getFlags()), IsOptimized(N->isOptimized()), - Unit(N->getRawUnit()), TemplateParams(N->getRawTemplateParams()), + ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()), + IsOptimized(N->isOptimized()), Unit(N->getRawUnit()), + TemplateParams(N->getRawTemplateParams()), Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {} bool isKeyOf(const DISubprogram *RHS) const { @@ -569,8 +572,10 @@ template <> struct MDNodeKeyImpl<DISubprogram> { ScopeLine == RHS->getScopeLine() && ContainingType == RHS->getRawContainingType() && Virtuality == RHS->getVirtuality() && - VirtualIndex == RHS->getVirtualIndex() && Flags == RHS->getFlags() && - IsOptimized == RHS->isOptimized() && Unit == RHS->getUnit() && + VirtualIndex == RHS->getVirtualIndex() && + ThisAdjustment == RHS->getThisAdjustment() && + Flags == RHS->getFlags() && IsOptimized == RHS->isOptimized() && + Unit == RHS->getUnit() && TemplateParams == RHS->getRawTemplateParams() && Declaration == RHS->getRawDeclaration() && Variables == RHS->getRawVariables(); |