llvm.org GIT mirror llvm / 60e3f9f
TableGen: Allow lists to be concatenated through '#' Currently one can concatenate strings using hash(#), but not lists, although that would be a natural thing to do. This patch allows one to write something like: def : A<!listconcat([1,2], [3,4])>; simply as : def : A<[1,2] # [3,4]>; This was missing feature was highlighted by Nicolai at FOSDEM talk. Reviewed by: nhaehnle, hfinkel Differential Revision: https://reviews.llvm.org/D58895 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@355414 91177308-0d34-0410-b5e6-96231b3b80d8 Javed Absar 7 months ago
4 changed file(s) with 78 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
819819 static BinOpInit *get(BinaryOp opc, Init *lhs, Init *rhs,
820820 RecTy *Type);
821821 static Init *getStrConcat(Init *lhs, Init *rhs);
822 static Init *getListConcat(TypedInit *lhs, Init *rhs);
822823
823824 void Profile(FoldingSetNodeID &ID) const;
824825
853853 if (const StringInit *I1s = dyn_cast(I1))
854854 return ConcatStringInits(I0s, I1s);
855855 return BinOpInit::get(BinOpInit::STRCONCAT, I0, I1, StringRecTy::get());
856 }
857
858 static ListInit *ConcatListInits(const ListInit *LHS,
859 const ListInit *RHS) {
860 SmallVector Args;
861 Args.insert(Args.end(), LHS->begin(), LHS->end());
862 Args.insert(Args.end(), RHS->begin(), RHS->end());
863 return ListInit::get(Args, LHS->getElementType());
864 }
865
866 Init *BinOpInit::getListConcat(TypedInit *LHS, Init *RHS) {
867 assert(isa(LHS->getType()) && "First arg must be a list");
868
869 // Shortcut for the common case of concatenating two lists.
870 if (const ListInit *LHSList = dyn_cast(LHS))
871 if (const ListInit *RHSList = dyn_cast(RHS))
872 return ConcatListInits(LHSList, RHSList);
873 return BinOpInit::get(BinOpInit::LISTCONCAT, LHS, RHS, LHS->getType());
856874 }
857875
858876 Init *BinOpInit::Fold(Record *CurRec) const {
21182118
21192119 case tgtok::paste:
21202120 SMLoc PasteLoc = Lex.getLoc();
2121
2122 // Create a !strconcat() operation, first casting each operand to
2123 // a string if necessary.
2124
21252121 TypedInit *LHS = dyn_cast(Result);
21262122 if (!LHS) {
21272123 Error(PasteLoc, "LHS of paste is not typed!");
21282124 return nullptr;
21292125 }
21302126
2127 // Check if it's a 'listA # listB'
2128 if (isa(LHS->getType())) {
2129 Lex.Lex(); // Eat the '#'.
2130
2131 switch (Lex.getCode()) {
2132 case tgtok::colon:
2133 case tgtok::semi:
2134 case tgtok::l_brace:
2135 Result = LHS; // trailing paste, ignore.
2136 break;
2137 default:
2138 Init *RHSResult = ParseValue(CurRec, ItemType, ParseNameMode);
2139 Result = BinOpInit::getListConcat(LHS, RHSResult);
2140 }
2141 break;
2142 }
2143
2144 // Create a !strconcat() operation, first casting each operand to
2145 // a string if necessary.
21312146 if (LHS->getType() != StringRecTy::get()) {
21322147 LHS = dyn_cast(
21332148 UnOpInit::get(UnOpInit::CAST, LHS, StringRecTy::get())
0 // RUN: llvm-tblgen %s | FileCheck %s
1
2 // CHECK: class A {
3 // CHECK: list lst = !listconcat([], !if(A:x, [], [4]));
4 // CHECK: }
5 class A {
6 list lst = [] # !if(x, [], [4]);
7 }
8
9 // CHECK: class A1 A1:l = ?> {
10 // CHECK: list A1List = A1:l;
11 // CHECK: }
12 class A1 l> {
13 list A1List = l;
14 }
15
16 // CHECK: def A0 {
17 // CHECK: list lst = [4];
18 // CHECK: }
19 def A0 : A<0>;
20
21 // CHECK: def A1 {
22 // CHECK: list lst = [];
23 // CHECK: }
24 def A1 : A<1>;
25
26 // CHECK: def A1_0 {
27 // CHECK: list A1List = [1, 2, 3, 4];
28 // CHECK: }
29 def A1_0 : A1<[1,2] # [3,4]>;
30
31 // CHECK: def A1_1 {
32 // CHECK: list A1List = [1, 2];
33 // CHECK: }
34 def A1_1 : A1<[] # [1,2]>;
35
36 // CHECK: def A1_2 { // A1
37 // CHECK: list A1List = [1, 2];
38 // CHECK: }
39 def A1_2 : A1<[1,2] # []>;