summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorAdrian Prantl <aprantl@apple.com>2017-04-26 22:56:44 +0000
committerAdrian Prantl <aprantl@apple.com>2017-04-26 22:56:44 +0000
commit1d12b885b09a92d268356292c2829a2a6b4aca1d (patch)
tree0760cd6360c18db743eec53ff0ae6d3c0739796d /llvm/lib
parent330e52b0187c6700d3761f4f704c44fc3c785acb (diff)
downloadbcm5719-llvm-1d12b885b09a92d268356292c2829a2a6b4aca1d.tar.gz
bcm5719-llvm-1d12b885b09a92d268356292c2829a2a6b4aca1d.zip
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
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp17
-rw-r--r--llvm/lib/Bitcode/Reader/MetadataLoader.cpp48
-rw-r--r--llvm/lib/Bitcode/Writer/BitcodeWriter.cpp1
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp10
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h3
-rw-r--r--llvm/lib/IR/AsmWriter.cpp1
-rw-r--r--llvm/lib/IR/DIBuilder.cpp26
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp12
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h12
-rw-r--r--llvm/lib/IR/Verifier.cpp8
10 files changed, 84 insertions, 54 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index c7076ed0dd8..a6a9b32d093 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -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;
}
diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
index d089684a052..7ca2e167da0 100644
--- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
+++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp
@@ -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++;
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index e5aba03c8dc..eb8b43219da 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -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();
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 16fb20dd7e2..f2e13992883 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -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);
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
index e84df465088..3bf4979030a 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h
@@ -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
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index b7de07170de..e396716428f 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -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 << ")";
}
diff --git a/llvm/lib/IR/DIBuilder.cpp b/llvm/lib/IR/DIBuilder.cpp
index 9407c805b92..24f75e8b3a4 100644
--- a/llvm/lib/IR/DIBuilder.cpp
+++ b/llvm/lib/IR/DIBuilder.cpp
@@ -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);
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index d14c6018d40..498617c4460 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -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),
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 0ee0b9c0da2..d2c4b021026 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -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
diff --git a/llvm/lib/IR/Verifier.cpp b/llvm/lib/IR/Verifier.cpp
index 4e04020f206..5f60774c302 100644
--- a/llvm/lib/IR/Verifier.cpp
+++ b/llvm/lib/IR/Verifier.cpp
@@ -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) {
OpenPOWER on IntegriCloud