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