• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "mir_parser.h"
17 #include "mir_function.h"
18 #include "opcode_info.h"
19 
20 namespace maple {
21 std::map<TokenKind, MIRParser::FuncPtrParseExpr> MIRParser::funcPtrMapForParseExpr =
22     MIRParser::InitFuncPtrMapForParseExpr();
23 std::map<TokenKind, MIRParser::FuncPtrParseStmt> MIRParser::funcPtrMapForParseStmt =
24     MIRParser::InitFuncPtrMapForParseStmt();
25 std::map<TokenKind, MIRParser::FuncPtrParseStmtBlock> MIRParser::funcPtrMapForParseStmtBlock =
26     MIRParser::InitFuncPtrMapForParseStmtBlock();
27 
ParseStmtDassign(StmtNodePtr & stmt)28 bool MIRParser::ParseStmtDassign(StmtNodePtr &stmt)
29 {
30     if (lexer.GetTokenKind() != TK_dassign) {
31         Error("expect dassign but get ");
32         return false;
33     }
34     // parse %i
35     lexer.NextToken();
36     StIdx stidx;
37     if (!ParseDeclaredSt(stidx)) {
38         return false;
39     }
40     if (stidx.FullIdx() == 0) {
41         Error("expect a symbol parsing ParseStmtDassign");
42         return false;
43     }
44     if (stidx.IsGlobal()) {
45         MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx());
46         DEBUG_ASSERT(sym != nullptr, "null ptr check");
47         sym->SetHasPotentialAssignment();
48     }
49     auto *assignStmt = mod.CurFuncCodeMemPool()->New<DassignNode>();
50     assignStmt->SetStIdx(stidx);
51     TokenKind nextToken = lexer.NextToken();
52     // parse field id
53     if (nextToken == TK_intconst) {  // may be a field id
54         assignStmt->SetFieldID(lexer.GetTheIntVal());
55         (void)lexer.NextToken();
56     }
57     // parse expression like (constval i32 0)
58     BaseNode *expr = nullptr;
59     if (!ParseExprOneOperand(expr)) {
60         return false;
61     }
62     assignStmt->SetRHS(expr);
63     stmt = assignStmt;
64     lexer.NextToken();
65     return true;
66 }
67 
ParseStmtDassignoff(StmtNodePtr & stmt)68 bool MIRParser::ParseStmtDassignoff(StmtNodePtr &stmt)
69 {
70     if (lexer.GetTokenKind() != TK_dassignoff) {
71         Error("expect dassignoff but get ");
72         return false;
73     }
74     if (!IsPrimitiveType(lexer.NextToken())) {
75         Error("expect primitive type but get ");
76         return false;
77     }
78     PrimType primType = GetPrimitiveType(lexer.GetTokenKind());
79     // parse %i
80     lexer.NextToken();
81     StIdx stidx;
82     if (!ParseDeclaredSt(stidx)) {
83         return false;
84     }
85     if (stidx.FullIdx() == 0) {
86         Error("expect a symbol parsing ParseStmtDassign");
87         return false;
88     }
89     if (stidx.IsGlobal()) {
90         MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx());
91         DEBUG_ASSERT(sym != nullptr, "null ptr check");
92         sym->SetHasPotentialAssignment();
93     }
94     DassignoffNode *assignStmt = mod.CurFuncCodeMemPool()->New<DassignoffNode>();
95     assignStmt->SetPrimType(primType);
96     assignStmt->stIdx = stidx;
97     TokenKind nextToken = lexer.NextToken();
98     // parse offset
99     if (nextToken == TK_intconst) {
100         assignStmt->offset = static_cast<int32>(lexer.GetTheIntVal());
101         (void)lexer.NextToken();
102     } else {
103         Error("expect integer offset but get ");
104         return false;
105     }
106     // parse expression like (constval i32 0)
107     BaseNode *expr = nullptr;
108     if (!ParseExprOneOperand(expr)) {
109         return false;
110     }
111     assignStmt->SetRHS(expr);
112     stmt = assignStmt;
113     lexer.NextToken();
114     return true;
115 }
116 
ParseStmtRegassign(StmtNodePtr & stmt)117 bool MIRParser::ParseStmtRegassign(StmtNodePtr &stmt)
118 {
119     if (!IsPrimitiveType(lexer.NextToken())) {
120         Error("expect type parsing binary operator but get ");
121         return false;
122     }
123     auto *regAssign = mod.CurFuncCodeMemPool()->New<RegassignNode>();
124     regAssign->SetPrimType(GetPrimitiveType(lexer.GetTokenKind()));
125     lexer.NextToken();
126     if (lexer.GetTokenKind() == TK_specialreg) {
127         PregIdx tempPregIdx = regAssign->GetRegIdx();
128         bool isSuccess = ParseSpecialReg(tempPregIdx);
129         regAssign->SetRegIdx(tempPregIdx);
130         if (!isSuccess) {
131             return false;
132         }
133     } else if (lexer.GetTokenKind() == TK_preg) {
134         PregIdx tempPregIdx = regAssign->GetRegIdx();
135         bool isSuccess = ParsePseudoReg(regAssign->GetPrimType(), tempPregIdx);
136         regAssign->SetRegIdx(tempPregIdx);
137         if (!isSuccess) {
138             return false;
139         }
140     } else {
141         Error("expect special or pseudo register but get ");
142         return false;
143     }
144     BaseNode *expr = nullptr;
145     if (!ParseExprOneOperand(expr)) {
146         return false;
147     }
148     regAssign->SetOpnd(expr, 0);
149     if (regAssign->GetRegIdx() > 0) {  // check type consistenency for the preg
150         MIRPreg *preg = mod.CurFunction()->GetPregTab()->PregFromPregIdx(regAssign->GetRegIdx());
151         if (preg->GetPrimType() == kPtyInvalid) {
152             preg->SetPrimType(expr->GetPrimType());
153         } else if (preg->GetPrimType() == PTY_dynany) {
154             if (!IsPrimitiveDynType(expr->GetPrimType())) {
155                 Error("inconsistent preg primitive dynamic type at ");
156                 return false;
157             }
158         }
159     }
160     stmt = regAssign;
161     lexer.NextToken();
162     return true;
163 }
164 
ParseStmtIassign(StmtNodePtr & stmt)165 bool MIRParser::ParseStmtIassign(StmtNodePtr &stmt)
166 {
167     // iAssign <* [10] int> ()
168     if (lexer.GetTokenKind() != TK_iassign) {
169         Error("expect iassign but get ");
170         return false;
171     }
172     // expect <> derived type
173     lexer.NextToken();
174     TyIdx tyIdx(0);
175     if (!ParseDerivedType(tyIdx)) {
176         Error("ParseStmtIassign failed when parsing derived type");
177         return false;
178     }
179     auto *iAssign = mod.CurFuncCodeMemPool()->New<IassignNode>();
180     iAssign->SetTyIdx(tyIdx);
181     if (lexer.GetTokenKind() == TK_intconst) {
182         iAssign->SetFieldID(lexer.theIntVal);
183         lexer.NextToken();
184     }
185     BaseNode *addr = nullptr;
186     BaseNode *rhs = nullptr;
187     // parse 2 operands then, #1 is address, the other would be value
188     if (!ParseExprTwoOperand(addr, rhs)) {
189         return false;
190     }
191     iAssign->SetOpnd(addr, 0);
192     iAssign->SetRHS(rhs);
193     lexer.NextToken();
194     stmt = iAssign;
195     return true;
196 }
197 
ParseStmtIassignoff(StmtNodePtr & stmt)198 bool MIRParser::ParseStmtIassignoff(StmtNodePtr &stmt)
199 {
200     if (!IsPrimitiveType(lexer.NextToken())) {
201         Error("expect type parsing binary operator but get ");
202         return false;
203     }
204     // iassign <prim-type> <offset> ( <addr-expr>, <rhs-expr> )
205     auto *iAssignOff = mod.CurFuncCodeMemPool()->New<IassignoffNode>();
206     iAssignOff->SetPrimType(GetPrimitiveType(lexer.GetTokenKind()));
207     if (lexer.NextToken() != TK_intconst) {
208         Error("expect offset but get ");
209         return false;
210     }
211     iAssignOff->SetOffset(lexer.GetTheIntVal());
212     lexer.NextToken();
213     BaseNode *addr = nullptr;
214     BaseNode *rhs = nullptr;
215     if (!ParseExprTwoOperand(addr, rhs)) {
216         return false;
217     }
218     iAssignOff->SetBOpnd(addr, 0);
219     iAssignOff->SetBOpnd(rhs, 1);
220     lexer.NextToken();
221     stmt = iAssignOff;
222     return true;
223 }
224 
ParseStmtIassignFPoff(StmtNodePtr & stmt)225 bool MIRParser::ParseStmtIassignFPoff(StmtNodePtr &stmt)
226 {
227     Opcode op = lexer.GetTokenKind() == TK_iassignfpoff ? OP_iassignfpoff : OP_iassignspoff;
228     if (!IsPrimitiveType(lexer.NextToken())) {
229         Error("expect type parsing binary operator but get ");
230         return false;
231     }
232     // iassignfpoff <prim-type> <offset> (<rhs-expr> )
233     auto *iAssignOff = mod.CurFuncCodeMemPool()->New<IassignFPoffNode>(op);
234     iAssignOff->SetPrimType(GetPrimitiveType(lexer.GetTokenKind()));
235     if (lexer.NextToken() != TK_intconst) {
236         Error("expect offset but get ");
237         return false;
238     }
239     iAssignOff->SetOffset(lexer.GetTheIntVal());
240     lexer.NextToken();
241     BaseNode *expr = nullptr;
242     if (!ParseExprOneOperand(expr)) {
243         return false;
244     }
245     iAssignOff->SetOpnd(expr, 0);
246     lexer.NextToken();
247     stmt = iAssignOff;
248     return true;
249 }
250 
ParseStmtBlkassignoff(StmtNodePtr & stmt)251 bool MIRParser::ParseStmtBlkassignoff(StmtNodePtr &stmt)
252 {
253     // blkassignoff <dest-offset> <size> (<dest-addr-expr>, <src-addr-expr>)
254     BlkassignoffNode *bassignoff = mod.CurFuncCodeMemPool()->New<BlkassignoffNode>();
255     if (lexer.NextToken() != TK_intconst) {
256         Error("expect offset but get ");
257         return false;
258     }
259     bassignoff->offset = static_cast<int32>(lexer.GetTheIntVal());
260     if (lexer.NextToken() != TK_intconst) {
261         Error("expect align but get ");
262         return false;
263     }
264     bassignoff->SetAlign(static_cast<uint32>(lexer.GetTheIntVal()));
265     if (lexer.NextToken() != TK_intconst) {
266         Error("expect size but get ");
267         return false;
268     }
269     bassignoff->blockSize = static_cast<int32>(lexer.GetTheIntVal());
270     lexer.NextToken();
271     BaseNode *destAddr = nullptr;
272     BaseNode *srcAddr = nullptr;
273     // parse 2 operands, the dest address followed by src address
274     if (!ParseExprTwoOperand(destAddr, srcAddr)) {
275         return false;
276     }
277     bassignoff->SetOpnd(destAddr, 0);
278     bassignoff->SetOpnd(srcAddr, 1);
279     lexer.NextToken();
280     stmt = bassignoff;
281     return true;
282 }
283 
ParseStmtDoloop(StmtNodePtr & stmt)284 bool MIRParser::ParseStmtDoloop(StmtNodePtr &stmt)
285 {
286     // syntax: doloop <do-var> (<start-expr>, <cont-expr>, <incr-amt>) {
287     //              <body-stmts> }
288     auto *doLoopNode = mod.CurFuncCodeMemPool()->New<DoloopNode>();
289     stmt = doLoopNode;
290     lexer.NextToken();
291     if (lexer.GetTokenKind() == TK_preg) {
292         uint32 pregNo = static_cast<uint32>(lexer.GetTheIntVal());
293         MIRFunction *mirFunc = mod.CurFunction();
294         PregIdx pregIdx = mirFunc->GetPregTab()->EnterPregNo(pregNo, kPtyInvalid);
295         doLoopNode->SetIsPreg(true);
296         doLoopNode->SetDoVarStFullIdx(pregIdx);
297         // let other appearances handle the preg primitive type
298     } else {
299         StIdx stIdx;
300         if (!ParseDeclaredSt(stIdx)) {
301             return false;
302         }
303         if (stIdx.FullIdx() == 0) {
304             Error("expect a symbol parsing ParseStmtDoloop");
305             return false;
306         }
307         if (stIdx.IsGlobal()) {
308             Error("expect local variable for doloop var but get ");
309             return false;
310         }
311         doLoopNode->SetDoVarStIdx(stIdx);
312     }
313     // parse (
314     if (lexer.NextToken() != TK_lparen) {
315         Error("expect ( but get ");
316         return false;
317     }
318     // parse start expression
319     lexer.NextToken();
320     BaseNode *start = nullptr;
321     if (!ParseExpression(start)) {
322         Error("ParseStmtDoloop when parsing start expression");
323         return false;
324     }
325     if (doLoopNode->IsPreg()) {
326         auto regIdx = static_cast<PregIdx>(doLoopNode->GetDoVarStIdx().FullIdx());
327         MIRPreg *mpReg = mod.CurFunction()->GetPregTab()->PregFromPregIdx(regIdx);
328         if (mpReg->GetPrimType() == kPtyInvalid) {
329             CHECK_FATAL(start != nullptr, "null ptr check");
330             mpReg->SetPrimType(start->GetPrimType());
331         }
332     }
333     if (lexer.GetTokenKind() != TK_coma) {
334         Error("expect , after start expression but get ");
335         return false;
336     }
337     doLoopNode->SetStartExpr(start);
338     // parse end expression
339     lexer.NextToken();
340     BaseNode *end = nullptr;
341     if (!ParseExpression(end)) {  // here should be a compare expression
342         Error("ParseStmtDoloop when parsing end expression");
343         return false;
344     }
345     if (lexer.GetTokenKind() != TK_coma) {
346         Error("expect , after condition expression but get ");
347         return false;
348     }
349     doLoopNode->SetContExpr(end);
350     // parse renew induction expression
351     lexer.NextToken();
352     BaseNode *induction = nullptr;
353     if (!ParseExpression(induction)) {
354         Error("ParseStmtDoloop when parsing induction");
355         return false;
356     }
357     // parse )
358     if (lexer.GetTokenKind() != TK_rparen) {
359         Error("expect ) parsing doloop but get ");
360         return false;
361     }
362     doLoopNode->SetIncrExpr(induction);
363     // parse body of the loop
364     lexer.NextToken();
365     BlockNode *bodyStmt = nullptr;
366     if (!ParseStmtBlock(bodyStmt)) {
367         Error("ParseStmtDoloop when parsing body of the loop");
368         return false;
369     }
370     doLoopNode->SetDoBody(bodyStmt);
371     return true;
372 }
373 
ParseStmtForeachelem(StmtNodePtr & stmt)374 bool MIRParser::ParseStmtForeachelem(StmtNodePtr &stmt)
375 {
376     // syntax: foreachelem <elemvar> <arrayvar> {
377     //              <body-stmts> }
378     auto *forNode = mod.CurFuncCodeMemPool()->New<ForeachelemNode>();
379     stmt = forNode;
380     lexer.NextToken();  // skip foreachelem token
381     StIdx stidx;
382     if (!ParseDeclaredSt(stidx)) {
383         return false;
384     }
385     if (stidx.FullIdx() == 0) {
386         Error("error parsing element variable of foreachelem in ");
387         return false;
388     }
389     if (stidx.IsGlobal()) {
390         Error("illegal global scope for element variable for foreachelem in ");
391         return false;
392     }
393     forNode->SetElemStIdx(stidx);
394     lexer.NextToken();
395     if (!ParseDeclaredSt(stidx)) {
396         return false;
397     }
398     if (stidx.FullIdx() == 0) {
399         Error("error parsing array/collection variable of foreachelem in ");
400         return false;
401     }
402     forNode->SetArrayStIdx(stidx);
403     lexer.NextToken();
404     // parse body of the loop
405     BlockNode *bodyStmt = nullptr;
406     if (!ParseStmtBlock(bodyStmt)) {
407         Error("error when parsing body of foreachelem loop in ");
408         return false;
409     }
410     forNode->SetLoopBody(bodyStmt);
411     return true;
412 }
413 
ParseStmtIf(StmtNodePtr & stmt)414 bool MIRParser::ParseStmtIf(StmtNodePtr &stmt)
415 {
416     if (lexer.GetTokenKind() != TK_if) {
417         Error("expect if but get ");
418         return false;
419     }
420     auto *ifStmt = mod.CurFuncCodeMemPool()->New<IfStmtNode>();
421     lexer.NextToken();
422     BaseNode *expr = nullptr;
423     if (!ParseExprOneOperand(expr)) {
424         return false;
425     }
426     ifStmt->SetOpnd(expr, 0);
427     if (lexer.NextToken() != TK_lbrace) {
428         Error("expect { begin if body but get ");
429         return false;
430     }
431     BlockNode *thenBlock = nullptr;
432     if (!ParseStmtBlock(thenBlock)) {
433         Error("ParseStmtIf failed when parsing then block");
434         return false;
435     }
436     ifStmt->SetThenPart(thenBlock);
437     BlockNode *elseBlock = nullptr;
438     if (lexer.GetTokenKind() == TK_else) {
439         // has else part
440         if (lexer.NextToken() != TK_lbrace) {
441             Error("expect { begin if body but get ");
442             return false;
443         }
444         if (!ParseStmtBlock(elseBlock)) {
445             Error("ParseStmtIf failed when parsing else block");
446             return false;
447         }
448         ifStmt->SetElsePart(elseBlock);
449     }
450     stmt = ifStmt;
451     return true;
452 }
453 
ParseStmtWhile(StmtNodePtr & stmt)454 bool MIRParser::ParseStmtWhile(StmtNodePtr &stmt)
455 {
456     if (lexer.GetTokenKind() != TK_while) {
457         Error("expect while but get ");
458         return false;
459     }
460     auto *whileStmt = mod.CurFuncCodeMemPool()->New<WhileStmtNode>(OP_while);
461     lexer.NextToken();
462     BaseNode *expr = nullptr;
463     if (!ParseExprOneOperand(expr)) {
464         return false;
465     }
466     whileStmt->SetOpnd(expr, 0);
467     if (lexer.NextToken() != TK_lbrace) {
468         Error("expect { begin if body but get ");
469         return false;
470     }
471     BlockNode *whileBody = nullptr;
472     if (!ParseStmtBlock(whileBody)) {
473         Error("ParseStmtWhile failed when parse while body");
474         return false;
475     }
476     whileStmt->SetBody(whileBody);
477     stmt = whileStmt;
478     return true;
479 }
480 
ParseStmtDowhile(StmtNodePtr & stmt)481 bool MIRParser::ParseStmtDowhile(StmtNodePtr &stmt)
482 {
483     if (lexer.GetTokenKind() != TK_dowhile) {
484         Error("expect while but get ");
485         return false;
486     }
487     auto *whileStmt = mod.CurFuncCodeMemPool()->New<WhileStmtNode>(OP_dowhile);
488     if (lexer.NextToken() != TK_lbrace) {
489         Error("expect { begin if body but get ");
490         return false;
491     }
492     BlockNode *doWhileBody = nullptr;
493     if (!ParseStmtBlock(doWhileBody)) {
494         Error("ParseStmtDowhile failed when trying to parsing do while body");
495         return false;
496     }
497     whileStmt->SetBody(doWhileBody);
498     BaseNode *expr = nullptr;
499     if (!ParseExprOneOperand(expr)) {
500         return false;
501     }
502     whileStmt->SetOpnd(expr, 0);
503     lexer.NextToken();
504     stmt = whileStmt;
505     return true;
506 }
507 
ParseStmtLabel(StmtNodePtr & stmt)508 bool MIRParser::ParseStmtLabel(StmtNodePtr &stmt)
509 {
510     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
511     LabelIdx labIdx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(strIdx);
512     if (labIdx == 0) {
513         labIdx = mod.CurFunction()->GetLabelTab()->CreateLabel();
514         mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labIdx, strIdx);
515         mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labIdx);
516     } else {
517         if (definedLabels.size() > labIdx && definedLabels[labIdx]) {
518             Error("label multiply declared ");
519             return false;
520         }
521     }
522     if (definedLabels.size() <= labIdx) {
523         definedLabels.resize(labIdx + 1);
524     }
525     definedLabels[labIdx] = true;
526     auto *labNode = mod.CurFuncCodeMemPool()->New<LabelNode>();
527     labNode->SetLabelIdx(labIdx);
528     stmt = labNode;
529     lexer.NextToken();
530     return true;
531 }
532 
ParseStmtGoto(StmtNodePtr & stmt)533 bool MIRParser::ParseStmtGoto(StmtNodePtr &stmt)
534 {
535     if (lexer.GetTokenKind() != TK_goto) {
536         Error("expect goto but get ");
537         return false;
538     }
539     if (lexer.NextToken() != TK_label) {
540         Error("expect label in goto but get ");
541         return false;
542     }
543     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
544     LabelIdx labIdx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(strIdx);
545     if (labIdx == 0) {
546         labIdx = mod.CurFunction()->GetLabelTab()->CreateLabel();
547         mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labIdx, strIdx);
548         mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labIdx);
549     }
550     auto *gotoNode = mod.CurFuncCodeMemPool()->New<GotoNode>(OP_goto);
551     gotoNode->SetOffset(labIdx);
552     stmt = gotoNode;
553     lexer.NextToken();
554     return true;
555 }
556 
ParseStmtBr(StmtNodePtr & stmt)557 bool MIRParser::ParseStmtBr(StmtNodePtr &stmt)
558 {
559     TokenKind tk = lexer.GetTokenKind();
560     if (tk != TK_brtrue && tk != TK_brfalse) {
561         Error("expect brtrue/brfalse but get ");
562         return false;
563     }
564     if (lexer.NextToken() != TK_label) {
565         Error("expect label in goto but get ");
566         return false;
567     }
568     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
569     LabelIdx labIdx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(strIdx);
570     if (labIdx == 0) {
571         labIdx = mod.CurFunction()->GetLabelTab()->CreateLabel();
572         mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labIdx, strIdx);
573         mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labIdx);
574     }
575     auto *condGoto = mod.CurFuncCodeMemPool()->New<CondGotoNode>(tk == TK_brtrue ? OP_brtrue : OP_brfalse);
576     condGoto->SetOffset(labIdx);
577     lexer.NextToken();
578     // parse (<expr>)
579     BaseNode *expr = nullptr;
580     if (!ParseExprOneOperand(expr)) {
581         return false;
582     }
583     condGoto->SetOpnd(expr, 0);
584     stmt = condGoto;
585     lexer.NextToken();
586     return true;
587 }
588 
ParseSwitchCase(int64 & constVal,LabelIdx & lblIdx)589 bool MIRParser::ParseSwitchCase(int64 &constVal, LabelIdx &lblIdx)
590 {
591     // syntax <intconst0>: goto <label0>
592     if (lexer.GetTokenKind() != TK_intconst) {
593         Error("expect intconst in switch but get ");
594         return false;
595     }
596     constVal = lexer.GetTheIntVal();
597     if (lexer.NextToken() != TK_colon) {
598         Error("expect : in switch but get ");
599         return false;
600     }
601     if (lexer.NextToken() != TK_goto) {
602         Error("expect goto in switch case but get ");
603         return false;
604     }
605     if (lexer.NextToken() != TK_label) {
606         Error("expect label in switch but get ");
607         return false;
608     }
609     lblIdx = mod.CurFunction()->GetOrCreateLableIdxFromName(lexer.GetName());
610     lexer.NextToken();
611     return true;
612 }
613 
ParseStmtSwitch(StmtNodePtr & stmt)614 bool MIRParser::ParseStmtSwitch(StmtNodePtr &stmt)
615 {
616     auto *switchNode = mod.CurFuncCodeMemPool()->New<SwitchNode>(mod);
617     stmt = switchNode;
618     lexer.NextToken();
619     BaseNode *expr = nullptr;
620     if (!ParseExprOneOperand(expr)) {
621         return false;
622     }
623     switchNode->SetSwitchOpnd(expr);
624     if (!IsPrimitiveInteger(expr->GetPrimType())) {
625         Error("expect expression return integer but get ");
626         return false;
627     }
628     if (lexer.NextToken() == TK_label) {
629         switchNode->SetDefaultLabel(mod.CurFunction()->GetOrCreateLableIdxFromName(lexer.GetName()));
630     } else {
631         Error("expect label in switch but get ");
632         return false;
633     }
634     if (lexer.NextToken() != TK_lbrace) {
635         Error("expect { in switch but get ");
636         return false;
637     }
638     // <intconst0>: goto <label0>
639     // <intconst1>: goto <label1>
640     // ...
641     // <intconstn>: goto <labeln>
642     TokenKind tk = lexer.NextToken();
643     std::set<int64> casesSet;
644     while (tk != TK_rbrace) {
645         int64 constVal = 0;
646         LabelIdx lbl = 0;
647         if (!ParseSwitchCase(constVal, lbl)) {
648             Error("parse switch case failed ");
649             return false;
650         }
651         if (casesSet.find(constVal) != casesSet.end()) {
652             Error("duplicated switch case ");
653             return false;
654         }
655         switchNode->InsertCasePair(CasePair(constVal, lbl));
656         (void)casesSet.insert(constVal);
657         tk = lexer.GetTokenKind();
658     }
659     lexer.NextToken();
660     return true;
661 }
662 
ParseStmtRangegoto(StmtNodePtr & stmt)663 bool MIRParser::ParseStmtRangegoto(StmtNodePtr &stmt)
664 {
665     auto *rangeGotoNode = mod.CurFuncCodeMemPool()->New<RangeGotoNode>(mod);
666     stmt = rangeGotoNode;
667     lexer.NextToken();
668     BaseNode *expr = nullptr;
669     if (!ParseExprOneOperand(expr)) {
670         return false;
671     }
672     if (!IsPrimitiveInteger(expr->GetPrimType())) {
673         Error("expect expression return integer but get ");
674         return false;
675     }
676     rangeGotoNode->SetOpnd(expr, 0);
677     if (lexer.NextToken() == TK_intconst) {
678         rangeGotoNode->SetTagOffset(static_cast<int32>(lexer.GetTheIntVal()));
679     } else {
680         Error("expect tag offset in rangegoto but get ");
681         return false;
682     }
683     if (lexer.NextToken() != TK_lbrace) {
684         Error("expect { in switch but get ");
685         return false;
686     }
687     // <intconst0>: goto <label0>
688     // <intconst1>: goto <label1>
689     // ...
690     // <intconstn>: goto <labeln>
691     TokenKind tk = lexer.NextToken();
692     std::set<uint16> casesSet;
693     int32 minIdx = UINT16_MAX;
694     int32 maxIdx = 0;
695     while (tk != TK_rbrace) {
696         int64 constVal = 0;
697         LabelIdx lbl = 0;
698         if (!ParseSwitchCase(constVal, lbl)) {
699             Error("parse switch case failed ");
700             return false;
701         }
702         if (constVal > UINT16_MAX || constVal < 0) {
703             Error("rangegoto case tag not within unsigned 16 bits range ");
704             return false;
705         }
706         if (casesSet.find(constVal) != casesSet.end()) {
707             Error("duplicated switch case ");
708             return false;
709         }
710         if (constVal < minIdx) {
711             minIdx = static_cast<int32>(constVal);
712         }
713         if (constVal > maxIdx) {
714             maxIdx = static_cast<int32>(constVal);
715         }
716         rangeGotoNode->AddRangeGoto(static_cast<uint32>(constVal), static_cast<uint32>(lbl));
717         (void)casesSet.insert(constVal);
718         tk = lexer.GetTokenKind();
719     }
720     DEBUG_ASSERT(rangeGotoNode->GetNumOpnds() == 1, "Rangegoto is a UnaryOpnd; numOpnds must be 1");
721     // check there is no gap
722     if (static_cast<size_t>(static_cast<uint32>(maxIdx - minIdx) + 1) != casesSet.size()) {
723         Error("gap not allowed in rangegoto case tags ");
724         return false;
725     }
726     lexer.NextToken();
727     return true;
728 }
729 
ParseStmtMultiway(StmtNodePtr & stmt)730 bool MIRParser::ParseStmtMultiway(StmtNodePtr &stmt)
731 {
732     auto *multiwayNode = mod.CurFuncCodeMemPool()->New<MultiwayNode>(mod);
733     stmt = multiwayNode;
734     lexer.NextToken();
735     BaseNode *expr = nullptr;
736     if (!ParseExprOneOperand(expr)) {
737         return false;
738     }
739     multiwayNode->SetMultiWayOpnd(expr);
740     if (lexer.NextToken() == TK_label) {
741         multiwayNode->SetDefaultlabel(mod.CurFunction()->GetOrCreateLableIdxFromName(lexer.GetName()));
742     } else {
743         Error("expect label in multiway but get ");
744         return false;
745     }
746     if (lexer.NextToken() != TK_lbrace) {
747         Error("expect { in switch but get ");
748         return false;
749     }
750     // (<expr0>): goto <label0>
751     // (<expr1>): goto <label1>
752     // ...
753     // (<exprn>): goto <labeln>
754     TokenKind tk = lexer.NextToken();
755     while (tk != TK_rbrace) {
756         BaseNode *x = nullptr;
757         if (!ParseExprOneOperand(x)) {
758             return false;
759         }
760         if (lexer.NextToken() != TK_colon) {
761             Error("expect : parsing multiway case tag specification but get ");
762             return false;
763         }
764         if (lexer.NextToken() != TK_goto) {
765             Error("expect goto in multiway case expression but get ");
766             return false;
767         }
768         if (lexer.NextToken() != TK_label) {
769             Error("expect goto label after multiway case expression but get ");
770             return false;
771         }
772         LabelIdx lblIdx = mod.CurFunction()->GetOrCreateLableIdxFromName(lexer.GetName());
773         lexer.NextToken();
774         multiwayNode->AppendElemToMultiWayTable(MCasePair(static_cast<BaseNode *>(x), lblIdx));
775         tk = lexer.GetTokenKind();
776     }
777     const MapleVector<MCasePair> &multiWayTable = multiwayNode->GetMultiWayTable();
778     multiwayNode->SetNumOpnds(multiWayTable.size());
779     lexer.NextToken();
780     return true;
781 }
782 
783 // used only when parsing mmpl
EnterUndeclaredFunction(bool isMcount)784 PUIdx MIRParser::EnterUndeclaredFunction(bool isMcount)
785 {
786     std::string funcName;
787     if (isMcount) {
788         funcName = "_mcount";
789     } else {
790         funcName = lexer.GetName();
791     }
792     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
793     MIRSymbol *funcSt = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
794     funcSt->SetNameStrIdx(strIdx);
795     (void)GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSt);
796     funcSt->SetStorageClass(kScText);
797     funcSt->SetSKind(kStFunc);
798     auto *fn = mod.GetMemPool()->New<MIRFunction>(&mod, funcSt->GetStIdx());
799     fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
800     GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
801     funcSt->SetFunction(fn);
802     auto *funcType = mod.GetMemPool()->New<MIRFuncType>();
803     fn->SetMIRFuncType(funcType);
804     if (isMcount) {
805         MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_void));
806         fn->SetReturnTyIdx(retType->GetTypeIndex());
807     }
808     return fn->GetPuidx();
809 }
810 
ParseStmtCallMcount(StmtNodePtr & stmt)811 bool MIRParser::ParseStmtCallMcount(StmtNodePtr &stmt)
812 {
813     // syntax: call <PU-name> (<opnd0>, ..., <opndn>)
814     Opcode o = OP_call;
815     PUIdx pIdx = EnterUndeclaredFunction(true);
816     auto *callStmt = mod.CurFuncCodeMemPool()->New<CallNode>(mod, o);
817     callStmt->SetPUIdx(pIdx);
818     MapleVector<BaseNode *> opndsvec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
819     callStmt->SetNOpnd(opndsvec);
820     callStmt->SetNumOpnds(opndsvec.size());
821     stmt = callStmt;
822     return true;
823 }
824 
ParseStmtCall(StmtNodePtr & stmt)825 bool MIRParser::ParseStmtCall(StmtNodePtr &stmt)
826 {
827     // syntax: call <PU-name> (<opnd0>, ..., <opndn>)
828     TokenKind tk = lexer.GetTokenKind();
829     Opcode o = GetOpFromToken(tk);
830     DEBUG_ASSERT(kOpcodeInfo.IsCall(o), "ParseStmtCall: not a call opcode");
831     bool hasAssigned = kOpcodeInfo.IsCallAssigned(o);
832     bool hasInstant = false;
833     bool withType = false;
834     switch (tk) {
835         case TK_polymorphiccall:
836         case TK_polymorphiccallassigned:
837             withType = true;
838             break;
839         case TK_callinstant:
840         case TK_virtualcallinstant:
841         case TK_superclasscallinstant:
842         case TK_interfacecallinstant:
843         case TK_callinstantassigned:
844         case TK_virtualcallinstantassigned:
845         case TK_superclasscallinstantassigned:
846         case TK_interfacecallinstantassigned:
847             hasInstant = true;
848             break;
849         default:
850             break;
851     }
852     TyIdx polymophicTyidx(0);
853     if (o == OP_polymorphiccallassigned || o == OP_polymorphiccall) {
854         TokenKind nextTk = lexer.NextToken();
855         if (nextTk == TK_langle) {
856             nextTk = lexer.NextToken();
857             if (nextTk == TK_func) {
858                 lexer.NextToken();
859                 if (!ParseFuncType(polymophicTyidx)) {
860                     Error("error parsing functype in ParseStmtCall for polymorphiccallassigned at ");
861                     return false;
862                 }
863             } else {
864                 Error("expect func in functype but get ");
865                 return false;
866             }
867         } else {
868             Error("expect < in functype but get ");
869             return false;
870         }
871     }
872     TokenKind funcTk = lexer.NextToken();
873     if (funcTk != TK_fname) {
874         Error("expect func name in call but get ");
875         return false;
876     }
877     PUIdx pIdx;
878     if (!ParseDeclaredFunc(pIdx)) {
879         if (mod.GetFlavor() < kMmpl) {
880             Error("expect .mmpl");
881             return false;
882         }
883         pIdx = EnterUndeclaredFunction();
884     }
885     lexer.NextToken();
886     CallNode *callStmt = nullptr;
887     CallinstantNode *callInstantStmt = nullptr;
888     if (withType) {
889         callStmt = mod.CurFuncCodeMemPool()->New<CallNode>(mod, o);
890         callStmt->SetTyIdx(polymophicTyidx);
891     } else if (hasInstant) {
892         TokenKind langleTk = lexer.GetTokenKind();
893         if (langleTk != TK_langle) {
894             Error("missing < in generic method instantiation at ");
895             return false;
896         }
897         TokenKind lbraceTk = lexer.NextToken();
898         if (lbraceTk != TK_lbrace) {
899             Error("missing { in generic method instantiation at ");
900             return false;
901         }
902         MIRInstantVectorType instVecTy;
903         if (!ParseGenericInstantVector(instVecTy)) {
904             Error("error parsing generic method instantiation at ");
905             return false;
906         }
907         TokenKind rangleTk = lexer.GetTokenKind();
908         if (rangleTk != TK_rangle) {
909             Error("missing > in generic method instantiation at ");
910             return false;
911         }
912         TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&instVecTy);
913         callInstantStmt = mod.CurFuncCodeMemPool()->New<CallinstantNode>(mod, o, tyIdx);
914         callStmt = callInstantStmt;
915         lexer.NextToken();  // skip the >
916     } else {
917         callStmt = mod.CurFuncCodeMemPool()->New<CallNode>(mod, o);
918     }
919     callStmt->SetPUIdx(pIdx);
920 
921     MIRFunction *callee = GlobalTables::GetFunctionTable().GetFuncTable()[pIdx];
922     callee->GetFuncSymbol()->SetAppearsInCode(true);
923     if (callee->GetName() == "setjmp") {
924         mod.CurFunction()->SetHasSetjmp();
925     }
926 
927     MapleVector<BaseNode *> opndsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
928     if (!ParseExprNaryOperand(opndsVec)) {
929         return false;
930     }
931     callStmt->SetNOpnd(opndsVec);
932     callStmt->SetNumOpnds(opndsVec.size());
933     if (hasAssigned) {
934         CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
935         if (!ParseCallReturns(retsVec)) {
936             return false;
937         }
938         if (!hasInstant) {
939             DEBUG_ASSERT(callStmt != nullptr, "callstmt is null in MIRParser::ParseStmtCall");
940             callStmt->SetReturnVec(retsVec);
941         } else {
942             DEBUG_ASSERT(callInstantStmt != nullptr, "callinstantstmt is null in MIRParser::ParseStmtCall");
943             callInstantStmt->SetReturnVec(retsVec);
944         }
945     }
946     lexer.NextToken();
947     stmt = callStmt;
948     return true;
949 }
950 
ParseStmtIcall(StmtNodePtr & stmt,Opcode op)951 bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt, Opcode op)
952 {
953     // syntax: icall (<PU-ptr>, <opnd0>, ..., <opndn>)
954     //         icallassigned <PU-ptr> (<opnd0>, ..., <opndn>) {
955     //              dassign <var-name0> <field-id0>
956     //              dassign <var-name1> <field-id1>
957     //               . . .
958     //              dassign <var-namen> <field-idn> }
959     //         icallproto <funcType> (<PU-ptr>, <opnd0>, ..., <opndn>)
960     //         icallprotoassigned <funcType> (<PU-ptr>, <opnd0>, ..., <opndn>) {
961     //              dassign <var-name0> <field-id0>
962     //              dassign <var-name1> <field-id1>
963     //               . . .
964     //              dassign <var-namen> <field-idn> }
965     IcallNode *iCallStmt = mod.CurFuncCodeMemPool()->New<IcallNode>(mod, op);
966     lexer.NextToken();
967     if (op == OP_icallproto || op == OP_icallprotoassigned) {
968         TyIdx tyIdx(0);
969         if (!ParseDerivedType(tyIdx)) {
970             Error("error parsing type in ParseStmtIcall for icallproto at ");
971             return false;
972         }
973         iCallStmt->SetRetTyIdx(tyIdx);
974     }
975     MapleVector<BaseNode *> opndsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
976     if (!ParseExprNaryOperand(opndsVec)) {
977         return false;
978     }
979     iCallStmt->SetNOpnd(opndsVec);
980     iCallStmt->SetNumOpnds(opndsVec.size());
981     if (op == OP_icallassigned || op == OP_icallprotoassigned) {
982         CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
983         if (!ParseCallReturns(retsVec)) {
984             return false;
985         }
986         iCallStmt->SetReturnVec(retsVec);
987     }
988     lexer.NextToken();
989     stmt = iCallStmt;
990     return true;
991 }
992 
ParseStmtIcall(StmtNodePtr & stmt)993 bool MIRParser::ParseStmtIcall(StmtNodePtr &stmt)
994 {
995     return ParseStmtIcall(stmt, OP_icall);
996 }
997 
ParseStmtIcallassigned(StmtNodePtr & stmt)998 bool MIRParser::ParseStmtIcallassigned(StmtNodePtr &stmt)
999 {
1000     return ParseStmtIcall(stmt, OP_icallassigned);
1001 }
1002 
ParseStmtIcallproto(StmtNodePtr & stmt)1003 bool MIRParser::ParseStmtIcallproto(StmtNodePtr &stmt)
1004 {
1005     return ParseStmtIcall(stmt, OP_icallproto);
1006 }
1007 
ParseStmtIcallprotoassigned(StmtNodePtr & stmt)1008 bool MIRParser::ParseStmtIcallprotoassigned(StmtNodePtr &stmt)
1009 {
1010     return ParseStmtIcall(stmt, OP_icallprotoassigned);
1011 }
1012 
ParseStmtIntrinsiccall(StmtNodePtr & stmt,bool isAssigned)1013 bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned)
1014 {
1015     Opcode o = !isAssigned ? (lexer.GetTokenKind() == TK_intrinsiccall ? OP_intrinsiccall : OP_xintrinsiccall)
1016                            : (lexer.GetTokenKind() == TK_intrinsiccallassigned ? OP_intrinsiccallassigned
1017                                                                                : OP_xintrinsiccallassigned);
1018     auto *intrnCallNode = mod.CurFuncCodeMemPool()->New<IntrinsiccallNode>(mod, o);
1019     lexer.NextToken();
1020     if (o == !isAssigned ? OP_intrinsiccall : OP_intrinsiccallassigned) {
1021         intrnCallNode->SetIntrinsic(GetIntrinsicID(lexer.GetTokenKind()));
1022     } else {
1023         intrnCallNode->SetIntrinsic(static_cast<MIRIntrinsicID>(lexer.GetTheIntVal()));
1024     }
1025     lexer.NextToken();
1026     MapleVector<BaseNode *> opndsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
1027     if (!ParseExprNaryOperand(opndsVec)) {
1028         return false;
1029     }
1030     intrnCallNode->SetNOpnd(opndsVec);
1031     intrnCallNode->SetNumOpnds(opndsVec.size());
1032     if (isAssigned) {
1033         CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
1034         if (!ParseCallReturns(retsVec)) {
1035             return false;
1036         }
1037         // store return type of IntrinsiccallNode
1038         if (retsVec.size() == 1 && retsVec[0].first.Idx() != 0) {
1039             MIRSymbol *retSymbol = curFunc->GetSymTab()->GetSymbolFromStIdx(retsVec[0].first.Idx());
1040             MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(retSymbol->GetTyIdx());
1041             CHECK_FATAL(retType != nullptr, "rettype is null in MIRParser::ParseStmtIntrinsiccallAssigned");
1042             intrnCallNode->SetPrimType(retType->GetPrimType());
1043         }
1044         intrnCallNode->SetReturnVec(retsVec);
1045     }
1046     stmt = intrnCallNode;
1047     lexer.NextToken();
1048     return true;
1049 }
1050 
ParseStmtIntrinsiccall(StmtNodePtr & stmt)1051 bool MIRParser::ParseStmtIntrinsiccall(StmtNodePtr &stmt)
1052 {
1053     return ParseStmtIntrinsiccall(stmt, false);
1054 }
1055 
ParseStmtIntrinsiccallassigned(StmtNodePtr & stmt)1056 bool MIRParser::ParseStmtIntrinsiccallassigned(StmtNodePtr &stmt)
1057 {
1058     return ParseStmtIntrinsiccall(stmt, true);
1059 }
1060 
ParseStmtIntrinsiccallwithtype(StmtNodePtr & stmt,bool isAssigned)1061 bool MIRParser::ParseStmtIntrinsiccallwithtype(StmtNodePtr &stmt, bool isAssigned)
1062 {
1063     Opcode o = (!isAssigned) ? OP_intrinsiccallwithtype : OP_intrinsiccallwithtypeassigned;
1064     IntrinsiccallNode *intrnCallNode = mod.CurFuncCodeMemPool()->New<IntrinsiccallNode>(mod, o);
1065     TokenKind tk = lexer.NextToken();
1066     TyIdx tyIdx(0);
1067     if (IsPrimitiveType(tk)) {
1068         if (!ParsePrimType(tyIdx)) {
1069             Error("expect primitive type in ParseStmtIntrinsiccallwithtype but get ");
1070             return false;
1071         }
1072     } else if (!ParseDerivedType(tyIdx)) {
1073         Error("error parsing type in ParseStmtIntrinsiccallwithtype at ");
1074         return false;
1075     }
1076     intrnCallNode->SetTyIdx(tyIdx);
1077     intrnCallNode->SetIntrinsic(GetIntrinsicID(lexer.GetTokenKind()));
1078     lexer.NextToken();
1079     MapleVector<BaseNode *> opndsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
1080     if (!ParseExprNaryOperand(opndsVec)) {
1081         return false;
1082     }
1083     intrnCallNode->SetNOpnd(opndsVec);
1084     intrnCallNode->SetNumOpnds(opndsVec.size());
1085     if (isAssigned) {
1086         CallReturnVector retsVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
1087         if (!ParseCallReturns(retsVec)) {
1088             return false;
1089         }
1090         // store return type of IntrinsiccallNode
1091         if (retsVec.size() == 1 && retsVec[0].first.Idx() != 0) {
1092             MIRSymbol *retSymbol = curFunc->GetSymTab()->GetSymbolFromStIdx(retsVec[0].first.Idx());
1093             MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(retSymbol->GetTyIdx());
1094             CHECK_FATAL(retType != nullptr, "rettype is null in MIRParser::ParseStmtIntrinsiccallwithtypeAssigned");
1095             intrnCallNode->SetPrimType(retType->GetPrimType());
1096         }
1097         intrnCallNode->SetReturnVec(retsVec);
1098     }
1099     stmt = intrnCallNode;
1100     lexer.NextToken();
1101     return true;
1102 }
1103 
ParseStmtIntrinsiccallwithtype(StmtNodePtr & stmt)1104 bool MIRParser::ParseStmtIntrinsiccallwithtype(StmtNodePtr &stmt)
1105 {
1106     return ParseStmtIntrinsiccallwithtype(stmt, false);
1107 }
1108 
ParseStmtIntrinsiccallwithtypeassigned(StmtNodePtr & stmt)1109 bool MIRParser::ParseStmtIntrinsiccallwithtypeassigned(StmtNodePtr &stmt)
1110 {
1111     return ParseStmtIntrinsiccallwithtype(stmt, true);
1112 }
1113 
ParseCallReturnPair(CallReturnPair & retpair)1114 bool MIRParser::ParseCallReturnPair(CallReturnPair &retpair)
1115 {
1116     bool isst = (lexer.GetTokenKind() == TK_dassign);
1117     if (isst) {
1118         // parse %i
1119         lexer.NextToken();
1120         StIdx stidx;
1121         // How to use islocal??
1122         if (!ParseDeclaredSt(stidx)) {
1123             return false;
1124         }
1125         if (lexer.GetTokenKind() == TK_lname) {
1126             MIRSymbolTable *lSymTab = mod.CurFunction()->GetSymTab();
1127             MIRSymbol *lSym = lSymTab->GetSymbolFromStIdx(stidx.Idx(), 0);
1128             DEBUG_ASSERT(lSym != nullptr, "lsym MIRSymbol is null");
1129             if (lSym->GetName().find("L_STR") == 0) {
1130                 MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(lSym->GetTyIdx());
1131                 auto *ptrTy = static_cast<MIRPtrType *>(ty->CopyMIRTypeNode());
1132                 DEBUG_ASSERT(ptrTy != nullptr, "null ptr check");
1133                 ptrTy->SetPrimType(GetExactPtrPrimType());
1134                 TyIdx newTyidx = GlobalTables::GetTypeTable().GetOrCreateMIRType(ptrTy);
1135                 delete ptrTy;
1136                 lSym->SetTyIdx(newTyidx);
1137             }
1138         }
1139         if (stidx.FullIdx() == 0) {
1140             Error("expect a symbol parsing call return assignment but get");
1141             return false;
1142         }
1143         uint16 fieldId = 0;
1144         TokenKind nextToken = lexer.NextToken();
1145         // parse field id
1146         if (nextToken == TK_intconst) {
1147             fieldId = lexer.GetTheIntVal();
1148             lexer.NextToken();
1149         }
1150         RegFieldPair regFieldPair;
1151         regFieldPair.SetFieldID(fieldId);
1152         retpair = CallReturnPair(stidx, regFieldPair);
1153     } else {
1154         // parse type
1155         lexer.NextToken();
1156         TyIdx tyidx(0);
1157         bool ret = ParsePrimType(tyidx);
1158         if (ret != true) {
1159             Error("call ParsePrimType failed in ParseCallReturns");
1160             return false;
1161         }
1162         if (tyidx == 0u) {
1163             Error("expect primitive type but get ");
1164             return false;
1165         }
1166         PrimType ptype = GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx);
1167         PregIdx pregIdx;
1168         if (lexer.GetTokenKind() == TK_specialreg) {
1169             if (!ParseSpecialReg(pregIdx)) {
1170                 Error("expect specialreg parsing callassign CallReturnVector");
1171                 return false;
1172             }
1173         } else if (lexer.GetTokenKind() == TK_preg) {
1174             if (!ParsePseudoReg(ptype, pregIdx)) {
1175                 Error("expect pseudoreg parsing callassign CallReturnVector");
1176                 return false;
1177             }
1178         } else {
1179             Error("expect special or pseudo register but get ");
1180             return false;
1181         }
1182         DEBUG_ASSERT(pregIdx > 0, "register number is zero");
1183         DEBUG_ASSERT(pregIdx <= 0xffff, "register number is over 16 bits");
1184         RegFieldPair regFieldPair;
1185         regFieldPair.SetPregIdx(pregIdx);
1186         retpair = CallReturnPair(StIdx(), regFieldPair);
1187     }
1188     return true;
1189 }
1190 
ParseCallReturns(CallReturnVector & retsvec)1191 bool MIRParser::ParseCallReturns(CallReturnVector &retsvec)
1192 {
1193     //             {
1194     //              dassign <var-name0> <field-id0>
1195     //              dassign <var-name1> <field-id1>
1196     //               . . .
1197     //              dassign <var-namen> <field-idn> }
1198     //              OR
1199     //             {
1200     //               regassign <type> <reg1>
1201     //               regassign <type> <reg2>
1202     //               regassign <type> <reg3>
1203     //             }
1204     if (lexer.NextToken() != TK_lbrace) {
1205         Error("expect { parsing call return values. ");
1206         return false;
1207     }
1208     TokenKind tk = lexer.NextToken();
1209     CallReturnPair retpair;
1210     while (tk != TK_rbrace) {
1211         if (lexer.GetTokenKind() != TK_dassign && lexer.GetTokenKind() != TK_regassign) {
1212             Error("expect dassign/regassign but get ");
1213             return false;
1214         }
1215         if (!ParseCallReturnPair(retpair)) {
1216             Error("error parsing call returns. ");
1217             return false;
1218         }
1219         retsvec.push_back(retpair);
1220         tk = lexer.GetTokenKind();
1221     }
1222     return true;
1223 }
1224 
ParseStmtAsm(StmtNodePtr & stmt)1225 bool MIRParser::ParseStmtAsm(StmtNodePtr &stmt)
1226 {
1227     AsmNode *asmNode = mod.CurFuncCodeMemPool()->New<AsmNode>(&mod.GetCurFuncCodeMPAllocator());
1228     mod.CurFunction()->SetHasAsm();
1229     lexer.NextToken();
1230     // parse qualifiers
1231     while (lexer.GetTokenKind() == TK_volatile || lexer.GetTokenKind() == TK_inline ||
1232            lexer.GetTokenKind() == TK_goto) {
1233         AsmQualifierKind qual;
1234         switch (lexer.GetTokenKind()) {
1235             case TK_volatile: {
1236                 qual = kASMvolatile;
1237                 break;
1238             }
1239             case TK_inline: {
1240                 qual = kASMinline;
1241                 break;
1242             }
1243             case TK_goto:
1244             default: {
1245                 qual = kASMgoto;
1246                 break;
1247             }
1248         }
1249         asmNode->SetQualifier(qual);
1250         lexer.NextToken();
1251     }
1252     // parse open brace
1253     if (lexer.GetTokenKind() != TK_lbrace) {
1254         Error("Open brace not found parsing asm statement.");
1255         return false;
1256     }
1257     lexer.NextToken();
1258     // parse asm string
1259     if (lexer.GetTokenKind() != TK_string) {
1260         Error("asm string not found parsing asm statement.");
1261         return false;
1262     }
1263     asmNode->asmString = lexer.GetName();
1264     lexer.NextToken();
1265     // parse first colon
1266     if (lexer.GetTokenKind() != TK_colon) {
1267         Error("first colon not found parsing asm statement.");
1268         return false;
1269     }
1270     lexer.NextToken();
1271     // parse outputs
1272     UStrIdx uStrIdx;
1273     CallReturnPair retpair;
1274     while (lexer.GetTokenKind() == TK_string) {
1275         // parse an output constraint string
1276         uStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1277         lexer.NextToken();
1278         if (!ParseCallReturnPair(retpair)) {
1279             Error("error parsing call returns. ");
1280             return false;
1281         }
1282         asmNode->outputConstraints.push_back(uStrIdx);
1283         asmNode->asmOutputs.push_back(retpair);
1284         if (lexer.GetTokenKind() == TK_coma) {
1285             lexer.NextToken();
1286         }
1287     }
1288     // parse second colon
1289     if (lexer.GetTokenKind() != TK_colon) {
1290         Error("second colon not found parsing asm statement.");
1291         return false;
1292     }
1293     lexer.NextToken();
1294     // parse inputs
1295     while (lexer.GetTokenKind() == TK_string) {
1296         // parse an input constraint string
1297         uStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1298         if (lexer.GetName()[0] == '+') {
1299             asmNode->SetHasWriteInputs();
1300         }
1301         if (lexer.NextToken() != TK_lparen) {
1302             Error("expect ( but get ");
1303             return false;
1304         }
1305         lexer.NextToken();
1306         BaseNode *expr = nullptr;
1307         if (!ParseExpression(expr)) {
1308             Error("ParseExpression failed");
1309             return false;
1310         }
1311         if (lexer.GetTokenKind() != TK_rparen) {
1312             Error("expect ) but get ");
1313             return false;
1314         }
1315         asmNode->inputConstraints.push_back(uStrIdx);
1316         asmNode->GetNopnd().push_back(expr);
1317         if (lexer.NextToken() == TK_coma) {
1318             lexer.NextToken();
1319         }
1320     }
1321     asmNode->SetNumOpnds(static_cast<uint8>(asmNode->GetNopndSize()));
1322     // parse third colon
1323     if (lexer.GetTokenKind() != TK_colon) {
1324         Error("third colon not found parsing asm statement.");
1325         return false;
1326     }
1327     lexer.NextToken();
1328     // parse clobber list
1329     while (lexer.GetTokenKind() == TK_string) {
1330         // parse an input constraint string
1331         uStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1332         asmNode->clobberList.push_back(uStrIdx);
1333         if (lexer.NextToken() == TK_coma) {
1334             lexer.NextToken();
1335         }
1336     }
1337     // parse fourth colon
1338     if (lexer.GetTokenKind() != TK_colon) {
1339         Error("fourth colon not found parsing asm statement.");
1340         return false;
1341     }
1342     lexer.NextToken();
1343     // parse labels
1344     while (lexer.GetTokenKind() == TK_label) {
1345         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1346         LabelIdx labIdx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(strIdx);
1347         if (labIdx == 0) {
1348             labIdx = mod.CurFunction()->GetLabelTab()->CreateLabel();
1349             mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labIdx, strIdx);
1350             mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labIdx);
1351         }
1352         asmNode->gotoLabels.push_back(labIdx);
1353         if (lexer.NextToken() == TK_coma) {
1354             lexer.NextToken();
1355         }
1356     }
1357     // parse closing brace
1358     if (lexer.GetTokenKind() != TK_rbrace) {
1359         Error("Closing brace not found parsing asm statement.");
1360         return false;
1361     }
1362     stmt = asmNode;
1363     lexer.NextToken();
1364     return true;
1365 }
1366 
ParseStmtSafeRegion(StmtNodePtr & stmt)1367 bool MIRParser::ParseStmtSafeRegion(StmtNodePtr &stmt)
1368 {
1369     switch (lexer.GetTokenKind()) {
1370         case TK_safe:
1371             safeRegionFlag.push(true);
1372             break;
1373         case TK_unsafe:
1374             safeRegionFlag.push(false);
1375             break;
1376         case TK_endsafe:
1377         case TK_endunsafe:
1378             safeRegionFlag.pop();
1379             break;
1380         default:
1381             Error("Only support safe/unsafe/endsafe/endunsafe.");
1382             return false;
1383     }
1384     (void)stmt;
1385     lexer.NextToken();
1386     return true;
1387 }
1388 
ParseStmtJsTry(StmtNodePtr & stmt)1389 bool MIRParser::ParseStmtJsTry(StmtNodePtr &stmt)
1390 {
1391     auto *tryNode = mod.CurFuncCodeMemPool()->New<JsTryNode>();
1392     lexer.NextToken();
1393     // parse handler label
1394     if (lexer.GetTokenKind() == TK_intconst && lexer.GetTheIntVal() == 0) {
1395         tryNode->SetCatchOffset(0);
1396     } else {
1397         if (lexer.GetTokenKind() != TK_label) {
1398             Error("expect handler label in try but get ");
1399             return false;
1400         }
1401         GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1402         LabelIdx labidx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(stridx);
1403         if (labidx == 0) {
1404             labidx = mod.CurFunction()->GetLabelTab()->CreateLabel();
1405             mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labidx, stridx);
1406             mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labidx);
1407         }
1408         tryNode->SetCatchOffset(labidx);
1409     }
1410     lexer.NextToken();
1411     // parse finally label
1412     if (lexer.GetTokenKind() == TK_intconst && lexer.GetTheIntVal() == 0) {
1413         tryNode->SetFinallyOffset(0);
1414     } else {
1415         if (lexer.GetTokenKind() != TK_label) {
1416             Error("expect finally label in try but get ");
1417             return false;
1418         }
1419         GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1420         LabelIdx labidx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(stridx);
1421         if (labidx == 0) {
1422             labidx = mod.CurFunction()->GetLabelTab()->CreateLabel();
1423             mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labidx, stridx);
1424             mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labidx);
1425         }
1426         tryNode->SetFinallyOffset(labidx);
1427     }
1428     stmt = tryNode;
1429     lexer.NextToken();
1430     return true;
1431 }
1432 
ParseStmtTry(StmtNodePtr & stmt)1433 bool MIRParser::ParseStmtTry(StmtNodePtr &stmt)
1434 {
1435     auto *tryNode = mod.CurFuncCodeMemPool()->New<TryNode>(mod);
1436     lexer.NextToken();
1437     DEBUG_ASSERT(lexer.GetTokenKind() == TK_lbrace, "expect left brace in try but get ");
1438     lexer.NextToken();
1439     // parse handler label
1440     while (lexer.GetTokenKind() != TK_rbrace) {
1441         if (lexer.GetTokenKind() != TK_label) {
1442             Error("expect handler label in try but get ");
1443             return false;
1444         }
1445         GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1446         LabelIdx labidx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(stridx);
1447         if (labidx == 0) {
1448             labidx = mod.CurFunction()->GetLabelTab()->CreateLabel();
1449             mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labidx, stridx);
1450             mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labidx);
1451         }
1452         tryNode->AddOffset(labidx);
1453         lexer.NextToken();
1454     }
1455     stmt = tryNode;
1456     lexer.NextToken();
1457     return true;
1458 }
1459 
ParseStmtCatch(StmtNodePtr & stmt)1460 bool MIRParser::ParseStmtCatch(StmtNodePtr &stmt)
1461 {
1462     auto *catchNode = mod.CurFuncCodeMemPool()->New<CatchNode>(mod);
1463     lexer.NextToken();
1464     DEBUG_ASSERT(lexer.GetTokenKind() == TK_lbrace, "expect left brace in catch but get ");
1465     lexer.NextToken();
1466     while (lexer.GetTokenKind() != TK_rbrace) {
1467         TyIdx tyidx(0);
1468         if (!ParseType(tyidx)) {
1469             Error("expect type parsing java catch statement");
1470             return false;
1471         }
1472         catchNode->PushBack(tyidx);
1473     }
1474     catchNode->SetNumOpnds(0);
1475     stmt = catchNode;
1476     lexer.NextToken();
1477     return true;
1478 }
1479 
ParseUnaryStmt(Opcode op,StmtNodePtr & stmt)1480 bool MIRParser::ParseUnaryStmt(Opcode op, StmtNodePtr &stmt)
1481 {
1482     lexer.NextToken();
1483     auto *throwStmt = mod.CurFuncCodeMemPool()->New<UnaryStmtNode>(op);
1484     stmt = throwStmt;
1485     BaseNode *expr = nullptr;
1486     if (!ParseExprOneOperand(expr)) {
1487         return false;
1488     }
1489     throwStmt->SetOpnd(expr, 0);
1490     lexer.NextToken();
1491     return true;
1492 }
1493 
ParseUnaryStmtThrow(StmtNodePtr & stmt)1494 bool MIRParser::ParseUnaryStmtThrow(StmtNodePtr &stmt)
1495 {
1496     return ParseUnaryStmt(OP_throw, stmt);
1497 }
1498 
ParseUnaryStmtDecRef(StmtNodePtr & stmt)1499 bool MIRParser::ParseUnaryStmtDecRef(StmtNodePtr &stmt)
1500 {
1501     return ParseUnaryStmt(OP_decref, stmt);
1502 }
1503 
ParseUnaryStmtIncRef(StmtNodePtr & stmt)1504 bool MIRParser::ParseUnaryStmtIncRef(StmtNodePtr &stmt)
1505 {
1506     return ParseUnaryStmt(OP_incref, stmt);
1507 }
1508 
ParseUnaryStmtDecRefReset(StmtNodePtr & stmt)1509 bool MIRParser::ParseUnaryStmtDecRefReset(StmtNodePtr &stmt)
1510 {
1511     return ParseUnaryStmt(OP_decrefreset, stmt);
1512 }
1513 
ParseUnaryStmtIGoto(StmtNodePtr & stmt)1514 bool MIRParser::ParseUnaryStmtIGoto(StmtNodePtr &stmt)
1515 {
1516     return ParseUnaryStmt(OP_igoto, stmt);
1517 }
1518 
ParseUnaryStmtEval(StmtNodePtr & stmt)1519 bool MIRParser::ParseUnaryStmtEval(StmtNodePtr &stmt)
1520 {
1521     return ParseUnaryStmt(OP_eval, stmt);
1522 }
1523 
ParseUnaryStmtFree(StmtNodePtr & stmt)1524 bool MIRParser::ParseUnaryStmtFree(StmtNodePtr &stmt)
1525 {
1526     return ParseUnaryStmt(OP_free, stmt);
1527 }
1528 
ParseUnaryStmtCallAssertNonNull(StmtNodePtr & stmt)1529 bool MIRParser::ParseUnaryStmtCallAssertNonNull(StmtNodePtr &stmt)
1530 {
1531     std::string funcName;
1532     std::string stmtFuncName;
1533     int index = 0;
1534     if (!ParseCallAssertInfo(funcName, &index, stmtFuncName)) {
1535         Error("ParseCallAssertInfo failed");
1536         return false;
1537     }
1538     lexer.NextToken();
1539     GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
1540     GStrIdx stmtstridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(stmtFuncName);
1541     stmt = mod.CurFuncCodeMemPool()->New<CallAssertNonnullStmtNode>(OP_callassertnonnull, stridx, index, stmtstridx);
1542     BaseNode *expr = nullptr;
1543     if (!ParseExprOneOperand(expr)) {
1544         return false;
1545     }
1546     stmt->SetOpnd(expr, 0);
1547     lexer.NextToken();
1548     return true;
1549 }
1550 
ParseAssertInfo(std::string & funcName)1551 bool MIRParser::ParseAssertInfo(std::string &funcName)
1552 {
1553     if (lexer.NextToken() != TK_langle) {
1554         Error("expect < parsing safey assert check ");
1555         return false;
1556     }
1557     if (lexer.NextToken() != TK_fname) {
1558         Error("expect &funcname parsing parsing safey assert check ");
1559         return false;
1560     }
1561     funcName = lexer.GetName();
1562     if (lexer.NextToken() != TK_rangle) {
1563         Error("expect > parsing safey assert check ");
1564         return false;
1565     }
1566     return true;
1567 }
1568 
ParseUnaryStmtAssertNonNullCheck(Opcode op,StmtNodePtr & stmt)1569 bool MIRParser::ParseUnaryStmtAssertNonNullCheck(Opcode op, StmtNodePtr &stmt)
1570 {
1571     std::string funcName;
1572     if (!ParseAssertInfo(funcName)) {
1573         Error("ParseAssertInfo failed");
1574         return false;
1575     }
1576     GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
1577     lexer.NextToken();
1578     stmt = mod.CurFuncCodeMemPool()->New<AssertNonnullStmtNode>(op, stridx);
1579     BaseNode *expr = nullptr;
1580     if (!ParseExprOneOperand(expr)) {
1581         return false;
1582     }
1583     stmt->SetOpnd(expr, 0);
1584     lexer.NextToken();
1585     return true;
1586 }
1587 
ParseUnaryStmtAssertNonNull(StmtNodePtr & stmt)1588 bool MIRParser::ParseUnaryStmtAssertNonNull(StmtNodePtr &stmt)
1589 {
1590     if (mod.IsCModule()) {
1591         return ParseUnaryStmtAssertNonNullCheck(OP_assertnonnull, stmt);
1592     } else {
1593         return ParseUnaryStmt(OP_assertnonnull, stmt);
1594     }
1595 }
1596 
ParseUnaryStmtAssignAssertNonNull(StmtNodePtr & stmt)1597 bool MIRParser::ParseUnaryStmtAssignAssertNonNull(StmtNodePtr &stmt)
1598 {
1599     return ParseUnaryStmtAssertNonNullCheck(OP_assignassertnonnull, stmt);
1600 }
1601 
ParseUnaryStmtReturnAssertNonNull(StmtNodePtr & stmt)1602 bool MIRParser::ParseUnaryStmtReturnAssertNonNull(StmtNodePtr &stmt)
1603 {
1604     return ParseUnaryStmtAssertNonNullCheck(OP_returnassertnonnull, stmt);
1605 }
1606 
ParseStmtMarker(StmtNodePtr & stmt)1607 bool MIRParser::ParseStmtMarker(StmtNodePtr &stmt)
1608 {
1609     Opcode op;
1610     switch (paramTokenKindForStmt) {
1611         case TK_jscatch:
1612             op = OP_jscatch;
1613             break;
1614         case TK_finally:
1615             op = OP_finally;
1616             break;
1617         case TK_cleanuptry:
1618             op = OP_cleanuptry;
1619             break;
1620         case TK_endtry:
1621             op = OP_endtry;
1622             break;
1623         case TK_retsub:
1624             op = OP_retsub;
1625             break;
1626         case TK_membaracquire:
1627             op = OP_membaracquire;
1628             break;
1629         case TK_membarrelease:
1630             op = OP_membarrelease;
1631             break;
1632         case TK_membarstoreload:
1633             op = OP_membarstoreload;
1634             break;
1635         case TK_membarstorestore:
1636             op = OP_membarstorestore;
1637             break;
1638         default:
1639             return false;
1640     }
1641     auto *stmtNode = mod.CurFuncCodeMemPool()->New<StmtNode>(op);
1642     stmt = stmtNode;
1643     lexer.NextToken();
1644     return true;
1645 }
1646 
ParseStmtGosub(StmtNodePtr & stmt)1647 bool MIRParser::ParseStmtGosub(StmtNodePtr &stmt)
1648 {
1649     if (lexer.NextToken() != TK_label) {
1650         Error("expect finally label in gosub but get ");
1651         return false;
1652     }
1653     GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1654     LabelIdx labidx = mod.CurFunction()->GetLabelTab()->GetLabelIdxFromStrIdx(stridx);
1655     if (labidx == 0) {
1656         labidx = mod.CurFunction()->GetLabelTab()->CreateLabel();
1657         mod.CurFunction()->GetLabelTab()->SetSymbolFromStIdx(labidx, stridx);
1658         mod.CurFunction()->GetLabelTab()->AddToStringLabelMap(labidx);
1659     }
1660     auto *goSubNode = mod.CurFuncCodeMemPool()->New<GotoNode>(OP_gosub);
1661     goSubNode->SetOffset(labidx);
1662     stmt = goSubNode;
1663     lexer.NextToken();
1664     return true;
1665 }
1666 
ParseBinaryStmt(StmtNodePtr & stmt,Opcode op)1667 bool MIRParser::ParseBinaryStmt(StmtNodePtr &stmt, Opcode op)
1668 {
1669     auto *assStmt = mod.CurFuncCodeMemPool()->New<BinaryStmtNode>(op);
1670     lexer.NextToken();
1671     BaseNode *opnd0 = nullptr;
1672     BaseNode *opnd1 = nullptr;
1673     if (!ParseExprTwoOperand(opnd0, opnd1)) {
1674         return false;
1675     }
1676     assStmt->SetBOpnd(opnd0, 0);
1677     assStmt->SetBOpnd(opnd1, 1);
1678     stmt = assStmt;
1679     lexer.NextToken();
1680     return true;
1681 }
1682 
ParseNaryStmtAssert(StmtNodePtr & stmt,Opcode op)1683 bool MIRParser::ParseNaryStmtAssert(StmtNodePtr &stmt, Opcode op)
1684 {
1685     std::string funcName;
1686     if (!ParseAssertInfo(funcName)) {
1687         Error("ParseAssertInfo failed");
1688         return false;
1689     }
1690     GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
1691     auto *assStmt = mod.CurFuncCodeMemPool()->New<AssertBoundaryStmtNode>(mod, op, stridx);
1692     if (!ParseNaryExpr(*assStmt)) {
1693         Error("ParseNaryStmtAssert failed");
1694         return false;
1695     }
1696     assStmt->SetNumOpnds(static_cast<uint8>(assStmt->GetNopndSize()));
1697     stmt = assStmt;
1698     lexer.NextToken();
1699     return true;
1700 }
1701 
ParseNaryStmtAssertGE(StmtNodePtr & stmt)1702 bool MIRParser::ParseNaryStmtAssertGE(StmtNodePtr &stmt)
1703 {
1704     return ParseNaryStmtAssert(stmt, OP_assertge);
1705 }
1706 
ParseNaryStmtAssertLT(StmtNodePtr & stmt)1707 bool MIRParser::ParseNaryStmtAssertLT(StmtNodePtr &stmt)
1708 {
1709     return ParseNaryStmtAssert(stmt, OP_assertlt);
1710 }
1711 
ParseNaryStmtReturnAssertLE(StmtNodePtr & stmt)1712 bool MIRParser::ParseNaryStmtReturnAssertLE(StmtNodePtr &stmt)
1713 {
1714     return ParseNaryStmtAssert(stmt, OP_returnassertle);
1715 }
1716 
ParseNaryStmtAssignAssertLE(StmtNodePtr & stmt)1717 bool MIRParser::ParseNaryStmtAssignAssertLE(StmtNodePtr &stmt)
1718 {
1719     return ParseNaryStmtAssert(stmt, OP_assignassertle);
1720 }
1721 
ParseNaryStmtCalcassertGE(StmtNodePtr & stmt)1722 bool MIRParser::ParseNaryStmtCalcassertGE(StmtNodePtr &stmt)
1723 {
1724     return ParseNaryStmtAssert(stmt, OP_calcassertge);
1725 }
1726 
ParseNaryStmtCalcassertLT(StmtNodePtr & stmt)1727 bool MIRParser::ParseNaryStmtCalcassertLT(StmtNodePtr &stmt)
1728 {
1729     return ParseNaryStmtAssert(stmt, OP_calcassertlt);
1730 }
1731 
ParseCallAssertInfo(std::string & funcName,int * paramIndex,std::string & stmtFuncName)1732 bool MIRParser::ParseCallAssertInfo(std::string &funcName, int *paramIndex, std::string &stmtFuncName)
1733 {
1734     if (lexer.NextToken() != TK_langle) {
1735         Error("expect < parsing safey call check ");
1736         return false;
1737     }
1738     if (lexer.NextToken() != TK_fname) {
1739         Error("expect &funcname parsing parsing safey call check ");
1740         return false;
1741     }
1742     funcName = lexer.GetName();
1743     if (lexer.NextToken() != TK_coma) {
1744         Error("expect , parsing parsing safey call check ");
1745         return false;
1746     }
1747     if (lexer.NextToken() != TK_intconst) {
1748         Error("expect intconst parsing parsing safey call check ");
1749         return false;
1750     }
1751     *paramIndex = static_cast<int>(lexer.GetTheIntVal());
1752     if (lexer.NextToken() != TK_coma) {
1753         Error("expect , parsing parsing safey call check ");
1754         return false;
1755     }
1756     if (lexer.NextToken() != TK_fname) {
1757         Error("expect &stmtfuncname parsing parsing safey call check ");
1758         return false;
1759     }
1760     stmtFuncName = lexer.GetName();
1761     if (lexer.NextToken() != TK_rangle) {
1762         Error("expect > parsing parsing safey call check ");
1763         return false;
1764     }
1765     return true;
1766 }
1767 
ParseNaryStmtCallAssertLE(StmtNodePtr & stmt)1768 bool MIRParser::ParseNaryStmtCallAssertLE(StmtNodePtr &stmt)
1769 {
1770     std::string funcName;
1771     std::string stmtFuncName;
1772     int index = 0;
1773     if (!ParseCallAssertInfo(funcName, &index, stmtFuncName)) {
1774         Error("ParseCallAssertInfo failed");
1775         return false;
1776     }
1777     GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
1778     GStrIdx stmtstridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(stmtFuncName);
1779     auto *assStmt =
1780         mod.CurFuncCodeMemPool()->New<CallAssertBoundaryStmtNode>(mod, OP_callassertle, stridx, index, stmtstridx);
1781     if (!ParseNaryExpr(*assStmt)) {
1782         Error("ParseNaryExpr failed");
1783         return false;
1784     }
1785     assStmt->SetNumOpnds(static_cast<uint8>(assStmt->GetNopndSize()));
1786     stmt = assStmt;
1787     lexer.NextToken();
1788     return true;
1789 }
1790 
ParseNaryExpr(NaryStmtNode & stmtNode)1791 bool MIRParser::ParseNaryExpr(NaryStmtNode &stmtNode)
1792 {
1793     if (lexer.NextToken() != TK_lparen) {
1794         Error("expect ( parsing NaryExpr ");
1795         return false;
1796     }
1797     (void)lexer.NextToken();  // skip TK_lparen
1798     while (lexer.GetTokenKind() != TK_rparen) {
1799         BaseNode *expr = nullptr;
1800         if (!ParseExpression(expr)) {
1801             Error("ParseStmtReturn failed");
1802             return false;
1803         }
1804         stmtNode.GetNopnd().push_back(expr);
1805         if (lexer.GetTokenKind() != TK_coma && lexer.GetTokenKind() != TK_rparen) {
1806             Error("expect , or ) parsing NaryStmt");
1807             return false;
1808         }
1809         if (lexer.GetTokenKind() == TK_coma) {
1810             lexer.NextToken();
1811         }
1812     }
1813     return true;
1814 }
1815 
ParseNaryStmt(StmtNodePtr & stmt,Opcode op)1816 bool MIRParser::ParseNaryStmt(StmtNodePtr &stmt, Opcode op)
1817 {
1818     auto *stmtReturn = mod.CurFuncCodeMemPool()->New<NaryStmtNode>(mod, op);
1819     if (op == OP_syncenter) {  // old code reconstruct later
1820         if (lexer.NextToken() != TK_lparen) {
1821             Error("expect return with ( but get ");
1822             return false;
1823         }
1824         lexer.NextToken();
1825         BaseNode *expr = nullptr;
1826         if (!ParseExpression(expr)) {
1827             Error("ParseStmtReturn failed");
1828             return false;
1829         }
1830         stmtReturn->GetNopnd().push_back(expr);
1831         if (lexer.GetTokenKind() == TK_coma) {
1832             lexer.NextToken();
1833             BaseNode *exprSync = nullptr;
1834             if (!ParseExpression(exprSync)) {
1835                 Error("ParseStmtReturn failed");
1836                 return false;
1837             }
1838             stmtReturn->GetNopnd().push_back(exprSync);
1839         } else {
1840             MIRType *intType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(PTY_i32));
1841             // default 2 for __sync_enter_fast()
1842             MIRIntConst *intConst = GlobalTables::GetIntConstTable().GetOrCreateIntConst(2, *intType);
1843             ConstvalNode *exprConst = mod.GetMemPool()->New<ConstvalNode>();
1844             exprConst->SetPrimType(PTY_i32);
1845             exprConst->SetConstVal(intConst);
1846             stmtReturn->GetNopnd().push_back(exprConst);
1847             stmtReturn->SetNumOpnds(stmtReturn->GetNopndSize());
1848         }
1849 
1850         if (lexer.GetTokenKind() != TK_rparen) {
1851             Error("expect ) parsing NaryStmt");
1852             return false;
1853         }
1854     } else if (!ParseNaryExpr(*stmtReturn)) {
1855         Error("ParseNaryExpr failed");
1856         return false;
1857     }
1858     stmtReturn->SetNumOpnds(stmtReturn->GetNopndSize());
1859     stmt = stmtReturn;
1860     lexer.NextToken();
1861     return true;
1862 }
1863 
ParseNaryStmtReturn(StmtNodePtr & stmt)1864 bool MIRParser::ParseNaryStmtReturn(StmtNodePtr &stmt)
1865 {
1866     return ParseNaryStmt(stmt, OP_return);
1867 }
1868 
ParseNaryStmtSyncEnter(StmtNodePtr & stmt)1869 bool MIRParser::ParseNaryStmtSyncEnter(StmtNodePtr &stmt)
1870 {
1871     return ParseNaryStmt(stmt, OP_syncenter);
1872 }
1873 
ParseNaryStmtSyncExit(StmtNodePtr & stmt)1874 bool MIRParser::ParseNaryStmtSyncExit(StmtNodePtr &stmt)
1875 {
1876     return ParseNaryStmt(stmt, OP_syncexit);
1877 }
1878 
ParseLoc()1879 bool MIRParser::ParseLoc()
1880 {
1881     if (lexer.NextToken() != TK_intconst) {
1882         Error("expect intconst in LOC but get ");
1883         return false;
1884     }
1885     lastFileNum = lexer.GetTheIntVal();
1886     if (lexer.NextToken() != TK_intconst) {
1887         Error("expect intconst in LOC but get ");
1888         return false;
1889     }
1890     lastLineNum = lexer.GetTheIntVal();
1891     if (firstLineNum == 0) {
1892         firstLineNum = lastLineNum;
1893     }
1894     if (lexer.NextToken() == TK_intconst) {  // optional column number
1895         lastColumnNum = static_cast<uint16>(lexer.GetTheIntVal());
1896         lexer.NextToken();
1897     }
1898     return true;
1899 }
1900 
ParseLocStmt(StmtNodePtr &)1901 bool MIRParser::ParseLocStmt(StmtNodePtr &)
1902 {
1903     return ParseLoc();
1904 }
1905 
ParseStatement(StmtNodePtr & stmt)1906 bool MIRParser::ParseStatement(StmtNodePtr &stmt)
1907 {
1908     paramTokenKindForStmt = lexer.GetTokenKind();
1909     uint32 mplNum = lexer.GetLineNum();
1910     uint32 lnum = lastLineNum;
1911     uint32 fnum = lastFileNum;
1912     uint16 cnum = lastColumnNum;
1913     std::map<TokenKind, FuncPtrParseStmt>::iterator itFuncPtr = funcPtrMapForParseStmt.find(paramTokenKindForStmt);
1914     if (itFuncPtr != funcPtrMapForParseStmt.end()) {
1915         if (!(this->*(itFuncPtr->second))(stmt)) {
1916             return false;
1917         }
1918     } else {
1919         return false;
1920     }
1921     if (stmt && stmt->GetSrcPos().MplLineNum() == 0) {
1922         stmt->GetSrcPos().SetFileNum(fnum);
1923         stmt->GetSrcPos().SetLineNum(lnum);
1924         stmt->GetSrcPos().SetColumn(cnum);
1925         stmt->GetSrcPos().SetMplLineNum(mplNum);
1926         if (safeRegionFlag.top()) {
1927             stmt->SetInSafeRegion();
1928         }
1929     }
1930     return true;
1931 }
1932 
1933 /* parse the statements enclosed by { and }
1934  */
ParseStmtBlock(BlockNodePtr & blk)1935 bool MIRParser::ParseStmtBlock(BlockNodePtr &blk)
1936 {
1937     if (lexer.GetTokenKind() != TK_lbrace) {
1938         Error("expect { for func body but get ");
1939         return false;
1940     }
1941     blk = mod.CurFuncCodeMemPool()->New<BlockNode>();
1942     MIRFunction *fn = mod.CurFunction();
1943     paramCurrFuncForParseStmtBlock = fn;
1944     lexer.NextToken();
1945     // Insert _mcount for PI.
1946     if (mod.GetWithProfileInfo()) {
1947         StmtNode *stmtt = nullptr;
1948         if (!ParseStmtCallMcount(stmtt)) {
1949             return false;
1950         }
1951         blk->AddStatement(stmtt);
1952     }
1953     while (true) {
1954         TokenKind stmtTk = lexer.GetTokenKind();
1955         // calculate the mpl file line number mplNum here to get accurate result
1956         uint32 mplNum = lexer.GetLineNum();
1957         if (IsStatement(stmtTk)) {
1958             ParseStmtBlockForSeenComment(blk, mplNum);
1959             StmtNode *stmt = nullptr;
1960             if (!ParseStatement(stmt)) {
1961                 Error("ParseStmtBlock failed when parsing a statement");
1962                 return false;
1963             }
1964             if (stmt != nullptr) {  // stmt is nullptr if it is a LOC
1965                 blk->AddStatement(stmt);
1966             }
1967         } else {
1968             std::map<TokenKind, FuncPtrParseStmtBlock>::iterator itFuncPtr = funcPtrMapForParseStmtBlock.find(stmtTk);
1969             if (itFuncPtr == funcPtrMapForParseStmtBlock.end()) {
1970                 if (stmtTk == TK_rbrace) {
1971                     ParseStmtBlockForSeenComment(blk, mplNum);
1972                     lexer.NextToken();
1973                     return true;
1974                 } else {
1975                     Error("expect } or var or statement for func body but get ");
1976                     return false;
1977                 }
1978             } else {
1979                 if (!(this->*(itFuncPtr->second))()) {
1980                     return false;
1981                 }
1982             }
1983         }
1984     }
1985 }
1986 
ParseStmtBlockForSeenComment(BlockNodePtr blk,uint32 mplNum)1987 void MIRParser::ParseStmtBlockForSeenComment(BlockNodePtr blk, uint32 mplNum)
1988 {
1989     if (Options::noComment) {
1990         lexer.seenComments.clear();
1991         return;
1992     }
1993     // collect accumulated comments into comment statement nodes
1994     if (!lexer.seenComments.empty()) {
1995         for (size_t i = 0; i < lexer.seenComments.size(); ++i) {
1996             auto *cmnt = mod.CurFuncCodeMemPool()->New<CommentNode>(mod);
1997             cmnt->SetComment(lexer.seenComments[i]);
1998             SetSrcPos(cmnt->GetSrcPos(), mplNum);
1999             blk->AddStatement(cmnt);
2000         }
2001         lexer.seenComments.clear();
2002     }
2003 }
2004 
ParseStmtBlockForVar(TokenKind stmtTK)2005 bool MIRParser::ParseStmtBlockForVar(TokenKind stmtTK)
2006 {
2007     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2008     MIRSymbol *st = fn->GetSymTab()->CreateSymbol(kScopeLocal);
2009     st->SetStorageClass(kScAuto);
2010     st->SetSKind(kStVar);
2011     SetSrcPos(st->GetSrcPosition(), lexer.GetLineNum());
2012     if (stmtTK == TK_tempvar) {
2013         st->SetIsTmp(true);
2014     }
2015     if (!ParseDeclareVar(*st)) {
2016         return false;
2017     }
2018     if (!fn->GetSymTab()->AddToStringSymbolMap(*st)) {
2019         Error("duplicate declare symbol parse function ");
2020         return false;
2021     }
2022     if (!ParseDeclareVarInitValue(*st)) {
2023         return false;
2024     }
2025     return true;
2026 }
2027 
ParseStmtBlockForVar()2028 bool MIRParser::ParseStmtBlockForVar()
2029 {
2030     return ParseStmtBlockForVar(TK_var);
2031 }
2032 
ParseStmtBlockForTempVar()2033 bool MIRParser::ParseStmtBlockForTempVar()
2034 {
2035     return ParseStmtBlockForVar(TK_tempvar);
2036 }
2037 
ParseStmtBlockForReg()2038 bool MIRParser::ParseStmtBlockForReg()
2039 {
2040     lexer.NextToken();
2041     if (lexer.GetTokenKind() != TK_preg) {
2042         Error("expect %%preg after reg");
2043         return false;
2044     }
2045     PregIdx pregIdx;
2046     if (!ParsePseudoReg(PTY_ref, pregIdx)) {
2047         return false;
2048     }
2049     MIRPreg *preg = mod.CurFunction()->GetPregTab()->PregFromPregIdx(pregIdx);
2050     TyIdx tyidx(0);
2051     if (!ParseType(tyidx)) {
2052         Error("ParseDeclareVar failed when parsing the type");
2053         return false;
2054     }
2055     DEBUG_ASSERT(tyidx > 0u, "parse declare var failed ");
2056     MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyidx);
2057     preg->SetMIRType(mirType);
2058     if (lexer.GetTokenKind() == TK_intconst) {
2059         int64 theIntVal = lexer.GetTheIntVal();
2060         if (theIntVal != 0 && theIntVal != 1) {
2061             Error("parseDeclareReg failed");
2062             return false;
2063         }
2064         preg->SetNeedRC(theIntVal == 0 ? false : true);
2065     } else {
2066         Error("parseDeclareReg failed");
2067         return false;
2068     }
2069     lexer.NextToken();
2070     return true;
2071 }
2072 
ParseStmtBlockForType()2073 bool MIRParser::ParseStmtBlockForType()
2074 {
2075     paramParseLocalType = true;
2076     if (!ParseTypedef()) {
2077         return false;
2078     }
2079     return true;
2080 }
2081 
ParseStmtBlockForFrameSize()2082 bool MIRParser::ParseStmtBlockForFrameSize()
2083 {
2084     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2085     lexer.NextToken();
2086     if (lexer.GetTokenKind() != TK_intconst) {
2087         Error("expect integer after frameSize but get ");
2088         return false;
2089     }
2090     fn->SetFrameSize(lexer.GetTheIntVal());
2091     lexer.NextToken();
2092     return true;
2093 }
2094 
ParseStmtBlockForUpformalSize()2095 bool MIRParser::ParseStmtBlockForUpformalSize()
2096 {
2097     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2098     lexer.NextToken();
2099     if (lexer.GetTokenKind() != TK_intconst) {
2100         Error("expect integer after upFormalSize but get ");
2101         return false;
2102     }
2103     fn->SetUpFormalSize(lexer.GetTheIntVal());
2104     lexer.NextToken();
2105     return true;
2106 }
2107 
ParseStmtBlockForModuleID()2108 bool MIRParser::ParseStmtBlockForModuleID()
2109 {
2110     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2111     lexer.NextToken();
2112     if (lexer.GetTokenKind() != TK_intconst) {
2113         Error("expect integer after moduleid but get ");
2114         return false;
2115     }
2116     fn->SetModuleID(lexer.GetTheIntVal());
2117     lexer.NextToken();
2118     return true;
2119 }
2120 
ParseStmtBlockForFuncSize()2121 bool MIRParser::ParseStmtBlockForFuncSize()
2122 {
2123     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2124     lexer.NextToken();
2125     if (lexer.GetTokenKind() != TK_intconst) {
2126         Error("expect integer after funcSize but get ");
2127         return false;
2128     }
2129     fn->SetFuncSize(lexer.GetTheIntVal());
2130     lexer.NextToken();
2131     return true;
2132 }
2133 
ParseStmtBlockForFuncID()2134 bool MIRParser::ParseStmtBlockForFuncID()
2135 {
2136     // funcid is for debugging purpose
2137     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2138     lexer.NextToken();
2139     if (lexer.GetTokenKind() != TK_intconst) {
2140         Error("expect integer after funcid but get ");
2141         return false;
2142     }
2143     fn->SetPuidxOrigin(lexer.GetTheIntVal());
2144     lexer.NextToken();
2145     return true;
2146 }
2147 
ParseStmtBlockForFormalWordsTypeTagged()2148 bool MIRParser::ParseStmtBlockForFormalWordsTypeTagged()
2149 {
2150     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2151     uint8 *addr = ParseWordsInfo(fn->GetUpFormalSize());
2152     if (addr == nullptr) {
2153         Error("parser error for formalwordstypetagged");
2154         return false;
2155     }
2156     fn->SetFormalWordsTypeTagged(addr);
2157     return true;
2158 }
2159 
ParseStmtBlockForLocalWordsTypeTagged()2160 bool MIRParser::ParseStmtBlockForLocalWordsTypeTagged()
2161 {
2162     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2163     uint8 *addr = ParseWordsInfo(fn->GetFrameSize());
2164     if (addr == nullptr) {
2165         Error("parser error for localWordsTypeTagged");
2166         return false;
2167     }
2168     fn->SetLocalWordsTypeTagged(addr);
2169     return true;
2170 }
2171 
ParseStmtBlockForFormalWordsRefCounted()2172 bool MIRParser::ParseStmtBlockForFormalWordsRefCounted()
2173 {
2174     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2175     uint8 *addr = ParseWordsInfo(fn->GetUpFormalSize());
2176     if (addr == nullptr) {
2177         Error("parser error for formalwordsrefcounted");
2178         return false;
2179     }
2180     fn->SetFormalWordsRefCounted(addr);
2181     return true;
2182 }
2183 
ParseStmtBlockForLocalWordsRefCounted()2184 bool MIRParser::ParseStmtBlockForLocalWordsRefCounted()
2185 {
2186     MIRFunction *fn = paramCurrFuncForParseStmtBlock;
2187     uint8 *addr = ParseWordsInfo(fn->GetFrameSize());
2188     if (addr == nullptr) {
2189         Error("parser error for localwordsrefcounted");
2190         return false;
2191     }
2192     fn->SetLocalWordsRefCounted(addr);
2193     return true;
2194 }
2195 
ParseStmtBlockForFuncInfo()2196 bool MIRParser::ParseStmtBlockForFuncInfo()
2197 {
2198     lexer.NextToken();
2199     if (!ParseFuncInfo()) {
2200         return false;
2201     }
2202     return true;
2203 }
2204 
2205 /* exprparser */
GetUnaryOp(TokenKind tk)2206 static Opcode GetUnaryOp(TokenKind tk)
2207 {
2208     switch (tk) {
2209 #define UNARYOP(P) \
2210     case TK_##P:   \
2211         return OP_##P;
2212 #include "unary_op.def"
2213 #undef UNARYOP
2214         default:
2215             return OP_undef;
2216     }
2217 }
2218 
GetBinaryOp(TokenKind tk)2219 static Opcode GetBinaryOp(TokenKind tk)
2220 {
2221     switch (tk) {
2222 #define BINARYOP(P) \
2223     case TK_##P:    \
2224         return OP_##P;
2225 #include "binary_op.def"
2226 #undef BINARYOP
2227         default:
2228             return OP_undef;
2229     }
2230 }
2231 
GetConvertOp(TokenKind tk)2232 static Opcode GetConvertOp(TokenKind tk)
2233 {
2234     switch (tk) {
2235         case TK_ceil:
2236             return OP_ceil;
2237         case TK_cvt:
2238             return OP_cvt;
2239         case TK_floor:
2240             return OP_floor;
2241         case TK_round:
2242             return OP_round;
2243         case TK_trunc:
2244             return OP_trunc;
2245         default:
2246             return OP_undef;
2247     }
2248 }
2249 
ParseExprOneOperand(BaseNodePtr & expr)2250 bool MIRParser::ParseExprOneOperand(BaseNodePtr &expr)
2251 {
2252     if (lexer.GetTokenKind() != TK_lparen) {
2253         Error("expect ( parsing operand parsing unary ");
2254         return false;
2255     }
2256     lexer.NextToken();
2257     if (!ParseExpression(expr)) {
2258         Error("expect expression as openrand of unary expression ");
2259         return false;
2260     }
2261     if (lexer.GetTokenKind() != TK_rparen) {
2262         Error("expect ) parsing operand parsing unary ");
2263         return false;
2264     }
2265     return true;
2266 }
2267 
ParseExprTwoOperand(BaseNodePtr & opnd0,BaseNodePtr & opnd1)2268 bool MIRParser::ParseExprTwoOperand(BaseNodePtr &opnd0, BaseNodePtr &opnd1)
2269 {
2270     if (lexer.GetTokenKind() != TK_lparen) {
2271         Error("expect ( parsing operand parsing unary ");
2272         return false;
2273     }
2274     lexer.NextToken();
2275     if (!ParseExpression(opnd0)) {
2276         return false;
2277     }
2278     if (lexer.GetTokenKind() != TK_coma) {
2279         Error("expect , between two operands but get ");
2280         return false;
2281     }
2282     lexer.NextToken();
2283     if (!ParseExpression(opnd1)) {
2284         return false;
2285     }
2286     if (lexer.GetTokenKind() != TK_rparen) {
2287         Error("expect ) parsing operand parsing unary ");
2288         return false;
2289     }
2290     return true;
2291 }
2292 
ParseExprNaryOperand(MapleVector<BaseNode * > & opndVec)2293 bool MIRParser::ParseExprNaryOperand(MapleVector<BaseNode *> &opndVec)
2294 {
2295     if (lexer.GetTokenKind() != TK_lparen) {
2296         Error("expect ( parsing operand parsing nary operands ");
2297         return false;
2298     }
2299     TokenKind tk = lexer.NextToken();
2300     while (tk != TK_rparen) {
2301         BaseNode *opnd = nullptr;
2302         if (!ParseExpression(opnd)) {
2303             Error("expect expression parsing nary operands ");
2304             return false;
2305         }
2306         opndVec.push_back(opnd);
2307         tk = lexer.GetTokenKind();
2308         if (tk == TK_coma) {
2309             tk = lexer.NextToken();
2310         }
2311     }
2312     return true;
2313 }
2314 
ParseDeclaredSt(StIdx & stidx)2315 bool MIRParser::ParseDeclaredSt(StIdx &stidx)
2316 {
2317     TokenKind varTk = lexer.GetTokenKind();
2318     stidx.SetFullIdx(0);
2319     GStrIdx stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2320     if (varTk == TK_gname) {
2321         stidx = GlobalTables::GetGsymTable().GetStIdxFromStrIdx(stridx);
2322         if (stidx.FullIdx() == 0) {
2323             MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
2324             st->SetNameStrIdx(stridx);
2325             st->SetSKind(kStVar);
2326             (void)GlobalTables::GetGsymTable().AddToStringSymbolMap(*st);
2327             stidx = GlobalTables::GetGsymTable().GetStIdxFromStrIdx(stridx);
2328             return true;
2329         }
2330     } else if (varTk == TK_lname) {
2331         stidx = mod.CurFunction()->GetSymTab()->GetStIdxFromStrIdx(stridx);
2332         if (stidx.FullIdx() == 0) {
2333             Error("local symbol not declared ");
2334             return false;
2335         }
2336     } else {
2337         Error("expect global/local name but get ");
2338         return false;
2339     }
2340     return true;
2341 }
2342 
CreateFuncMIRSymbol(PUIdx & puidx,GStrIdx strIdx)2343 void MIRParser::CreateFuncMIRSymbol(PUIdx &puidx, GStrIdx strIdx)
2344 {
2345     MIRSymbol *funcSt = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
2346     funcSt->SetNameStrIdx(strIdx);
2347     (void)GlobalTables::GetGsymTable().AddToStringSymbolMap(*funcSt);
2348     funcSt->SetStorageClass(kScText);
2349     funcSt->SetSKind(kStFunc);
2350     funcSt->SetNeedForwDecl();
2351     auto *fn = mod.GetMemPool()->New<MIRFunction>(&mod, funcSt->GetStIdx());
2352     puidx = static_cast<PUIdx>(GlobalTables::GetFunctionTable().GetFuncTable().size());
2353     fn->SetPuidx(puidx);
2354     GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
2355     funcSt->SetFunction(fn);
2356     if (options & kParseInlineFuncBody) {
2357         funcSt->SetIsTmpUnused(true);
2358     }
2359 }
2360 
ParseDeclaredFunc(PUIdx & puidx)2361 bool MIRParser::ParseDeclaredFunc(PUIdx &puidx)
2362 {
2363     GStrIdx stridx = GlobalTables::GetStrTable().GetStrIdxFromName(lexer.GetName());
2364     if (stridx == 0u) {
2365         stridx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2366     }
2367     StIdx stidx = GlobalTables::GetGsymTable().GetStIdxFromStrIdx(stridx);
2368     if (stidx.FullIdx() == 0) {
2369         CreateFuncMIRSymbol(puidx, stridx);
2370         return true;
2371     }
2372     MIRSymbol *st = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx());
2373     DEBUG_ASSERT(st != nullptr, "null ptr check");
2374     if (st->GetSKind() != kStFunc) {
2375         Error("function name not declared as function");
2376         return false;
2377     }
2378     MIRFunction *func = st->GetFunction();
2379     puidx = func->GetPuidx();
2380     st->SetAppearsInCode(true);
2381     return true;
2382 }
2383 
ParseExprDread(BaseNodePtr & expr)2384 bool MIRParser::ParseExprDread(BaseNodePtr &expr)
2385 {
2386     if (lexer.GetTokenKind() != TK_dread) {
2387         Error("expect dread but get ");
2388         return false;
2389     }
2390     AddrofNode *dexpr = mod.CurFuncCodeMemPool()->New<AddrofNode>(OP_dread);
2391     expr = dexpr;
2392     lexer.NextToken();
2393     TyIdx tyidx(0);
2394     bool parseRet = ParsePrimType(tyidx);
2395     if (tyidx == 0u || !parseRet) {
2396         Error("expect primitive type but get ");
2397         return false;
2398     }
2399     expr->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2400     StIdx stidx;
2401     if (!ParseDeclaredSt(stidx)) {
2402         return false;
2403     }
2404     if (stidx.FullIdx() == 0) {
2405         Error("expect a symbol ParseExprDread failed");
2406         return false;
2407     }
2408     dexpr->SetStIdx(stidx);
2409     TokenKind endtk = lexer.NextToken();
2410     if (endtk == TK_intconst) {
2411         dexpr->SetFieldID(lexer.GetTheIntVal());
2412         lexer.NextToken();
2413     } else if (!IsDelimitationTK(endtk)) {
2414         Error("expect , or ) delimitation token but get ");
2415         return false;
2416     } else {
2417         dexpr->SetFieldID(0);
2418     }
2419     if (!dexpr->CheckNode(mod)) {
2420         Error("dread is not legal");
2421         return false;
2422     }
2423     return true;
2424 }
2425 
ParseExprDreadoff(BaseNodePtr & expr)2426 bool MIRParser::ParseExprDreadoff(BaseNodePtr &expr)
2427 {
2428     if (lexer.GetTokenKind() != TK_dreadoff) {
2429         Error("expect dreadoff but get ");
2430         return false;
2431     }
2432     DreadoffNode *dexpr = mod.CurFuncCodeMemPool()->New<DreadoffNode>(OP_dreadoff);
2433     expr = dexpr;
2434     lexer.NextToken();
2435     TyIdx tyidx(0);
2436     bool parseRet = ParsePrimType(tyidx);
2437     if (tyidx == 0u || !parseRet) {
2438         Error("expect primitive type but get ");
2439         return false;
2440     }
2441     expr->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2442     StIdx stidx;
2443     if (!ParseDeclaredSt(stidx)) {
2444         return false;
2445     }
2446     if (stidx.FullIdx() == 0) {
2447         Error("expect a symbol ParseExprDread failed");
2448         return false;
2449     }
2450     dexpr->stIdx = stidx;
2451     TokenKind endtk = lexer.NextToken();
2452     if (endtk == TK_intconst) {
2453         dexpr->offset = static_cast<int32>(lexer.GetTheIntVal());
2454         lexer.NextToken();
2455     } else {
2456         Error("expect integer offset but get ");
2457         return false;
2458     }
2459     return true;
2460 }
2461 
ParseExprRegread(BaseNodePtr & expr)2462 bool MIRParser::ParseExprRegread(BaseNodePtr &expr)
2463 {
2464     auto *regRead = mod.CurFuncCodeMemPool()->New<RegreadNode>();
2465     expr = regRead;
2466     lexer.NextToken();
2467     TyIdx tyidx(0);
2468     if (!ParsePrimType(tyidx)) {
2469         return false;
2470     }
2471     if (tyidx == 0u) {
2472         Error("expect primitive type but get ");
2473         return false;
2474     }
2475     expr->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2476     if (lexer.GetTokenKind() == TK_specialreg) {
2477         PregIdx tempPregIdx = regRead->GetRegIdx();
2478         bool isSuccess = ParseSpecialReg(tempPregIdx);
2479         regRead->SetRegIdx(tempPregIdx);
2480         return isSuccess;
2481     }
2482     if (lexer.GetTokenKind() == TK_preg) {
2483         PregIdx tempPregIdx = regRead->GetRegIdx();
2484         bool isSuccess = ParsePseudoReg(regRead->GetPrimType(), tempPregIdx);
2485         regRead->SetRegIdx(tempPregIdx);
2486         return isSuccess;
2487     }
2488     Error("expect special or pseudo register but get ");
2489     return false;
2490 }
2491 
ParseExprConstval(BaseNodePtr & expr)2492 bool MIRParser::ParseExprConstval(BaseNodePtr &expr)
2493 {
2494     auto *exprConst = mod.CurFuncCodeMemPool()->New<ConstvalNode>();
2495     TokenKind typeTk = lexer.NextToken();
2496     if (!IsPrimitiveType(typeTk)) {
2497         Error("expect type for GetConstVal but get ");
2498         return false;
2499     }
2500     exprConst->SetPrimType(GetPrimitiveType(typeTk));
2501     lexer.NextToken();
2502     MIRConst *constVal = nullptr;
2503     if (!ParseScalarValue(constVal, *GlobalTables::GetTypeTable().GetPrimType(exprConst->GetPrimType()))) {
2504         Error("expect scalar type but get ");
2505         return false;
2506     }
2507     exprConst->SetConstVal(constVal);
2508     expr = exprConst;
2509     lexer.NextToken();
2510     return true;
2511 }
2512 
ParseExprConststr(BaseNodePtr & expr)2513 bool MIRParser::ParseExprConststr(BaseNodePtr &expr)
2514 {
2515     auto *strConst = mod.CurFuncCodeMemPool()->New<ConststrNode>();
2516     TokenKind tk = lexer.NextToken();
2517     if (!IsPrimitiveType(tk)) {
2518         Error("expect primitive type for conststr but get ");
2519         return false;
2520     }
2521     strConst->SetPrimType(GetPrimitiveType(tk));
2522     if (!IsAddress(strConst->GetPrimType())) {
2523         Error("expect primitive type for conststr but get ");
2524         return false;
2525     }
2526     tk = lexer.NextToken();
2527     if (tk != TK_string) {
2528         Error("expect string literal for conststr but get ");
2529         return false;
2530     }
2531     strConst->SetStrIdx(GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName()));
2532     expr = strConst;
2533     lexer.NextToken();
2534     return true;
2535 }
2536 
ParseExprConststr16(BaseNodePtr & expr)2537 bool MIRParser::ParseExprConststr16(BaseNodePtr &expr)
2538 {
2539     auto *str16Const = mod.CurFuncCodeMemPool()->New<Conststr16Node>();
2540     TokenKind tk = lexer.NextToken();
2541     if (!IsPrimitiveType(tk)) {
2542         Error("expect primitive type for conststr16 but get ");
2543         return false;
2544     }
2545     str16Const->SetPrimType(GetPrimitiveType(tk));
2546     if (!IsAddress(str16Const->GetPrimType())) {
2547         Error("expect primitive type for conststr16 but get ");
2548         return false;
2549     }
2550     tk = lexer.NextToken();
2551     if (tk != TK_string) {
2552         Error("expect string literal for conststr16 but get ");
2553         return false;
2554     }
2555     // UTF-16 strings in mpl files are presented as UTF-8 strings
2556     // to keep the printable chars in ascii form
2557     // so we need to do a UTF8ToUTF16 conversion
2558     std::string str = lexer.GetName();
2559     std::u16string str16;
2560     (void)namemangler::UTF8ToUTF16(str16, str);
2561     str16Const->SetStrIdx(GlobalTables::GetU16StrTable().GetOrCreateStrIdxFromName(str16));
2562     expr = str16Const;
2563     lexer.NextToken();
2564     return true;
2565 }
2566 
ParseExprSizeoftype(BaseNodePtr & expr)2567 bool MIRParser::ParseExprSizeoftype(BaseNodePtr &expr)
2568 {
2569     auto *exprSizeOfType = mod.CurFuncCodeMemPool()->New<SizeoftypeNode>();
2570     TokenKind typeTk = lexer.NextToken();
2571     if (!IsPrimitiveType(typeTk)) {
2572         Error("expect type for GetConstVal but get ");
2573         return false;
2574     }
2575     exprSizeOfType->SetPrimType(GetPrimitiveType(typeTk));
2576     lexer.NextToken();
2577     TyIdx tyidx(0);
2578     if (!ParseType(tyidx)) {
2579         Error("expect type parsing array but get ");
2580         return false;
2581     }
2582     exprSizeOfType->SetTyIdx(tyidx);
2583     expr = exprSizeOfType;
2584     return true;
2585 }
2586 
ParseExprFieldsDist(BaseNodePtr & expr)2587 bool MIRParser::ParseExprFieldsDist(BaseNodePtr &expr)
2588 {
2589     TokenKind typeTk = lexer.NextToken();
2590     if (!IsPrimitiveType(typeTk)) {
2591         Error("expect type for GetConstVal but get ");
2592         return false;
2593     }
2594     auto *node = mod.CurFuncCodeMemPool()->New<FieldsDistNode>();
2595     node->SetPrimType(GetPrimitiveType(typeTk));
2596     lexer.NextToken();
2597     TyIdx tyIdx(0);
2598     if (!ParseType(tyIdx)) {
2599         Error("expect type parsing array but get ");
2600         return false;
2601     }
2602     node->SetTyIdx(tyIdx);
2603     TokenKind tk = lexer.GetTokenKind();
2604     if (tk != TK_intconst) {
2605         Error("expect type int but get");
2606         return false;
2607     }
2608     node->SetFiledID1(lexer.GetTheIntVal());
2609     tk = lexer.NextToken();
2610     if (tk != TK_intconst) {
2611         Error("expect type int but get");
2612         return false;
2613     }
2614     node->SetFiledID2(lexer.GetTheIntVal());
2615     lexer.NextToken();
2616     expr = node;
2617     return true;
2618 }
2619 
ParseExprBinary(BaseNodePtr & expr)2620 bool MIRParser::ParseExprBinary(BaseNodePtr &expr)
2621 {
2622     Opcode opcode = GetBinaryOp(lexer.GetTokenKind());
2623     if (opcode == OP_undef) {
2624         Error("expect add operator but get ");
2625         return false;
2626     }
2627     auto *addExpr = mod.CurFuncCodeMemPool()->New<BinaryNode>(opcode);
2628     if (!IsPrimitiveType(lexer.NextToken())) {
2629         Error("expect type parsing binary operator but get ");
2630         return false;
2631     }
2632     addExpr->SetPrimType(GetPrimitiveType(lexer.GetTokenKind()));
2633     lexer.NextToken();
2634     BaseNode *opnd0 = nullptr;
2635     BaseNode *opnd1 = nullptr;
2636     if (!ParseExprTwoOperand(opnd0, opnd1)) {
2637         return false;
2638     }
2639     addExpr->SetBOpnd(opnd0, 0);
2640     addExpr->SetBOpnd(opnd1, 1);
2641     expr = addExpr;
2642     lexer.NextToken();
2643     return true;
2644 }
2645 
ParseExprCompare(BaseNodePtr & expr)2646 bool MIRParser::ParseExprCompare(BaseNodePtr &expr)
2647 {
2648     Opcode opcode = GetBinaryOp(lexer.GetTokenKind());
2649     auto *addExpr = mod.CurFuncCodeMemPool()->New<CompareNode>(opcode);
2650     if (!IsPrimitiveType(lexer.NextToken())) {
2651         Error("expect type parsing compare operator but get ");
2652         return false;
2653     }
2654     addExpr->SetPrimType(GetPrimitiveType(lexer.GetTokenKind()));
2655     if (!IsPrimitiveType(lexer.NextToken())) {
2656         Error("expect operand type parsing compare operator but get ");
2657         return false;
2658     }
2659     addExpr->SetOpndType(GetPrimitiveType(lexer.GetTokenKind()));
2660     lexer.NextToken();
2661     BaseNode *opnd0 = nullptr;
2662     BaseNode *opnd1 = nullptr;
2663     if (!ParseExprTwoOperand(opnd0, opnd1)) {
2664         return false;
2665     }
2666     addExpr->SetBOpnd(opnd0, 0);
2667     addExpr->SetBOpnd(opnd1, 1);
2668     expr = addExpr;
2669     lexer.NextToken();
2670     return true;
2671 }
2672 
ParseExprDepositbits(BaseNodePtr & expr)2673 bool MIRParser::ParseExprDepositbits(BaseNodePtr &expr)
2674 {
2675     // syntax: depositbits <int-type> <bOffset> <bSize> (<opnd0>, <opnd1>)
2676     if (lexer.GetTokenKind() != TK_depositbits) {
2677         Error("expect depositbits but get ");
2678         return false;
2679     }
2680     auto *dpsbNode = mod.CurFuncCodeMemPool()->New<DepositbitsNode>();
2681     expr = dpsbNode;
2682     PrimType ptyp = GetPrimitiveType(lexer.NextToken());
2683     if (!IsPrimitiveInteger(ptyp)) {
2684         Error("expect <int-type> but get ");
2685         return false;
2686     }
2687     dpsbNode->SetPrimType(ptyp);
2688     if (lexer.NextToken() != TK_intconst) {
2689         Error("expect bOffset but get ");
2690         return false;
2691     }
2692     dpsbNode->SetBitsOffset(lexer.GetTheIntVal());
2693     if (lexer.NextToken() != TK_intconst) {
2694         Error("expect bSize but get ");
2695         return false;
2696     }
2697     dpsbNode->SetBitsSize(lexer.GetTheIntVal());
2698     lexer.NextToken();
2699     BaseNode *opnd0 = nullptr;
2700     BaseNode *opnd1 = nullptr;
2701     if (!ParseExprTwoOperand(opnd0, opnd1)) {
2702         Error("ParseExprDepositbits when parsing two operand");
2703         return false;
2704     }
2705     dpsbNode->SetBOpnd(opnd0, 0);
2706     dpsbNode->SetBOpnd(opnd1, 1);
2707     lexer.NextToken();
2708     return true;
2709 }
2710 
ParseExprIreadIaddrof(IreadNode & expr)2711 bool MIRParser::ParseExprIreadIaddrof(IreadNode &expr)
2712 {
2713     // syntax : iread/iaddrof <prim-type> <type> <field-id> (<addr-expr>)
2714     if (!IsPrimitiveType(lexer.NextToken())) {
2715         Error("expect primitive type but get ");
2716         return false;
2717     }
2718     TyIdx tyidx(0);
2719     if (!ParsePrimType(tyidx)) {
2720         return false;
2721     }
2722     expr.SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2723     tyidx = TyIdx(0);
2724     if (!ParseDerivedType(tyidx)) {
2725         Error("ParseExprIreadIaddrof failed when paring derived type");
2726         return false;
2727     }
2728     expr.SetTyIdx(tyidx);
2729     if (lexer.GetTokenKind() == TK_intconst) {
2730         expr.SetFieldID(lexer.theIntVal);
2731         lexer.NextToken();
2732     }
2733     BaseNode *opnd0 = nullptr;
2734     if (!ParseExprOneOperand(opnd0)) {
2735         return false;
2736     }
2737     expr.SetOpnd(opnd0, 0);
2738     lexer.NextToken();
2739     return true;
2740 }
2741 
ParseExprIread(BaseNodePtr & expr)2742 bool MIRParser::ParseExprIread(BaseNodePtr &expr)
2743 {
2744     // syntax : iread <prim-type> <type> <field-id> (<addr-expr>)
2745     auto *iExpr = mod.CurFuncCodeMemPool()->New<IreadNode>(OP_iread);
2746     if (!ParseExprIreadIaddrof(*iExpr)) {
2747         Error("ParseExprIread failed when trying to parse addof");
2748         return false;
2749     }
2750     expr = iExpr;
2751     return true;
2752 }
2753 
ParseExprIaddrof(BaseNodePtr & expr)2754 bool MIRParser::ParseExprIaddrof(BaseNodePtr &expr)
2755 {
2756     // syntax : iaddrof <prim-type> <type> <field-id> (<addr-expr>)
2757     auto *iExpr = mod.CurFuncCodeMemPool()->New<IreadNode>(OP_iaddrof);
2758     if (!ParseExprIreadIaddrof(*iExpr)) {
2759         Error("ParseExprIaddrof failed when trying to parse addof");
2760         return false;
2761     }
2762     expr = iExpr;
2763     return true;
2764 }
2765 
ParseExprIreadoff(BaseNodePtr & expr)2766 bool MIRParser::ParseExprIreadoff(BaseNodePtr &expr)
2767 {
2768     // syntax : iread <prim-type> <offset> (<addr-expr>)
2769     auto *iReadOff = mod.CurFuncCodeMemPool()->New<IreadoffNode>();
2770     expr = iReadOff;
2771     if (!IsPrimitiveType(lexer.NextToken())) {
2772         Error("expect primitive type but get ");
2773         return false;
2774     }
2775     TyIdx tyidx(0);
2776     if (!ParsePrimType(tyidx)) {
2777         return false;
2778     }
2779     iReadOff->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2780     if (!IsPrimitiveScalar(iReadOff->GetPrimType())) {
2781         Error("only scalar types allowed for ireadoff");
2782         return false;
2783     }
2784     if (lexer.GetTokenKind() != TK_intconst) {
2785         Error("expect offset but get ");
2786         return false;
2787     }
2788     iReadOff->SetOffset(lexer.GetTheIntVal());
2789     lexer.NextToken();
2790     BaseNode *opnd = nullptr;
2791     if (!ParseExprOneOperand(opnd)) {
2792         Error("ParseExprIreadoff when paring one operand");
2793         return false;
2794     }
2795     iReadOff->SetOpnd(opnd, 0);
2796     lexer.NextToken();
2797     return true;
2798 }
2799 
ParseExprIreadFPoff(BaseNodePtr & expr)2800 bool MIRParser::ParseExprIreadFPoff(BaseNodePtr &expr)
2801 {
2802     // syntax : iread <prim-type> <offset>
2803     auto *iReadOff = mod.CurFuncCodeMemPool()->New<IreadFPoffNode>();
2804     expr = iReadOff;
2805     if (!IsPrimitiveType(lexer.NextToken())) {
2806         Error("expect primitive type but get ");
2807         return false;
2808     }
2809     TyIdx tyidx(0);
2810     if (!ParsePrimType(tyidx)) {
2811         return false;
2812     }
2813     iReadOff->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2814     if (lexer.GetTokenKind() != TK_intconst) {
2815         Error("expect offset but get ");
2816         return false;
2817     }
2818     iReadOff->SetOffset(lexer.GetTheIntVal());
2819     lexer.NextToken();
2820     return true;
2821 }
2822 
ParseExprAddrof(BaseNodePtr & expr)2823 bool MIRParser::ParseExprAddrof(BaseNodePtr &expr)
2824 {
2825     // syntax: addrof <prim-type> <var-name> <field-id>
2826     auto *addrofNode = mod.CurFuncCodeMemPool()->New<AddrofNode>(OP_addrof);
2827     expr = addrofNode;
2828     if (lexer.GetTokenKind() != TK_addrof) {
2829         Error("expect addrof but get ");
2830         return false;
2831     }
2832     lexer.NextToken();
2833     TyIdx tyidx(0);
2834     if (!ParsePrimType(tyidx)) {
2835         Error("expect primitive type but get ");
2836         return false;
2837     }
2838     addrofNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2839     StIdx stidx;
2840     if (!ParseDeclaredSt(stidx)) {
2841         return false;
2842     }
2843     if (stidx.FullIdx() == 0) {
2844         Error("expect symbol ParseExprAddroffunc");
2845         return false;
2846     }
2847     if (stidx.IsGlobal()) {
2848         MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx());
2849         DEBUG_ASSERT(sym != nullptr, "null ptr check");
2850         sym->SetHasPotentialAssignment();
2851     }
2852     addrofNode->SetStIdx(stidx);
2853     TokenKind tk = lexer.NextToken();
2854     if (IsDelimitationTK(tk)) {
2855         addrofNode->SetFieldID(0);
2856     } else if (tk == TK_intconst) {
2857         addrofNode->SetFieldID(lexer.GetTheIntVal());
2858         lexer.NextToken();
2859     } else {
2860         addrofNode->SetFieldID(0);
2861     }
2862     return true;
2863 }
2864 
ParseExprAddrofoff(BaseNodePtr & expr)2865 bool MIRParser::ParseExprAddrofoff(BaseNodePtr &expr)
2866 {
2867     // syntax: addrofoff <prim-type> <var-name> <offset>
2868     AddrofoffNode *addrofoffNode = mod.CurFuncCodeMemPool()->New<AddrofoffNode>(OP_addrofoff);
2869     expr = addrofoffNode;
2870     if (lexer.GetTokenKind() != TK_addrofoff) {
2871         Error("expect addrofoff but get ");
2872         return false;
2873     }
2874     lexer.NextToken();
2875     TyIdx tyidx(0);
2876     if (!ParsePrimType(tyidx)) {
2877         Error("expect primitive type but get ");
2878         return false;
2879     }
2880     addrofoffNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2881     StIdx stidx;
2882     if (!ParseDeclaredSt(stidx)) {
2883         return false;
2884     }
2885     if (stidx.FullIdx() == 0) {
2886         Error("expect symbol ParseExprAddroffunc");
2887         return false;
2888     }
2889     if (stidx.IsGlobal()) {
2890         MIRSymbol *sym = GlobalTables::GetGsymTable().GetSymbolFromStidx(stidx.Idx());
2891         DEBUG_ASSERT(sym != nullptr, "null ptr check");
2892         sym->SetHasPotentialAssignment();
2893     }
2894     addrofoffNode->stIdx = stidx;
2895     TokenKind tk = lexer.NextToken();
2896     if (tk == TK_intconst) {
2897         addrofoffNode->offset = static_cast<int32>(lexer.GetTheIntVal());
2898         lexer.NextToken();
2899     } else {
2900         Error("expect integer offset but get ");
2901         return false;
2902     }
2903     return true;
2904 }
2905 
ParseExprAddroffunc(BaseNodePtr & expr)2906 bool MIRParser::ParseExprAddroffunc(BaseNodePtr &expr)
2907 {
2908     auto *addrOfFuncNode = mod.CurFuncCodeMemPool()->New<AddroffuncNode>();
2909     expr = addrOfFuncNode;
2910     TokenKind tk = lexer.NextToken();
2911     if (tk != TK_a32 && tk != TK_a64 && tk != TK_ptr) {
2912         Error("expect address primitive type but get ");
2913         return false;
2914     }
2915     TyIdx tyidx(0);
2916     if (!ParsePrimType(tyidx)) {
2917         Error("ParseExprAddroffunc failed when parsing primitive type");
2918         return false;
2919     }
2920     addrOfFuncNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2921     if (lexer.GetTokenKind() != TK_fname) {
2922         Error("expect function name but get ");
2923         return false;
2924     }
2925     PUIdx pidx;
2926     if (!ParseDeclaredFunc(pidx)) {
2927         if (mod.GetFlavor() < kMmpl) {
2928             Error("expect .mmpl file");
2929             return false;
2930         }
2931         pidx = EnterUndeclaredFunction();
2932     }
2933     addrOfFuncNode->SetPUIdx(pidx);
2934     lexer.NextToken();
2935     return true;
2936 }
2937 
ParseExprAddroflabel(BaseNodePtr & expr)2938 bool MIRParser::ParseExprAddroflabel(BaseNodePtr &expr)
2939 {
2940     // syntax: addroflabel <prim-type> <label>
2941     auto *addrOfLabelNode = mod.CurFuncCodeMemPool()->New<AddroflabelNode>();
2942     expr = addrOfLabelNode;
2943     TokenKind tk = lexer.NextToken();
2944     if (tk != TK_a32 && tk != TK_a64 && tk != TK_ptr) {
2945         Error("expect address primitive type but get ");
2946         return false;
2947     }
2948     TyIdx tyidx(0);
2949     if (!ParsePrimType(tyidx)) {
2950         Error("ParseExprAddroflabel failed");
2951         return false;
2952     }
2953     addrOfLabelNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2954     if (lexer.GetTokenKind() != TK_label) {
2955         Error("expect label but get ");
2956         return false;
2957     }
2958     LabelIdx lblIdx = mod.CurFunction()->GetOrCreateLableIdxFromName(lexer.GetName());
2959     addrOfLabelNode->SetOffset(lblIdx);
2960     (void)mod.CurFunction()->GetLabelTab()->GetAddrTakenLabels().insert(lblIdx);
2961     lexer.NextToken();
2962     return true;
2963 }
2964 
ParseExprUnary(BaseNodePtr & expr)2965 bool MIRParser::ParseExprUnary(BaseNodePtr &expr)
2966 {
2967     // syntax op <prim-type> <label>
2968     Opcode op = GetUnaryOp(lexer.GetTokenKind());
2969     if (op == OP_undef) {
2970         Error("expect unary op but get ");
2971         return false;
2972     }
2973     lexer.NextToken();
2974     TyIdx tyidx(0);
2975     if (!ParsePrimType(tyidx)) {
2976         Error("expect primitive parsing unary operator ");
2977         return false;
2978     }
2979     auto *unaryNode = mod.CurFuncCodeMemPool()->New<UnaryNode>(op);
2980     expr = unaryNode;
2981     unaryNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
2982     BaseNode *opnd = nullptr;
2983     if (!ParseExprOneOperand(opnd)) {
2984         Error("parsing unary wrong ");
2985         return false;
2986     }
2987     unaryNode->SetOpnd(opnd, 0);
2988     lexer.NextToken();
2989     return true;
2990 }
2991 
ParseExprGCMalloc(BaseNodePtr & expr)2992 bool MIRParser::ParseExprGCMalloc(BaseNodePtr &expr)
2993 {
2994     // syntax op <prim-type> <type>
2995     TokenKind tk = lexer.GetTokenKind();
2996     if (tk != TK_gcmalloc && tk != TK_gcpermalloc) {
2997         Error("expect gcmalloc or gcpermalloc but get ");
2998         return false;
2999     }
3000     Opcode op = (tk == TK_gcmalloc) ? OP_gcmalloc : OP_gcpermalloc;
3001     lexer.NextToken();
3002     TyIdx ptyidx(0);
3003     if (IsPrimitiveType(lexer.GetTokenKind())) {
3004         if (!ParsePrimType(ptyidx)) {
3005             return false;
3006         }
3007     }
3008     TyIdx tyidx(0);
3009     if (!ParseType(tyidx)) {
3010         Error("expect type parsing unary operator ");
3011         return false;
3012     }
3013     auto *mallocNode = mod.CurFuncCodeMemPool()->New<GCMallocNode>(op);
3014     expr = mallocNode;
3015     mallocNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(ptyidx));
3016     mallocNode->SetOrigPType(mallocNode->GetPrimType());
3017     mallocNode->SetTyIdx(tyidx);
3018     return true;
3019 }
3020 
ParseExprJarray(BaseNodePtr & expr)3021 bool MIRParser::ParseExprJarray(BaseNodePtr &expr)
3022 {
3023     // syntax op <prim-type> <java-array-type> <label>
3024     Opcode op = GetUnaryOp(lexer.GetTokenKind());
3025     if (op != OP_gcmallocjarray && op != OP_gcpermallocjarray) {
3026         Error("expect gcmallocjarray or gcpermallocjarray but get ");
3027         return false;
3028     }
3029     TyIdx ptyidx(0);
3030     lexer.NextToken();
3031     if (IsPrimitiveType(lexer.GetTokenKind())) {
3032         if (!ParsePrimType(ptyidx)) {
3033             return false;
3034         }
3035     }
3036     TyIdx tyidx(0);
3037     if (!ParseType(tyidx)) {
3038         Error("expect primitive parsing unary operator ");
3039         return false;
3040     }
3041     auto *jarrayNode = mod.CurFuncCodeMemPool()->New<JarrayMallocNode>(op);
3042     expr = jarrayNode;
3043     jarrayNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(ptyidx));
3044     jarrayNode->SetTyIdx(tyidx);
3045     BaseNode *opnd = nullptr;
3046     if (!ParseExprOneOperand(opnd)) {
3047         Error("parsing unary wrong ");
3048         return false;
3049     }
3050     jarrayNode->SetOpnd(opnd, 0);
3051     lexer.NextToken();
3052     return true;
3053 }
3054 
3055 // parse extractbits, sext, zext
ParseExprExtractbits(BaseNodePtr & expr)3056 bool MIRParser::ParseExprExtractbits(BaseNodePtr &expr)
3057 {
3058     // extractbits <int-type> <bOffset> <bSize> (<opnd0>)
3059     Opcode op = GetUnaryOp(lexer.GetTokenKind());
3060     if (op == OP_undef) {
3061         Error("expect unary op but get ");
3062         return false;
3063     }
3064     auto *extrctNode = mod.CurFuncCodeMemPool()->New<ExtractbitsNode>(op);
3065     expr = extrctNode;
3066     lexer.NextToken();
3067     TyIdx tyidx(0);
3068     if (!ParsePrimType(tyidx)) {
3069         Error("expect int type after extractbits after");
3070         return false;
3071     }
3072     PrimType ptyp = GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx);
3073     if (!IsPrimitiveInteger(ptyp)) {
3074         Error("sematical error expect int type for extractbits");
3075         return false;
3076     }
3077     extrctNode->SetPrimType(ptyp);
3078     if (op == OP_extractbits) {
3079         if (lexer.GetTokenKind() != TK_intconst) {
3080             Error("expect bOffset but get ");
3081             return false;
3082         }
3083         extrctNode->SetBitsOffset(lexer.GetTheIntVal());
3084         lexer.NextToken();
3085     }
3086     if (lexer.GetTokenKind() != TK_intconst) {
3087         Error("expect bSize but get ");
3088         return false;
3089     }
3090     extrctNode->SetBitsSize(lexer.GetTheIntVal());
3091     lexer.NextToken();
3092     BaseNode *opnd = nullptr;
3093     if (!ParseExprOneOperand(opnd)) {
3094         Error("ParseExprExtractbits failed");
3095         return false;
3096     }
3097     extrctNode->SetOpnd(opnd, 0);
3098     lexer.NextToken();
3099     return true;
3100 }
3101 
ParseExprTyconvert(BaseNodePtr & expr)3102 bool MIRParser::ParseExprTyconvert(BaseNodePtr &expr)
3103 {
3104     Opcode op = GetConvertOp(lexer.GetTokenKind());
3105     if (op == OP_undef) {
3106         Error("expect covertion operator but get ");
3107         return false;
3108     }
3109     auto *cvtNode = mod.CurFuncCodeMemPool()->New<TypeCvtNode>(op);
3110     expr = static_cast<BaseNode *>(cvtNode);
3111     PrimType toType = GetPrimitiveType(lexer.NextToken());
3112     if (toType == kPtyInvalid) {
3113         Error("expect to-type parsing conversion");
3114         return false;
3115     }
3116     cvtNode->SetPrimType(toType);
3117     lexer.NextToken();
3118     PrimType fromType = GetPrimitiveType(lexer.GetTokenKind());
3119     if (fromType == kPtyInvalid) {
3120         Error("expect type parsing conversion ");
3121         return false;
3122     }
3123     cvtNode->SetFromType(fromType);
3124     lexer.NextToken();
3125     BaseNode *opnd = nullptr;
3126     if (!ParseExprOneOperand(opnd)) {
3127         return false;
3128     }
3129     cvtNode->SetOpnd(opnd, 0);
3130     if (op == OP_retype) {
3131         cvtNode->SetFromType(opnd->GetPrimType());
3132     }
3133     lexer.NextToken();
3134     return true;
3135 }
3136 
ParseExprRetype(BaseNodePtr & expr)3137 bool MIRParser::ParseExprRetype(BaseNodePtr &expr)
3138 {
3139     auto *cvtNode = mod.CurFuncCodeMemPool()->New<RetypeNode>();
3140     expr = static_cast<BaseNode *>(cvtNode);
3141     PrimType toType = GetPrimitiveType(lexer.NextToken());
3142     if (toType == kPtyInvalid) {
3143         Error("expect to-type parsing conversion");
3144         return false;
3145     }
3146     cvtNode->SetPrimType(toType);
3147     lexer.NextToken();
3148     TyIdx tyidx(0);
3149     if (!ParseDerivedType(tyidx)) {
3150         Error("ParseExprRetype failed when parsing derived type ");
3151         return false;
3152     }
3153     cvtNode->SetTyIdx(tyidx);
3154     BaseNode *opnd = nullptr;
3155     if (!ParseExprOneOperand(opnd)) {
3156         return false;
3157     }
3158     cvtNode->SetOpnd(opnd, 0);
3159     cvtNode->SetFromType(opnd->GetPrimType());
3160     lexer.NextToken();
3161     return true;
3162 }
3163 
ParseExprTernary(BaseNodePtr & expr)3164 bool MIRParser::ParseExprTernary(BaseNodePtr &expr)
3165 {
3166     if (lexer.GetTokenKind() != TK_select) {
3167         Error("expect select but get ");
3168         return false;
3169     }
3170     TernaryNode *ternaryNode = mod.CurFuncCodeMemPool()->New<TernaryNode>(OP_select);
3171     expr = ternaryNode;
3172     lexer.NextToken();
3173     TyIdx tyidx(0);
3174     if (!ParsePrimType(tyidx)) {
3175         Error("expect primtype type but get ");
3176         return false;
3177     }
3178     ternaryNode->SetPrimType(GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx));
3179     MapleVector<BaseNode *> opndVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
3180     if (!ParseExprNaryOperand(opndVec)) {
3181         Error("ParseExprTernary failed");
3182         return false;
3183     }
3184     if (opndVec.size() != 3) {  // expect number of operands to be 3
3185         Error("expect 3 operands for ternary operator ");
3186         return false;
3187     }
3188     ternaryNode->SetOpnd(opndVec[kFirstOpnd], kFirstOpnd);
3189     ternaryNode->SetOpnd(opndVec[kSecondOpnd], kSecondOpnd);
3190     ternaryNode->SetOpnd(opndVec[kThirdOpnd], kThirdOpnd);
3191     lexer.NextToken();
3192     return true;
3193 }
3194 
ParseExprArray(BaseNodePtr & expr)3195 bool MIRParser::ParseExprArray(BaseNodePtr &expr)
3196 {
3197     // syntax: array <addr-type> <array-type> (<opnd0>, <opnd1>, . . . , <opndn>)
3198     auto *arrayNode = mod.CurFuncCodeMemPool()->New<ArrayNode>(mod);
3199     expr = arrayNode;
3200     if (lexer.GetTokenKind() != TK_array) {
3201         Error("expect array but get ");
3202         return false;
3203     }
3204     lexer.NextToken();
3205     if (lexer.GetTokenKind() == TK_intconst) {
3206         if (lexer.GetTheIntVal() == 1) {
3207             arrayNode->SetBoundsCheck(true);
3208         } else if (lexer.GetTheIntVal() == 0) {
3209             arrayNode->SetBoundsCheck(false);
3210         } else {
3211             Error("expect bounds_check(0/1) but get ");
3212             return false;
3213         }
3214     }
3215     lexer.NextToken();
3216     TyIdx tyidx;
3217     if (!ParsePrimType(tyidx)) {
3218         Error("expect address type but get ");
3219         return false;
3220     }
3221     auto arrayPtyp = GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(tyidx);
3222     arrayPtyp = arrayPtyp == PTY_ptr ? GetExactPtrPrimType() : arrayPtyp;
3223     arrayNode->SetPrimType(arrayPtyp);
3224     tyidx = TyIdx(0);
3225     if (!ParseType(tyidx)) {
3226         Error("expect type parsing array but get ");
3227         return false;
3228     }
3229     arrayNode->SetTyIdx(tyidx);
3230     // number of operand can not be zero
3231     MapleVector<BaseNode *> opndVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
3232     if (!ParseExprNaryOperand(opndVec)) {
3233         Error("ParseExprArray failed");
3234         return false;
3235     }
3236     if (opndVec.empty()) {
3237         Error("sematic error operands number of array expression is 0 ");
3238         return false;
3239     }
3240     arrayNode->SetNOpnd(opndVec);
3241     arrayNode->SetNumOpnds(opndVec.size());
3242     lexer.NextToken();
3243     return true;
3244 }
3245 
ParseIntrinsicId(IntrinsicopNode & intrnOpNode)3246 bool MIRParser::ParseIntrinsicId(IntrinsicopNode &intrnOpNode)
3247 {
3248     MIRIntrinsicID intrinId = GetIntrinsicID(lexer.GetTokenKind());
3249     if (intrinId <= INTRN_UNDEFINED || intrinId >= INTRN_LAST) {
3250         Error("wrong intrinsic id ");
3251         return false;
3252     }
3253     intrnOpNode.SetIntrinsic(intrinId);
3254     return true;
3255 }
3256 
ParseExprIntrinsicop(BaseNodePtr & expr)3257 bool MIRParser::ParseExprIntrinsicop(BaseNodePtr &expr)
3258 {
3259     // syntax: intrinsicop <prim-type> <intrinsic> (<opnd0>, ..., <opndn>)
3260     // syntax: intrinsicopwithtype <prim-type> <intrinsic> (<opnd0>, ..., <opndn>)
3261     Opcode opCode = OP_intrinsicopwithtype;
3262     TokenKind kind = lexer.GetTokenKind();
3263     if (kind == TK_intrinsicop) {
3264         opCode = OP_intrinsicop;
3265     } else if (kind != TK_intrinsicopwithtype) {
3266         Error("expect intrinsicop(withtype) but get ");
3267         return false;
3268     }
3269     lexer.NextToken();
3270     TyIdx pTyIdx(0);
3271     if (!ParsePrimType(pTyIdx)) {
3272         Error("ParseExprIntrinsicop(withtype) failed when parsing type");
3273         return false;
3274     }
3275 
3276     TyIdx tyIdx(0);
3277     if (opCode == OP_intrinsicopwithtype && !ParseDerivedType(tyIdx)) {
3278         Error("ParseExprIntrinsicop(withtype) failed when parsing derived type ");
3279         return false;
3280     }
3281     auto *intrnOpNode = mod.CurFuncCodeMemPool()->New<IntrinsicopNode>(
3282         mod, opCode, GlobalTables::GetTypeTable().GetPrimTypeFromTyIdx(pTyIdx), tyIdx);
3283     expr = intrnOpNode;
3284     if (!ParseIntrinsicId(*intrnOpNode)) {
3285         return false;
3286     }
3287     // number of operand can not be zero
3288     lexer.NextToken();
3289     MapleVector<BaseNode *> opndVec(mod.CurFuncCodeMemPoolAllocator()->Adapter());
3290     if (!ParseExprNaryOperand(opndVec)) {
3291         Error("ParseExprIntrinsicop(withtype) failed");
3292         return false;
3293     }
3294     intrnOpNode->SetNOpnd(opndVec);
3295     intrnOpNode->SetNumOpnds(opndVec.size());
3296     lexer.NextToken();
3297     return true;
3298 }
3299 
ParseScalarValue(MIRConstPtr & stype,MIRType & type)3300 bool MIRParser::ParseScalarValue(MIRConstPtr &stype, MIRType &type)
3301 {
3302     PrimType ptp = type.GetPrimType();
3303     if (IsPrimitiveInteger(ptp) || IsPrimitiveDynType(ptp) || ptp == PTY_gen) {
3304         if (lexer.GetTokenKind() != TK_intconst) {
3305             Error("constant value incompatible with integer type at ");
3306             return false;
3307         }
3308         stype = GlobalTables::GetIntConstTable().GetOrCreateIntConst(lexer.GetTheIntVal(), type);
3309     } else if (ptp == PTY_f32) {
3310         if (lexer.GetTokenKind() != TK_floatconst) {
3311             Error("constant value incompatible with single-precision float type at ");
3312             return false;
3313         }
3314         MIRFloatConst *fConst = GlobalTables::GetFpConstTable().GetOrCreateFloatConst(lexer.GetTheFloatVal());
3315         stype = fConst;
3316     } else if (ptp == PTY_f64) {
3317         if (lexer.GetTokenKind() != TK_doubleconst && lexer.GetTokenKind() != TK_intconst) {
3318             Error("constant value incompatible with double-precision float type at ");
3319             return false;
3320         }
3321         MIRDoubleConst *dconst = GlobalTables::GetFpConstTable().GetOrCreateDoubleConst(lexer.GetTheDoubleVal());
3322         stype = dconst;
3323     } else {
3324         return false;
3325     }
3326     return true;
3327 }
3328 
ParseConstAddrLeafExpr(MIRConstPtr & cexpr)3329 bool MIRParser::ParseConstAddrLeafExpr(MIRConstPtr &cexpr)
3330 {
3331     BaseNode *expr = nullptr;
3332     if (!ParseExpression(expr)) {
3333         return false;
3334     }
3335     CHECK_FATAL(expr != nullptr, "null ptr check");
3336     if (expr->GetOpCode() != OP_addrof && expr->GetOpCode() != OP_addroffunc && expr->GetOpCode() != OP_addroflabel &&
3337         expr->GetOpCode() != OP_conststr && expr->GetOpCode() != OP_conststr16) {
3338         Error("ParseConstAddrLeafExpr expects one of OP_addrof, OP_addroffunc, OP_conststr and OP_conststr16");
3339         return false;
3340     }
3341     if (expr->GetOpCode() == OP_addrof) {
3342         auto *anode = static_cast<AddrofNode *>(expr);
3343         auto *currFn = static_cast<MIRFunction *>(mod.CurFunction());
3344         MIRSymbol *var = currFn->GetLocalOrGlobalSymbol(anode->GetStIdx());
3345         DEBUG_ASSERT(var != nullptr, "null ptr check");
3346         var->SetNeedForwDecl();
3347         mod.SetSomeSymbolNeedForDecl(true);
3348         TyIdx ptyIdx = var->GetTyIdx();
3349         MIRPtrType ptrType(ptyIdx, (mod.IsJavaModule() ? PTY_ref : GetExactPtrPrimType()));
3350         ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
3351         MIRType *exprTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
3352         uint32 ofst = 0;
3353         if (lexer.GetTokenKind() == TK_lparen) {
3354             lexer.NextToken();
3355             if (lexer.GetTokenKind() != TK_intconst) {
3356                 Error("ParseConstAddrLeafExpr: wrong offset specification for addrof");
3357                 return false;
3358             } else {
3359                 ofst = static_cast<uint32>(lexer.GetTheIntVal());
3360             }
3361             lexer.NextToken();
3362             if (lexer.GetTokenKind() != TK_rparen) {
3363                 Error("ParseConstAddrLeafExpr expects closing paren after offset value for addrof");
3364                 return false;
3365             }
3366             lexer.NextToken();
3367         }
3368         cexpr = mod.CurFunction()->GetDataMemPool()->New<MIRAddrofConst>(anode->GetStIdx(), anode->GetFieldID(),
3369                                                                          *exprTy, ofst);
3370     } else if (expr->GetOpCode() == OP_addroffunc) {
3371         auto *aof = static_cast<AddroffuncNode *>(expr);
3372         MIRFunction *f = GlobalTables::GetFunctionTable().GetFunctionFromPuidx(aof->GetPUIdx());
3373         MIRSymbol *fName = f->GetFuncSymbol();
3374         fName->SetAppearsInCode(true);
3375         TyIdx ptyIdx = fName->GetTyIdx();
3376         MIRPtrType ptrType(ptyIdx);
3377         ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
3378         MIRType *exprTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
3379         cexpr = mod.CurFunction()->GetDataMemPool()->New<MIRAddroffuncConst>(aof->GetPUIdx(), *exprTy);
3380     } else if (expr->op == OP_addroflabel) {
3381         AddroflabelNode *aol = static_cast<AddroflabelNode *>(expr);
3382         MIRType *mirtype = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(GetExactPtrPrimType()));
3383         // func code mempool will be released after irmap, but MIRLblConst won't be passed to me ir.
3384         // So MIRLblConst can NOT be allocated in func code mempool.
3385         cexpr = mod.CurFunction()->GetDataMemPool()->New<MIRLblConst>(aol->GetOffset(), mod.CurFunction()->GetPuidx(),
3386                                                                       *mirtype);
3387     } else if (expr->GetOpCode() == OP_conststr) {
3388         auto *cs = static_cast<ConststrNode *>(expr);
3389         UStrIdx stridx = cs->GetStrIdx();
3390         TyIdx ptyIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_u8))->GetTypeIndex();
3391         MIRPtrType ptrtype(ptyIdx);
3392         ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrtype);
3393         MIRType *exprty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
3394         // func code mempool will be released after irmap, but MIRStrConst won't be passed to me ir.
3395         // So MIRStrConst can NOT be allocated in func code mempool.
3396         cexpr = mod.CurFunction()->GetDataMemPool()->New<MIRStrConst>(stridx, *exprty);
3397     } else {
3398         auto *cs = static_cast<Conststr16Node *>(expr);
3399         U16StrIdx stridx = cs->GetStrIdx();
3400         TyIdx ptyIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_u16))->GetTypeIndex();
3401         MIRPtrType ptrType(ptyIdx);
3402         ptyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&ptrType);
3403         MIRType *exprTy = GlobalTables::GetTypeTable().GetTypeFromTyIdx(ptyIdx);
3404         // func code mempool will be released after irmap, but MIRStr16Const won't be passed to me ir.
3405         // So MIRStr16Const can NOT be allocated in func code mempool.
3406         cexpr = mod.CurFunction()->GetDataMemPool()->New<MIRStr16Const>(stridx, *exprTy);
3407     }
3408     return true;
3409 }
3410 
ParseExpression(BaseNodePtr & expr)3411 bool MIRParser::ParseExpression(BaseNodePtr &expr)
3412 {
3413     TokenKind tk = lexer.GetTokenKind();
3414     std::map<TokenKind, MIRParser::FuncPtrParseExpr>::iterator itFuncPtr = funcPtrMapForParseExpr.find(tk);
3415     if (itFuncPtr == funcPtrMapForParseExpr.end()) {
3416         Error("expect expression but get ");
3417         return false;
3418     } else {
3419         if (!(this->*(itFuncPtr->second))(expr)) {
3420             return false;
3421         }
3422     }
3423     return true;
3424 }
3425 
InitFuncPtrMapForParseExpr()3426 std::map<TokenKind, MIRParser::FuncPtrParseExpr> MIRParser::InitFuncPtrMapForParseExpr()
3427 {
3428     std::map<TokenKind, MIRParser::FuncPtrParseExpr> funcPtrMap;
3429     funcPtrMap[TK_addrof] = &MIRParser::ParseExprAddrof;
3430     funcPtrMap[TK_addrofoff] = &MIRParser::ParseExprAddrofoff;
3431     funcPtrMap[TK_addroffunc] = &MIRParser::ParseExprAddroffunc;
3432     funcPtrMap[TK_addroflabel] = &MIRParser::ParseExprAddroflabel;
3433     funcPtrMap[TK_abs] = &MIRParser::ParseExprUnary;
3434     funcPtrMap[TK_bnot] = &MIRParser::ParseExprUnary;
3435     funcPtrMap[TK_lnot] = &MIRParser::ParseExprUnary;
3436     funcPtrMap[TK_neg] = &MIRParser::ParseExprUnary;
3437     funcPtrMap[TK_recip] = &MIRParser::ParseExprUnary;
3438     funcPtrMap[TK_sqrt] = &MIRParser::ParseExprUnary;
3439     funcPtrMap[TK_alloca] = &MIRParser::ParseExprUnary;
3440     funcPtrMap[TK_malloc] = &MIRParser::ParseExprUnary;
3441     funcPtrMap[TK_gcmalloc] = &MIRParser::ParseExprGCMalloc;
3442     funcPtrMap[TK_gcpermalloc] = &MIRParser::ParseExprGCMalloc;
3443     funcPtrMap[TK_gcmallocjarray] = &MIRParser::ParseExprJarray;
3444     funcPtrMap[TK_gcpermallocjarray] = &MIRParser::ParseExprJarray;
3445     funcPtrMap[TK_sext] = &MIRParser::ParseExprExtractbits;
3446     funcPtrMap[TK_zext] = &MIRParser::ParseExprExtractbits;
3447     funcPtrMap[TK_extractbits] = &MIRParser::ParseExprExtractbits;
3448     funcPtrMap[TK_ceil] = &MIRParser::ParseExprTyconvert;
3449     funcPtrMap[TK_cvt] = &MIRParser::ParseExprTyconvert;
3450     funcPtrMap[TK_floor] = &MIRParser::ParseExprTyconvert;
3451     funcPtrMap[TK_round] = &MIRParser::ParseExprTyconvert;
3452     funcPtrMap[TK_trunc] = &MIRParser::ParseExprTyconvert;
3453     funcPtrMap[TK_retype] = &MIRParser::ParseExprRetype;
3454     funcPtrMap[TK_select] = &MIRParser::ParseExprTernary;
3455     funcPtrMap[TK_array] = &MIRParser::ParseExprArray;
3456     funcPtrMap[TK_intrinsicop] = &MIRParser::ParseExprIntrinsicop;
3457     funcPtrMap[TK_intrinsicopwithtype] = &MIRParser::ParseExprIntrinsicop;
3458     funcPtrMap[TK_constval] = &MIRParser::ParseExprConstval;
3459     funcPtrMap[TK_conststr] = &MIRParser::ParseExprConststr;
3460     funcPtrMap[TK_conststr16] = &MIRParser::ParseExprConststr16;
3461     funcPtrMap[TK_sizeoftype] = &MIRParser::ParseExprSizeoftype;
3462     funcPtrMap[TK_fieldsdist] = &MIRParser::ParseExprFieldsDist;
3463     funcPtrMap[TK_iaddrof] = &MIRParser::ParseExprIaddrof;
3464     funcPtrMap[TK_iread] = &MIRParser::ParseExprIread;
3465     funcPtrMap[TK_ireadoff] = &MIRParser::ParseExprIreadoff;
3466     funcPtrMap[TK_ireadfpoff] = &MIRParser::ParseExprIreadFPoff;
3467     funcPtrMap[TK_dread] = &MIRParser::ParseExprDread;
3468     funcPtrMap[TK_dreadoff] = &MIRParser::ParseExprDreadoff;
3469     funcPtrMap[TK_regread] = &MIRParser::ParseExprRegread;
3470     funcPtrMap[TK_add] = &MIRParser::ParseExprBinary;
3471     funcPtrMap[TK_ashr] = &MIRParser::ParseExprBinary;
3472     funcPtrMap[TK_band] = &MIRParser::ParseExprBinary;
3473     funcPtrMap[TK_bior] = &MIRParser::ParseExprBinary;
3474     funcPtrMap[TK_bxor] = &MIRParser::ParseExprBinary;
3475     funcPtrMap[TK_cand] = &MIRParser::ParseExprBinary;
3476     funcPtrMap[TK_cior] = &MIRParser::ParseExprBinary;
3477     funcPtrMap[TK_div] = &MIRParser::ParseExprBinary;
3478     funcPtrMap[TK_land] = &MIRParser::ParseExprBinary;
3479     funcPtrMap[TK_lior] = &MIRParser::ParseExprBinary;
3480     funcPtrMap[TK_lshr] = &MIRParser::ParseExprBinary;
3481     funcPtrMap[TK_max] = &MIRParser::ParseExprBinary;
3482     funcPtrMap[TK_min] = &MIRParser::ParseExprBinary;
3483     funcPtrMap[TK_mul] = &MIRParser::ParseExprBinary;
3484     funcPtrMap[TK_rem] = &MIRParser::ParseExprBinary;
3485     funcPtrMap[TK_shl] = &MIRParser::ParseExprBinary;
3486     funcPtrMap[TK_ror] = &MIRParser::ParseExprBinary;
3487     funcPtrMap[TK_sub] = &MIRParser::ParseExprBinary;
3488     funcPtrMap[TK_CG_array_elem_add] = &MIRParser::ParseExprBinary;
3489     funcPtrMap[TK_cmp] = &MIRParser::ParseExprCompare;
3490     funcPtrMap[TK_cmpl] = &MIRParser::ParseExprCompare;
3491     funcPtrMap[TK_cmpg] = &MIRParser::ParseExprCompare;
3492     funcPtrMap[TK_eq] = &MIRParser::ParseExprCompare;
3493     funcPtrMap[TK_ge] = &MIRParser::ParseExprCompare;
3494     funcPtrMap[TK_gt] = &MIRParser::ParseExprCompare;
3495     funcPtrMap[TK_le] = &MIRParser::ParseExprCompare;
3496     funcPtrMap[TK_lt] = &MIRParser::ParseExprCompare;
3497     funcPtrMap[TK_ne] = &MIRParser::ParseExprCompare;
3498     funcPtrMap[TK_depositbits] = &MIRParser::ParseExprDepositbits;
3499     return funcPtrMap;
3500 }
3501 
InitFuncPtrMapForParseStmt()3502 std::map<TokenKind, MIRParser::FuncPtrParseStmt> MIRParser::InitFuncPtrMapForParseStmt()
3503 {
3504     std::map<TokenKind, MIRParser::FuncPtrParseStmt> funcPtrMap;
3505     funcPtrMap[TK_dassign] = &MIRParser::ParseStmtDassign;
3506     funcPtrMap[TK_dassignoff] = &MIRParser::ParseStmtDassignoff;
3507     funcPtrMap[TK_iassign] = &MIRParser::ParseStmtIassign;
3508     funcPtrMap[TK_iassignoff] = &MIRParser::ParseStmtIassignoff;
3509     funcPtrMap[TK_iassignfpoff] = &MIRParser::ParseStmtIassignFPoff;
3510     funcPtrMap[TK_iassignspoff] = &MIRParser::ParseStmtIassignFPoff;
3511     funcPtrMap[TK_blkassignoff] = &MIRParser::ParseStmtBlkassignoff;
3512     funcPtrMap[TK_regassign] = &MIRParser::ParseStmtRegassign;
3513     funcPtrMap[TK_doloop] = &MIRParser::ParseStmtDoloop;
3514     funcPtrMap[TK_foreachelem] = &MIRParser::ParseStmtForeachelem;
3515     funcPtrMap[TK_dowhile] = &MIRParser::ParseStmtDowhile;
3516     funcPtrMap[TK_if] = &MIRParser::ParseStmtIf;
3517     funcPtrMap[TK_while] = &MIRParser::ParseStmtWhile;
3518     funcPtrMap[TK_goto] = &MIRParser::ParseStmtGoto;
3519     funcPtrMap[TK_brfalse] = &MIRParser::ParseStmtBr;
3520     funcPtrMap[TK_brtrue] = &MIRParser::ParseStmtBr;
3521     funcPtrMap[TK_switch] = &MIRParser::ParseStmtSwitch;
3522     funcPtrMap[TK_rangegoto] = &MIRParser::ParseStmtRangegoto;
3523     funcPtrMap[TK_multiway] = &MIRParser::ParseStmtMultiway;
3524     funcPtrMap[TK_call] = &MIRParser::ParseStmtCall;
3525     funcPtrMap[TK_virtualcall] = &MIRParser::ParseStmtCall;
3526     funcPtrMap[TK_virtualicall] = &MIRParser::ParseStmtCall;
3527     funcPtrMap[TK_superclasscall] = &MIRParser::ParseStmtCall;
3528     funcPtrMap[TK_interfacecall] = &MIRParser::ParseStmtCall;
3529     funcPtrMap[TK_interfaceicall] = &MIRParser::ParseStmtCall;
3530     funcPtrMap[TK_customcall] = &MIRParser::ParseStmtCall;
3531     funcPtrMap[TK_polymorphiccall] = &MIRParser::ParseStmtCall;
3532     funcPtrMap[TK_callinstant] = &MIRParser::ParseStmtCall;
3533     funcPtrMap[TK_virtualcallinstant] = &MIRParser::ParseStmtCall;
3534     funcPtrMap[TK_superclasscallinstant] = &MIRParser::ParseStmtCall;
3535     funcPtrMap[TK_interfacecallinstant] = &MIRParser::ParseStmtCall;
3536     funcPtrMap[TK_callassigned] = &MIRParser::ParseStmtCall;
3537     funcPtrMap[TK_virtualcallassigned] = &MIRParser::ParseStmtCall;
3538     funcPtrMap[TK_virtualicallassigned] = &MIRParser::ParseStmtCall;
3539     funcPtrMap[TK_superclasscallassigned] = &MIRParser::ParseStmtCall;
3540     funcPtrMap[TK_interfacecallassigned] = &MIRParser::ParseStmtCall;
3541     funcPtrMap[TK_interfaceicallassigned] = &MIRParser::ParseStmtCall;
3542     funcPtrMap[TK_customcallassigned] = &MIRParser::ParseStmtCall;
3543     funcPtrMap[TK_polymorphiccallassigned] = &MIRParser::ParseStmtCall;
3544     funcPtrMap[TK_callinstantassigned] = &MIRParser::ParseStmtCall;
3545     funcPtrMap[TK_virtualcallinstantassigned] = &MIRParser::ParseStmtCall;
3546     funcPtrMap[TK_superclasscallinstantassigned] = &MIRParser::ParseStmtCall;
3547     funcPtrMap[TK_interfacecallinstantassigned] = &MIRParser::ParseStmtCall;
3548     funcPtrMap[TK_icall] = &MIRParser::ParseStmtIcall;
3549     funcPtrMap[TK_icallassigned] = &MIRParser::ParseStmtIcallassigned;
3550     funcPtrMap[TK_icallproto] = &MIRParser::ParseStmtIcallproto;
3551     funcPtrMap[TK_icallprotoassigned] = &MIRParser::ParseStmtIcallprotoassigned;
3552     funcPtrMap[TK_intrinsiccall] = &MIRParser::ParseStmtIntrinsiccall;
3553     funcPtrMap[TK_intrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned;
3554     funcPtrMap[TK_xintrinsiccall] = &MIRParser::ParseStmtIntrinsiccall;
3555     funcPtrMap[TK_xintrinsiccallassigned] = &MIRParser::ParseStmtIntrinsiccallassigned;
3556     funcPtrMap[TK_intrinsiccallwithtype] = &MIRParser::ParseStmtIntrinsiccallwithtype;
3557     funcPtrMap[TK_intrinsiccallwithtypeassigned] = &MIRParser::ParseStmtIntrinsiccallwithtypeassigned;
3558     funcPtrMap[TK_return] = &MIRParser::ParseNaryStmtReturn;
3559     funcPtrMap[TK_jstry] = &MIRParser::ParseStmtJsTry;
3560     funcPtrMap[TK_try] = &MIRParser::ParseStmtTry;
3561     funcPtrMap[TK_catch] = &MIRParser::ParseStmtCatch;
3562     funcPtrMap[TK_syncenter] = &MIRParser::ParseNaryStmtSyncEnter;
3563     funcPtrMap[TK_syncexit] = &MIRParser::ParseNaryStmtSyncExit;
3564     funcPtrMap[TK_throw] = &MIRParser::ParseUnaryStmtThrow;
3565     funcPtrMap[TK_decref] = &MIRParser::ParseUnaryStmtDecRef;
3566     funcPtrMap[TK_incref] = &MIRParser::ParseUnaryStmtIncRef;
3567     funcPtrMap[TK_decrefreset] = &MIRParser::ParseUnaryStmtDecRefReset;
3568     funcPtrMap[TK_igoto] = &MIRParser::ParseUnaryStmtIGoto;
3569     funcPtrMap[TK_jscatch] = &MIRParser::ParseStmtMarker;
3570     funcPtrMap[TK_finally] = &MIRParser::ParseStmtMarker;
3571     funcPtrMap[TK_cleanuptry] = &MIRParser::ParseStmtMarker;
3572     funcPtrMap[TK_endtry] = &MIRParser::ParseStmtMarker;
3573     funcPtrMap[TK_retsub] = &MIRParser::ParseStmtMarker;
3574     funcPtrMap[TK_membaracquire] = &MIRParser::ParseStmtMarker;
3575     funcPtrMap[TK_membarrelease] = &MIRParser::ParseStmtMarker;
3576     funcPtrMap[TK_membarstoreload] = &MIRParser::ParseStmtMarker;
3577     funcPtrMap[TK_membarstorestore] = &MIRParser::ParseStmtMarker;
3578     funcPtrMap[TK_gosub] = &MIRParser::ParseStmtGosub;
3579     funcPtrMap[TK_eval] = &MIRParser::ParseUnaryStmtEval;
3580     funcPtrMap[TK_free] = &MIRParser::ParseUnaryStmtFree;
3581     funcPtrMap[TK_assertnonnull] = &MIRParser::ParseUnaryStmtAssertNonNull;
3582     funcPtrMap[TK_callassertnonnull] = &MIRParser::ParseUnaryStmtCallAssertNonNull;
3583     funcPtrMap[TK_assignassertnonnull] = &MIRParser::ParseUnaryStmtAssignAssertNonNull;
3584     funcPtrMap[TK_returnassertnonnull] = &MIRParser::ParseUnaryStmtReturnAssertNonNull;
3585     funcPtrMap[TK_assertge] = &MIRParser::ParseNaryStmtAssertGE;
3586     funcPtrMap[TK_assertlt] = &MIRParser::ParseNaryStmtAssertLT;
3587     funcPtrMap[TK_calcassertge] = &MIRParser::ParseNaryStmtCalcassertGE;
3588     funcPtrMap[TK_calcassertlt] = &MIRParser::ParseNaryStmtCalcassertLT;
3589     funcPtrMap[TK_returnassertle] = &MIRParser::ParseNaryStmtReturnAssertLE;
3590     funcPtrMap[TK_callassertle] = &MIRParser::ParseNaryStmtCallAssertLE;
3591     funcPtrMap[TK_assignassertle] = &MIRParser::ParseNaryStmtAssignAssertLE;
3592     funcPtrMap[TK_label] = &MIRParser::ParseStmtLabel;
3593     funcPtrMap[TK_LOC] = &MIRParser::ParseLocStmt;
3594     funcPtrMap[TK_SCOPE] = &MIRParser::ParseScope;
3595     funcPtrMap[TK_ALIAS] = &MIRParser::ParseAlias;
3596     funcPtrMap[TK_asm] = &MIRParser::ParseStmtAsm;
3597     funcPtrMap[TK_safe] = &MIRParser::ParseStmtSafeRegion;
3598     funcPtrMap[TK_endsafe] = &MIRParser::ParseStmtSafeRegion;
3599     funcPtrMap[TK_unsafe] = &MIRParser::ParseStmtSafeRegion;
3600     funcPtrMap[TK_endunsafe] = &MIRParser::ParseStmtSafeRegion;
3601     return funcPtrMap;
3602 }
3603 
InitFuncPtrMapForParseStmtBlock()3604 std::map<TokenKind, MIRParser::FuncPtrParseStmtBlock> MIRParser::InitFuncPtrMapForParseStmtBlock()
3605 {
3606     std::map<TokenKind, MIRParser::FuncPtrParseStmtBlock> funcPtrMap;
3607     funcPtrMap[TK_var] = &MIRParser::ParseStmtBlockForVar;
3608     funcPtrMap[TK_tempvar] = &MIRParser::ParseStmtBlockForTempVar;
3609     funcPtrMap[TK_reg] = &MIRParser::ParseStmtBlockForReg;
3610     funcPtrMap[TK_type] = &MIRParser::ParseStmtBlockForType;
3611     funcPtrMap[TK_framesize] = &MIRParser::ParseStmtBlockForFrameSize;
3612     funcPtrMap[TK_upformalsize] = &MIRParser::ParseStmtBlockForUpformalSize;
3613     funcPtrMap[TK_moduleid] = &MIRParser::ParseStmtBlockForModuleID;
3614     funcPtrMap[TK_funcsize] = &MIRParser::ParseStmtBlockForFuncSize;
3615     funcPtrMap[TK_funcid] = &MIRParser::ParseStmtBlockForFuncID;
3616     funcPtrMap[TK_formalwordstypetagged] = &MIRParser::ParseStmtBlockForFormalWordsTypeTagged;
3617     funcPtrMap[TK_localwordstypetagged] = &MIRParser::ParseStmtBlockForLocalWordsTypeTagged;
3618     funcPtrMap[TK_formalwordsrefcounted] = &MIRParser::ParseStmtBlockForFormalWordsRefCounted;
3619     funcPtrMap[TK_localwordsrefcounted] = &MIRParser::ParseStmtBlockForLocalWordsRefCounted;
3620     funcPtrMap[TK_funcinfo] = &MIRParser::ParseStmtBlockForFuncInfo;
3621     return funcPtrMap;
3622 }
3623 
SetSrcPos(SrcPosition & srcPosition,uint32 mplNum)3624 void MIRParser::SetSrcPos(SrcPosition &srcPosition, uint32 mplNum)
3625 {
3626     srcPosition.SetFileNum(lastFileNum);
3627     srcPosition.SetLineNum(lastLineNum);
3628     srcPosition.SetColumn(lastColumnNum);
3629     srcPosition.SetMplLineNum(mplNum);
3630 }
3631 }  // namespace maple
3632