184c287e3SPeter Collingbourne //===- Record.cpp - Record implementation ---------------------------------===//
284c287e3SPeter Collingbourne //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
684c287e3SPeter Collingbourne //
784c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
884c287e3SPeter Collingbourne //
984c287e3SPeter Collingbourne // Implement the tablegen record classes.
1084c287e3SPeter Collingbourne //
1184c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
1284c287e3SPeter Collingbourne 
1392f49b89Sserge-sans-paille #include "llvm/TableGen/Record.h"
14af615896SEugene Zelenko #include "llvm/ADT/ArrayRef.h"
1584c287e3SPeter Collingbourne #include "llvm/ADT/DenseMap.h"
1684c287e3SPeter Collingbourne #include "llvm/ADT/FoldingSet.h"
1784bac184SMatthias Braun #include "llvm/ADT/SmallString.h"
18ed0881b2SChandler Carruth #include "llvm/ADT/SmallVector.h"
1984c287e3SPeter Collingbourne #include "llvm/ADT/StringExtras.h"
2084c287e3SPeter Collingbourne #include "llvm/ADT/StringMap.h"
21af615896SEugene Zelenko #include "llvm/ADT/StringRef.h"
22432a3883SNico Weber #include "llvm/Config/llvm-config.h"
23af615896SEugene Zelenko #include "llvm/Support/Allocator.h"
24af615896SEugene Zelenko #include "llvm/Support/Casting.h"
2533d7b762SEugene Zelenko #include "llvm/Support/Compiler.h"
26ed0881b2SChandler Carruth #include "llvm/Support/ErrorHandling.h"
27af615896SEugene Zelenko #include "llvm/Support/SMLoc.h"
28af615896SEugene Zelenko #include "llvm/Support/raw_ostream.h"
29ed0881b2SChandler Carruth #include "llvm/TableGen/Error.h"
3033d7b762SEugene Zelenko #include <cassert>
3133d7b762SEugene Zelenko #include <cstdint>
32cdb7c31fSSimon Tatham #include <map>
3392f49b89Sserge-sans-paille #include <memory>
34af615896SEugene Zelenko #include <string>
35af615896SEugene Zelenko #include <utility>
36af615896SEugene Zelenko #include <vector>
3784c287e3SPeter Collingbourne 
3884c287e3SPeter Collingbourne using namespace llvm;
3984c287e3SPeter Collingbourne 
40c365cee6SDaniel Sanders #define DEBUG_TYPE "tblgen-records"
41c365cee6SDaniel Sanders 
427480efd6SRiver Riddle //===----------------------------------------------------------------------===//
437480efd6SRiver Riddle //    Context
447480efd6SRiver Riddle //===----------------------------------------------------------------------===//
457480efd6SRiver Riddle 
467480efd6SRiver Riddle namespace llvm {
477480efd6SRiver Riddle namespace detail {
482ac3cd20SRiver Riddle /// This class represents the internal implementation of the RecordKeeper.
492ac3cd20SRiver Riddle /// It contains all of the contextual static state of the Record classes. It is
502ac3cd20SRiver Riddle /// kept out-of-line to simplify dependencies, and also make it easier for
512ac3cd20SRiver Riddle /// internal classes to access the uniquer state of the keeper.
522ac3cd20SRiver Riddle struct RecordKeeperImpl {
RecordKeeperImplllvm::detail::RecordKeeperImpl532ac3cd20SRiver Riddle   RecordKeeperImpl(RecordKeeper &RK)
542ac3cd20SRiver Riddle       : SharedBitRecTy(RK), SharedIntRecTy(RK), SharedStringRecTy(RK),
552ac3cd20SRiver Riddle         SharedDagRecTy(RK), AnyRecord(RK, 0), TheUnsetInit(RK),
562ac3cd20SRiver Riddle         TrueBitInit(true, &SharedBitRecTy),
577480efd6SRiver Riddle         FalseBitInit(false, &SharedBitRecTy), StringInitStringPool(Allocator),
582ac3cd20SRiver Riddle         StringInitCodePool(Allocator), AnonCounter(0), LastRecordID(0) {}
597480efd6SRiver Riddle 
607480efd6SRiver Riddle   BumpPtrAllocator Allocator;
617480efd6SRiver Riddle   std::vector<BitsRecTy *> SharedBitsRecTys;
627480efd6SRiver Riddle   BitRecTy SharedBitRecTy;
637480efd6SRiver Riddle   IntRecTy SharedIntRecTy;
647480efd6SRiver Riddle   StringRecTy SharedStringRecTy;
657480efd6SRiver Riddle   DagRecTy SharedDagRecTy;
667480efd6SRiver Riddle 
677480efd6SRiver Riddle   RecordRecTy AnyRecord;
687480efd6SRiver Riddle   UnsetInit TheUnsetInit;
697480efd6SRiver Riddle   BitInit TrueBitInit;
707480efd6SRiver Riddle   BitInit FalseBitInit;
717480efd6SRiver Riddle 
727480efd6SRiver Riddle   FoldingSet<BitsInit> TheBitsInitPool;
737480efd6SRiver Riddle   std::map<int64_t, IntInit *> TheIntInitPool;
747480efd6SRiver Riddle   StringMap<StringInit *, BumpPtrAllocator &> StringInitStringPool;
757480efd6SRiver Riddle   StringMap<StringInit *, BumpPtrAllocator &> StringInitCodePool;
767480efd6SRiver Riddle   FoldingSet<ListInit> TheListInitPool;
777480efd6SRiver Riddle   FoldingSet<UnOpInit> TheUnOpInitPool;
787480efd6SRiver Riddle   FoldingSet<BinOpInit> TheBinOpInitPool;
797480efd6SRiver Riddle   FoldingSet<TernOpInit> TheTernOpInitPool;
807480efd6SRiver Riddle   FoldingSet<FoldOpInit> TheFoldOpInitPool;
817480efd6SRiver Riddle   FoldingSet<IsAOpInit> TheIsAOpInitPool;
8263448488Swangpc   FoldingSet<ExistsOpInit> TheExistsOpInitPool;
837480efd6SRiver Riddle   DenseMap<std::pair<RecTy *, Init *>, VarInit *> TheVarInitPool;
847480efd6SRiver Riddle   DenseMap<std::pair<TypedInit *, unsigned>, VarBitInit *> TheVarBitInitPool;
857480efd6SRiver Riddle   DenseMap<std::pair<TypedInit *, unsigned>, VarListElementInit *>
867480efd6SRiver Riddle       TheVarListElementInitPool;
877480efd6SRiver Riddle   FoldingSet<VarDefInit> TheVarDefInitPool;
887480efd6SRiver Riddle   DenseMap<std::pair<Init *, StringInit *>, FieldInit *> TheFieldInitPool;
897480efd6SRiver Riddle   FoldingSet<CondOpInit> TheCondOpInitPool;
907480efd6SRiver Riddle   FoldingSet<DagInit> TheDagInitPool;
912ac3cd20SRiver Riddle   FoldingSet<RecordRecTy> RecordTypePool;
927480efd6SRiver Riddle 
932ac3cd20SRiver Riddle   unsigned AnonCounter;
947480efd6SRiver Riddle   unsigned LastRecordID;
957480efd6SRiver Riddle };
967480efd6SRiver Riddle } // namespace detail
977480efd6SRiver Riddle } // namespace llvm
987480efd6SRiver Riddle 
9984c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
10084c287e3SPeter Collingbourne //    Type implementations
10184c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
10284c287e3SPeter Collingbourne 
103615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const104eb2a2546SYaron Keren LLVM_DUMP_METHOD void RecTy::dump() const { print(errs()); }
1058c209aa8SMatthias Braun #endif
10684c287e3SPeter Collingbourne 
getListTy()10784c287e3SPeter Collingbourne ListRecTy *RecTy::getListTy() {
10884c287e3SPeter Collingbourne   if (!ListTy)
1092ac3cd20SRiver Riddle     ListTy = new (RK.getImpl().Allocator) ListRecTy(this);
110d0edb0dfSMatthias Braun   return ListTy;
11184c287e3SPeter Collingbourne }
11284c287e3SPeter Collingbourne 
typeIsConvertibleTo(const RecTy * RHS) const11315864f15SCraig Topper bool RecTy::typeIsConvertibleTo(const RecTy *RHS) const {
11493be7d59SSean Silva   assert(RHS && "NULL pointer");
11593be7d59SSean Silva   return Kind == RHS->getRecTyKind();
11693be7d59SSean Silva }
11793be7d59SSean Silva 
typeIsA(const RecTy * RHS) const118dfda9dccSNicolai Haehnle bool RecTy::typeIsA(const RecTy *RHS) const { return this == RHS; }
119dfda9dccSNicolai Haehnle 
get(RecordKeeper & RK)1202ac3cd20SRiver Riddle BitRecTy *BitRecTy::get(RecordKeeper &RK) {
1212ac3cd20SRiver Riddle   return &RK.getImpl().SharedBitRecTy;
1222ac3cd20SRiver Riddle }
1237480efd6SRiver Riddle 
typeIsConvertibleTo(const RecTy * RHS) const12415864f15SCraig Topper bool BitRecTy::typeIsConvertibleTo(const RecTy *RHS) const{
12515864f15SCraig Topper   if (RecTy::typeIsConvertibleTo(RHS) || RHS->getRecTyKind() == IntRecTyKind)
12693be7d59SSean Silva     return true;
12793be7d59SSean Silva   if (const BitsRecTy *BitsTy = dyn_cast<BitsRecTy>(RHS))
12893be7d59SSean Silva     return BitsTy->getNumBits() == 1;
12993be7d59SSean Silva   return false;
13093be7d59SSean Silva }
13193be7d59SSean Silva 
get(RecordKeeper & RK,unsigned Sz)1322ac3cd20SRiver Riddle BitsRecTy *BitsRecTy::get(RecordKeeper &RK, unsigned Sz) {
1332ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
1342ac3cd20SRiver Riddle   if (Sz >= RKImpl.SharedBitsRecTys.size())
1352ac3cd20SRiver Riddle     RKImpl.SharedBitsRecTys.resize(Sz + 1);
1362ac3cd20SRiver Riddle   BitsRecTy *&Ty = RKImpl.SharedBitsRecTys[Sz];
13784c287e3SPeter Collingbourne   if (!Ty)
1382ac3cd20SRiver Riddle     Ty = new (RKImpl.Allocator) BitsRecTy(RK, Sz);
139d0edb0dfSMatthias Braun   return Ty;
14084c287e3SPeter Collingbourne }
14184c287e3SPeter Collingbourne 
getAsString() const14284c287e3SPeter Collingbourne std::string BitsRecTy::getAsString() const {
14384c287e3SPeter Collingbourne   return "bits<" + utostr(Size) + ">";
14484c287e3SPeter Collingbourne }
14584c287e3SPeter Collingbourne 
typeIsConvertibleTo(const RecTy * RHS) const14615864f15SCraig Topper bool BitsRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
14715864f15SCraig Topper   if (RecTy::typeIsConvertibleTo(RHS)) //argument and the sender are same type
14893be7d59SSean Silva     return cast<BitsRecTy>(RHS)->Size == Size;
14993be7d59SSean Silva   RecTyKind kind = RHS->getRecTyKind();
15093be7d59SSean Silva   return (kind == BitRecTyKind && Size == 1) || (kind == IntRecTyKind);
15193be7d59SSean Silva }
15293be7d59SSean Silva 
typeIsA(const RecTy * RHS) const153dfda9dccSNicolai Haehnle bool BitsRecTy::typeIsA(const RecTy *RHS) const {
154dfda9dccSNicolai Haehnle   if (const BitsRecTy *RHSb = dyn_cast<BitsRecTy>(RHS))
155dfda9dccSNicolai Haehnle     return RHSb->Size == Size;
156dfda9dccSNicolai Haehnle   return false;
157dfda9dccSNicolai Haehnle }
158dfda9dccSNicolai Haehnle 
get(RecordKeeper & RK)1592ac3cd20SRiver Riddle IntRecTy *IntRecTy::get(RecordKeeper &RK) {
1602ac3cd20SRiver Riddle   return &RK.getImpl().SharedIntRecTy;
1612ac3cd20SRiver Riddle }
1627480efd6SRiver Riddle 
typeIsConvertibleTo(const RecTy * RHS) const16315864f15SCraig Topper bool IntRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
16493be7d59SSean Silva   RecTyKind kind = RHS->getRecTyKind();
16593be7d59SSean Silva   return kind==BitRecTyKind || kind==BitsRecTyKind || kind==IntRecTyKind;
16693be7d59SSean Silva }
16793be7d59SSean Silva 
get(RecordKeeper & RK)1682ac3cd20SRiver Riddle StringRecTy *StringRecTy::get(RecordKeeper &RK) {
1692ac3cd20SRiver Riddle   return &RK.getImpl().SharedStringRecTy;
1702ac3cd20SRiver Riddle }
1717480efd6SRiver Riddle 
getAsString() const1726548196cSCraig Topper std::string StringRecTy::getAsString() const {
1736548196cSCraig Topper   return "string";
1746548196cSCraig Topper }
17584c287e3SPeter Collingbourne 
typeIsConvertibleTo(const RecTy * RHS) const1768fb962c0SNicolai Haehnle bool StringRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
1778fb962c0SNicolai Haehnle   RecTyKind Kind = RHS->getRecTyKind();
178415fab6fSPaul C. Anagnostopoulos   return Kind == StringRecTyKind;
1798fb962c0SNicolai Haehnle }
1808fb962c0SNicolai Haehnle 
getAsString() const18184c287e3SPeter Collingbourne std::string ListRecTy::getAsString() const {
1828ce75e27SPaul C. Anagnostopoulos   return "list<" + ElementTy->getAsString() + ">";
18384c287e3SPeter Collingbourne }
18484c287e3SPeter Collingbourne 
typeIsConvertibleTo(const RecTy * RHS) const18515864f15SCraig Topper bool ListRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
18615864f15SCraig Topper   if (const auto *ListTy = dyn_cast<ListRecTy>(RHS))
1878ce75e27SPaul C. Anagnostopoulos     return ElementTy->typeIsConvertibleTo(ListTy->getElementType());
18893be7d59SSean Silva   return false;
18993be7d59SSean Silva }
19093be7d59SSean Silva 
typeIsA(const RecTy * RHS) const191dfda9dccSNicolai Haehnle bool ListRecTy::typeIsA(const RecTy *RHS) const {
192dfda9dccSNicolai Haehnle   if (const ListRecTy *RHSl = dyn_cast<ListRecTy>(RHS))
193dfda9dccSNicolai Haehnle     return getElementType()->typeIsA(RHSl->getElementType());
194dfda9dccSNicolai Haehnle   return false;
195dfda9dccSNicolai Haehnle }
196dfda9dccSNicolai Haehnle 
get(RecordKeeper & RK)1972ac3cd20SRiver Riddle DagRecTy *DagRecTy::get(RecordKeeper &RK) {
1982ac3cd20SRiver Riddle   return &RK.getImpl().SharedDagRecTy;
1992ac3cd20SRiver Riddle }
2007480efd6SRiver Riddle 
getAsString() const2016548196cSCraig Topper std::string DagRecTy::getAsString() const {
2026548196cSCraig Topper   return "dag";
2036548196cSCraig Topper }
2046548196cSCraig Topper 
ProfileRecordRecTy(FoldingSetNodeID & ID,ArrayRef<Record * > Classes)20513080fd1SNicolai Haehnle static void ProfileRecordRecTy(FoldingSetNodeID &ID,
20613080fd1SNicolai Haehnle                                ArrayRef<Record *> Classes) {
20713080fd1SNicolai Haehnle   ID.AddInteger(Classes.size());
20813080fd1SNicolai Haehnle   for (Record *R : Classes)
20913080fd1SNicolai Haehnle     ID.AddPointer(R);
21013080fd1SNicolai Haehnle }
21113080fd1SNicolai Haehnle 
get(RecordKeeper & RK,ArrayRef<Record * > UnsortedClasses)2122ac3cd20SRiver Riddle RecordRecTy *RecordRecTy::get(RecordKeeper &RK,
2132ac3cd20SRiver Riddle                               ArrayRef<Record *> UnsortedClasses) {
2142ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
2157480efd6SRiver Riddle   if (UnsortedClasses.empty())
2162ac3cd20SRiver Riddle     return &RKImpl.AnyRecord;
21713080fd1SNicolai Haehnle 
2182ac3cd20SRiver Riddle   FoldingSet<RecordRecTy> &ThePool = RKImpl.RecordTypePool;
21913080fd1SNicolai Haehnle 
22013080fd1SNicolai Haehnle   SmallVector<Record *, 4> Classes(UnsortedClasses.begin(),
22113080fd1SNicolai Haehnle                                    UnsortedClasses.end());
2220cac726aSFangrui Song   llvm::sort(Classes, [](Record *LHS, Record *RHS) {
22313080fd1SNicolai Haehnle     return LHS->getNameInitAsString() < RHS->getNameInitAsString();
22413080fd1SNicolai Haehnle   });
22513080fd1SNicolai Haehnle 
22613080fd1SNicolai Haehnle   FoldingSetNodeID ID;
22713080fd1SNicolai Haehnle   ProfileRecordRecTy(ID, Classes);
22813080fd1SNicolai Haehnle 
22913080fd1SNicolai Haehnle   void *IP = nullptr;
23013080fd1SNicolai Haehnle   if (RecordRecTy *Ty = ThePool.FindNodeOrInsertPos(ID, IP))
23113080fd1SNicolai Haehnle     return Ty;
23213080fd1SNicolai Haehnle 
23313080fd1SNicolai Haehnle #ifndef NDEBUG
23413080fd1SNicolai Haehnle   // Check for redundancy.
23513080fd1SNicolai Haehnle   for (unsigned i = 0; i < Classes.size(); ++i) {
23613080fd1SNicolai Haehnle     for (unsigned j = 0; j < Classes.size(); ++j) {
23713080fd1SNicolai Haehnle       assert(i == j || !Classes[i]->isSubClassOf(Classes[j]));
23813080fd1SNicolai Haehnle     }
23913080fd1SNicolai Haehnle     assert(&Classes[0]->getRecords() == &Classes[i]->getRecords());
24013080fd1SNicolai Haehnle   }
24113080fd1SNicolai Haehnle #endif
24213080fd1SNicolai Haehnle 
2432ac3cd20SRiver Riddle   void *Mem = RKImpl.Allocator.Allocate(
2447480efd6SRiver Riddle       totalSizeToAlloc<Record *>(Classes.size()), alignof(RecordRecTy));
2452ac3cd20SRiver Riddle   RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes.size());
24613080fd1SNicolai Haehnle   std::uninitialized_copy(Classes.begin(), Classes.end(),
24713080fd1SNicolai Haehnle                           Ty->getTrailingObjects<Record *>());
24813080fd1SNicolai Haehnle   ThePool.InsertNode(Ty, IP);
24913080fd1SNicolai Haehnle   return Ty;
25013080fd1SNicolai Haehnle }
get(Record * Class)2512ac3cd20SRiver Riddle RecordRecTy *RecordRecTy::get(Record *Class) {
2522ac3cd20SRiver Riddle   assert(Class && "unexpected null class");
2532ac3cd20SRiver Riddle   return get(Class->getRecords(), Class);
2542ac3cd20SRiver Riddle }
25513080fd1SNicolai Haehnle 
Profile(FoldingSetNodeID & ID) const25613080fd1SNicolai Haehnle void RecordRecTy::Profile(FoldingSetNodeID &ID) const {
25713080fd1SNicolai Haehnle   ProfileRecordRecTy(ID, getClasses());
25884c287e3SPeter Collingbourne }
25984c287e3SPeter Collingbourne 
getAsString() const26084c287e3SPeter Collingbourne std::string RecordRecTy::getAsString() const {
26113080fd1SNicolai Haehnle   if (NumClasses == 1)
2624186cc7cSNicolai Haehnle     return getClasses()[0]->getNameInitAsString();
26313080fd1SNicolai Haehnle 
26413080fd1SNicolai Haehnle   std::string Str = "{";
26513080fd1SNicolai Haehnle   bool First = true;
26613080fd1SNicolai Haehnle   for (Record *R : getClasses()) {
26713080fd1SNicolai Haehnle     if (!First)
26813080fd1SNicolai Haehnle       Str += ", ";
26913080fd1SNicolai Haehnle     First = false;
2704186cc7cSNicolai Haehnle     Str += R->getNameInitAsString();
27113080fd1SNicolai Haehnle   }
27213080fd1SNicolai Haehnle   Str += "}";
27313080fd1SNicolai Haehnle   return Str;
27413080fd1SNicolai Haehnle }
27513080fd1SNicolai Haehnle 
isSubClassOf(Record * Class) const27613080fd1SNicolai Haehnle bool RecordRecTy::isSubClassOf(Record *Class) const {
27713080fd1SNicolai Haehnle   return llvm::any_of(getClasses(), [Class](Record *MySuperClass) {
27813080fd1SNicolai Haehnle                                       return MySuperClass == Class ||
27913080fd1SNicolai Haehnle                                              MySuperClass->isSubClassOf(Class);
28013080fd1SNicolai Haehnle                                     });
28184c287e3SPeter Collingbourne }
28284c287e3SPeter Collingbourne 
typeIsConvertibleTo(const RecTy * RHS) const28315864f15SCraig Topper bool RecordRecTy::typeIsConvertibleTo(const RecTy *RHS) const {
28413080fd1SNicolai Haehnle   if (this == RHS)
28513080fd1SNicolai Haehnle     return true;
28613080fd1SNicolai Haehnle 
28793be7d59SSean Silva   const RecordRecTy *RTy = dyn_cast<RecordRecTy>(RHS);
28893be7d59SSean Silva   if (!RTy)
28993be7d59SSean Silva     return false;
29093be7d59SSean Silva 
29113080fd1SNicolai Haehnle   return llvm::all_of(RTy->getClasses(), [this](Record *TargetClass) {
29213080fd1SNicolai Haehnle                                            return isSubClassOf(TargetClass);
29313080fd1SNicolai Haehnle                                          });
29413080fd1SNicolai Haehnle }
29584c287e3SPeter Collingbourne 
typeIsA(const RecTy * RHS) const296dfda9dccSNicolai Haehnle bool RecordRecTy::typeIsA(const RecTy *RHS) const {
297dfda9dccSNicolai Haehnle   return typeIsConvertibleTo(RHS);
298dfda9dccSNicolai Haehnle }
299dfda9dccSNicolai Haehnle 
resolveRecordTypes(RecordRecTy * T1,RecordRecTy * T2)30013080fd1SNicolai Haehnle static RecordRecTy *resolveRecordTypes(RecordRecTy *T1, RecordRecTy *T2) {
30113080fd1SNicolai Haehnle   SmallVector<Record *, 4> CommonSuperClasses;
302848e8f93SKazu Hirata   SmallVector<Record *, 4> Stack(T1->classes_begin(), T1->classes_end());
30313080fd1SNicolai Haehnle 
30413080fd1SNicolai Haehnle   while (!Stack.empty()) {
30516baad8fSKazu Hirata     Record *R = Stack.pop_back_val();
30613080fd1SNicolai Haehnle 
30713080fd1SNicolai Haehnle     if (T2->isSubClassOf(R)) {
30813080fd1SNicolai Haehnle       CommonSuperClasses.push_back(R);
30913080fd1SNicolai Haehnle     } else {
31013080fd1SNicolai Haehnle       R->getDirectSuperClasses(Stack);
31113080fd1SNicolai Haehnle     }
31213080fd1SNicolai Haehnle   }
31313080fd1SNicolai Haehnle 
3142ac3cd20SRiver Riddle   return RecordRecTy::get(T1->getRecordKeeper(), CommonSuperClasses);
31584c287e3SPeter Collingbourne }
31684c287e3SPeter Collingbourne 
resolveTypes(RecTy * T1,RecTy * T2)31784c287e3SPeter Collingbourne RecTy *llvm::resolveTypes(RecTy *T1, RecTy *T2) {
31813080fd1SNicolai Haehnle   if (T1 == T2)
31913080fd1SNicolai Haehnle     return T1;
32013080fd1SNicolai Haehnle 
32113080fd1SNicolai Haehnle   if (RecordRecTy *RecTy1 = dyn_cast<RecordRecTy>(T1)) {
32213080fd1SNicolai Haehnle     if (RecordRecTy *RecTy2 = dyn_cast<RecordRecTy>(T2))
32313080fd1SNicolai Haehnle       return resolveRecordTypes(RecTy1, RecTy2);
32413080fd1SNicolai Haehnle   }
32513080fd1SNicolai Haehnle 
3268f43c6f0SSean Silva   if (T1->typeIsConvertibleTo(T2))
3278f43c6f0SSean Silva     return T2;
3288f43c6f0SSean Silva   if (T2->typeIsConvertibleTo(T1))
3298f43c6f0SSean Silva     return T1;
3308f43c6f0SSean Silva 
33113080fd1SNicolai Haehnle   if (ListRecTy *ListTy1 = dyn_cast<ListRecTy>(T1)) {
33213080fd1SNicolai Haehnle     if (ListRecTy *ListTy2 = dyn_cast<ListRecTy>(T2)) {
33313080fd1SNicolai Haehnle       RecTy* NewType = resolveTypes(ListTy1->getElementType(),
33413080fd1SNicolai Haehnle                                     ListTy2->getElementType());
33513080fd1SNicolai Haehnle       if (NewType)
33613080fd1SNicolai Haehnle         return NewType->getListTy();
33784c287e3SPeter Collingbourne     }
33884c287e3SPeter Collingbourne   }
33913080fd1SNicolai Haehnle 
340011817a0SCraig Topper   return nullptr;
34184c287e3SPeter Collingbourne }
34284c287e3SPeter Collingbourne 
34384c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
34484c287e3SPeter Collingbourne //    Initializer implementations
34584c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
34684c287e3SPeter Collingbourne 
anchor()347a379b181SDavid Blaikie void Init::anchor() {}
348af615896SEugene Zelenko 
349615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const350eb2a2546SYaron Keren LLVM_DUMP_METHOD void Init::dump() const { return print(errs()); }
3518c209aa8SMatthias Braun #endif
35284c287e3SPeter Collingbourne 
getRecordKeeper() const3532ac3cd20SRiver Riddle RecordKeeper &Init::getRecordKeeper() const {
3542ac3cd20SRiver Riddle   if (auto *TyInit = dyn_cast<TypedInit>(this))
3552ac3cd20SRiver Riddle     return TyInit->getType()->getRecordKeeper();
3562ac3cd20SRiver Riddle   return cast<UnsetInit>(this)->getRecordKeeper();
3572ac3cd20SRiver Riddle }
3582ac3cd20SRiver Riddle 
get(RecordKeeper & RK)3592ac3cd20SRiver Riddle UnsetInit *UnsetInit::get(RecordKeeper &RK) {
3602ac3cd20SRiver Riddle   return &RK.getImpl().TheUnsetInit;
3612ac3cd20SRiver Riddle }
36284c287e3SPeter Collingbourne 
getCastTo(RecTy * Ty) const363dfda9dccSNicolai Haehnle Init *UnsetInit::getCastTo(RecTy *Ty) const {
364dfda9dccSNicolai Haehnle   return const_cast<UnsetInit *>(this);
36595819069SCraig Topper }
36695819069SCraig Topper 
convertInitializerTo(RecTy * Ty) const367dfda9dccSNicolai Haehnle Init *UnsetInit::convertInitializerTo(RecTy *Ty) const {
36895819069SCraig Topper   return const_cast<UnsetInit *>(this);
36995819069SCraig Topper }
370a379b181SDavid Blaikie 
get(RecordKeeper & RK,bool V)3712ac3cd20SRiver Riddle BitInit *BitInit::get(RecordKeeper &RK, bool V) {
3722ac3cd20SRiver Riddle   return V ? &RK.getImpl().TrueBitInit : &RK.getImpl().FalseBitInit;
37384c287e3SPeter Collingbourne }
37484c287e3SPeter Collingbourne 
convertInitializerTo(RecTy * Ty) const37595819069SCraig Topper Init *BitInit::convertInitializerTo(RecTy *Ty) const {
37695819069SCraig Topper   if (isa<BitRecTy>(Ty))
37795819069SCraig Topper     return const_cast<BitInit *>(this);
37895819069SCraig Topper 
37995819069SCraig Topper   if (isa<IntRecTy>(Ty))
3802ac3cd20SRiver Riddle     return IntInit::get(getRecordKeeper(), getValue());
38195819069SCraig Topper 
38295819069SCraig Topper   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
38395819069SCraig Topper     // Can only convert single bit.
38495819069SCraig Topper     if (BRT->getNumBits() == 1)
3852ac3cd20SRiver Riddle       return BitsInit::get(getRecordKeeper(), const_cast<BitInit *>(this));
38695819069SCraig Topper   }
38795819069SCraig Topper 
38895819069SCraig Topper   return nullptr;
38995819069SCraig Topper }
39095819069SCraig Topper 
39184c287e3SPeter Collingbourne static void
ProfileBitsInit(FoldingSetNodeID & ID,ArrayRef<Init * > Range)39284c287e3SPeter Collingbourne ProfileBitsInit(FoldingSetNodeID &ID, ArrayRef<Init *> Range) {
39384c287e3SPeter Collingbourne   ID.AddInteger(Range.size());
39484c287e3SPeter Collingbourne 
395119998dbSCraig Topper   for (Init *I : Range)
396119998dbSCraig Topper     ID.AddPointer(I);
39784c287e3SPeter Collingbourne }
39884c287e3SPeter Collingbourne 
get(RecordKeeper & RK,ArrayRef<Init * > Range)3992ac3cd20SRiver Riddle BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<Init *> Range) {
40084c287e3SPeter Collingbourne   FoldingSetNodeID ID;
40184c287e3SPeter Collingbourne   ProfileBitsInit(ID, Range);
40284c287e3SPeter Collingbourne 
4032ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
404011817a0SCraig Topper   void *IP = nullptr;
4052ac3cd20SRiver Riddle   if (BitsInit *I = RKImpl.TheBitsInitPool.FindNodeOrInsertPos(ID, IP))
40684c287e3SPeter Collingbourne     return I;
40784c287e3SPeter Collingbourne 
4082ac3cd20SRiver Riddle   void *Mem = RKImpl.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
4092ac3cd20SRiver Riddle                                         alignof(BitsInit));
4102ac3cd20SRiver Riddle   BitsInit *I = new (Mem) BitsInit(RK, Range.size());
411fbfd5780SCraig Topper   std::uninitialized_copy(Range.begin(), Range.end(),
412fbfd5780SCraig Topper                           I->getTrailingObjects<Init *>());
4132ac3cd20SRiver Riddle   RKImpl.TheBitsInitPool.InsertNode(I, IP);
41484c287e3SPeter Collingbourne   return I;
41584c287e3SPeter Collingbourne }
41684c287e3SPeter Collingbourne 
Profile(FoldingSetNodeID & ID) const41784c287e3SPeter Collingbourne void BitsInit::Profile(FoldingSetNodeID &ID) const {
418fbfd5780SCraig Topper   ProfileBitsInit(ID, makeArrayRef(getTrailingObjects<Init *>(), NumBits));
41984c287e3SPeter Collingbourne }
42084c287e3SPeter Collingbourne 
convertInitializerTo(RecTy * Ty) const42195819069SCraig Topper Init *BitsInit::convertInitializerTo(RecTy *Ty) const {
42295819069SCraig Topper   if (isa<BitRecTy>(Ty)) {
42395819069SCraig Topper     if (getNumBits() != 1) return nullptr; // Only accept if just one bit!
42495819069SCraig Topper     return getBit(0);
42595819069SCraig Topper   }
42695819069SCraig Topper 
42795819069SCraig Topper   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
42895819069SCraig Topper     // If the number of bits is right, return it.  Otherwise we need to expand
42995819069SCraig Topper     // or truncate.
43095819069SCraig Topper     if (getNumBits() != BRT->getNumBits()) return nullptr;
43195819069SCraig Topper     return const_cast<BitsInit *>(this);
43295819069SCraig Topper   }
43395819069SCraig Topper 
43495819069SCraig Topper   if (isa<IntRecTy>(Ty)) {
43595819069SCraig Topper     int64_t Result = 0;
43695819069SCraig Topper     for (unsigned i = 0, e = getNumBits(); i != e; ++i)
43795819069SCraig Topper       if (auto *Bit = dyn_cast<BitInit>(getBit(i)))
43895819069SCraig Topper         Result |= static_cast<int64_t>(Bit->getValue()) << i;
43995819069SCraig Topper       else
44095819069SCraig Topper         return nullptr;
4412ac3cd20SRiver Riddle     return IntInit::get(getRecordKeeper(), Result);
44295819069SCraig Topper   }
44395819069SCraig Topper 
44495819069SCraig Topper   return nullptr;
44595819069SCraig Topper }
44695819069SCraig Topper 
44784c287e3SPeter Collingbourne Init *
convertInitializerBitRange(ArrayRef<unsigned> Bits) const4481ddb78cdSMatthias Braun BitsInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
44984c287e3SPeter Collingbourne   SmallVector<Init *, 16> NewBits(Bits.size());
45084c287e3SPeter Collingbourne 
45184c287e3SPeter Collingbourne   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
45284c287e3SPeter Collingbourne     if (Bits[i] >= getNumBits())
453011817a0SCraig Topper       return nullptr;
45484c287e3SPeter Collingbourne     NewBits[i] = getBit(Bits[i]);
45584c287e3SPeter Collingbourne   }
4562ac3cd20SRiver Riddle   return BitsInit::get(getRecordKeeper(), NewBits);
45784c287e3SPeter Collingbourne }
45884c287e3SPeter Collingbourne 
isConcrete() const4590f529885SNicolai Haehnle bool BitsInit::isConcrete() const {
4600f529885SNicolai Haehnle   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
4610f529885SNicolai Haehnle     if (!getBit(i)->isConcrete())
4620f529885SNicolai Haehnle       return false;
4630f529885SNicolai Haehnle   }
4640f529885SNicolai Haehnle   return true;
4650f529885SNicolai Haehnle }
4660f529885SNicolai Haehnle 
getAsString() const46784c287e3SPeter Collingbourne std::string BitsInit::getAsString() const {
46884c287e3SPeter Collingbourne   std::string Result = "{ ";
46984c287e3SPeter Collingbourne   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
47084c287e3SPeter Collingbourne     if (i) Result += ", ";
47184c287e3SPeter Collingbourne     if (Init *Bit = getBit(e-i-1))
47284c287e3SPeter Collingbourne       Result += Bit->getAsString();
47384c287e3SPeter Collingbourne     else
47484c287e3SPeter Collingbourne       Result += "*";
47584c287e3SPeter Collingbourne   }
47684c287e3SPeter Collingbourne   return Result + " }";
47784c287e3SPeter Collingbourne }
47884c287e3SPeter Collingbourne 
47984c287e3SPeter Collingbourne // resolveReferences - If there are any field references that refer to fields
48084c287e3SPeter Collingbourne // that have been filled in, we can propagate the values now.
resolveReferences(Resolver & R) const4810b0eaf7eSNicolai Haehnle Init *BitsInit::resolveReferences(Resolver &R) const {
48284c287e3SPeter Collingbourne   bool Changed = false;
48384c287e3SPeter Collingbourne   SmallVector<Init *, 16> NewBits(getNumBits());
48484c287e3SPeter Collingbourne 
4859a84a509SNicolai Haehnle   Init *CachedBitVarRef = nullptr;
4869a84a509SNicolai Haehnle   Init *CachedBitVarResolved = nullptr;
48784c287e3SPeter Collingbourne 
488026f8333SMichael Liao   for (unsigned i = 0, e = getNumBits(); i != e; ++i) {
489fbfd5780SCraig Topper     Init *CurBit = getBit(i);
4909a84a509SNicolai Haehnle     Init *NewBit = CurBit;
491026f8333SMichael Liao 
4929a84a509SNicolai Haehnle     if (VarBitInit *CurBitVar = dyn_cast<VarBitInit>(CurBit)) {
4939a84a509SNicolai Haehnle       if (CurBitVar->getBitVar() != CachedBitVarRef) {
4949a84a509SNicolai Haehnle         CachedBitVarRef = CurBitVar->getBitVar();
4959a84a509SNicolai Haehnle         CachedBitVarResolved = CachedBitVarRef->resolveReferences(R);
496026f8333SMichael Liao       }
497e8877d04SSimon Pilgrim       assert(CachedBitVarResolved && "Unresolved bitvar reference");
4989a84a509SNicolai Haehnle       NewBit = CachedBitVarResolved->getBit(CurBitVar->getBitNum());
4999a84a509SNicolai Haehnle     } else {
5009a84a509SNicolai Haehnle       // getBit(0) implicitly converts int and bits<1> values to bit.
5019a84a509SNicolai Haehnle       NewBit = CurBit->resolveReferences(R)->getBit(0);
502026f8333SMichael Liao     }
5039a84a509SNicolai Haehnle 
5049a84a509SNicolai Haehnle     if (isa<UnsetInit>(NewBit) && R.keepUnsetBits())
5059a84a509SNicolai Haehnle       NewBit = CurBit;
5069a84a509SNicolai Haehnle     NewBits[i] = NewBit;
5079a84a509SNicolai Haehnle     Changed |= CurBit != NewBit;
50884c287e3SPeter Collingbourne   }
50984c287e3SPeter Collingbourne 
51084c287e3SPeter Collingbourne   if (Changed)
5112ac3cd20SRiver Riddle     return BitsInit::get(getRecordKeeper(), NewBits);
51284c287e3SPeter Collingbourne 
51384c287e3SPeter Collingbourne   return const_cast<BitsInit *>(this);
51484c287e3SPeter Collingbourne }
51584c287e3SPeter Collingbourne 
get(RecordKeeper & RK,int64_t V)5162ac3cd20SRiver Riddle IntInit *IntInit::get(RecordKeeper &RK, int64_t V) {
5172ac3cd20SRiver Riddle   IntInit *&I = RK.getImpl().TheIntInitPool[V];
5187480efd6SRiver Riddle   if (!I)
5192ac3cd20SRiver Riddle     I = new (RK.getImpl().Allocator) IntInit(RK, V);
520d0edb0dfSMatthias Braun   return I;
52184c287e3SPeter Collingbourne }
52284c287e3SPeter Collingbourne 
getAsString() const52384c287e3SPeter Collingbourne std::string IntInit::getAsString() const {
52484c287e3SPeter Collingbourne   return itostr(Value);
52584c287e3SPeter Collingbourne }
52684c287e3SPeter Collingbourne 
canFitInBitfield(int64_t Value,unsigned NumBits)52795819069SCraig Topper static bool canFitInBitfield(int64_t Value, unsigned NumBits) {
52895819069SCraig Topper   // For example, with NumBits == 4, we permit Values from [-7 .. 15].
52995819069SCraig Topper   return (NumBits >= sizeof(Value) * 8) ||
53095819069SCraig Topper          (Value >> NumBits == 0) || (Value >> (NumBits-1) == -1);
53195819069SCraig Topper }
53295819069SCraig Topper 
convertInitializerTo(RecTy * Ty) const53395819069SCraig Topper Init *IntInit::convertInitializerTo(RecTy *Ty) const {
53495819069SCraig Topper   if (isa<IntRecTy>(Ty))
53595819069SCraig Topper     return const_cast<IntInit *>(this);
53695819069SCraig Topper 
53795819069SCraig Topper   if (isa<BitRecTy>(Ty)) {
53895819069SCraig Topper     int64_t Val = getValue();
53995819069SCraig Topper     if (Val != 0 && Val != 1) return nullptr;  // Only accept 0 or 1 for a bit!
5402ac3cd20SRiver Riddle     return BitInit::get(getRecordKeeper(), Val != 0);
54195819069SCraig Topper   }
54295819069SCraig Topper 
54395819069SCraig Topper   if (auto *BRT = dyn_cast<BitsRecTy>(Ty)) {
54495819069SCraig Topper     int64_t Value = getValue();
54595819069SCraig Topper     // Make sure this bitfield is large enough to hold the integer value.
54695819069SCraig Topper     if (!canFitInBitfield(Value, BRT->getNumBits()))
54795819069SCraig Topper       return nullptr;
54895819069SCraig Topper 
54995819069SCraig Topper     SmallVector<Init *, 16> NewBits(BRT->getNumBits());
55095819069SCraig Topper     for (unsigned i = 0; i != BRT->getNumBits(); ++i)
5512ac3cd20SRiver Riddle       NewBits[i] =
5522ac3cd20SRiver Riddle           BitInit::get(getRecordKeeper(), Value & ((i < 64) ? (1LL << i) : 0));
55395819069SCraig Topper 
5542ac3cd20SRiver Riddle     return BitsInit::get(getRecordKeeper(), NewBits);
55595819069SCraig Topper   }
55695819069SCraig Topper 
55795819069SCraig Topper   return nullptr;
55895819069SCraig Topper }
55995819069SCraig Topper 
56084c287e3SPeter Collingbourne Init *
convertInitializerBitRange(ArrayRef<unsigned> Bits) const5611ddb78cdSMatthias Braun IntInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
56284c287e3SPeter Collingbourne   SmallVector<Init *, 16> NewBits(Bits.size());
56384c287e3SPeter Collingbourne 
56484c287e3SPeter Collingbourne   for (unsigned i = 0, e = Bits.size(); i != e; ++i) {
56584c287e3SPeter Collingbourne     if (Bits[i] >= 64)
566011817a0SCraig Topper       return nullptr;
56784c287e3SPeter Collingbourne 
5682ac3cd20SRiver Riddle     NewBits[i] =
5692ac3cd20SRiver Riddle         BitInit::get(getRecordKeeper(), Value & (INT64_C(1) << Bits[i]));
57084c287e3SPeter Collingbourne   }
5712ac3cd20SRiver Riddle   return BitsInit::get(getRecordKeeper(), NewBits);
57284c287e3SPeter Collingbourne }
57384c287e3SPeter Collingbourne 
get(RecordKeeper & RK,unsigned V)5742ac3cd20SRiver Riddle AnonymousNameInit *AnonymousNameInit::get(RecordKeeper &RK, unsigned V) {
5752ac3cd20SRiver Riddle   return new (RK.getImpl().Allocator) AnonymousNameInit(RK, V);
576267b573bSJ-Y You }
577267b573bSJ-Y You 
getNameInit() const578267b573bSJ-Y You StringInit *AnonymousNameInit::getNameInit() const {
5792ac3cd20SRiver Riddle   return StringInit::get(getRecordKeeper(), getAsString());
580267b573bSJ-Y You }
581267b573bSJ-Y You 
getAsString() const582267b573bSJ-Y You std::string AnonymousNameInit::getAsString() const {
583267b573bSJ-Y You   return "anonymous_" + utostr(Value);
584267b573bSJ-Y You }
585267b573bSJ-Y You 
resolveReferences(Resolver & R) const586267b573bSJ-Y You Init *AnonymousNameInit::resolveReferences(Resolver &R) const {
587267b573bSJ-Y You   auto *Old = const_cast<Init *>(static_cast<const Init *>(this));
588267b573bSJ-Y You   auto *New = R.resolve(Old);
589267b573bSJ-Y You   New = New ? New : Old;
590267b573bSJ-Y You   if (R.isFinal())
591267b573bSJ-Y You     if (auto *Anonymous = dyn_cast<AnonymousNameInit>(New))
592267b573bSJ-Y You       return Anonymous->getNameInit();
593267b573bSJ-Y You   return New;
594267b573bSJ-Y You }
595267b573bSJ-Y You 
get(RecordKeeper & RK,StringRef V,StringFormat Fmt)5962ac3cd20SRiver Riddle StringInit *StringInit::get(RecordKeeper &RK, StringRef V, StringFormat Fmt) {
5972ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
5982ac3cd20SRiver Riddle   auto &InitMap = Fmt == SF_String ? RKImpl.StringInitStringPool
5992ac3cd20SRiver Riddle                                    : RKImpl.StringInitCodePool;
6007480efd6SRiver Riddle   auto &Entry = *InitMap.insert(std::make_pair(V, nullptr)).first;
601b23e84ffSPaul C. Anagnostopoulos   if (!Entry.second)
6022ac3cd20SRiver Riddle     Entry.second = new (RKImpl.Allocator) StringInit(RK, Entry.getKey(), Fmt);
603415fab6fSPaul C. Anagnostopoulos   return Entry.second;
60484c287e3SPeter Collingbourne }
60584c287e3SPeter Collingbourne 
convertInitializerTo(RecTy * Ty) const60695819069SCraig Topper Init *StringInit::convertInitializerTo(RecTy *Ty) const {
60795819069SCraig Topper   if (isa<StringRecTy>(Ty))
60895819069SCraig Topper     return const_cast<StringInit *>(this);
60988403d7aSTim Northover 
61088403d7aSTim Northover   return nullptr;
61188403d7aSTim Northover }
61288403d7aSTim Northover 
ProfileListInit(FoldingSetNodeID & ID,ArrayRef<Init * > Range,RecTy * EltTy)61384c287e3SPeter Collingbourne static void ProfileListInit(FoldingSetNodeID &ID,
61484c287e3SPeter Collingbourne                             ArrayRef<Init *> Range,
61584c287e3SPeter Collingbourne                             RecTy *EltTy) {
61684c287e3SPeter Collingbourne   ID.AddInteger(Range.size());
61784c287e3SPeter Collingbourne   ID.AddPointer(EltTy);
61884c287e3SPeter Collingbourne 
619119998dbSCraig Topper   for (Init *I : Range)
620119998dbSCraig Topper     ID.AddPointer(I);
62184c287e3SPeter Collingbourne }
62284c287e3SPeter Collingbourne 
get(ArrayRef<Init * > Range,RecTy * EltTy)62384c287e3SPeter Collingbourne ListInit *ListInit::get(ArrayRef<Init *> Range, RecTy *EltTy) {
62484c287e3SPeter Collingbourne   FoldingSetNodeID ID;
62584c287e3SPeter Collingbourne   ProfileListInit(ID, Range, EltTy);
62684c287e3SPeter Collingbourne 
6272ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = EltTy->getRecordKeeper().getImpl();
628011817a0SCraig Topper   void *IP = nullptr;
6292ac3cd20SRiver Riddle   if (ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP))
63084c287e3SPeter Collingbourne     return I;
63184c287e3SPeter Collingbourne 
632d9f0b07fSNicolai Haehnle   assert(Range.empty() || !isa<TypedInit>(Range[0]) ||
633d9f0b07fSNicolai Haehnle          cast<TypedInit>(Range[0])->getType()->typeIsConvertibleTo(EltTy));
634d9f0b07fSNicolai Haehnle 
6352ac3cd20SRiver Riddle   void *Mem = RK.Allocator.Allocate(totalSizeToAlloc<Init *>(Range.size()),
6362ac3cd20SRiver Riddle                                     alignof(ListInit));
637fbfd5780SCraig Topper   ListInit *I = new (Mem) ListInit(Range.size(), EltTy);
638fbfd5780SCraig Topper   std::uninitialized_copy(Range.begin(), Range.end(),
639fbfd5780SCraig Topper                           I->getTrailingObjects<Init *>());
6402ac3cd20SRiver Riddle   RK.TheListInitPool.InsertNode(I, IP);
64184c287e3SPeter Collingbourne   return I;
64284c287e3SPeter Collingbourne }
64384c287e3SPeter Collingbourne 
Profile(FoldingSetNodeID & ID) const64484c287e3SPeter Collingbourne void ListInit::Profile(FoldingSetNodeID &ID) const {
645ed5a9508SCraig Topper   RecTy *EltTy = cast<ListRecTy>(getType())->getElementType();
64684c287e3SPeter Collingbourne 
647fbfd5780SCraig Topper   ProfileListInit(ID, getValues(), EltTy);
64884c287e3SPeter Collingbourne }
64984c287e3SPeter Collingbourne 
convertInitializerTo(RecTy * Ty) const65095819069SCraig Topper Init *ListInit::convertInitializerTo(RecTy *Ty) const {
651dbe6e7deSMatthias Braun   if (getType() == Ty)
652dbe6e7deSMatthias Braun     return const_cast<ListInit*>(this);
653dbe6e7deSMatthias Braun 
65495819069SCraig Topper   if (auto *LRT = dyn_cast<ListRecTy>(Ty)) {
6551ddb78cdSMatthias Braun     SmallVector<Init*, 8> Elements;
656dbe6e7deSMatthias Braun     Elements.reserve(getValues().size());
65795819069SCraig Topper 
65895819069SCraig Topper     // Verify that all of the elements of the list are subclasses of the
65995819069SCraig Topper     // appropriate class!
660dbe6e7deSMatthias Braun     bool Changed = false;
661dbe6e7deSMatthias Braun     RecTy *ElementType = LRT->getElementType();
662ef0578a8SCraig Topper     for (Init *I : getValues())
663dbe6e7deSMatthias Braun       if (Init *CI = I->convertInitializerTo(ElementType)) {
66495819069SCraig Topper         Elements.push_back(CI);
665dbe6e7deSMatthias Braun         if (CI != I)
666dbe6e7deSMatthias Braun           Changed = true;
667dbe6e7deSMatthias Braun       } else
66895819069SCraig Topper         return nullptr;
66995819069SCraig Topper 
670dbe6e7deSMatthias Braun     if (!Changed)
671dbe6e7deSMatthias Braun       return const_cast<ListInit*>(this);
67281097ba6SNicolai Haehnle     return ListInit::get(Elements, ElementType);
67395819069SCraig Topper   }
67495819069SCraig Topper 
67595819069SCraig Topper   return nullptr;
67695819069SCraig Topper }
67795819069SCraig Topper 
convertInitListSlice(ArrayRef<unsigned> Elements) const6781ddb78cdSMatthias Braun Init *ListInit::convertInitListSlice(ArrayRef<unsigned> Elements) const {
679489cdeddSPaul C. Anagnostopoulos   if (Elements.size() == 1) {
680489cdeddSPaul C. Anagnostopoulos     if (Elements[0] >= size())
681489cdeddSPaul C. Anagnostopoulos       return nullptr;
682489cdeddSPaul C. Anagnostopoulos     return getElement(Elements[0]);
683489cdeddSPaul C. Anagnostopoulos   }
68414580ce2SPaul C. Anagnostopoulos 
6851ddb78cdSMatthias Braun   SmallVector<Init*, 8> Vals;
686ca151317SMatthias Braun   Vals.reserve(Elements.size());
687ca151317SMatthias Braun   for (unsigned Element : Elements) {
688ca151317SMatthias Braun     if (Element >= size())
689011817a0SCraig Topper       return nullptr;
690ca151317SMatthias Braun     Vals.push_back(getElement(Element));
69184c287e3SPeter Collingbourne   }
69281097ba6SNicolai Haehnle   return ListInit::get(Vals, getElementType());
69384c287e3SPeter Collingbourne }
69484c287e3SPeter Collingbourne 
getElementAsRecord(unsigned i) const69584c287e3SPeter Collingbourne Record *ListInit::getElementAsRecord(unsigned i) const {
6967dcb1a5cSCraig Topper   assert(i < NumValues && "List element index out of range!");
697fbfd5780SCraig Topper   DefInit *DI = dyn_cast<DefInit>(getElement(i));
698011817a0SCraig Topper   if (!DI)
699635debe8SJoerg Sonnenberger     PrintFatalError("Expected record in list!");
70084c287e3SPeter Collingbourne   return DI->getDef();
70184c287e3SPeter Collingbourne }
70284c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const7030b0eaf7eSNicolai Haehnle Init *ListInit::resolveReferences(Resolver &R) const {
7041ddb78cdSMatthias Braun   SmallVector<Init*, 8> Resolved;
705664f6a04SCraig Topper   Resolved.reserve(size());
70684c287e3SPeter Collingbourne   bool Changed = false;
70784c287e3SPeter Collingbourne 
708ef0578a8SCraig Topper   for (Init *CurElt : getValues()) {
70987aec1b1SNicolai Haehnle     Init *E = CurElt->resolveReferences(R);
71084c287e3SPeter Collingbourne     Changed |= E != CurElt;
71184c287e3SPeter Collingbourne     Resolved.push_back(E);
71284c287e3SPeter Collingbourne   }
71384c287e3SPeter Collingbourne 
71484c287e3SPeter Collingbourne   if (Changed)
71581097ba6SNicolai Haehnle     return ListInit::get(Resolved, getElementType());
71684c287e3SPeter Collingbourne   return const_cast<ListInit *>(this);
71784c287e3SPeter Collingbourne }
71884c287e3SPeter Collingbourne 
isComplete() const719be50657cSDaniel Sanders bool ListInit::isComplete() const {
720be50657cSDaniel Sanders   for (Init *Element : *this) {
721be50657cSDaniel Sanders     if (!Element->isComplete())
722be50657cSDaniel Sanders       return false;
723be50657cSDaniel Sanders   }
724be50657cSDaniel Sanders   return true;
725be50657cSDaniel Sanders }
726be50657cSDaniel Sanders 
isConcrete() const7270f529885SNicolai Haehnle bool ListInit::isConcrete() const {
7280f529885SNicolai Haehnle   for (Init *Element : *this) {
7290f529885SNicolai Haehnle     if (!Element->isConcrete())
7300f529885SNicolai Haehnle       return false;
7310f529885SNicolai Haehnle   }
7320f529885SNicolai Haehnle   return true;
7330f529885SNicolai Haehnle }
7340f529885SNicolai Haehnle 
getAsString() const73584c287e3SPeter Collingbourne std::string ListInit::getAsString() const {
73684c287e3SPeter Collingbourne   std::string Result = "[";
737ca151317SMatthias Braun   const char *sep = "";
738ca151317SMatthias Braun   for (Init *Element : *this) {
739ca151317SMatthias Braun     Result += sep;
740ca151317SMatthias Braun     sep = ", ";
741ca151317SMatthias Braun     Result += Element->getAsString();
74284c287e3SPeter Collingbourne   }
74384c287e3SPeter Collingbourne   return Result + "]";
74484c287e3SPeter Collingbourne }
74584c287e3SPeter Collingbourne 
getBit(unsigned Bit) const746026f8333SMichael Liao Init *OpInit::getBit(unsigned Bit) const {
7472ac3cd20SRiver Riddle   if (getType() == BitRecTy::get(getRecordKeeper()))
748026f8333SMichael Liao     return const_cast<OpInit*>(this);
749026f8333SMichael Liao   return VarBitInit::get(const_cast<OpInit*>(this), Bit);
750026f8333SMichael Liao }
751026f8333SMichael Liao 
7525e46adb0SCraig Topper static void
ProfileUnOpInit(FoldingSetNodeID & ID,unsigned Opcode,Init * Op,RecTy * Type)7535e46adb0SCraig Topper ProfileUnOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *Op, RecTy *Type) {
7545e46adb0SCraig Topper   ID.AddInteger(Opcode);
7555e46adb0SCraig Topper   ID.AddPointer(Op);
7565e46adb0SCraig Topper   ID.AddPointer(Type);
7575e46adb0SCraig Topper }
75884c287e3SPeter Collingbourne 
get(UnaryOp Opc,Init * LHS,RecTy * Type)7595e46adb0SCraig Topper UnOpInit *UnOpInit::get(UnaryOp Opc, Init *LHS, RecTy *Type) {
7605e46adb0SCraig Topper   FoldingSetNodeID ID;
7615e46adb0SCraig Topper   ProfileUnOpInit(ID, Opc, LHS, Type);
7625e46adb0SCraig Topper 
7632ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = Type->getRecordKeeper().getImpl();
7645e46adb0SCraig Topper   void *IP = nullptr;
7652ac3cd20SRiver Riddle   if (UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
7665e46adb0SCraig Topper     return I;
7675e46adb0SCraig Topper 
7682ac3cd20SRiver Riddle   UnOpInit *I = new (RK.Allocator) UnOpInit(Opc, LHS, Type);
7692ac3cd20SRiver Riddle   RK.TheUnOpInitPool.InsertNode(I, IP);
7705e46adb0SCraig Topper   return I;
7715e46adb0SCraig Topper }
7725e46adb0SCraig Topper 
Profile(FoldingSetNodeID & ID) const7735e46adb0SCraig Topper void UnOpInit::Profile(FoldingSetNodeID &ID) const {
7745e46adb0SCraig Topper   ProfileUnOpInit(ID, getOpcode(), getOperand(), getType());
77584c287e3SPeter Collingbourne }
77684c287e3SPeter Collingbourne 
Fold(Record * CurRec,bool IsFinal) const7774186cc7cSNicolai Haehnle Init *UnOpInit::Fold(Record *CurRec, bool IsFinal) const {
7782ac3cd20SRiver Riddle   RecordKeeper &RK = getRecordKeeper();
77984c287e3SPeter Collingbourne   switch (getOpcode()) {
780af615896SEugene Zelenko   case CAST:
7812a8d4b29SCraig Topper     if (isa<StringRecTy>(getType())) {
78288eb8dd4SSean Silva       if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
78384c287e3SPeter Collingbourne         return LHSs;
78484c287e3SPeter Collingbourne 
78588eb8dd4SSean Silva       if (DefInit *LHSd = dyn_cast<DefInit>(LHS))
7862ac3cd20SRiver Riddle         return StringInit::get(RK, LHSd->getAsString());
7876291f3a4SDavid Greene 
7882ac3cd20SRiver Riddle       if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
7892ac3cd20SRiver Riddle               LHS->convertInitializerTo(IntRecTy::get(RK))))
7902ac3cd20SRiver Riddle         return StringInit::get(RK, LHSi->getAsString());
791a022be62SPaul C. Anagnostopoulos 
792dfda9dccSNicolai Haehnle     } else if (isa<RecordRecTy>(getType())) {
7936a441839SMatthias Braun       if (StringInit *Name = dyn_cast<StringInit>(LHS)) {
79452391ea0SValery Pykhtin         if (!CurRec && !IsFinal)
79552391ea0SValery Pykhtin           break;
7965be22a12SMichael Ilseman         assert(CurRec && "NULL pointer");
7974186cc7cSNicolai Haehnle         Record *D;
79884c287e3SPeter Collingbourne 
7994186cc7cSNicolai Haehnle         // Self-references are allowed, but their resolution is delayed until
8004186cc7cSNicolai Haehnle         // the final resolve to ensure that we get the correct type for them.
801267b573bSJ-Y You         auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit());
802267b573bSJ-Y You         if (Name == CurRec->getNameInit() ||
803267b573bSJ-Y You             (Anonymous && Name == Anonymous->getNameInit())) {
8044186cc7cSNicolai Haehnle           if (!IsFinal)
8054186cc7cSNicolai Haehnle             break;
8064186cc7cSNicolai Haehnle           D = CurRec;
8074186cc7cSNicolai Haehnle         } else {
8084186cc7cSNicolai Haehnle           D = CurRec->getRecords().getDef(Name->getValue());
8094186cc7cSNicolai Haehnle           if (!D) {
8104186cc7cSNicolai Haehnle             if (IsFinal)
811635debe8SJoerg Sonnenberger               PrintFatalError(CurRec->getLoc(),
812c47fe129SNicolai Haehnle                               Twine("Undefined reference to record: '") +
813c47fe129SNicolai Haehnle                               Name->getValue() + "'\n");
8144186cc7cSNicolai Haehnle             break;
8154186cc7cSNicolai Haehnle           }
8164186cc7cSNicolai Haehnle         }
8174186cc7cSNicolai Haehnle 
8184186cc7cSNicolai Haehnle         DefInit *DI = DefInit::get(D);
8194186cc7cSNicolai Haehnle         if (!DI->getType()->typeIsA(getType())) {
8204186cc7cSNicolai Haehnle           PrintFatalError(CurRec->getLoc(),
8214186cc7cSNicolai Haehnle                           Twine("Expected type '") +
8224186cc7cSNicolai Haehnle                           getType()->getAsString() + "', got '" +
8234186cc7cSNicolai Haehnle                           DI->getType()->getAsString() + "' in: " +
8244186cc7cSNicolai Haehnle                           getAsString() + "\n");
8254186cc7cSNicolai Haehnle         }
8264186cc7cSNicolai Haehnle         return DI;
82784c287e3SPeter Collingbourne       }
828dfda9dccSNicolai Haehnle     }
829a7bc7db5SMatt Arsenault 
830dfda9dccSNicolai Haehnle     if (Init *NewInit = LHS->convertInitializerTo(getType()))
831a7bc7db5SMatt Arsenault       return NewInit;
832a7bc7db5SMatt Arsenault     break;
833af615896SEugene Zelenko 
8344767bb2cSPaul C. Anagnostopoulos   case NOT:
8352ac3cd20SRiver Riddle     if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
8362ac3cd20SRiver Riddle             LHS->convertInitializerTo(IntRecTy::get(RK))))
8372ac3cd20SRiver Riddle       return IntInit::get(RK, LHSi->getValue() ? 0 : 1);
8384767bb2cSPaul C. Anagnostopoulos     break;
8394767bb2cSPaul C. Anagnostopoulos 
840af615896SEugene Zelenko   case HEAD:
84188eb8dd4SSean Silva     if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
84241ce4de0SCraig Topper       assert(!LHSl->empty() && "Empty list in head");
84384c287e3SPeter Collingbourne       return LHSl->getElement(0);
84484c287e3SPeter Collingbourne     }
84584c287e3SPeter Collingbourne     break;
846af615896SEugene Zelenko 
847af615896SEugene Zelenko   case TAIL:
84888eb8dd4SSean Silva     if (ListInit *LHSl = dyn_cast<ListInit>(LHS)) {
84941ce4de0SCraig Topper       assert(!LHSl->empty() && "Empty list in tail");
85084c287e3SPeter Collingbourne       // Note the +1.  We can't just pass the result of getValues()
85184c287e3SPeter Collingbourne       // directly.
85281097ba6SNicolai Haehnle       return ListInit::get(LHSl->getValues().slice(1), LHSl->getElementType());
85384c287e3SPeter Collingbourne     }
85484c287e3SPeter Collingbourne     break;
855af615896SEugene Zelenko 
8560243aaf4SNicolai Haehnle   case SIZE:
8570243aaf4SNicolai Haehnle     if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
8582ac3cd20SRiver Riddle       return IntInit::get(RK, LHSl->size());
859dc5d6632SPaul C. Anagnostopoulos     if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
8602ac3cd20SRiver Riddle       return IntInit::get(RK, LHSd->arg_size());
861dc5d6632SPaul C. Anagnostopoulos     if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
8622ac3cd20SRiver Riddle       return IntInit::get(RK, LHSs->getValue().size());
8630243aaf4SNicolai Haehnle     break;
8640243aaf4SNicolai Haehnle 
865af615896SEugene Zelenko   case EMPTY:
8668ddb0d82SCraig Topper     if (ListInit *LHSl = dyn_cast<ListInit>(LHS))
8672ac3cd20SRiver Riddle       return IntInit::get(RK, LHSl->empty());
868dc5d6632SPaul C. Anagnostopoulos     if (DagInit *LHSd = dyn_cast<DagInit>(LHS))
8692ac3cd20SRiver Riddle       return IntInit::get(RK, LHSd->arg_empty());
8708ddb0d82SCraig Topper     if (StringInit *LHSs = dyn_cast<StringInit>(LHS))
8712ac3cd20SRiver Riddle       return IntInit::get(RK, LHSs->getValue().empty());
87284c287e3SPeter Collingbourne     break;
8731fed9a0cSSimon Tatham 
874876af264SPaul C. Anagnostopoulos   case GETDAGOP:
8751fed9a0cSSimon Tatham     if (DagInit *Dag = dyn_cast<DagInit>(LHS)) {
8761fed9a0cSSimon Tatham       DefInit *DI = DefInit::get(Dag->getOperatorAsDef({}));
8771fed9a0cSSimon Tatham       if (!DI->getType()->typeIsA(getType())) {
8781fed9a0cSSimon Tatham         PrintFatalError(CurRec->getLoc(),
8791fed9a0cSSimon Tatham                         Twine("Expected type '") +
8801fed9a0cSSimon Tatham                         getType()->getAsString() + "', got '" +
8811fed9a0cSSimon Tatham                         DI->getType()->getAsString() + "' in: " +
8821fed9a0cSSimon Tatham                         getAsString() + "\n");
8831fed9a0cSSimon Tatham       } else {
8841fed9a0cSSimon Tatham         return DI;
8851fed9a0cSSimon Tatham       }
8861fed9a0cSSimon Tatham     }
8871fed9a0cSSimon Tatham     break;
88884c287e3SPeter Collingbourne   }
88984c287e3SPeter Collingbourne   return const_cast<UnOpInit *>(this);
89084c287e3SPeter Collingbourne }
89184c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const8920b0eaf7eSNicolai Haehnle Init *UnOpInit::resolveReferences(Resolver &R) const {
8930b0eaf7eSNicolai Haehnle   Init *lhs = LHS->resolveReferences(R);
89484c287e3SPeter Collingbourne 
8954186cc7cSNicolai Haehnle   if (LHS != lhs || (R.isFinal() && getOpcode() == CAST))
8960b0eaf7eSNicolai Haehnle     return (UnOpInit::get(getOpcode(), lhs, getType()))
8974186cc7cSNicolai Haehnle         ->Fold(R.getCurrentRecord(), R.isFinal());
898335c70f5SNicolai Haehnle   return const_cast<UnOpInit *>(this);
89984c287e3SPeter Collingbourne }
90084c287e3SPeter Collingbourne 
getAsString() const90184c287e3SPeter Collingbourne std::string UnOpInit::getAsString() const {
90284c287e3SPeter Collingbourne   std::string Result;
9035a6dda53SCraig Topper   switch (getOpcode()) {
90484c287e3SPeter Collingbourne   case CAST: Result = "!cast<" + getType()->getAsString() + ">"; break;
9054767bb2cSPaul C. Anagnostopoulos   case NOT: Result = "!not"; break;
90684c287e3SPeter Collingbourne   case HEAD: Result = "!head"; break;
90784c287e3SPeter Collingbourne   case TAIL: Result = "!tail"; break;
9080243aaf4SNicolai Haehnle   case SIZE: Result = "!size"; break;
90984c287e3SPeter Collingbourne   case EMPTY: Result = "!empty"; break;
910876af264SPaul C. Anagnostopoulos   case GETDAGOP: Result = "!getdagop"; break;
91184c287e3SPeter Collingbourne   }
91284c287e3SPeter Collingbourne   return Result + "(" + LHS->getAsString() + ")";
91384c287e3SPeter Collingbourne }
91484c287e3SPeter Collingbourne 
9155e46adb0SCraig Topper static void
ProfileBinOpInit(FoldingSetNodeID & ID,unsigned Opcode,Init * LHS,Init * RHS,RecTy * Type)9165e46adb0SCraig Topper ProfileBinOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *RHS,
9175e46adb0SCraig Topper                  RecTy *Type) {
9185e46adb0SCraig Topper   ID.AddInteger(Opcode);
9195e46adb0SCraig Topper   ID.AddPointer(LHS);
9205e46adb0SCraig Topper   ID.AddPointer(RHS);
9215e46adb0SCraig Topper   ID.AddPointer(Type);
9225e46adb0SCraig Topper }
92384c287e3SPeter Collingbourne 
get(BinaryOp Opc,Init * LHS,Init * RHS,RecTy * Type)9247480efd6SRiver Riddle BinOpInit *BinOpInit::get(BinaryOp Opc, Init *LHS, Init *RHS, RecTy *Type) {
9255e46adb0SCraig Topper   FoldingSetNodeID ID;
9265e46adb0SCraig Topper   ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
92784c287e3SPeter Collingbourne 
9282ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
9295e46adb0SCraig Topper   void *IP = nullptr;
9302ac3cd20SRiver Riddle   if (BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
9315e46adb0SCraig Topper     return I;
9325e46adb0SCraig Topper 
9332ac3cd20SRiver Riddle   BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type);
9342ac3cd20SRiver Riddle   RK.TheBinOpInitPool.InsertNode(I, IP);
9355e46adb0SCraig Topper   return I;
9365e46adb0SCraig Topper }
9375e46adb0SCraig Topper 
Profile(FoldingSetNodeID & ID) const9385e46adb0SCraig Topper void BinOpInit::Profile(FoldingSetNodeID &ID) const {
9395e46adb0SCraig Topper   ProfileBinOpInit(ID, getOpcode(), getLHS(), getRHS(), getType());
94084c287e3SPeter Collingbourne }
94184c287e3SPeter Collingbourne 
ConcatStringInits(const StringInit * I0,const StringInit * I1)9426e074de4SMatthias Braun static StringInit *ConcatStringInits(const StringInit *I0,
9436e074de4SMatthias Braun                                      const StringInit *I1) {
9446e074de4SMatthias Braun   SmallString<80> Concat(I0->getValue());
9456e074de4SMatthias Braun   Concat.append(I1->getValue());
9462ac3cd20SRiver Riddle   return StringInit::get(
9472ac3cd20SRiver Riddle       I0->getRecordKeeper(), Concat,
9482ac3cd20SRiver Riddle       StringInit::determineFormat(I0->getFormat(), I1->getFormat()));
9496e074de4SMatthias Braun }
9506e074de4SMatthias Braun 
interleaveStringList(const ListInit * List,const StringInit * Delim)951d56cd429SPaul C. Anagnostopoulos static StringInit *interleaveStringList(const ListInit *List,
952d56cd429SPaul C. Anagnostopoulos                                         const StringInit *Delim) {
953d56cd429SPaul C. Anagnostopoulos   if (List->size() == 0)
9542ac3cd20SRiver Riddle     return StringInit::get(List->getRecordKeeper(), "");
9554820af99SPaul C. Anagnostopoulos   StringInit *Element = dyn_cast<StringInit>(List->getElement(0));
9564820af99SPaul C. Anagnostopoulos   if (!Element)
9574820af99SPaul C. Anagnostopoulos     return nullptr;
9584820af99SPaul C. Anagnostopoulos   SmallString<80> Result(Element->getValue());
959415fab6fSPaul C. Anagnostopoulos   StringInit::StringFormat Fmt = StringInit::SF_String;
960d56cd429SPaul C. Anagnostopoulos 
961d56cd429SPaul C. Anagnostopoulos   for (unsigned I = 1, E = List->size(); I < E; ++I) {
962d56cd429SPaul C. Anagnostopoulos     Result.append(Delim->getValue());
9634820af99SPaul C. Anagnostopoulos     StringInit *Element = dyn_cast<StringInit>(List->getElement(I));
9644820af99SPaul C. Anagnostopoulos     if (!Element)
9654820af99SPaul C. Anagnostopoulos       return nullptr;
9664820af99SPaul C. Anagnostopoulos     Result.append(Element->getValue());
9674820af99SPaul C. Anagnostopoulos     Fmt = StringInit::determineFormat(Fmt, Element->getFormat());
968d56cd429SPaul C. Anagnostopoulos   }
9692ac3cd20SRiver Riddle   return StringInit::get(List->getRecordKeeper(), Result, Fmt);
970d56cd429SPaul C. Anagnostopoulos }
971d56cd429SPaul C. Anagnostopoulos 
interleaveIntList(const ListInit * List,const StringInit * Delim)972d56cd429SPaul C. Anagnostopoulos static StringInit *interleaveIntList(const ListInit *List,
973d56cd429SPaul C. Anagnostopoulos                                      const StringInit *Delim) {
9742ac3cd20SRiver Riddle   RecordKeeper &RK = List->getRecordKeeper();
975d56cd429SPaul C. Anagnostopoulos   if (List->size() == 0)
9762ac3cd20SRiver Riddle     return StringInit::get(RK, "");
9772ac3cd20SRiver Riddle   IntInit *Element = dyn_cast_or_null<IntInit>(
9782ac3cd20SRiver Riddle       List->getElement(0)->convertInitializerTo(IntRecTy::get(RK)));
9794820af99SPaul C. Anagnostopoulos   if (!Element)
9804820af99SPaul C. Anagnostopoulos     return nullptr;
9814820af99SPaul C. Anagnostopoulos   SmallString<80> Result(Element->getAsString());
982d56cd429SPaul C. Anagnostopoulos 
983d56cd429SPaul C. Anagnostopoulos   for (unsigned I = 1, E = List->size(); I < E; ++I) {
984d56cd429SPaul C. Anagnostopoulos     Result.append(Delim->getValue());
9852ac3cd20SRiver Riddle     IntInit *Element = dyn_cast_or_null<IntInit>(
9862ac3cd20SRiver Riddle         List->getElement(I)->convertInitializerTo(IntRecTy::get(RK)));
9874820af99SPaul C. Anagnostopoulos     if (!Element)
9884820af99SPaul C. Anagnostopoulos       return nullptr;
9894820af99SPaul C. Anagnostopoulos     Result.append(Element->getAsString());
990d56cd429SPaul C. Anagnostopoulos   }
9912ac3cd20SRiver Riddle   return StringInit::get(RK, Result);
992d56cd429SPaul C. Anagnostopoulos }
993d56cd429SPaul C. Anagnostopoulos 
getStrConcat(Init * I0,Init * I1)9941eaebc62SNicolai Haehnle Init *BinOpInit::getStrConcat(Init *I0, Init *I1) {
9951eaebc62SNicolai Haehnle   // Shortcut for the common case of concatenating two strings.
9961eaebc62SNicolai Haehnle   if (const StringInit *I0s = dyn_cast<StringInit>(I0))
9971eaebc62SNicolai Haehnle     if (const StringInit *I1s = dyn_cast<StringInit>(I1))
9981eaebc62SNicolai Haehnle       return ConcatStringInits(I0s, I1s);
9992ac3cd20SRiver Riddle   return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1,
10002ac3cd20SRiver Riddle                         StringRecTy::get(I0->getRecordKeeper()));
10011eaebc62SNicolai Haehnle }
10021eaebc62SNicolai Haehnle 
ConcatListInits(const ListInit * LHS,const ListInit * RHS)100334d3b80dSJaved Absar static ListInit *ConcatListInits(const ListInit *LHS,
100434d3b80dSJaved Absar                                  const ListInit *RHS) {
100534d3b80dSJaved Absar   SmallVector<Init *, 8> Args;
10061d0bc055SKazu Hirata   llvm::append_range(Args, *LHS);
10071d0bc055SKazu Hirata   llvm::append_range(Args, *RHS);
100834d3b80dSJaved Absar   return ListInit::get(Args, LHS->getElementType());
100934d3b80dSJaved Absar }
101034d3b80dSJaved Absar 
getListConcat(TypedInit * LHS,Init * RHS)101134d3b80dSJaved Absar Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) {
101234d3b80dSJaved Absar   assert(isa<ListRecTy>(LHS->getType()) && "First arg must be a list");
101334d3b80dSJaved Absar 
101434d3b80dSJaved Absar   // Shortcut for the common case of concatenating two lists.
101534d3b80dSJaved Absar    if (const ListInit *LHSList = dyn_cast<ListInit>(LHS))
101634d3b80dSJaved Absar      if (const ListInit *RHSList = dyn_cast<ListInit>(RHS))
101734d3b80dSJaved Absar        return ConcatListInits(LHSList, RHSList);
101834d3b80dSJaved Absar    return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType());
101934d3b80dSJaved Absar }
102034d3b80dSJaved Absar 
Fold(Record * CurRec) const1021c47fe129SNicolai Haehnle Init *BinOpInit::Fold(Record *CurRec) const {
102284c287e3SPeter Collingbourne   switch (getOpcode()) {
102384c287e3SPeter Collingbourne   case CONCAT: {
1024fb509ed1SSean Silva     DagInit *LHSs = dyn_cast<DagInit>(LHS);
1025fb509ed1SSean Silva     DagInit *RHSs = dyn_cast<DagInit>(RHS);
102684c287e3SPeter Collingbourne     if (LHSs && RHSs) {
1027fb509ed1SSean Silva       DefInit *LOp = dyn_cast<DefInit>(LHSs->getOperator());
1028fb509ed1SSean Silva       DefInit *ROp = dyn_cast<DefInit>(RHSs->getOperator());
10290e894edeSSimon Tatham       if ((!LOp && !isa<UnsetInit>(LHSs->getOperator())) ||
10300e894edeSSimon Tatham           (!ROp && !isa<UnsetInit>(RHSs->getOperator())))
1031b61c26e6SNicolai Haehnle         break;
10320e894edeSSimon Tatham       if (LOp && ROp && LOp->getDef() != ROp->getDef()) {
1033b61c26e6SNicolai Haehnle         PrintFatalError(Twine("Concatenated Dag operators do not match: '") +
1034b61c26e6SNicolai Haehnle                         LHSs->getAsString() + "' vs. '" + RHSs->getAsString() +
1035b61c26e6SNicolai Haehnle                         "'");
1036b61c26e6SNicolai Haehnle       }
10370e894edeSSimon Tatham       Init *Op = LOp ? LOp : ROp;
10380e894edeSSimon Tatham       if (!Op)
10392ac3cd20SRiver Riddle         Op = UnsetInit::get(getRecordKeeper());
10400e894edeSSimon Tatham 
10411ddb78cdSMatthias Braun       SmallVector<Init*, 8> Args;
10421ddb78cdSMatthias Braun       SmallVector<StringInit*, 8> ArgNames;
104384c287e3SPeter Collingbourne       for (unsigned i = 0, e = LHSs->getNumArgs(); i != e; ++i) {
104484c287e3SPeter Collingbourne         Args.push_back(LHSs->getArg(i));
104584c287e3SPeter Collingbourne         ArgNames.push_back(LHSs->getArgName(i));
104684c287e3SPeter Collingbourne       }
104784c287e3SPeter Collingbourne       for (unsigned i = 0, e = RHSs->getNumArgs(); i != e; ++i) {
104884c287e3SPeter Collingbourne         Args.push_back(RHSs->getArg(i));
104984c287e3SPeter Collingbourne         ArgNames.push_back(RHSs->getArgName(i));
105084c287e3SPeter Collingbourne       }
10510e894edeSSimon Tatham       return DagInit::get(Op, nullptr, Args, ArgNames);
105284c287e3SPeter Collingbourne     }
105384c287e3SPeter Collingbourne     break;
105484c287e3SPeter Collingbourne   }
1055314e80e5SDaniel Sanders   case LISTCONCAT: {
1056314e80e5SDaniel Sanders     ListInit *LHSs = dyn_cast<ListInit>(LHS);
1057314e80e5SDaniel Sanders     ListInit *RHSs = dyn_cast<ListInit>(RHS);
1058314e80e5SDaniel Sanders     if (LHSs && RHSs) {
10591ddb78cdSMatthias Braun       SmallVector<Init *, 8> Args;
10601d0bc055SKazu Hirata       llvm::append_range(Args, *LHSs);
10611d0bc055SKazu Hirata       llvm::append_range(Args, *RHSs);
106281097ba6SNicolai Haehnle       return ListInit::get(Args, LHSs->getElementType());
1063314e80e5SDaniel Sanders     }
1064314e80e5SDaniel Sanders     break;
1065314e80e5SDaniel Sanders   }
10665d9f656bSRoman Lebedev   case LISTSPLAT: {
10675d9f656bSRoman Lebedev     TypedInit *Value = dyn_cast<TypedInit>(LHS);
10685d9f656bSRoman Lebedev     IntInit *Size = dyn_cast<IntInit>(RHS);
10695d9f656bSRoman Lebedev     if (Value && Size) {
10705d9f656bSRoman Lebedev       SmallVector<Init *, 8> Args(Size->getValue(), Value);
10715d9f656bSRoman Lebedev       return ListInit::get(Args, Value->getType());
10725d9f656bSRoman Lebedev     }
10735d9f656bSRoman Lebedev     break;
10745d9f656bSRoman Lebedev   }
107584c287e3SPeter Collingbourne   case STRCONCAT: {
1076fb509ed1SSean Silva     StringInit *LHSs = dyn_cast<StringInit>(LHS);
1077fb509ed1SSean Silva     StringInit *RHSs = dyn_cast<StringInit>(RHS);
10786e074de4SMatthias Braun     if (LHSs && RHSs)
10796e074de4SMatthias Braun       return ConcatStringInits(LHSs, RHSs);
108084c287e3SPeter Collingbourne     break;
108184c287e3SPeter Collingbourne   }
1082d56cd429SPaul C. Anagnostopoulos   case INTERLEAVE: {
1083d56cd429SPaul C. Anagnostopoulos     ListInit *List = dyn_cast<ListInit>(LHS);
1084d56cd429SPaul C. Anagnostopoulos     StringInit *Delim = dyn_cast<StringInit>(RHS);
1085d56cd429SPaul C. Anagnostopoulos     if (List && Delim) {
10864820af99SPaul C. Anagnostopoulos       StringInit *Result;
1087d56cd429SPaul C. Anagnostopoulos       if (isa<StringRecTy>(List->getElementType()))
10884820af99SPaul C. Anagnostopoulos         Result = interleaveStringList(List, Delim);
1089d56cd429SPaul C. Anagnostopoulos       else
10904820af99SPaul C. Anagnostopoulos         Result = interleaveIntList(List, Delim);
10914820af99SPaul C. Anagnostopoulos       if (Result)
10924820af99SPaul C. Anagnostopoulos         return Result;
1093d56cd429SPaul C. Anagnostopoulos     }
1094d56cd429SPaul C. Anagnostopoulos     break;
1095d56cd429SPaul C. Anagnostopoulos   }
1096aa9ca691SNicolai Haehnle   case EQ:
1097aa9ca691SNicolai Haehnle   case NE:
1098aa9ca691SNicolai Haehnle   case LE:
1099aa9ca691SNicolai Haehnle   case LT:
1100aa9ca691SNicolai Haehnle   case GE:
1101aa9ca691SNicolai Haehnle   case GT: {
1102641428f9SPaul C. Anagnostopoulos     // First see if we have two bit, bits, or int.
11032ac3cd20SRiver Riddle     IntInit *LHSi = dyn_cast_or_null<IntInit>(
11042ac3cd20SRiver Riddle         LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
11052ac3cd20SRiver Riddle     IntInit *RHSi = dyn_cast_or_null<IntInit>(
11062ac3cd20SRiver Riddle         RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
110784c287e3SPeter Collingbourne 
1108641428f9SPaul C. Anagnostopoulos     if (LHSi && RHSi) {
1109aa9ca691SNicolai Haehnle       bool Result;
1110aa9ca691SNicolai Haehnle       switch (getOpcode()) {
1111641428f9SPaul C. Anagnostopoulos       case EQ: Result = LHSi->getValue() == RHSi->getValue(); break;
1112641428f9SPaul C. Anagnostopoulos       case NE: Result = LHSi->getValue() != RHSi->getValue(); break;
1113641428f9SPaul C. Anagnostopoulos       case LE: Result = LHSi->getValue() <= RHSi->getValue(); break;
1114641428f9SPaul C. Anagnostopoulos       case LT: Result = LHSi->getValue() <  RHSi->getValue(); break;
1115641428f9SPaul C. Anagnostopoulos       case GE: Result = LHSi->getValue() >= RHSi->getValue(); break;
1116641428f9SPaul C. Anagnostopoulos       case GT: Result = LHSi->getValue() >  RHSi->getValue(); break;
1117aa9ca691SNicolai Haehnle       default: llvm_unreachable("unhandled comparison");
1118aa9ca691SNicolai Haehnle       }
11192ac3cd20SRiver Riddle       return BitInit::get(getRecordKeeper(), Result);
1120aa9ca691SNicolai Haehnle     }
112184c287e3SPeter Collingbourne 
1122641428f9SPaul C. Anagnostopoulos     // Next try strings.
1123fb509ed1SSean Silva     StringInit *LHSs = dyn_cast<StringInit>(LHS);
1124fb509ed1SSean Silva     StringInit *RHSs = dyn_cast<StringInit>(RHS);
112584c287e3SPeter Collingbourne 
1126aa9ca691SNicolai Haehnle     if (LHSs && RHSs) {
1127641428f9SPaul C. Anagnostopoulos       bool Result;
1128641428f9SPaul C. Anagnostopoulos       switch (getOpcode()) {
1129641428f9SPaul C. Anagnostopoulos       case EQ: Result = LHSs->getValue() == RHSs->getValue(); break;
1130641428f9SPaul C. Anagnostopoulos       case NE: Result = LHSs->getValue() != RHSs->getValue(); break;
1131641428f9SPaul C. Anagnostopoulos       case LE: Result = LHSs->getValue() <= RHSs->getValue(); break;
1132641428f9SPaul C. Anagnostopoulos       case LT: Result = LHSs->getValue() <  RHSs->getValue(); break;
1133641428f9SPaul C. Anagnostopoulos       case GE: Result = LHSs->getValue() >= RHSs->getValue(); break;
1134641428f9SPaul C. Anagnostopoulos       case GT: Result = LHSs->getValue() >  RHSs->getValue(); break;
1135641428f9SPaul C. Anagnostopoulos       default: llvm_unreachable("unhandled comparison");
1136aa9ca691SNicolai Haehnle       }
11372ac3cd20SRiver Riddle       return BitInit::get(getRecordKeeper(), Result);
1138641428f9SPaul C. Anagnostopoulos     }
1139641428f9SPaul C. Anagnostopoulos 
1140641428f9SPaul C. Anagnostopoulos     // Finally, !eq and !ne can be used with records.
1141641428f9SPaul C. Anagnostopoulos     if (getOpcode() == EQ || getOpcode() == NE) {
1142641428f9SPaul C. Anagnostopoulos       DefInit *LHSd = dyn_cast<DefInit>(LHS);
1143641428f9SPaul C. Anagnostopoulos       DefInit *RHSd = dyn_cast<DefInit>(RHS);
1144641428f9SPaul C. Anagnostopoulos       if (LHSd && RHSd)
11452ac3cd20SRiver Riddle         return BitInit::get(getRecordKeeper(),
11462ac3cd20SRiver Riddle                             (getOpcode() == EQ) ? LHSd == RHSd : LHSd != RHSd);
1147aa9ca691SNicolai Haehnle     }
114884c287e3SPeter Collingbourne 
114984c287e3SPeter Collingbourne     break;
115084c287e3SPeter Collingbourne   }
1151876af264SPaul C. Anagnostopoulos   case SETDAGOP: {
11521fed9a0cSSimon Tatham     DagInit *Dag = dyn_cast<DagInit>(LHS);
11531fed9a0cSSimon Tatham     DefInit *Op = dyn_cast<DefInit>(RHS);
11541fed9a0cSSimon Tatham     if (Dag && Op) {
11551fed9a0cSSimon Tatham       SmallVector<Init*, 8> Args;
11561fed9a0cSSimon Tatham       SmallVector<StringInit*, 8> ArgNames;
11571fed9a0cSSimon Tatham       for (unsigned i = 0, e = Dag->getNumArgs(); i != e; ++i) {
11581fed9a0cSSimon Tatham         Args.push_back(Dag->getArg(i));
11591fed9a0cSSimon Tatham         ArgNames.push_back(Dag->getArgName(i));
11601fed9a0cSSimon Tatham       }
11611fed9a0cSSimon Tatham       return DagInit::get(Op, nullptr, Args, ArgNames);
11621fed9a0cSSimon Tatham     }
11631fed9a0cSSimon Tatham     break;
11641fed9a0cSSimon Tatham   }
1165c7d4dc13SHal Finkel   case ADD:
11669d72065cSPaul C. Anagnostopoulos   case SUB:
1167a8967569SNicola Zaghen   case MUL:
11686b41a990SJoerg Sonnenberger   case AND:
11691c8d9338SMatt Arsenault   case OR:
11704767bb2cSPaul C. Anagnostopoulos   case XOR:
117184c287e3SPeter Collingbourne   case SHL:
117284c287e3SPeter Collingbourne   case SRA:
117384c287e3SPeter Collingbourne   case SRL: {
11742ac3cd20SRiver Riddle     IntInit *LHSi = dyn_cast_or_null<IntInit>(
11752ac3cd20SRiver Riddle         LHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
11762ac3cd20SRiver Riddle     IntInit *RHSi = dyn_cast_or_null<IntInit>(
11772ac3cd20SRiver Riddle         RHS->convertInitializerTo(IntRecTy::get(getRecordKeeper())));
117884c287e3SPeter Collingbourne     if (LHSi && RHSi) {
117984c287e3SPeter Collingbourne       int64_t LHSv = LHSi->getValue(), RHSv = RHSi->getValue();
118084c287e3SPeter Collingbourne       int64_t Result;
118184c287e3SPeter Collingbourne       switch (getOpcode()) {
1182a2886c21SCraig Topper       default: llvm_unreachable("Bad opcode!");
1183c7d4dc13SHal Finkel       case ADD: Result = LHSv + RHSv; break;
11849d72065cSPaul C. Anagnostopoulos       case SUB: Result = LHSv - RHSv; break;
1185a8967569SNicola Zaghen       case MUL: Result = LHSv * RHSv; break;
11866b41a990SJoerg Sonnenberger       case AND: Result = LHSv & RHSv; break;
11871c8d9338SMatt Arsenault       case OR:  Result = LHSv | RHSv; break;
11884767bb2cSPaul C. Anagnostopoulos       case XOR: Result = LHSv ^ RHSv; break;
11893f0c9c16SStanislav Mekhanoshin       case SHL: Result = (uint64_t)LHSv << (uint64_t)RHSv; break;
119084c287e3SPeter Collingbourne       case SRA: Result = LHSv >> RHSv; break;
119184c287e3SPeter Collingbourne       case SRL: Result = (uint64_t)LHSv >> (uint64_t)RHSv; break;
119284c287e3SPeter Collingbourne       }
11932ac3cd20SRiver Riddle       return IntInit::get(getRecordKeeper(), Result);
119484c287e3SPeter Collingbourne     }
119584c287e3SPeter Collingbourne     break;
119684c287e3SPeter Collingbourne   }
119784c287e3SPeter Collingbourne   }
119884c287e3SPeter Collingbourne   return const_cast<BinOpInit *>(this);
119984c287e3SPeter Collingbourne }
120084c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const12010b0eaf7eSNicolai Haehnle Init *BinOpInit::resolveReferences(Resolver &R) const {
12020b0eaf7eSNicolai Haehnle   Init *lhs = LHS->resolveReferences(R);
12030b0eaf7eSNicolai Haehnle   Init *rhs = RHS->resolveReferences(R);
120484c287e3SPeter Collingbourne 
120584c287e3SPeter Collingbourne   if (LHS != lhs || RHS != rhs)
12060b0eaf7eSNicolai Haehnle     return (BinOpInit::get(getOpcode(), lhs, rhs, getType()))
1207c47fe129SNicolai Haehnle         ->Fold(R.getCurrentRecord());
1208335c70f5SNicolai Haehnle   return const_cast<BinOpInit *>(this);
120984c287e3SPeter Collingbourne }
121084c287e3SPeter Collingbourne 
getAsString() const121184c287e3SPeter Collingbourne std::string BinOpInit::getAsString() const {
121284c287e3SPeter Collingbourne   std::string Result;
12135a6dda53SCraig Topper   switch (getOpcode()) {
121484c287e3SPeter Collingbourne   case CONCAT: Result = "!con"; break;
1215c7d4dc13SHal Finkel   case ADD: Result = "!add"; break;
12169d72065cSPaul C. Anagnostopoulos   case SUB: Result = "!sub"; break;
1217a8967569SNicola Zaghen   case MUL: Result = "!mul"; break;
12186b41a990SJoerg Sonnenberger   case AND: Result = "!and"; break;
12191c8d9338SMatt Arsenault   case OR: Result = "!or"; break;
12204767bb2cSPaul C. Anagnostopoulos   case XOR: Result = "!xor"; break;
122184c287e3SPeter Collingbourne   case SHL: Result = "!shl"; break;
122284c287e3SPeter Collingbourne   case SRA: Result = "!sra"; break;
122384c287e3SPeter Collingbourne   case SRL: Result = "!srl"; break;
122484c287e3SPeter Collingbourne   case EQ: Result = "!eq"; break;
1225aa9ca691SNicolai Haehnle   case NE: Result = "!ne"; break;
1226aa9ca691SNicolai Haehnle   case LE: Result = "!le"; break;
1227aa9ca691SNicolai Haehnle   case LT: Result = "!lt"; break;
1228aa9ca691SNicolai Haehnle   case GE: Result = "!ge"; break;
1229aa9ca691SNicolai Haehnle   case GT: Result = "!gt"; break;
1230314e80e5SDaniel Sanders   case LISTCONCAT: Result = "!listconcat"; break;
12315d9f656bSRoman Lebedev   case LISTSPLAT: Result = "!listsplat"; break;
123284c287e3SPeter Collingbourne   case STRCONCAT: Result = "!strconcat"; break;
1233d56cd429SPaul C. Anagnostopoulos   case INTERLEAVE: Result = "!interleave"; break;
1234876af264SPaul C. Anagnostopoulos   case SETDAGOP: Result = "!setdagop"; break;
123584c287e3SPeter Collingbourne   }
123684c287e3SPeter Collingbourne   return Result + "(" + LHS->getAsString() + ", " + RHS->getAsString() + ")";
123784c287e3SPeter Collingbourne }
123884c287e3SPeter Collingbourne 
12395e46adb0SCraig Topper static void
ProfileTernOpInit(FoldingSetNodeID & ID,unsigned Opcode,Init * LHS,Init * MHS,Init * RHS,RecTy * Type)12405e46adb0SCraig Topper ProfileTernOpInit(FoldingSetNodeID &ID, unsigned Opcode, Init *LHS, Init *MHS,
12415e46adb0SCraig Topper                   Init *RHS, RecTy *Type) {
12425e46adb0SCraig Topper   ID.AddInteger(Opcode);
12435e46adb0SCraig Topper   ID.AddPointer(LHS);
12445e46adb0SCraig Topper   ID.AddPointer(MHS);
12455e46adb0SCraig Topper   ID.AddPointer(RHS);
12465e46adb0SCraig Topper   ID.AddPointer(Type);
12475e46adb0SCraig Topper }
12485e46adb0SCraig Topper 
get(TernaryOp Opc,Init * LHS,Init * MHS,Init * RHS,RecTy * Type)12495e46adb0SCraig Topper TernOpInit *TernOpInit::get(TernaryOp Opc, Init *LHS, Init *MHS, Init *RHS,
125084c287e3SPeter Collingbourne                             RecTy *Type) {
12515e46adb0SCraig Topper   FoldingSetNodeID ID;
12525e46adb0SCraig Topper   ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
125384c287e3SPeter Collingbourne 
12542ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
12555e46adb0SCraig Topper   void *IP = nullptr;
12562ac3cd20SRiver Riddle   if (TernOpInit *I = RK.TheTernOpInitPool.FindNodeOrInsertPos(ID, IP))
12575e46adb0SCraig Topper     return I;
125884c287e3SPeter Collingbourne 
12592ac3cd20SRiver Riddle   TernOpInit *I = new (RK.Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
12602ac3cd20SRiver Riddle   RK.TheTernOpInitPool.InsertNode(I, IP);
12615e46adb0SCraig Topper   return I;
12625e46adb0SCraig Topper }
12635e46adb0SCraig Topper 
Profile(FoldingSetNodeID & ID) const12645e46adb0SCraig Topper void TernOpInit::Profile(FoldingSetNodeID &ID) const {
12655e46adb0SCraig Topper   ProfileTernOpInit(ID, getOpcode(), getLHS(), getMHS(), getRHS(), getType());
126684c287e3SPeter Collingbourne }
126784c287e3SPeter Collingbourne 
ItemApply(Init * LHS,Init * MHSe,Init * RHS,Record * CurRec)126891d2e5c8SPaul C. Anagnostopoulos static Init *ItemApply(Init *LHS, Init *MHSe, Init *RHS, Record *CurRec) {
12698ebf7e4dSNicolai Haehnle   MapResolver R(CurRec);
12708ebf7e4dSNicolai Haehnle   R.set(LHS, MHSe);
12718ebf7e4dSNicolai Haehnle   return RHS->resolveReferences(R);
12728ebf7e4dSNicolai Haehnle }
127384c287e3SPeter Collingbourne 
ForeachDagApply(Init * LHS,DagInit * MHSd,Init * RHS,Record * CurRec)12748ebf7e4dSNicolai Haehnle static Init *ForeachDagApply(Init *LHS, DagInit *MHSd, Init *RHS,
12758ebf7e4dSNicolai Haehnle                              Record *CurRec) {
12768ebf7e4dSNicolai Haehnle   bool Change = false;
127791d2e5c8SPaul C. Anagnostopoulos   Init *Val = ItemApply(LHS, MHSd->getOperator(), RHS, CurRec);
12788ebf7e4dSNicolai Haehnle   if (Val != MHSd->getOperator())
12798ebf7e4dSNicolai Haehnle     Change = true;
12808ebf7e4dSNicolai Haehnle 
12818ebf7e4dSNicolai Haehnle   SmallVector<std::pair<Init *, StringInit *>, 8> NewArgs;
12828ebf7e4dSNicolai Haehnle   for (unsigned int i = 0; i < MHSd->getNumArgs(); ++i) {
12838ebf7e4dSNicolai Haehnle     Init *Arg = MHSd->getArg(i);
12848ebf7e4dSNicolai Haehnle     Init *NewArg;
12858ebf7e4dSNicolai Haehnle     StringInit *ArgName = MHSd->getArgName(i);
12868ebf7e4dSNicolai Haehnle 
12878ebf7e4dSNicolai Haehnle     if (DagInit *Argd = dyn_cast<DagInit>(Arg))
12888ebf7e4dSNicolai Haehnle       NewArg = ForeachDagApply(LHS, Argd, RHS, CurRec);
12899ef76499SCraig Topper     else
129091d2e5c8SPaul C. Anagnostopoulos       NewArg = ItemApply(LHS, Arg, RHS, CurRec);
12918ebf7e4dSNicolai Haehnle 
12928ebf7e4dSNicolai Haehnle     NewArgs.push_back(std::make_pair(NewArg, ArgName));
12938ebf7e4dSNicolai Haehnle     if (Arg != NewArg)
12948ebf7e4dSNicolai Haehnle       Change = true;
129584c287e3SPeter Collingbourne   }
129684c287e3SPeter Collingbourne 
12978ebf7e4dSNicolai Haehnle   if (Change)
12988ebf7e4dSNicolai Haehnle     return DagInit::get(Val, nullptr, NewArgs);
12998ebf7e4dSNicolai Haehnle   return MHSd;
130084c287e3SPeter Collingbourne }
130184c287e3SPeter Collingbourne 
1302d75805e0SArtem Belevich // Applies RHS to all elements of MHS, using LHS as a temp variable.
ForeachHelper(Init * LHS,Init * MHS,Init * RHS,RecTy * Type,Record * CurRec)130381097ba6SNicolai Haehnle static Init *ForeachHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
13048ebf7e4dSNicolai Haehnle                            Record *CurRec) {
13058ebf7e4dSNicolai Haehnle   if (DagInit *MHSd = dyn_cast<DagInit>(MHS))
13068ebf7e4dSNicolai Haehnle     return ForeachDagApply(LHS, MHSd, RHS, CurRec);
130784c287e3SPeter Collingbourne 
13088ebf7e4dSNicolai Haehnle   if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
13091ddb78cdSMatthias Braun     SmallVector<Init *, 8> NewList(MHSl->begin(), MHSl->end());
13108ebf7e4dSNicolai Haehnle 
13118ebf7e4dSNicolai Haehnle     for (Init *&Item : NewList) {
131291d2e5c8SPaul C. Anagnostopoulos       Init *NewItem = ItemApply(LHS, Item, RHS, CurRec);
13138ebf7e4dSNicolai Haehnle       if (NewItem != Item)
13148ebf7e4dSNicolai Haehnle         Item = NewItem;
131584c287e3SPeter Collingbourne     }
13168ebf7e4dSNicolai Haehnle     return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
131784c287e3SPeter Collingbourne   }
13188ebf7e4dSNicolai Haehnle 
1319011817a0SCraig Topper   return nullptr;
132084c287e3SPeter Collingbourne }
132184c287e3SPeter Collingbourne 
132291d2e5c8SPaul C. Anagnostopoulos // Evaluates RHS for all elements of MHS, using LHS as a temp variable.
132391d2e5c8SPaul C. Anagnostopoulos // Creates a new list with the elements that evaluated to true.
FilterHelper(Init * LHS,Init * MHS,Init * RHS,RecTy * Type,Record * CurRec)132491d2e5c8SPaul C. Anagnostopoulos static Init *FilterHelper(Init *LHS, Init *MHS, Init *RHS, RecTy *Type,
132591d2e5c8SPaul C. Anagnostopoulos                           Record *CurRec) {
132691d2e5c8SPaul C. Anagnostopoulos   if (ListInit *MHSl = dyn_cast<ListInit>(MHS)) {
132791d2e5c8SPaul C. Anagnostopoulos     SmallVector<Init *, 8> NewList;
132891d2e5c8SPaul C. Anagnostopoulos 
132991d2e5c8SPaul C. Anagnostopoulos     for (Init *Item : MHSl->getValues()) {
133091d2e5c8SPaul C. Anagnostopoulos       Init *Include = ItemApply(LHS, Item, RHS, CurRec);
133191d2e5c8SPaul C. Anagnostopoulos       if (!Include)
133291d2e5c8SPaul C. Anagnostopoulos         return nullptr;
13332ac3cd20SRiver Riddle       if (IntInit *IncludeInt =
13342ac3cd20SRiver Riddle               dyn_cast_or_null<IntInit>(Include->convertInitializerTo(
13352ac3cd20SRiver Riddle                   IntRecTy::get(LHS->getRecordKeeper())))) {
133691d2e5c8SPaul C. Anagnostopoulos         if (IncludeInt->getValue())
133791d2e5c8SPaul C. Anagnostopoulos           NewList.push_back(Item);
133891d2e5c8SPaul C. Anagnostopoulos       } else {
133991d2e5c8SPaul C. Anagnostopoulos         return nullptr;
134091d2e5c8SPaul C. Anagnostopoulos       }
134191d2e5c8SPaul C. Anagnostopoulos     }
134291d2e5c8SPaul C. Anagnostopoulos     return ListInit::get(NewList, cast<ListRecTy>(Type)->getElementType());
134391d2e5c8SPaul C. Anagnostopoulos   }
134491d2e5c8SPaul C. Anagnostopoulos 
134591d2e5c8SPaul C. Anagnostopoulos   return nullptr;
134691d2e5c8SPaul C. Anagnostopoulos }
134791d2e5c8SPaul C. Anagnostopoulos 
Fold(Record * CurRec) const1348c47fe129SNicolai Haehnle Init *TernOpInit::Fold(Record *CurRec) const {
13492ac3cd20SRiver Riddle   RecordKeeper &RK = getRecordKeeper();
135084c287e3SPeter Collingbourne   switch (getOpcode()) {
135184c287e3SPeter Collingbourne   case SUBST: {
1352fb509ed1SSean Silva     DefInit *LHSd = dyn_cast<DefInit>(LHS);
1353fb509ed1SSean Silva     VarInit *LHSv = dyn_cast<VarInit>(LHS);
1354fb509ed1SSean Silva     StringInit *LHSs = dyn_cast<StringInit>(LHS);
135584c287e3SPeter Collingbourne 
1356fb509ed1SSean Silva     DefInit *MHSd = dyn_cast<DefInit>(MHS);
1357fb509ed1SSean Silva     VarInit *MHSv = dyn_cast<VarInit>(MHS);
1358fb509ed1SSean Silva     StringInit *MHSs = dyn_cast<StringInit>(MHS);
135984c287e3SPeter Collingbourne 
1360fb509ed1SSean Silva     DefInit *RHSd = dyn_cast<DefInit>(RHS);
1361fb509ed1SSean Silva     VarInit *RHSv = dyn_cast<VarInit>(RHS);
1362fb509ed1SSean Silva     StringInit *RHSs = dyn_cast<StringInit>(RHS);
136384c287e3SPeter Collingbourne 
1364b1846a35SCraig Topper     if (LHSd && MHSd && RHSd) {
136584c287e3SPeter Collingbourne       Record *Val = RHSd->getDef();
1366a9642b4eSCraig Topper       if (LHSd->getAsString() == RHSd->getAsString())
136784c287e3SPeter Collingbourne         Val = MHSd->getDef();
136884c287e3SPeter Collingbourne       return DefInit::get(Val);
136984c287e3SPeter Collingbourne     }
1370b1846a35SCraig Topper     if (LHSv && MHSv && RHSv) {
1371adcd0268SBenjamin Kramer       std::string Val = std::string(RHSv->getName());
1372a9642b4eSCraig Topper       if (LHSv->getAsString() == RHSv->getAsString())
1373adcd0268SBenjamin Kramer         Val = std::string(MHSv->getName());
137484c287e3SPeter Collingbourne       return VarInit::get(Val, getType());
137584c287e3SPeter Collingbourne     }
1376b1846a35SCraig Topper     if (LHSs && MHSs && RHSs) {
1377adcd0268SBenjamin Kramer       std::string Val = std::string(RHSs->getValue());
137884c287e3SPeter Collingbourne 
137984c287e3SPeter Collingbourne       std::string::size_type found;
138084c287e3SPeter Collingbourne       std::string::size_type idx = 0;
13816ee494b6SCraig Topper       while (true) {
1382adcd0268SBenjamin Kramer         found = Val.find(std::string(LHSs->getValue()), idx);
13836ee494b6SCraig Topper         if (found == std::string::npos)
13846ee494b6SCraig Topper           break;
1385adcd0268SBenjamin Kramer         Val.replace(found, LHSs->getValue().size(),
1386adcd0268SBenjamin Kramer                     std::string(MHSs->getValue()));
138784c287e3SPeter Collingbourne         idx = found + MHSs->getValue().size();
13886ee494b6SCraig Topper       }
138984c287e3SPeter Collingbourne 
13902ac3cd20SRiver Riddle       return StringInit::get(RK, Val);
139184c287e3SPeter Collingbourne     }
139284c287e3SPeter Collingbourne     break;
139384c287e3SPeter Collingbourne   }
139484c287e3SPeter Collingbourne 
139584c287e3SPeter Collingbourne   case FOREACH: {
13968ebf7e4dSNicolai Haehnle     if (Init *Result = ForeachHelper(LHS, MHS, RHS, getType(), CurRec))
139784c287e3SPeter Collingbourne       return Result;
139884c287e3SPeter Collingbourne     break;
139984c287e3SPeter Collingbourne   }
140084c287e3SPeter Collingbourne 
140191d2e5c8SPaul C. Anagnostopoulos   case FILTER: {
140291d2e5c8SPaul C. Anagnostopoulos     if (Init *Result = FilterHelper(LHS, MHS, RHS, getType(), CurRec))
140391d2e5c8SPaul C. Anagnostopoulos       return Result;
140491d2e5c8SPaul C. Anagnostopoulos     break;
140591d2e5c8SPaul C. Anagnostopoulos   }
140691d2e5c8SPaul C. Anagnostopoulos 
140784c287e3SPeter Collingbourne   case IF: {
1408dfda9dccSNicolai Haehnle     if (IntInit *LHSi = dyn_cast_or_null<IntInit>(
14092ac3cd20SRiver Riddle             LHS->convertInitializerTo(IntRecTy::get(RK)))) {
1410a9642b4eSCraig Topper       if (LHSi->getValue())
141184c287e3SPeter Collingbourne         return MHS;
141284c287e3SPeter Collingbourne       return RHS;
141384c287e3SPeter Collingbourne     }
141484c287e3SPeter Collingbourne     break;
141584c287e3SPeter Collingbourne   }
14166c118656SNicolai Haehnle 
14176c118656SNicolai Haehnle   case DAG: {
14186c118656SNicolai Haehnle     ListInit *MHSl = dyn_cast<ListInit>(MHS);
14196c118656SNicolai Haehnle     ListInit *RHSl = dyn_cast<ListInit>(RHS);
14206c118656SNicolai Haehnle     bool MHSok = MHSl || isa<UnsetInit>(MHS);
14216c118656SNicolai Haehnle     bool RHSok = RHSl || isa<UnsetInit>(RHS);
14226c118656SNicolai Haehnle 
14236c118656SNicolai Haehnle     if (isa<UnsetInit>(MHS) && isa<UnsetInit>(RHS))
14246c118656SNicolai Haehnle       break; // Typically prevented by the parser, but might happen with template args
14256c118656SNicolai Haehnle 
14266c118656SNicolai Haehnle     if (MHSok && RHSok && (!MHSl || !RHSl || MHSl->size() == RHSl->size())) {
14276c118656SNicolai Haehnle       SmallVector<std::pair<Init *, StringInit *>, 8> Children;
14286c118656SNicolai Haehnle       unsigned Size = MHSl ? MHSl->size() : RHSl->size();
14296c118656SNicolai Haehnle       for (unsigned i = 0; i != Size; ++i) {
14302ac3cd20SRiver Riddle         Init *Node = MHSl ? MHSl->getElement(i) : UnsetInit::get(RK);
14312ac3cd20SRiver Riddle         Init *Name = RHSl ? RHSl->getElement(i) : UnsetInit::get(RK);
14326c118656SNicolai Haehnle         if (!isa<StringInit>(Name) && !isa<UnsetInit>(Name))
14336c118656SNicolai Haehnle           return const_cast<TernOpInit *>(this);
14346c118656SNicolai Haehnle         Children.emplace_back(Node, dyn_cast<StringInit>(Name));
14356c118656SNicolai Haehnle       }
14366c118656SNicolai Haehnle       return DagInit::get(LHS, nullptr, Children);
14376c118656SNicolai Haehnle     }
14386c118656SNicolai Haehnle     break;
14396c118656SNicolai Haehnle   }
1440e122a71aSPaul C. Anagnostopoulos 
1441e122a71aSPaul C. Anagnostopoulos   case SUBSTR: {
1442e122a71aSPaul C. Anagnostopoulos     StringInit *LHSs = dyn_cast<StringInit>(LHS);
1443e122a71aSPaul C. Anagnostopoulos     IntInit *MHSi = dyn_cast<IntInit>(MHS);
1444e122a71aSPaul C. Anagnostopoulos     IntInit *RHSi = dyn_cast<IntInit>(RHS);
1445e122a71aSPaul C. Anagnostopoulos     if (LHSs && MHSi && RHSi) {
1446e122a71aSPaul C. Anagnostopoulos       int64_t StringSize = LHSs->getValue().size();
1447e122a71aSPaul C. Anagnostopoulos       int64_t Start = MHSi->getValue();
1448e122a71aSPaul C. Anagnostopoulos       int64_t Length = RHSi->getValue();
1449e122a71aSPaul C. Anagnostopoulos       if (Start < 0 || Start > StringSize)
1450e122a71aSPaul C. Anagnostopoulos         PrintError(CurRec->getLoc(),
1451e122a71aSPaul C. Anagnostopoulos                    Twine("!substr start position is out of range 0...") +
1452e122a71aSPaul C. Anagnostopoulos                        std::to_string(StringSize) + ": " +
1453e122a71aSPaul C. Anagnostopoulos                        std::to_string(Start));
1454e122a71aSPaul C. Anagnostopoulos       if (Length < 0)
1455e122a71aSPaul C. Anagnostopoulos         PrintError(CurRec->getLoc(), "!substr length must be nonnegative");
14562ac3cd20SRiver Riddle       return StringInit::get(RK, LHSs->getValue().substr(Start, Length),
1457e122a71aSPaul C. Anagnostopoulos                              LHSs->getFormat());
1458e122a71aSPaul C. Anagnostopoulos     }
1459e122a71aSPaul C. Anagnostopoulos     break;
1460e122a71aSPaul C. Anagnostopoulos   }
1461952c6dddSPaul C. Anagnostopoulos 
1462952c6dddSPaul C. Anagnostopoulos   case FIND: {
1463952c6dddSPaul C. Anagnostopoulos     StringInit *LHSs = dyn_cast<StringInit>(LHS);
1464952c6dddSPaul C. Anagnostopoulos     StringInit *MHSs = dyn_cast<StringInit>(MHS);
1465952c6dddSPaul C. Anagnostopoulos     IntInit *RHSi = dyn_cast<IntInit>(RHS);
1466952c6dddSPaul C. Anagnostopoulos     if (LHSs && MHSs && RHSi) {
1467952c6dddSPaul C. Anagnostopoulos       int64_t SourceSize = LHSs->getValue().size();
1468952c6dddSPaul C. Anagnostopoulos       int64_t Start = RHSi->getValue();
1469952c6dddSPaul C. Anagnostopoulos       if (Start < 0 || Start > SourceSize)
1470952c6dddSPaul C. Anagnostopoulos         PrintError(CurRec->getLoc(),
1471952c6dddSPaul C. Anagnostopoulos                    Twine("!find start position is out of range 0...") +
1472952c6dddSPaul C. Anagnostopoulos                        std::to_string(SourceSize) + ": " +
1473952c6dddSPaul C. Anagnostopoulos                        std::to_string(Start));
1474952c6dddSPaul C. Anagnostopoulos       auto I = LHSs->getValue().find(MHSs->getValue(), Start);
1475952c6dddSPaul C. Anagnostopoulos       if (I == std::string::npos)
14762ac3cd20SRiver Riddle         return IntInit::get(RK, -1);
14772ac3cd20SRiver Riddle       return IntInit::get(RK, I);
1478952c6dddSPaul C. Anagnostopoulos     }
1479952c6dddSPaul C. Anagnostopoulos     break;
1480952c6dddSPaul C. Anagnostopoulos   }
148184c287e3SPeter Collingbourne   }
148284c287e3SPeter Collingbourne 
148384c287e3SPeter Collingbourne   return const_cast<TernOpInit *>(this);
148484c287e3SPeter Collingbourne }
148584c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const14860b0eaf7eSNicolai Haehnle Init *TernOpInit::resolveReferences(Resolver &R) const {
14870b0eaf7eSNicolai Haehnle   Init *lhs = LHS->resolveReferences(R);
148884c287e3SPeter Collingbourne 
14895a6dda53SCraig Topper   if (getOpcode() == IF && lhs != LHS) {
1490dfda9dccSNicolai Haehnle     if (IntInit *Value = dyn_cast_or_null<IntInit>(
14912ac3cd20SRiver Riddle             lhs->convertInitializerTo(IntRecTy::get(getRecordKeeper())))) {
149284c287e3SPeter Collingbourne       // Short-circuit
1493dfda9dccSNicolai Haehnle       if (Value->getValue())
1494dfda9dccSNicolai Haehnle         return MHS->resolveReferences(R);
1495dfda9dccSNicolai Haehnle       return RHS->resolveReferences(R);
149684c287e3SPeter Collingbourne     }
149784c287e3SPeter Collingbourne   }
149884c287e3SPeter Collingbourne 
14990b0eaf7eSNicolai Haehnle   Init *mhs = MHS->resolveReferences(R);
15008ebf7e4dSNicolai Haehnle   Init *rhs;
15018ebf7e4dSNicolai Haehnle 
150291d2e5c8SPaul C. Anagnostopoulos   if (getOpcode() == FOREACH || getOpcode() == FILTER) {
15038ebf7e4dSNicolai Haehnle     ShadowResolver SR(R);
15048ebf7e4dSNicolai Haehnle     SR.addShadow(lhs);
15058ebf7e4dSNicolai Haehnle     rhs = RHS->resolveReferences(SR);
15068ebf7e4dSNicolai Haehnle   } else {
15078ebf7e4dSNicolai Haehnle     rhs = RHS->resolveReferences(R);
15088ebf7e4dSNicolai Haehnle   }
150984c287e3SPeter Collingbourne 
151084c287e3SPeter Collingbourne   if (LHS != lhs || MHS != mhs || RHS != rhs)
15110b0eaf7eSNicolai Haehnle     return (TernOpInit::get(getOpcode(), lhs, mhs, rhs, getType()))
1512c47fe129SNicolai Haehnle         ->Fold(R.getCurrentRecord());
1513335c70f5SNicolai Haehnle   return const_cast<TernOpInit *>(this);
151484c287e3SPeter Collingbourne }
151584c287e3SPeter Collingbourne 
getAsString() const151684c287e3SPeter Collingbourne std::string TernOpInit::getAsString() const {
151784c287e3SPeter Collingbourne   std::string Result;
15186a02604eSSimon Tatham   bool UnquotedLHS = false;
15195a6dda53SCraig Topper   switch (getOpcode()) {
1520554eb1f6SPaul C. Anagnostopoulos   case DAG: Result = "!dag"; break;
1521e122a71aSPaul C. Anagnostopoulos   case FILTER: Result = "!filter"; UnquotedLHS = true; break;
1522e122a71aSPaul C. Anagnostopoulos   case FOREACH: Result = "!foreach"; UnquotedLHS = true; break;
1523e122a71aSPaul C. Anagnostopoulos   case IF: Result = "!if"; break;
1524e122a71aSPaul C. Anagnostopoulos   case SUBST: Result = "!subst"; break;
1525e122a71aSPaul C. Anagnostopoulos   case SUBSTR: Result = "!substr"; break;
1526952c6dddSPaul C. Anagnostopoulos   case FIND: Result = "!find"; break;
152784c287e3SPeter Collingbourne   }
15286a02604eSSimon Tatham   return (Result + "(" +
15296a02604eSSimon Tatham           (UnquotedLHS ? LHS->getAsUnquotedString() : LHS->getAsString()) +
15306a02604eSSimon Tatham           ", " + MHS->getAsString() + ", " + RHS->getAsString() + ")");
153184c287e3SPeter Collingbourne }
153284c287e3SPeter Collingbourne 
ProfileFoldOpInit(FoldingSetNodeID & ID,Init * Start,Init * List,Init * A,Init * B,Init * Expr,RecTy * Type)1533ef8df920SPaul C. Anagnostopoulos static void ProfileFoldOpInit(FoldingSetNodeID &ID, Init *Start, Init *List,
1534ef8df920SPaul C. Anagnostopoulos                               Init *A, Init *B, Init *Expr, RecTy *Type) {
1535d34f6843SNicolai Haehnle   ID.AddPointer(Start);
1536d34f6843SNicolai Haehnle   ID.AddPointer(List);
1537d34f6843SNicolai Haehnle   ID.AddPointer(A);
1538d34f6843SNicolai Haehnle   ID.AddPointer(B);
1539d34f6843SNicolai Haehnle   ID.AddPointer(Expr);
1540d34f6843SNicolai Haehnle   ID.AddPointer(Type);
1541d34f6843SNicolai Haehnle }
1542d34f6843SNicolai Haehnle 
get(Init * Start,Init * List,Init * A,Init * B,Init * Expr,RecTy * Type)1543d34f6843SNicolai Haehnle FoldOpInit *FoldOpInit::get(Init *Start, Init *List, Init *A, Init *B,
1544d34f6843SNicolai Haehnle                             Init *Expr, RecTy *Type) {
1545d34f6843SNicolai Haehnle   FoldingSetNodeID ID;
1546d34f6843SNicolai Haehnle   ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type);
1547d34f6843SNicolai Haehnle 
15482ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = Start->getRecordKeeper().getImpl();
1549d34f6843SNicolai Haehnle   void *IP = nullptr;
15502ac3cd20SRiver Riddle   if (FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
1551d34f6843SNicolai Haehnle     return I;
1552d34f6843SNicolai Haehnle 
15532ac3cd20SRiver Riddle   FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
15542ac3cd20SRiver Riddle   RK.TheFoldOpInitPool.InsertNode(I, IP);
1555d34f6843SNicolai Haehnle   return I;
1556d34f6843SNicolai Haehnle }
1557d34f6843SNicolai Haehnle 
Profile(FoldingSetNodeID & ID) const1558d34f6843SNicolai Haehnle void FoldOpInit::Profile(FoldingSetNodeID &ID) const {
1559d34f6843SNicolai Haehnle   ProfileFoldOpInit(ID, Start, List, A, B, Expr, getType());
1560d34f6843SNicolai Haehnle }
1561d34f6843SNicolai Haehnle 
Fold(Record * CurRec) const1562d34f6843SNicolai Haehnle Init *FoldOpInit::Fold(Record *CurRec) const {
1563d34f6843SNicolai Haehnle   if (ListInit *LI = dyn_cast<ListInit>(List)) {
1564d34f6843SNicolai Haehnle     Init *Accum = Start;
1565d34f6843SNicolai Haehnle     for (Init *Elt : *LI) {
1566d34f6843SNicolai Haehnle       MapResolver R(CurRec);
1567d34f6843SNicolai Haehnle       R.set(A, Accum);
1568d34f6843SNicolai Haehnle       R.set(B, Elt);
1569d34f6843SNicolai Haehnle       Accum = Expr->resolveReferences(R);
1570d34f6843SNicolai Haehnle     }
1571d34f6843SNicolai Haehnle     return Accum;
1572d34f6843SNicolai Haehnle   }
1573d34f6843SNicolai Haehnle   return const_cast<FoldOpInit *>(this);
1574d34f6843SNicolai Haehnle }
1575d34f6843SNicolai Haehnle 
resolveReferences(Resolver & R) const1576d34f6843SNicolai Haehnle Init *FoldOpInit::resolveReferences(Resolver &R) const {
1577d34f6843SNicolai Haehnle   Init *NewStart = Start->resolveReferences(R);
1578d34f6843SNicolai Haehnle   Init *NewList = List->resolveReferences(R);
1579d34f6843SNicolai Haehnle   ShadowResolver SR(R);
1580d34f6843SNicolai Haehnle   SR.addShadow(A);
1581d34f6843SNicolai Haehnle   SR.addShadow(B);
1582d34f6843SNicolai Haehnle   Init *NewExpr = Expr->resolveReferences(SR);
1583d34f6843SNicolai Haehnle 
1584d34f6843SNicolai Haehnle   if (Start == NewStart && List == NewList && Expr == NewExpr)
1585d34f6843SNicolai Haehnle     return const_cast<FoldOpInit *>(this);
1586d34f6843SNicolai Haehnle 
1587d34f6843SNicolai Haehnle   return get(NewStart, NewList, A, B, NewExpr, getType())
1588d34f6843SNicolai Haehnle       ->Fold(R.getCurrentRecord());
1589d34f6843SNicolai Haehnle }
1590d34f6843SNicolai Haehnle 
getBit(unsigned Bit) const1591d34f6843SNicolai Haehnle Init *FoldOpInit::getBit(unsigned Bit) const {
1592d34f6843SNicolai Haehnle   return VarBitInit::get(const_cast<FoldOpInit *>(this), Bit);
1593d34f6843SNicolai Haehnle }
1594d34f6843SNicolai Haehnle 
getAsString() const1595d34f6843SNicolai Haehnle std::string FoldOpInit::getAsString() const {
1596d34f6843SNicolai Haehnle   return (Twine("!foldl(") + Start->getAsString() + ", " + List->getAsString() +
1597d34f6843SNicolai Haehnle           ", " + A->getAsUnquotedString() + ", " + B->getAsUnquotedString() +
1598d34f6843SNicolai Haehnle           ", " + Expr->getAsString() + ")")
1599d34f6843SNicolai Haehnle       .str();
1600d34f6843SNicolai Haehnle }
1601d34f6843SNicolai Haehnle 
ProfileIsAOpInit(FoldingSetNodeID & ID,RecTy * CheckType,Init * Expr)1602b5376059SNicolai Haehnle static void ProfileIsAOpInit(FoldingSetNodeID &ID, RecTy *CheckType,
1603b5376059SNicolai Haehnle                              Init *Expr) {
1604b5376059SNicolai Haehnle   ID.AddPointer(CheckType);
1605b5376059SNicolai Haehnle   ID.AddPointer(Expr);
1606b5376059SNicolai Haehnle }
1607b5376059SNicolai Haehnle 
get(RecTy * CheckType,Init * Expr)1608b5376059SNicolai Haehnle IsAOpInit *IsAOpInit::get(RecTy *CheckType, Init *Expr) {
1609b5376059SNicolai Haehnle 
1610b5376059SNicolai Haehnle   FoldingSetNodeID ID;
1611b5376059SNicolai Haehnle   ProfileIsAOpInit(ID, CheckType, Expr);
1612b5376059SNicolai Haehnle 
16132ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
1614b5376059SNicolai Haehnle   void *IP = nullptr;
16152ac3cd20SRiver Riddle   if (IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
1616b5376059SNicolai Haehnle     return I;
1617b5376059SNicolai Haehnle 
16182ac3cd20SRiver Riddle   IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr);
16192ac3cd20SRiver Riddle   RK.TheIsAOpInitPool.InsertNode(I, IP);
1620b5376059SNicolai Haehnle   return I;
1621b5376059SNicolai Haehnle }
1622b5376059SNicolai Haehnle 
Profile(FoldingSetNodeID & ID) const1623b5376059SNicolai Haehnle void IsAOpInit::Profile(FoldingSetNodeID &ID) const {
1624b5376059SNicolai Haehnle   ProfileIsAOpInit(ID, CheckType, Expr);
1625b5376059SNicolai Haehnle }
1626b5376059SNicolai Haehnle 
Fold() const1627b5376059SNicolai Haehnle Init *IsAOpInit::Fold() const {
1628b5376059SNicolai Haehnle   if (TypedInit *TI = dyn_cast<TypedInit>(Expr)) {
1629b5376059SNicolai Haehnle     // Is the expression type known to be (a subclass of) the desired type?
1630b5376059SNicolai Haehnle     if (TI->getType()->typeIsConvertibleTo(CheckType))
16312ac3cd20SRiver Riddle       return IntInit::get(getRecordKeeper(), 1);
1632b5376059SNicolai Haehnle 
1633b5376059SNicolai Haehnle     if (isa<RecordRecTy>(CheckType)) {
1634b5376059SNicolai Haehnle       // If the target type is not a subclass of the expression type, or if
1635b5376059SNicolai Haehnle       // the expression has fully resolved to a record, we know that it can't
1636b5376059SNicolai Haehnle       // be of the required type.
1637b5376059SNicolai Haehnle       if (!CheckType->typeIsConvertibleTo(TI->getType()) || isa<DefInit>(Expr))
16382ac3cd20SRiver Riddle         return IntInit::get(getRecordKeeper(), 0);
1639b5376059SNicolai Haehnle     } else {
1640b5376059SNicolai Haehnle       // We treat non-record types as not castable.
16412ac3cd20SRiver Riddle       return IntInit::get(getRecordKeeper(), 0);
1642b5376059SNicolai Haehnle     }
1643b5376059SNicolai Haehnle   }
1644b5376059SNicolai Haehnle   return const_cast<IsAOpInit *>(this);
1645b5376059SNicolai Haehnle }
1646b5376059SNicolai Haehnle 
resolveReferences(Resolver & R) const1647b5376059SNicolai Haehnle Init *IsAOpInit::resolveReferences(Resolver &R) const {
1648b5376059SNicolai Haehnle   Init *NewExpr = Expr->resolveReferences(R);
1649b5376059SNicolai Haehnle   if (Expr != NewExpr)
1650b5376059SNicolai Haehnle     return get(CheckType, NewExpr)->Fold();
1651b5376059SNicolai Haehnle   return const_cast<IsAOpInit *>(this);
1652b5376059SNicolai Haehnle }
1653b5376059SNicolai Haehnle 
getBit(unsigned Bit) const1654b5376059SNicolai Haehnle Init *IsAOpInit::getBit(unsigned Bit) const {
1655b5376059SNicolai Haehnle   return VarBitInit::get(const_cast<IsAOpInit *>(this), Bit);
1656b5376059SNicolai Haehnle }
1657b5376059SNicolai Haehnle 
getAsString() const1658b5376059SNicolai Haehnle std::string IsAOpInit::getAsString() const {
1659b5376059SNicolai Haehnle   return (Twine("!isa<") + CheckType->getAsString() + ">(" +
1660b5376059SNicolai Haehnle           Expr->getAsString() + ")")
1661b5376059SNicolai Haehnle       .str();
1662b5376059SNicolai Haehnle }
1663b5376059SNicolai Haehnle 
ProfileExistsOpInit(FoldingSetNodeID & ID,RecTy * CheckType,Init * Expr)166463448488Swangpc static void ProfileExistsOpInit(FoldingSetNodeID &ID, RecTy *CheckType,
166563448488Swangpc                                 Init *Expr) {
166663448488Swangpc   ID.AddPointer(CheckType);
166763448488Swangpc   ID.AddPointer(Expr);
166863448488Swangpc }
166963448488Swangpc 
get(RecTy * CheckType,Init * Expr)167063448488Swangpc ExistsOpInit *ExistsOpInit::get(RecTy *CheckType, Init *Expr) {
167163448488Swangpc   FoldingSetNodeID ID;
167263448488Swangpc   ProfileExistsOpInit(ID, CheckType, Expr);
167363448488Swangpc 
167463448488Swangpc   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
167563448488Swangpc   void *IP = nullptr;
167663448488Swangpc   if (ExistsOpInit *I = RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP))
167763448488Swangpc     return I;
167863448488Swangpc 
167963448488Swangpc   ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr);
168063448488Swangpc   RK.TheExistsOpInitPool.InsertNode(I, IP);
168163448488Swangpc   return I;
168263448488Swangpc }
168363448488Swangpc 
Profile(FoldingSetNodeID & ID) const168463448488Swangpc void ExistsOpInit::Profile(FoldingSetNodeID &ID) const {
168563448488Swangpc   ProfileExistsOpInit(ID, CheckType, Expr);
168663448488Swangpc }
168763448488Swangpc 
Fold(Record * CurRec,bool IsFinal) const168863448488Swangpc Init *ExistsOpInit::Fold(Record *CurRec, bool IsFinal) const {
168963448488Swangpc   if (StringInit *Name = dyn_cast<StringInit>(Expr)) {
169063448488Swangpc     if (!CurRec && !IsFinal)
169163448488Swangpc       return const_cast<ExistsOpInit *>(this);
169263448488Swangpc 
169363448488Swangpc     // Self-references are allowed, but their resolution is delayed until
169463448488Swangpc     // the final resolve to ensure that we get the correct type for them.
169563448488Swangpc     auto *Anonymous = dyn_cast<AnonymousNameInit>(CurRec->getNameInit());
169663448488Swangpc     if (Name == CurRec->getNameInit() ||
169763448488Swangpc         (Anonymous && Name == Anonymous->getNameInit())) {
169863448488Swangpc       if (!IsFinal)
169963448488Swangpc         return const_cast<ExistsOpInit *>(this);
170063448488Swangpc 
170163448488Swangpc       // No doubt that there exists a record, so we should check if types are
170263448488Swangpc       // compatiable.
170363448488Swangpc       return IntInit::get(getRecordKeeper(),
170463448488Swangpc                           CurRec->getType()->typeIsA(CheckType));
170563448488Swangpc     }
170663448488Swangpc 
170763448488Swangpc     // Look up all defined records to see if we can find one.
170863448488Swangpc     Record *D = CheckType->getRecordKeeper().getDef(Name->getValue());
170963448488Swangpc     if (!D) {
171063448488Swangpc       if (IsFinal)
171163448488Swangpc         return IntInit::get(getRecordKeeper(), 0);
171263448488Swangpc       return const_cast<ExistsOpInit *>(this);
171363448488Swangpc     }
171463448488Swangpc 
171563448488Swangpc     // Check if types are compatiable.
171663448488Swangpc     return IntInit::get(getRecordKeeper(),
171763448488Swangpc                         DefInit::get(D)->getType()->typeIsA(CheckType));
171863448488Swangpc   }
171963448488Swangpc   return const_cast<ExistsOpInit *>(this);
172063448488Swangpc }
172163448488Swangpc 
resolveReferences(Resolver & R) const172263448488Swangpc Init *ExistsOpInit::resolveReferences(Resolver &R) const {
172363448488Swangpc   Init *NewExpr = Expr->resolveReferences(R);
172463448488Swangpc   if (Expr != NewExpr || R.isFinal())
172563448488Swangpc     return get(CheckType, NewExpr)->Fold(R.getCurrentRecord(), R.isFinal());
172663448488Swangpc   return const_cast<ExistsOpInit *>(this);
172763448488Swangpc }
172863448488Swangpc 
getBit(unsigned Bit) const172963448488Swangpc Init *ExistsOpInit::getBit(unsigned Bit) const {
173063448488Swangpc   return VarBitInit::get(const_cast<ExistsOpInit *>(this), Bit);
173163448488Swangpc }
173263448488Swangpc 
getAsString() const173363448488Swangpc std::string ExistsOpInit::getAsString() const {
173463448488Swangpc   return (Twine("!exists<") + CheckType->getAsString() + ">(" +
173563448488Swangpc           Expr->getAsString() + ")")
173663448488Swangpc       .str();
173763448488Swangpc }
173863448488Swangpc 
getFieldType(StringInit * FieldName) const17396a441839SMatthias Braun RecTy *TypedInit::getFieldType(StringInit *FieldName) const {
174013080fd1SNicolai Haehnle   if (RecordRecTy *RecordType = dyn_cast<RecordRecTy>(getType())) {
174113080fd1SNicolai Haehnle     for (Record *Rec : RecordType->getClasses()) {
174213080fd1SNicolai Haehnle       if (RecordVal *Field = Rec->getValue(FieldName))
174384c287e3SPeter Collingbourne         return Field->getType();
174413080fd1SNicolai Haehnle     }
174513080fd1SNicolai Haehnle   }
1746011817a0SCraig Topper   return nullptr;
174784c287e3SPeter Collingbourne }
174884c287e3SPeter Collingbourne 
174984c287e3SPeter Collingbourne Init *
convertInitializerTo(RecTy * Ty) const175095819069SCraig Topper TypedInit::convertInitializerTo(RecTy *Ty) const {
1751dfda9dccSNicolai Haehnle   if (getType() == Ty || getType()->typeIsA(Ty))
175295819069SCraig Topper     return const_cast<TypedInit *>(this);
175395819069SCraig Topper 
1754dfda9dccSNicolai Haehnle   if (isa<BitRecTy>(getType()) && isa<BitsRecTy>(Ty) &&
1755dfda9dccSNicolai Haehnle       cast<BitsRecTy>(Ty)->getNumBits() == 1)
17562ac3cd20SRiver Riddle     return BitsInit::get(getRecordKeeper(), {const_cast<TypedInit *>(this)});
175795819069SCraig Topper 
175895819069SCraig Topper   return nullptr;
175995819069SCraig Topper }
176095819069SCraig Topper 
convertInitializerBitRange(ArrayRef<unsigned> Bits) const17611ddb78cdSMatthias Braun Init *TypedInit::convertInitializerBitRange(ArrayRef<unsigned> Bits) const {
176298c61711SSean Silva   BitsRecTy *T = dyn_cast<BitsRecTy>(getType());
1763011817a0SCraig Topper   if (!T) return nullptr;  // Cannot subscript a non-bits variable.
176484c287e3SPeter Collingbourne   unsigned NumBits = T->getNumBits();
176584c287e3SPeter Collingbourne 
1766ca151317SMatthias Braun   SmallVector<Init *, 16> NewBits;
1767ca151317SMatthias Braun   NewBits.reserve(Bits.size());
1768ca151317SMatthias Braun   for (unsigned Bit : Bits) {
1769ca151317SMatthias Braun     if (Bit >= NumBits)
1770011817a0SCraig Topper       return nullptr;
177184c287e3SPeter Collingbourne 
1772ca151317SMatthias Braun     NewBits.push_back(VarBitInit::get(const_cast<TypedInit *>(this), Bit));
177384c287e3SPeter Collingbourne   }
17742ac3cd20SRiver Riddle   return BitsInit::get(getRecordKeeper(), NewBits);
177584c287e3SPeter Collingbourne }
177684c287e3SPeter Collingbourne 
getCastTo(RecTy * Ty) const1777dfda9dccSNicolai Haehnle Init *TypedInit::getCastTo(RecTy *Ty) const {
1778dfda9dccSNicolai Haehnle   // Handle the common case quickly
1779dfda9dccSNicolai Haehnle   if (getType() == Ty || getType()->typeIsA(Ty))
1780dfda9dccSNicolai Haehnle     return const_cast<TypedInit *>(this);
1781dfda9dccSNicolai Haehnle 
1782dfda9dccSNicolai Haehnle   if (Init *Converted = convertInitializerTo(Ty)) {
1783dfda9dccSNicolai Haehnle     assert(!isa<TypedInit>(Converted) ||
1784dfda9dccSNicolai Haehnle            cast<TypedInit>(Converted)->getType()->typeIsA(Ty));
1785dfda9dccSNicolai Haehnle     return Converted;
1786dfda9dccSNicolai Haehnle   }
1787dfda9dccSNicolai Haehnle 
1788dfda9dccSNicolai Haehnle   if (!getType()->typeIsConvertibleTo(Ty))
1789dfda9dccSNicolai Haehnle     return nullptr;
1790dfda9dccSNicolai Haehnle 
1791dfda9dccSNicolai Haehnle   return UnOpInit::get(UnOpInit::CAST, const_cast<TypedInit *>(this), Ty)
1792c47fe129SNicolai Haehnle       ->Fold(nullptr);
1793dfda9dccSNicolai Haehnle }
1794dfda9dccSNicolai Haehnle 
convertInitListSlice(ArrayRef<unsigned> Elements) const17951ddb78cdSMatthias Braun Init *TypedInit::convertInitListSlice(ArrayRef<unsigned> Elements) const {
179698c61711SSean Silva   ListRecTy *T = dyn_cast<ListRecTy>(getType());
1797011817a0SCraig Topper   if (!T) return nullptr;  // Cannot subscript a non-list variable.
179884c287e3SPeter Collingbourne 
179984c287e3SPeter Collingbourne   if (Elements.size() == 1)
180084c287e3SPeter Collingbourne     return VarListElementInit::get(const_cast<TypedInit *>(this), Elements[0]);
180184c287e3SPeter Collingbourne 
18021ddb78cdSMatthias Braun   SmallVector<Init*, 8> ListInits;
180384c287e3SPeter Collingbourne   ListInits.reserve(Elements.size());
1804ca151317SMatthias Braun   for (unsigned Element : Elements)
180584c287e3SPeter Collingbourne     ListInits.push_back(VarListElementInit::get(const_cast<TypedInit *>(this),
1806ca151317SMatthias Braun                                                 Element));
180781097ba6SNicolai Haehnle   return ListInit::get(ListInits, T->getElementType());
180884c287e3SPeter Collingbourne }
180984c287e3SPeter Collingbourne 
181084c287e3SPeter Collingbourne 
get(StringRef VN,RecTy * T)18115ce90576SMatthias Braun VarInit *VarInit::get(StringRef VN, RecTy *T) {
18122ac3cd20SRiver Riddle   Init *Value = StringInit::get(T->getRecordKeeper(), VN);
1813914adf0eSDavid Greene   return VarInit::get(Value, T);
1814914adf0eSDavid Greene }
1815914adf0eSDavid Greene 
get(Init * VN,RecTy * T)1816914adf0eSDavid Greene VarInit *VarInit::get(Init *VN, RecTy *T) {
18172ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
18182ac3cd20SRiver Riddle   VarInit *&I = RK.TheVarInitPool[std::make_pair(T, VN)];
1819d0edb0dfSMatthias Braun   if (!I)
18202ac3cd20SRiver Riddle     I = new (RK.Allocator) VarInit(VN, T);
1821d0edb0dfSMatthias Braun   return I;
182284c287e3SPeter Collingbourne }
182384c287e3SPeter Collingbourne 
getName() const18244a86d456SMatthias Braun StringRef VarInit::getName() const {
1825ed5a9508SCraig Topper   StringInit *NameString = cast<StringInit>(getNameInit());
1826914adf0eSDavid Greene   return NameString->getValue();
1827914adf0eSDavid Greene }
1828914adf0eSDavid Greene 
getBit(unsigned Bit) const1829026f8333SMichael Liao Init *VarInit::getBit(unsigned Bit) const {
18302ac3cd20SRiver Riddle   if (getType() == BitRecTy::get(getRecordKeeper()))
1831026f8333SMichael Liao     return const_cast<VarInit*>(this);
1832026f8333SMichael Liao   return VarBitInit::get(const_cast<VarInit*>(this), Bit);
183384c287e3SPeter Collingbourne }
183484c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const18350b0eaf7eSNicolai Haehnle Init *VarInit::resolveReferences(Resolver &R) const {
18360b0eaf7eSNicolai Haehnle   if (Init *Val = R.resolve(VarName))
18370b0eaf7eSNicolai Haehnle     return Val;
183884c287e3SPeter Collingbourne   return const_cast<VarInit *>(this);
183984c287e3SPeter Collingbourne }
184084c287e3SPeter Collingbourne 
get(TypedInit * T,unsigned B)184184c287e3SPeter Collingbourne VarBitInit *VarBitInit::get(TypedInit *T, unsigned B) {
18422ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
18432ac3cd20SRiver Riddle   VarBitInit *&I = RK.TheVarBitInitPool[std::make_pair(T, B)];
1844d0edb0dfSMatthias Braun   if (!I)
18452ac3cd20SRiver Riddle     I = new (RK.Allocator) VarBitInit(T, B);
1846d0edb0dfSMatthias Braun   return I;
184784c287e3SPeter Collingbourne }
184884c287e3SPeter Collingbourne 
getAsString() const184984c287e3SPeter Collingbourne std::string VarBitInit::getAsString() const {
185084c287e3SPeter Collingbourne   return TI->getAsString() + "{" + utostr(Bit) + "}";
185184c287e3SPeter Collingbourne }
185284c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const18530b0eaf7eSNicolai Haehnle Init *VarBitInit::resolveReferences(Resolver &R) const {
18540b0eaf7eSNicolai Haehnle   Init *I = TI->resolveReferences(R);
1855026f8333SMichael Liao   if (TI != I)
1856026f8333SMichael Liao     return I->getBit(getBitNum());
1857026f8333SMichael Liao 
185884c287e3SPeter Collingbourne   return const_cast<VarBitInit*>(this);
185984c287e3SPeter Collingbourne }
186084c287e3SPeter Collingbourne 
get(TypedInit * T,unsigned E)18617480efd6SRiver Riddle VarListElementInit *VarListElementInit::get(TypedInit *T, unsigned E) {
18622ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = T->getRecordKeeper().getImpl();
18632ac3cd20SRiver Riddle   VarListElementInit *&I = RK.TheVarListElementInitPool[std::make_pair(T, E)];
18647480efd6SRiver Riddle   if (!I)
18652ac3cd20SRiver Riddle     I = new (RK.Allocator) VarListElementInit(T, E);
1866d0edb0dfSMatthias Braun   return I;
186784c287e3SPeter Collingbourne }
186884c287e3SPeter Collingbourne 
getAsString() const186984c287e3SPeter Collingbourne std::string VarListElementInit::getAsString() const {
187084c287e3SPeter Collingbourne   return TI->getAsString() + "[" + utostr(Element) + "]";
187184c287e3SPeter Collingbourne }
187284c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const18730b0eaf7eSNicolai Haehnle Init *VarListElementInit::resolveReferences(Resolver &R) const {
18740b0eaf7eSNicolai Haehnle   Init *NewTI = TI->resolveReferences(R);
1875801403acSNicolai Haehnle   if (ListInit *List = dyn_cast<ListInit>(NewTI)) {
1876801403acSNicolai Haehnle     // Leave out-of-bounds array references as-is. This can happen without
1877801403acSNicolai Haehnle     // being an error, e.g. in the untaken "branch" of an !if expression.
1878801403acSNicolai Haehnle     if (getElementNum() < List->size())
1879801403acSNicolai Haehnle       return List->getElement(getElementNum());
1880801403acSNicolai Haehnle   }
1881801403acSNicolai Haehnle   if (NewTI != TI && isa<TypedInit>(NewTI))
1882801403acSNicolai Haehnle     return VarListElementInit::get(cast<TypedInit>(NewTI), getElementNum());
188384c287e3SPeter Collingbourne   return const_cast<VarListElementInit *>(this);
188484c287e3SPeter Collingbourne }
188584c287e3SPeter Collingbourne 
getBit(unsigned Bit) const1886026f8333SMichael Liao Init *VarListElementInit::getBit(unsigned Bit) const {
18872ac3cd20SRiver Riddle   if (getType() == BitRecTy::get(getRecordKeeper()))
1888026f8333SMichael Liao     return const_cast<VarListElementInit*>(this);
1889026f8333SMichael Liao   return VarBitInit::get(const_cast<VarListElementInit*>(this), Bit);
189084c287e3SPeter Collingbourne }
189184c287e3SPeter Collingbourne 
DefInit(Record * D)189213080fd1SNicolai Haehnle DefInit::DefInit(Record *D)
1893420e28c7SNicolai Haehnle     : TypedInit(IK_DefInit, D->getType()), Def(D) {}
189413080fd1SNicolai Haehnle 
get(Record * R)189584c287e3SPeter Collingbourne DefInit *DefInit::get(Record *R) {
189684c287e3SPeter Collingbourne   return R->getDefInit();
189784c287e3SPeter Collingbourne }
189884c287e3SPeter Collingbourne 
convertInitializerTo(RecTy * Ty) const189995819069SCraig Topper Init *DefInit::convertInitializerTo(RecTy *Ty) const {
190095819069SCraig Topper   if (auto *RRT = dyn_cast<RecordRecTy>(Ty))
190113080fd1SNicolai Haehnle     if (getType()->typeIsConvertibleTo(RRT))
190295819069SCraig Topper       return const_cast<DefInit *>(this);
190395819069SCraig Topper   return nullptr;
190495819069SCraig Topper }
190595819069SCraig Topper 
getFieldType(StringInit * FieldName) const19066a441839SMatthias Braun RecTy *DefInit::getFieldType(StringInit *FieldName) const {
190784c287e3SPeter Collingbourne   if (const RecordVal *RV = Def->getValue(FieldName))
190884c287e3SPeter Collingbourne     return RV->getType();
1909011817a0SCraig Topper   return nullptr;
191084c287e3SPeter Collingbourne }
191184c287e3SPeter Collingbourne 
getAsString() const1912adcd0268SBenjamin Kramer std::string DefInit::getAsString() const { return std::string(Def->getName()); }
191384c287e3SPeter Collingbourne 
ProfileVarDefInit(FoldingSetNodeID & ID,Record * Class,ArrayRef<Init * > Args)1914d4c0a5d0SNicolai Haehnle static void ProfileVarDefInit(FoldingSetNodeID &ID,
1915d4c0a5d0SNicolai Haehnle                               Record *Class,
1916d4c0a5d0SNicolai Haehnle                               ArrayRef<Init *> Args) {
1917d4c0a5d0SNicolai Haehnle   ID.AddInteger(Args.size());
1918d4c0a5d0SNicolai Haehnle   ID.AddPointer(Class);
1919d4c0a5d0SNicolai Haehnle 
1920d4c0a5d0SNicolai Haehnle   for (Init *I : Args)
1921d4c0a5d0SNicolai Haehnle     ID.AddPointer(I);
1922d4c0a5d0SNicolai Haehnle }
1923d4c0a5d0SNicolai Haehnle 
VarDefInit(Record * Class,unsigned N)19242ac3cd20SRiver Riddle VarDefInit::VarDefInit(Record *Class, unsigned N)
19252ac3cd20SRiver Riddle     : TypedInit(IK_VarDefInit, RecordRecTy::get(Class)), Class(Class),
19262ac3cd20SRiver Riddle       NumArgs(N) {}
19272ac3cd20SRiver Riddle 
get(Record * Class,ArrayRef<Init * > Args)1928d4c0a5d0SNicolai Haehnle VarDefInit *VarDefInit::get(Record *Class, ArrayRef<Init *> Args) {
1929d4c0a5d0SNicolai Haehnle   FoldingSetNodeID ID;
1930d4c0a5d0SNicolai Haehnle   ProfileVarDefInit(ID, Class, Args);
1931d4c0a5d0SNicolai Haehnle 
19322ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = Class->getRecords().getImpl();
1933d4c0a5d0SNicolai Haehnle   void *IP = nullptr;
19342ac3cd20SRiver Riddle   if (VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
1935d4c0a5d0SNicolai Haehnle     return I;
1936d4c0a5d0SNicolai Haehnle 
19372ac3cd20SRiver Riddle   void *Mem = RK.Allocator.Allocate(totalSizeToAlloc<Init *>(Args.size()),
1938d4c0a5d0SNicolai Haehnle                                     alignof(VarDefInit));
1939d4c0a5d0SNicolai Haehnle   VarDefInit *I = new (Mem) VarDefInit(Class, Args.size());
1940d4c0a5d0SNicolai Haehnle   std::uninitialized_copy(Args.begin(), Args.end(),
1941d4c0a5d0SNicolai Haehnle                           I->getTrailingObjects<Init *>());
19422ac3cd20SRiver Riddle   RK.TheVarDefInitPool.InsertNode(I, IP);
1943d4c0a5d0SNicolai Haehnle   return I;
1944d4c0a5d0SNicolai Haehnle }
1945d4c0a5d0SNicolai Haehnle 
Profile(FoldingSetNodeID & ID) const1946d4c0a5d0SNicolai Haehnle void VarDefInit::Profile(FoldingSetNodeID &ID) const {
1947d4c0a5d0SNicolai Haehnle   ProfileVarDefInit(ID, Class, args());
1948d4c0a5d0SNicolai Haehnle }
1949d4c0a5d0SNicolai Haehnle 
instantiate()1950d4c0a5d0SNicolai Haehnle DefInit *VarDefInit::instantiate() {
1951d4c0a5d0SNicolai Haehnle   if (!Def) {
1952d4c0a5d0SNicolai Haehnle     RecordKeeper &Records = Class->getRecords();
19530eaee545SJonas Devlieghere     auto NewRecOwner = std::make_unique<Record>(Records.getNewAnonymousName(),
1954d4c0a5d0SNicolai Haehnle                                            Class->getLoc(), Records,
1955d4c0a5d0SNicolai Haehnle                                            /*IsAnonymous=*/true);
1956d4c0a5d0SNicolai Haehnle     Record *NewRec = NewRecOwner.get();
1957d4c0a5d0SNicolai Haehnle 
1958d4c0a5d0SNicolai Haehnle     // Copy values from class to instance
195901d261f1SNicolai Haehnle     for (const RecordVal &Val : Class->getValues())
1960d4c0a5d0SNicolai Haehnle       NewRec->addValue(Val);
1961d4c0a5d0SNicolai Haehnle 
19625f473a04SPaul C. Anagnostopoulos     // Copy assertions from class to instance.
19635f473a04SPaul C. Anagnostopoulos     NewRec->appendAssertions(Class);
19645f473a04SPaul C. Anagnostopoulos 
1965d4c0a5d0SNicolai Haehnle     // Substitute and resolve template arguments
1966d4c0a5d0SNicolai Haehnle     ArrayRef<Init *> TArgs = Class->getTemplateArgs();
1967d4c0a5d0SNicolai Haehnle     MapResolver R(NewRec);
1968d4c0a5d0SNicolai Haehnle 
1969d4c0a5d0SNicolai Haehnle     for (unsigned i = 0, e = TArgs.size(); i != e; ++i) {
1970d4c0a5d0SNicolai Haehnle       if (i < args_size())
1971d4c0a5d0SNicolai Haehnle         R.set(TArgs[i], getArg(i));
1972d4c0a5d0SNicolai Haehnle       else
1973d4c0a5d0SNicolai Haehnle         R.set(TArgs[i], NewRec->getValue(TArgs[i])->getValue());
1974d4c0a5d0SNicolai Haehnle 
1975d4c0a5d0SNicolai Haehnle       NewRec->removeValue(TArgs[i]);
1976d4c0a5d0SNicolai Haehnle     }
1977d4c0a5d0SNicolai Haehnle 
1978d4c0a5d0SNicolai Haehnle     NewRec->resolveReferences(R);
1979d4c0a5d0SNicolai Haehnle 
1980d4c0a5d0SNicolai Haehnle     // Add superclasses.
1981d4c0a5d0SNicolai Haehnle     ArrayRef<std::pair<Record *, SMRange>> SCs = Class->getSuperClasses();
1982d4c0a5d0SNicolai Haehnle     for (const auto &SCPair : SCs)
1983d4c0a5d0SNicolai Haehnle       NewRec->addSuperClass(SCPair.first, SCPair.second);
1984d4c0a5d0SNicolai Haehnle 
1985d4c0a5d0SNicolai Haehnle     NewRec->addSuperClass(Class,
1986d4c0a5d0SNicolai Haehnle                           SMRange(Class->getLoc().back(),
1987d4c0a5d0SNicolai Haehnle                                   Class->getLoc().back()));
1988d4c0a5d0SNicolai Haehnle 
1989d4c0a5d0SNicolai Haehnle     // Resolve internal references and store in record keeper
1990d4c0a5d0SNicolai Haehnle     NewRec->resolveReferences();
1991d4c0a5d0SNicolai Haehnle     Records.addDef(std::move(NewRecOwner));
1992d4c0a5d0SNicolai Haehnle 
19935f473a04SPaul C. Anagnostopoulos     // Check the assertions.
1994a5aaec8fSPaul C. Anagnostopoulos     NewRec->checkRecordAssertions();
19955f473a04SPaul C. Anagnostopoulos 
1996d4c0a5d0SNicolai Haehnle     Def = DefInit::get(NewRec);
1997d4c0a5d0SNicolai Haehnle   }
1998d4c0a5d0SNicolai Haehnle 
1999d4c0a5d0SNicolai Haehnle   return Def;
2000d4c0a5d0SNicolai Haehnle }
2001d4c0a5d0SNicolai Haehnle 
resolveReferences(Resolver & R) const2002d4c0a5d0SNicolai Haehnle Init *VarDefInit::resolveReferences(Resolver &R) const {
2003d4c0a5d0SNicolai Haehnle   TrackUnresolvedResolver UR(&R);
2004d4c0a5d0SNicolai Haehnle   bool Changed = false;
2005d4c0a5d0SNicolai Haehnle   SmallVector<Init *, 8> NewArgs;
2006d4c0a5d0SNicolai Haehnle   NewArgs.reserve(args_size());
2007d4c0a5d0SNicolai Haehnle 
2008d4c0a5d0SNicolai Haehnle   for (Init *Arg : args()) {
2009d4c0a5d0SNicolai Haehnle     Init *NewArg = Arg->resolveReferences(UR);
2010d4c0a5d0SNicolai Haehnle     NewArgs.push_back(NewArg);
2011d4c0a5d0SNicolai Haehnle     Changed |= NewArg != Arg;
2012d4c0a5d0SNicolai Haehnle   }
2013d4c0a5d0SNicolai Haehnle 
2014d4c0a5d0SNicolai Haehnle   if (Changed) {
2015d4c0a5d0SNicolai Haehnle     auto New = VarDefInit::get(Class, NewArgs);
2016d4c0a5d0SNicolai Haehnle     if (!UR.foundUnresolved())
2017d4c0a5d0SNicolai Haehnle       return New->instantiate();
2018d4c0a5d0SNicolai Haehnle     return New;
2019d4c0a5d0SNicolai Haehnle   }
2020d4c0a5d0SNicolai Haehnle   return const_cast<VarDefInit *>(this);
2021d4c0a5d0SNicolai Haehnle }
2022d4c0a5d0SNicolai Haehnle 
Fold() const2023d4c0a5d0SNicolai Haehnle Init *VarDefInit::Fold() const {
2024d4c0a5d0SNicolai Haehnle   if (Def)
2025d4c0a5d0SNicolai Haehnle     return Def;
2026d4c0a5d0SNicolai Haehnle 
2027d4c0a5d0SNicolai Haehnle   TrackUnresolvedResolver R;
2028d4c0a5d0SNicolai Haehnle   for (Init *Arg : args())
2029d4c0a5d0SNicolai Haehnle     Arg->resolveReferences(R);
2030d4c0a5d0SNicolai Haehnle 
2031d4c0a5d0SNicolai Haehnle   if (!R.foundUnresolved())
2032d4c0a5d0SNicolai Haehnle     return const_cast<VarDefInit *>(this)->instantiate();
2033d4c0a5d0SNicolai Haehnle   return const_cast<VarDefInit *>(this);
2034d4c0a5d0SNicolai Haehnle }
2035d4c0a5d0SNicolai Haehnle 
getAsString() const2036d4c0a5d0SNicolai Haehnle std::string VarDefInit::getAsString() const {
2037d4c0a5d0SNicolai Haehnle   std::string Result = Class->getNameInitAsString() + "<";
2038d4c0a5d0SNicolai Haehnle   const char *sep = "";
2039d4c0a5d0SNicolai Haehnle   for (Init *Arg : args()) {
2040d4c0a5d0SNicolai Haehnle     Result += sep;
2041d4c0a5d0SNicolai Haehnle     sep = ", ";
2042d4c0a5d0SNicolai Haehnle     Result += Arg->getAsString();
2043d4c0a5d0SNicolai Haehnle   }
2044d4c0a5d0SNicolai Haehnle   return Result + ">";
2045d4c0a5d0SNicolai Haehnle }
2046d4c0a5d0SNicolai Haehnle 
get(Init * R,StringInit * FN)20476a441839SMatthias Braun FieldInit *FieldInit::get(Init *R, StringInit *FN) {
20482ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = R->getRecordKeeper().getImpl();
20492ac3cd20SRiver Riddle   FieldInit *&I = RK.TheFieldInitPool[std::make_pair(R, FN)];
20507480efd6SRiver Riddle   if (!I)
20512ac3cd20SRiver Riddle     I = new (RK.Allocator) FieldInit(R, FN);
2052d0edb0dfSMatthias Braun   return I;
205384c287e3SPeter Collingbourne }
205484c287e3SPeter Collingbourne 
getBit(unsigned Bit) const2055026f8333SMichael Liao Init *FieldInit::getBit(unsigned Bit) const {
20562ac3cd20SRiver Riddle   if (getType() == BitRecTy::get(getRecordKeeper()))
2057026f8333SMichael Liao     return const_cast<FieldInit*>(this);
2058026f8333SMichael Liao   return VarBitInit::get(const_cast<FieldInit*>(this), Bit);
205984c287e3SPeter Collingbourne }
206084c287e3SPeter Collingbourne 
resolveReferences(Resolver & R) const20610b0eaf7eSNicolai Haehnle Init *FieldInit::resolveReferences(Resolver &R) const {
20620b0eaf7eSNicolai Haehnle   Init *NewRec = Rec->resolveReferences(R);
20638aa9d583SNicolai Haehnle   if (NewRec != Rec)
20642ad19016SNicolai Haehnle     return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord());
20658aa9d583SNicolai Haehnle   return const_cast<FieldInit *>(this);
206684c287e3SPeter Collingbourne }
206784c287e3SPeter Collingbourne 
Fold(Record * CurRec) const20682ad19016SNicolai Haehnle Init *FieldInit::Fold(Record *CurRec) const {
20698aa9d583SNicolai Haehnle   if (DefInit *DI = dyn_cast<DefInit>(Rec)) {
20702ad19016SNicolai Haehnle     Record *Def = DI->getDef();
20712ad19016SNicolai Haehnle     if (Def == CurRec)
20722ad19016SNicolai Haehnle       PrintFatalError(CurRec->getLoc(),
20732ad19016SNicolai Haehnle                       Twine("Attempting to access field '") +
20742ad19016SNicolai Haehnle                       FieldName->getAsUnquotedString() + "' of '" +
20752ad19016SNicolai Haehnle                       Rec->getAsString() + "' is a forbidden self-reference");
20762ad19016SNicolai Haehnle     Init *FieldVal = Def->getValue(FieldName)->getValue();
2077be50657cSDaniel Sanders     if (FieldVal->isConcrete())
20788aa9d583SNicolai Haehnle       return FieldVal;
20798aa9d583SNicolai Haehnle   }
208084c287e3SPeter Collingbourne   return const_cast<FieldInit *>(this);
208184c287e3SPeter Collingbourne }
208284c287e3SPeter Collingbourne 
isConcrete() const208352086f80SRiver Riddle bool FieldInit::isConcrete() const {
208452086f80SRiver Riddle   if (DefInit *DI = dyn_cast<DefInit>(Rec)) {
208552086f80SRiver Riddle     Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
208652086f80SRiver Riddle     return FieldVal->isConcrete();
208752086f80SRiver Riddle   }
208852086f80SRiver Riddle   return false;
208952086f80SRiver Riddle }
209052086f80SRiver Riddle 
ProfileCondOpInit(FoldingSetNodeID & ID,ArrayRef<Init * > CondRange,ArrayRef<Init * > ValRange,const RecTy * ValType)2091a3e3d852SJaved Absar static void ProfileCondOpInit(FoldingSetNodeID &ID,
2092a3e3d852SJaved Absar                              ArrayRef<Init *> CondRange,
2093a3e3d852SJaved Absar                              ArrayRef<Init *> ValRange,
2094a3e3d852SJaved Absar                              const RecTy *ValType) {
2095a3e3d852SJaved Absar   assert(CondRange.size() == ValRange.size() &&
2096a3e3d852SJaved Absar          "Number of conditions and values must match!");
2097a3e3d852SJaved Absar   ID.AddPointer(ValType);
2098a3e3d852SJaved Absar   ArrayRef<Init *>::iterator Case = CondRange.begin();
2099a3e3d852SJaved Absar   ArrayRef<Init *>::iterator Val = ValRange.begin();
2100a3e3d852SJaved Absar 
2101a3e3d852SJaved Absar   while (Case != CondRange.end()) {
2102a3e3d852SJaved Absar     ID.AddPointer(*Case++);
2103a3e3d852SJaved Absar     ID.AddPointer(*Val++);
2104a3e3d852SJaved Absar   }
2105a3e3d852SJaved Absar }
2106a3e3d852SJaved Absar 
Profile(FoldingSetNodeID & ID) const2107a3e3d852SJaved Absar void CondOpInit::Profile(FoldingSetNodeID &ID) const {
2108a3e3d852SJaved Absar   ProfileCondOpInit(ID,
2109a3e3d852SJaved Absar       makeArrayRef(getTrailingObjects<Init *>(), NumConds),
2110a3e3d852SJaved Absar       makeArrayRef(getTrailingObjects<Init *>() + NumConds, NumConds),
2111a3e3d852SJaved Absar       ValType);
2112a3e3d852SJaved Absar }
2113a3e3d852SJaved Absar 
get(ArrayRef<Init * > CondRange,ArrayRef<Init * > ValRange,RecTy * Ty)21142ac3cd20SRiver Riddle CondOpInit *CondOpInit::get(ArrayRef<Init *> CondRange,
2115a3e3d852SJaved Absar                             ArrayRef<Init *> ValRange, RecTy *Ty) {
2116a3e3d852SJaved Absar   assert(CondRange.size() == ValRange.size() &&
2117a3e3d852SJaved Absar          "Number of conditions and values must match!");
2118a3e3d852SJaved Absar 
2119a3e3d852SJaved Absar   FoldingSetNodeID ID;
2120a3e3d852SJaved Absar   ProfileCondOpInit(ID, CondRange, ValRange, Ty);
2121a3e3d852SJaved Absar 
21222ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = Ty->getRecordKeeper().getImpl();
2123a3e3d852SJaved Absar   void *IP = nullptr;
21242ac3cd20SRiver Riddle   if (CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
2125a3e3d852SJaved Absar     return I;
2126a3e3d852SJaved Absar 
21272ac3cd20SRiver Riddle   void *Mem = RK.Allocator.Allocate(
21287480efd6SRiver Riddle       totalSizeToAlloc<Init *>(2 * CondRange.size()), alignof(BitsInit));
2129a3e3d852SJaved Absar   CondOpInit *I = new(Mem) CondOpInit(CondRange.size(), Ty);
2130a3e3d852SJaved Absar 
2131a3e3d852SJaved Absar   std::uninitialized_copy(CondRange.begin(), CondRange.end(),
2132a3e3d852SJaved Absar                           I->getTrailingObjects<Init *>());
2133a3e3d852SJaved Absar   std::uninitialized_copy(ValRange.begin(), ValRange.end(),
2134a3e3d852SJaved Absar                           I->getTrailingObjects<Init *>()+CondRange.size());
21352ac3cd20SRiver Riddle   RK.TheCondOpInitPool.InsertNode(I, IP);
2136a3e3d852SJaved Absar   return I;
2137a3e3d852SJaved Absar }
2138a3e3d852SJaved Absar 
resolveReferences(Resolver & R) const2139a3e3d852SJaved Absar Init *CondOpInit::resolveReferences(Resolver &R) const {
2140a3e3d852SJaved Absar   SmallVector<Init*, 4> NewConds;
2141a3e3d852SJaved Absar   bool Changed = false;
2142a3e3d852SJaved Absar   for (const Init *Case : getConds()) {
2143a3e3d852SJaved Absar     Init *NewCase = Case->resolveReferences(R);
2144a3e3d852SJaved Absar     NewConds.push_back(NewCase);
2145a3e3d852SJaved Absar     Changed |= NewCase != Case;
2146a3e3d852SJaved Absar   }
2147a3e3d852SJaved Absar 
2148a3e3d852SJaved Absar   SmallVector<Init*, 4> NewVals;
2149a3e3d852SJaved Absar   for (const Init *Val : getVals()) {
2150a3e3d852SJaved Absar     Init *NewVal = Val->resolveReferences(R);
2151a3e3d852SJaved Absar     NewVals.push_back(NewVal);
2152a3e3d852SJaved Absar     Changed |= NewVal != Val;
2153a3e3d852SJaved Absar   }
2154a3e3d852SJaved Absar 
2155a3e3d852SJaved Absar   if (Changed)
2156a3e3d852SJaved Absar     return (CondOpInit::get(NewConds, NewVals,
2157a3e3d852SJaved Absar             getValType()))->Fold(R.getCurrentRecord());
2158a3e3d852SJaved Absar 
2159a3e3d852SJaved Absar   return const_cast<CondOpInit *>(this);
2160a3e3d852SJaved Absar }
2161a3e3d852SJaved Absar 
Fold(Record * CurRec) const2162a3e3d852SJaved Absar Init *CondOpInit::Fold(Record *CurRec) const {
21632ac3cd20SRiver Riddle   RecordKeeper &RK = getRecordKeeper();
2164a3e3d852SJaved Absar   for ( unsigned i = 0; i < NumConds; ++i) {
2165a3e3d852SJaved Absar     Init *Cond = getCond(i);
2166a3e3d852SJaved Absar     Init *Val = getVal(i);
2167a3e3d852SJaved Absar 
2168a3e3d852SJaved Absar     if (IntInit *CondI = dyn_cast_or_null<IntInit>(
21692ac3cd20SRiver Riddle             Cond->convertInitializerTo(IntRecTy::get(RK)))) {
2170a3e3d852SJaved Absar       if (CondI->getValue())
2171a3e3d852SJaved Absar         return Val->convertInitializerTo(getValType());
21722ac3cd20SRiver Riddle     } else {
2173a3e3d852SJaved Absar       return const_cast<CondOpInit *>(this);
2174a3e3d852SJaved Absar     }
21752ac3cd20SRiver Riddle   }
2176a3e3d852SJaved Absar 
2177a3e3d852SJaved Absar   PrintFatalError(CurRec->getLoc(),
2178a3e3d852SJaved Absar                   CurRec->getName() +
2179a3e3d852SJaved Absar                   " does not have any true condition in:" +
2180a3e3d852SJaved Absar                   this->getAsString());
2181a3e3d852SJaved Absar   return nullptr;
2182a3e3d852SJaved Absar }
2183a3e3d852SJaved Absar 
isConcrete() const2184a3e3d852SJaved Absar bool CondOpInit::isConcrete() const {
2185a3e3d852SJaved Absar   for (const Init *Case : getConds())
2186a3e3d852SJaved Absar     if (!Case->isConcrete())
2187a3e3d852SJaved Absar       return false;
2188a3e3d852SJaved Absar 
2189a3e3d852SJaved Absar   for (const Init *Val : getVals())
2190a3e3d852SJaved Absar     if (!Val->isConcrete())
2191a3e3d852SJaved Absar       return false;
2192a3e3d852SJaved Absar 
2193a3e3d852SJaved Absar   return true;
2194a3e3d852SJaved Absar }
2195a3e3d852SJaved Absar 
isComplete() const2196a3e3d852SJaved Absar bool CondOpInit::isComplete() const {
2197a3e3d852SJaved Absar   for (const Init *Case : getConds())
2198a3e3d852SJaved Absar     if (!Case->isComplete())
2199a3e3d852SJaved Absar       return false;
2200a3e3d852SJaved Absar 
2201a3e3d852SJaved Absar   for (const Init *Val : getVals())
2202a3e3d852SJaved Absar     if (!Val->isConcrete())
2203a3e3d852SJaved Absar       return false;
2204a3e3d852SJaved Absar 
2205a3e3d852SJaved Absar   return true;
2206a3e3d852SJaved Absar }
2207a3e3d852SJaved Absar 
getAsString() const2208a3e3d852SJaved Absar std::string CondOpInit::getAsString() const {
2209a3e3d852SJaved Absar   std::string Result = "!cond(";
2210a3e3d852SJaved Absar   for (unsigned i = 0; i < getNumConds(); i++) {
2211a3e3d852SJaved Absar     Result += getCond(i)->getAsString() + ": ";
2212a3e3d852SJaved Absar     Result += getVal(i)->getAsString();
2213a3e3d852SJaved Absar     if (i != getNumConds()-1)
2214a3e3d852SJaved Absar       Result += ", ";
2215a3e3d852SJaved Absar   }
2216a3e3d852SJaved Absar   return Result + ")";
2217a3e3d852SJaved Absar }
2218a3e3d852SJaved Absar 
getBit(unsigned Bit) const2219a3e3d852SJaved Absar Init *CondOpInit::getBit(unsigned Bit) const {
2220a3e3d852SJaved Absar   return VarBitInit::get(const_cast<CondOpInit *>(this), Bit);
2221a3e3d852SJaved Absar }
2222a3e3d852SJaved Absar 
ProfileDagInit(FoldingSetNodeID & ID,Init * V,StringInit * VN,ArrayRef<Init * > ArgRange,ArrayRef<StringInit * > NameRange)22237cf3b112SMatthias Braun static void ProfileDagInit(FoldingSetNodeID &ID, Init *V, StringInit *VN,
222484c287e3SPeter Collingbourne                            ArrayRef<Init *> ArgRange,
2225bb053164SMatthias Braun                            ArrayRef<StringInit *> NameRange) {
222684c287e3SPeter Collingbourne   ID.AddPointer(V);
22277cf3b112SMatthias Braun   ID.AddPointer(VN);
222884c287e3SPeter Collingbourne 
222984c287e3SPeter Collingbourne   ArrayRef<Init *>::iterator Arg = ArgRange.begin();
2230bb053164SMatthias Braun   ArrayRef<StringInit *>::iterator Name = NameRange.begin();
223184c287e3SPeter Collingbourne   while (Arg != ArgRange.end()) {
223284c287e3SPeter Collingbourne     assert(Name != NameRange.end() && "Arg name underflow!");
223384c287e3SPeter Collingbourne     ID.AddPointer(*Arg++);
2234bb053164SMatthias Braun     ID.AddPointer(*Name++);
223584c287e3SPeter Collingbourne   }
223684c287e3SPeter Collingbourne   assert(Name == NameRange.end() && "Arg name overflow!");
223784c287e3SPeter Collingbourne }
223884c287e3SPeter Collingbourne 
get(Init * V,StringInit * VN,ArrayRef<Init * > ArgRange,ArrayRef<StringInit * > NameRange)22397480efd6SRiver Riddle DagInit *DagInit::get(Init *V, StringInit *VN, ArrayRef<Init *> ArgRange,
2240bb053164SMatthias Braun                       ArrayRef<StringInit *> NameRange) {
224184c287e3SPeter Collingbourne   FoldingSetNodeID ID;
224284c287e3SPeter Collingbourne   ProfileDagInit(ID, V, VN, ArgRange, NameRange);
224384c287e3SPeter Collingbourne 
22442ac3cd20SRiver Riddle   detail::RecordKeeperImpl &RK = V->getRecordKeeper().getImpl();
2245011817a0SCraig Topper   void *IP = nullptr;
22462ac3cd20SRiver Riddle   if (DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP))
224784c287e3SPeter Collingbourne     return I;
224884c287e3SPeter Collingbourne 
22492ac3cd20SRiver Riddle   void *Mem = RK.Allocator.Allocate(
22507480efd6SRiver Riddle       totalSizeToAlloc<Init *, StringInit *>(ArgRange.size(), NameRange.size()),
22517480efd6SRiver Riddle       alignof(BitsInit));
2252a568c72bSCraig Topper   DagInit *I = new (Mem) DagInit(V, VN, ArgRange.size(), NameRange.size());
2253a568c72bSCraig Topper   std::uninitialized_copy(ArgRange.begin(), ArgRange.end(),
2254a568c72bSCraig Topper                           I->getTrailingObjects<Init *>());
2255a568c72bSCraig Topper   std::uninitialized_copy(NameRange.begin(), NameRange.end(),
2256a568c72bSCraig Topper                           I->getTrailingObjects<StringInit *>());
22572ac3cd20SRiver Riddle   RK.TheDagInitPool.InsertNode(I, IP);
225884c287e3SPeter Collingbourne   return I;
225984c287e3SPeter Collingbourne }
226084c287e3SPeter Collingbourne 
226184c287e3SPeter Collingbourne DagInit *
get(Init * V,StringInit * VN,ArrayRef<std::pair<Init *,StringInit * >> args)22627cf3b112SMatthias Braun DagInit::get(Init *V, StringInit *VN,
22631ddb78cdSMatthias Braun              ArrayRef<std::pair<Init*, StringInit*>> args) {
22641ddb78cdSMatthias Braun   SmallVector<Init *, 8> Args;
22651ddb78cdSMatthias Braun   SmallVector<StringInit *, 8> Names;
226684c287e3SPeter Collingbourne 
2267119998dbSCraig Topper   for (const auto &Arg : args) {
2268119998dbSCraig Topper     Args.push_back(Arg.first);
2269119998dbSCraig Topper     Names.push_back(Arg.second);
227084c287e3SPeter Collingbourne   }
227184c287e3SPeter Collingbourne 
227284c287e3SPeter Collingbourne   return DagInit::get(V, VN, Args, Names);
227384c287e3SPeter Collingbourne }
227484c287e3SPeter Collingbourne 
Profile(FoldingSetNodeID & ID) const227584c287e3SPeter Collingbourne void DagInit::Profile(FoldingSetNodeID &ID) const {
2276a568c72bSCraig Topper   ProfileDagInit(ID, Val, ValName, makeArrayRef(getTrailingObjects<Init *>(), NumArgs), makeArrayRef(getTrailingObjects<StringInit *>(), NumArgNames));
227784c287e3SPeter Collingbourne }
227884c287e3SPeter Collingbourne 
getOperatorAsDef(ArrayRef<SMLoc> Loc) const22794b7cabf1SDaniel Sanders Record *DagInit::getOperatorAsDef(ArrayRef<SMLoc> Loc) const {
22804b7cabf1SDaniel Sanders   if (DefInit *DefI = dyn_cast<DefInit>(Val))
22814b7cabf1SDaniel Sanders     return DefI->getDef();
22824b7cabf1SDaniel Sanders   PrintFatalError(Loc, "Expected record as operator");
22834b7cabf1SDaniel Sanders   return nullptr;
22844b7cabf1SDaniel Sanders }
22854b7cabf1SDaniel Sanders 
resolveReferences(Resolver & R) const22860b0eaf7eSNicolai Haehnle Init *DagInit::resolveReferences(Resolver &R) const {
22871ddb78cdSMatthias Braun   SmallVector<Init*, 8> NewArgs;
2288a568c72bSCraig Topper   NewArgs.reserve(arg_size());
22891ddb78cdSMatthias Braun   bool ArgsChanged = false;
2290481ff708SCraig Topper   for (const Init *Arg : getArgs()) {
22910b0eaf7eSNicolai Haehnle     Init *NewArg = Arg->resolveReferences(R);
22921ddb78cdSMatthias Braun     NewArgs.push_back(NewArg);
22931ddb78cdSMatthias Braun     ArgsChanged |= NewArg != Arg;
22941ddb78cdSMatthias Braun   }
229584c287e3SPeter Collingbourne 
22960b0eaf7eSNicolai Haehnle   Init *Op = Val->resolveReferences(R);
22971ddb78cdSMatthias Braun   if (Op != Val || ArgsChanged)
2298a568c72bSCraig Topper     return DagInit::get(Op, ValName, NewArgs, getArgNames());
229984c287e3SPeter Collingbourne 
230084c287e3SPeter Collingbourne   return const_cast<DagInit *>(this);
230184c287e3SPeter Collingbourne }
230284c287e3SPeter Collingbourne 
isConcrete() const23030f529885SNicolai Haehnle bool DagInit::isConcrete() const {
23040f529885SNicolai Haehnle   if (!Val->isConcrete())
23050f529885SNicolai Haehnle     return false;
23060f529885SNicolai Haehnle   for (const Init *Elt : getArgs()) {
23070f529885SNicolai Haehnle     if (!Elt->isConcrete())
23080f529885SNicolai Haehnle       return false;
23090f529885SNicolai Haehnle   }
23100f529885SNicolai Haehnle   return true;
23110f529885SNicolai Haehnle }
23120f529885SNicolai Haehnle 
getAsString() const231384c287e3SPeter Collingbourne std::string DagInit::getAsString() const {
231484c287e3SPeter Collingbourne   std::string Result = "(" + Val->getAsString();
23157cf3b112SMatthias Braun   if (ValName)
23167cf3b112SMatthias Braun     Result += ":" + ValName->getAsUnquotedString();
2317a568c72bSCraig Topper   if (!arg_empty()) {
2318a568c72bSCraig Topper     Result += " " + getArg(0)->getAsString();
2319a568c72bSCraig Topper     if (getArgName(0)) Result += ":$" + getArgName(0)->getAsUnquotedString();
2320a568c72bSCraig Topper     for (unsigned i = 1, e = getNumArgs(); i != e; ++i) {
2321a568c72bSCraig Topper       Result += ", " + getArg(i)->getAsString();
2322a568c72bSCraig Topper       if (getArgName(i)) Result += ":$" + getArgName(i)->getAsUnquotedString();
232384c287e3SPeter Collingbourne     }
232484c287e3SPeter Collingbourne   }
232584c287e3SPeter Collingbourne   return Result + ")";
232684c287e3SPeter Collingbourne }
232784c287e3SPeter Collingbourne 
232884c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
232984c287e3SPeter Collingbourne //    Other implementations
233084c287e3SPeter Collingbourne //===----------------------------------------------------------------------===//
233184c287e3SPeter Collingbourne 
RecordVal(Init * N,RecTy * T,FieldKind K)2332aa7968a8SPaul C. Anagnostopoulos RecordVal::RecordVal(Init *N, RecTy *T, FieldKind K)
2333aa7968a8SPaul C. Anagnostopoulos     : Name(N), TyAndKind(T, K) {
23342ac3cd20SRiver Riddle   setValue(UnsetInit::get(N->getRecordKeeper()));
233584c287e3SPeter Collingbourne   assert(Value && "Cannot create unset value for current type!");
233684c287e3SPeter Collingbourne }
233784c287e3SPeter Collingbourne 
2338b3931188SPaul C. Anagnostopoulos // This constructor accepts the same arguments as the above, but also
2339b3931188SPaul C. Anagnostopoulos // a source location.
RecordVal(Init * N,SMLoc Loc,RecTy * T,FieldKind K)2340aa7968a8SPaul C. Anagnostopoulos RecordVal::RecordVal(Init *N, SMLoc Loc, RecTy *T, FieldKind K)
2341aa7968a8SPaul C. Anagnostopoulos     : Name(N), Loc(Loc), TyAndKind(T, K) {
23422ac3cd20SRiver Riddle   setValue(UnsetInit::get(N->getRecordKeeper()));
2343b3931188SPaul C. Anagnostopoulos   assert(Value && "Cannot create unset value for current type!");
2344b3931188SPaul C. Anagnostopoulos }
2345b3931188SPaul C. Anagnostopoulos 
getName() const23464a86d456SMatthias Braun StringRef RecordVal::getName() const {
2347b849203cSCraig Topper   return cast<StringInit>(getNameInit())->getValue();
234884c287e3SPeter Collingbourne }
234984c287e3SPeter Collingbourne 
getPrintType() const2350415fab6fSPaul C. Anagnostopoulos std::string RecordVal::getPrintType() const {
23512ac3cd20SRiver Riddle   if (getType() == StringRecTy::get(getRecordKeeper())) {
2352415fab6fSPaul C. Anagnostopoulos     if (auto *StrInit = dyn_cast<StringInit>(Value)) {
2353415fab6fSPaul C. Anagnostopoulos       if (StrInit->hasCodeFormat())
2354415fab6fSPaul C. Anagnostopoulos         return "code";
2355415fab6fSPaul C. Anagnostopoulos       else
2356415fab6fSPaul C. Anagnostopoulos         return "string";
2357415fab6fSPaul C. Anagnostopoulos     } else {
2358415fab6fSPaul C. Anagnostopoulos       return "string";
2359415fab6fSPaul C. Anagnostopoulos     }
2360415fab6fSPaul C. Anagnostopoulos   } else {
2361aa7968a8SPaul C. Anagnostopoulos     return TyAndKind.getPointer()->getAsString();
2362415fab6fSPaul C. Anagnostopoulos   }
2363415fab6fSPaul C. Anagnostopoulos }
2364415fab6fSPaul C. Anagnostopoulos 
setValue(Init * V)2365dfda9dccSNicolai Haehnle bool RecordVal::setValue(Init *V) {
2366dfda9dccSNicolai Haehnle   if (V) {
2367dfda9dccSNicolai Haehnle     Value = V->getCastTo(getType());
2368dfda9dccSNicolai Haehnle     if (Value) {
2369dfda9dccSNicolai Haehnle       assert(!isa<TypedInit>(Value) ||
2370dfda9dccSNicolai Haehnle              cast<TypedInit>(Value)->getType()->typeIsA(getType()));
2371dfda9dccSNicolai Haehnle       if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
2372dfda9dccSNicolai Haehnle         if (!isa<BitsInit>(Value)) {
2373dfda9dccSNicolai Haehnle           SmallVector<Init *, 64> Bits;
2374dfda9dccSNicolai Haehnle           Bits.reserve(BTy->getNumBits());
2375b3931188SPaul C. Anagnostopoulos           for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
2376b3931188SPaul C. Anagnostopoulos             Bits.push_back(Value->getBit(I));
23772ac3cd20SRiver Riddle           Value = BitsInit::get(V->getRecordKeeper(), Bits);
2378dfda9dccSNicolai Haehnle         }
2379dfda9dccSNicolai Haehnle       }
2380dfda9dccSNicolai Haehnle     }
2381dfda9dccSNicolai Haehnle     return Value == nullptr;
2382dfda9dccSNicolai Haehnle   }
2383dfda9dccSNicolai Haehnle   Value = nullptr;
2384dfda9dccSNicolai Haehnle   return false;
2385dfda9dccSNicolai Haehnle }
2386dfda9dccSNicolai Haehnle 
2387b23e84ffSPaul C. Anagnostopoulos // This version of setValue takes a source location and resets the
2388b3931188SPaul C. Anagnostopoulos // location in the RecordVal.
setValue(Init * V,SMLoc NewLoc)2389b3931188SPaul C. Anagnostopoulos bool RecordVal::setValue(Init *V, SMLoc NewLoc) {
2390b3931188SPaul C. Anagnostopoulos   Loc = NewLoc;
2391b3931188SPaul C. Anagnostopoulos   if (V) {
2392b3931188SPaul C. Anagnostopoulos     Value = V->getCastTo(getType());
2393b3931188SPaul C. Anagnostopoulos     if (Value) {
2394b3931188SPaul C. Anagnostopoulos       assert(!isa<TypedInit>(Value) ||
2395b3931188SPaul C. Anagnostopoulos              cast<TypedInit>(Value)->getType()->typeIsA(getType()));
2396b3931188SPaul C. Anagnostopoulos       if (BitsRecTy *BTy = dyn_cast<BitsRecTy>(getType())) {
2397b3931188SPaul C. Anagnostopoulos         if (!isa<BitsInit>(Value)) {
2398b3931188SPaul C. Anagnostopoulos           SmallVector<Init *, 64> Bits;
2399b3931188SPaul C. Anagnostopoulos           Bits.reserve(BTy->getNumBits());
2400b3931188SPaul C. Anagnostopoulos           for (unsigned I = 0, E = BTy->getNumBits(); I < E; ++I)
2401b3931188SPaul C. Anagnostopoulos             Bits.push_back(Value->getBit(I));
24022ac3cd20SRiver Riddle           Value = BitsInit::get(getRecordKeeper(), Bits);
2403b3931188SPaul C. Anagnostopoulos         }
2404b3931188SPaul C. Anagnostopoulos       }
2405b3931188SPaul C. Anagnostopoulos     }
2406b3931188SPaul C. Anagnostopoulos     return Value == nullptr;
2407b3931188SPaul C. Anagnostopoulos   }
2408b3931188SPaul C. Anagnostopoulos   Value = nullptr;
2409b3931188SPaul C. Anagnostopoulos   return false;
2410b3931188SPaul C. Anagnostopoulos }
2411b3931188SPaul C. Anagnostopoulos 
2412615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
241392f49b89Sserge-sans-paille #include "llvm/TableGen/Record.h"
dump() const2414eb2a2546SYaron Keren LLVM_DUMP_METHOD void RecordVal::dump() const { errs() << *this; }
24158c209aa8SMatthias Braun #endif
241684c287e3SPeter Collingbourne 
print(raw_ostream & OS,bool PrintSem) const241784c287e3SPeter Collingbourne void RecordVal::print(raw_ostream &OS, bool PrintSem) const {
2418aa7968a8SPaul C. Anagnostopoulos   if (isNonconcreteOK()) OS << "field ";
2419415fab6fSPaul C. Anagnostopoulos   OS << getPrintType() << " " << getNameInitAsString();
242084c287e3SPeter Collingbourne 
242184c287e3SPeter Collingbourne   if (getValue())
242284c287e3SPeter Collingbourne     OS << " = " << *getValue();
242384c287e3SPeter Collingbourne 
242484c287e3SPeter Collingbourne   if (PrintSem) OS << ";\n";
242584c287e3SPeter Collingbourne }
242684c287e3SPeter Collingbourne 
updateClassLoc(SMLoc Loc)2427*394a388dSRoman Rusyaev void Record::updateClassLoc(SMLoc Loc) {
2428*394a388dSRoman Rusyaev   assert(Locs.size() == 1);
2429*394a388dSRoman Rusyaev   ForwardDeclarationLocs.push_back(Locs.front());
2430*394a388dSRoman Rusyaev 
2431*394a388dSRoman Rusyaev   Locs.clear();
2432*394a388dSRoman Rusyaev   Locs.push_back(Loc);
2433*394a388dSRoman Rusyaev }
2434*394a388dSRoman Rusyaev 
checkName()243584c287e3SPeter Collingbourne void Record::checkName() {
243684c287e3SPeter Collingbourne   // Ensure the record name has string type.
2437ed5a9508SCraig Topper   const TypedInit *TypedName = cast<const TypedInit>(Name);
24385a2dfdcdSCraig Topper   if (!isa<StringRecTy>(TypedName->getType()))
2439420e28c7SNicolai Haehnle     PrintFatalError(getLoc(), Twine("Record name '") + Name->getAsString() +
2440420e28c7SNicolai Haehnle                                   "' is not a string!");
2441420e28c7SNicolai Haehnle }
2442420e28c7SNicolai Haehnle 
getType()2443420e28c7SNicolai Haehnle RecordRecTy *Record::getType() {
2444420e28c7SNicolai Haehnle   SmallVector<Record *, 4> DirectSCs;
2445420e28c7SNicolai Haehnle   getDirectSuperClasses(DirectSCs);
24462ac3cd20SRiver Riddle   return RecordRecTy::get(TrackedRecords, DirectSCs);
244784c287e3SPeter Collingbourne }
244884c287e3SPeter Collingbourne 
getDefInit()244984c287e3SPeter Collingbourne DefInit *Record::getDefInit() {
24502ac3cd20SRiver Riddle   if (!CorrespondingDefInit) {
24512ac3cd20SRiver Riddle     CorrespondingDefInit =
24522ac3cd20SRiver Riddle         new (TrackedRecords.getImpl().Allocator) DefInit(this);
24532ac3cd20SRiver Riddle   }
245404cebd90SPaul C. Anagnostopoulos   return CorrespondingDefInit;
245584c287e3SPeter Collingbourne }
245684c287e3SPeter Collingbourne 
getNewUID(RecordKeeper & RK)24572ac3cd20SRiver Riddle unsigned Record::getNewUID(RecordKeeper &RK) {
24582ac3cd20SRiver Riddle   return RK.getImpl().LastRecordID++;
24592ac3cd20SRiver Riddle }
24607480efd6SRiver Riddle 
setName(Init * NewName)246184c287e3SPeter Collingbourne void Record::setName(Init *NewName) {
2462f651a2a5SDavid Greene   Name = NewName;
246384c287e3SPeter Collingbourne   checkName();
246484c287e3SPeter Collingbourne   // DO NOT resolve record values to the name at this point because
246584c287e3SPeter Collingbourne   // there might be default values for arguments of this def.  Those
246684c287e3SPeter Collingbourne   // arguments might not have been resolved yet so we don't want to
246784c287e3SPeter Collingbourne   // prematurely assume values for those arguments were not passed to
246884c287e3SPeter Collingbourne   // this def.
246984c287e3SPeter Collingbourne   //
247084c287e3SPeter Collingbourne   // Nonetheless, it may be that some of this Record's values
247184c287e3SPeter Collingbourne   // reference the record name.  Indeed, the reason for having the
247284c287e3SPeter Collingbourne   // record name be an Init is to provide this flexibility.  The extra
247384c287e3SPeter Collingbourne   // resolve steps after completely instantiating defs takes care of
247484c287e3SPeter Collingbourne   // this.  See TGParser::ParseDef and TGParser::ParseDefm.
247584c287e3SPeter Collingbourne }
247684c287e3SPeter Collingbourne 
24770c1bb4f8SPaul C. Anagnostopoulos // NOTE for the next two functions:
2478bd55d5b2SPaul C. Anagnostopoulos // Superclasses are in post-order, so the final one is a direct
2479bd55d5b2SPaul C. Anagnostopoulos // superclass. All of its transitive superclases immediately precede it,
2480bd55d5b2SPaul C. Anagnostopoulos // so we can step through the direct superclasses in reverse order.
24810c1bb4f8SPaul C. Anagnostopoulos 
hasDirectSuperClass(const Record * Superclass) const24820c1bb4f8SPaul C. Anagnostopoulos bool Record::hasDirectSuperClass(const Record *Superclass) const {
24830c1bb4f8SPaul C. Anagnostopoulos   ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
24840c1bb4f8SPaul C. Anagnostopoulos 
24850c1bb4f8SPaul C. Anagnostopoulos   for (int I = SCs.size() - 1; I >= 0; --I) {
24860c1bb4f8SPaul C. Anagnostopoulos     const Record *SC = SCs[I].first;
24870c1bb4f8SPaul C. Anagnostopoulos     if (SC == Superclass)
24880c1bb4f8SPaul C. Anagnostopoulos       return true;
24890c1bb4f8SPaul C. Anagnostopoulos     I -= SC->getSuperClasses().size();
24900c1bb4f8SPaul C. Anagnostopoulos   }
24910c1bb4f8SPaul C. Anagnostopoulos 
24920c1bb4f8SPaul C. Anagnostopoulos   return false;
24930c1bb4f8SPaul C. Anagnostopoulos }
24940c1bb4f8SPaul C. Anagnostopoulos 
getDirectSuperClasses(SmallVectorImpl<Record * > & Classes) const24950c1bb4f8SPaul C. Anagnostopoulos void Record::getDirectSuperClasses(SmallVectorImpl<Record *> &Classes) const {
24960c1bb4f8SPaul C. Anagnostopoulos   ArrayRef<std::pair<Record *, SMRange>> SCs = getSuperClasses();
24970c1bb4f8SPaul C. Anagnostopoulos 
249813080fd1SNicolai Haehnle   while (!SCs.empty()) {
249913080fd1SNicolai Haehnle     Record *SC = SCs.back().first;
250013080fd1SNicolai Haehnle     SCs = SCs.drop_back(1 + SC->getSuperClasses().size());
250113080fd1SNicolai Haehnle     Classes.push_back(SC);
250213080fd1SNicolai Haehnle   }
250313080fd1SNicolai Haehnle }
250413080fd1SNicolai Haehnle 
resolveReferences(Resolver & R,const RecordVal * SkipVal)2505b0cf9e93SNicolai Haehnle void Record::resolveReferences(Resolver &R, const RecordVal *SkipVal) {
2506267b573bSJ-Y You   Init *OldName = getNameInit();
2507267b573bSJ-Y You   Init *NewName = Name->resolveReferences(R);
2508267b573bSJ-Y You   if (NewName != OldName) {
2509267b573bSJ-Y You     // Re-register with RecordKeeper.
2510267b573bSJ-Y You     setName(NewName);
2511267b573bSJ-Y You   }
25125f473a04SPaul C. Anagnostopoulos 
25135f473a04SPaul C. Anagnostopoulos   // Resolve the field values.
2514ca151317SMatthias Braun   for (RecordVal &Value : Values) {
2515b0cf9e93SNicolai Haehnle     if (SkipVal == &Value) // Skip resolve the same field as the given one
2516aa0f752fSJakob Stoklund Olesen       continue;
2517b0cf9e93SNicolai Haehnle     if (Init *V = Value.getValue()) {
2518b0cf9e93SNicolai Haehnle       Init *VR = V->resolveReferences(R);
251964da6990SNicolai Haehnle       if (Value.setValue(VR)) {
252064da6990SNicolai Haehnle         std::string Type;
252164da6990SNicolai Haehnle         if (TypedInit *VRT = dyn_cast<TypedInit>(VR))
252264da6990SNicolai Haehnle           Type =
252364da6990SNicolai Haehnle               (Twine("of type '") + VRT->getType()->getAsString() + "' ").str();
2524a9fc44c5SPaul C. Anagnostopoulos         PrintFatalError(
2525a9fc44c5SPaul C. Anagnostopoulos             getLoc(),
2526a9fc44c5SPaul C. Anagnostopoulos             Twine("Invalid value ") + Type + "found when setting field '" +
2527a9fc44c5SPaul C. Anagnostopoulos                 Value.getNameInitAsString() + "' of type '" +
252864da6990SNicolai Haehnle                 Value.getType()->getAsString() +
2529a9fc44c5SPaul C. Anagnostopoulos                 "' after resolving references: " + VR->getAsUnquotedString() +
2530a9fc44c5SPaul C. Anagnostopoulos                 "\n");
2531b0cf9e93SNicolai Haehnle       }
253284c287e3SPeter Collingbourne     }
253364da6990SNicolai Haehnle   }
25345f473a04SPaul C. Anagnostopoulos 
25355f473a04SPaul C. Anagnostopoulos   // Resolve the assertion expressions.
25365f473a04SPaul C. Anagnostopoulos   for (auto &Assertion : Assertions) {
25372d4c4d3cSPaul C. Anagnostopoulos     Init *Value = Assertion.Condition->resolveReferences(R);
25382d4c4d3cSPaul C. Anagnostopoulos     Assertion.Condition = Value;
25392d4c4d3cSPaul C. Anagnostopoulos     Value = Assertion.Message->resolveReferences(R);
25402d4c4d3cSPaul C. Anagnostopoulos     Assertion.Message = Value;
25415f473a04SPaul C. Anagnostopoulos   }
254284c287e3SPeter Collingbourne }
254384c287e3SPeter Collingbourne 
resolveReferences(Init * NewName)2544267b573bSJ-Y You void Record::resolveReferences(Init *NewName) {
2545b0cf9e93SNicolai Haehnle   RecordResolver R(*this);
2546267b573bSJ-Y You   R.setName(NewName);
25474186cc7cSNicolai Haehnle   R.setFinal(true);
2548b0cf9e93SNicolai Haehnle   resolveReferences(R);
2549b0cf9e93SNicolai Haehnle }
2550b0cf9e93SNicolai Haehnle 
2551615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2552eb2a2546SYaron Keren LLVM_DUMP_METHOD void Record::dump() const { errs() << *this; }
25538c209aa8SMatthias Braun #endif
255484c287e3SPeter Collingbourne 
operator <<(raw_ostream & OS,const Record & R)255584c287e3SPeter Collingbourne raw_ostream &llvm::operator<<(raw_ostream &OS, const Record &R) {
255698be78aeSDavid Greene   OS << R.getNameInitAsString();
255784c287e3SPeter Collingbourne 
25587ecf8c22SBenjamin Kramer   ArrayRef<Init *> TArgs = R.getTemplateArgs();
255984c287e3SPeter Collingbourne   if (!TArgs.empty()) {
256084c287e3SPeter Collingbourne     OS << "<";
25615ec17246SCraig Topper     bool NeedComma = false;
25625ec17246SCraig Topper     for (const Init *TA : TArgs) {
25635ec17246SCraig Topper       if (NeedComma) OS << ", ";
25645ec17246SCraig Topper       NeedComma = true;
25655ec17246SCraig Topper       const RecordVal *RV = R.getValue(TA);
256684c287e3SPeter Collingbourne       assert(RV && "Template argument record not found??");
256784c287e3SPeter Collingbourne       RV->print(OS, false);
256884c287e3SPeter Collingbourne     }
256984c287e3SPeter Collingbourne     OS << ">";
257084c287e3SPeter Collingbourne   }
257184c287e3SPeter Collingbourne 
257284c287e3SPeter Collingbourne   OS << " {";
25730e41d0b9SCraig Topper   ArrayRef<std::pair<Record *, SMRange>> SC = R.getSuperClasses();
257484c287e3SPeter Collingbourne   if (!SC.empty()) {
257584c287e3SPeter Collingbourne     OS << "\t//";
25760e41d0b9SCraig Topper     for (const auto &SuperPair : SC)
25770e41d0b9SCraig Topper       OS << " " << SuperPair.first->getNameInitAsString();
257884c287e3SPeter Collingbourne   }
257984c287e3SPeter Collingbourne   OS << "\n";
258084c287e3SPeter Collingbourne 
25815ec17246SCraig Topper   for (const RecordVal &Val : R.getValues())
2582aa7968a8SPaul C. Anagnostopoulos     if (Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
25835ec17246SCraig Topper       OS << Val;
25845ec17246SCraig Topper   for (const RecordVal &Val : R.getValues())
2585aa7968a8SPaul C. Anagnostopoulos     if (!Val.isNonconcreteOK() && !R.isTemplateArg(Val.getNameInit()))
25865ec17246SCraig Topper       OS << Val;
258784c287e3SPeter Collingbourne 
258884c287e3SPeter Collingbourne   return OS << "}\n";
258984c287e3SPeter Collingbourne }
259084c287e3SPeter Collingbourne 
getFieldLoc(StringRef FieldName) const2591b23e84ffSPaul C. Anagnostopoulos SMLoc Record::getFieldLoc(StringRef FieldName) const {
2592b23e84ffSPaul C. Anagnostopoulos   const RecordVal *R = getValue(FieldName);
2593b23e84ffSPaul C. Anagnostopoulos   if (!R)
2594b23e84ffSPaul C. Anagnostopoulos     PrintFatalError(getLoc(), "Record `" + getName() +
2595b23e84ffSPaul C. Anagnostopoulos       "' does not have a field named `" + FieldName + "'!\n");
2596b23e84ffSPaul C. Anagnostopoulos   return R->getLoc();
2597b23e84ffSPaul C. Anagnostopoulos }
2598b23e84ffSPaul C. Anagnostopoulos 
getValueInit(StringRef FieldName) const259984c287e3SPeter Collingbourne Init *Record::getValueInit(StringRef FieldName) const {
260084c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2601011817a0SCraig Topper   if (!R || !R->getValue())
2602635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
260348e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
260484c287e3SPeter Collingbourne   return R->getValue();
260584c287e3SPeter Collingbourne }
260684c287e3SPeter Collingbourne 
getValueAsString(StringRef FieldName) const26072b8419a2SCraig Topper StringRef Record::getValueAsString(StringRef FieldName) const {
260876419525SJohn Demme   llvm::Optional<StringRef> S = getValueAsOptionalString(FieldName);
2609a7938c74SKazu Hirata   if (!S)
2610635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
261148e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
2612611ffcf4SKazu Hirata   return S.value();
261376419525SJohn Demme }
2614415fab6fSPaul C. Anagnostopoulos 
261576419525SJohn Demme llvm::Optional<StringRef>
getValueAsOptionalString(StringRef FieldName) const261676419525SJohn Demme Record::getValueAsOptionalString(StringRef FieldName) const {
261776419525SJohn Demme   const RecordVal *R = getValue(FieldName);
261876419525SJohn Demme   if (!R || !R->getValue())
261976419525SJohn Demme     return llvm::Optional<StringRef>();
262076419525SJohn Demme   if (isa<UnsetInit>(R->getValue()))
262176419525SJohn Demme     return llvm::Optional<StringRef>();
262284c287e3SPeter Collingbourne 
2623fb509ed1SSean Silva   if (StringInit *SI = dyn_cast<StringInit>(R->getValue()))
262484c287e3SPeter Collingbourne     return SI->getValue();
262588403d7aSTim Northover 
262676419525SJohn Demme   PrintFatalError(getLoc(),
262776419525SJohn Demme                   "Record `" + getName() + "', ` field `" + FieldName +
262876419525SJohn Demme                       "' exists but does not have a string initializer!");
262976419525SJohn Demme }
263084c287e3SPeter Collingbourne 
getValueAsBitsInit(StringRef FieldName) const263184c287e3SPeter Collingbourne BitsInit *Record::getValueAsBitsInit(StringRef FieldName) const {
263284c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2633011817a0SCraig Topper   if (!R || !R->getValue())
2634635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
263548e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
263684c287e3SPeter Collingbourne 
2637fb509ed1SSean Silva   if (BitsInit *BI = dyn_cast<BitsInit>(R->getValue()))
263884c287e3SPeter Collingbourne     return BI;
2639b3931188SPaul C. Anagnostopoulos   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
2640b3931188SPaul C. Anagnostopoulos                                 "' exists but does not have a bits value");
264184c287e3SPeter Collingbourne }
264284c287e3SPeter Collingbourne 
getValueAsListInit(StringRef FieldName) const264384c287e3SPeter Collingbourne ListInit *Record::getValueAsListInit(StringRef FieldName) const {
264484c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2645011817a0SCraig Topper   if (!R || !R->getValue())
2646635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
264748e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
264884c287e3SPeter Collingbourne 
2649fb509ed1SSean Silva   if (ListInit *LI = dyn_cast<ListInit>(R->getValue()))
265084c287e3SPeter Collingbourne     return LI;
2651b3931188SPaul C. Anagnostopoulos   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" + FieldName +
2652b3931188SPaul C. Anagnostopoulos                                 "' exists but does not have a list value");
265384c287e3SPeter Collingbourne }
265484c287e3SPeter Collingbourne 
265584c287e3SPeter Collingbourne std::vector<Record*>
getValueAsListOfDefs(StringRef FieldName) const265684c287e3SPeter Collingbourne Record::getValueAsListOfDefs(StringRef FieldName) const {
265784c287e3SPeter Collingbourne   ListInit *List = getValueAsListInit(FieldName);
265884c287e3SPeter Collingbourne   std::vector<Record*> Defs;
2659ef0578a8SCraig Topper   for (Init *I : List->getValues()) {
2660ef0578a8SCraig Topper     if (DefInit *DI = dyn_cast<DefInit>(I))
266184c287e3SPeter Collingbourne       Defs.push_back(DI->getDef());
2662a9642b4eSCraig Topper     else
2663635debe8SJoerg Sonnenberger       PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
266448e7e85dSBenjamin Kramer         FieldName + "' list is not entirely DefInit!");
266584c287e3SPeter Collingbourne   }
266684c287e3SPeter Collingbourne   return Defs;
266784c287e3SPeter Collingbourne }
266884c287e3SPeter Collingbourne 
getValueAsInt(StringRef FieldName) const266984c287e3SPeter Collingbourne int64_t Record::getValueAsInt(StringRef FieldName) const {
267084c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2671011817a0SCraig Topper   if (!R || !R->getValue())
2672635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
267348e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
267484c287e3SPeter Collingbourne 
2675fb509ed1SSean Silva   if (IntInit *II = dyn_cast<IntInit>(R->getValue()))
267684c287e3SPeter Collingbourne     return II->getValue();
267764da6990SNicolai Haehnle   PrintFatalError(getLoc(), Twine("Record `") + getName() + "', field `" +
267864da6990SNicolai Haehnle                                 FieldName +
2679b3931188SPaul C. Anagnostopoulos                                 "' exists but does not have an int value: " +
268064da6990SNicolai Haehnle                                 R->getValue()->getAsString());
268184c287e3SPeter Collingbourne }
268284c287e3SPeter Collingbourne 
268384c287e3SPeter Collingbourne std::vector<int64_t>
getValueAsListOfInts(StringRef FieldName) const268484c287e3SPeter Collingbourne Record::getValueAsListOfInts(StringRef FieldName) const {
268584c287e3SPeter Collingbourne   ListInit *List = getValueAsListInit(FieldName);
268684c287e3SPeter Collingbourne   std::vector<int64_t> Ints;
2687ef0578a8SCraig Topper   for (Init *I : List->getValues()) {
2688ef0578a8SCraig Topper     if (IntInit *II = dyn_cast<IntInit>(I))
268984c287e3SPeter Collingbourne       Ints.push_back(II->getValue());
2690a9642b4eSCraig Topper     else
269164da6990SNicolai Haehnle       PrintFatalError(getLoc(),
269264da6990SNicolai Haehnle                       Twine("Record `") + getName() + "', field `" + FieldName +
2693b3931188SPaul C. Anagnostopoulos                           "' exists but does not have a list of ints value: " +
269464da6990SNicolai Haehnle                           I->getAsString());
269584c287e3SPeter Collingbourne   }
269684c287e3SPeter Collingbourne   return Ints;
269784c287e3SPeter Collingbourne }
269884c287e3SPeter Collingbourne 
26992b8419a2SCraig Topper std::vector<StringRef>
getValueAsListOfStrings(StringRef FieldName) const270084c287e3SPeter Collingbourne Record::getValueAsListOfStrings(StringRef FieldName) const {
270184c287e3SPeter Collingbourne   ListInit *List = getValueAsListInit(FieldName);
27022b8419a2SCraig Topper   std::vector<StringRef> Strings;
2703ef0578a8SCraig Topper   for (Init *I : List->getValues()) {
2704ef0578a8SCraig Topper     if (StringInit *SI = dyn_cast<StringInit>(I))
2705ef0578a8SCraig Topper       Strings.push_back(SI->getValue());
2706a9642b4eSCraig Topper     else
270764da6990SNicolai Haehnle       PrintFatalError(getLoc(),
270864da6990SNicolai Haehnle                       Twine("Record `") + getName() + "', field `" + FieldName +
2709b3931188SPaul C. Anagnostopoulos                           "' exists but does not have a list of strings value: " +
271064da6990SNicolai Haehnle                           I->getAsString());
271184c287e3SPeter Collingbourne   }
271284c287e3SPeter Collingbourne   return Strings;
271384c287e3SPeter Collingbourne }
271484c287e3SPeter Collingbourne 
getValueAsDef(StringRef FieldName) const271584c287e3SPeter Collingbourne Record *Record::getValueAsDef(StringRef FieldName) const {
271684c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2717011817a0SCraig Topper   if (!R || !R->getValue())
2718635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
271948e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
272084c287e3SPeter Collingbourne 
2721fb509ed1SSean Silva   if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
272284c287e3SPeter Collingbourne     return DI->getDef();
2723635debe8SJoerg Sonnenberger   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
272448e7e85dSBenjamin Kramer     FieldName + "' does not have a def initializer!");
272584c287e3SPeter Collingbourne }
272684c287e3SPeter Collingbourne 
getValueAsOptionalDef(StringRef FieldName) const272727e2c8faSJohn McCall Record *Record::getValueAsOptionalDef(StringRef FieldName) const {
272827e2c8faSJohn McCall   const RecordVal *R = getValue(FieldName);
272927e2c8faSJohn McCall   if (!R || !R->getValue())
273027e2c8faSJohn McCall     PrintFatalError(getLoc(), "Record `" + getName() +
273127e2c8faSJohn McCall       "' does not have a field named `" + FieldName + "'!\n");
273227e2c8faSJohn McCall 
273327e2c8faSJohn McCall   if (DefInit *DI = dyn_cast<DefInit>(R->getValue()))
273427e2c8faSJohn McCall     return DI->getDef();
273527e2c8faSJohn McCall   if (isa<UnsetInit>(R->getValue()))
273627e2c8faSJohn McCall     return nullptr;
273727e2c8faSJohn McCall   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
273827e2c8faSJohn McCall     FieldName + "' does not have either a def initializer or '?'!");
273927e2c8faSJohn McCall }
274027e2c8faSJohn McCall 
274127e2c8faSJohn McCall 
getValueAsBit(StringRef FieldName) const274284c287e3SPeter Collingbourne bool Record::getValueAsBit(StringRef FieldName) const {
274384c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2744011817a0SCraig Topper   if (!R || !R->getValue())
2745635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
274648e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
274784c287e3SPeter Collingbourne 
2748fb509ed1SSean Silva   if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
274984c287e3SPeter Collingbourne     return BI->getValue();
2750635debe8SJoerg Sonnenberger   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
275148e7e85dSBenjamin Kramer     FieldName + "' does not have a bit initializer!");
275284c287e3SPeter Collingbourne }
275384c287e3SPeter Collingbourne 
getValueAsBitOrUnset(StringRef FieldName,bool & Unset) const2754af507bf4SJakob Stoklund Olesen bool Record::getValueAsBitOrUnset(StringRef FieldName, bool &Unset) const {
2755af507bf4SJakob Stoklund Olesen   const RecordVal *R = getValue(FieldName);
2756011817a0SCraig Topper   if (!R || !R->getValue())
2757635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
2758635debe8SJoerg Sonnenberger       "' does not have a field named `" + FieldName.str() + "'!\n");
2759af507bf4SJakob Stoklund Olesen 
27601bf3d1f5SCraig Topper   if (isa<UnsetInit>(R->getValue())) {
2761af507bf4SJakob Stoklund Olesen     Unset = true;
2762af507bf4SJakob Stoklund Olesen     return false;
2763af507bf4SJakob Stoklund Olesen   }
2764af507bf4SJakob Stoklund Olesen   Unset = false;
2765fb509ed1SSean Silva   if (BitInit *BI = dyn_cast<BitInit>(R->getValue()))
2766af507bf4SJakob Stoklund Olesen     return BI->getValue();
2767635debe8SJoerg Sonnenberger   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
276848e7e85dSBenjamin Kramer     FieldName + "' does not have a bit initializer!");
2769af507bf4SJakob Stoklund Olesen }
2770af507bf4SJakob Stoklund Olesen 
getValueAsDag(StringRef FieldName) const277184c287e3SPeter Collingbourne DagInit *Record::getValueAsDag(StringRef FieldName) const {
277284c287e3SPeter Collingbourne   const RecordVal *R = getValue(FieldName);
2773011817a0SCraig Topper   if (!R || !R->getValue())
2774635debe8SJoerg Sonnenberger     PrintFatalError(getLoc(), "Record `" + getName() +
277548e7e85dSBenjamin Kramer       "' does not have a field named `" + FieldName + "'!\n");
277684c287e3SPeter Collingbourne 
2777fb509ed1SSean Silva   if (DagInit *DI = dyn_cast<DagInit>(R->getValue()))
277884c287e3SPeter Collingbourne     return DI;
2779635debe8SJoerg Sonnenberger   PrintFatalError(getLoc(), "Record `" + getName() + "', field `" +
278048e7e85dSBenjamin Kramer     FieldName + "' does not have a dag initializer!");
278184c287e3SPeter Collingbourne }
278284c287e3SPeter Collingbourne 
27835f473a04SPaul C. Anagnostopoulos // Check all record assertions: For each one, resolve the condition
27845f473a04SPaul C. Anagnostopoulos // and message, then call CheckAssert().
27855f473a04SPaul C. Anagnostopoulos // Note: The condition and message are probably already resolved,
27865f473a04SPaul C. Anagnostopoulos //       but resolving again allows calls before records are resolved.
checkRecordAssertions()2787a5aaec8fSPaul C. Anagnostopoulos void Record::checkRecordAssertions() {
27885f473a04SPaul C. Anagnostopoulos   RecordResolver R(*this);
27895f473a04SPaul C. Anagnostopoulos   R.setFinal(true);
27905f473a04SPaul C. Anagnostopoulos 
2791e4b2f66dSSimon Pilgrim   for (const auto &Assertion : getAssertions()) {
27922d4c4d3cSPaul C. Anagnostopoulos     Init *Condition = Assertion.Condition->resolveReferences(R);
27932d4c4d3cSPaul C. Anagnostopoulos     Init *Message = Assertion.Message->resolveReferences(R);
27942d4c4d3cSPaul C. Anagnostopoulos     CheckAssert(Assertion.Loc, Condition, Message);
27955f473a04SPaul C. Anagnostopoulos   }
27965f473a04SPaul C. Anagnostopoulos }
27975f473a04SPaul C. Anagnostopoulos 
2798d968b173SCullen Rhodes // Report a warning if the record has unused template arguments.
checkUnusedTemplateArgs()2799d968b173SCullen Rhodes void Record::checkUnusedTemplateArgs() {
2800d968b173SCullen Rhodes   for (const Init *TA : getTemplateArgs()) {
2801d968b173SCullen Rhodes     const RecordVal *Arg = getValue(TA);
2802d968b173SCullen Rhodes     if (!Arg->isUsed())
2803d968b173SCullen Rhodes       PrintWarning(Arg->getLoc(),
2804d968b173SCullen Rhodes                    "unused template argument: " + Twine(Arg->getName()));
2805d968b173SCullen Rhodes   }
2806d968b173SCullen Rhodes }
2807d968b173SCullen Rhodes 
RecordKeeper()28082ac3cd20SRiver Riddle RecordKeeper::RecordKeeper()
28092ac3cd20SRiver Riddle     : Impl(std::make_unique<detail::RecordKeeperImpl>(*this)) {}
28102ac3cd20SRiver Riddle RecordKeeper::~RecordKeeper() = default;
28112ac3cd20SRiver Riddle 
2812615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const2813eb2a2546SYaron Keren LLVM_DUMP_METHOD void RecordKeeper::dump() const { errs() << *this; }
28148c209aa8SMatthias Braun #endif
281584c287e3SPeter Collingbourne 
operator <<(raw_ostream & OS,const RecordKeeper & RK)281684c287e3SPeter Collingbourne raw_ostream &llvm::operator<<(raw_ostream &OS, const RecordKeeper &RK) {
281784c287e3SPeter Collingbourne   OS << "------------- Classes -----------------\n";
2818a0ff540bSCraig Topper   for (const auto &C : RK.getClasses())
281980f0e432SDylan Noblesmith     OS << "class " << *C.second;
282084c287e3SPeter Collingbourne 
282184c287e3SPeter Collingbourne   OS << "------------- Defs -----------------\n";
2822a0ff540bSCraig Topper   for (const auto &D : RK.getDefs())
282380f0e432SDylan Noblesmith     OS << "def " << *D.second;
282484c287e3SPeter Collingbourne   return OS;
282584c287e3SPeter Collingbourne }
282684c287e3SPeter Collingbourne 
282773355bcdSNicolai Haehnle /// GetNewAnonymousName - Generate a unique anonymous name that can be used as
282873355bcdSNicolai Haehnle /// an identifier.
getNewAnonymousName()282973355bcdSNicolai Haehnle Init *RecordKeeper::getNewAnonymousName() {
28302ac3cd20SRiver Riddle   return AnonymousNameInit::get(*this, getImpl().AnonCounter++);
283173355bcdSNicolai Haehnle }
283273355bcdSNicolai Haehnle 
283354f9ee33SPaul C. Anagnostopoulos // These functions implement the phase timing facility. Starting a timer
283454f9ee33SPaul C. Anagnostopoulos // when one is already running stops the running one.
283554f9ee33SPaul C. Anagnostopoulos 
startTimer(StringRef Name)283654f9ee33SPaul C. Anagnostopoulos void RecordKeeper::startTimer(StringRef Name) {
283754f9ee33SPaul C. Anagnostopoulos   if (TimingGroup) {
283854f9ee33SPaul C. Anagnostopoulos     if (LastTimer && LastTimer->isRunning()) {
283954f9ee33SPaul C. Anagnostopoulos       LastTimer->stopTimer();
284054f9ee33SPaul C. Anagnostopoulos       if (BackendTimer) {
284154f9ee33SPaul C. Anagnostopoulos         LastTimer->clear();
284254f9ee33SPaul C. Anagnostopoulos         BackendTimer = false;
284354f9ee33SPaul C. Anagnostopoulos       }
284454f9ee33SPaul C. Anagnostopoulos     }
284554f9ee33SPaul C. Anagnostopoulos 
284654f9ee33SPaul C. Anagnostopoulos     LastTimer = new Timer("", Name, *TimingGroup);
284754f9ee33SPaul C. Anagnostopoulos     LastTimer->startTimer();
284854f9ee33SPaul C. Anagnostopoulos   }
284954f9ee33SPaul C. Anagnostopoulos }
285054f9ee33SPaul C. Anagnostopoulos 
stopTimer()285154f9ee33SPaul C. Anagnostopoulos void RecordKeeper::stopTimer() {
285254f9ee33SPaul C. Anagnostopoulos   if (TimingGroup) {
285354f9ee33SPaul C. Anagnostopoulos     assert(LastTimer && "No phase timer was started");
285454f9ee33SPaul C. Anagnostopoulos     LastTimer->stopTimer();
285554f9ee33SPaul C. Anagnostopoulos   }
285654f9ee33SPaul C. Anagnostopoulos }
285754f9ee33SPaul C. Anagnostopoulos 
startBackendTimer(StringRef Name)285854f9ee33SPaul C. Anagnostopoulos void RecordKeeper::startBackendTimer(StringRef Name) {
285954f9ee33SPaul C. Anagnostopoulos   if (TimingGroup) {
286054f9ee33SPaul C. Anagnostopoulos     startTimer(Name);
286154f9ee33SPaul C. Anagnostopoulos     BackendTimer = true;
286254f9ee33SPaul C. Anagnostopoulos   }
286354f9ee33SPaul C. Anagnostopoulos }
286454f9ee33SPaul C. Anagnostopoulos 
stopBackendTimer()286554f9ee33SPaul C. Anagnostopoulos void RecordKeeper::stopBackendTimer() {
286654f9ee33SPaul C. Anagnostopoulos   if (TimingGroup) {
28679671790bSPaul C. Anagnostopoulos     if (BackendTimer) {
286854f9ee33SPaul C. Anagnostopoulos       stopTimer();
286954f9ee33SPaul C. Anagnostopoulos       BackendTimer = false;
287054f9ee33SPaul C. Anagnostopoulos     }
287154f9ee33SPaul C. Anagnostopoulos   }
28729671790bSPaul C. Anagnostopoulos }
287354f9ee33SPaul C. Anagnostopoulos 
28741d7120c6SRiver Riddle std::vector<Record *>
getAllDerivedDefinitions(StringRef ClassName) const28751d7120c6SRiver Riddle RecordKeeper::getAllDerivedDefinitions(StringRef ClassName) const {
28766266f362SPaul C. Anagnostopoulos   // We cache the record vectors for single classes. Many backends request
28776266f362SPaul C. Anagnostopoulos   // the same vectors multiple times.
28786266f362SPaul C. Anagnostopoulos   auto Pair = ClassRecordsMap.try_emplace(ClassName);
28796266f362SPaul C. Anagnostopoulos   if (Pair.second)
28806266f362SPaul C. Anagnostopoulos     Pair.first->second = getAllDerivedDefinitions(makeArrayRef(ClassName));
28816266f362SPaul C. Anagnostopoulos 
28826266f362SPaul C. Anagnostopoulos   return Pair.first->second;
28836266f362SPaul C. Anagnostopoulos }
28846266f362SPaul C. Anagnostopoulos 
getAllDerivedDefinitions(ArrayRef<StringRef> ClassNames) const28856266f362SPaul C. Anagnostopoulos std::vector<Record *> RecordKeeper::getAllDerivedDefinitions(
28866266f362SPaul C. Anagnostopoulos     ArrayRef<StringRef> ClassNames) const {
2887350fafabSPaul C. Anagnostopoulos   SmallVector<Record *, 2> ClassRecs;
2888350fafabSPaul C. Anagnostopoulos   std::vector<Record *> Defs;
2889350fafabSPaul C. Anagnostopoulos 
2890350fafabSPaul C. Anagnostopoulos   assert(ClassNames.size() > 0 && "At least one class must be passed.");
2891350fafabSPaul C. Anagnostopoulos   for (const auto &ClassName : ClassNames) {
289284c287e3SPeter Collingbourne     Record *Class = getClass(ClassName);
289384c287e3SPeter Collingbourne     if (!Class)
2894350fafabSPaul C. Anagnostopoulos       PrintFatalError("The class '" + ClassName + "' is not defined\n");
2895350fafabSPaul C. Anagnostopoulos     ClassRecs.push_back(Class);
2896350fafabSPaul C. Anagnostopoulos   }
289784c287e3SPeter Collingbourne 
2898350fafabSPaul C. Anagnostopoulos   for (const auto &OneDef : getDefs()) {
2899350fafabSPaul C. Anagnostopoulos     if (all_of(ClassRecs, [&OneDef](const Record *Class) {
2900350fafabSPaul C. Anagnostopoulos                             return OneDef.second->isSubClassOf(Class);
2901350fafabSPaul C. Anagnostopoulos                           }))
2902350fafabSPaul C. Anagnostopoulos       Defs.push_back(OneDef.second.get());
2903350fafabSPaul C. Anagnostopoulos   }
290484c287e3SPeter Collingbourne 
290584c287e3SPeter Collingbourne   return Defs;
290684c287e3SPeter Collingbourne }
290784c287e3SPeter Collingbourne 
29081d7120c6SRiver Riddle std::vector<Record *>
getAllDerivedDefinitionsIfDefined(StringRef ClassName) const29091d7120c6SRiver Riddle RecordKeeper::getAllDerivedDefinitionsIfDefined(StringRef ClassName) const {
29101d7120c6SRiver Riddle   return getClass(ClassName) ? getAllDerivedDefinitions(ClassName)
29111d7120c6SRiver Riddle                              : std::vector<Record *>();
29121d7120c6SRiver Riddle }
29131d7120c6SRiver Riddle 
resolve(Init * VarName)29148ebf7e4dSNicolai Haehnle Init *MapResolver::resolve(Init *VarName) {
29158ebf7e4dSNicolai Haehnle   auto It = Map.find(VarName);
29168ebf7e4dSNicolai Haehnle   if (It == Map.end())
29178ebf7e4dSNicolai Haehnle     return nullptr;
29188ebf7e4dSNicolai Haehnle 
29198ebf7e4dSNicolai Haehnle   Init *I = It->second.V;
29208ebf7e4dSNicolai Haehnle 
29218ebf7e4dSNicolai Haehnle   if (!It->second.Resolved && Map.size() > 1) {
29228ebf7e4dSNicolai Haehnle     // Resolve mutual references among the mapped variables, but prevent
29238ebf7e4dSNicolai Haehnle     // infinite recursion.
29248ebf7e4dSNicolai Haehnle     Map.erase(It);
29258ebf7e4dSNicolai Haehnle     I = I->resolveReferences(*this);
29268ebf7e4dSNicolai Haehnle     Map[VarName] = {I, true};
29278ebf7e4dSNicolai Haehnle   }
29288ebf7e4dSNicolai Haehnle 
29298ebf7e4dSNicolai Haehnle   return I;
29308ebf7e4dSNicolai Haehnle }
29318ebf7e4dSNicolai Haehnle 
resolve(Init * VarName)29320b0eaf7eSNicolai Haehnle Init *RecordResolver::resolve(Init *VarName) {
29330b0eaf7eSNicolai Haehnle   Init *Val = Cache.lookup(VarName);
29340b0eaf7eSNicolai Haehnle   if (Val)
29350b0eaf7eSNicolai Haehnle     return Val;
29360b0eaf7eSNicolai Haehnle 
2937910e2d1eSKazu Hirata   if (llvm::is_contained(Stack, VarName))
29380b0eaf7eSNicolai Haehnle     return nullptr; // prevent infinite recursion
29390b0eaf7eSNicolai Haehnle 
29400b0eaf7eSNicolai Haehnle   if (RecordVal *RV = getCurrentRecord()->getValue(VarName)) {
29410b0eaf7eSNicolai Haehnle     if (!isa<UnsetInit>(RV->getValue())) {
29420b0eaf7eSNicolai Haehnle       Val = RV->getValue();
29430b0eaf7eSNicolai Haehnle       Stack.push_back(VarName);
29440b0eaf7eSNicolai Haehnle       Val = Val->resolveReferences(*this);
29450b0eaf7eSNicolai Haehnle       Stack.pop_back();
29460b0eaf7eSNicolai Haehnle     }
2947267b573bSJ-Y You   } else if (Name && VarName == getCurrentRecord()->getNameInit()) {
2948267b573bSJ-Y You     Stack.push_back(VarName);
2949267b573bSJ-Y You     Val = Name->resolveReferences(*this);
2950267b573bSJ-Y You     Stack.pop_back();
29510b0eaf7eSNicolai Haehnle   }
29520b0eaf7eSNicolai Haehnle 
29530b0eaf7eSNicolai Haehnle   Cache[VarName] = Val;
29540b0eaf7eSNicolai Haehnle   return Val;
29550b0eaf7eSNicolai Haehnle }
2956d4c0a5d0SNicolai Haehnle 
resolve(Init * VarName)2957d4c0a5d0SNicolai Haehnle Init *TrackUnresolvedResolver::resolve(Init *VarName) {
2958d4c0a5d0SNicolai Haehnle   Init *I = nullptr;
2959d4c0a5d0SNicolai Haehnle 
2960d4c0a5d0SNicolai Haehnle   if (R) {
2961d4c0a5d0SNicolai Haehnle     I = R->resolve(VarName);
2962d4c0a5d0SNicolai Haehnle     if (I && !FoundUnresolved) {
2963d4c0a5d0SNicolai Haehnle       // Do not recurse into the resolved initializer, as that would change
2964d4c0a5d0SNicolai Haehnle       // the behavior of the resolver we're delegating, but do check to see
2965d4c0a5d0SNicolai Haehnle       // if there are unresolved variables remaining.
2966d4c0a5d0SNicolai Haehnle       TrackUnresolvedResolver Sub;
2967d4c0a5d0SNicolai Haehnle       I->resolveReferences(Sub);
2968d4c0a5d0SNicolai Haehnle       FoundUnresolved |= Sub.FoundUnresolved;
2969d4c0a5d0SNicolai Haehnle     }
2970d4c0a5d0SNicolai Haehnle   }
2971d4c0a5d0SNicolai Haehnle 
2972d4c0a5d0SNicolai Haehnle   if (!I)
2973d4c0a5d0SNicolai Haehnle     FoundUnresolved = true;
2974d4c0a5d0SNicolai Haehnle   return I;
2975d4c0a5d0SNicolai Haehnle }
297601d261f1SNicolai Haehnle 
resolve(Init * VarName)297701d261f1SNicolai Haehnle Init *HasReferenceResolver::resolve(Init *VarName)
297801d261f1SNicolai Haehnle {
297901d261f1SNicolai Haehnle   if (VarName == VarNameToTrack)
298001d261f1SNicolai Haehnle     Found = true;
298101d261f1SNicolai Haehnle   return nullptr;
298201d261f1SNicolai Haehnle }
2983