summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorTim Northover <t.p.northover@gmail.com>2020-01-07 10:03:31 +0000
committerTim Northover <t.p.northover@gmail.com>2020-01-07 15:11:43 +0000
commite130eef58814d12b0490033fbedcf75db8a4f148 (patch)
tree956859221165f7ccd74e8283f560a866905a4fcc /llvm
parentf26ed6e47cb8b080c236d11c4942a12265180084 (diff)
downloadbcm5719-llvm-e130eef58814d12b0490033fbedcf75db8a4f148.tar.gz
bcm5719-llvm-e130eef58814d12b0490033fbedcf75db8a4f148.zip
OpaquePtr: print byval types containing anonymous types correctly.
Attribute::getAsString doesn't have enough information to print anonymous Module-level types correctly, so they come back as "%type 0xabcd". This results in broken IR when printing as text. Instead, print type-attributes (currently just byval) using the TypePrinting infrastructure available in AsmWriter. This only applies to function argument attributes.
Diffstat (limited to 'llvm')
-rw-r--r--llvm/lib/IR/AsmWriter.cpp47
-rw-r--r--llvm/test/Assembler/byval-type-attr.ll12
2 files changed, 53 insertions, 6 deletions
diff --git a/llvm/lib/IR/AsmWriter.cpp b/llvm/lib/IR/AsmWriter.cpp
index cda5fd0a381..acf0e4afef2 100644
--- a/llvm/lib/IR/AsmWriter.cpp
+++ b/llvm/lib/IR/AsmWriter.cpp
@@ -2399,6 +2399,8 @@ public:
void writeAllMDNodes();
void writeMDNode(unsigned Slot, const MDNode *Node);
+ void writeAttribute(const Attribute &Attr, bool InAttrGroup = false);
+ void writeAttributeSet(const AttributeSet &AttrSet, bool InAttrGroup = false);
void writeAllAttributeGroups();
void printTypeIdentities();
@@ -2531,8 +2533,10 @@ void AssemblyWriter::writeParamOperand(const Value *Operand,
// Print the type
TypePrinter.print(Operand->getType(), Out);
// Print parameter attributes list
- if (Attrs.hasAttributes())
- Out << ' ' << Attrs.getAsString();
+ if (Attrs.hasAttributes()) {
+ Out << ' ';
+ writeAttributeSet(Attrs);
+ }
Out << ' ';
// Print the operand
WriteAsOperandInternal(Out, Operand, &TypePrinter, &Machine, TheModule);
@@ -3462,8 +3466,10 @@ void AssemblyWriter::printFunction(const Function *F) {
TypePrinter.print(FT->getParamType(I), Out);
AttributeSet ArgAttrs = Attrs.getParamAttributes(I);
- if (ArgAttrs.hasAttributes())
- Out << ' ' << ArgAttrs.getAsString();
+ if (ArgAttrs.hasAttributes()) {
+ Out << ' ';
+ writeAttributeSet(ArgAttrs);
+ }
}
} else {
// The arguments are meaningful here, print them in detail.
@@ -3549,8 +3555,10 @@ void AssemblyWriter::printArgument(const Argument *Arg, AttributeSet Attrs) {
TypePrinter.print(Arg->getType(), Out);
// Output parameter attributes list
- if (Attrs.hasAttributes())
- Out << ' ' << Attrs.getAsString();
+ if (Attrs.hasAttributes()) {
+ Out << ' ';
+ writeAttributeSet(Attrs);
+ }
// Output name, if available...
if (Arg->hasName()) {
@@ -4126,6 +4134,33 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
WriteMDNodeBodyInternal(Out, Node, &TypePrinter, &Machine, TheModule);
}
+void AssemblyWriter::writeAttribute(const Attribute &Attr, bool InAttrGroup) {
+ if (!Attr.isTypeAttribute()) {
+ Out << Attr.getAsString(InAttrGroup);
+ return;
+ }
+
+ assert(Attr.hasAttribute(Attribute::ByVal) && "unexpected type attr");
+
+ Out << "byval";
+ if (Type *Ty = Attr.getValueAsType()) {
+ Out << '(';
+ TypePrinter.print(Ty, Out);
+ Out << ')';
+ }
+}
+
+void AssemblyWriter::writeAttributeSet(const AttributeSet &AttrSet,
+ bool InAttrGroup) {
+ bool FirstAttr = true;
+ for (const auto &Attr : AttrSet) {
+ if (!FirstAttr)
+ Out << ' ';
+ writeAttribute(Attr, InAttrGroup);
+ FirstAttr = false;
+ }
+}
+
void AssemblyWriter::writeAllAttributeGroups() {
std::vector<std::pair<AttributeSet, unsigned>> asVec;
asVec.resize(Machine.as_size());
diff --git a/llvm/test/Assembler/byval-type-attr.ll b/llvm/test/Assembler/byval-type-attr.ll
index c868885d2cc..dd195a39651 100644
--- a/llvm/test/Assembler/byval-type-attr.ll
+++ b/llvm/test/Assembler/byval-type-attr.ll
@@ -29,3 +29,15 @@ fail:
declare void @baz(%named_type* byval(%named_type))
declare i32 @__gxx_personality_v0(...)
+
+%0 = type opaque
+
+; CHECK: define void @anon({ %0* }* byval({ %0* }) %arg)
+; CHECK: call void @anon_callee({ %0* }* byval({ %0* }) %arg)
+define void @anon({ %0* }* byval({ %0* }) %arg) {
+ call void @anon_callee({ %0* }* byval({ %0* }) %arg)
+ ret void
+}
+
+; CHECK: declare void @anon_callee({ %0* }* byval({ %0* }))
+declare void @anon_callee({ %0* }* byval({ %0* }))
OpenPOWER on IntegriCloud