1// RUN: llvm-tblgen %s | FileCheck %s 2// RUN: not llvm-tblgen -DERROR1 %s 2>&1 | FileCheck --check-prefix=ERROR1 %s 3// RUN: not llvm-tblgen -DERROR2 %s 2>&1 | FileCheck --check-prefix=ERROR2 %s 4// RUN: not llvm-tblgen -DERROR3 %s 2>&1 | FileCheck --check-prefix=ERROR3 %s 5 6#ifdef ERROR1 7// Refer to a variable we haven't defined *yet*, expecting an error. 8// ERROR1: [[@LINE+1]]:22: error: Variable not defined: 'myvar' 9def bad { dag x = (? myvar); } 10#endif 11 12// Define a global variable. 13defvar myvar = "foo"; 14 15#ifdef ERROR2 16// Demonstrate an error when a global variable is redefined. 17// ERROR2: [[@LINE+1]]:8: error: def or global variable of this name already exists 18defvar myvar = "another value"; 19#endif 20 21multiclass Test<int x> { 22 // Refer to a global variable, while inside a local scope like a multiclass. 23 def _with_global_string { string s = myvar; } 24 25 // Define some variables local to this multiclass, and prove we can refer to 26 // those too. 27 defvar myvar = !add(x, 100); 28 defvar myvar2 = "string of " # myvar; 29 def _with_local_int { int i = myvar; string s = myvar2; } 30 31#ifdef ERROR3 32 // Demonstrate an error when a local variable is redefined. 33 // ERROR3: [[@LINE+1]]:10: error: local variable of this name already exists 34 defvar myvar = "another value"; 35#endif 36} 37 38// Instantiate the above multiclass, and expect all the right outputs. 39 40// CHECK: def aaa_with_global_string { 41// CHECK-NEXT: string s = "foo"; 42// CHECK: def aaa_with_local_int { 43// CHECK-NEXT: int i = 101; 44// CHECK-NEXT: string s = "string of 101"; 45// CHECK: def bbb_with_global_string { 46// CHECK-NEXT: string s = "foo"; 47// CHECK: def bbb_with_local_int { 48// CHECK-NEXT: int i = 102; 49// CHECK-NEXT: string s = "string of 102"; 50defm aaa: Test<1>; 51defm bbb: Test<2>; 52 53// Test that local variables can be defined inside a foreach block, and inside 54// an object body. 55// 56// The scopes nest (you can refer to variables in an outer block from an inner 57// one), and the variables go out of scope again at the end of the block (in 58// particular, you don't get a redefinition error the next time round the 59// loop). 60 61// CHECK: def nest_f1_s3 { 62// CHECK-NEXT: int member = 113; 63// CHECK-NEXT: } 64// CHECK: def nest_f1_s4 { 65// CHECK-NEXT: int member = 114; 66// CHECK-NEXT: } 67// CHECK: def nest_f2_s3 { 68// CHECK-NEXT: int member = 123; 69// CHECK-NEXT: } 70// CHECK: def nest_f2_s4 { 71// CHECK-NEXT: int member = 124; 72// CHECK-NEXT: } 73foreach first = [ 1, 2 ] in { 74 defvar firstStr = "f" # first; 75 foreach second = [ 3, 4 ] in { 76 defvar secondStr = "s" # second; 77 def "nest_" # firstStr # "_" # secondStr { 78 defvar defLocalVariable = !add(!mul(first, 10), second); 79 int member = !add(100, defLocalVariable); 80 } 81 } 82} 83defvar firstStr = "now define this at the top level and still expect no error"; 84 85// Test that you can shadow an outer declaration with an inner one. Here, we 86// expect all the shadowOuter records (both above and below the inner foreach) 87// to get the value 1 from the outer definition of shadowedVariable, and the 88// shadowInner ones to get 2 from the inner definition. 89 90// CHECK: def shadowInner11 { 91// CHECK-NEXT: int var = 2; 92// CHECK: def shadowInner12 { 93// CHECK-NEXT: int var = 2; 94// CHECK: def shadowInner21 { 95// CHECK-NEXT: int var = 2; 96// CHECK: def shadowInner22 { 97// CHECK-NEXT: int var = 2; 98// CHECK: def shadowInnerIf1 { 99// CHECK-NEXT: int var = 3; 100// CHECK: def shadowOuterAbove1 { 101// CHECK-NEXT: int var = 1; 102// CHECK: def shadowOuterAbove2 { 103// CHECK-NEXT: int var = 1; 104// CHECK: def shadowOuterBelowForeach1 { 105// CHECK-NEXT: int var = 1; 106// CHECK: def shadowOuterBelowForeach2 { 107// CHECK-NEXT: int var = 1; 108// CHECK: def shadowOuterBelowIf1 { 109// CHECK-NEXT: int var = 1; 110// CHECK: def shadowOuterBelowIf2 { 111// CHECK-NEXT: int var = 1; 112 113foreach first = [ 1, 2 ] in { 114 defvar shadowedVariable = 1; 115 def shadowOuterAbove # first { int var = shadowedVariable; } 116 117 // The foreach statement opens a new scope, in which a new variable of the 118 // same name can be defined without clashing with the outer one. 119 foreach second = [ 1, 2 ] in { 120 defvar shadowedVariable = 2; 121 def shadowInner # first # second { int var = shadowedVariable; } 122 } 123 124 // Now the outer variable is back in scope. 125 def shadowOuterBelowForeach # first { int var = shadowedVariable; } 126 127 // An if statement also opens a new scope. 128 if !eq(first, 1) then { 129 defvar shadowedVariable = 3; 130 def shadowInnerIf # first { int var = shadowedVariable; } 131 } 132 133 // Now the outer variable is back in scope again. 134 def shadowOuterBelowIf # first { int var = shadowedVariable; } 135} 136 137// Test that a top-level let statement also makes a variable scope (on the 138// general principle of consistency, because it defines a braced sub-block). 139 140let someVariable = "some value" in { 141 defvar myvar = "override the definition from above and expect no error"; 142} 143// CHECK: def topLevelLetTest { 144// CHECK-NEXT: string val = "foo"; 145def topLevelLetTest { string val = myvar; } 146