• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <climits>
17 #include <cstdlib>
18 #include <sstream>
19 #include <fstream>
20 #include "mir_parser.h"
21 #include "mir_scope.h"
22 #include "mir_function.h"
23 #include "namemangler.h"
24 #include "opcode_info.h"
25 #include "mir_pragma.h"
26 #include "bin_mplt.h"
27 #include "option.h"
28 #include "clone.h"
29 #include "string_utils.h"
30 #include "debug_info.h"
31 
32 namespace {
33 using namespace maple;
34 constexpr char kLexerStringSp[] = "SP";
35 constexpr char kLexerStringFp[] = "FP";
36 constexpr char kLexerStringGp[] = "GP";
37 constexpr char kLexerStringThrownval[] = "thrownval";
38 constexpr char kLexerStringRetval[] = "retval";
39 const std::map<std::string, SpecialReg> pregMapIdx = {{kLexerStringSp, kSregSp},
40                                                       {kLexerStringFp, kSregFp},
41                                                       {kLexerStringGp, kSregGp},
42                                                       {kLexerStringThrownval, kSregThrownval},
43                                                       {kLexerStringRetval, kSregRetval0}};
44 
45 const std::map<TokenKind, PragmaKind> tkPragmaKind = {{TK_class, kPragmaClass},
46                                                       {TK_func, kPragmaFunc},
47                                                       {TK_var, kPragmaVar},
48                                                       {TK_param, kPragmaParam},
49                                                       {TK_func_ex, kPragmaFuncExecptioni},
50                                                       {TK_func_var, kPragmaFuncVar}};
51 const std::map<TokenKind, PragmaValueType> tkPragmaValType = {
52     {TK_i8, kValueByte},          {TK_i16, kValueShort},  {TK_u16, kValueChar},    {TK_i32, kValueInt},
53     {TK_i64, kValueLong},         {TK_f32, kValueFloat},  {TK_f64, kValueDouble},  {TK_retype, kValueMethodType},
54     {TK_ref, kValueMethodHandle}, {TK_ptr, kValueString}, {TK_type, kValueType},   {TK_var, kValueField},
55     {TK_func, kValueMethod},      {TK_enum, kValueEnum},  {TK_array, kValueArray}, {TK_annotation, kValueAnnotation},
56     {TK_const, kValueNull},       {TK_u1, kValueBoolean}};
57 }  // namespace
58 
59 namespace maple {
60 std::map<TokenKind, MIRParser::FuncPtrParseMIRForElem> MIRParser::funcPtrMapForParseMIR =
61     MIRParser::InitFuncPtrMapForParseMIR();
62 
CreateDummyFunction()63 MIRFunction *MIRParser::CreateDummyFunction()
64 {
65     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("__$$__");
66     MIRBuilder mirBuilder(&mod);
67     MIRSymbol *funcSt = mirBuilder.CreateSymbol(TyIdx(0), strIdx, kStFunc, kScUnused, nullptr, kScopeGlobal);
68     CHECK_FATAL(funcSt != nullptr, "Failed to create MIRSymbol");
69     // Don't add the function to the function table.
70     // It appears Storage class kScUnused is not honored.
71     MIRFunction *func = mirBuilder.CreateFunction(funcSt->GetStIdx(), false);
72     CHECK_FATAL(func != nullptr, "Failed to create MIRFunction");
73     func->SetPuidxOrigin(func->GetPuidx());
74     MIRType *returnType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_void));
75     func->SetReturnTyIdx(returnType->GetTypeIndex());
76     func->SetClassTyIdx(0U);
77     func->SetBaseClassFuncNames(strIdx);
78     funcSt->SetFunction(func);
79     return func;
80 }
81 
IsDelimitationTK(TokenKind tk) const82 bool MIRParser::IsDelimitationTK(TokenKind tk) const
83 {
84     switch (tk) {
85         case TK_rparen:
86         case TK_coma:
87             return true;
88         default:
89             return false;
90     }
91 }
92 
IsPowerOf2(uint64 num)93 inline bool IsPowerOf2(uint64 num)
94 {
95     if (num == 0) {
96         return false;
97     }
98     return (~(num - 1) & num) == num;
99 }
100 
GetOpFromToken(TokenKind tk) const101 Opcode MIRParser::GetOpFromToken(TokenKind tk) const
102 {
103     switch (tk) {
104 #define OPCODE(X, Y, Z, S) \
105     case TK_##X:           \
106         return OP_##X;
107 #include "opcodes.def"
108 #undef OPCODE
109         default:
110             return OP_undef;
111     }
112 }
113 
IsClassInterfaceTypeName(const std::string & nameStr)114 static bool IsClassInterfaceTypeName(const std::string &nameStr)
115 {
116     return (!nameStr.empty() && nameStr.front() == 'L' && StringUtils::EndsWith(nameStr, "_3B"));
117 }
118 
IsStatement(TokenKind tk) const119 bool MIRParser::IsStatement(TokenKind tk) const
120 {
121     if (tk == TK_LOC || tk == TK_ALIAS || tk == TK_SCOPE) {
122         return true;
123     }
124     Opcode op = GetOpFromToken(tk);
125     return kOpcodeInfo.IsStmt(op);
126 }
127 
GetPrimitiveType(TokenKind tk) const128 PrimType MIRParser::GetPrimitiveType(TokenKind tk) const
129 {
130 #define LOAD_ALGO_PRIMARY_TYPE
131     switch (tk) {
132 #define PRIMTYPE(P)                       \
133     case TK_##P: {                        \
134         if (tk == TK_ptr) {               \
135             return GetExactPtrPrimType(); \
136         }                                 \
137         return PTY_##P;                   \
138     }
139 #include "prim_types.def"
140 #undef PRIMTYPE
141         default:
142             return kPtyInvalid;
143     }
144 }
145 
GetIntrinsicID(TokenKind tk) const146 MIRIntrinsicID MIRParser::GetIntrinsicID(TokenKind tk) const
147 {
148     switch (tk) {
149         default:
150 #define DEF_MIR_INTRINSIC(P, NAME, INTRN_CLASS, RETURN_TYPE, ...) \
151     case TK_##P: {                                                \
152         return INTRN_##P;                                         \
153     }
154 #include "intrinsics.def"
155 #undef DEF_MIR_INTRINSIC
156     }
157 }
158 
Error(const std::string & str)159 void MIRParser::Error(const std::string &str)
160 {
161     std::stringstream strStream;
162     const std::string &lexName = lexer.GetName();
163     int curIdx = lexer.GetCurIdx() - lexName.length() + 1;
164     strStream << "line: " << lexer.GetLineNum() << ":" << curIdx << ":";
165     message += strStream.str();
166     message += str;
167     message += ": ";
168     message += lexer.GetTokenString();
169     message += "\n";
170     mod.GetDbgInfo()->SetErrPos(lexer.GetLineNum(), lexer.GetCurIdx());
171 }
172 
GetError()173 const std::string &MIRParser::GetError()
174 {
175     if (lexer.GetTokenKind() == TK_invalid) {
176         std::stringstream strStream;
177         strStream << "line: " << lexer.GetLineNum() << ":" << lexer.GetCurIdx() << ":";
178         message += strStream.str();
179         message += " invalid token\n";
180     }
181     return message;
182 }
183 
Warning(const std::string & str)184 void MIRParser::Warning(const std::string &str)
185 {
186     std::stringstream strStream;
187     const std::string &lexName = lexer.GetName();
188     int curIdx = lexer.GetCurIdx() - lexName.length() + 1;
189     strStream << "  >> warning line: " << lexer.GetLineNum() << ":" << curIdx << ":";
190     warningMessage += strStream.str();
191     warningMessage += str;
192     warningMessage += "\n";
193 }
194 
GetWarning() const195 const std::string &MIRParser::GetWarning() const
196 {
197     return warningMessage;
198 }
199 
ParseSpecialReg(PregIdx & pRegIdx)200 bool MIRParser::ParseSpecialReg(PregIdx &pRegIdx)
201 {
202     const std::string &lexName = lexer.GetName();
203     size_t lexSize = lexName.size();
204     size_t retValSize = strlen(kLexerStringRetval);
205     if (strncmp(lexName.c_str(), kLexerStringRetval, retValSize) == 0 && (lexSize > retValSize) &&
206         isdigit(lexName[retValSize])) {
207         int32 retValNo = lexName[retValSize] - '0';
208         for (size_t i = retValSize + 1; (i < lexSize) && isdigit(lexName[i]); ++i) {
209             retValNo = retValNo * 10 + lexName[i] - '0'; // 10 for decimal
210         }
211         pRegIdx = -kSregRetval0 - retValNo;
212         lexer.NextToken();
213         return true;
214     }
215 
216     auto it = pregMapIdx.find(lexName);
217     if (it != pregMapIdx.end()) {
218         pRegIdx = -(it->second);
219         lexer.NextToken();
220         return true;
221     }
222 
223     Error("unrecognized special register ");
224     return false;
225 }
226 
ParsePseudoReg(PrimType primType,PregIdx & pRegIdx)227 bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx)
228 {
229     uint32 pregNo = static_cast<uint32>(lexer.GetTheIntVal());
230     DEBUG_ASSERT(pregNo <= 0xffff, "preg number must be 16 bits");
231     MIRFunction *curfunc = mod.CurFunction();
232     pRegIdx = curfunc->GetPregTab()->EnterPregNo(pregNo, primType);
233     MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx);
234     if (primType != kPtyInvalid) {
235         if (preg->GetPrimType() != primType) {
236             if (IsAddress(preg->GetPrimType()) && IsAddress(primType)) {
237             } else {
238                 Error("inconsistent preg primitive type at ");
239                 return false;
240             }
241         }
242     }
243 
244     lexer.NextToken();
245     return true;
246 }
247 
CheckPrimAndDerivedType(TokenKind tokenKind,TyIdx & tyIdx)248 bool MIRParser::CheckPrimAndDerivedType(TokenKind tokenKind, TyIdx &tyIdx)
249 {
250     if (IsPrimitiveType(tokenKind)) {
251         return ParsePrimType(tyIdx);
252     }
253     if (tokenKind == TK_langle) {
254         return ParseDerivedType(tyIdx);
255     }
256     return false;
257 }
258 
ParseType(TyIdx & tyIdx)259 bool MIRParser::ParseType(TyIdx &tyIdx)
260 {
261     TokenKind tk = lexer.GetTokenKind();
262     if (IsVarName(tk)) {
263         return ParseDefinedTypename(tyIdx);
264     }
265     if (CheckPrimAndDerivedType(tk, tyIdx)) {
266         return true;
267     }
268     Error("token is not a type ");
269     return false;
270 }
271 
ParseFarrayType(TyIdx & arrayTyIdx)272 bool MIRParser::ParseFarrayType(TyIdx &arrayTyIdx)
273 {
274     TokenKind tokenKind = lexer.NextToken();
275     TyIdx tyIdx;
276     if (!CheckPrimAndDerivedType(tokenKind, tyIdx)) {
277         Error("unexpect token parsing flexible array element type ");
278         return false;
279     }
280     DEBUG_ASSERT(tyIdx != 0u, "error encountered parsing flexible array element type ");
281     if (mod.IsJavaModule() || mod.IsCharModule()) {
282         MIRJarrayType jarrayType(tyIdx);
283         arrayTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&jarrayType);
284     } else {
285         MIRFarrayType farrayType(tyIdx);
286         arrayTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&farrayType);
287     }
288     return true;
289 }
290 
ParseArrayType(TyIdx & arrayTyIdx)291 bool MIRParser::ParseArrayType(TyIdx &arrayTyIdx)
292 {
293     TokenKind tokenKind = lexer.GetTokenKind();
294     if (tokenKind != TK_lbrack) {
295         Error("expect [ for array type but get ");
296         return false;
297     }
298     std::vector<uint32> vec;
299     while (tokenKind == TK_lbrack) {
300         tokenKind = lexer.NextToken();
301         if (tokenKind == TK_rbrack && vec.empty()) {
302             break;
303         }
304         if (tokenKind != TK_intconst) {
305             Error("expect int value parsing array type after [ but get ");
306             return false;
307         }
308         int64 val = lexer.GetTheIntVal();
309         if (val < 0) {
310             Error("expect array value >= 0 ");
311             return false;
312         }
313         vec.push_back(val);
314         if (lexer.NextToken() != TK_rbrack) {
315             Error("expect ] after int value parsing array type but get ");
316             return false;
317         }
318         tokenKind = lexer.NextToken();
319     }
320     if (tokenKind == TK_rbrack && vec.empty()) {
321         return ParseFarrayType(arrayTyIdx);
322     }
323     TyIdx tyIdx;
324     if (!CheckPrimAndDerivedType(tokenKind, tyIdx)) {
325         Error("unexpect token parsing array type after ] ");
326         return false;
327     }
328     DEBUG_ASSERT(tyIdx != 0u, "something wrong with parsing element type ");
329     MIRArrayType arrayType(tyIdx, vec);
330     if (!ParseTypeAttrs(arrayType.GetTypeAttrs())) {
331         Error("bad type attribute in pointer type specification");
332         return false;
333     }
334     arrayTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&arrayType);
335     return true;
336 }
337 
ParseBitFieldType(TyIdx & fieldTyIdx)338 bool MIRParser::ParseBitFieldType(TyIdx &fieldTyIdx)
339 {
340     if (lexer.GetTokenKind() != TK_colon) {
341         Error("expect : parsing field type but get ");
342         return false;
343     }
344     if (lexer.NextToken() != TK_intconst) {
345         Error("expect int const val parsing field type but get ");
346         return false;
347     }
348     DEBUG_ASSERT(lexer.GetTheIntVal() <= 0xFFU, "lexer.theIntVal is larger than max uint8 bitsize value.");
349     uint8 bitSize = static_cast<uint8>(lexer.GetTheIntVal()) & 0xFFU;
350     PrimType primType = GetPrimitiveType(lexer.NextToken());
351     if (primType == kPtyInvalid) {
352         Error("expect primitive type but get ");
353         return false;
354     }
355     if (!IsPrimitiveInteger(primType)) {
356         Error("syntax error bit field should be integer type but get ");
357         return false;
358     }
359     MIRBitFieldType bitFieldType(bitSize, primType);
360     fieldTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&bitFieldType);
361     lexer.NextToken();
362     return true;
363 }
364 
ParsePragmaElement(MIRPragmaElement & elem)365 bool MIRParser::ParsePragmaElement(MIRPragmaElement &elem)
366 {
367     TokenKind tk = lexer.GetTokenKind();
368     lexer.NextToken();
369     auto it = tkPragmaValType.find(tk);
370     if (it == tkPragmaValType.end()) {
371         Error("parsing pragma error: wrong element type");
372         return false;
373     }
374     elem.SetType(it->second);
375 
376     switch (tk) {
377         case TK_i8:
378         case TK_i16:
379         case TK_i32:
380             elem.SetI32Val(static_cast<int32>(lexer.GetTheIntVal()));
381             break;
382         case TK_u16:
383         case TK_ref:
384             elem.SetU64Val(static_cast<uint64>(lexer.GetTheIntVal()));
385             break;
386         case TK_i64:
387         case TK_retype:
388         case TK_const:
389         case TK_u1:
390             elem.SetI64Val(lexer.GetTheIntVal());
391             break;
392         case TK_f32:
393             elem.SetFloatVal(lexer.GetTheFloatVal());
394             break;
395         case TK_f64:
396             elem.SetDoubleVal(lexer.GetTheDoubleVal());
397             break;
398         case TK_ptr:
399         case TK_var:
400         case TK_func:
401         case TK_enum:
402             elem.SetI32Val(static_cast<int32>(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName())));
403             break;
404         case TK_type:
405             lexer.NextToken();
406             elem.SetI32Val(static_cast<int32>(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName())));
407             lexer.NextToken();
408             break;
409         case TK_array:
410             if (!ParsePragmaElementForArray(elem)) {
411                 return false;
412             }
413             break;
414         case TK_annotation:
415             if (!ParsePragmaElementForAnnotation(elem)) {
416                 return false;
417             }
418             break;
419         default:
420             return false;
421     }
422     return true;
423 }
424 
ParsePragmaElementForArray(MIRPragmaElement & elem)425 bool MIRParser::ParsePragmaElementForArray(MIRPragmaElement &elem)
426 {
427     TokenKind tk;
428     tk = lexer.GetTokenKind();
429     if (tk != TK_lbrack) {
430         Error("parsing pragma error: expecting [ but get ");
431         return false;
432     }
433     tk = lexer.NextToken();
434     if (tk != TK_intconst) {
435         Error("parsing pragma error: expecting int but get ");
436         return false;
437     }
438     int64 size = lexer.GetTheIntVal();
439     tk = lexer.NextToken();
440     if (tk != TK_coma && size) {
441         Error("parsing pragma error: expecting , but get ");
442         return false;
443     }
444     for (int64 i = 0; i < size; ++i) {
445         auto *e0 = mod.GetMemPool()->New<MIRPragmaElement>(mod);
446         tk = lexer.NextToken();
447         if (!ParsePragmaElement(*e0)) {
448             Error("parsing pragma error type ");
449             return false;
450         }
451         elem.SubElemVecPushBack(e0);
452         tk = lexer.NextToken();
453         if (tk != TK_coma && tk != TK_rbrack) {
454             Error("parsing pragma error: expecting , or ] but get ");
455             return false;
456         }
457     }
458     return true;
459 }
460 
ParsePragmaElementForAnnotation(MIRPragmaElement & elem)461 bool MIRParser::ParsePragmaElementForAnnotation(MIRPragmaElement &elem)
462 {
463     TokenKind tk;
464     tk = lexer.GetTokenKind();
465     if (tk != TK_langle) {
466         Error("parsing pragma error: expecting < but get ");
467         return false;
468     }
469     tk = lexer.NextToken();
470     elem.SetTypeStrIdx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName()));
471     tk = lexer.NextToken();
472     if (tk != TK_rangle) {
473         Error("parsing pragma error: expecting > but get ");
474         return false;
475     }
476     tk = lexer.NextToken();
477     if (tk != TK_lbrack) {
478         Error("parsing pragma error: expecting [ but get ");
479         return false;
480     }
481     tk = lexer.NextToken();
482     if (tk != TK_intconst) {
483         Error("parsing pragma error: expecting int but get ");
484         return false;
485     }
486     int64 size = lexer.GetTheIntVal();
487     tk = lexer.NextToken();
488     if (tk != TK_coma && size) {
489         Error("parsing pragma error: expecting , but get ");
490         return false;
491     }
492     for (int64 i = 0; i < size; ++i) {
493         auto *e0 = mod.GetMemPool()->New<MIRPragmaElement>(mod);
494         tk = lexer.NextToken();
495         if (tk != TK_label) {
496             Error("parsing pragma error: expecting @ but get ");
497             return false;
498         }
499         e0->SetNameStrIdx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName()));
500         tk = lexer.NextToken();
501         if (!ParsePragmaElement(*e0)) {
502             Error("parsing pragma error type ");
503             return false;
504         }
505         elem.SubElemVecPushBack(e0);
506         tk = lexer.NextToken();
507         if (tk != TK_coma && tk != TK_rbrack) {
508             Error("parsing pragma error: expecting , or ] but get ");
509             return false;
510         }
511     }
512     return true;
513 }
514 
ParsePragma(MIRStructType & type)515 bool MIRParser::ParsePragma(MIRStructType &type)
516 {
517     auto *p = mod.GetMemPool()->New<MIRPragma>(mod);
518     p->SetVisibility(lexer.GetTheIntVal());
519     TokenKind tk = lexer.NextToken();
520 
521     auto it = tkPragmaKind.find(tk);
522     if (it == tkPragmaKind.end()) {
523         Error("parsing pragma error: wrong kind ");
524         return false;
525     }
526     p->SetKind(it->second);
527 
528     if (tk == TK_param) {
529         lexer.NextToken();
530         p->SetParamNum(lexer.GetTheIntVal());
531     }
532     tk = lexer.NextToken();
533     if (tk != TK_gname && tk != TK_lname && tk != TK_fname) {
534         Error("expect global or local token parsing pragma but get ");
535         return false;
536     }
537     p->SetStrIdx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName()));
538     lexer.NextToken();
539     TyIdx tyIdx;
540     if (!ParseType(tyIdx)) {
541         Error("parsing pragma error: wrong type ");
542         return false;
543     }
544     p->SetTyIdx(tyIdx);
545 
546     tk = lexer.GetTokenKind();
547     if (tk != TK_lbrace) {
548         TyIdx tyIdxEx;
549         if (!ParseType(tyIdxEx)) {
550             Error("parsing pragma error: wrong type ");
551             return false;
552         }
553         p->SetTyIdxEx(tyIdxEx);
554     }
555 
556     tk = lexer.NextToken();
557     while (tk != TK_rbrace) {
558         auto *e = mod.GetMemPool()->New<MIRPragmaElement>(mod);
559         e->SetNameStrIdx(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName()));
560         tk = lexer.NextToken();
561         if (!ParsePragmaElement(*e)) {
562             Error("parsing pragma error type ");
563             return false;
564         }
565         p->PushElementVector(e);
566         tk = lexer.NextToken();
567         if (tk != TK_rbrace && tk != TK_coma) {
568             Error("parsing pragma error syntax ");
569             return false;
570         }
571         if (tk == TK_coma) {
572             lexer.NextToken();
573         }
574     }
575     lexer.NextToken();
576     type.PushbackPragma(p);
577     return true;
578 }
579 
580 // lexer.GetTokenKind() assumed to be the TK_lbrace that starts the fields
ParseFields(MIRStructType & type)581 bool MIRParser::ParseFields(MIRStructType &type)
582 {
583     if (type.IsIncomplete()) {
584         Warning("incomplete class/interface type");
585     }
586     TokenKind tk = lexer.NextToken();
587     MIRTypeKind tyKind = type.GetKind();
588     while (tk == TK_label || tk == TK_prntfield || tk == TK_pragma) {
589         bool isPragma = (tk == TK_pragma);
590         bool notaType = false;
591         TyIdx fieldTyIdx(0);
592         bool isParentField = false;
593         if (tk == TK_prntfield) {
594             isParentField = true;
595         }
596         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
597         tk = lexer.NextToken();
598         if (isPragma) {
599             if (tyKind == kTypeClass || tyKind == kTypeClassIncomplete || tyKind == kTypeInterface ||
600                 tyKind == kTypeInterfaceIncomplete) {
601                 if (!ParsePragma(type)) {
602                     Error("parsing pragma error ");
603                     return false;
604                 }
605             } else {
606                 Error("parsing pragma error ");
607                 return false;
608             }
609             notaType = true;
610         } else if ((tk == TK_lbrack) && (GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx) == "staticvalue")) {
611             while (tk != TK_coma) {
612                 EncodedValue elem;
613                 if (tk != TK_lbrack) {
614                     Error("parsing staticvalue error ");
615                     return false;
616                 }
617                 tk = lexer.NextToken();
618                 uint32 i = 0;
619                 while (tk != TK_rbrack) {
620                     if (tk != TK_intconst) {
621                         Error("parsing staticvalue error ");
622                         return false;
623                     }
624                     elem.encodedValue[i++] = lexer.GetTheIntVal();
625                     tk = lexer.NextToken();
626                 }
627                 tk = lexer.NextToken();
628                 if (tyKind == kTypeClass || tyKind == kTypeClassIncomplete || tyKind == kTypeInterface ||
629                     tyKind == kTypeInterfaceIncomplete) {
630                     type.PushbackStaticValue(elem);
631                 } else {
632                     Error("parsing staticvalue error ");
633                     return false;
634                 }
635             }
636             notaType = true;
637         } else if (tk == TK_colon) {  // a bitfield
638             if (!ParseBitFieldType(fieldTyIdx)) {
639                 Error("parsing struct type error ");
640                 return false;
641             }
642         } else if (tk == TK_langle) {
643             if (!ParseDerivedType(fieldTyIdx)) {
644                 Error("parsing struct type error ");
645                 return false;
646             }
647         } else if ((IsPrimitiveType(tk))) {
648             if (!ParsePrimType(fieldTyIdx)) {
649                 Error("expect :<val> or primitive type or derived type parsing struct type ");
650                 return false;
651             }
652         } else if ((tk == TK_intconst || tk == TK_string) && !isParentField &&
653                    (tyKind == kTypeClass || tyKind == kTypeClassIncomplete || tyKind == kTypeInterface ||
654                     tyKind == kTypeInterfaceIncomplete)) {
655             uint32 infoVal =
656                 (tk == TK_intconst)
657                     ? static_cast<uint32>(lexer.GetTheIntVal())
658                     : static_cast<uint32>(GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName()));
659             type.PushbackMIRInfo(MIRInfoPair(strIdx, infoVal));
660             type.PushbackIsString(tk != TK_intconst);
661             notaType = true;
662             lexer.NextToken();
663         } else {
664             Error("unexpected type parsing struct type at ");
665             return false;
666         }
667         DEBUG_ASSERT((fieldTyIdx != 0u || notaType), "something wrong parsing struct type");
668         if (!notaType) {
669             FieldAttrs tA;
670             if (!ParseFieldAttrs(tA)) {
671                 Error("bad type attribute in struct field at ");
672                 return false;
673             }
674             if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx)->HasTypeParam()) {
675                 tA.SetAttr(FLDATTR_generic);
676             }
677             FieldPair p = FieldPair(strIdx, TyIdxFieldAttrPair(fieldTyIdx, tA));
678             bool isStaticField = false;
679             if (tA.GetAttr(FLDATTR_static)) {
680                 // static and parent share the same ^ token
681                 isStaticField = true;
682                 isParentField = false;
683             }
684             if (isParentField) {
685                 type.GetParentFields().push_back(p);
686             } else if (isStaticField) {
687                 type.GetStaticFields().push_back(p);
688             } else {
689                 type.GetFields().push_back(p);
690             }
691             tk = lexer.GetTokenKind();
692             bool isConst = tA.GetAttr(FLDATTR_static) && tA.GetAttr(FLDATTR_final) &&
693                            (tA.GetAttr(FLDATTR_public) || tA.GetAttr(FLDATTR_protected));
694             if (isConst && tk == TK_eqsign) {
695                 tk = lexer.NextToken();
696                 MIRConst *mirConst = nullptr;
697                 if (!ParseInitValue(mirConst, fieldTyIdx)) {
698                     Error("wrong initialization value at ");
699                     return false;
700                 }
701                 GlobalTables::GetConstPool().InsertConstPool(p.first, mirConst);
702                 tk = lexer.GetTokenKind();
703             }
704         } else {
705             tk = lexer.GetTokenKind();
706         }
707         tk = lexer.GetTokenKind();
708         if (tk == TK_rbrace) {
709             return true;
710         }
711         if (tk != TK_coma) {
712             Error(", missing after ");
713             return false;
714         }
715         tk = lexer.NextToken();
716         if (tk == TK_rbrace) {
717             Error(",} is not legal, expect another field type after ,");
718             return false;
719         }
720     }
721     while (tk == TK_fname) {
722         const std::string &funcName = lexer.GetName();
723         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
724         MIRSymbol *prevFuncSymbol = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
725         if (prevFuncSymbol && (prevFuncSymbol->GetStorageClass() != kScText || prevFuncSymbol->GetSKind() != kStFunc)) {
726             // Based on the current maple format, a previous declaration at this
727             // point can only come from another module. Check consistency.
728             Error("redeclaration of name as func in ");
729             return false;
730         }
731         // Always create a new symbol because we can not reuse symbol from other module
732         maple::MIRBuilder mirBuilder(&mod);
733         MIRSymbol *funcSymbol = mirBuilder.CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal);
734         DEBUG_ASSERT(funcSymbol != nullptr, "Failed to create MIRSymbol");
735         SetSrcPos(funcSymbol->GetSrcPosition(), lexer.GetLineNum());
736 
737         MIRFunction *fn = mod.GetMemPool()->New<MIRFunction>(&mod, funcSymbol->GetStIdx());
738         fn->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
739         GlobalTables::GetFunctionTable().GetFuncTable().push_back(fn);
740         funcSymbol->SetFunction(fn);
741         fn->SetFileIndex(0);
742         fn->SetBaseClassFuncNames(funcSymbol->GetNameStrIdx());
743         FuncAttrs tA;
744         if (lexer.NextToken() != TK_lparen) {
745             if (!ParseFuncAttrs(tA)) {
746                 return false;
747             }
748             // Skip attribute checking
749             fn->SetFuncAttrs(tA);
750         }
751         TyIdx funcTyIdx;
752         if (!ParseFuncType(funcTyIdx)) {
753             return false;
754         }
755         // tyIdx does not work. Calling EqualTo does not work either.
756         auto *funcType = static_cast<MIRFuncType *>(GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcTyIdx));
757         fn->SetMIRFuncType(funcType);
758         fn->SetReturnStruct(*GlobalTables::GetTypeTable().GetTypeFromTyIdx(funcType->GetRetTyIdx()));
759         funcSymbol->SetTyIdx(funcTyIdx);
760 
761         for (size_t i = 0; i < funcType->GetParamTypeList().size(); i++) {
762             FormalDef formalDef(nullptr, funcType->GetParamTypeList()[i], funcType->GetParamAttrsList()[i]);
763             fn->GetFormalDefVec().push_back(formalDef);
764         }
765 
766         MethodPair p = MethodPair(funcSymbol->GetStIdx(), TyidxFuncAttrPair(funcTyIdx, FuncAttrs(tA)));
767         type.GetMethods().push_back(p);
768         tk = lexer.GetTokenKind();
769         if (tk == TK_coma) {
770             tk = lexer.NextToken();
771             if (tk == TK_rbrace) {
772                 Error(",} is not legal, expect another field type after ,");
773                 return false;
774             }
775         } else if (tk != TK_rbrace) {
776             Error(", missing after ");
777             return false;
778         } else {
779             return true;
780         }
781     }
782     // interfaces_implemented
783     while (tk == TK_gname) {
784         tk = lexer.NextToken();
785         if ((tk == TK_coma || tk == TK_rbrace) && (tyKind == kTypeClass || tyKind == kTypeClassIncomplete)) {
786             auto *classType = static_cast<MIRClassType *>(&type);
787             std::string nameStr = lexer.GetName();
788             GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(nameStr);
789             TyIdx tyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
790             if (tyIdx == 0u) {
791                 MIRInterfaceType interfaceType(kTypeInterfaceIncomplete);
792                 interfaceType.SetNameStrIdx(strIdx);
793                 tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&interfaceType);
794                 mod.AddClass(tyIdx);
795                 mod.AddExternStructType(tyIdx);
796                 mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
797             }
798             classType->GetInterfaceImplemented().push_back(tyIdx);
799         }
800         if (tk == TK_coma) {
801             tk = lexer.NextToken();
802         }
803     }
804     // allow empty class for third party classes we do not have info
805     if (tk == TK_rbrace) {
806         return true;
807     }
808     Error("expect field or member function name in struct/class body but get ");
809     return false;
810 }
811 
ParseStructType(TyIdx & styIdx,const GStrIdx & strIdx)812 bool MIRParser::ParseStructType(TyIdx &styIdx, const GStrIdx &strIdx)
813 {
814     MIRTypeKind tkind = kTypeInvalid;
815     switch (lexer.GetTokenKind()) {
816         case TK_struct:
817             tkind = kTypeStruct;
818             break;
819         case TK_structincomplete:
820             tkind = kTypeStructIncomplete;
821             break;
822         case TK_union:
823             tkind = kTypeUnion;
824             break;
825         default:
826             break;
827     }
828     MIRStructType structType(tkind, strIdx);
829     if (lexer.NextToken() != TK_lbrace) {
830         if (!ParseTypeAttrs(structType.GetTypeAttrs())) {
831             Error("bad type attribute in struct type specification");
832             return false;
833         }
834     }
835     if (lexer.GetTokenKind() != TK_lbrace) {
836         Error("expect { parsing struct body");
837         return false;
838     }
839     if (mod.GetSrcLang() == kSrcLangCPlusPlus) {
840         structType.SetIsCPlusPlus(true);
841     }
842     if (!ParseFields(structType)) {
843         return false;
844     }
845     // Bytecode file create a struct type with name, but do not check the type field.
846     if (styIdx != 0u) {
847         MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(styIdx);
848         DEBUG_ASSERT(prevType->GetKind() == kTypeStruct || prevType->IsIncomplete(), "type kind should be consistent.");
849         if (static_cast<MIRStructType *>(prevType)->IsIncomplete() && !(structType.IsIncomplete())) {
850             structType.SetNameStrIdx(prevType->GetNameStrIdx());
851             structType.SetTypeIndex(styIdx);
852             GlobalTables::GetTypeTable().SetTypeWithTyIdx(styIdx, *structType.CopyMIRTypeNode());
853         }
854     } else {
855         TyIdx prevTypeIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
856         if (prevTypeIdx != 0u) {
857             // if the MIRStructType has been created by name or incompletely, refresh the prev created type
858             MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTypeIdx);
859             if (prevType->GetKind() == kTypeByName ||
860                 (prevType->GetKind() == kTypeStructIncomplete && tkind == kTypeStruct)) {
861                 structType.SetTypeIndex(prevTypeIdx);
862                 GlobalTables::GetTypeTable().SetTypeWithTyIdx(prevTypeIdx, *structType.CopyMIRTypeNode());
863             }
864             styIdx = prevTypeIdx;
865         } else {
866             styIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&structType);
867         }
868     }
869     lexer.NextToken();
870     return true;
871 }
872 
ParseClassType(TyIdx & styidx,const GStrIdx & strIdx)873 bool MIRParser::ParseClassType(TyIdx &styidx, const GStrIdx &strIdx)
874 {
875     MIRTypeKind tkind = (lexer.GetTokenKind() == TK_class) ? kTypeClass : kTypeClassIncomplete;
876     TyIdx parentTypeIdx(0);
877     if (lexer.NextToken() == TK_langle) {
878         // parsing parent as class
879         if (!ParseDerivedType(parentTypeIdx, kTypeClass)) {
880             Error("parsing class parent type error ");
881             return false;
882         }
883     }
884     MIRClassType classType(tkind, strIdx);
885     classType.SetParentTyIdx(parentTypeIdx);
886     if (!ParseFields(classType)) {
887         return false;
888     }
889     // Bytecode file create a strtuct type with name, but donot check the type field.
890     MIRType *prevType = nullptr;
891     if (styidx != 0u) {
892         prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(styidx);
893     }
894     if (prevType != nullptr && prevType->GetKind() != kTypeByName) {
895         DEBUG_ASSERT(prevType->GetKind() == kTypeClass || prevType->IsIncomplete(), "type kind should be consistent.");
896         if (static_cast<MIRClassType *>(prevType)->IsIncomplete() && !(classType.IsIncomplete())) {
897             classType.SetNameStrIdx(prevType->GetNameStrIdx());
898             classType.SetTypeIndex(styidx);
899             GlobalTables::GetTypeTable().SetTypeWithTyIdx(styidx, *classType.CopyMIRTypeNode());
900         }
901     } else {
902         styidx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&classType);
903         // set up classTyIdx for methods
904         for (size_t i = 0; i < classType.GetMethods().size(); ++i) {
905             StIdx stIdx = classType.GetMethodsElement(i).first;
906             MIRSymbol *st = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx());
907             DEBUG_ASSERT(st->GetSKind() == kStFunc, "unexpected st->sKind");
908             st->GetFunction()->SetClassTyIdx(styidx);
909         }
910         mod.AddClass(styidx);
911     }
912     lexer.NextToken();
913     return true;
914 }
915 
ParseInterfaceType(TyIdx & sTyIdx,const GStrIdx & strIdx)916 bool MIRParser::ParseInterfaceType(TyIdx &sTyIdx, const GStrIdx &strIdx)
917 {
918     MIRTypeKind tkind = (lexer.GetTokenKind() == TK_interface) ? kTypeInterface : kTypeInterfaceIncomplete;
919     std::vector<TyIdx> parents;
920     TokenKind tk = lexer.NextToken();
921     while (tk == TK_langle) {
922         TyIdx parentTypeIdx(0);
923         // parsing parents as interfaces
924         if (!ParseDerivedType(parentTypeIdx, kTypeInterface)) {
925             Error("parsing interface parent type error ");
926             return false;
927         }
928         parents.push_back(parentTypeIdx);
929         tk = lexer.GetTokenKind();
930     }
931     MIRInterfaceType interfaceType(tkind, strIdx);
932     interfaceType.SetParentsTyIdx(parents);
933     if (!ParseFields(interfaceType)) {
934         return false;
935     }
936     // Bytecode file create a strtuct type with name, but donot check the type field.
937     if (sTyIdx != 0u) {
938         MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(sTyIdx);
939         DEBUG_ASSERT(prevType->GetKind() == kTypeInterface || prevType->IsIncomplete(),
940                      "type kind should be consistent.");
941         if (static_cast<MIRInterfaceType *>(prevType)->IsIncomplete() && !(interfaceType.IsIncomplete())) {
942             interfaceType.SetNameStrIdx(prevType->GetNameStrIdx());
943             interfaceType.SetTypeIndex(sTyIdx);
944             GlobalTables::GetTypeTable().SetTypeWithTyIdx(sTyIdx, *interfaceType.CopyMIRTypeNode());
945         }
946     } else {
947         sTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&interfaceType);
948         // set up classTyIdx for methods
949         for (size_t i = 0; i < interfaceType.GetMethods().size(); ++i) {
950             StIdx stIdx = interfaceType.GetMethodsElement(i).first;
951             MIRSymbol *st = GlobalTables::GetGsymTable().GetSymbolFromStidx(stIdx.Idx());
952             DEBUG_ASSERT(st != nullptr, "st is null");
953             DEBUG_ASSERT(st->GetSKind() == kStFunc, "unexpected st->sKind");
954             st->GetFunction()->SetClassTyIdx(sTyIdx);
955         }
956         mod.AddClass(sTyIdx);
957     }
958     lexer.NextToken();
959     return true;
960 }
961 
CheckAlignTk()962 bool MIRParser::CheckAlignTk()
963 {
964     if (lexer.NextToken() != TK_lparen) {
965         Error("unexpected token in alignment specification after ");
966         return false;
967     }
968     if (lexer.NextToken() != TK_intconst) {
969         Error("unexpected token in alignment specification after ");
970         return false;
971     }
972     if (!IsPowerOf2(lexer.GetTheIntVal())) {
973         Error("specified alignment must be power of 2 instead of ");
974         return false;
975     }
976     if (lexer.NextToken() != TK_rparen) {
977         Error("unexpected token in alignment specification after ");
978         return false;
979     }
980     return true;
981 }
982 
ParseAlignAttrs(TypeAttrs & tA)983 bool MIRParser::ParseAlignAttrs(TypeAttrs &tA)
984 {
985     if (lexer.GetTokenKind() != TK_align) {
986         Error("wrong TK kind taken from file");
987         return false;
988     }
989     if (!CheckAlignTk()) {
990         return false;
991     }
992     tA.SetAlign(lexer.GetTheIntVal());
993     return true;
994 }
995 
ParsePackAttrs()996 bool MIRParser::ParsePackAttrs()
997 {
998     if (lexer.GetTokenKind() != TK_pack) {
999         Error("wrong TK kind taken from file");
1000         return false;
1001     }
1002     if (!CheckAlignTk()) {
1003         return false;
1004     }
1005     return true;
1006 }
1007 
1008 // for variable declaration type attribute specification
1009 // it has also storage-class qualifier.
ParseVarTypeAttrs(MIRSymbol & st)1010 bool MIRParser::ParseVarTypeAttrs(MIRSymbol &st)
1011 {
1012     do {
1013         switch (lexer.GetTokenKind()) {
1014 // parse attr without no content
1015 #define TYPE_ATTR
1016 #define NOCONTENT_ATTR
1017 #define ATTR(X)               \
1018     case TK_##X: {            \
1019         st.SetAttr(ATTR_##X); \
1020         break;                \
1021     }
1022 #include "all_attributes.def"
1023 #undef ATTR
1024 #undef TYPE_ATTR
1025 #undef NOCONTENT_ATTR
1026                 // parse attr with no content
1027             case TK_align: {
1028                 if (!ParseAlignAttrs(st.GetAttrs())) {
1029                     return false;
1030                 }
1031                 break;
1032             }
1033             default:
1034                 return true;
1035         }  // switch
1036         lexer.NextToken();
1037     } while (true);
1038 }
1039 
1040 // for non-variable type attribute specification.
ParseTypeAttrs(TypeAttrs & attrs)1041 bool MIRParser::ParseTypeAttrs(TypeAttrs &attrs)
1042 {
1043     do {
1044         switch (lexer.GetTokenKind()) {
1045 // parse attr without no content
1046 #define TYPE_ATTR
1047 #define NOCONTENT_ATTR
1048 #define ATTR(X)                  \
1049     case TK_##X:                 \
1050         attrs.SetAttr(ATTR_##X); \
1051         break;
1052 #include "all_attributes.def"
1053 #undef ATTR
1054 #undef TYPE_ATTR
1055 #undef NOCONTENT_ATTR
1056                 // parse attr with no content
1057             case TK_align: {
1058                 if (!ParseAlignAttrs(attrs)) {
1059                     return false;
1060                 }
1061                 break;
1062             }
1063             case TK_pack: {
1064                 attrs.SetAttr(ATTR_pack);
1065                 if (!ParsePackAttrs()) {
1066                     return false;
1067                 }
1068                 attrs.SetPack(static_cast<uint32>(lexer.GetTheIntVal()));
1069                 break;
1070             }
1071             default:
1072                 return true;
1073         }  // switch
1074         lexer.NextToken();
1075     } while (true);
1076 }
1077 
ParseFieldAttrs(FieldAttrs & attrs)1078 bool MIRParser::ParseFieldAttrs(FieldAttrs &attrs)
1079 {
1080     do {
1081         switch (lexer.GetTokenKind()) {
1082 // parse attr without no content
1083 #define FIELD_ATTR
1084 #define NOCONTENT_ATTR
1085 #define ATTR(X)                     \
1086     case TK_##X:                    \
1087         attrs.SetAttr(FLDATTR_##X); \
1088         break;
1089 #include "all_attributes.def"
1090 #undef ATTR
1091 #undef NOCONTENT_ATTR
1092 #undef FIELD_ATTR
1093                 // parse attr with no content
1094             case TK_align: {
1095                 if (!CheckAlignTk()) {
1096                     return false;
1097                 }
1098                 attrs.SetAlign(lexer.GetTheIntVal());
1099                 break;
1100             }
1101             case TK_pack: {
1102                 attrs.SetAttr(FLDATTR_pack);
1103                 if (!ParsePackAttrs()) {
1104                     return false;
1105                 }
1106                 break;
1107             }
1108             default:
1109                 return true;
1110         }  // switch
1111         lexer.NextToken();
1112     } while (true);
1113 }
1114 
ParseFuncAttrs(FuncAttrs & attrs)1115 bool MIRParser::ParseFuncAttrs(FuncAttrs &attrs)
1116 {
1117     do {
1118         FuncAttrKind attrKind;
1119         TokenKind currentToken = lexer.GetTokenKind();
1120         switch (currentToken) {
1121 #define FUNC_ATTR
1122 #define ATTR(X)                  \
1123     case TK_##X: {               \
1124         attrKind = FUNCATTR_##X; \
1125         attrs.SetAttr(attrKind); \
1126         break;                   \
1127     }
1128 #include "all_attributes.def"
1129 #undef ATTR
1130 #undef FUNC_ATTR
1131             default:
1132                 return true;
1133         }  // switch
1134         if (currentToken != TK_alias && currentToken != TK_section && currentToken != TK_constructor_priority &&
1135             currentToken != TK_destructor_priority) {
1136             lexer.NextToken();
1137             continue;
1138         }
1139         if (lexer.NextToken() != TK_lparen) {
1140             return false;
1141         }
1142         lexer.NextToken();
1143         SetAttrContent(attrs, attrKind, lexer);
1144         if (lexer.NextToken() != TK_rparen) {
1145             return false;
1146         }
1147         lexer.NextToken();
1148     } while (true);
1149 }
1150 
SetAttrContent(FuncAttrs & attrs,FuncAttrKind x,const MIRLexer & mirLexer)1151 void MIRParser::SetAttrContent(FuncAttrs &attrs, FuncAttrKind x, const MIRLexer &mirLexer)
1152 {
1153     switch (x) {
1154         case FUNCATTR_alias: {
1155             attrs.SetAliasFuncName(mirLexer.GetName());
1156             break;
1157         }
1158         case FUNCATTR_section: {
1159             attrs.SetPrefixSectionName(mirLexer.GetName());
1160             break;
1161         }
1162         case FUNCATTR_constructor_priority: {
1163             attrs.SetConstructorPriority(static_cast<int32>(mirLexer.GetTheIntVal()));
1164             break;
1165         }
1166         case FUNCATTR_destructor_priority: {
1167             attrs.SetDestructorPriority(static_cast<int32>(mirLexer.GetTheIntVal()));
1168             break;
1169         }
1170         default:
1171             break;
1172     }
1173 }
1174 
ParsePrimType(TyIdx & tyIdx)1175 bool MIRParser::ParsePrimType(TyIdx &tyIdx)
1176 {
1177     PrimType primType = GetPrimitiveType(lexer.GetTokenKind());
1178     if (primType == kPtyInvalid) {
1179         tyIdx = TyIdx(0);
1180         Error("ParsePrimType failed, invalid token");
1181         return false;
1182     }
1183     lexer.NextToken();
1184     tyIdx = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(primType))->GetTypeIndex();
1185     return true;
1186 }
1187 
ParseTypeParam(TyIdx & definedTyIdx)1188 bool MIRParser::ParseTypeParam(TyIdx &definedTyIdx)
1189 {
1190     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1191     MIRTypeParam typeParm(strIdx);
1192     definedTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&typeParm);
1193     lexer.NextToken();
1194     return true;
1195 }
1196 
1197 // LB not handled in binary format
ParseDefinedTypename(TyIdx & definedTyIdx,MIRTypeKind kind)1198 bool MIRParser::ParseDefinedTypename(TyIdx &definedTyIdx, MIRTypeKind kind)
1199 {
1200     TokenKind tk = lexer.GetTokenKind();
1201     if (!IsVarName(tk)) {
1202         Error("expect global or local token parsing typedef type but get ");
1203         return false;
1204     }
1205     std::string nameStr = lexer.GetName();
1206     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(nameStr);
1207     // check if type already exist
1208     definedTyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
1209     TyIdx prevTypeIdx(0);
1210     if (definedTyIdx) {
1211         MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(definedTyIdx);
1212         if (type->IsStructType()) {
1213             auto *stype = static_cast<MIRStructType *>(type);
1214             // check whether need to update from incomplete class to interface
1215             if (stype->GetKind() == kind) {
1216                 lexer.NextToken();
1217                 return true;
1218             }
1219             prevTypeIdx = definedTyIdx;
1220         }
1221     }
1222     if (tk == TK_gname) {
1223         definedTyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
1224         if (definedTyIdx == 0u) {
1225             if (kind == kTypeInterface || kind == kTypeInterfaceIncomplete) {
1226                 MIRInterfaceType interfaceType(kTypeInterfaceIncomplete);
1227                 interfaceType.SetNameStrIdx(strIdx);
1228                 definedTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&interfaceType);
1229                 mod.AddClass(definedTyIdx);
1230                 mod.AddExternStructType(definedTyIdx);
1231                 mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, definedTyIdx);
1232             } else if (kind == kTypeClass || kind == kTypeClassIncomplete || IsClassInterfaceTypeName(nameStr)) {
1233                 MIRClassType classType(kTypeClassIncomplete);
1234                 classType.SetNameStrIdx(strIdx);
1235                 definedTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&classType);
1236                 mod.AddClass(definedTyIdx);
1237                 mod.AddExternStructType(definedTyIdx);
1238                 mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, definedTyIdx);
1239             } else {
1240                 MIRTypeByName nameType(strIdx);
1241                 definedTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&nameType);
1242                 mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, definedTyIdx);
1243             }
1244         }
1245     } else {
1246         definedTyIdx = mod.CurFunction()->GetTyIdxFromGStrIdx(strIdx);
1247         if (definedTyIdx == 0u) {
1248             MIRTypeByName nameType(strIdx);
1249             definedTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&nameType);
1250             mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, definedTyIdx);
1251         }
1252     }
1253     // replace prevTypeIdx with definedTyIdx
1254     if (prevTypeIdx != 0u && prevTypeIdx != definedTyIdx) {
1255         // replace all uses of prevTypeIdx by tyIdx in type_table_
1256         typeDefIdxMap[prevTypeIdx] = definedTyIdx;
1257         // remove prevTypeIdx from classlist
1258         mod.RemoveClass(prevTypeIdx);
1259     }
1260     lexer.NextToken();
1261     return true;
1262 }
1263 
ParsePointType(TyIdx & tyIdx)1264 bool MIRParser::ParsePointType(TyIdx &tyIdx)
1265 {
1266     TokenKind pdtk;
1267     if (lexer.GetTokenKind() == TK_func) {  // a function pointer
1268         pdtk = TK_func;
1269     } else if (lexer.GetTokenKind() != TK_asterisk) {
1270         Error("expect * for point type but get ");
1271         return false;
1272     } else {
1273         pdtk = lexer.NextToken();
1274     }
1275     TyIdx pointTypeIdx(0);
1276     if (IsPrimitiveType(pdtk)) {
1277         if (!ParsePrimType(pointTypeIdx)) {
1278             return false;
1279         }
1280     } else if (pdtk == TK_asterisk) {  // a point type
1281         if (!ParsePointType(pointTypeIdx)) {
1282             return false;
1283         }
1284     } else if (pdtk == TK_lbrack) {  // a array type
1285         if (!ParseArrayType(pointTypeIdx)) {
1286             return false;
1287         }
1288     } else if (pdtk == TK_struct || pdtk == TK_union || pdtk == TK_structincomplete) {
1289         if (!ParseStructType(pointTypeIdx)) {
1290             return false;
1291         }
1292     } else if (pdtk == TK_class || pdtk == TK_classincomplete) {
1293         if (!ParseClassType(pointTypeIdx)) {
1294             return false;
1295         }
1296     } else if (pdtk == TK_gname) {
1297         if (!ParseDefinedTypename(pointTypeIdx)) {
1298             return false;
1299         }
1300     } else if (pdtk == TK_langle) {
1301         if (!ParseDerivedType(pointTypeIdx)) {
1302             return false;
1303         }
1304     } else if (pdtk == TK_func) {
1305         lexer.NextToken();
1306         if (!ParseFuncType(pointTypeIdx)) {
1307             return false;
1308         }
1309     } else {
1310         Error("unexpect type ");
1311         return false;
1312     }
1313     DEBUG_ASSERT(pointTypeIdx != 0u, "something wrong with parsing element type ");
1314     PrimType pty = mod.IsJavaModule() ? PTY_ref : GetExactPtrPrimType();
1315     if (pdtk == maple::TK_constStr) {
1316         pty = GetExactPtrPrimType();
1317     }
1318     MIRPtrType pointType(pointTypeIdx, pty);  // use reference type here
1319     if (!ParseTypeAttrs(pointType.GetTypeAttrs())) {
1320         Error("bad type attribute in pointer type specification");
1321         return false;
1322     }
1323     tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&pointType);
1324     return true;
1325 }
1326 
1327 // used in parsing the parameter list (types only, without parameter names)
1328 // in function pointer specification and member function prototypes inside
1329 // structs and classes
ParseFuncType(TyIdx & tyIdx)1330 bool MIRParser::ParseFuncType(TyIdx &tyIdx)
1331 {
1332     // parse function attributes
1333     FuncAttrs fAttrs;
1334     if (lexer.GetTokenKind() != TK_lparen) {
1335         if (!ParseFuncAttrs(fAttrs)) {
1336             Error("bad function attribute specification in function type at ");
1337             return false;
1338         }
1339     }
1340 
1341     // parse parameters
1342     if (lexer.GetTokenKind() != TK_lparen) {
1343         Error("expect ( parse function type parameters but get ");
1344         return false;
1345     }
1346     std::vector<TyIdx> vecTyIdx;
1347     std::vector<TypeAttrs> vecAttrs;
1348     TokenKind tokenKind = lexer.NextToken();
1349     bool varargs = false;
1350     while (tokenKind != TK_rparen) {
1351         if (tokenKind == TK_dotdotdot) {
1352             if (vecTyIdx.size() == 0) {
1353                 Error("variable arguments can only appear after fixed parameters ");
1354                 return false;
1355             }
1356             varargs = true;
1357             tokenKind = lexer.NextToken();
1358             if (tokenKind != TK_rparen) {
1359                 Error("expect ) after ... but get");
1360                 return false;
1361             }
1362             break;
1363         }
1364         TyIdx tyIdxTmp(0);
1365         if (!ParseType(tyIdxTmp)) {
1366             Error("expect type parsing function parameters ");
1367             return false;
1368         }
1369         TypeAttrs typeAttrs;
1370         if (!ParseTypeAttrs(typeAttrs)) {
1371             Error("bad attribute in function parameter type at ");
1372             return false;
1373         }
1374         tokenKind = lexer.GetTokenKind();
1375         if (tokenKind == TK_coma) {
1376             tokenKind = lexer.NextToken();
1377             if (tokenKind == TK_rparen) {
1378                 Error("syntax error, meeting ,) expect another type after , or ) without , ");
1379                 return false;
1380             }
1381         }
1382         if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdxTmp)->HasTypeParam()) {
1383             typeAttrs.SetAttr(ATTR_generic);
1384         }
1385         vecTyIdx.push_back(tyIdxTmp);
1386         vecAttrs.push_back(typeAttrs);
1387     }
1388     // parse return type
1389     lexer.NextToken();
1390     TyIdx retTyIdx(0);
1391     if (!ParseType(retTyIdx)) {
1392         Error("expect return type for function type but get ");
1393         return false;
1394     }
1395     TypeAttrs retTypeAttrs;
1396     if (!ParseTypeAttrs(retTypeAttrs)) {
1397         Error("bad attribute in function ret type at ");
1398         return false;
1399     }
1400     MIRFuncType functype(retTyIdx, vecTyIdx, vecAttrs, retTypeAttrs);
1401     functype.funcAttrs = fAttrs;
1402     if (varargs) {
1403         functype.SetVarArgs();
1404     }
1405     tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&functype);
1406     return true;
1407 }
1408 
1409 // parse the generic type instantiation vector enclosed inside braces; syntax
1410 // is: { <type-param> = <real-type> [, <type-param> = <real-type>] }
1411 // where the contents enclosed in [ and ] can occur 0 or more times
ParseGenericInstantVector(MIRInstantVectorType & insVecType)1412 bool MIRParser::ParseGenericInstantVector(MIRInstantVectorType &insVecType)
1413 {
1414     TokenKind tokenKind;
1415     TyIdx typeParmIdx;
1416     do {
1417         tokenKind = lexer.NextToken();  // skip the lbrace or comma
1418         if (!ParseTypeParam(typeParmIdx)) {
1419             Error("type parameter incorrectly specified in generic type/function instantiation at ");
1420             return false;
1421         }
1422         tokenKind = lexer.GetTokenKind();
1423         if (tokenKind != TK_eqsign) {
1424             Error("missing = in generic type/function instantiation at ");
1425             return false;
1426         }
1427         tokenKind = lexer.NextToken();  // skip the =
1428         TyIdx realTyIdx;
1429         if (!ParseType(realTyIdx)) {
1430             Error("error parsing type in generic type/function instantiation at ");
1431             return false;
1432         }
1433         insVecType.AddInstant(TypePair(typeParmIdx, realTyIdx));
1434         tokenKind = lexer.GetTokenKind();
1435         if (tokenKind == TK_rbrace) {
1436             lexer.NextToken();  // skip the rbrace
1437             return true;
1438         }
1439     } while (tokenKind == TK_coma);
1440     Error("error parsing generic type/function instantiation at ");
1441     return false;
1442 }
1443 
ParseDerivedType(TyIdx & tyIdx,MIRTypeKind kind,const GStrIdx & strIdx)1444 bool MIRParser::ParseDerivedType(TyIdx &tyIdx, MIRTypeKind kind, const GStrIdx &strIdx)
1445 {
1446     if (lexer.GetTokenKind() != TK_langle) {
1447         Error("expect langle but get ");
1448         return false;
1449     }
1450     TokenKind ltk = lexer.NextToken();
1451     if (IsPrimitiveType(ltk)) {
1452         if (!ParsePrimType(tyIdx)) {
1453             Error("ParseDerivedType failed when parsing tyIdx at ");
1454             return false;
1455         }
1456     } else {
1457         switch (ltk) {
1458             case TK_asterisk:  // point type
1459             case TK_func:
1460                 if (!ParsePointType(tyIdx)) {
1461                     Error("point type wrong when parsing derived type at ");
1462                     return false;
1463                 }
1464                 break;
1465             case TK_lbrack:  // array type
1466                 if (!ParseArrayType(tyIdx)) {
1467                     Error("array type wrong when parsing derived type at ");
1468                     return false;
1469                 }
1470                 break;
1471             case TK_struct:            // struct type
1472             case TK_structincomplete:  // structincomplete type
1473             case TK_union:             // union type
1474                 if (!ParseStructType(tyIdx, strIdx)) {
1475                     Error("struct/union type wrong when parsing derived type at ");
1476                     return false;
1477                 }
1478                 break;
1479             case TK_class:  // class type
1480             case TK_classincomplete:
1481                 if (!ParseClassType(tyIdx, strIdx)) {
1482                     Error("class type wrong when parsing derived type at ");
1483                     return false;
1484                 }
1485                 break;
1486             case TK_interface:  // interface type
1487             case TK_interfaceincomplete:
1488                 if (!ParseInterfaceType(tyIdx, strIdx)) {
1489                     Error("interface type wrong when parsing derived type at ");
1490                     return false;
1491                 }
1492                 break;
1493             case TK_lname:  // local type
1494             case TK_gname:  // global type
1495                 if (!ParseDefinedTypename(tyIdx, kind)) {
1496                     Error("type name wrong when parsing derived type at ");
1497                     return false;
1498                 }
1499                 if (lexer.GetTokenKind() == TK_lbrace) {
1500                     MIRGenericInstantType genericinstty(tyIdx);
1501                     if (!ParseGenericInstantVector(genericinstty)) {
1502                         Error("error parsing generic type instantiation at ");
1503                         return false;
1504                     }
1505                     tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&genericinstty);
1506                 }
1507                 break;
1508             case TK_typeparam:
1509                 if (!ParseTypeParam(tyIdx)) {
1510                     Error("type parameter wrong when parsing derived type at ");
1511                     return false;
1512                 }
1513                 break;
1514             default:
1515                 Error("expect type token but get ");
1516                 return false;
1517         }
1518     }
1519     // parse >
1520     if (lexer.GetTokenKind() != TK_rangle) {
1521         Error("expect > parse derived type but get ");
1522         return false;
1523     }
1524     lexer.NextToken();
1525     return true;
1526 }
1527 
FixForwardReferencedTypeForOneAgg(MIRType * type)1528 void MIRParser::FixForwardReferencedTypeForOneAgg(MIRType *type)
1529 {
1530     if (type->GetKind() == kTypePointer) {
1531         auto *ptrType = static_cast<MIRPtrType *>(type);
1532         std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(ptrType->GetPointedTyIdx());
1533         if (it != typeDefIdxMap.end()) {
1534             ptrType->SetPointedTyIdx(it->second);
1535         }
1536     } else if (type->GetKind() == kTypeArray) {
1537         MIRArrayType *arrayType = static_cast<MIRArrayType *>(type);
1538         std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(arrayType->GetElemTyIdx());
1539         if (it != typeDefIdxMap.end()) {
1540             arrayType->SetElemTyIdx(it->second);
1541         }
1542     } else if (type->GetKind() == kTypeFArray || type->GetKind() == kTypeJArray) {
1543         MIRFarrayType *arrayType = static_cast<MIRFarrayType *>(type);
1544         std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(arrayType->GetElemTyIdx());
1545         if (it != typeDefIdxMap.end()) {
1546             arrayType->SetElemtTyIdx(it->second);
1547         }
1548     } else if (type->GetKind() == kTypeStruct || type->GetKind() == kTypeStructIncomplete ||
1549                type->GetKind() == kTypeUnion || type->GetKind() == kTypeClass ||
1550                type->GetKind() == kTypeClassIncomplete || type->GetKind() == kTypeInterface ||
1551                type->GetKind() == kTypeInterfaceIncomplete) {
1552         if (type->GetKind() == kTypeClass || type->GetKind() == kTypeClassIncomplete) {
1553             auto *classType = static_cast<MIRClassType *>(type);
1554             std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(classType->GetParentTyIdx());
1555             if (it != typeDefIdxMap.end()) {
1556                 classType->SetParentTyIdx(it->second);
1557             }
1558             for (size_t j = 0; j < classType->GetInterfaceImplemented().size(); ++j) {
1559                 std::map<TyIdx, TyIdx>::iterator it2 = typeDefIdxMap.find(classType->GetNthInterfaceImplemented(j));
1560                 if (it2 != typeDefIdxMap.end()) {
1561                     classType->SetNthInterfaceImplemented(j, it2->second);
1562                 }
1563             }
1564         } else if (type->GetKind() == kTypeInterface || type->GetKind() == kTypeInterfaceIncomplete) {
1565             auto *interfaceType = static_cast<MIRInterfaceType *>(type);
1566             for (uint32 j = 0; j < interfaceType->GetParentsTyIdx().size(); ++j) {
1567                 std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(interfaceType->GetParentsElementTyIdx(j));
1568                 if (it != typeDefIdxMap.end()) {
1569                     interfaceType->SetParentsElementTyIdx(j, it->second);
1570                 }
1571             }
1572         }
1573         auto *structType = static_cast<MIRStructType *>(type);
1574         for (uint32 j = 0; j < structType->GetFieldsSize(); ++j) {
1575             TyIdx fieldTyIdx = structType->GetElemTyIdx(j);
1576             std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(fieldTyIdx);
1577             if (it != typeDefIdxMap.end()) {
1578                 structType->SetElemtTyIdx(j, it->second);
1579             }
1580         }
1581         for (size_t j = 0; j < structType->GetStaticFields().size(); ++j) {
1582             TyIdx fieldTyIdx = structType->GetStaticElemtTyIdx(j);
1583             std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(fieldTyIdx);
1584             if (it != typeDefIdxMap.end()) {
1585                 structType->SetStaticElemtTyIdx(j, it->second);
1586             }
1587         }
1588         for (size_t j = 0; j < structType->GetMethods().size(); ++j) {
1589             TyIdx methodTyIdx = structType->GetMethodsElement(j).second.first;
1590             std::map<TyIdx, TyIdx>::iterator it = typeDefIdxMap.find(methodTyIdx);
1591             if (it != typeDefIdxMap.end()) {
1592                 structType->SetMethodTyIdx(j, it->second);
1593             }
1594         }
1595     }
1596 }
1597 
FixupForwardReferencedTypeByMap()1598 void MIRParser::FixupForwardReferencedTypeByMap()
1599 {
1600     for (size_t i = 1; i < GlobalTables::GetTypeTable().GetTypeTable().size(); ++i) {
1601         MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(i));
1602         FixForwardReferencedTypeForOneAgg(type);
1603     }
1604 }
1605 
ParseTypedef()1606 bool MIRParser::ParseTypedef()
1607 {
1608     bool isLocal = paramParseLocalType;
1609     if (lexer.GetTokenKind() != TK_type) {
1610         Error("expect type but get ");
1611         return false;
1612     }
1613     TokenKind tokenKind = lexer.NextToken();
1614     if (tokenKind != TK_gname && tokenKind != TK_lname) {
1615         Error("expect type name but get ");
1616         return false;
1617     }
1618     const std::string &name = lexer.GetName();
1619     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(name);
1620     TyIdx prevTyIdx;
1621     TyIdx tyIdx(0);
1622     if (tokenKind == TK_gname) {
1623         if (isLocal) {
1624             Error("A local type must use local type name ");
1625             return false;
1626         }
1627         prevTyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
1628         if (prevTyIdx != 0u) {
1629             MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx);
1630             if (!mod.IsCModule()) {
1631                 CHECK_FATAL(prevType->IsStructType(), "type error");
1632             }
1633             if ((prevType->GetKind() != kTypeByName) && !prevType->IsIncomplete()) {
1634                 // allow duplicated type def if kKeepFirst is set which is the default
1635                 if (options & kKeepFirst) {
1636                     lexer.NextToken();
1637                     Warning("redefined global type");
1638                     if (!ParseDerivedType(tyIdx, kTypeUnknown)) {
1639                         Error("error passing derived type at ");
1640                         return false;
1641                     }
1642                     return true;
1643                 } else {
1644                     Error("redefined global type");
1645                     return false;
1646                 }
1647             }
1648         }
1649     } else {
1650         if (!isLocal) {
1651             Error("A global type must use global type name ");
1652             return false;
1653         }
1654         prevTyIdx = mod.CurFunction()->GetTyIdxFromGStrIdx(strIdx);
1655         if (prevTyIdx != 0u) {
1656             MIRType *prevType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(prevTyIdx);
1657             if ((prevType->GetKind() != kTypeByName) && !prevType->IsIncomplete()) {
1658                 Error("redefined local type name ");
1659                 return false;
1660             }
1661         }
1662     }
1663     // at this point,if prev_tyidx is not zero, this type name has been
1664     // forward-referenced
1665     tokenKind = lexer.NextToken();
1666     tyIdx = kInitTyIdx;
1667     if (IsPrimitiveType(tokenKind)) {
1668         if (!ParsePrimType(tyIdx)) {
1669             Error("expect primitive type after typedef but get ");
1670             return false;
1671         }
1672     } else if (!ParseDerivedType(tyIdx, kTypeUnknown, strIdx)) {
1673         Error("error passing derived type at ");
1674         return false;
1675     }
1676     // for class/interface types, prev_tyidx could also be set during processing
1677     // so we check again right before SetGStrIdxToTyIdx
1678     if (isLocal) {
1679         prevTyIdx = mod.CurFunction()->GetTyIdxFromGStrIdx(strIdx);
1680         mod.CurFunction()->SetGStrIdxToTyIdx(strIdx, tyIdx);
1681         DEBUG_ASSERT(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check");
1682         if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->GetNameStrIdx() == 0u) {
1683             GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->SetNameIsLocal(true);
1684         }
1685     } else {
1686         prevTyIdx = mod.GetTypeNameTab()->GetTyIdxFromGStrIdx(strIdx);
1687         mod.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
1688         mod.PushbackTypeDefOrder(strIdx);
1689     }
1690 
1691     if (prevTyIdx != TyIdx(0) && prevTyIdx != tyIdx) {
1692         // replace all uses of prev_tyidx by tyIdx in typeTable
1693         typeDefIdxMap[prevTyIdx] = tyIdx;  // record the real tydix
1694         // remove prev_tyidx from classlist
1695         mod.RemoveClass(prevTyIdx);
1696     }
1697 
1698     // Merge class or interface type at the cross-module level
1699     DEBUG_ASSERT(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check");
1700     MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
1701     if (!isLocal && (type->GetKind() == kTypeClass || type->GetKind() == kTypeClassIncomplete ||
1702                      type->GetKind() == kTypeInterface || type->GetKind() == kTypeInterfaceIncomplete)) {
1703         prevTyIdx = GlobalTables::GetTypeNameTable().GetTyIdxFromGStrIdx(strIdx);
1704         if (prevTyIdx == 0u) {
1705             GlobalTables::GetTypeNameTable().SetGStrIdxToTyIdx(strIdx, tyIdx);
1706         }
1707         // setup eh root type
1708         MIRType *ehType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
1709         if (mod.GetThrowableTyIdx() == 0u &&
1710             (ehType->GetKind() == kTypeClass || ehType->GetKind() == kTypeClassIncomplete)) {
1711             GStrIdx ehTypeNameIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(
1712                 namemangler::GetInternalNameLiteral(namemangler::kJavaLangObjectStr));
1713             if (ehTypeNameIdx == ehType->GetNameStrIdx()) {
1714                 mod.SetThrowableTyIdx(tyIdx);
1715             }
1716         }
1717     }
1718     return true;
1719 }
1720 
ParseJavaClassInterface(MIRSymbol & symbol,bool isClass)1721 bool MIRParser::ParseJavaClassInterface(MIRSymbol &symbol, bool isClass)
1722 {
1723     TokenKind tk = lexer.NextToken();
1724     if (tk != TK_gname) {
1725         Error("expect global name for javaclass but get ");
1726         return false;
1727     }
1728     symbol.SetNameStrIdx(lexer.GetName());
1729     if (!GlobalTables::GetGsymTable().AddToStringSymbolMap(symbol)) {
1730         Error("duplicate symbol name used in javainterface at ");
1731         return false;
1732     }
1733     lexer.NextToken();
1734     TyIdx tyidx(0);
1735     if (!ParseType(tyidx)) {
1736         Error("ParseType failed trying parsing the type");
1737         return false;
1738     }
1739     MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyidx);
1740     if (isClass && type->GetKind() != kTypeClass && type->GetKind() != kTypeClassIncomplete) {
1741         Error("type in javaclass declaration must be of class type at ");
1742         return false;
1743     } else if (!isClass && type->GetKind() != kTypeInterface && type->GetKind() != kTypeInterfaceIncomplete) {
1744         Error("type in javainterface declaration must be of interface type at ");
1745         return false;
1746     }
1747     symbol.SetTyIdx(tyidx);
1748     if (!ParseTypeAttrs(symbol.GetAttrs())) {
1749         Error("bad type attribute in variable declaration at ");
1750         return false;
1751     }
1752     if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyidx)->HasTypeParam()) {
1753         symbol.SetAttr(ATTR_generic);
1754     }
1755     return true;
1756 }
1757 
ParseStorageClass(MIRSymbol & symbol) const1758 bool MIRParser::ParseStorageClass(MIRSymbol &symbol) const
1759 {
1760     TokenKind tk = lexer.GetTokenKind();
1761     switch (tk) {
1762         case TK_fstatic:
1763             symbol.SetStorageClass(kScFstatic);
1764             return true;
1765         case TK_pstatic:
1766             symbol.SetStorageClass(kScPstatic);
1767             return true;
1768         case TK_extern:
1769             symbol.SetStorageClass(kScExtern);
1770             return true;
1771         default:
1772             break;
1773     }
1774     return false;
1775 }
1776 
ParseDeclareReg(MIRSymbol & symbol,const MIRFunction & func)1777 bool MIRParser::ParseDeclareReg(MIRSymbol &symbol, const MIRFunction &func)
1778 {
1779     TokenKind tk = lexer.GetTokenKind();
1780     // i.e, reg %1 u1
1781     if (tk != TK_reg) {  // reg
1782         Error("expect reg bug get ");
1783         return false;
1784     }
1785     TokenKind regNumTK = lexer.NextToken();
1786     if (regNumTK != TK_preg) {
1787         Error("expect preg but get");
1788         return false;
1789     }
1790     uint32 thePRegNO = static_cast<uint32>(lexer.GetTheIntVal());
1791     lexer.NextToken();
1792     // parse ty
1793     TyIdx tyIdx(0);
1794     if (!ParseType(tyIdx)) {
1795         Error("ParseDeclarePreg failed while parsing the type");
1796         return false;
1797     }
1798     DEBUG_ASSERT(tyIdx > 0u, "parse declare preg failed");
1799     if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->GetKind() == kTypeByName) {
1800         Error("type in var declaration cannot be forward-referenced at ");
1801         return false;
1802     }
1803     symbol.SetTyIdx(tyIdx);
1804     MIRType *mirType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
1805     PregIdx pRegIdx = func.GetPregTab()->EnterPregNo(thePRegNO, mirType->GetPrimType(), mirType);
1806     MIRPregTable *pRegTab = func.GetPregTab();
1807     MIRPreg *preg = pRegTab->PregFromPregIdx(pRegIdx);
1808     preg->SetPrimType(mirType->GetPrimType());
1809     symbol.SetPreg(preg);
1810     if (!ParseVarTypeAttrs(symbol)) {
1811         Error("bad type attribute in variable declaration at ");
1812         return false;
1813     }
1814     if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->HasTypeParam()) {
1815         symbol.SetAttr(ATTR_generic);
1816         mod.CurFunction()->SetAttr(FUNCATTR_generic);
1817     }
1818     return true;
1819 }
1820 
ParseDeclareVarInitValue(MIRSymbol & symbol)1821 bool MIRParser::ParseDeclareVarInitValue(MIRSymbol &symbol)
1822 {
1823     TokenKind tk = lexer.GetTokenKind();
1824     // take a look if there are any initialized values
1825     if (tk == TK_eqsign) {
1826         // parse initialized values
1827         MIRConst *mirConst = nullptr;
1828         lexer.NextToken();
1829         if (!ParseInitValue(mirConst, symbol.GetTyIdx(), mod.IsCModule())) {
1830             Error("wrong initialization value at ");
1831             return false;
1832         }
1833         symbol.SetKonst(mirConst);
1834     }
1835     return true;
1836 }
1837 
ParseDeclareVar(MIRSymbol & symbol)1838 bool MIRParser::ParseDeclareVar(MIRSymbol &symbol)
1839 {
1840     TokenKind tk = lexer.GetTokenKind();
1841     // i.e, var %i i32
1842     if (tk != TK_var && tk != TK_tempvar) {  // var
1843         Error("expect var but get ");
1844         return false;
1845     }
1846     bool isLocal = symbol.IsLocal();
1847     // %i
1848     TokenKind nameTk = lexer.NextToken();
1849     if (isLocal) {
1850         if (nameTk == TK_static) {
1851             symbol.SetStorageClass(kScPstatic);
1852             nameTk = lexer.NextToken();
1853         }
1854         if (nameTk != TK_lname) {
1855             Error("expect local name but get ");
1856             return false;
1857         }
1858     } else {
1859         if (nameTk != TK_gname) {
1860             Error("expect global name but get ");
1861             return false;
1862         }
1863     }
1864     std::string symbolStrName = lexer.GetName();
1865     GStrIdx symbolStrID = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(symbolStrName);
1866     symbol.SetNameStrIdx(symbolStrID);
1867     tk = lexer.NextToken();
1868     if (ParseStorageClass(symbol)) {
1869         lexer.NextToken();
1870     }
1871     // i32
1872     TyIdx tyIdx(0);
1873     if (!ParseType(tyIdx)) {
1874         Error("ParseDeclareVar failed when parsing the type");
1875         return false;
1876     }
1877     DEBUG_ASSERT(tyIdx > 0u, "parse declare var failed ");
1878     if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->GetKind() == kTypeByName) {
1879         Error("type in var declaration cannot be forward-referenced at ");
1880         return false;
1881     }
1882     symbol.SetTyIdx(tyIdx);
1883     /* parse section/register attribute from inline assembly */
1884     if (lexer.GetTokenKind() == TK_section) {
1885         lexer.NextToken();
1886         if (lexer.GetTokenKind() != TK_lparen) {
1887             Error("expect ( for section attribute but get ");
1888             return false;
1889         }
1890         lexer.NextToken();
1891         if (lexer.GetTokenKind() != TK_string) {
1892             Error("expect string literal for section attribute but get ");
1893             return false;
1894         }
1895         UStrIdx literalStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1896         symbol.sectionAttr = literalStrIdx;
1897         lexer.NextToken();
1898         if (lexer.GetTokenKind() != TK_rparen) {
1899             Error("expect ) for section attribute but get ");
1900             return false;
1901         }
1902         lexer.NextToken();
1903     } else if (lexer.GetTokenKind() == TK_asmattr) { /* Specifying Registers for Local Variables */
1904         lexer.NextToken();
1905         if (lexer.GetTokenKind() != TK_lparen) {
1906             Error("expect ( for register inline-asm attribute but get ");
1907             return false;
1908         }
1909         lexer.NextToken();
1910         if (lexer.GetTokenKind() != TK_string) {
1911             Error("expect string literal for section attribute but get ");
1912             return false;
1913         }
1914         UStrIdx literalStrIdx = GlobalTables::GetUStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1915         symbol.asmAttr = literalStrIdx;
1916 
1917         lexer.NextToken();
1918         if (lexer.GetTokenKind() != TK_rparen) {
1919             Error("expect ) for section attribute but get ");
1920             return false;
1921         }
1922         lexer.NextToken();
1923     }
1924     if (!ParseVarTypeAttrs(symbol)) {
1925         Error("bad type attribute in variable declaration at ");
1926         return false;
1927     }
1928     if (symbol.GetStorageClass() == kScExtern && symbol.IsStatic()) {
1929         const std::string &staticFieldName = symbol.GetName();
1930         constexpr int kPosOffset = 3;
1931         size_t pos = staticFieldName.find(namemangler::kClassNameSplitterStr) + kPosOffset;
1932         if (pos != 0 && pos != std::string::npos) {
1933             std::string className = staticFieldName.substr(0, pos);
1934             MIRSymbol *classSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(
1935                 GlobalTables::GetStrTable().GetStrIdxFromName(className));
1936             if (classSt != nullptr) {
1937                 symbol.SetStorageClass(kScGlobal);
1938             }
1939         }
1940     }
1941     if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx)->HasTypeParam()) {
1942         symbol.SetAttr(ATTR_generic);
1943         if (isLocal) {
1944             mod.CurFunction()->SetAttr(FUNCATTR_generic);
1945         }
1946     }
1947     return true;
1948 }
1949 
ParseDeclareFormal(FormalDef & formalDef)1950 bool MIRParser::ParseDeclareFormal(FormalDef &formalDef)
1951 {
1952     TokenKind tk = lexer.GetTokenKind();
1953     if (tk != TK_var && tk != TK_reg) {
1954         return false;
1955     }
1956     TokenKind nameTk = lexer.NextToken();
1957     if (tk == TK_var) {
1958         if (nameTk != TK_lname) {
1959             Error("expect local name but get ");
1960             return false;
1961         }
1962         formalDef.formalStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
1963     } else {  // tk == TK_reg
1964         if (nameTk != TK_preg) {
1965             Error("expect preg but get ");
1966             return false;
1967         }
1968         formalDef.formalStrIdx =
1969             GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(std::to_string(lexer.GetTheIntVal()));
1970     }
1971     (void)lexer.NextToken();
1972     if (!ParseType(formalDef.formalTyIdx)) {
1973         Error("ParseDeclareFormal failed when parsing the type");
1974         return false;
1975     }
1976     if (GlobalTables::GetTypeTable().GetTypeFromTyIdx(formalDef.formalTyIdx)->GetKind() == kTypeByName) {
1977         Error("type in var declaration cannot be forward-referenced at ");
1978         return false;
1979     }
1980     if (!ParseTypeAttrs(formalDef.formalAttrs)) {
1981         Error("ParseDeclareFormal failed when parsing type attributes");
1982         return false;
1983     }
1984     return true;
1985 }
1986 
ParsePrototype(MIRFunction & func,MIRSymbol & funcSymbol,TyIdx & funcTyIdx)1987 bool MIRParser::ParsePrototype(MIRFunction &func, MIRSymbol &funcSymbol, TyIdx &funcTyIdx)
1988 {
1989     if (lexer.GetTokenKind() == TK_lbrace) {
1990         if (mod.GetFlavor() < kMmpl) {
1991             Error("funcion prototype missing for non-MMPL flavor of Maple IR");
1992             return false;
1993         }
1994         // mmpl flavor has no prototype declaration, return normally
1995         return true;
1996     }
1997     std::vector<TyIdx> vecTy;      // for storing the parameter types
1998     std::vector<TypeAttrs> vecAt;  // for storing the parameter type attributes
1999     // this part for parsing the argument list and return type
2000     if (lexer.GetTokenKind() != TK_lparen) {
2001         Error("expect ( for func but get ");
2002         return false;
2003     }
2004     // parse parameters
2005     bool varArgs = false;
2006     TokenKind pmTk = lexer.NextToken();
2007     while (pmTk != TK_rparen) {
2008         if (pmTk == TK_dotdotdot) {
2009             varArgs = true;
2010             func.SetVarArgs();
2011             pmTk = lexer.NextToken();
2012             if (pmTk != TK_rparen) {
2013                 Error("expect ) after ... but get");
2014                 return false;
2015             }
2016             break;
2017         } else {
2018             FormalDef formalDef;
2019             if (!ParseDeclareFormal(formalDef)) {
2020                 Error("ParsePrototype expects formal parameter declaration");
2021                 return false;
2022             }
2023             func.GetFormalDefVec().push_back(formalDef);
2024             vecTy.push_back(formalDef.formalTyIdx);
2025             vecAt.push_back(formalDef.formalAttrs);
2026             pmTk = lexer.GetTokenKind();
2027             if (pmTk == TK_coma) {
2028                 pmTk = lexer.NextToken();
2029                 if (pmTk == TK_rparen) {
2030                     Error("\',\' cannot be followed by");
2031                     return false;
2032                 }
2033             }
2034         }
2035     }
2036 
2037     // parse return type
2038     lexer.NextToken();
2039     TyIdx tyIdx(0);
2040     if (!ParseType(tyIdx)) {
2041         return false;
2042     }
2043     MIRType *retType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
2044     func.SetReturnStruct(*retType);
2045     MIRType *funcType = GlobalTables::GetTypeTable().GetOrCreateFunctionType(tyIdx, vecTy, vecAt, varArgs);
2046     funcTyIdx = funcType->GetTypeIndex();
2047     funcSymbol.SetTyIdx(funcTyIdx);
2048     func.SetMIRFuncType(static_cast<MIRFuncType *>(funcType));
2049     return true;
2050 }
2051 
2052 // if prototype declaration, only create the symbol and type;
2053 // if a redeclaration, re-process the symbol and type declaration;
2054 // if function declaration, link MIRFunction to ->mod in addition
ParseFunction(uint32 fileIdx)2055 bool MIRParser::ParseFunction(uint32 fileIdx)
2056 {
2057     TokenKind tokenKind = lexer.GetTokenKind();
2058     if (tokenKind != TK_func) {
2059         Error("expect func but get ");
2060         return false;
2061     }
2062     lexer.NextToken();
2063     if (lexer.GetTokenKind() != TK_gname && lexer.GetTokenKind() != TK_fname) {
2064         Error("expect function name for func but get ");
2065         return false;
2066     }
2067     const std::string &funcName = lexer.GetName();
2068     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(funcName);
2069     MIRSymbol *funcSymbol = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(strIdx);
2070     MIRFunction *func = nullptr;
2071     lexer.NextToken();
2072     FuncAttrs funcAttrs;
2073     if (!ParseFuncAttrs(funcAttrs)) {
2074         Error("bad function attribute in function declaration at ");
2075         return false;
2076     }
2077     if (funcSymbol != nullptr && funcSymbol->GetSKind() == kStFunc && funcSymbol->IsNeedForwDecl() == true &&
2078         !funcSymbol->GetFunction()->GetBody()) {
2079         SetSrcPos(funcSymbol->GetSrcPosition(), lexer.GetLineNum());
2080     }
2081     if (funcSymbol != nullptr) {
2082         // there has been an earlier forward declaration, so check consistency
2083         if (funcSymbol->GetStorageClass() != kScText || funcSymbol->GetSKind() != kStFunc) {
2084             Error("redeclaration of name as func in ");
2085             return false;
2086         }
2087         if (funcSymbol->GetFunction()->GetBody()) {
2088             // Function definition has been processed. Here it may be
2089             // another declaration due to multi-mpl merge. If this
2090             // is indeed another definition, we will throw error.
2091             MIRSymbol *tmpSymbol = mod.GetMemPool()->New<MIRSymbol>();
2092             tmpSymbol->SetStorageClass(kScText);
2093             tmpSymbol->SetAppearsInCode(true);
2094             tmpSymbol->SetSKind(kStFunc);
2095             MIRFunction *tmpFunc = mod.GetMemPool()->New<MIRFunction>(&mod, tmpSymbol->GetStIdx());
2096             tmpSymbol->SetFunction(tmpFunc);
2097             TyIdx tmpTyIdx;
2098             if (!ParsePrototype(*tmpFunc, *tmpSymbol, tmpTyIdx)) {
2099                 return false;
2100             }
2101             if (lexer.GetTokenKind() == TK_lbrace) {
2102                 Error("function body defined second time in ");
2103                 return false;
2104             }
2105             return true;
2106         }
2107         // Skip attribute checking
2108         func = funcSymbol->GetFunction();
2109         func->ClearFormals();
2110 
2111         // update with current attr
2112         if (funcAttrs.GetAttrFlag()) {
2113             if (func->IsIpaSeen()) {
2114                 funcAttrs.SetAttr(FUNCATTR_ipaseen);
2115             }
2116             if (func->IsNoDefEffect()) {
2117                 funcAttrs.SetAttr(FUNCATTR_nodefeffect);
2118             }
2119             if (func->IsNoRetGlobal()) {
2120                 funcAttrs.SetAttr(FUNCATTR_noretglobal);
2121             }
2122             if (func->IsPure()) {
2123                 funcAttrs.SetAttr(FUNCATTR_pure);
2124             }
2125             if (func->IsNoThrowException()) {
2126                 funcAttrs.SetAttr(FUNCATTR_nothrow_exception);
2127             }
2128             if (func->IsNoDefArgEffect()) {
2129                 funcAttrs.SetAttr(FUNCATTR_nodefargeffect);
2130             }
2131             if (func->IsNoRetArg()) {
2132                 funcAttrs.SetAttr(FUNCATTR_noretarg);
2133             }
2134             if (func->IsNoPrivateDefEffect()) {
2135                 funcAttrs.SetAttr(FUNCATTR_noprivate_defeffect);
2136             }
2137             func->SetFuncAttrs(funcAttrs);
2138         }
2139     } else {
2140         maple::MIRBuilder mirBuilder(&mod);
2141         funcSymbol = mirBuilder.CreateSymbol(TyIdx(0), strIdx, kStFunc, kScText, nullptr, kScopeGlobal);
2142         SetSrcPos(funcSymbol->GetSrcPosition(), lexer.GetLineNum());
2143         func = mod.GetMemPool()->New<MIRFunction>(&mod, funcSymbol->GetStIdx());
2144         func->SetPuidx(GlobalTables::GetFunctionTable().GetFuncTable().size());
2145         GlobalTables::GetFunctionTable().GetFuncTable().push_back(func);
2146         funcSymbol->SetFunction(func);
2147         func->SetFuncAttrs(funcAttrs);
2148     }
2149     func->SetFileIndex(fileIdx);
2150     curFunc = func;
2151     if (mod.IsJavaModule()) {
2152         func->SetBaseClassFuncNames(funcSymbol->GetNameStrIdx());
2153     }
2154     TyIdx funcTyidx;
2155     if (!ParsePrototype(*func, *funcSymbol, funcTyidx)) {
2156         return false;
2157     }
2158     if (lexer.GetTokenKind() == TK_lbrace) {  // #2 parse Function body
2159         funcSymbol->SetAppearsInCode(true);
2160         // when parsing func in mplt_inline file, set it as tmpunused.
2161         if (options & kParseInlineFuncBody) {
2162             funcSymbol->SetIsTmpUnused(true);
2163         }
2164         definedLabels.clear();
2165         mod.SetCurFunction(func);
2166         mod.AddFunction(func);
2167         // set maple line number for function
2168         func->GetSrcPosition().SetMplLineNum(lexer.GetLineNum());
2169         // initialize source line number to be 0
2170         // to avoid carrying over info from previous function
2171         firstLineNum = 0;
2172         lastLineNum = 0;
2173         lastColumnNum = 0;
2174         func->NewBody();
2175         BlockNode *block = nullptr;
2176         safeRegionFlag.push(curFunc->IsSafe());
2177         auto IsParseSucc = ParseStmtBlock(block);
2178         safeRegionFlag.pop();
2179         if (!IsParseSucc) {
2180             Error("ParseFunction failed when parsing stmt block");
2181             ResetCurrentFunction();
2182             return false;
2183         }
2184         func->SetBody(block);
2185 
2186         // set source file number for function
2187         func->GetSrcPosition().SetLineNum(firstLineNum);
2188         func->GetSrcPosition().SetFileNum(lastFileNum);
2189         func->GetSrcPosition().SetColumn(lastColumnNum);
2190         // check if any local type name is undefined
2191         for (auto it : func->GetGStrIdxToTyIdxMap()) {
2192             MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(it.second);
2193             if (type->GetKind() == kTypeByName) {
2194                 std::string strStream;
2195                 const std::string &name = GlobalTables::GetStrTable().GetStringFromStrIdx(it.first);
2196                 strStream += "type %";
2197                 strStream += name;
2198                 strStream += " used but not defined\n";
2199                 message += strStream;
2200                 ResetCurrentFunction();
2201                 return false;
2202             }
2203         }
2204     }
2205     ResetCurrentFunction();
2206     return true;
2207 }
2208 
ParseInitValue(MIRConstPtr & theConst,TyIdx tyIdx,bool allowEmpty)2209 bool MIRParser::ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmpty)
2210 {
2211     TokenKind tokenKind = lexer.GetTokenKind();
2212     MIRType &type = *GlobalTables::GetTypeTable().GetTypeFromTyIdx(tyIdx);
2213     if (tokenKind != TK_lbrack) {  // scalar
2214         MIRConst *mirConst = nullptr;
2215         if (IsConstValue(tokenKind)) {
2216             if (!ParseScalarValue(mirConst, type)) {
2217                 Error("ParseInitValue expect scalar value");
2218                 return false;
2219             }
2220             lexer.NextToken();
2221         } else if (IsConstAddrExpr(tokenKind)) {
2222             if (!ParseConstAddrLeafExpr(mirConst)) {
2223                 Error("ParseInitValue expect const addr expr");
2224                 return false;
2225             }
2226         } else {
2227             Error("initialiation value expected but get ");
2228             return false;
2229         }
2230         theConst = mirConst;
2231     } else {  // aggregates
2232         FixForwardReferencedTypeForOneAgg(&type);
2233         if (type.GetKind() == kTypeArray) {
2234             auto &arrayType = static_cast<MIRArrayType &>(type);
2235             MIRType *elemType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(arrayType.GetElemTyIdx());
2236             MIRAggConst *newConst = mod.GetMemPool()->New<MIRAggConst>(mod, type);
2237             theConst = newConst;
2238             tokenKind = lexer.NextToken();
2239             if (tokenKind == TK_rbrack) {
2240                 if (allowEmpty) {
2241                     lexer.NextToken();
2242                     return true;
2243                 } else {
2244                     Error("illegal empty initialization for array at ");
2245                     return false;
2246                 }
2247             }
2248             do {
2249                 // parse single const or another dimension array
2250                 MIRConst *subConst = nullptr;
2251                 if (IsConstValue(tokenKind)) {
2252                     if (!ParseScalarValue(subConst, *elemType)) {
2253                         Error("ParseInitValue expect scalar value");
2254                         return false;
2255                     }
2256                     lexer.NextToken();
2257                 } else if (IsConstAddrExpr(tokenKind)) {
2258                     if (!ParseConstAddrLeafExpr(subConst)) {
2259                         Error("ParseInitValue expect const addr expr");
2260                         return false;
2261                     }
2262                 } else if (tokenKind == TK_lbrack) {
2263                     if (elemType->GetKind() == kTypeStruct && arrayType.GetDim() == 1) {
2264                         if (!ParseInitValue(subConst, arrayType.GetElemTyIdx(), allowEmpty)) {
2265                             Error("initializaton value wrong when parsing structure array ");
2266                             return false;
2267                         }
2268                     } else {
2269                         TyIdx elemTyIdx;
2270                         if (arrayType.GetDim() == 1) {
2271                             elemTyIdx = elemType->GetTypeIndex();
2272                         } else {
2273                             std::vector<uint32> sizeSubArray;
2274                             for (uint16 i = 1; i < arrayType.GetDim(); ++i) {
2275                                 sizeSubArray.push_back(arrayType.GetSizeArrayItem(i));
2276                             }
2277                             MIRArrayType subArrayType(elemType->GetTypeIndex(), sizeSubArray);
2278                             elemTyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&subArrayType);
2279                         }
2280                         if (!ParseInitValue(subConst, elemTyIdx, allowEmpty)) {
2281                             Error("initializaton value wrong when parsing sub array ");
2282                             return false;
2283                         }
2284                     }
2285                 } else {
2286                     Error("expect const value or group of const values but get ");
2287                     return false;
2288                 }
2289                 newConst->AddItem(subConst, 0);
2290                 // parse comma or rbrack
2291                 tokenKind = lexer.GetTokenKind();
2292                 if (tokenKind == TK_coma) {
2293                     tokenKind = lexer.NextToken();
2294                     if (tokenKind == TK_rbrack) {
2295                         Error("not expect, followed by ] ");
2296                         return false;
2297                     }
2298                 }
2299             } while (tokenKind != TK_rbrack);
2300             lexer.NextToken();
2301         } else if (type.GetKind() == kTypeStruct || type.GetKind() == kTypeUnion) {
2302             MIRAggConst *newConst = mod.GetMemPool()->New<MIRAggConst>(mod, type);
2303             uint32 theFieldIdx;
2304             TyIdx fieldTyIdx;
2305             theConst = newConst;
2306             tokenKind = lexer.NextToken();
2307             if (tokenKind == TK_rbrack) {
2308                 if (allowEmpty) {
2309                     lexer.NextToken();
2310                     return true;
2311                 } else {
2312                     Error("illegal empty initialization for struct at ");
2313                     return false;
2314                 }
2315             }
2316             do {
2317                 if (lexer.GetTokenKind() != TK_intconst) {
2318                     Error("expect field ID in struct initialization but get ");
2319                     return false;
2320                 }
2321                 theFieldIdx = static_cast<uint32>(lexer.GetTheIntVal());
2322                 if (lexer.NextToken() != TK_eqsign) {
2323                     Error("expect = after field ID in struct initialization but get ");
2324                     return false;
2325                 }
2326                 FieldPair thepair = static_cast<MIRStructType &>(type).GetFields()[theFieldIdx - 1];
2327                 fieldTyIdx = thepair.second.first;
2328                 if (fieldTyIdx == 0u) {
2329                     Error("field ID out of range at struct initialization at ");
2330                     return false;
2331                 }
2332                 tokenKind = lexer.NextToken();
2333                 MIRConst *subConst = nullptr;
2334                 if (IsConstValue(tokenKind)) {
2335                     if (!ParseScalarValue(subConst, *GlobalTables::GetTypeTable().GetTypeFromTyIdx(fieldTyIdx))) {
2336                         Error("ParseInitValue expect scalar value");
2337                         return false;
2338                     }
2339                     lexer.NextToken();
2340                 } else if (IsConstAddrExpr(tokenKind)) {
2341                     if (!ParseConstAddrLeafExpr(subConst)) {
2342                         Error("ParseInitValue expect const addr expr");
2343                         return false;
2344                     }
2345                 } else if (tokenKind == TK_lbrack) {
2346                     if (!ParseInitValue(subConst, fieldTyIdx, allowEmpty)) {
2347                         Error("parse init value wrong when parse sub struct ");
2348                         return false;
2349                     }
2350                 } else {
2351                     Error("expect const value or group of const values but get ");
2352                     return false;
2353                 }
2354                 DEBUG_ASSERT(subConst != nullptr, "subConst is null in MIRParser::ParseInitValue");
2355                 newConst->AddItem(subConst, theFieldIdx);
2356                 tokenKind = lexer.GetTokenKind();
2357                 // parse comma or rbrack
2358                 if (tokenKind == TK_coma) {
2359                     tokenKind = lexer.NextToken();
2360                     if (tokenKind == TK_rbrack) {
2361                         Error("not expect \',\' followed by ] ");
2362                         return false;
2363                     }
2364                 }
2365             } while (tokenKind != TK_rbrack);
2366             lexer.NextToken();
2367         } else {
2368             Error("non-struct should not have aggregate initialization in ");
2369             return false;
2370         }
2371     }
2372     return true;
2373 }
2374 
ParseFuncInfo()2375 bool MIRParser::ParseFuncInfo()
2376 {
2377     if (lexer.GetTokenKind() != TK_lbrace) {
2378         Error("expect left brace after funcinfo but get ");
2379         return false;
2380     }
2381     MIRFunction *func = mod.CurFunction();
2382     TokenKind tokenKind = lexer.NextToken();
2383     while (tokenKind == TK_label) {
2384         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2385         tokenKind = lexer.NextToken();
2386         if (tokenKind == TK_intconst) {
2387             uint32 fieldVal = lexer.GetTheIntVal();
2388             func->PushbackMIRInfo(MIRInfoPair(strIdx, fieldVal));
2389             func->PushbackIsString(false);
2390         } else if (tokenKind == TK_string) {
2391             GStrIdx literalStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2392             func->PushbackMIRInfo(MIRInfoPair(strIdx, literalStrIdx));
2393             func->PushbackIsString(true);
2394         } else {
2395             Error("illegal value after funcinfo field name at ");
2396             return false;
2397         }
2398         tokenKind = lexer.NextToken();
2399         if (tokenKind == TK_rbrace) {
2400             lexer.NextToken();
2401             return true;
2402         }
2403         if (tokenKind == TK_coma) {
2404             tokenKind = lexer.NextToken();
2405         } else {
2406             Error("expect comma after funcinfo field value but get ");
2407             return false;
2408         }
2409     }
2410     Error("expect field name in funcinfo but get ");
2411     return false;
2412 }
2413 
ParsePosition(SrcPosition & pos)2414 bool MIRParser::ParsePosition(SrcPosition &pos)
2415 {
2416     TokenKind nameTk = lexer.NextToken();
2417     if (nameTk != TK_lparen) {
2418         Error("expect ( in SrcPos but get ");
2419         return false;
2420     }
2421     nameTk = lexer.NextToken();
2422     if (nameTk != TK_intconst) {
2423         Error("expect int in SrcPos but get ");
2424         return false;
2425     }
2426     uint32 i = static_cast<uint32>(lexer.GetTheIntVal());
2427     pos.SetFileNum(static_cast<uint16>(i));
2428     nameTk = lexer.NextToken();
2429     if (nameTk != TK_coma) {
2430         Error("expect comma in SrcPos but get ");
2431         return false;
2432     }
2433 
2434     nameTk = lexer.NextToken();
2435     if (nameTk != TK_intconst) {
2436         Error("expect int in SrcPos but get ");
2437         return false;
2438     }
2439     i = static_cast<uint32>(lexer.GetTheIntVal());
2440     pos.SetLineNum(i);
2441     nameTk = lexer.NextToken();
2442     if (nameTk != TK_coma) {
2443         Error("expect comma in SrcPos but get ");
2444         return false;
2445     }
2446 
2447     nameTk = lexer.NextToken();
2448     if (nameTk != TK_intconst) {
2449         Error("expect int in SrcPos but get ");
2450         return false;
2451     }
2452     i = static_cast<uint32>(lexer.GetTheIntVal());
2453     pos.SetColumn(static_cast<uint16>(i));
2454     nameTk = lexer.NextToken();
2455     if (nameTk != TK_rparen) {
2456         Error("expect ) in SrcPos but get ");
2457         return false;
2458     }
2459 
2460     return true;
2461 }
2462 
ParseOneScope(MIRScope & scope)2463 bool MIRParser::ParseOneScope(MIRScope &scope)
2464 {
2465     TokenKind nameTk = lexer.GetTokenKind();
2466     if (nameTk != TK_SCOPE) {
2467         Error("expect SCOPE but get ");
2468         return false;
2469     }
2470     nameTk = lexer.NextToken();
2471     if (nameTk != TK_langle) {
2472         Error("expect < in SCOPE but get ");
2473         return false;
2474     }
2475     SrcPosition low;
2476     if (!ParsePosition(low)) {
2477         Error("parsePosition low failed when parsing SCOPE ");
2478         return false;
2479     }
2480     nameTk = lexer.NextToken();
2481     if (nameTk != TK_coma) {
2482         Error("expect comma in SCOPE but get ");
2483         return false;
2484     }
2485     SrcPosition high;
2486     if (!ParsePosition(high)) {
2487         Error("parsePosition high failed when parsing SCOPE ");
2488         return false;
2489     }
2490     nameTk = lexer.NextToken();
2491     if (nameTk != TK_rangle) {
2492         Error("expect > in SCOPE but get ");
2493         return false;
2494     }
2495     nameTk = lexer.NextToken();
2496     if (nameTk != TK_lbrace) {
2497         Error("expect { in SCOPE but get ");
2498         return false;
2499     }
2500     scope.SetRange(low, high);
2501     nameTk = lexer.NextToken();
2502     while (1) {
2503         bool status = false;
2504         switch (lexer.GetTokenKind()) {
2505             case TK_ALIAS: {
2506                 GStrIdx strIdx;
2507                 MIRAliasVars aliasVar;
2508                 status = ParseOneAlias(strIdx, aliasVar);
2509                 if (status) {
2510                     scope.SetAliasVarMap(strIdx, aliasVar);
2511                 }
2512                 break;
2513             }
2514             case TK_SCOPE: {
2515                 // initial level 1
2516                 MIRScope *scp = mod.GetMemPool()->New<MIRScope>(&mod, 1);
2517                 status = ParseOneScope(*scp);
2518                 if (status) {
2519                     scope.AddScope(scp);
2520                 } else {
2521                     delete scp;
2522                 }
2523                 break;
2524             }
2525             default:
2526                 break;
2527         }
2528         if (!status) {
2529             break;
2530         }
2531     }
2532     nameTk = lexer.GetTokenKind();
2533     if (nameTk != TK_rbrace) {
2534         Error("expect } in SCOPE but get ");
2535         return false;
2536     }
2537     lexer.NextToken();
2538     return true;
2539 }
2540 
ParseScope(StmtNodePtr & stmt)2541 bool MIRParser::ParseScope(StmtNodePtr &stmt)
2542 {
2543     // initial level 1
2544     MIRScope *scp = mod.GetMemPool()->New<MIRScope>(&mod, 1);
2545     bool status = ParseOneScope(*scp);
2546     if (status) {
2547         mod.CurFunction()->GetScope()->AddScope(scp);
2548     } else {
2549         delete scp;
2550     }
2551     return true;
2552 }
2553 
ParseOneAlias(GStrIdx & strIdx,MIRAliasVars & aliasVar)2554 bool MIRParser::ParseOneAlias(GStrIdx &strIdx, MIRAliasVars &aliasVar)
2555 {
2556     TokenKind nameTk = lexer.GetTokenKind();
2557     if (nameTk != TK_ALIAS) {
2558         Error("expect ALIAS but get ");
2559         return false;
2560     }
2561     nameTk = lexer.NextToken();
2562     if (nameTk != TK_lname) {
2563         Error("expect local in ALIAS but get ");
2564         return false;
2565     }
2566     strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2567     nameTk = lexer.NextToken();
2568     bool isLocal;
2569     if (nameTk == TK_lname) {
2570         isLocal = true;
2571     } else if (nameTk == TK_gname) {
2572         isLocal = false;
2573     } else {
2574         Error("expect name in ALIAS but get ");
2575         return false;
2576     }
2577     GStrIdx mplStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2578     lexer.NextToken();
2579     TyIdx tyIdx(0);
2580     if (!ParseType(tyIdx)) {
2581         Error("parseType failed when parsing ALIAS ");
2582         return false;
2583     }
2584     GStrIdx signStrIdx(0);
2585     if (lexer.GetTokenKind() == TK_string) {
2586         signStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
2587         lexer.NextToken();
2588     }
2589     aliasVar.mplStrIdx = mplStrIdx;
2590     aliasVar.tyIdx = tyIdx;
2591     aliasVar.isLocal = isLocal;
2592     aliasVar.sigStrIdx = signStrIdx;
2593     return true;
2594 }
2595 
ParseAlias(StmtNodePtr & stmt)2596 bool MIRParser::ParseAlias(StmtNodePtr &stmt)
2597 {
2598     GStrIdx strIdx;
2599     MIRAliasVars aliasVar;
2600 
2601     ParseOneAlias(strIdx, aliasVar);
2602 
2603     mod.CurFunction()->SetAliasVarMap(strIdx, aliasVar);
2604     return true;
2605 }
2606 
ParseWordsInfo(uint32 size)2607 uint8 *MIRParser::ParseWordsInfo(uint32 size)
2608 {
2609     lexer.NextToken();
2610     if (lexer.GetTokenKind() != TK_eqsign) {
2611         Error("expect = after it but get ");
2612         return nullptr;
2613     }
2614     lexer.NextToken();
2615     if (lexer.GetTokenKind() != TK_lbrack) {
2616         Error("expect [ for it but get ");
2617         return nullptr;
2618     }
2619     uint8 *origp = static_cast<uint8 *>(mod.GetMemPool()->Malloc(BlockSize2BitVectorSize(size)));
2620     // initialize it based on the input
2621     for (uint32 *p = reinterpret_cast<uint32 *>(origp); lexer.NextToken() == TK_intconst; ++p) {
2622         *p = static_cast<uint32>(lexer.GetTheIntVal());
2623     }
2624     if (lexer.GetTokenKind() != TK_rbrack) {
2625         Error("expect ] at end of globalwordstypetagged but get ");
2626         return nullptr;
2627     }
2628     lexer.NextToken();
2629     return origp;
2630 }
2631 
GenJStringType(MIRModule & module)2632 static void GenJStringType(MIRModule &module)
2633 {
2634     MIRStructType metaClassType(kTypeStructIncomplete);
2635     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("dummy");
2636     metaClassType.GetFields().push_back(FieldPair(strIdx, TyIdxFieldAttrPair(TyIdx(PTY_ref), FieldAttrs())));
2637     strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("__class_meta__");
2638     metaClassType.SetNameStrIdx(strIdx);
2639     TyIdx tyIdx = GlobalTables::GetTypeTable().GetOrCreateMIRType(&metaClassType);
2640     // Global
2641     module.GetTypeNameTab()->SetGStrIdxToTyIdx(strIdx, tyIdx);
2642     DEBUG_ASSERT(GlobalTables::GetTypeTable().GetTypeTable().empty() == false, "container check");
2643 }
2644 
ParseMIR(std::ifstream & mplFile)2645 bool MIRParser::ParseMIR(std::ifstream &mplFile)
2646 {
2647     std::ifstream *origFile = lexer.GetFile();
2648     // parse mplfile
2649     lexer.SetFile(mplFile);
2650     // try to read the first line
2651     if (lexer.ReadALine() < 0) {
2652         lexer.lineNum = 0;
2653     } else {
2654         lexer.lineNum = 1;
2655     }
2656     // for optimized functions file
2657     bool status = ParseMIR(0, kParseOptFunc);
2658     // restore airFile
2659     lexer.SetFile(*origFile);
2660     return status;
2661 }
2662 
ParseInlineFuncBody(std::ifstream & mplFile)2663 bool MIRParser::ParseInlineFuncBody(std::ifstream &mplFile)
2664 {
2665     std::ifstream *origFile = lexer.GetFile();
2666     lexer.SetFile(mplFile);
2667     // try to read the first line
2668     if (lexer.ReadALine() < 0) {
2669         lexer.lineNum = 0;
2670     } else {
2671         lexer.lineNum = 1;
2672     }
2673     // parse mplFile
2674     bool status = ParseMIR(0, kParseOptFunc | kParseInlineFuncBody);
2675     // restore airFile
2676     lexer.SetFile(*origFile);
2677     return status;
2678 }
2679 
ParseSrcLang(MIRSrcLang & srcLang)2680 bool MIRParser::ParseSrcLang(MIRSrcLang &srcLang)
2681 {
2682     PrepareParsingMIR();
2683     bool atEof = false;
2684     lexer.NextToken();
2685     while (!atEof) {
2686         paramTokenKind = lexer.GetTokenKind();
2687         if (paramTokenKind == TK_eof) {
2688             atEof = true;
2689         } else if (paramTokenKind == TK_srclang) {
2690             lexer.NextToken();
2691             if (lexer.GetTokenKind() != TK_intconst) {
2692                 Error("expect integer after srclang but get ");
2693                 return false;
2694             }
2695             srcLang = static_cast<MIRSrcLang>(lexer.GetTheIntVal());
2696             return true;
2697         } else {
2698             lexer.NextToken();
2699         }
2700     }
2701     return false;
2702 }
2703 
ParseMIR(uint32 fileIdx,uint32 option,bool isIPA,bool isComb)2704 bool MIRParser::ParseMIR(uint32 fileIdx, uint32 option, bool isIPA, bool isComb)
2705 {
2706     if ((option & kParseOptFunc) == 0) {
2707         PrepareParsingMIR();
2708     }
2709     if (option != 0) {
2710         this->options |= option;
2711     }
2712     // profiling setup
2713     mod.SetWithProfileInfo(((this->options & kWithProfileInfo) != 0));
2714     bool atEof = false;
2715     paramFileIdx = fileIdx;
2716     paramIsIPA = isIPA;
2717     paramIsComb = isComb;
2718     lexer.NextToken();
2719     while (!atEof) {
2720         paramTokenKind = lexer.GetTokenKind();
2721         std::map<TokenKind, FuncPtrParseMIRForElem>::iterator itFuncPtr = funcPtrMapForParseMIR.find(paramTokenKind);
2722         if (itFuncPtr == funcPtrMapForParseMIR.end()) {
2723             if (paramTokenKind == TK_eof) {
2724                 atEof = true;
2725             } else {
2726                 Error("expect func or var but get ");
2727                 return false;
2728             }
2729         } else {
2730             if (!(this->*(itFuncPtr->second))()) {
2731                 return false;
2732             }
2733         }
2734     }
2735     // fix the typedef type
2736     FixupForwardReferencedTypeByMap();
2737     // check if any global type name is undefined
2738     for (auto it = mod.GetTypeNameTab()->GetGStrIdxToTyIdxMap().begin();
2739          it != mod.GetTypeNameTab()->GetGStrIdxToTyIdxMap().end(); ++it) {
2740         MIRType *type = GlobalTables::GetTypeTable().GetTypeFromTyIdx(it->second);
2741         CHECK_FATAL(type != nullptr, "type is null");
2742         if (type->GetKind() == kTypeByName) {
2743             std::string strStream;
2744             const std::string &name = GlobalTables::GetStrTable().GetStringFromStrIdx(it->first);
2745             strStream += "type $";
2746             strStream += name;
2747             strStream += " used but not defined\n";
2748             message += strStream;
2749             return false;
2750         }
2751     }
2752     if (!isIPA && isComb) {
2753         for (auto it = paramImportFileList.begin(); it != paramImportFileList.end(); ++it) {
2754             BinaryMplt binMplt(mod);
2755             std::string importFilename = *it;
2756             if (!binMplt.Import(importFilename, false, true)) {  // not a binary mplt
2757                 std::ifstream mpltFile(importFilename);
2758                 if (!mpltFile.is_open()) {
2759                     FATAL(kLncFatal, "cannot open MPLT file: %s\n", importFilename.c_str());
2760                 }
2761                 bool failedParse = !ParseMPLT(mpltFile, importFilename);
2762                 mpltFile.close();
2763                 if (failedParse) {
2764                     return false;
2765                 }
2766             }
2767         }
2768     }
2769     return true;
2770 }
2771 
InitFuncPtrMapForParseMIR()2772 std::map<TokenKind, MIRParser::FuncPtrParseMIRForElem> MIRParser::InitFuncPtrMapForParseMIR()
2773 {
2774     std::map<TokenKind, MIRParser::FuncPtrParseMIRForElem> funcPtrMap;
2775     funcPtrMap[TK_func] = &MIRParser::ParseMIRForFunc;
2776     funcPtrMap[TK_tempvar] = &MIRParser::ParseMIRForVar;
2777     funcPtrMap[TK_var] = &MIRParser::ParseMIRForVar;
2778     funcPtrMap[TK_javaclass] = &MIRParser::ParseMIRForClass;
2779     funcPtrMap[TK_javainterface] = &MIRParser::ParseMIRForInterface;
2780     funcPtrMap[TK_type] = &MIRParser::ParseTypedef;
2781     funcPtrMap[TK_flavor] = &MIRParser::ParseMIRForFlavor;
2782     funcPtrMap[TK_srclang] = &MIRParser::ParseMIRForSrcLang;
2783     funcPtrMap[TK_globalmemsize] = &MIRParser::ParseMIRForGlobalMemSize;
2784     funcPtrMap[TK_globalmemmap] = &MIRParser::ParseMIRForGlobalMemMap;
2785     funcPtrMap[TK_globalwordstypetagged] = &MIRParser::ParseMIRForGlobalWordsTypeTagged;
2786     funcPtrMap[TK_globalwordsrefcounted] = &MIRParser::ParseMIRForGlobalWordsRefCounted;
2787     funcPtrMap[TK_id] = &MIRParser::ParseMIRForID;
2788     funcPtrMap[TK_numfuncs] = &MIRParser::ParseMIRForNumFuncs;
2789     funcPtrMap[TK_entryfunc] = &MIRParser::ParseMIRForEntryFunc;
2790     funcPtrMap[TK_fileinfo] = &MIRParser::ParseMIRForFileInfo;
2791     funcPtrMap[TK_filedata] = &MIRParser::ParseMIRForFileData;
2792     funcPtrMap[TK_srcfileinfo] = &MIRParser::ParseMIRForSrcFileInfo;
2793     funcPtrMap[TK_import] = &MIRParser::ParseMIRForImport;
2794     funcPtrMap[TK_importpath] = &MIRParser::ParseMIRForImportPath;
2795     funcPtrMap[TK_asmdecl] = &MIRParser::ParseMIRForAsmdecl;
2796     funcPtrMap[TK_LOC] = &MIRParser::ParseLoc;
2797     return funcPtrMap;
2798 }
2799 
ParseMIRForFunc()2800 bool MIRParser::ParseMIRForFunc()
2801 {
2802     curFunc = nullptr;
2803     if (!ParseFunction(paramFileIdx)) {
2804         return false;
2805     }
2806     // when parsing function in mplt_inline file, set fromMpltInline as true.
2807     if ((this->options & kParseInlineFuncBody) && curFunc) {
2808         curFunc->SetFromMpltInline(true);
2809         return true;
2810     }
2811     if ((this->options & kParseOptFunc) && curFunc) {
2812         curFunc->SetAttr(FUNCATTR_optimized);
2813         mod.AddOptFuncs(curFunc);
2814     }
2815     return true;
2816 }
2817 
TypeCompatible(TyIdx typeIdx1,TyIdx typeIdx2)2818 bool MIRParser::TypeCompatible(TyIdx typeIdx1, TyIdx typeIdx2)
2819 {
2820     if (typeIdx1 == typeIdx2) {
2821         return true;
2822     }
2823     MIRType *type1 = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx1);
2824     MIRType *type2 = GlobalTables::GetTypeTable().GetTypeFromTyIdx(typeIdx2);
2825     if (type1 == nullptr || type2 == nullptr) {
2826         // this means we saw the use of this symbol before def.
2827         return false;
2828     }
2829     while (type1->IsMIRPtrType() || type1->IsMIRArrayType()) {
2830         if (type1->IsMIRPtrType()) {
2831             CHECK_FATAL(type2->IsMIRPtrType(), "Error");
2832             type1 = static_cast<MIRPtrType *>(type1)->GetPointedType();
2833             type2 = static_cast<MIRPtrType *>(type2)->GetPointedType();
2834         } else {
2835             CHECK_FATAL(type2->IsMIRArrayType(), "Error");
2836             auto *arrayType1 = static_cast<MIRArrayType *>(type1);
2837             auto *arrayType2 = static_cast<MIRArrayType *>(type2);
2838             if (arrayType1->IsIncompleteArray() || arrayType2->IsIncompleteArray()) {
2839                 return true;
2840             }
2841             type1 = static_cast<MIRArrayType *>(type1)->GetElemType();
2842             type2 = static_cast<MIRArrayType *>(type2)->GetElemType();
2843         }
2844     }
2845     if (type1 == type2) {
2846         return true;
2847     }
2848     if (type1->IsIncomplete() || type2->IsIncomplete()) {
2849         return true;
2850     }
2851     return false;
2852 }
2853 
IsTypeIncomplete(MIRType * type)2854 bool MIRParser::IsTypeIncomplete(MIRType *type)
2855 {
2856     if (type->IsIncomplete()) {
2857         return true;
2858     }
2859     while (type->IsMIRPtrType() || type->IsMIRArrayType()) {
2860         if (type->IsMIRPtrType()) {
2861             type = static_cast<MIRPtrType *>(type)->GetPointedType();
2862         } else {
2863             auto *arrayType = static_cast<MIRArrayType *>(type);
2864             if (arrayType->IsIncompleteArray()) {
2865                 return true;
2866             }
2867             type = static_cast<MIRArrayType *>(type)->GetElemType();
2868         }
2869     }
2870     return type->IsIncomplete();
2871 }
2872 
ParseMIRForVar()2873 bool MIRParser::ParseMIRForVar()
2874 {
2875     MIRSymbol st(0, kScopeGlobal);
2876     st.SetStorageClass(kScGlobal);
2877     st.SetSKind(kStVar);
2878     if (paramTokenKind == TK_tempvar) {
2879         st.SetIsTmp(true);
2880     }
2881     if (!ParseDeclareVar(st)) {
2882         return false;
2883     }
2884     MIRSymbol *prevSt = GlobalTables::GetGsymTable().GetSymbolFromStrIdx(st.GetNameStrIdx());
2885     if (prevSt != nullptr) {
2886         bool ret = TypeCompatible(prevSt->GetTyIdx(), st.GetTyIdx());
2887 #ifdef DEBUG
2888         if (!ret) {
2889             LogInfo::MapleLogger() << "\n=====prevSymbol===== \n";
2890             prevSt->Dump(false, 0);
2891             LogInfo::MapleLogger() << "\n=====curSymbol===== \n";
2892             st.Dump(false, 0);
2893             LogInfo::MapleLogger() << "\n=====   end   ===== \n";
2894         }
2895 #endif
2896         if (ret &&
2897             (prevSt->GetStorageClass() == st.GetStorageClass() || prevSt->GetStorageClass() == kScExtern ||
2898              st.GetStorageClass() == kScExtern) &&
2899             prevSt->GetSKind() == st.GetSKind() && (prevSt->GetKonst() == nullptr || st.GetKonst() == nullptr)) {
2900             // previously declared: accumulate new information to the symbol
2901             prevSt->GetAttrs().SetAttrFlag(prevSt->GetAttrs().GetAttrFlag() | st.GetAttrs().GetAttrFlag());
2902             if (prevSt->GetKonst() == nullptr) {
2903                 prevSt->SetKonst(st.GetKonst());
2904             }
2905             if (prevSt->GetStorageClass() == kScExtern) {
2906                 prevSt->SetStorageClass(st.GetStorageClass());
2907             }
2908             if (prevSt->sectionAttr == UStrIdx(0)) {
2909                 prevSt->sectionAttr = st.sectionAttr;
2910             }
2911             if (IsTypeIncomplete(prevSt->GetType())) {
2912                 prevSt->SetTyIdx(st.GetTyIdx());
2913             }
2914         } else if (prevSt->GetSKind() == maple::kStVar && prevSt->GetStorageClass() == maple::kScInvalid) {
2915             prevSt->SetStorageClass(kScGlobal);
2916             prevSt->SetAttrs(st.GetAttrs());
2917             prevSt->SetNameStrIdx(st.GetNameStrIdx());
2918             prevSt->sectionAttr = st.sectionAttr;
2919             prevSt->SetValue(st.GetValue());
2920             prevSt->SetTyIdx(st.GetTyIdx());
2921             SetSrcPos(prevSt->GetSrcPosition(), lexer.GetLineNum());
2922         }
2923         if (!ParseDeclareVarInitValue(*prevSt)) {
2924             return false;
2925         }
2926     } else {  // seeing the first time
2927         maple::MIRBuilder mirBuilder(&mod);
2928         MIRSymbol *newst = mirBuilder.CreateSymbol(st.GetTyIdx(), st.GetNameStrIdx(), st.GetSKind(),
2929                                                    st.GetStorageClass(), nullptr, kScopeGlobal);
2930         // when parsing var in mplt_inline file, set it as tmpunused.
2931         if (this->options & kParseInlineFuncBody) {
2932             newst->SetIsTmpUnused(true);
2933         }
2934         newst->SetAttrs(st.GetAttrs());
2935         newst->SetNameStrIdx(st.GetNameStrIdx());
2936         newst->sectionAttr = st.sectionAttr;
2937         newst->SetValue(st.GetValue());
2938         SetSrcPos(newst->GetSrcPosition(), lexer.GetLineNum());
2939         if (!ParseDeclareVarInitValue(*newst)) {
2940             return false;
2941         }
2942     }
2943     if (mod.CurFunction() && mod.GetFunctionList().empty()) {
2944         mod.CurFunction()->ReleaseCodeMemory();
2945     }
2946     return true;
2947 }
2948 
ParseMIRForClass()2949 bool MIRParser::ParseMIRForClass()
2950 {
2951     MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
2952     DEBUG_ASSERT(st != nullptr, "st nullptr check");
2953     st->SetStorageClass(kScInvalid);
2954     st->SetSKind(kStJavaClass);
2955     return ParseJavaClassInterface(*st, true);
2956 }
2957 
ParseMIRForInterface()2958 bool MIRParser::ParseMIRForInterface()
2959 {
2960     MIRSymbol *st = GlobalTables::GetGsymTable().CreateSymbol(kScopeGlobal);
2961     DEBUG_ASSERT(st != nullptr, "st nullptr check");
2962     st->SetStorageClass(kScInvalid);
2963     st->SetSKind(kStJavaInterface);
2964     return ParseJavaClassInterface(*st, false);
2965 }
2966 
ParseMIRForFlavor()2967 bool MIRParser::ParseMIRForFlavor()
2968 {
2969     lexer.NextToken();
2970     if (lexer.GetTokenKind() != TK_intconst) {
2971         Error("expect integer after flavor but get ");
2972         return false;
2973     }
2974     mod.SetFlavor(static_cast<MIRFlavor>(lexer.GetTheIntVal()));
2975     lexer.NextToken();
2976     return true;
2977 }
2978 
ParseMIRForSrcLang()2979 bool MIRParser::ParseMIRForSrcLang()
2980 {
2981     lexer.NextToken();
2982     if (lexer.GetTokenKind() != TK_intconst) {
2983         Error("expect integer after srclang but get ");
2984         return false;
2985     }
2986     mod.SetSrcLang(static_cast<MIRSrcLang>(lexer.GetTheIntVal()));
2987     lexer.NextToken();
2988     return true;
2989 }
2990 
ParseMIRForGlobalMemSize()2991 bool MIRParser::ParseMIRForGlobalMemSize()
2992 {
2993     lexer.NextToken();
2994     if (lexer.GetTokenKind() != TK_intconst) {
2995         Error("expect integer after globalmemsize but get ");
2996         return false;
2997     }
2998     mod.SetGlobalMemSize(lexer.GetTheIntVal());
2999     lexer.NextToken();
3000     return true;
3001 }
3002 
ParseMIRForGlobalMemMap()3003 bool MIRParser::ParseMIRForGlobalMemMap()
3004 {
3005     lexer.NextToken();
3006     if (lexer.GetTokenKind() != TK_eqsign) {
3007         Error("expect = after globalmemmap but get ");
3008         return false;
3009     }
3010     lexer.NextToken();
3011     if (lexer.GetTokenKind() != TK_lbrack) {
3012         Error("expect [ for globalmemmap but get ");
3013         return false;
3014     }
3015     mod.SetGlobalBlockMap(static_cast<uint8 *>(mod.GetMemPool()->Malloc(mod.GetGlobalMemSize())));
3016     // initialize globalblkmap based on the input
3017     for (uint32 *p = reinterpret_cast<uint32 *>(mod.GetGlobalBlockMap()); lexer.NextToken() == TK_intconst; ++p) {
3018         *p = static_cast<uint32>(lexer.GetTheIntVal());
3019     }
3020     if (lexer.GetTokenKind() != TK_rbrack) {
3021         Error("expect ] at end of globalmemmap but get ");
3022         return false;
3023     }
3024     lexer.NextToken();
3025     return true;
3026 }
3027 
ParseMIRForGlobalWordsTypeTagged()3028 bool MIRParser::ParseMIRForGlobalWordsTypeTagged()
3029 {
3030     uint8 *typeAddr = ParseWordsInfo(mod.GetGlobalMemSize());
3031     if (typeAddr == nullptr) {
3032         Error("parser error for globalwordstypetagged");
3033         return false;
3034     }
3035     mod.SetGlobalWordsTypeTagged(typeAddr);
3036     return true;
3037 }
3038 
ParseMIRForGlobalWordsRefCounted()3039 bool MIRParser::ParseMIRForGlobalWordsRefCounted()
3040 {
3041     uint8 *refAddr = ParseWordsInfo(mod.GetGlobalMemSize());
3042     if (refAddr == nullptr) {
3043         Error("parser error for globalwordsrefcounted");
3044         return false;
3045     }
3046     mod.SetGlobalWordsRefCounted(refAddr);
3047     return true;
3048 }
3049 
ParseMIRForID()3050 bool MIRParser::ParseMIRForID()
3051 {
3052     lexer.NextToken();
3053     if (lexer.GetTokenKind() != TK_intconst) {
3054         Error("expect integer after id but get ");
3055         return false;
3056     }
3057     mod.SetID(static_cast<uint16>(lexer.GetTheIntVal()));
3058     lexer.NextToken();
3059     return true;
3060 }
3061 
ParseMIRForNumFuncs()3062 bool MIRParser::ParseMIRForNumFuncs()
3063 {
3064     lexer.NextToken();
3065     if (lexer.GetTokenKind() != TK_intconst) {
3066         Error("expect integer after numfuncs but get ");
3067         return false;
3068     }
3069     mod.SetNumFuncs(lexer.GetTheIntVal());
3070     lexer.NextToken();
3071     return true;
3072 }
3073 
ParseMIRForEntryFunc()3074 bool MIRParser::ParseMIRForEntryFunc()
3075 {
3076     lexer.NextToken();
3077     if (lexer.GetTokenKind() != TK_fname) {
3078         Error("expect function name for func but get ");
3079         return false;
3080     }
3081     mod.SetEntryFuncName(lexer.GetName());
3082     lexer.NextToken();
3083     return true;
3084 }
3085 
ParseMIRForFileInfo()3086 bool MIRParser::ParseMIRForFileInfo()
3087 {
3088     lexer.NextToken();
3089     if (lexer.GetTokenKind() != TK_lbrace) {
3090         Error("expect left brace after fileInfo but get ");
3091         return false;
3092     }
3093     TokenKind tk = lexer.NextToken();
3094     while (tk == TK_label) {
3095         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
3096         tk = lexer.NextToken();
3097         if (tk == TK_intconst) {
3098             uint32 fieldVal = lexer.GetTheIntVal();
3099             mod.PushFileInfoPair(MIRInfoPair(strIdx, fieldVal));
3100             mod.PushFileInfoIsString(false);
3101         } else if (tk == TK_string) {
3102             GStrIdx litStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
3103             mod.PushFileInfoPair(MIRInfoPair(strIdx, litStrIdx));
3104             mod.PushFileInfoIsString(true);
3105         } else {
3106             Error("illegal value after fileInfo field name at ");
3107             return false;
3108         }
3109         tk = lexer.NextToken();
3110         if (tk == TK_rbrace) {
3111             lexer.NextToken();
3112             return true;
3113         }
3114         if (tk == TK_coma) {
3115             tk = lexer.NextToken();
3116         } else {
3117             Error("expect comma after fileInfo field value but get ");
3118             return false;
3119         }
3120     }
3121     Error("expect field name in fileInfo but get ");
3122     return false;
3123 }
3124 
ParseMIRForFileData()3125 bool MIRParser::ParseMIRForFileData()
3126 {
3127     lexer.NextToken();
3128     if (lexer.GetTokenKind() != TK_lbrace) {
3129         Error("expect left brace after fileData but get ");
3130         return false;
3131     }
3132     TokenKind tk = lexer.NextToken();
3133     while (tk == TK_label) {
3134         GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
3135         tk = lexer.NextToken();
3136         std::vector<uint8> data;
3137         while (tk == TK_intconst) {
3138             uint32 fieldVal = lexer.GetTheIntVal();
3139             data.push_back(fieldVal);
3140             tk = lexer.NextToken();
3141         }
3142         mod.PushbackFileData(MIRDataPair(strIdx, data));
3143         if (tk == TK_coma) {
3144             tk = lexer.NextToken();
3145         } else if (tk == TK_rbrace) {
3146             lexer.NextToken();
3147             return true;
3148         } else {
3149             Error("expect comma after fileData field value but get ");
3150             return false;
3151         }
3152     }
3153     Error("expect field name in fileData but get ");
3154     return false;
3155 }
3156 
ParseMIRForSrcFileInfo()3157 bool MIRParser::ParseMIRForSrcFileInfo()
3158 {
3159     lexer.NextToken();
3160     if (lexer.GetTokenKind() != TK_lbrace) {
3161         Error("expect left brace after fileInfo but get ");
3162         return false;
3163     }
3164     TokenKind tk = lexer.NextToken();
3165     while (tk == TK_intconst) {
3166         uint32 fieldVal = lexer.GetTheIntVal();
3167         tk = lexer.NextToken();
3168         if (tk == TK_string) {
3169             GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
3170             mod.PushbackFileInfo(MIRInfoPair(strIdx, fieldVal));
3171         } else {
3172             Error("illegal value after srcfileinfo field name at ");
3173             return false;
3174         }
3175         tk = lexer.NextToken();
3176         if (tk == TK_rbrace) {
3177             lexer.NextToken();
3178             return true;
3179         }
3180         if (tk == TK_coma) {
3181             tk = lexer.NextToken();
3182         } else {
3183             Error("expect comma after srcfileinfo field value but get ");
3184             return false;
3185         }
3186     }
3187     Error("expect field name in srcfileinfo but get ");
3188     return false;
3189 }
3190 
ParseMIRForImport()3191 bool MIRParser::ParseMIRForImport()
3192 {
3193     lexer.NextToken();
3194     if (lexer.GetTokenKind() != TK_string) {
3195         Error("expect file name string after import but get ");
3196         return false;
3197     }
3198     std::string importFileName = lexer.GetName();
3199     paramImportFileList.push_back(importFileName);
3200     // check illegal file name for the .mplt file
3201     std::string::size_type lastDot = importFileName.find_last_of(".");
3202     if (lastDot == std::string::npos || lastDot != importFileName.length() - strlen(".mplt")) {
3203         FATAL(kLncFatal, "MPLT file has no or wrong suffix: %s\n", importFileName.c_str());
3204     }
3205     if (importFileName.compare(lastDot, strlen(".mplt"), ".mplt") != 0) {
3206         FATAL(kLncFatal, "MPLT file has wrong suffix: %s\n", importFileName.c_str());
3207     }
3208     if (paramIsIPA && firstImport) {
3209         BinaryMplt *binMplt = new BinaryMplt(mod);
3210         mod.SetBinMplt(binMplt);
3211         if (!(*binMplt).Import(importFileName, paramIsIPA && !firstImport, paramIsComb)) {  // not a binary mplt
3212             std::ifstream mpltFile(importFileName);
3213             if (!mpltFile.is_open()) {
3214                 FATAL(kLncFatal, "cannot open MPLT file: %s\n", importFileName.c_str());
3215             }
3216             bool failedParse = !ParseMPLT(mpltFile, importFileName);
3217             mpltFile.close();
3218             if (failedParse) {  // parse the mplt file
3219                 return false;
3220             }
3221         }
3222         firstImport = false;
3223     } else {
3224         BinaryMplt binMplt(mod);
3225         if (!binMplt.Import(importFileName, paramIsIPA, false)) {  // not a binary mplt
3226             std::ifstream mpltFile(importFileName);
3227             if (!mpltFile.is_open()) {
3228                 FATAL(kLncFatal, "cannot open MPLT file: %s\n", importFileName.c_str());
3229             }
3230             bool failedParse = !ParseMPLT(mpltFile, importFileName);
3231             mpltFile.close();
3232             if (failedParse) {  // parse the mplt file
3233                 return false;
3234             }
3235         }
3236     }
3237     if (GlobalTables::GetStrTable().GetStrIdxFromName("__class_meta__") == 0u) {
3238         GenJStringType(mod);
3239     }
3240     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(importFileName);
3241     auto it = mod.GetImportFiles().begin();
3242     (void)mod.GetImportFiles().insert(it, strIdx);
3243     // record the imported file for later reading summary info, if exists
3244     mod.PushbackImportedMplt(importFileName);
3245     lexer.NextToken();
3246     return true;
3247 }
3248 
ParseMIRForImportPath()3249 bool MIRParser::ParseMIRForImportPath()
3250 {
3251     lexer.NextToken();
3252     if (lexer.GetTokenKind() != TK_string) {
3253         Error("expect path string after importpath but get ");
3254         return false;
3255     }
3256     GStrIdx litStrIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(lexer.GetName());
3257     mod.PushbackImportPath(litStrIdx);
3258     lexer.NextToken();
3259     return true;
3260 }
3261 
ParseMIRForAsmdecl()3262 bool MIRParser::ParseMIRForAsmdecl()
3263 {
3264     lexer.NextToken();
3265     if (lexer.GetTokenKind() != TK_string) {
3266         Error("expect asm string after iasm but get ");
3267         return false;
3268     }
3269     mod.GetAsmDecls().emplace_back(MapleString(lexer.GetName(), mod.GetMemPool()));
3270     lexer.NextToken();
3271     return true;
3272 }
3273 
PrepareParsingMIR()3274 void MIRParser::PrepareParsingMIR()
3275 {
3276     dummyFunction = CreateDummyFunction();
3277     mod.SetCurFunction(dummyFunction);
3278     if (mod.IsNeedFile()) {
3279         lexer.PrepareForFile(mod.GetFileName());
3280     } else {
3281         lexer.PrepareForString(mod.GetFileText());
3282     }
3283 }
3284 
PrepareParsingMplt()3285 void MIRParser::PrepareParsingMplt()
3286 {
3287     lexer.PrepareForFile(mod.GetFileName());
3288 }
3289 
ParseTypeFromString(const std::string & src,TyIdx & tyIdx)3290 bool MIRParser::ParseTypeFromString(const std::string &src, TyIdx &tyIdx)
3291 {
3292     lexer.PrepareForString(src);
3293     return ParseType(tyIdx);
3294 }
3295 
ParseMPLT(std::ifstream & mpltFile,const std::string & importFileName)3296 bool MIRParser::ParseMPLT(std::ifstream &mpltFile, const std::string &importFileName)
3297 {
3298     // save relevant values for the main input file
3299     std::ifstream *airFileSave = lexer.GetFile();
3300     int lineNumSave = lexer.lineNum;
3301     std::string modFileNameSave = mod.GetFileName();
3302     // set up to read next line from the import file
3303     lexer.curIdx = 0;
3304     lexer.currentLineSize = 0;
3305     lexer.SetFile(mpltFile);
3306     lexer.lineNum = 0;
3307     mod.SetFileName(importFileName);
3308     bool atEof = false;
3309     lexer.NextToken();
3310     while (!atEof) {
3311         TokenKind tokenKind = lexer.GetTokenKind();
3312         switch (tokenKind) {
3313             default: {
3314                 Error("expect func or var but get ");
3315                 return false;
3316             }
3317             case TK_eof:
3318                 atEof = true;
3319                 break;
3320             case TK_type:
3321                 paramParseLocalType = false;
3322                 if (!ParseTypedef()) {
3323                     return false;
3324                 }
3325                 break;
3326             case TK_var: {
3327                 tokenKind = lexer.NextToken();
3328                 if (tokenKind == TK_gname) {
3329                     std::string literalName = lexer.GetName();
3330                     GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(literalName);
3331                     GlobalTables::GetConstPool().PutLiteralNameAsImported(strIdx);
3332                     lexer.NextToken();
3333                 } else {
3334                     return false;
3335                 }
3336                 break;
3337             }
3338         }
3339     }
3340     // restore old values to continue reading from the main input file
3341     lexer.curIdx = 0;  // to force reading new line
3342     lexer.currentLineSize = 0;
3343     lexer.lineNum = lineNumSave;
3344     lexer.SetFile(*airFileSave);
3345     mod.SetFileName(modFileNameSave);
3346     return true;
3347 }
3348 
ParseMPLTStandalone(std::ifstream & mpltFile,const std::string & importFileName)3349 bool MIRParser::ParseMPLTStandalone(std::ifstream &mpltFile, const std::string &importFileName)
3350 {
3351     PrepareParsingMIR();
3352     if (!ParseMPLT(mpltFile, importFileName)) {
3353         return false;
3354     }
3355     lexer.lineNum = 0;
3356     // fix the typedef type
3357     FixupForwardReferencedTypeByMap();
3358     return true;
3359 }
3360 
ParsePrototypeRemaining(MIRFunction & func,std::vector<TyIdx> & vecTyIdx,std::vector<TypeAttrs> & vecAttrs,bool & varArgs)3361 bool MIRParser::ParsePrototypeRemaining(MIRFunction &func, std::vector<TyIdx> &vecTyIdx,
3362                                         std::vector<TypeAttrs> &vecAttrs, bool &varArgs)
3363 {
3364     TokenKind pmTk = lexer.GetTokenKind();
3365     while (pmTk != TK_rparen) {
3366         // parse ","
3367         if (pmTk != TK_coma) {
3368             Error("expect , after a declare var/preg but get");
3369             return false;
3370         }
3371         pmTk = lexer.NextToken();
3372         if (pmTk == TK_dotdotdot) {
3373             varArgs = true;
3374             func.SetVarArgs();
3375             pmTk = lexer.NextToken();
3376             if (pmTk != TK_rparen) {
3377                 Error("expect ) after ... but get");
3378                 return false;
3379             }
3380             break;
3381         }
3382         MIRSymbol *symbol = func.GetSymTab()->CreateSymbol(kScopeLocal);
3383         DEBUG_ASSERT(symbol != nullptr, "symbol nullptr check");
3384         symbol->SetStorageClass(kScFormal);
3385         TokenKind loopStTK = lexer.GetTokenKind();
3386         if (loopStTK == TK_reg) {
3387             symbol->SetSKind(kStPreg);
3388             if (!ParseDeclareReg(*symbol, func)) {
3389                 Error("ParseFunction expect scalar value");
3390                 return false;
3391             }
3392         } else {
3393             symbol->SetSKind(kStVar);
3394             if (!ParseDeclareVar(*symbol)) {
3395                 Error("ParseFunction expect scalar value");
3396                 return false;
3397             }
3398             (void)func.GetSymTab()->AddToStringSymbolMap(*symbol);
3399             if (!ParseDeclareVarInitValue(*symbol)) {
3400                 return false;
3401             }
3402         }
3403         func.AddArgument(symbol);
3404         vecTyIdx.push_back(symbol->GetTyIdx());
3405         vecAttrs.push_back(symbol->GetAttrs());
3406         pmTk = lexer.GetTokenKind();
3407     }
3408     return true;
3409 }
3410 
EmitError(const std::string & fileName)3411 void MIRParser::EmitError(const std::string &fileName)
3412 {
3413     if (!strlen(GetError().c_str())) {
3414         return;
3415     }
3416     mod.GetDbgInfo()->EmitMsg();
3417     ERR(kLncErr, "%s \n%s", fileName.c_str(), GetError().c_str());
3418 }
3419 
EmitWarning(const std::string & fileName)3420 void MIRParser::EmitWarning(const std::string &fileName)
3421 {
3422     if (!strlen(GetWarning().c_str())) {
3423         return;
3424     }
3425     WARN(kLncWarn, "%s \n%s\n", fileName.c_str(), GetWarning().c_str());
3426 }
3427 }  // namespace maple
3428