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