From be50657c6ac534215b2cef562e2a29197259ec85 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Tue, 13 Apr 2021 11:14:30 -0700 Subject: [PATCH] [TableGen] Resolve concrete but not complete field access initializers This fixes the resolution of Rec10.Zero in ListSlices.td. As part of this, correct the definition of complete for ListInit such that it's complete iff all the elements in the list are complete rather than always being complete regardless of the elements. This is the reason Rec10.TwoFive from ListSlices.td previously resolved despite being incomplete like Rec10.Zero was Depends on D100247 Reviewed By: Paul-C-Anagnostopoulos Differential Revision: https://reviews.llvm.org/D100253 --- llvm/include/llvm/TableGen/Record.h | 1 + llvm/lib/TableGen/Record.cpp | 10 +++++++++- llvm/test/TableGen/ListSlices.td | 10 +++++----- llvm/test/TableGen/field-access-initializers.td | 6 +++++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/TableGen/Record.h b/llvm/include/llvm/TableGen/Record.h index 9432de673861..177679e31722 100644 --- a/llvm/include/llvm/TableGen/Record.h +++ b/llvm/include/llvm/TableGen/Record.h @@ -708,6 +708,7 @@ public: /// Init *resolveReferences(Resolver &R) const override; + bool isComplete() const override; bool isConcrete() const override; std::string getAsString() const override; diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 92b583da9296..1c36b64aee1e 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -655,6 +655,14 @@ Init *ListInit::resolveReferences(Resolver &R) const { return const_cast(this); } +bool ListInit::isComplete() const { + for (Init *Element : *this) { + if (!Element->isComplete()) + return false; + } + return true; +} + bool ListInit::isConcrete() const { for (Init *Element : *this) { if (!Element->isConcrete()) @@ -1924,7 +1932,7 @@ Init *FieldInit::Fold(Record *CurRec) const { FieldName->getAsUnquotedString() + "' of '" + Rec->getAsString() + "' is a forbidden self-reference"); Init *FieldVal = Def->getValue(FieldName)->getValue(); - if (FieldVal->isComplete()) + if (FieldVal->isConcrete()) return FieldVal; } return const_cast(this); diff --git a/llvm/test/TableGen/ListSlices.td b/llvm/test/TableGen/ListSlices.td index ef9fd534b609..9e80fb215f88 100644 --- a/llvm/test/TableGen/ListSlices.td +++ b/llvm/test/TableGen/ListSlices.td @@ -111,8 +111,11 @@ def Rec08 { // CHECK: def Rec09 // CHECK: int Zero = ?; // CHECK: list TwoFive = [2, 3, ?, 5]; -// CHECK: def Rec10 -// CHECK: list TwoFive = [2, 3, ?, 5]; +// We need CHECK-NEXT for these because otherwise it will match anonymous defs +// that appear later. +// CHECK: def Rec10 { +// CHECK-NEXT: int Zero = ?; +// CHECK-NEXT: list TwoFive = [2, 3, ?, 5]; def Rec09 : Class1<[?, ?, 2, 3, ?, 5, ?]>; @@ -120,6 +123,3 @@ def Rec10 { int Zero = Class1<[?, ?, 2, 3, ?, 5, ?]>.Zero; list TwoFive = Class1<[?, ?, 2, 3, ?, 5, ?]>.TwoFive; } - -// TO-DO: Notice that the first field in Rec10 is not checked. -// It is not fully resolved for reasons that need to be investigated. diff --git a/llvm/test/TableGen/field-access-initializers.td b/llvm/test/TableGen/field-access-initializers.td index 5a25e2901aee..ca25d067a168 100644 --- a/llvm/test/TableGen/field-access-initializers.td +++ b/llvm/test/TableGen/field-access-initializers.td @@ -1,6 +1,10 @@ // RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak +// CHECK: class B { +// CHECK: string value = B:impl.value; +// CHECK: } + // CHECK: --- Defs --- // CHECK: def A1 { @@ -8,7 +12,7 @@ // CHECK: } // CHECK: def B1 { -// CHECK: string value = A1.value; +// CHECK: string value = ?; // CHECK: } class A {