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 #ifndef MAPLE_IR_INCLUDE_MIR_PARSER_H 17 #define MAPLE_IR_INCLUDE_MIR_PARSER_H 18 #include "mir_module.h" 19 #include "lexer.h" 20 #include "mir_nodes.h" 21 #include "mir_preg.h" 22 #include "mir_scope.h" 23 #include "parser_opt.h" 24 25 namespace maple { 26 using BaseNodePtr = BaseNode *; 27 using StmtNodePtr = StmtNode *; 28 using BlockNodePtr = BlockNode *; 29 30 class FormalDef; 31 32 class MIRParser { 33 public: MIRParser(MIRModule & md)34 explicit MIRParser(MIRModule &md) : lexer(md), mod(md), definedLabels(mod.GetMPAllocator().Adapter()) 35 { 36 safeRegionFlag.push(false); 37 } 38 39 ~MIRParser() = default; 40 41 MIRFunction *CreateDummyFunction(); ResetCurrentFunction()42 void ResetCurrentFunction() 43 { 44 mod.SetCurFunction(dummyFunction); 45 } 46 47 bool ParseLoc(); 48 bool ParseLocStmt(StmtNodePtr &stmt); 49 bool ParsePosition(SrcPosition &pos); 50 bool ParseOneScope(MIRScope &scope); 51 bool ParseScope(StmtNodePtr &stmt); 52 bool ParseOneAlias(GStrIdx &strIdx, MIRAliasVars &aliasVar); 53 bool ParseAlias(StmtNodePtr &stmt); 54 uint8 *ParseWordsInfo(uint32 size); 55 bool ParseSwitchCase(int64 &, LabelIdx &); 56 bool ParseExprOneOperand(BaseNodePtr &expr); 57 bool ParseExprTwoOperand(BaseNodePtr &opnd0, BaseNodePtr &opnd1); 58 bool ParseExprNaryOperand(MapleVector<BaseNode *> &opndVec); 59 bool IsDelimitationTK(TokenKind tk) const; 60 Opcode GetOpFromToken(TokenKind tk) const; 61 bool IsStatement(TokenKind tk) const; 62 PrimType GetPrimitiveType(TokenKind tk) const; 63 MIRIntrinsicID GetIntrinsicID(TokenKind tk) const; 64 bool ParseScalarValue(MIRConstPtr &stype, MIRType &type); 65 bool ParseConstAddrLeafExpr(MIRConstPtr &cexpr); 66 bool ParseInitValue(MIRConstPtr &theConst, TyIdx tyIdx, bool allowEmpty = false); 67 bool ParseDeclaredSt(StIdx &stidx); 68 void CreateFuncMIRSymbol(PUIdx &puidx, GStrIdx strIdx); 69 bool ParseDeclaredFunc(PUIdx &puidx); 70 bool ParseTypeAttrs(TypeAttrs &attrs); 71 bool ParseVarTypeAttrs(MIRSymbol &st); 72 bool CheckAlignTk(); 73 bool ParseAlignAttrs(TypeAttrs &tA); 74 bool ParsePackAttrs(); 75 bool ParseFieldAttrs(FieldAttrs &attrs); 76 bool ParseFuncAttrs(FuncAttrs &attrs); 77 void SetAttrContent(FuncAttrs &attrs, FuncAttrKind x, const MIRLexer &lexer); 78 bool CheckPrimAndDerivedType(TokenKind tokenKind, TyIdx &tyIdx); 79 bool ParsePrimType(TyIdx &tyIdx); 80 bool ParseFarrayType(TyIdx &arrayTyIdx); 81 bool ParseArrayType(TyIdx &arrayTyIdx); 82 bool ParseBitFieldType(TyIdx &fieldTyIdx); 83 bool ParsePragmaElement(MIRPragmaElement &elem); 84 bool ParsePragmaElementForArray(MIRPragmaElement &elem); 85 bool ParsePragmaElementForAnnotation(MIRPragmaElement &elem); 86 bool ParsePragma(MIRStructType &type); 87 bool ParseFields(MIRStructType &type); 88 bool ParseStructType(TyIdx &styIdx, const GStrIdx &strIdx = GStrIdx(0)); 89 bool ParseClassType(TyIdx &styidx, const GStrIdx &strIdx = GStrIdx(0)); 90 bool ParseInterfaceType(TyIdx &sTyIdx, const GStrIdx &strIdx = GStrIdx(0)); 91 bool ParseDefinedTypename(TyIdx &definedTyIdx, MIRTypeKind kind = kTypeUnknown); 92 bool ParseTypeParam(TyIdx &definedTyIdx); 93 bool ParsePointType(TyIdx &tyIdx); 94 bool ParseFuncType(TyIdx &tyIdx); 95 bool ParseGenericInstantVector(MIRInstantVectorType &insVecType); 96 bool ParseDerivedType(TyIdx &tyIdx, MIRTypeKind kind = kTypeUnknown, const GStrIdx &strIdx = GStrIdx(0)); 97 bool ParseType(TyIdx &tyIdx); 98 bool ParseStatement(StmtNodePtr &stmt); 99 bool ParseSpecialReg(PregIdx &pRegIdx); 100 bool ParsePseudoReg(PrimType primType, PregIdx &pRegIdx); 101 bool ParseStmtBlock(BlockNodePtr &blk); 102 bool ParsePrototype(MIRFunction &func, MIRSymbol &funcSymbol, TyIdx &funcTyIdx); 103 bool ParseFunction(uint32 fileIdx = 0); 104 bool ParseStorageClass(MIRSymbol &symbol) const; 105 bool ParseDeclareVarInitValue(MIRSymbol &symbol); 106 bool ParseDeclareVar(MIRSymbol &); 107 bool ParseDeclareReg(MIRSymbol &symbol, const MIRFunction &func); 108 bool ParseDeclareFormal(FormalDef &formalDef); 109 bool ParsePrototypeRemaining(MIRFunction &func, std::vector<TyIdx> &vecTyIdx, std::vector<TypeAttrs> &vecAttrs, 110 bool &varArgs); 111 112 // Stmt Parser 113 bool ParseStmtDassign(StmtNodePtr &stmt); 114 bool ParseStmtDassignoff(StmtNodePtr &stmt); 115 bool ParseStmtRegassign(StmtNodePtr &stmt); 116 bool ParseStmtIassign(StmtNodePtr &stmt); 117 bool ParseStmtIassignoff(StmtNodePtr &stmt); 118 bool ParseStmtIassignFPoff(StmtNodePtr &stmt); 119 bool ParseStmtBlkassignoff(StmtNodePtr &stmt); 120 bool ParseStmtDoloop(StmtNodePtr &stmt); 121 bool ParseStmtForeachelem(StmtNodePtr &stmt); 122 bool ParseStmtDowhile(StmtNodePtr &stmt); 123 bool ParseStmtIf(StmtNodePtr &stmt); 124 bool ParseStmtWhile(StmtNodePtr &stmt); 125 bool ParseStmtLabel(StmtNodePtr &stmt); 126 bool ParseStmtGoto(StmtNodePtr &stmt); 127 bool ParseStmtBr(StmtNodePtr &stmt); 128 bool ParseStmtSwitch(StmtNodePtr &stmt); 129 bool ParseStmtRangegoto(StmtNodePtr &stmt); 130 bool ParseStmtMultiway(StmtNodePtr &stmt); 131 PUIdx EnterUndeclaredFunction(bool isMcount = false); // for -pg in order to add "void _mcount()" 132 bool ParseStmtCall(StmtNodePtr &stmt); 133 bool ParseStmtCallMcount(StmtNodePtr &stmt); // for -pg in order to add "void _mcount()" to all the functions 134 bool ParseStmtIcall(StmtNodePtr &stmt, Opcode op); 135 bool ParseStmtIcall(StmtNodePtr &stmt); 136 bool ParseStmtIcallassigned(StmtNodePtr &stmt); 137 bool ParseStmtIcallproto(StmtNodePtr &stmt); 138 bool ParseStmtIcallprotoassigned(StmtNodePtr &stmt); 139 bool ParseStmtIntrinsiccall(StmtNodePtr &stmt, bool isAssigned); 140 bool ParseStmtIntrinsiccall(StmtNodePtr &stmt); 141 bool ParseStmtIntrinsiccallassigned(StmtNodePtr &stmt); 142 bool ParseStmtIntrinsiccallwithtype(StmtNodePtr &stmt, bool isAssigned); 143 bool ParseStmtIntrinsiccallwithtype(StmtNodePtr &stmt); 144 bool ParseStmtIntrinsiccallwithtypeassigned(StmtNodePtr &stmt); 145 bool ParseCallReturnPair(CallReturnPair &retpair); 146 bool ParseCallReturns(CallReturnVector &retsvec); 147 bool ParseBinaryStmt(StmtNodePtr &stmt, Opcode op); 148 bool ParseNaryStmtAssert(StmtNodePtr &stmt, Opcode op); 149 bool ParseNaryStmtAssertGE(StmtNodePtr &stmt); 150 bool ParseNaryStmtAssertLT(StmtNodePtr &stmt); 151 bool ParseNaryStmtCalcassertGE(StmtNodePtr &stmt); 152 bool ParseNaryStmtCalcassertLT(StmtNodePtr &stmt); 153 bool ParseNaryStmtCallAssertLE(StmtNodePtr &stmt); 154 bool ParseNaryStmtReturnAssertLE(StmtNodePtr &stmt); 155 bool ParseNaryStmtAssignAssertLE(StmtNodePtr &stmt); 156 bool ParseNaryStmt(StmtNodePtr &stmt, Opcode op); 157 bool ParseNaryStmtReturn(StmtNodePtr &stmt); 158 bool ParseNaryStmtSyncEnter(StmtNodePtr &stmt); 159 bool ParseNaryStmtSyncExit(StmtNodePtr &stmt); 160 bool ParseStmtJsTry(StmtNodePtr &stmt); 161 bool ParseStmtTry(StmtNodePtr &stmt); 162 bool ParseStmtCatch(StmtNodePtr &stmt); 163 bool ParseUnaryStmt(Opcode op, StmtNodePtr &stmt); 164 bool ParseUnaryStmtThrow(StmtNodePtr &stmt); 165 bool ParseUnaryStmtDecRef(StmtNodePtr &stmt); 166 bool ParseUnaryStmtIncRef(StmtNodePtr &stmt); 167 bool ParseUnaryStmtDecRefReset(StmtNodePtr &stmt); 168 bool ParseUnaryStmtIGoto(StmtNodePtr &stmt); 169 bool ParseUnaryStmtEval(StmtNodePtr &stmt); 170 bool ParseUnaryStmtFree(StmtNodePtr &stmt); 171 bool ParseUnaryStmtAssertNonNullCheck(Opcode op, StmtNodePtr &stmt); 172 bool ParseUnaryStmtAssertNonNull(StmtNodePtr &stmt); 173 bool ParseUnaryStmtCallAssertNonNull(StmtNodePtr &stmt); 174 bool ParseUnaryStmtAssignAssertNonNull(StmtNodePtr &stmt); 175 bool ParseUnaryStmtReturnAssertNonNull(StmtNodePtr &stmt); 176 bool ParseStmtMarker(StmtNodePtr &stmt); 177 bool ParseStmtGosub(StmtNodePtr &stmt); 178 bool ParseStmtAsm(StmtNodePtr &stmt); 179 bool ParseStmtSafeRegion(StmtNodePtr &stmt); 180 181 // Expression Parser 182 bool ParseExpression(BaseNodePtr &expr); 183 bool ParseExprDread(BaseNodePtr &expr); 184 bool ParseExprDreadoff(BaseNodePtr &expr); 185 bool ParseExprRegread(BaseNodePtr &expr); 186 bool ParseExprBinary(BaseNodePtr &expr); 187 bool ParseExprCompare(BaseNodePtr &expr); 188 bool ParseExprDepositbits(BaseNodePtr &expr); 189 bool ParseExprConstval(BaseNodePtr &expr); 190 bool ParseExprConststr(BaseNodePtr &expr); 191 bool ParseExprConststr16(BaseNodePtr &expr); 192 bool ParseExprSizeoftype(BaseNodePtr &expr); 193 bool ParseExprFieldsDist(BaseNodePtr &expr); 194 bool ParseExprIreadIaddrof(IreadNode &expr); 195 bool ParseExprIread(BaseNodePtr &expr); 196 bool ParseExprIreadoff(BaseNodePtr &expr); 197 bool ParseExprIreadFPoff(BaseNodePtr &expr); 198 bool ParseExprIaddrof(BaseNodePtr &expr); 199 bool ParseExprAddrof(BaseNodePtr &expr); 200 bool ParseExprAddrofoff(BaseNodePtr &expr); 201 bool ParseExprAddroffunc(BaseNodePtr &expr); 202 bool ParseExprAddroflabel(BaseNodePtr &expr); 203 bool ParseExprUnary(BaseNodePtr &expr); 204 bool ParseExprJarray(BaseNodePtr &expr); 205 bool ParseExprSTACKJarray(BaseNodePtr &expr); 206 bool ParseExprGCMalloc(BaseNodePtr &expr); 207 bool ParseExprExtractbits(BaseNodePtr &expr); 208 bool ParseExprTyconvert(BaseNodePtr &expr); 209 bool ParseExprRetype(BaseNodePtr &expr); 210 bool ParseExprTernary(BaseNodePtr &expr); 211 bool ParseExprArray(BaseNodePtr &expr); 212 bool ParseExprIntrinsicop(BaseNodePtr &expr); 213 bool ParseNaryExpr(NaryStmtNode &stmtNode); 214 215 // funcName and paramIndex is out parameter 216 bool ParseCallAssertInfo(std::string &funcName, int *paramIndex, std::string &stmtFuncName); 217 bool ParseAssertInfo(std::string &funcName); 218 bool ParseTypedef(); 219 bool ParseJavaClassInterface(MIRSymbol &symbol, bool isClass); 220 bool ParseIntrinsicId(IntrinsicopNode &intrnOpNode); 221 void Error(const std::string &str); 222 void Warning(const std::string &str); 223 void FixForwardReferencedTypeForOneAgg(MIRType *type); 224 void FixupForwardReferencedTypeByMap(); 225 226 const std::string &GetError(); 227 const std::string &GetWarning() const; 228 bool ParseFuncInfo(void); 229 void PrepareParsingMIR(); 230 void PrepareParsingMplt(); 231 bool ParseSrcLang(MIRSrcLang &srcLang); 232 bool ParseMIR(uint32 fileIdx = 0, uint32 option = 0, bool isIPA = false, bool isComb = false); 233 bool ParseMIR(std::ifstream &mplFile); // the main entry point 234 bool ParseInlineFuncBody(std::ifstream &mplFile); 235 bool ParseMPLT(std::ifstream &mpltFile, const std::string &importFileName); 236 bool ParseMPLTStandalone(std::ifstream &mpltFile, const std::string &importFileName); 237 bool ParseTypeFromString(const std::string &src, TyIdx &tyIdx); 238 void EmitError(const std::string &fileName); 239 void EmitWarning(const std::string &fileName); GetOptions()240 uint32 GetOptions() const 241 { 242 return options; 243 } 244 245 private: 246 // func ptr map for ParseMIR() 247 using FuncPtrParseMIRForElem = bool (MIRParser::*)(); 248 static std::map<TokenKind, FuncPtrParseMIRForElem> funcPtrMapForParseMIR; 249 static std::map<TokenKind, FuncPtrParseMIRForElem> InitFuncPtrMapForParseMIR(); 250 251 bool TypeCompatible(TyIdx typeIdx1, TyIdx typeIdx2); 252 bool IsTypeIncomplete(MIRType *type); 253 254 // func for ParseMIR 255 bool ParseMIRForFunc(); 256 bool ParseMIRForVar(); 257 bool ParseMIRForClass(); 258 bool ParseMIRForInterface(); 259 bool ParseMIRForFlavor(); 260 bool ParseMIRForSrcLang(); 261 bool ParseMIRForGlobalMemSize(); 262 bool ParseMIRForGlobalMemMap(); 263 bool ParseMIRForGlobalWordsTypeTagged(); 264 bool ParseMIRForGlobalWordsRefCounted(); 265 bool ParseMIRForID(); 266 bool ParseMIRForNumFuncs(); 267 bool ParseMIRForEntryFunc(); 268 bool ParseMIRForFileInfo(); 269 bool ParseMIRForFileData(); 270 bool ParseMIRForSrcFileInfo(); 271 bool ParseMIRForImport(); 272 bool ParseMIRForImportPath(); 273 bool ParseMIRForAsmdecl(); 274 275 // func for ParseExpr 276 using FuncPtrParseExpr = bool (MIRParser::*)(BaseNodePtr &ptr); 277 static std::map<TokenKind, FuncPtrParseExpr> funcPtrMapForParseExpr; 278 static std::map<TokenKind, FuncPtrParseExpr> InitFuncPtrMapForParseExpr(); 279 280 // func and param for ParseStmt 281 using FuncPtrParseStmt = bool (MIRParser::*)(StmtNodePtr &stmt); 282 static std::map<TokenKind, FuncPtrParseStmt> funcPtrMapForParseStmt; 283 static std::map<TokenKind, FuncPtrParseStmt> InitFuncPtrMapForParseStmt(); 284 285 // func and param for ParseStmtBlock 286 using FuncPtrParseStmtBlock = bool (MIRParser::*)(); 287 static std::map<TokenKind, FuncPtrParseStmtBlock> funcPtrMapForParseStmtBlock; 288 static std::map<TokenKind, FuncPtrParseStmtBlock> InitFuncPtrMapForParseStmtBlock(); 289 void ParseStmtBlockForSeenComment(BlockNodePtr blk, uint32 mplNum); 290 bool ParseStmtBlockForVar(TokenKind stmtTK); 291 bool ParseStmtBlockForVar(); 292 bool ParseStmtBlockForTempVar(); 293 bool ParseStmtBlockForReg(); 294 bool ParseStmtBlockForType(); 295 bool ParseStmtBlockForFrameSize(); 296 bool ParseStmtBlockForUpformalSize(); 297 bool ParseStmtBlockForModuleID(); 298 bool ParseStmtBlockForFuncSize(); 299 bool ParseStmtBlockForFuncID(); 300 bool ParseStmtBlockForFormalWordsTypeTagged(); 301 bool ParseStmtBlockForLocalWordsTypeTagged(); 302 bool ParseStmtBlockForFormalWordsRefCounted(); 303 bool ParseStmtBlockForLocalWordsRefCounted(); 304 bool ParseStmtBlockForFuncInfo(); 305 306 // common func 307 void SetSrcPos(SrcPosition &srcPosition, uint32 mplNum); 308 309 // func for ParseExpr 310 Opcode paramOpForStmt = OP_undef; 311 TokenKind paramTokenKindForStmt = TK_invalid; 312 // func and param for ParseStmtBlock 313 MIRFunction *paramCurrFuncForParseStmtBlock = nullptr; 314 MIRLexer lexer; 315 MIRModule &mod; 316 std::string message; 317 std::string warningMessage; 318 uint32 options = kKeepFirst; 319 MapleVector<bool> definedLabels; // true if label at labidx is defined 320 MIRFunction *dummyFunction = nullptr; 321 MIRFunction *curFunc = nullptr; 322 uint16 lastFileNum = 0; // to remember first number after LOC 323 uint32 lastLineNum = 0; // to remember second number after LOC 324 uint16 lastColumnNum = 0; // to remember third number after LOC 325 uint32 firstLineNum = 0; // to track function starting line 326 std::map<TyIdx, TyIdx> typeDefIdxMap; // map previous declared tyIdx 327 bool firstImport = true; // Mark the first imported mplt file 328 bool paramParseLocalType = false; // param for ParseTypedef 329 uint32 paramFileIdx = 0; // param for ParseMIR() 330 bool paramIsIPA = false; 331 bool paramIsComb = false; 332 TokenKind paramTokenKind = TK_invalid; 333 std::vector<std::string> paramImportFileList; 334 std::stack<bool> safeRegionFlag; 335 }; 336 } // namespace maple 337 #endif // MAPLE_IR_INCLUDE_MIR_PARSER_H 338