diff options
author | Philip Reames <preames@rivosinc.com> | 2023-03-10 15:49:27 -0800 |
---|---|---|
committer | Philip Reames <listmail@philipreames.com> | 2023-03-10 15:50:11 -0800 |
commit | 8a4451cdc3fffe121e5b5a0bddb7f44457dd0753 (patch) | |
tree | 94d5c2ecf1e9db6e333cbd9a85734a34ddd9d51a /llvm/lib/TableGen | |
parent | c3801568ef2b7f923f9116f72a6b0bb382bcaa41 (diff) | |
download | llvm-8a4451cdc3fffe121e5b5a0bddb7f44457dd0753.zip llvm-8a4451cdc3fffe121e5b5a0bddb7f44457dd0753.tar.gz llvm-8a4451cdc3fffe121e5b5a0bddb7f44457dd0753.tar.bz2 |
[llvm-tblgen] Support conditional definitions using !casts clauses
This is a follow on to D145108. This started as simply fixing the crash on an error case reported against that change, but I think this also ends up fixing the original reported issue (https://github.com/llvm/llvm-project/issues/49830) as well. More accurately, D145108 fixed the case where the cast resolves to an existing record, and this change fixes the case where the named record doesn't exist.
Differential Revision: https://reviews.llvm.org/D145711
Diffstat (limited to 'llvm/lib/TableGen')
-rw-r--r-- | llvm/lib/TableGen/Record.cpp | 55 |
1 files changed, 29 insertions, 26 deletions
diff --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp index 3bcf86c..a3f09bd 100644 --- a/llvm/lib/TableGen/Record.cpp +++ b/llvm/lib/TableGen/Record.cpp @@ -800,37 +800,40 @@ Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const { } else if (isa<RecordRecTy>(getType())) { if (StringInit *Name = dyn_cast<StringInit>(LHS)) { - if (!CurRec && !IsFinal) - break; - assert(CurRec && "NULL pointer"); - Record *D; - - // Self-references are allowed, but their resolution is delayed until - // the final resolve to ensure that we get the correct type for them. - auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit()); - if (Name == CurRec->getNameInit() || - (Anonymous && Name == Anonymous->getNameInit())) { - if (!IsFinal) - break; - D = CurRec; - } else { - D = CurRec->getRecords().getDef(Name->getValue()); - if (!D) { - if (IsFinal) - PrintFatalError(CurRec->getLoc(), - Twine("Undefined reference to record: '") + - Name->getValue() + "'\n"); - break; + Record *D = RK.getDef(Name->getValue()); + if (!D && CurRec) { + // Self-references are allowed, but their resolution is delayed until + // the final resolve to ensure that we get the correct type for them. + auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit()); + if (Name == CurRec->getNameInit() || + (Anonymous && Name == Anonymous->getNameInit())) { + if (!IsFinal) + break; + D = CurRec; } } + auto PrintFatalErrorHelper = [CurRec](const Twine &T) { + if (CurRec) + PrintFatalError(CurRec->getLoc(), T); + else + PrintFatalError(T); + }; + + if (!D) { + if (IsFinal) { + PrintFatalErrorHelper(Twine("Undefined reference to record: '") + + Name->getValue() + "'\n"); + } + break; + } + DefInit *DI = DefInit::get(D); if (!DI->getType()->typeIsA(getType())) { - PrintFatalError(CurRec->getLoc(), - Twine("Expected type '") + - getType()->getAsString() + "', got '" + - DI->getType()->getAsString() + "' in: " + - getAsString() + "\n"); + PrintFatalErrorHelper(Twine("Expected type '") + + getType()->getAsString() + "', got '" + + DI->getType()->getAsString() + "' in: " + + getAsString() + "\n"); } return DI; } |