• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #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