Index: llvm/trunk/lib/TableGen/TGParser.cpp =================================================================== --- llvm/trunk/lib/TableGen/TGParser.cpp +++ llvm/trunk/lib/TableGen/TGParser.cpp @@ -740,6 +740,9 @@ } if (CurMultiClass) { + if (Name->getValue() == "NAME") + return VarInit::get(Name, StringRecTy::get()); + Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); if (CurMultiClass->Rec.isTemplateArg(MCName)) { Index: llvm/trunk/test/TableGen/MultiClass-defm-fail.td =================================================================== --- llvm/trunk/test/TableGen/MultiClass-defm-fail.td +++ llvm/trunk/test/TableGen/MultiClass-defm-fail.td @@ -0,0 +1,32 @@ +// RUN: not llvm-tblgen %s 2>&1 | FileCheck %s +// XFAIL: vg_leak + +// This test verifies that tablegen does fail if it can't resolve an unresolved +// !cast() during processing top-level defm. + +class A {} +class B { + A ba = a; +} + +multiclass M0 { + // This should work fine. + def _m00 : B(s)>; + // CHECK: error: Undefined reference:'d1_r1_no_such_record' + def _m01: B(s#"_no_such_record")>; +} + +multiclass M1 { + def _r1 : A; + // It would be nice if we could refer to _r1's name without having to pass it + // explicitly via 's'. + // XCHECK-DAG: note: instantiated from multiclass + defm _m1: M0; +} + +// CHECK: defm d1: M1 +// CHECK: note: instantiated from multiclass +// CHECK: defm _m1: M0 +// CHECK: note: instantiated from multiclass +// CHECK: def _m01: B +defm d1: M1<"d1">; Index: llvm/trunk/test/TableGen/MultiClass-defm.td =================================================================== --- llvm/trunk/test/TableGen/MultiClass-defm.td +++ llvm/trunk/test/TableGen/MultiClass-defm.td @@ -0,0 +1,50 @@ +// RUN: llvm-tblgen %s | FileCheck %s +// XFAIL: vg_leak + +class A {} +class B { + A ba = a; +} + +multiclass M0 { + def _m0 : B(s)>; + + // Uncomment to test that !cast will eventually fail if the record it refers + // to does not exist by the time we instantiate this record from the top + // level. + //def _m1 : B(s#"X")>; +} + +multiclass M1 { + def _r1 : A; + // It would be nice if we could refer to _r1's name without having to pass it + // explicitly via 's'. + defm _m1: M0; +} + +multiclass M2 { + def _x : A { + string n = NAME; + } + + def _y : B(NAME # "_x")>; + + // This used to throw an error during multiclass parsing as NAME was not + // recognized when parsing the template arguments. + defm NAME: M1; +} +defm d0: M2; +// CHECK-LABEL: def d0_m1_m0 +// CHECK: A ba = d0_r1; +// +// CHECK-LABEL: def d0_x { +// CHECK: string n = "d0"; +// +// CHECK-LABEL: def d0_y { +// CHECK: A ba = d0_x; + +// This always works, because d1_r1 is instantiated before d1_m1 which would +// attempt to !cast to it. +defm d1: M1<"d1">; +// CHECK-LABEL: def d1_m1_m0 +// CHECK: A ba = d1_r1;