1 //===- llvm/unittest/IR/Metadata.cpp - Metadata unit tests ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/IR/Metadata.h" 11 #include "llvm/IR/Constants.h" 12 #include "llvm/IR/Instructions.h" 13 #include "llvm/IR/LLVMContext.h" 14 #include "llvm/IR/Module.h" 15 #include "llvm/IR/Type.h" 16 #include "llvm/Support/raw_ostream.h" 17 #include "gtest/gtest.h" 18 using namespace llvm; 19 20 namespace { 21 22 class MetadataTest : public testing::Test { 23 protected: 24 LLVMContext Context; 25 }; 26 typedef MetadataTest MDStringTest; 27 28 // Test that construction of MDString with different value produces different 29 // MDString objects, even with the same string pointer and nulls in the string. 30 TEST_F(MDStringTest, CreateDifferent) { 31 char x[3] = { 'f', 0, 'A' }; 32 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 33 x[2] = 'B'; 34 MDString *s2 = MDString::get(Context, StringRef(&x[0], 3)); 35 EXPECT_NE(s1, s2); 36 } 37 38 // Test that creation of MDStrings with the same string contents produces the 39 // same MDString object, even with different pointers. 40 TEST_F(MDStringTest, CreateSame) { 41 char x[4] = { 'a', 'b', 'c', 'X' }; 42 char y[4] = { 'a', 'b', 'c', 'Y' }; 43 44 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 45 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); 46 EXPECT_EQ(s1, s2); 47 } 48 49 // Test that MDString prints out the string we fed it. 50 TEST_F(MDStringTest, PrintingSimple) { 51 char *str = new char[13]; 52 strncpy(str, "testing 1 2 3", 13); 53 MDString *s = MDString::get(Context, StringRef(str, 13)); 54 strncpy(str, "aaaaaaaaaaaaa", 13); 55 delete[] str; 56 57 std::string Str; 58 raw_string_ostream oss(Str); 59 s->print(oss); 60 EXPECT_STREQ("metadata !\"testing 1 2 3\"", oss.str().c_str()); 61 } 62 63 // Test printing of MDString with non-printable characters. 64 TEST_F(MDStringTest, PrintingComplex) { 65 char str[5] = {0, '\n', '"', '\\', (char)-1}; 66 MDString *s = MDString::get(Context, StringRef(str+0, 5)); 67 std::string Str; 68 raw_string_ostream oss(Str); 69 s->print(oss); 70 EXPECT_STREQ("metadata !\"\\00\\0A\\22\\5C\\FF\"", oss.str().c_str()); 71 } 72 73 typedef MetadataTest MDNodeTest; 74 75 // Test the two constructors, and containing other Constants. 76 TEST_F(MDNodeTest, Simple) { 77 char x[3] = { 'a', 'b', 'c' }; 78 char y[3] = { '1', '2', '3' }; 79 80 MDString *s1 = MDString::get(Context, StringRef(&x[0], 3)); 81 MDString *s2 = MDString::get(Context, StringRef(&y[0], 3)); 82 ConstantAsMetadata *CI = ConstantAsMetadata::get( 83 ConstantInt::get(getGlobalContext(), APInt(8, 0))); 84 85 std::vector<Metadata *> V; 86 V.push_back(s1); 87 V.push_back(CI); 88 V.push_back(s2); 89 90 MDNode *n1 = MDNode::get(Context, V); 91 Metadata *const c1 = n1; 92 MDNode *n2 = MDNode::get(Context, c1); 93 Metadata *const c2 = n2; 94 MDNode *n3 = MDNode::get(Context, V); 95 MDNode *n4 = MDNode::getIfExists(Context, V); 96 MDNode *n5 = MDNode::getIfExists(Context, c1); 97 MDNode *n6 = MDNode::getIfExists(Context, c2); 98 EXPECT_NE(n1, n2); 99 EXPECT_EQ(n1, n3); 100 EXPECT_EQ(n4, n1); 101 EXPECT_EQ(n5, n2); 102 EXPECT_EQ(n6, (Metadata *)nullptr); 103 104 EXPECT_EQ(3u, n1->getNumOperands()); 105 EXPECT_EQ(s1, n1->getOperand(0)); 106 EXPECT_EQ(CI, n1->getOperand(1)); 107 EXPECT_EQ(s2, n1->getOperand(2)); 108 109 EXPECT_EQ(1u, n2->getNumOperands()); 110 EXPECT_EQ(n1, n2->getOperand(0)); 111 } 112 113 TEST_F(MDNodeTest, Delete) { 114 Constant *C = ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 1); 115 Instruction *I = new BitCastInst(C, Type::getInt32Ty(getGlobalContext())); 116 117 Metadata *const V = LocalAsMetadata::get(I); 118 MDNode *n = MDNode::get(Context, V); 119 TrackingMDRef wvh(n); 120 121 EXPECT_EQ(n, wvh); 122 123 delete I; 124 } 125 126 TEST_F(MDNodeTest, SelfReference) { 127 // !0 = metadata !{metadata !0} 128 // !1 = metadata !{metadata !0} 129 { 130 MDNode *Temp = MDNode::getTemporary(Context, None); 131 Metadata *Args[] = {Temp}; 132 MDNode *Self = MDNode::get(Context, Args); 133 Self->replaceOperandWith(0, Self); 134 MDNode::deleteTemporary(Temp); 135 ASSERT_EQ(Self, Self->getOperand(0)); 136 137 // Self-references should be distinct, so MDNode::get() should grab a 138 // uniqued node that references Self, not Self. 139 Args[0] = Self; 140 MDNode *Ref1 = MDNode::get(Context, Args); 141 MDNode *Ref2 = MDNode::get(Context, Args); 142 EXPECT_NE(Self, Ref1); 143 EXPECT_EQ(Ref1, Ref2); 144 } 145 146 // !0 = metadata !{metadata !0, metadata !{}} 147 // !1 = metadata !{metadata !0, metadata !{}} 148 { 149 MDNode *Temp = MDNode::getTemporary(Context, None); 150 Metadata *Args[] = {Temp, MDNode::get(Context, None)}; 151 MDNode *Self = MDNode::get(Context, Args); 152 Self->replaceOperandWith(0, Self); 153 MDNode::deleteTemporary(Temp); 154 ASSERT_EQ(Self, Self->getOperand(0)); 155 156 // Self-references should be distinct, so MDNode::get() should grab a 157 // uniqued node that references Self, not Self itself. 158 Args[0] = Self; 159 MDNode *Ref1 = MDNode::get(Context, Args); 160 MDNode *Ref2 = MDNode::get(Context, Args); 161 EXPECT_NE(Self, Ref1); 162 EXPECT_EQ(Ref1, Ref2); 163 } 164 } 165 166 typedef MetadataTest MetadataAsValueTest; 167 168 TEST_F(MetadataAsValueTest, MDNode) { 169 MDNode *N = MDNode::get(Context, None); 170 auto *V = MetadataAsValue::get(Context, N); 171 EXPECT_TRUE(V->getType()->isMetadataTy()); 172 EXPECT_EQ(N, V->getMetadata()); 173 174 auto *V2 = MetadataAsValue::get(Context, N); 175 EXPECT_EQ(V, V2); 176 } 177 178 TEST_F(MetadataAsValueTest, MDNodeMDNode) { 179 MDNode *N = MDNode::get(Context, None); 180 Metadata *Ops[] = {N}; 181 MDNode *N2 = MDNode::get(Context, Ops); 182 auto *V = MetadataAsValue::get(Context, N2); 183 EXPECT_TRUE(V->getType()->isMetadataTy()); 184 EXPECT_EQ(N2, V->getMetadata()); 185 186 auto *V2 = MetadataAsValue::get(Context, N2); 187 EXPECT_EQ(V, V2); 188 189 auto *V3 = MetadataAsValue::get(Context, N); 190 EXPECT_TRUE(V3->getType()->isMetadataTy()); 191 EXPECT_NE(V, V3); 192 EXPECT_EQ(N, V3->getMetadata()); 193 } 194 195 TEST_F(MetadataAsValueTest, MDNodeConstant) { 196 auto *C = ConstantInt::getTrue(Context); 197 auto *MD = ConstantAsMetadata::get(C); 198 Metadata *Ops[] = {MD}; 199 auto *N = MDNode::get(Context, Ops); 200 201 auto *V = MetadataAsValue::get(Context, MD); 202 EXPECT_TRUE(V->getType()->isMetadataTy()); 203 EXPECT_EQ(MD, V->getMetadata()); 204 205 auto *V2 = MetadataAsValue::get(Context, N); 206 EXPECT_EQ(MD, V2->getMetadata()); 207 EXPECT_EQ(V, V2); 208 } 209 210 TEST(NamedMDNodeTest, Search) { 211 LLVMContext Context; 212 ConstantAsMetadata *C = 213 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 1)); 214 ConstantAsMetadata *C2 = 215 ConstantAsMetadata::get(ConstantInt::get(Type::getInt32Ty(Context), 2)); 216 217 Metadata *const V = C; 218 Metadata *const V2 = C2; 219 MDNode *n = MDNode::get(Context, V); 220 MDNode *n2 = MDNode::get(Context, V2); 221 222 Module M("MyModule", Context); 223 const char *Name = "llvm.NMD1"; 224 NamedMDNode *NMD = M.getOrInsertNamedMetadata(Name); 225 NMD->addOperand(n); 226 NMD->addOperand(n2); 227 228 std::string Str; 229 raw_string_ostream oss(Str); 230 NMD->print(oss); 231 EXPECT_STREQ("!llvm.NMD1 = !{!0, !1}\n", 232 oss.str().c_str()); 233 } 234 } 235