2021SC@SDUSC
本次博客继续分析方舟编译器的MIRParser类。MIRParser类主要负责MIR的语法分析,组建IR中的语句等,都是在这个类所负责处理的。
本次分析parser.cpp中的内容。
MIRFunction *MIRParser::CreateDummyFunction() {
GStrIdx strIdx = GlobalTables::GetStrTable().GetOrCreateStrIdxFromName("$$");
MIRBuilder mirBuilder(&mod);
MIRSymbol *funcSt = mirBuilder.CreateSymbol(TyIdx(0), strIdx, kStFunc, kScUnused, nullptr, kScopeGlobal);
CHECK_FATAL(funcSt != nullptr, “Failed to create MIRSymbol”);
// Don’t add the function to the function table.
// It appears Storage class kScUnused is not honored.
MIRFunction *func = mirBuilder.CreateFunction(funcSt->GetStIdx(), false);
CHECK_FATAL(func != nullptr, “Failed to create MIRFunction”);
func->SetPuidxOrigin(func->GetPuidx());
MIRType *returnType = GlobalTables::GetTypeTable().GetTypeFromTyIdx(TyIdx(PTY_void));
func->SetReturnTyIdx(returnType->GetTypeIndex());
func->SetClassTyIdx(0U);
func->SetBaseClassFuncNames(strIdx);
funcSt->SetFunction(func);
return func;
}
建立空函数
bool MIRParser::IsDelimitationTK(TokenKind tk) const {
switch (tk) {
case TK_rparen:
case TK_coma:
return true;
default:
return false;
}
}
判断tk的类型
Opcode MIRParser::GetOpFromToken(TokenKind tk) const {
switch (tk) {
#define OPCODE(X, Y, Z, S)
case TK_##X:
return OP_##X;
#include “opcodes.def”
#undef OPCODE
default:
return OP_undef;
}
}
判断tk的种类
bool MIRParser::IsStatement(TokenKind tk) const {
if (tk == TK_LOC || tk == TK_ALIAS) {
return true;
}
Opcode op = GetOpFromToken(tk);
return kOpcodeInfo.IsStmt(op);
}
判断tk种类
PrimType MIRParser::GetPrimitiveType(TokenKind tk) const {
#define LOAD_ALGO_PRIMARY_TYPE
switch (tk) {
#define PRIMTYPE§
case TK_##P:
return PTY_##P;
#include “prim_types.def”
#undef PRIMTYPE
default:
return kPtyInvalid;
}
}
判断tk种类
MIRIntrinsicID MIRParser::GetIntrinsicID(TokenKind tk) const {
switch (tk) {
default:
#define DEF_MIR_INTRINSIC(P, NAME, INTRN_CLASS, RETURN_TYPE, …)
case TK_##P:
return INTRN_##P;
#include “intrinsics.def”
#undef DEF_MIR_INTRINSIC
}
}
判断tk种类
void MIRParser::Error(const std::string &str) {
std::stringstream strStream;
const std::string &lexName = lexer.GetName();
int curIdx = lexer.GetCurIdx() - lexName.length() + 1;
strStream << "line: " << lexer.GetLineNum() << “:” << curIdx << “:”;
message += strStream.str();
message += str;
message += ": ";
message += lexer.GetTokenString();
message += “\n”;
mod.GetDbgInfo()->SetErrPos(lexer.GetLineNum(), lexer.GetCurIdx());
}
判断tk种类
const std::string &MIRParser::GetError() {
if (lexer.GetTokenKind() == TK_invalid) {
std::stringstream strStream;
strStream << “line: " << lexer.GetLineNum() << “:” << lexer.GetCurIdx() << “:”;
message += strStream.str();
message += " invalid token\n”;
}
return message;
}
判断tk种类
void MIRParser::Warning(const std::string &str) {
std::stringstream strStream;
const std::string &lexName = lexer.GetName();
int curIdx = lexer.GetCurIdx() - lexName.length() + 1;
strStream << " >> warning line: " << lexer.GetLineNum() << “:” << curIdx << “:”;
warningMessage += strStream.str();
warningMessage += str;
warningMessage += “\n”;
}
const std::string &MIRParser::GetWarning() const {
return warningMessage;
}
获得警告
bool MIRParser::ParseSpecialReg(PregIdx &pRegIdx) {
const std::string &lexName = lexer.GetName();
size_t lexSize = lexName.size();
size_t retValSize = strlen(kLexerStringRetval);
if (strncmp(lexName.c_str(), kLexerStringRetval, retValSize) == 0 && (lexSize > retValSize) &&
isdigit(lexName[retValSize])) {
int32 retValNo = lexName[retValSize] - ‘0’;
for (size_t i = retValSize + 1; (i < lexSize) && isdigit(lexName[i]); ++i) {
retValNo = retValNo * 10 + lexName[i] - ‘0’;
}
pRegIdx = -kSregRetval0 - retValNo;
lexer.NextToken();
return true;
}
auto it = pregMapIdx.find(lexName);
if (it != pregMapIdx.end()) {
pRegIdx = -(it->second);
lexer.NextToken();
return true;
}
Error("unrecognized special register ");
return false;
}
判断是否分析特殊命令
bool MIRParser::ParsePseudoReg(PrimType primType, PregIdx &pRegIdx) {
uint32 pregNo = static_cast(lexer.GetTheIntVal());
ASSERT(pregNo <= 0xffff, “preg number must be 16 bits”);
MIRFunction *curfunc = mod.CurFunction();
pRegIdx = curfunc->GetPregTab()->EnterPregNo(pregNo, primType);
MIRPreg *preg = curfunc->GetPregTab()->PregFromPregIdx(pRegIdx);
if (primType != kPtyInvalid) {
if (preg->GetPrimType() != primType) {
if ((primType == PTY_ref || primType == PTY_ptr) &&
(preg->GetPrimType() == PTY_ref || preg->GetPrimType() == PTY_ptr)) {
; // PTY_ref and PTY_ptr are compatible with each other
} else {
Error("inconsistent preg primitive type at ");
return false;
}
}
}
lexer.NextToken();
return true;
}
判断是否能分析假命令