diff options
Diffstat (limited to 'lib/IR/Core.cpp')
-rw-r--r-- | lib/IR/Core.cpp | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index a25c4d66d3bbd..753d9c229eca1 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -563,9 +563,23 @@ LLVMValueRef LLVMGetMetadata(LLVMValueRef Inst, unsigned KindID) { return nullptr; } -void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef MD) { - MDNode *N = - MD ? cast<MDNode>(unwrap<MetadataAsValue>(MD)->getMetadata()) : nullptr; +// MetadataAsValue uses a canonical format which strips the actual MDNode for +// MDNode with just a single constant value, storing just a ConstantAsMetadata +// This undoes this canonicalization, reconstructing the MDNode. +static MDNode *extractMDNode(MetadataAsValue *MAV) { + Metadata *MD = MAV->getMetadata(); + assert((isa<MDNode>(MD) || isa<ConstantAsMetadata>(MD)) && + "Expected a metadata node or a canonicalized constant"); + + if (MDNode *N = dyn_cast<MDNode>(MD)) + return N; + + return MDNode::get(MAV->getContext(), MD); +} + +void LLVMSetMetadata(LLVMValueRef Inst, unsigned KindID, LLVMValueRef Val) { + MDNode *N = Val ? extractMDNode(unwrap<MetadataAsValue>(Val)) : nullptr; + unwrap<Instruction>(Inst)->setMetadata(KindID, N); } @@ -795,7 +809,7 @@ void LLVMAddNamedMetadataOperand(LLVMModuleRef M, const char* name, return; if (!Val) return; - N->addOperand(cast<MDNode>(unwrap<MetadataAsValue>(Val)->getMetadata())); + N->addOperand(extractMDNode(unwrap<MetadataAsValue>(Val))); } /*--.. Operations on scalar constants ......................................--*/ |