• 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_BUILDER_H
17 #define MAPLE_IR_INCLUDE_MIR_BUILDER_H
18 #include <string>
19 #include <utility>
20 #include <vector>
21 #include <map>
22 #ifdef _WIN32
23 #include <pthread.h>
24 #endif
25 #include "opcodes.h"
26 #include "prim_types.h"
27 #include "mir_type.h"
28 #include "mir_const.h"
29 #include "mir_symbol.h"
30 #include "mir_nodes.h"
31 #include "mir_module.h"
32 #include "mir_preg.h"
33 #include "mir_function.h"
34 #include "printing.h"
35 #include "intrinsic_op.h"
36 #include "opcode_info.h"
37 #include "global_tables.h"
38 
39 namespace maple {
40 using ArgPair = std::pair<std::string, MIRType *>;
41 using ArgVector = MapleVector<ArgPair>;
42 class MIRBuilder {
43 public:
44     enum MatchStyle {
45         kUpdateFieldID = 0,  // do not match but traverse to update fieldID
46         kMatchTopField = 1,  // match top level field only
47         kMatchAnyField = 2,  // match any field
48         kParentFirst = 4,    // traverse parent first
49         kFoundInChild = 8,   // found in child
50     };
51 
MIRBuilder(MIRModule * module)52     explicit MIRBuilder(MIRModule *module)
53         : mirModule(module), incompleteTypeRefedSet(mirModule->GetMPAllocator().Adapter())
54     {
55     }
56 
57     virtual ~MIRBuilder() = default;
58 
SetCurrentFunction(MIRFunction & fun)59     virtual void SetCurrentFunction(MIRFunction &fun)
60     {
61         mirModule->SetCurFunction(&fun);
62     }
63 
GetCurrentFunction()64     virtual MIRFunction *GetCurrentFunction() const
65     {
66         return mirModule->CurFunction();
67     }
GetCurrentFunctionNotNull()68     MIRFunction *GetCurrentFunctionNotNull() const
69     {
70         MIRFunction *func = GetCurrentFunction();
71         CHECK_FATAL(func != nullptr, "nullptr check");
72         return func;
73     }
74 
GetMirModule()75     MIRModule &GetMirModule()
76     {
77         return *mirModule;
78     }
79 
GetIncompleteTypeRefedSet()80     const MapleSet<TyIdx> &GetIncompleteTypeRefedSet() const
81     {
82         return incompleteTypeRefedSet;
83     }
84 
GetExtraFieldsTuples()85     std::vector<std::tuple<uint32, uint32, uint32, uint32>> &GetExtraFieldsTuples()
86     {
87         return extraFieldsTuples;
88     }
89 
GetLineNum()90     unsigned int GetLineNum() const
91     {
92         return lineNum;
93     }
SetLineNum(unsigned int num)94     void SetLineNum(unsigned int num)
95     {
96         lineNum = num;
97     }
98 
GetOrCreateStringIndex(const std::string & str)99     GStrIdx GetOrCreateStringIndex(const std::string &str) const
100     {
101         return GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(str);
102     }
103 
GetOrCreateStringIndex(GStrIdx strIdx,const std::string & str)104     GStrIdx GetOrCreateStringIndex(GStrIdx strIdx, const std::string &str) const
105     {
106         std::string firstString(GlobalTables::GetStrTable().GetStringFromStrIdx(strIdx));
107         firstString += str;
108         return GlobalTables::GetStrTable().GetOrCreateStrIdxFromName(firstString);
109     }
110 
GetStringIndex(const std::string & str)111     GStrIdx GetStringIndex(const std::string &str) const
112     {
113         return GlobalTables::GetStrTable().GetStrIdxFromName(str);
114     }
115 
116     MIRFunction *GetOrCreateFunction(const std::string &, TyIdx);
117     MIRFunction *GetFunctionFromSymbol(const MIRSymbol &funcst);
118     MIRFunction *GetFunctionFromStidx(StIdx stIdx);
119     MIRFunction *GetFunctionFromName(const std::string &);
120     // For compiler-generated metadata struct
121     void AddIntFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID, int64 constValue);
122     void AddAddrofFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID,
123                              const MIRSymbol &fieldSt);
124     void AddAddroffuncFieldConst(const MIRStructType &sType, MIRAggConst &newConst, uint32 fieldID,
125                                  const MIRSymbol &funcSt);
126 
127     bool TraverseToNamedField(MIRStructType &structType, GStrIdx nameIdx, uint32 &fieldID);
128     bool TraverseToNamedFieldWithTypeAndMatchStyle(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx,
129                                                    uint32 &fieldID, unsigned int matchStyle);
130     void TraverseToNamedFieldWithType(MIRStructType &structType, GStrIdx nameIdx, TyIdx typeIdx, uint32 &fieldID,
131                                       uint32 &idx);
132 
133     FieldID GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx, unsigned int matchStyle);
134     FieldID GetStructFieldIDFromNameAndType(MIRType &type, const std::string &name, TyIdx idx);
135     FieldID GetStructFieldIDFromNameAndTypeParentFirst(MIRType &type, const std::string &name, TyIdx idx);
136     FieldID GetStructFieldIDFromNameAndTypeParentFirstFoundInChild(MIRType &type, const std::string &name, TyIdx idx);
137 
138     FieldID GetStructFieldIDFromFieldName(MIRType &type, const std::string &name);
139     FieldID GetStructFieldIDFromFieldNameParentFirst(MIRType *type, const std::string &name);
140 
141     void SetStructFieldIDFromFieldName(MIRStructType &structType, const std::string &name, GStrIdx newStrIdx,
142                                        const MIRType &newFieldType);
143     // for creating Function.
GetFunctionArgument(MIRFunction & fun,uint32 index)144     MIRSymbol *GetFunctionArgument(MIRFunction &fun, uint32 index) const
145     {
146         CHECK(index < fun.GetFormalCount(), "index out of range in GetFunctionArgument");
147         return fun.GetFormal(index);
148     }
149 
150     MIRFunction *CreateFunction(const std::string &name, const MIRType &returnType, const ArgVector &arguments,
151                                 bool isVarg = false, bool createBody = true) const;
152     MIRFunction *CreateFunction(StIdx stIdx, bool addToTable = true) const;
UpdateFunction(MIRFunction &,const MIRType *,const ArgVector &)153     virtual void UpdateFunction(MIRFunction &, const MIRType *, const ArgVector &) {}
154 
155     MIRSymbol *GetSymbolFromEnclosingScope(StIdx stIdx) const;
156     virtual MIRSymbol *GetOrCreateLocalDecl(const std::string &str, const MIRType &type);
157     MIRSymbol *GetLocalDecl(const std::string &str);
158     MIRSymbol *CreateLocalDecl(const std::string &str, const MIRType &type);
159     MIRSymbol *GetOrCreateGlobalDecl(const std::string &str, const MIRType &type);
160     MIRSymbol *GetGlobalDecl(const std::string &str);
161     MIRSymbol *GetDecl(const std::string &str);
162     MIRSymbol *CreateGlobalDecl(const std::string &str, const MIRType &type, MIRStorageClass sc = kScGlobal);
163     MIRSymbol *GetOrCreateDeclInFunc(const std::string &str, const MIRType &type, MIRFunction &func);
164     // for creating Expression
165     ConstvalNode *CreateConstval(MIRConst *constVal);
166     ConstvalNode *CreateIntConst(uint64, PrimType);
167     ConstvalNode *CreateFloatConst(float val);
168     ConstvalNode *CreateDoubleConst(double val);
169     ConstvalNode *CreateFloat128Const(const uint64 *val);
170     ConstvalNode *GetConstInt(MemPool &memPool, int val);
GetConstInt(int val)171     ConstvalNode *GetConstInt(int val)
172     {
173         return CreateIntConst(val, PTY_i32);
174     }
175 
GetConstUInt1(bool val)176     ConstvalNode *GetConstUInt1(bool val)
177     {
178         return CreateIntConst(val, PTY_u1);
179     }
180 
GetConstUInt8(uint8 val)181     ConstvalNode *GetConstUInt8(uint8 val)
182     {
183         return CreateIntConst(val, PTY_u8);
184     }
185 
GetConstUInt16(uint16 val)186     ConstvalNode *GetConstUInt16(uint16 val)
187     {
188         return CreateIntConst(val, PTY_u16);
189     }
190 
GetConstUInt32(uint32 val)191     ConstvalNode *GetConstUInt32(uint32 val)
192     {
193         return CreateIntConst(val, PTY_u32);
194     }
195 
GetConstUInt64(uint64 val)196     ConstvalNode *GetConstUInt64(uint64 val)
197     {
198         return CreateIntConst(val, PTY_u64);
199     }
200 
201     ConstvalNode *CreateAddrofConst(BaseNode &);
202     ConstvalNode *CreateAddroffuncConst(const BaseNode &);
203     ConstvalNode *CreateStrConst(const BaseNode &);
204     ConstvalNode *CreateStr16Const(const BaseNode &);
205     SizeoftypeNode *CreateExprSizeoftype(const MIRType &type);
206     FieldsDistNode *CreateExprFieldsDist(const MIRType &type, FieldID field1, FieldID field2);
207     AddrofNode *CreateExprAddrof(FieldID fieldID, const MIRSymbol &symbol, MemPool *memPool = nullptr);
208     AddrofNode *CreateExprAddrof(FieldID fieldID, StIdx symbolStIdx, MemPool *memPool = nullptr);
209     AddroffuncNode *CreateExprAddroffunc(PUIdx, MemPool *memPool = nullptr);
210     AddrofNode *CreateExprDread(const MIRType &type, FieldID fieldID, const MIRSymbol &symbol);
211     AddrofNode *CreateExprDread(PrimType ptyp, FieldID fieldID, const MIRSymbol &symbol);
212     virtual AddrofNode *CreateExprDread(MIRType &type, MIRSymbol &symbol);
213     virtual AddrofNode *CreateExprDread(MIRSymbol &symbol);
214     AddrofNode *CreateExprDread(PregIdx pregID, PrimType pty);
215     AddrofNode *CreateExprDread(MIRSymbol &symbol, uint16 fieldID);
216     DreadoffNode *CreateExprDreadoff(Opcode op, PrimType pty, const MIRSymbol &symbol, int32 offset);
217     RegreadNode *CreateExprRegread(PrimType pty, PregIdx regIdx);
218     IreadNode *CreateExprIread(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID, BaseNode *addr);
219     IreadoffNode *CreateExprIreadoff(PrimType pty, int32 offset, BaseNode *opnd0);
220     IreadFPoffNode *CreateExprIreadFPoff(PrimType pty, int32 offset);
221     IaddrofNode *CreateExprIaddrof(const MIRType &returnType, const MIRType &ptrType, FieldID fieldID, BaseNode *addr);
222     IaddrofNode *CreateExprIaddrof(PrimType returnTypePty, TyIdx ptrTypeIdx, FieldID fieldID, BaseNode *addr);
223     BinaryNode *CreateExprBinary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1);
CreateExprBinary(Opcode opcode,PrimType pty,BaseNode * opnd0,BaseNode * opnd1)224     BinaryNode *CreateExprBinary(Opcode opcode, PrimType pty, BaseNode *opnd0, BaseNode *opnd1)
225     {
226         MIRType *ty = GlobalTables::GetTypeTable().GetTypeFromTyIdx(static_cast<TyIdx>(pty));
227         return CreateExprBinary(opcode, *ty, opnd0, opnd1);
228     }
229     TernaryNode *CreateExprTernary(Opcode opcode, const MIRType &type, BaseNode *opnd0, BaseNode *opnd1,
230                                    BaseNode *opnd2);
231     CompareNode *CreateExprCompare(Opcode opcode, const MIRType &type, const MIRType &opndType, BaseNode *opnd0,
232                                    BaseNode *opnd1);
233     UnaryNode *CreateExprUnary(Opcode opcode, const MIRType &type, BaseNode *opnd);
234     GCMallocNode *CreateExprGCMalloc(Opcode opcode, const MIRType &ptype, const MIRType &type);
235     JarrayMallocNode *CreateExprJarrayMalloc(Opcode opcode, const MIRType &ptype, const MIRType &type, BaseNode *opnd);
236     TypeCvtNode *CreateExprTypeCvt(Opcode o, PrimType toPrimType, PrimType fromPrimType, BaseNode &opnd);
237     TypeCvtNode *CreateExprTypeCvt(Opcode o, const MIRType &type, const MIRType &fromtype, BaseNode *opnd);
238     ExtractbitsNode *CreateExprExtractbits(Opcode o, const MIRType &type, uint32 bOffset, uint32 bSize, BaseNode *opnd);
239     ExtractbitsNode *CreateExprExtractbits(Opcode o, PrimType type, uint32 bOffset, uint32 bSize, BaseNode *opnd);
240     DepositbitsNode *CreateExprDepositbits(Opcode o, PrimType type, uint32 bOffset, uint32 bSize, BaseNode *leftOpnd,
241                                            BaseNode *rightOpnd);
242     RetypeNode *CreateExprRetype(const MIRType &type, const MIRType &fromType, BaseNode *opnd);
243     RetypeNode *CreateExprRetype(const MIRType &type, PrimType fromType, BaseNode *opnd);
244     ArrayNode *CreateExprArray(const MIRType &arrayType);
245     ArrayNode *CreateExprArray(const MIRType &arrayType, BaseNode *op);
246     ArrayNode *CreateExprArray(const MIRType &arrayType, BaseNode *op1, BaseNode *op2);
247     ArrayNode *CreateExprArray(const MIRType &arrayType, std::vector<BaseNode *> ops);
248     IntrinsicopNode *CreateExprIntrinsicop(MIRIntrinsicID id, Opcode op, PrimType primType, TyIdx tyIdx,
249                                            const MapleVector<BaseNode *> &ops);
250     IntrinsicopNode *CreateExprIntrinsicop(MIRIntrinsicID idx, Opcode opcode, const MIRType &type,
251                                            const MapleVector<BaseNode *> &ops);
252     // for creating Statement.
253     NaryStmtNode *CreateStmtReturn(BaseNode *rVal);
254     NaryStmtNode *CreateStmtNary(Opcode op, BaseNode *rVal);
255     NaryStmtNode *CreateStmtNary(Opcode op, const MapleVector<BaseNode *> &rVals);
256     AssertNonnullStmtNode *CreateStmtAssertNonnull(Opcode op, BaseNode *rVal, GStrIdx funcNameIdx);
257     CallAssertNonnullStmtNode *CreateStmtCallAssertNonnull(Opcode op, BaseNode *rVal, GStrIdx callFuncNameIdx,
258                                                            size_t index, GStrIdx stmtFuncNameIdx);
259     CallAssertBoundaryStmtNode *CreateStmtCallAssertBoundary(Opcode op, const MapleVector<BaseNode *> &rVals,
260                                                              GStrIdx funcNameIdx, size_t index,
261                                                              GStrIdx stmtFuncNameIdx);
262     AssertBoundaryStmtNode *CreateStmtAssertBoundary(Opcode op, const MapleVector<BaseNode *> &rVals,
263                                                      GStrIdx funcNameIdx);
264     UnaryStmtNode *CreateStmtUnary(Opcode op, BaseNode *rVal);
265     UnaryStmtNode *CreateStmtThrow(BaseNode *rVal);
266     DassignNode *CreateStmtDassign(const MIRSymbol &var, FieldID fieldID, BaseNode *src);
267     DassignNode *CreateStmtDassign(StIdx sIdx, FieldID fieldID, BaseNode *src);
268     RegassignNode *CreateStmtRegassign(PrimType pty, PregIdx regIdx, BaseNode *src);
269     IassignNode *CreateStmtIassign(const MIRType &type, FieldID fieldID, BaseNode *addr, BaseNode *src);
270     IassignoffNode *CreateStmtIassignoff(PrimType pty, int32 offset, BaseNode *opnd0, BaseNode *src);
271     IassignFPoffNode *CreateStmtIassignFPoff(Opcode op, PrimType pty, int32 offset, BaseNode *src);
272     CallNode *CreateStmtCall(PUIdx puIdx, const MapleVector<BaseNode *> &args, Opcode opcode = OP_call);
273     CallNode *CreateStmtCall(const std::string &name, const MapleVector<BaseNode *> &args);
CreateStmtVirtualCall(PUIdx puIdx,const MapleVector<BaseNode * > & args)274     CallNode *CreateStmtVirtualCall(PUIdx puIdx, const MapleVector<BaseNode *> &args)
275     {
276         return CreateStmtCall(puIdx, args, OP_virtualcall);
277     }
278 
CreateStmtSuperclassCall(PUIdx puIdx,const MapleVector<BaseNode * > & args)279     CallNode *CreateStmtSuperclassCall(PUIdx puIdx, const MapleVector<BaseNode *> &args)
280     {
281         return CreateStmtCall(puIdx, args, OP_superclasscall);
282     }
283 
CreateStmtInterfaceCall(PUIdx puIdx,const MapleVector<BaseNode * > & args)284     CallNode *CreateStmtInterfaceCall(PUIdx puIdx, const MapleVector<BaseNode *> &args)
285     {
286         return CreateStmtCall(puIdx, args, OP_interfacecall);
287     }
288 
289     IcallNode *CreateStmtIcall(const MapleVector<BaseNode *> &args);
290     IcallNode *CreateStmtIcallAssigned(const MapleVector<BaseNode *> &args, const MIRSymbol &ret);
291     IcallNode *CreateStmtIcallAssigned(const MapleVector<BaseNode *> &args, PregIdx pregIdx);
292     IcallNode *CreateStmtIcallproto(const MapleVector<BaseNode *> &args, const TyIdx &prototypeIdx);
293     IcallNode *CreateStmtIcallprotoAssigned(const MapleVector<BaseNode *> &args, const MIRSymbol &ret);
294     // For Call, VirtualCall, SuperclassCall, InterfaceCall
295     IntrinsiccallNode *CreateStmtIntrinsicCall(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
296                                                TyIdx tyIdx = TyIdx());
297     IntrinsiccallNode *CreateStmtXintrinsicCall(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments);
298     CallNode *CreateStmtCallAssigned(PUIdx puidx, const MIRSymbol *ret, Opcode op = OP_callassigned);
299     CallNode *CreateStmtCallAssigned(PUIdx puidx, const MapleVector<BaseNode *> &args, const MIRSymbol *ret,
300                                      Opcode op = OP_callassigned, TyIdx tyIdx = TyIdx());
301     CallNode *CreateStmtCallRegassigned(PUIdx, PregIdx, Opcode);
302     CallNode *CreateStmtCallRegassigned(PUIdx, PregIdx, Opcode, BaseNode *opnd);
303     CallNode *CreateStmtCallRegassigned(PUIdx, const MapleVector<BaseNode *> &, PregIdx, Opcode);
304     IntrinsiccallNode *CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
305                                                        PregIdx retPregIdx);
306     IntrinsiccallNode *CreateStmtIntrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &arguments,
307                                                        const MIRSymbol *ret, TyIdx tyIdx = TyIdx());
308     IntrinsiccallNode *CreateStmtXintrinsicCallAssigned(MIRIntrinsicID idx, const MapleVector<BaseNode *> &args,
309                                                         const MIRSymbol *ret);
310     IfStmtNode *CreateStmtIf(BaseNode *cond);
311     IfStmtNode *CreateStmtIfThenElse(BaseNode *cond);
312     DoloopNode *CreateStmtDoloop(StIdx, bool, BaseNode *, BaseNode *, BaseNode *);
313     SwitchNode *CreateStmtSwitch(BaseNode *opnd, LabelIdx defaultLabel, const CaseVector &switchTable);
314     GotoNode *CreateStmtGoto(Opcode o, LabelIdx labIdx);
315     JsTryNode *CreateStmtJsTry(Opcode o, LabelIdx cLabIdx, LabelIdx fLabIdx);
316     TryNode *CreateStmtTry(const MapleVector<LabelIdx> &cLabIdxs);
317     CatchNode *CreateStmtCatch(const MapleVector<TyIdx> &tyIdxVec);
318     LabelIdx GetOrCreateMIRLabel(const std::string &name);
319     LabelIdx CreateLabIdx(MIRFunction &mirFunc);
320     LabelNode *CreateStmtLabel(LabelIdx labIdx);
321     StmtNode *CreateStmtComment(const std::string &comment);
322     CondGotoNode *CreateStmtCondGoto(BaseNode *cond, Opcode op, LabelIdx labIdx);
323     void AddStmtInCurrentFunctionBody(StmtNode &stmt);
324     MIRSymbol *GetSymbol(TyIdx, const std::string &, MIRSymKind, MIRStorageClass, uint8, bool) const;
325     MIRSymbol *GetSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, uint8, bool) const;
326     MIRSymbol *GetOrCreateSymbol(TyIdx, const std::string &, MIRSymKind, MIRStorageClass, MIRFunction *, uint8,
327                                  bool) const;
328     MIRSymbol *GetOrCreateSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, MIRFunction *, uint8, bool) const;
329     MIRSymbol *CreatePregFormalSymbol(TyIdx, PregIdx, MIRFunction &) const;
330     // for creating symbol
331     MIRSymbol *CreateSymbol(TyIdx, const std::string &, MIRSymKind, MIRStorageClass, MIRFunction *, uint8) const;
332     MIRSymbol *CreateSymbol(TyIdx, GStrIdx, MIRSymKind, MIRStorageClass, MIRFunction *, uint8) const;
333     MIRSymbol *CreateConstStringSymbol(const std::string &symbolName, const std::string &content);
334     // for creating nodes
335     AddrofNode *CreateAddrof(const MIRSymbol &st, PrimType pty = PTY_ptr);
336     AddrofNode *CreateDread(const MIRSymbol &st, PrimType pty);
337     virtual MemPool *GetCurrentFuncCodeMp();
338     virtual MapleAllocator *GetCurrentFuncCodeMpAllocator();
339     virtual MemPool *GetCurrentFuncDataMp();
340 
GlobalLock()341     virtual void GlobalLock() {}
GlobalUnlock()342     virtual void GlobalUnlock() {}
343 
SetCurrentDebugComment(const std::string & comment)344     void SetCurrentDebugComment(const std::string &comment)
345     {
346         currComment = GetMirModule().CurFunction()->AddNewDebugComment(comment);
347     }
348 
ClearCurrentDebugComment()349     void ClearCurrentDebugComment()
350     {
351         currComment = nullptr;
352     }
353 
354 private:
355     MIRSymbol *GetOrCreateGlobalDecl(const std::string &str, TyIdx tyIdx, bool &created) const;
356     MIRSymbol *GetOrCreateLocalDecl(const std::string &str, TyIdx tyIdx, MIRSymbolTable &symbolTable,
357                                     bool &created) const;
358     template <class T, typename... Arguments>
NewNode(Arguments &&...args)359     T *NewNode(Arguments &&... args)
360     {
361         static_assert(std::is_base_of_v<BaseNode, T>);
362         T *stmt =  GetCurrentFuncCodeMp()->New<T>(args...);
363         stmt->SetDebugComment(currComment);
364         return stmt;
365     }
366 
367     MIRModule *mirModule;
368     MapleSet<TyIdx> incompleteTypeRefedSet;
369     // <className strIdx, fieldname strIdx, typename strIdx, attr list strIdx>
370     std::vector<std::tuple<uint32, uint32, uint32, uint32>> extraFieldsTuples;
371     unsigned int lineNum = 0;
372     const MapleString *currComment { nullptr };
373 };
374 
375 class MIRBuilderExt : public MIRBuilder {
376 public:
377     explicit MIRBuilderExt(MIRModule *module, pthread_mutex_t *mutex = nullptr);
378     virtual ~MIRBuilderExt() = default;
379 
SetCurrentFunction(MIRFunction & func)380     void SetCurrentFunction(MIRFunction &func) override
381     {
382         curFunction = &func;
383     }
384 
GetCurrentFunction()385     MIRFunction *GetCurrentFunction() const override
386     {
387         return curFunction;
388     }
389 
390     MemPool *GetCurrentFuncCodeMp() override;
391     MapleAllocator *GetCurrentFuncCodeMpAllocator() override;
392     void GlobalLock() override;
393     void GlobalUnlock() override;
394 
395 private:
396     MIRFunction *curFunction = nullptr;
397     pthread_mutex_t *mutex = nullptr;
398 };
399 }  // namespace maple
400 #endif  // MAPLE_IR_INCLUDE_MIR_BUILDER_H
401