mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:40:38 +00:00
Add support for DW_TAG_thrown_type.
For Swift we would like to be able to encode the error types that a function may throw, so the debugger can display them alongside the function's return value when finish-ing a function. DWARF defines DW_TAG_thrown_type (intended to be used for C++ throw() declarations) that is a perfect fit for this purpose. This patch wires up support for DW_TAG_thrown_type in LLVM by adding a list of thrown types to DISubprogram. To offset the cost of the extra pointer, there is a follow-up patch that turns DISubprogram into a variable-length node. rdar://problem/29481673 Differential Revision: https://reviews.llvm.org/D32559 llvm-svn: 301489
This commit is contained in:
parent
7cdb7b7867
commit
23c2febb59
@ -577,15 +577,14 @@ namespace llvm {
|
||||
/// These flags are used to emit dwarf attributes.
|
||||
/// \param isOptimized True if optimization is ON.
|
||||
/// \param TParams Function template parameters.
|
||||
DISubprogram *createFunction(DIScope *Scope, StringRef Name,
|
||||
StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty,
|
||||
bool isLocalToUnit, bool isDefinition,
|
||||
unsigned ScopeLine,
|
||||
DINode::DIFlags Flags = DINode::FlagZero,
|
||||
bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DISubprogram *Decl = nullptr);
|
||||
/// \param ThrownTypes Exception types this function may throw.
|
||||
DISubprogram *createFunction(
|
||||
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned ScopeLine,
|
||||
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr);
|
||||
|
||||
/// Identical to createFunction,
|
||||
/// except that the resulting DbgNode is meant to be RAUWed.
|
||||
@ -595,7 +594,7 @@ namespace llvm {
|
||||
bool isDefinition, unsigned ScopeLine,
|
||||
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DISubprogram *Decl = nullptr);
|
||||
DISubprogram *Decl = nullptr, DITypeArray ThrownTypes = nullptr);
|
||||
|
||||
/// Create a new descriptor for the specified C++ method.
|
||||
/// See comments in \a DISubprogram* for descriptions of these fields.
|
||||
@ -619,13 +618,15 @@ namespace llvm {
|
||||
/// This flags are used to emit dwarf attributes.
|
||||
/// \param isOptimized True if optimization is ON.
|
||||
/// \param TParams Function template parameters.
|
||||
/// \param ThrownTypes Exception types this function may throw.
|
||||
DISubprogram *createMethod(
|
||||
DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned Virtuality = 0, unsigned VTableIndex = 0,
|
||||
int ThisAdjustment = 0, DIType *VTableHolder = nullptr,
|
||||
DINode::DIFlags Flags = DINode::FlagZero, bool isOptimized = false,
|
||||
DITemplateParameterArray TParams = nullptr);
|
||||
DITemplateParameterArray TParams = nullptr,
|
||||
DITypeArray ThrownTypes = nullptr);
|
||||
|
||||
/// This creates new descriptor for a namespace with the specified
|
||||
/// parent scope.
|
||||
|
@ -1509,14 +1509,14 @@ class DISubprogram : public DILocalScope {
|
||||
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
|
||||
bool IsOptimized, DICompileUnit *Unit,
|
||||
DITemplateParameterArray TemplateParams, DISubprogram *Declaration,
|
||||
DILocalVariableArray Variables, StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
DILocalVariableArray Variables, DITypeArray ThrownTypes,
|
||||
StorageType Storage, bool ShouldCreate = true) {
|
||||
return getImpl(Context, Scope, getCanonicalMDString(Context, Name),
|
||||
getCanonicalMDString(Context, LinkageName), File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams.get(), Declaration, Variables.get(),
|
||||
Storage, ShouldCreate);
|
||||
ThrownTypes.get(), Storage, ShouldCreate);
|
||||
}
|
||||
static DISubprogram *
|
||||
getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
|
||||
@ -1525,15 +1525,16 @@ class DISubprogram : public DILocalScope {
|
||||
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
|
||||
int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
|
||||
Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
Metadata *ThrownTypes, StorageType Storage, bool ShouldCreate = true);
|
||||
|
||||
TempDISubprogram cloneImpl() const {
|
||||
return getTemporary(
|
||||
getContext(), getScope(), getName(), getLinkageName(), getFile(),
|
||||
getLine(), getType(), isLocalToUnit(), isDefinition(), getScopeLine(),
|
||||
getContainingType(), getVirtuality(), getVirtualIndex(),
|
||||
getThisAdjustment(), getFlags(), isOptimized(), getUnit(),
|
||||
getTemplateParams(), getDeclaration(), getVariables());
|
||||
return getTemporary(getContext(), getScope(), getName(), getLinkageName(),
|
||||
getFile(), getLine(), getType(), isLocalToUnit(),
|
||||
isDefinition(), getScopeLine(), getContainingType(),
|
||||
getVirtuality(), getVirtualIndex(), getThisAdjustment(),
|
||||
getFlags(), isOptimized(), getUnit(),
|
||||
getTemplateParams(), getDeclaration(), getVariables(),
|
||||
getThrownTypes());
|
||||
}
|
||||
|
||||
public:
|
||||
@ -1546,11 +1547,12 @@ public:
|
||||
bool IsOptimized, DICompileUnit *Unit,
|
||||
DITemplateParameterArray TemplateParams = nullptr,
|
||||
DISubprogram *Declaration = nullptr,
|
||||
DILocalVariableArray Variables = nullptr),
|
||||
DILocalVariableArray Variables = nullptr,
|
||||
DITypeArray ThrownTypes = nullptr),
|
||||
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
|
||||
IsDefinition, ScopeLine, ContainingType, Virtuality,
|
||||
VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables))
|
||||
TemplateParams, Declaration, Variables, ThrownTypes))
|
||||
DEFINE_MDNODE_GET(
|
||||
DISubprogram,
|
||||
(Metadata * Scope, MDString *Name, MDString *LinkageName, Metadata *File,
|
||||
@ -1558,10 +1560,12 @@ public:
|
||||
unsigned ScopeLine, Metadata *ContainingType, unsigned Virtuality,
|
||||
unsigned VirtualIndex, int ThisAdjustment, DIFlags Flags,
|
||||
bool IsOptimized, Metadata *Unit, Metadata *TemplateParams = nullptr,
|
||||
Metadata *Declaration = nullptr, Metadata *Variables = nullptr),
|
||||
Metadata *Declaration = nullptr, Metadata *Variables = nullptr,
|
||||
Metadata *ThrownTypes = nullptr),
|
||||
(Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit, IsDefinition,
|
||||
ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment,
|
||||
Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables))
|
||||
Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables,
|
||||
ThrownTypes))
|
||||
|
||||
TempDISubprogram clone() const { return cloneImpl(); }
|
||||
|
||||
@ -1626,9 +1630,7 @@ public:
|
||||
DICompileUnit *getUnit() const {
|
||||
return cast_or_null<DICompileUnit>(getRawUnit());
|
||||
}
|
||||
void replaceUnit(DICompileUnit *CU) {
|
||||
replaceOperandWith(7, CU);
|
||||
}
|
||||
void replaceUnit(DICompileUnit *CU) { replaceOperandWith(7, CU); }
|
||||
DITemplateParameterArray getTemplateParams() const {
|
||||
return cast_or_null<MDTuple>(getRawTemplateParams());
|
||||
}
|
||||
@ -1638,6 +1640,9 @@ public:
|
||||
DILocalVariableArray getVariables() const {
|
||||
return cast_or_null<MDTuple>(getRawVariables());
|
||||
}
|
||||
DITypeArray getThrownTypes() const {
|
||||
return cast_or_null<MDTuple>(getRawThrownTypes());
|
||||
}
|
||||
|
||||
Metadata *getRawScope() const { return getOperand(1); }
|
||||
Metadata *getRawType() const { return getOperand(5); }
|
||||
@ -1646,6 +1651,7 @@ public:
|
||||
Metadata *getRawTemplateParams() const { return getOperand(8); }
|
||||
Metadata *getRawDeclaration() const { return getOperand(9); }
|
||||
Metadata *getRawVariables() const { return getOperand(10); }
|
||||
Metadata *getRawThrownTypes() const { return getOperand(11); }
|
||||
|
||||
/// Check if this subprogram describes the given function.
|
||||
///
|
||||
|
@ -4071,7 +4071,7 @@ bool LLParser::ParseDICompileUnit(MDNode *&Result, bool IsDistinct) {
|
||||
/// virtuality: DW_VIRTUALTIY_pure_virtual,
|
||||
/// virtualIndex: 10, thisAdjustment: 4, flags: 11,
|
||||
/// isOptimized: false, templateParams: !4, declaration: !5,
|
||||
/// variables: !6)
|
||||
/// variables: !6, thrownTypes: !7)
|
||||
bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
|
||||
auto Loc = Lex.getLoc();
|
||||
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
|
||||
@ -4093,7 +4093,8 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
|
||||
OPTIONAL(unit, MDField, ); \
|
||||
OPTIONAL(templateParams, MDField, ); \
|
||||
OPTIONAL(declaration, MDField, ); \
|
||||
OPTIONAL(variables, MDField, );
|
||||
OPTIONAL(variables, MDField, ); \
|
||||
OPTIONAL(thrownTypes, MDField, );
|
||||
PARSE_MD_FIELDS();
|
||||
#undef VISIT_MD_FIELDS
|
||||
|
||||
@ -4103,12 +4104,12 @@ bool LLParser::ParseDISubprogram(MDNode *&Result, bool IsDistinct) {
|
||||
"missing 'distinct', required for !DISubprogram when 'isDefinition'");
|
||||
|
||||
Result = GET_OR_DISTINCT(
|
||||
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, thisAdjustment.Val, flags.Val,
|
||||
isOptimized.Val, unit.Val, templateParams.Val,
|
||||
declaration.Val, variables.Val));
|
||||
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, thisAdjustment.Val,
|
||||
flags.Val, isOptimized.Val, unit.Val, templateParams.Val,
|
||||
declaration.Val, variables.Val, thrownTypes.Val));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1298,7 +1298,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
||||
break;
|
||||
}
|
||||
case bitc::METADATA_SUBPROGRAM: {
|
||||
if (Record.size() < 18 || Record.size() > 20)
|
||||
if (Record.size() < 18 || Record.size() > 21)
|
||||
return error("Invalid record");
|
||||
|
||||
IsDistinct =
|
||||
@ -1314,29 +1314,31 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
||||
unsigned Offset = Record.size() >= 19 ? 1 : 0;
|
||||
bool HasFn = Offset && !HasUnit;
|
||||
bool HasThisAdj = Record.size() >= 20;
|
||||
bool HasThrownTypes = Record.size() >= 21;
|
||||
DISubprogram *SP = GET_OR_DISTINCT(
|
||||
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
|
||||
static_cast<DINode::DIFlags>(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
|
||||
));
|
||||
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
|
||||
static_cast<DINode::DIFlags>(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
|
||||
HasThrownTypes ? getMDOrNull(Record[20]) : nullptr // thrownTypes
|
||||
));
|
||||
MetadataList.assignValue(SP, NextMetadataNo);
|
||||
NextMetadataNo++;
|
||||
|
||||
|
@ -1608,6 +1608,7 @@ void ModuleBitcodeWriter::writeDISubprogram(const DISubprogram *N,
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getDeclaration()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getVariables().get()));
|
||||
Record.push_back(N->getThisAdjustment());
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getThrownTypes().get()));
|
||||
|
||||
Stream.EmitRecord(bitc::METADATA_SUBPROGRAM, Record, Abbrev);
|
||||
Record.clear();
|
||||
|
@ -662,6 +662,14 @@ void DwarfUnit::addTemplateParams(DIE &Buffer, DINodeArray TParams) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Add thrown types.
|
||||
void DwarfUnit::addThrownTypes(DIE &Die, DINodeArray ThrownTypes) {
|
||||
for (const auto *Ty : ThrownTypes) {
|
||||
DIE &TT = createAndAddDIE(dwarf::DW_TAG_thrown_type, Die);
|
||||
addType(TT, cast<DIType>(Ty));
|
||||
}
|
||||
}
|
||||
|
||||
DIE *DwarfUnit::getOrCreateContextDIE(const DIScope *Context) {
|
||||
if (!Context || isa<DIFile>(Context))
|
||||
return &getUnitDie();
|
||||
@ -1249,6 +1257,8 @@ void DwarfUnit::applySubprogramAttributes(const DISubprogram *SP, DIE &SPDie,
|
||||
constructSubprogramArguments(SPDie, Args);
|
||||
}
|
||||
|
||||
addThrownTypes(SPDie, SP->getThrownTypes());
|
||||
|
||||
if (SP->isArtificial())
|
||||
addFlag(SPDie, dwarf::DW_AT_artificial);
|
||||
|
||||
|
@ -230,6 +230,9 @@ public:
|
||||
/// Add template parameters in buffer.
|
||||
void addTemplateParams(DIE &Buffer, DINodeArray TParams);
|
||||
|
||||
/// Add thrown types.
|
||||
void addThrownTypes(DIE &Die, DINodeArray ThrownTypes);
|
||||
|
||||
// FIXME: Should be reformulated in terms of addComplexAddress.
|
||||
/// Start with the address based on the location provided, and generate the
|
||||
/// DWARF information necessary to find the actual Block variable (navigating
|
||||
|
@ -1719,6 +1719,7 @@ static void writeDISubprogram(raw_ostream &Out, const DISubprogram *N,
|
||||
Printer.printMetadata("templateParams", N->getRawTemplateParams());
|
||||
Printer.printMetadata("declaration", N->getRawDeclaration());
|
||||
Printer.printMetadata("variables", N->getRawVariables());
|
||||
Printer.printMetadata("thrownTypes", N->getRawThrownTypes());
|
||||
Out << ")";
|
||||
}
|
||||
|
||||
|
@ -676,13 +676,14 @@ DISubprogram *DIBuilder::createFunction(
|
||||
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned ScopeLine, DINode::DIFlags Flags,
|
||||
bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl) {
|
||||
bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl,
|
||||
DITypeArray ThrownTypes) {
|
||||
auto *Node = getSubprogram(
|
||||
/* IsDistinct = */ isDefinition, VMContext,
|
||||
getNonCompileUnitScope(Context), Name, LinkageName, File, LineNo, Ty,
|
||||
isLocalToUnit, isDefinition, ScopeLine, nullptr, 0, 0, 0, Flags,
|
||||
isOptimized, isDefinition ? CUNode : nullptr, TParams, Decl,
|
||||
MDTuple::getTemporary(VMContext, None).release());
|
||||
MDTuple::getTemporary(VMContext, None).release(), ThrownTypes);
|
||||
|
||||
if (isDefinition)
|
||||
AllSubprograms.push_back(Node);
|
||||
@ -694,23 +695,22 @@ DISubprogram *DIBuilder::createTempFunctionFwdDecl(
|
||||
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *File,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned ScopeLine, DINode::DIFlags Flags,
|
||||
bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl) {
|
||||
bool isOptimized, DITemplateParameterArray TParams, DISubprogram *Decl,
|
||||
DITypeArray ThrownTypes) {
|
||||
return DISubprogram::getTemporary(
|
||||
VMContext, getNonCompileUnitScope(Context), Name, LinkageName,
|
||||
File, LineNo, Ty, isLocalToUnit, isDefinition, ScopeLine, nullptr,
|
||||
0, 0, 0, Flags, isOptimized, isDefinition ? CUNode : nullptr,
|
||||
TParams, Decl, nullptr)
|
||||
TParams, Decl, nullptr, ThrownTypes)
|
||||
.release();
|
||||
}
|
||||
|
||||
DISubprogram *DIBuilder::createMethod(DIScope *Context, StringRef Name,
|
||||
StringRef LinkageName, DIFile *F,
|
||||
unsigned LineNo, DISubroutineType *Ty,
|
||||
bool isLocalToUnit, bool isDefinition,
|
||||
unsigned VK, unsigned VIndex,
|
||||
int ThisAdjustment, DIType *VTableHolder,
|
||||
DINode::DIFlags Flags, bool isOptimized,
|
||||
DITemplateParameterArray TParams) {
|
||||
DISubprogram *DIBuilder::createMethod(
|
||||
DIScope *Context, StringRef Name, StringRef LinkageName, DIFile *F,
|
||||
unsigned LineNo, DISubroutineType *Ty, bool isLocalToUnit,
|
||||
bool isDefinition, unsigned VK, unsigned VIndex, int ThisAdjustment,
|
||||
DIType *VTableHolder, DINode::DIFlags Flags, bool isOptimized,
|
||||
DITemplateParameterArray TParams, DITypeArray ThrownTypes) {
|
||||
assert(getNonCompileUnitScope(Context) &&
|
||||
"Methods should have both a Context and a context that isn't "
|
||||
"the compile unit.");
|
||||
@ -719,7 +719,7 @@ DISubprogram *DIBuilder::createMethod(DIScope *Context, StringRef Name,
|
||||
/* IsDistinct = */ isDefinition, VMContext, cast<DIScope>(Context), Name,
|
||||
LinkageName, F, LineNo, Ty, isLocalToUnit, isDefinition, LineNo,
|
||||
VTableHolder, VK, VIndex, ThisAdjustment, Flags, isOptimized,
|
||||
isDefinition ? CUNode : nullptr, TParams, nullptr, nullptr);
|
||||
isDefinition ? CUNode : nullptr, TParams, nullptr, nullptr, ThrownTypes);
|
||||
|
||||
if (isDefinition)
|
||||
AllSubprograms.push_back(SP);
|
||||
|
@ -441,17 +441,17 @@ DISubprogram *DISubprogram::getImpl(
|
||||
Metadata *ContainingType, unsigned Virtuality, unsigned VirtualIndex,
|
||||
int ThisAdjustment, DIFlags Flags, bool IsOptimized, Metadata *Unit,
|
||||
Metadata *TemplateParams, Metadata *Declaration, Metadata *Variables,
|
||||
StorageType Storage, bool ShouldCreate) {
|
||||
Metadata *ThrownTypes, 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, ThisAdjustment,
|
||||
Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables));
|
||||
DISubprogram, (Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
|
||||
IsDefinition, ScopeLine, ContainingType, Virtuality,
|
||||
VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
Metadata *Ops[] = {File, Scope, Name, Name,
|
||||
LinkageName, Type, ContainingType, Unit,
|
||||
TemplateParams, Declaration, Variables};
|
||||
TemplateParams, Declaration, Variables, ThrownTypes};
|
||||
DEFINE_GETIMPL_STORE(DISubprogram, (Line, ScopeLine, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsLocalToUnit,
|
||||
IsDefinition, IsOptimized),
|
||||
|
@ -552,6 +552,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
|
||||
Metadata *TemplateParams;
|
||||
Metadata *Declaration;
|
||||
Metadata *Variables;
|
||||
Metadata *ThrownTypes;
|
||||
|
||||
MDNodeKeyImpl(Metadata *Scope, MDString *Name, MDString *LinkageName,
|
||||
Metadata *File, unsigned Line, Metadata *Type,
|
||||
@ -559,7 +560,8 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
|
||||
Metadata *ContainingType, unsigned Virtuality,
|
||||
unsigned VirtualIndex, int ThisAdjustment, unsigned Flags,
|
||||
bool IsOptimized, Metadata *Unit, Metadata *TemplateParams,
|
||||
Metadata *Declaration, Metadata *Variables)
|
||||
Metadata *Declaration, Metadata *Variables,
|
||||
Metadata *ThrownTypes)
|
||||
: Scope(Scope), Name(Name), LinkageName(LinkageName), File(File),
|
||||
Line(Line), Type(Type), IsLocalToUnit(IsLocalToUnit),
|
||||
IsDefinition(IsDefinition), ScopeLine(ScopeLine),
|
||||
@ -567,7 +569,7 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
|
||||
VirtualIndex(VirtualIndex), ThisAdjustment(ThisAdjustment),
|
||||
Flags(Flags), IsOptimized(IsOptimized), Unit(Unit),
|
||||
TemplateParams(TemplateParams), Declaration(Declaration),
|
||||
Variables(Variables) {}
|
||||
Variables(Variables), ThrownTypes(ThrownTypes) {}
|
||||
MDNodeKeyImpl(const DISubprogram *N)
|
||||
: Scope(N->getRawScope()), Name(N->getRawName()),
|
||||
LinkageName(N->getRawLinkageName()), File(N->getRawFile()),
|
||||
@ -578,7 +580,8 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
|
||||
ThisAdjustment(N->getThisAdjustment()), Flags(N->getFlags()),
|
||||
IsOptimized(N->isOptimized()), Unit(N->getRawUnit()),
|
||||
TemplateParams(N->getRawTemplateParams()),
|
||||
Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()) {}
|
||||
Declaration(N->getRawDeclaration()), Variables(N->getRawVariables()),
|
||||
ThrownTypes(N->getRawThrownTypes()) {}
|
||||
|
||||
bool isKeyOf(const DISubprogram *RHS) const {
|
||||
return Scope == RHS->getRawScope() && Name == RHS->getRawName() &&
|
||||
@ -595,7 +598,8 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
|
||||
Unit == RHS->getUnit() &&
|
||||
TemplateParams == RHS->getRawTemplateParams() &&
|
||||
Declaration == RHS->getRawDeclaration() &&
|
||||
Variables == RHS->getRawVariables();
|
||||
Variables == RHS->getRawVariables() &&
|
||||
ThrownTypes == RHS->getRawThrownTypes();
|
||||
}
|
||||
unsigned getHashValue() const {
|
||||
// If this is a declaration inside an ODR type, only hash the type and the
|
||||
|
@ -1050,6 +1050,14 @@ void Verifier::visitDISubprogram(const DISubprogram &N) {
|
||||
// Subprogram declarations (part of the type hierarchy).
|
||||
AssertDI(!Unit, "subprogram declarations must not have a compile unit", &N);
|
||||
}
|
||||
|
||||
if (auto *RawThrownTypes = N.getRawThrownTypes()) {
|
||||
auto *ThrownTypes = dyn_cast<MDTuple>(RawThrownTypes);
|
||||
AssertDI(ThrownTypes, "invalid thrown types list", &N, RawThrownTypes);
|
||||
for (Metadata *Op : ThrownTypes->operands())
|
||||
AssertDI(Op && isa<DIType>(Op), "invalid thrown type", &N, ThrownTypes,
|
||||
Op);
|
||||
}
|
||||
}
|
||||
|
||||
void Verifier::visitDILexicalBlockBase(const DILexicalBlockBase &N) {
|
||||
|
@ -6,8 +6,8 @@ define void @_Z3foov() !dbg !9 {
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12}
|
||||
; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14}
|
||||
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14}
|
||||
|
||||
!0 = !{null}
|
||||
!1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
|
||||
@ -61,6 +61,14 @@ define void @_Z3foov() !dbg !9 {
|
||||
unit: !8,
|
||||
templateParams: !5, declaration: !9, variables: !6)
|
||||
|
||||
!13 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!llvm.module.flags = !{!13}
|
||||
!13 = !{!4}
|
||||
; CHECK: !13 = !{!4}
|
||||
; CHECK: !14 = distinct !DISubprogram(name: "foo", scope: !1, file: !2, line: 1, type: !3, isLocal: true, isDefinition: true, scopeLine: 2, isOptimized: false, unit: !8, thrownTypes: !13)
|
||||
!14 = distinct !DISubprogram(name: "foo", scope: !1,
|
||||
file: !2, line: 1, type: !3, isLocal: true,
|
||||
isDefinition: true, scopeLine: 2, isOptimized: false,
|
||||
unit: !8, thrownTypes: !13)
|
||||
|
||||
!15 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!llvm.module.flags = !{!15}
|
||||
!llvm.dbg.cu = !{!8}
|
||||
|
38
test/DebugInfo/Generic/thrownTypes.ll
Normal file
38
test/DebugInfo/Generic/thrownTypes.ll
Normal file
@ -0,0 +1,38 @@
|
||||
; REQUIRES: object-emission
|
||||
|
||||
; RUN: %llc_dwarf -O0 -filetype=obj < %s | llvm-dwarfdump -debug-dump=info - | FileCheck %s
|
||||
|
||||
; CHECK: DW_TAG_subprogram
|
||||
; CHECK: DW_AT_name {{.*}} "f"
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_TAG_thrown_type
|
||||
; CHECK-NEXT: DW_AT_type {{.*}} {[[ERROR:.*]]}
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_TAG_thrown_type
|
||||
; CHECK-NEXT: DW_AT_type {{.*}} {[[ERROR2:.*]]}
|
||||
; CHECK: [[ERROR]]: DW_TAG_structure_type
|
||||
; CHECK-NEXT: DW_AT_name {{.*}} "Error"
|
||||
; CHECK: [[ERROR2]]: DW_TAG_structure_type
|
||||
; CHECK-NEXT: DW_AT_name {{.*}} "DifferentError"
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @f() #0 !dbg !5 {
|
||||
entry:
|
||||
ret void, !dbg !11
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind uwtable }
|
||||
|
||||
!llvm.dbg.cu = !{!0}
|
||||
!llvm.module.flags = !{!8, !9}
|
||||
|
||||
!0 = distinct !DICompileUnit(language: DW_LANG_Swift, producer: "swiftc", isOptimized: false, emissionKind: FullDebug, file: !1)
|
||||
!1 = !DIFile(filename: "f.swift", directory: "/")
|
||||
!3 = !DICompositeType(tag: DW_TAG_structure_type, name: "Error")
|
||||
!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentError")
|
||||
!5 = distinct !DISubprogram(name: "f", line: 2, isLocal: false, isDefinition: true, unit: !0, scopeLine: 2, file: !1, scope: !1, type: !6, thrownTypes: !{!3, !4})
|
||||
!6 = !DISubroutineType(types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!9 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!11 = !DILocation(line: 3, scope: !5)
|
22
test/Verifier/DISubprogram.ll
Normal file
22
test/Verifier/DISubprogram.ll
Normal file
@ -0,0 +1,22 @@
|
||||
; RUN: not opt -S <%s 2>&1| FileCheck %s
|
||||
|
||||
define void @f() !dbg !14 {
|
||||
ret void
|
||||
}
|
||||
|
||||
!0 = !{null}
|
||||
!1 = distinct !DICompositeType(tag: DW_TAG_structure_type)
|
||||
!2 = !DIFile(filename: "path/to/file", directory: "/path/to/dir")
|
||||
!3 = !DISubroutineType(types: !0)
|
||||
!4 = distinct !DICompositeType(tag: DW_TAG_structure_type)
|
||||
!8 = distinct !DICompileUnit(language: DW_LANG_Swift, producer: "clang",
|
||||
file: !2, emissionKind: 2)
|
||||
; CHECK: invalid thrown type
|
||||
!13 = !{!14}
|
||||
!14 = distinct !DISubprogram(name: "f", scope: !1,
|
||||
file: !2, line: 1, type: !3, isLocal: true,
|
||||
isDefinition: true, scopeLine: 2,
|
||||
unit: !8, thrownTypes: !13)
|
||||
!15 = !{i32 1, !"Debug Info Version", i32 3}
|
||||
!llvm.module.flags = !{!15}
|
||||
!llvm.dbg.cu = !{!8}
|
@ -356,6 +356,25 @@ TEST_F(IRBuilderTest, RAIIHelpersTest) {
|
||||
EXPECT_EQ(BB, Builder.GetInsertBlock());
|
||||
}
|
||||
|
||||
TEST_F(IRBuilderTest, createFunction) {
|
||||
IRBuilder<> Builder(BB);
|
||||
DIBuilder DIB(*M);
|
||||
auto File = DIB.createFile("error.swift", "/");
|
||||
auto CU =
|
||||
DIB.createCompileUnit(dwarf::DW_LANG_Swift, File, "swiftc", true, "", 0);
|
||||
auto Type = DIB.createSubroutineType(DIB.getOrCreateTypeArray(None));
|
||||
auto NoErr = DIB.createFunction(CU, "noerr", "", File, 1, Type, false, true, 1,
|
||||
DINode::FlagZero, true);
|
||||
EXPECT_TRUE(!NoErr->getThrownTypes());
|
||||
auto Int = DIB.createBasicType("Int", 64, dwarf::DW_ATE_signed);
|
||||
auto Error = DIB.getOrCreateArray({Int});
|
||||
auto Err =
|
||||
DIB.createFunction(CU, "err", "", File, 1, Type, false, true, 1,
|
||||
DINode::FlagZero, true, nullptr, nullptr, Error.get());
|
||||
EXPECT_TRUE(Err->getThrownTypes().get() == Error.get());
|
||||
DIB.finalize();
|
||||
}
|
||||
|
||||
TEST_F(IRBuilderTest, DIBuilder) {
|
||||
IRBuilder<> Builder(BB);
|
||||
DIBuilder DIB(*M);
|
||||
|
@ -1512,13 +1512,14 @@ TEST_F(DISubprogramTest, get) {
|
||||
MDTuple *TemplateParams = getTuple();
|
||||
DISubprogram *Declaration = getSubprogram();
|
||||
MDTuple *Variables = getTuple();
|
||||
MDTuple *ThrownTypes = getTuple();
|
||||
DICompileUnit *Unit = getUnit();
|
||||
|
||||
auto *N = DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables);
|
||||
auto *N = DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type, IsLocalToUnit,
|
||||
IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration,
|
||||
Variables, ThrownTypes);
|
||||
|
||||
EXPECT_EQ(dwarf::DW_TAG_subprogram, N->getTag());
|
||||
EXPECT_EQ(Scope, N->getScope());
|
||||
@ -1540,98 +1541,109 @@ TEST_F(DISubprogramTest, get) {
|
||||
EXPECT_EQ(TemplateParams, N->getTemplateParams().get());
|
||||
EXPECT_EQ(Declaration, N->getDeclaration());
|
||||
EXPECT_EQ(Variables, N->getVariables().get());
|
||||
EXPECT_EQ(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
EXPECT_EQ(ThrownTypes, N->getThrownTypes().get());
|
||||
EXPECT_EQ(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, getCompositeType(), Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables));
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, "other", LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, "other", File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, "other", File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, getFile(), Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables));
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line + 1, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables));
|
||||
EXPECT_NE(N,
|
||||
DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
getSubroutineType(), IsLocalToUnit, IsDefinition,
|
||||
ScopeLine, ContainingType, Virtuality,
|
||||
VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables));
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, !IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, !IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
getSubroutineType(), IsLocalToUnit,
|
||||
IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment,
|
||||
Flags, IsOptimized, Unit, TemplateParams,
|
||||
Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
!IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, !IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine + 1, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
getCompositeType(), Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, getCompositeType(),
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality + 1, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
TemplateParams, Declaration, Variables,
|
||||
ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex + 1,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
TemplateParams, Declaration, Variables,
|
||||
ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, !IsOptimized, Unit,
|
||||
TemplateParams, Declaration, Variables));
|
||||
TemplateParams, Declaration, Variables,
|
||||
ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, nullptr,
|
||||
TemplateParams, Declaration, Variables));
|
||||
TemplateParams, Declaration, Variables,
|
||||
ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, getTuple(), Declaration, Variables, ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
getTuple(), Declaration, Variables));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, getSubprogram(), Variables));
|
||||
TemplateParams, getSubprogram(), Variables,
|
||||
ThrownTypes));
|
||||
EXPECT_NE(N, DISubprogram::get(Context, Scope, Name, LinkageName, File, Line,
|
||||
Type, IsLocalToUnit, IsDefinition, ScopeLine,
|
||||
ContainingType, Virtuality, VirtualIndex,
|
||||
ThisAdjustment, Flags, IsOptimized, Unit,
|
||||
TemplateParams, Declaration, getTuple()));
|
||||
EXPECT_NE(N, DISubprogram::get(
|
||||
Context, Scope, Name, LinkageName, File, Line, Type,
|
||||
IsLocalToUnit, IsDefinition, ScopeLine, ContainingType,
|
||||
Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized,
|
||||
Unit, TemplateParams, Declaration, Variables, getTuple()));
|
||||
|
||||
TempDISubprogram Temp = N->clone();
|
||||
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
|
||||
|
Loading…
Reference in New Issue
Block a user