1// RUN: llvm-tblgen -dump-json %s | %python %S/JSON-check.py %s 2 3// CHECK: data['!tablegen_json_version'] == 1 4 5// CHECK: all(data[s]['!name'] == s for s in data if not s.startswith("!")) 6 7class Base {} 8class Intermediate : Base {} 9class Derived : Intermediate {} 10 11def D : Intermediate {} 12// CHECK: 'D' in data['!instanceof']['Base'] 13// CHECK: 'D' in data['!instanceof']['Intermediate'] 14// CHECK: 'D' not in data['!instanceof']['Derived'] 15// CHECK: 'Base' in data['D']['!superclasses'] 16// CHECK: 'Intermediate' in data['D']['!superclasses'] 17// CHECK: 'Derived' not in data['D']['!superclasses'] 18 19def ExampleDagOp; 20 21def FieldKeywordTest { 22 int a; 23 field int b; 24 // CHECK: 'a' not in data['FieldKeywordTest']['!fields'] 25 // CHECK: 'b' in data['FieldKeywordTest']['!fields'] 26} 27 28class Variables { 29 int i; 30 string s; 31 bit b; 32 bits<8> bs; 33 code c; 34 list<int> li; 35 Base base; 36 dag d; 37} 38def VarNull : Variables { 39 // A variable not filled in at all has its value set to JSON 40 // 'null', which translates to Python None 41 // CHECK: data['VarNull']['i'] is None 42} 43def VarPrim : Variables { 44 // Test initializers that map to primitive JSON types 45 46 int i = 3; 47 // CHECK: data['VarPrim']['i'] == 3 48 49 // Integer literals should be emitted in the JSON at full 64-bit 50 // precision, for the benefit of JSON readers that preserve that 51 // much information. Python's is one such. 52 int enormous_pos = 9123456789123456789; 53 int enormous_neg = -9123456789123456789; 54 // CHECK: data['VarPrim']['enormous_pos'] == 9123456789123456789 55 // CHECK: data['VarPrim']['enormous_neg'] == -9123456789123456789 56 57 string s = "hello, world"; 58 // CHECK: data['VarPrim']['s'] == 'hello, world' 59 60 bit b = 0; 61 // CHECK: data['VarPrim']['b'] == 0 62 63 // bits<> arrays are stored in logical order (array[i] is the same 64 // bit identified in .td files as bs{i}), which means the _visual_ 65 // order of the list (in default rendering) is reversed. 66 bits<8> bs = { 0,0,0,1,0,1,1,1 }; 67 // CHECK: data['VarPrim']['bs'] == [ 1,1,1,0,1,0,0,0 ] 68 69 code c = [{ \" }]; 70 // CHECK: data['VarPrim']['c'] == r' \" ' 71 72 list<int> li = [ 1, 2, 3, 4 ]; 73 // CHECK: data['VarPrim']['li'] == [ 1, 2, 3, 4 ] 74} 75def VarObj : Variables { 76 // Test initializers that map to JSON objects containing a 'kind' 77 // discriminator 78 79 Base base = D; 80 // CHECK: data['VarObj']['base']['kind'] == 'def' 81 // CHECK: data['VarObj']['base']['def'] == 'D' 82 // CHECK: data['VarObj']['base']['printable'] == 'D' 83 84 dag d = (ExampleDagOp 22, "hello":$foo); 85 // CHECK: data['VarObj']['d']['kind'] == 'dag' 86 // CHECK: data['VarObj']['d']['operator']['kind'] == 'def' 87 // CHECK: data['VarObj']['d']['operator']['def'] == 'ExampleDagOp' 88 // CHECK: data['VarObj']['d']['operator']['printable'] == 'ExampleDagOp' 89 // CHECK: data['VarObj']['d']['args'] == [[22, None], ["hello", "foo"]] 90 // CHECK: data['VarObj']['d']['printable'] == '(ExampleDagOp 22, "hello":$foo)' 91 92 int undef_int; 93 field int ref_int = undef_int; 94 // CHECK: data['VarObj']['ref_int']['kind'] == 'var' 95 // CHECK: data['VarObj']['ref_int']['var'] == 'undef_int' 96 // CHECK: data['VarObj']['ref_int']['printable'] == 'undef_int' 97 98 bits<2> undef_bits; 99 bits<4> ref_bits; 100 let ref_bits{3-2} = 0b10; 101 let ref_bits{1-0} = undef_bits{1-0}; 102 // CHECK: data['VarObj']['ref_bits'][3] == 1 103 // CHECK: data['VarObj']['ref_bits'][2] == 0 104 // CHECK: data['VarObj']['ref_bits'][1]['kind'] == 'varbit' 105 // CHECK: data['VarObj']['ref_bits'][1]['var'] == 'undef_bits' 106 // CHECK: data['VarObj']['ref_bits'][1]['index'] == 1 107 // CHECK: data['VarObj']['ref_bits'][1]['printable'] == 'undef_bits{1}' 108 // CHECK: data['VarObj']['ref_bits'][0]['kind'] == 'varbit' 109 // CHECK: data['VarObj']['ref_bits'][0]['var'] == 'undef_bits' 110 // CHECK: data['VarObj']['ref_bits'][0]['index'] == 0 111 // CHECK: data['VarObj']['ref_bits'][0]['printable'] == 'undef_bits{0}' 112 113 field int complex_ref_int = !add(undef_int, 2); 114 // CHECK: data['VarObj']['complex_ref_int']['kind'] == 'complex' 115 // CHECK: data['VarObj']['complex_ref_int']['printable'] == '!add(undef_int, 2)' 116} 117 118// Test the !anonymous member. This is tricky because when a def is 119// anonymous, almost by definition, the test can't reliably predict 120// the name it will be stored under! So we have to search all the defs 121// in the JSON output looking for the one that has the test integer 122// field set to the right value. 123 124def Named { int AnonTestField = 1; } 125// CHECK: data['Named']['AnonTestField'] == 1 126// CHECK: data['Named']['!anonymous'] is False 127 128def { int AnonTestField = 2; } 129// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 2)['!anonymous'] is True 130 131multiclass AnonTestMulticlass<int base> { 132 def _plus_one { int AnonTestField = !add(base,1); } 133 def { int AnonTestField = !add(base,2); } 134} 135 136defm NamedDefm : AnonTestMulticlass<10>; 137// CHECK: data['NamedDefm_plus_one']['!anonymous'] is False 138// CHECK: data['NamedDefm_plus_one']['AnonTestField'] == 11 139// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 12)['!anonymous'] is True 140 141// D47431 clarifies that a named def inside a multiclass gives a 142// *non*-anonymous output record, even if the defm that instantiates 143// that multiclass is anonymous. 144defm : AnonTestMulticlass<20>; 145// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 21)['!anonymous'] is False 146// CHECK: next(rec for rec in data.values() if isinstance(rec, dict) and rec.get('AnonTestField') == 22)['!anonymous'] is True 147