string dtype(Record* rec) { Init* typeInit = rec->getValueInit("VT"); if(!typeInit) return ""; string type = typeInit->getAsString(); if(type == "iPTR") return "void*"; string vec = ""; if(type[0] == 'v') { size_t i = 1; while(i != type.size() && type[i] <= '9' && type[i] >= '0') i++; vec = type.substr(1, i - 1); type = type.substr(i); } if(vec.size() > 0 && type.size() > 0) { int typeSize, vecElements; if( sscanf(vec.c_str(), "%d", &vecElements) == 1 && sscanf(type.c_str() + 1, "%d", &typeSize) == 1 && typeSize * vecElements > 256) { return ""; } } if(type == "i8") return "byte" + vec; else if(type == "i16") return "short" + vec; else if(type == "i32") return "int" + vec; else if(type == "i64") return "long" + vec; else if(type == "f32") return "float" + vec; else if(type == "f64") return "double" + vec; else return ""; }
json::Value JSONEmitter::translateInit(const Init &I) { // Init subclasses that we return as JSON primitive values of one // kind or another. if (isa<UnsetInit>(&I)) { return nullptr; } else if (auto *Bit = dyn_cast<BitInit>(&I)) { return Bit->getValue() ? 1 : 0; } else if (auto *Bits = dyn_cast<BitsInit>(&I)) { json::Array array; for (unsigned i = 0, limit = Bits->getNumBits(); i < limit; i++) array.push_back(translateInit(*Bits->getBit(i))); return std::move(array); } else if (auto *Int = dyn_cast<IntInit>(&I)) { return Int->getValue(); } else if (auto *Str = dyn_cast<StringInit>(&I)) { return Str->getValue(); } else if (auto *Code = dyn_cast<CodeInit>(&I)) { return Code->getValue(); } else if (auto *List = dyn_cast<ListInit>(&I)) { json::Array array; for (auto val : *List) array.push_back(translateInit(*val)); return std::move(array); } // Init subclasses that we return as JSON objects containing a // 'kind' discriminator. For these, we also provide the same // translation back into TableGen input syntax that -print-records // would give. json::Object obj; obj["printable"] = I.getAsString(); if (auto *Def = dyn_cast<DefInit>(&I)) { obj["kind"] = "def"; obj["def"] = Def->getDef()->getName(); return std::move(obj); } else if (auto *Var = dyn_cast<VarInit>(&I)) { obj["kind"] = "var"; obj["var"] = Var->getName(); return std::move(obj); } else if (auto *VarBit = dyn_cast<VarBitInit>(&I)) { if (auto *Var = dyn_cast<VarInit>(VarBit->getBitVar())) { obj["kind"] = "varbit"; obj["var"] = Var->getName(); obj["index"] = VarBit->getBitNum(); return std::move(obj); } } else if (auto *Dag = dyn_cast<DagInit>(&I)) { obj["kind"] = "dag"; obj["operator"] = translateInit(*Dag->getOperator()); if (auto name = Dag->getName()) obj["name"] = name->getAsUnquotedString(); json::Array args; for (unsigned i = 0, limit = Dag->getNumArgs(); i < limit; ++i) { json::Array arg; arg.push_back(translateInit(*Dag->getArg(i))); if (auto argname = Dag->getArgName(i)) arg.push_back(argname->getAsUnquotedString()); else arg.push_back(nullptr); args.push_back(std::move(arg)); } obj["args"] = std::move(args); return std::move(obj); } // Final fallback: anything that gets past here is simply given a // kind field of 'complex', and the only other field is the standard // 'printable' representation. assert(!I.isConcrete()); obj["kind"] = "complex"; return std::move(obj); }
/// ParseValue - Parse a tblgen value. This returns null on error. /// /// Value ::= SimpleValue ValueSuffix* /// ValueSuffix ::= '{' BitList '}' /// ValueSuffix ::= '[' BitList ']' /// ValueSuffix ::= '.' ID /// Init *TGParser::ParseValue(Record *CurRec) { Init *Result = ParseSimpleValue(CurRec); if (Result == 0) return 0; // Parse the suffixes now if present. while (1) { switch (Lex.getCode()) { default: return Result; case tgtok::l_brace: { TGLoc CurlyLoc = Lex.getLoc(); Lex.Lex(); // eat the '{' std::vector<unsigned> Ranges = ParseRangeList(); if (Ranges.empty()) return 0; // Reverse the bitlist. std::reverse(Ranges.begin(), Ranges.end()); Result = Result->convertInitializerBitRange(Ranges); if (Result == 0) { Error(CurlyLoc, "Invalid bit range for value"); return 0; } // Eat the '}'. if (Lex.getCode() != tgtok::r_brace) { TokError("expected '}' at end of bit range list"); return 0; } Lex.Lex(); break; } case tgtok::l_square: { TGLoc SquareLoc = Lex.getLoc(); Lex.Lex(); // eat the '[' std::vector<unsigned> Ranges = ParseRangeList(); if (Ranges.empty()) return 0; Result = Result->convertInitListSlice(Ranges); if (Result == 0) { Error(SquareLoc, "Invalid range for list slice"); return 0; } // Eat the ']'. if (Lex.getCode() != tgtok::r_square) { TokError("expected ']' at end of list slice"); return 0; } Lex.Lex(); break; } case tgtok::period: if (Lex.Lex() != tgtok::Id) { // eat the . TokError("expected field identifier after '.'"); return 0; } if (!Result->getFieldType(Lex.getCurStrVal())) { TokError("Cannot access field '" + Lex.getCurStrVal() + "' of value '" + Result->getAsString() + "'"); return 0; } Result = new FieldInit(Result, Lex.getCurStrVal()); Lex.Lex(); // eat field name break; } } }