本文整理汇总了C++中RepoAuthType类的典型用法代码示例。如果您正苦于以下问题:C++ RepoAuthType类的具体用法?C++ RepoAuthType怎么用?C++ RepoAuthType使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了RepoAuthType类的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: ratToAssertType
/*
* Note: this is currently separate from typeFromRAT for now, just because we
* don't want to enable every single type for assertions yet.
*
* (Some of them currently regress performance, presumably because the IR
* doesn't always handle the additional type information very well. It is
* possibly a compile-time slowdown only, but we haven't investigated yet.)
*/
folly::Optional<Type> ratToAssertType(IRGS& env, RepoAuthType rat) {
using T = RepoAuthType::Tag;
switch (rat.tag()) {
case T::Uninit:
case T::InitNull:
case T::Null:
case T::Bool:
case T::Int:
case T::Dbl:
case T::Res:
case T::SStr:
case T::Str:
case T::Obj:
case T::SArr:
case T::Arr:
case T::Cell:
case T::Ref:
case T::InitUnc:
case T::Unc:
return typeFromRAT(rat);
case T::OptExactObj:
case T::OptSubObj:
case T::ExactObj:
case T::SubObj: {
auto ty = typeFromRAT(rat);
auto const cls = Unit::lookupClassOrUniqueClass(rat.clsName());
if (!classIsUniqueOrCtxParent(env, cls)) {
ty |= TObj; // Kill specialization.
}
return ty;
}
// Type assertions can't currently handle Init-ness.
case T::InitCell:
return TCell;
case T::InitGen:
return folly::none;
case T::Gen:
return folly::none;
case T::OptInt:
case T::OptObj:
case T::OptDbl:
case T::OptBool:
case T::OptSStr:
case T::OptStr:
case T::OptRes:
return folly::none;
case T::OptSArr:
case T::OptArr:
// TODO(#4205897): optional array types.
return folly::none;
}
not_reached();
}
示例2: collect_simple
// Simple stats about opcodes (that don't require full type
// information---those cases are only enabled when extendedStats is
// on).
void collect_simple(Stats& stats, const Bytecode& bc) {
++stats.op_counts[static_cast<uint64_t>(bc.op)];
RepoAuthType rat;
switch (bc.op) {
case Op::AssertRATL:
rat = bc.AssertRATL.rat;
break;
case Op::AssertRATStk:
rat = bc.AssertRATStk.rat;
break;
default:
return;
}
using U = std::underlying_type<RepoAuthType::Tag>::type;
auto const tagInt = static_cast<U>(rat.tag());
assert(tagInt < stats.ratL_tags.size());
if (bc.op == Op::AssertRATL) {
++stats.ratL_tags[tagInt];
} else {
++stats.ratStk_tags[tagInt];
}
if (rat.mayHaveArrData()) {
if (rat.array()) {
if (bc.op == Op::AssertRATL) {
++stats.ratL_specialized_array;
} else {
++stats.ratStk_specialized_array;
}
}
}
}
示例3: convertToType
Type convertToType(RepoAuthType ty) {
using T = RepoAuthType::Tag;
switch (ty.tag()) {
case T::OptBool: return Type::Bool | Type::InitNull;
case T::OptInt: return Type::Int | Type::InitNull;
case T::OptSStr: return Type::StaticStr | Type::InitNull;
case T::OptStr: return Type::Str | Type::InitNull;
case T::OptDbl: return Type::Dbl | Type::InitNull;
case T::OptRes: return Type::Res | Type::InitNull;
case T::OptObj: return Type::Obj | Type::InitNull;
case T::Uninit: return Type::Uninit;
case T::InitNull: return Type::InitNull;
case T::Null: return Type::Null;
case T::Bool: return Type::Bool;
case T::Int: return Type::Int;
case T::Dbl: return Type::Dbl;
case T::Res: return Type::Res;
case T::SStr: return Type::StaticStr;
case T::Str: return Type::Str;
case T::Obj: return Type::Obj;
case T::Cell: return Type::Cell;
case T::Ref: return Type::BoxedCell;
case T::InitUnc: return Type::UncountedInit;
case T::Unc: return Type::Uncounted;
case T::InitCell: return Type::InitCell;
case T::InitGen: return Type::Init;
case T::Gen: return Type::Gen;
// TODO(#4205897): option specialized array types
case T::OptArr: return Type::Arr | Type::InitNull;
case T::OptSArr: return Type::StaticArr | Type::InitNull;
case T::SArr:
if (auto const ar = ty.array()) return Type::StaticArr.specialize(ar);
return Type::StaticArr;
case T::Arr:
if (auto const ar = ty.array()) return Type::Arr.specialize(ar);
return Type::Arr;
case T::SubObj:
case T::ExactObj:
if (auto const cls = Unit::lookupUniqueClass(ty.clsName())) {
return Type::Obj.specialize(cls);
}
return Type::Obj;
case T::OptSubObj:
case T::OptExactObj:
if (auto const cls = Unit::lookupUniqueClass(ty.clsName())) {
return Type::Obj.specialize(cls) | Type::InitNull;
}
return Type::Obj | Type::InitNull;
}
not_reached();
}
示例4: array
bool RepoAuthType::operator==(RepoAuthType o) const {
using T = Tag;
if (tag() != o.tag()) return false;
switch (tag()) {
case T::OptBool:
case T::OptInt:
case T::OptSStr:
case T::OptStr:
case T::OptDbl:
case T::OptRes:
case T::OptObj:
case T::Null:
case T::Cell:
case T::Ref:
case T::InitUnc:
case T::Unc:
case T::InitCell:
case T::InitGen:
case T::Gen:
case T::Uninit:
case T::InitNull:
case T::Bool:
case T::Int:
case T::Dbl:
case T::Res:
case T::SStr:
case T::Str:
case T::Obj:
return true;
case T::OptSArr:
case T::OptArr:
// Can't currently have array() info.
return true;
case T::SArr:
case T::Arr:
if (array() == nullptr && o.array() == nullptr) {
return true;
}
if ((array() == nullptr) != (o.array() == nullptr)) {
return false;
}
return array()->id() == o.array()->id();
case T::SubObj:
case T::ExactObj:
case T::OptSubObj:
case T::OptExactObj:
return clsName() == o.clsName();
}
not_reached();
}
示例5: merge_repo_auth_type
void merge_repo_auth_type(UnitEmitter& ue, RepoAuthType rat) {
using T = RepoAuthType::Tag;
switch (rat.tag()) {
case T::OptBool:
case T::OptInt:
case T::OptSStr:
case T::OptStr:
case T::OptDbl:
case T::OptRes:
case T::OptObj:
case T::Null:
case T::Cell:
case T::Ref:
case T::InitUnc:
case T::Unc:
case T::InitCell:
case T::InitGen:
case T::Gen:
case T::Uninit:
case T::InitNull:
case T::Bool:
case T::Int:
case T::Dbl:
case T::Res:
case T::SStr:
case T::Str:
case T::Obj:
return;
case T::OptSArr:
case T::OptArr:
case T::SArr:
case T::Arr:
// We don't need to merge the litstrs in the array, because rats
// in arrays in the array type table must be using global litstr
// ids. (As the array type table itself is not associated with
// any unit.)
return;
case T::OptSubObj:
case T::OptExactObj:
case T::SubObj:
case T::ExactObj:
ue.mergeLitstr(rat.clsName());
return;
}
}
示例6: convertToDataType
folly::Optional<DataType> convertToDataType(RepoAuthType ty) {
using T = RepoAuthType::Tag;
switch (ty.tag()) {
case T::OptBool:
case T::OptInt:
case T::OptSArr:
case T::OptArr:
case T::OptSVec:
case T::OptVec:
case T::OptSDict:
case T::OptDict:
case T::OptSKeyset:
case T::OptKeyset:
case T::OptSStr:
case T::OptStr:
case T::OptDbl:
case T::OptRes:
case T::OptSubObj:
case T::OptExactObj:
case T::OptObj:
case T::Null:
return folly::none;
case T::Cell:
case T::Ref:
case T::InitUnc:
case T::Unc:
case T::InitCell:
case T::InitGen:
case T::Gen:
return folly::none;
case T::Uninit: return KindOfUninit;
case T::InitNull: return KindOfNull;
case T::Bool: return KindOfBoolean;
case T::Int: return KindOfInt64;
case T::Dbl: return KindOfDouble;
case T::Res: return KindOfResource;
case T::SStr:
case T::Str: return KindOfString;
case T::SArr:
case T::Arr: return KindOfArray;
case T::SVec:
case T::Vec: return KindOfVec;
case T::SDict:
case T::Dict: return KindOfDict;
case T::SKeyset:
case T::Keyset: return KindOfKeyset;
case T::Obj:
case T::SubObj:
case T::ExactObj: return KindOfObject;
}
not_reached();
}
示例7: encodeRAT
void encodeRAT(UnitEmitter& ue, RepoAuthType rat) {
using T = RepoAuthType::Tag;
switch (rat.tag()) {
case T::Uninit:
case T::InitNull:
case T::Null:
case T::Int:
case T::OptInt:
case T::Dbl:
case T::OptDbl:
case T::Res:
case T::OptRes:
case T::Bool:
case T::OptBool:
case T::SStr:
case T::OptSStr:
case T::Str:
case T::OptStr:
case T::SVec:
case T::OptSVec:
case T::Vec:
case T::OptVec:
case T::SDict:
case T::OptSDict:
case T::Dict:
case T::OptDict:
case T::SKeyset:
case T::OptSKeyset:
case T::Keyset:
case T::OptKeyset:
case T::Obj:
case T::OptObj:
case T::UncArrKey:
case T::ArrKey:
case T::OptUncArrKey:
case T::OptArrKey:
case T::InitUnc:
case T::Unc:
case T::InitCell:
case T::Cell:
case T::Ref:
case T::InitGen:
case T::Gen:
ue.emitByte(static_cast<uint8_t>(rat.tag()));
break;
case T::SArr:
case T::OptSArr:
case T::Arr:
case T::OptArr:
case T::SVArr:
case T::OptSVArr:
case T::VArr:
case T::OptVArr:
case T::SDArr:
case T::OptSDArr:
case T::DArr:
case T::OptDArr:
{
auto tagByte = static_cast<uint8_t>(rat.tag());
if (rat.hasArrData()) tagByte |= kRATArrayDataBit;
ue.emitByte(tagByte);
if (rat.hasArrData()) {
ue.emitInt32(rat.arrayId());
}
break;
}
case T::ExactObj:
case T::SubObj:
case T::OptExactObj:
case T::OptSubObj:
ue.emitByte(static_cast<uint8_t>(rat.tag()));
ue.emitInt32(ue.mergeLitstr(rat.clsName()));
break;
}
}
示例8: typeFromRAT
Type typeFromRAT(RepoAuthType ty) {
using T = RepoAuthType::Tag;
switch (ty.tag()) {
case T::OptBool: return TBool | TInitNull;
case T::OptInt: return TInt | TInitNull;
case T::OptSStr: return TStaticStr | TInitNull;
case T::OptStr: return TStr | TInitNull;
case T::OptDbl: return TDbl | TInitNull;
case T::OptRes: return TRes | TInitNull;
case T::OptObj: return TObj | TInitNull;
case T::Uninit: return TUninit;
case T::InitNull: return TInitNull;
case T::Null: return TNull;
case T::Bool: return TBool;
case T::Int: return TInt;
case T::Dbl: return TDbl;
case T::Res: return TRes;
case T::SStr: return TStaticStr;
case T::Str: return TStr;
case T::Obj: return TObj;
case T::Cell: return TCell;
case T::Ref: return TBoxedInitCell;
case T::InitUnc: return TUncountedInit;
case T::Unc: return TUncounted;
case T::InitCell: return TInitCell;
case T::InitGen: return TInitGen;
case T::Gen: return TGen;
// TODO(#4205897): option specialized array types
case T::OptArr: return TArr | TInitNull;
case T::OptSArr: return TStaticArr | TInitNull;
case T::SArr:
if (auto const ar = ty.array()) return Type::StaticArray(ar);
return TStaticArr;
case T::Arr:
if (auto const ar = ty.array()) return Type::Array(ar);
return TArr;
case T::SubObj:
case T::ExactObj:
case T::OptSubObj:
case T::OptExactObj: {
auto base = TObj;
if (auto const cls = Unit::lookupClassOrUniqueClass(ty.clsName())) {
if (ty.tag() == T::ExactObj || ty.tag() == T::OptExactObj) {
base = Type::ExactObj(cls);
} else {
base = Type::SubObj(cls);
}
}
if (ty.tag() == T::OptSubObj || ty.tag() == T::OptExactObj) {
base |= TInitNull;
}
return base;
}
}
not_reached();
}
示例9: show
std::string show(RepoAuthType rat) {
auto const tag = rat.tag();
using T = RepoAuthType::Tag;
switch (tag) {
case T::OptBool:
return "?Bool";
case T::OptInt:
return "?Int";
case T::OptSStr:
return "?SStr";
case T::OptStr:
return "?Str";
case T::OptDbl:
return "?Dbl";
case T::OptRes:
return "?Res";
case T::OptObj:
return "?Obj";
case T::Null:
return "Null";
case T::Cell:
return "Cell";
case T::Ref:
return "Ref";
case T::InitUnc:
return "InitUnc";
case T::Unc:
return "Unc";
case T::InitCell:
return "InitCell";
case T::InitGen:
return "InitGen";
case T::Gen:
return "Gen";
case T::Uninit:
return "Uninit";
case T::InitNull:
return "InitNull";
case T::Bool:
return "Bool";
case T::Int:
return "Int";
case T::Dbl:
return "Dbl";
case T::Res:
return "Res";
case T::SStr:
return "SStr";
case T::Str:
return "Str";
case T::Obj:
return "Obj";
case T::OptSArr:
case T::OptArr:
case T::SArr:
case T::Arr:
{
auto ret = std::string{};
if (tag == T::OptArr || tag == T::OptSArr) {
ret += '?';
}
if (tag == T::SArr || tag == T::OptSArr) {
ret += 'S';
}
ret += "Arr";
if (auto const ar = rat.array()) {
folly::format(&ret, "{}", show(*ar));
}
return ret;
}
break;
case T::OptSubObj:
case T::OptExactObj:
case T::SubObj:
case T::ExactObj:
{
auto ret = std::string{};
if (tag == T::OptSubObj || tag == T::OptExactObj) {
ret += '?';
}
ret += "Obj";
if (tag == T::OptSubObj || tag == T::SubObj) {
ret += "<";
}
ret += '=';
ret += rat.clsName()->data();
return ret;
}
}
not_reached();
}
示例10: tvMatchesRepoAuthType
bool tvMatchesRepoAuthType(TypedValue tv, RepoAuthType ty) {
assert(tvIsPlausible(tv));
bool const initNull = tv.m_type == KindOfNull;
using T = RepoAuthType::Tag;
switch (ty.tag()) {
case T::Uninit:
return tv.m_type == KindOfUninit;
case T::InitNull:
return initNull;
case T::OptBool:
if (initNull) return true;
// fallthrough
case T::Bool:
return tv.m_type == KindOfBoolean;
case T::OptInt:
if (initNull) return true;
// fallthrough
case T::Int:
return tv.m_type == KindOfInt64;
case T::OptDbl:
if (initNull) return true;
// fallthrough
case T::Dbl:
return tv.m_type == KindOfDouble;
case T::OptRes:
if (initNull) return true;
// fallthrough
case T::Res:
return tv.m_type == KindOfResource;
case T::OptObj:
if (initNull) return true;
// fallthrough
case T::Obj:
return tv.m_type == KindOfObject;
case T::OptSStr:
if (initNull) return true;
// fallthrough
case T::SStr:
return tv.m_type == KindOfStaticString ||
(tv.m_type == KindOfString && tv.m_data.pstr->isStatic());
case T::OptStr:
if (initNull) return true;
// fallthrough
case T::Str:
return IS_STRING_TYPE(tv.m_type);
case T::OptSArr:
if (initNull) return true;
// fallthrough
case T::SArr:
if (tv.m_type != KindOfArray || !tv.m_data.parr->isStatic()) {
return false;
}
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::OptArr:
if (initNull) return true;
// fallthrough
case T::Arr:
if (tv.m_type != KindOfArray) return false;
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::Null:
return initNull || tv.m_type == KindOfUninit;
case T::OptSubObj:
if (initNull) return true;
// fallthrough
case T::SubObj:
{
auto const cls = Unit::lookupClass(ty.clsName());
if (!cls) return false;
return tv.m_type == KindOfObject &&
tv.m_data.pobj->getVMClass()->classof(cls);
}
case T::OptExactObj:
if (initNull) return true;
// fallthrough
case T::ExactObj:
{
auto const cls = Unit::lookupClass(ty.clsName());
if (!cls) return false;
return tv.m_type == KindOfObject && tv.m_data.pobj->getVMClass() == cls;
}
case T::InitUnc:
if (tv.m_type == KindOfUninit) return false;
// fallthrough
//.........这里部分代码省略.........
示例11: show
std::string show(RepoAuthType rat) {
auto const tag = rat.tag();
using T = RepoAuthType::Tag;
switch (tag) {
case T::OptBool: return "?Bool";
case T::OptInt: return "?Int";
case T::OptSStr: return "?SStr";
case T::OptStr: return "?Str";
case T::OptDbl: return "?Dbl";
case T::OptRes: return "?Res";
case T::OptObj: return "?Obj";
case T::OptUncArrKey: return "?UncArrKey";
case T::OptArrKey: return "?ArrKey";
case T::Null: return "Null";
case T::Cell: return "Cell";
case T::Ref: return "Ref";
case T::InitUnc: return "InitUnc";
case T::Unc: return "Unc";
case T::UncArrKey:return "UncArrKey";
case T::ArrKey: return "ArrKey";
case T::InitCell: return "InitCell";
case T::InitGen: return "InitGen";
case T::Gen: return "Gen";
case T::Uninit: return "Uninit";
case T::InitNull: return "InitNull";
case T::Bool: return "Bool";
case T::Int: return "Int";
case T::Dbl: return "Dbl";
case T::Res: return "Res";
case T::SStr: return "SStr";
case T::Str: return "Str";
case T::Obj: return "Obj";
case T::OptSArr:
case T::OptArr:
case T::SArr:
case T::Arr:
case T::OptSVArr:
case T::OptVArr:
case T::SVArr:
case T::VArr:
case T::OptSDArr:
case T::OptDArr:
case T::SDArr:
case T::DArr:
{
auto ret = std::string{};
if (tag == T::OptArr || tag == T::OptSArr ||
tag == T::OptVArr || tag == T::OptSVArr ||
tag == T::OptDArr || tag == T::OptSDArr) {
ret += '?';
}
if (tag == T::SArr || tag == T::OptSArr ||
tag == T::SVArr || tag == T::OptSVArr ||
tag == T::SDArr || tag == T::OptSDArr) {
ret += 'S';
}
if (tag == T::OptArr || tag == T::Arr ||
tag == T::OptSArr || tag == T::SArr) {
ret += "Arr";
} else if (tag == T::OptVArr || tag == T::VArr ||
tag == T::OptSVArr || tag == T::SVArr) {
ret += "VArr";
} else {
ret += "DArr";
}
if (rat.hasArrData()) folly::format(&ret, "{}", show(*rat.array()));
return ret;
}
break;
case T::SVec: return "SVec";
case T::Vec: return "Vec";
case T::OptSVec: return "?SVec";
case T::OptVec: return "?Vec";
case T::SDict: return "SDict";
case T::Dict: return "Dict";
case T::OptSDict: return "?SDict";
case T::OptDict: return "?Dict";
case T::SKeyset: return "SKeyset";
case T::Keyset: return "Keyset";
case T::OptSKeyset: return "?SKeyset";
case T::OptKeyset: return "?Keyset";
case T::OptSubObj:
case T::OptExactObj:
case T::SubObj:
case T::ExactObj:
{
auto ret = std::string{};
if (tag == T::OptSubObj || tag == T::OptExactObj) {
ret += '?';
}
ret += "Obj";
if (tag == T::OptSubObj || tag == T::SubObj) {
ret += "<";
}
ret += '=';
//.........这里部分代码省略.........
示例12: tvMatchesRepoAuthType
bool tvMatchesRepoAuthType(TypedValue tv, RepoAuthType ty) {
assert(tvIsPlausible(tv));
bool const initNull = tv.m_type == KindOfNull;
using T = RepoAuthType::Tag;
switch (ty.tag()) {
case T::Uninit: return tv.m_type == KindOfUninit;
case T::InitNull: return initNull;
case T::OptBool: if (initNull) return true;
// fallthrough
case T::Bool: return tv.m_type == KindOfBoolean;
case T::OptInt: if (initNull) return true;
// fallthrough
case T::Int: return tv.m_type == KindOfInt64;
case T::OptDbl: if (initNull) return true;
// fallthrough
case T::Dbl: return tv.m_type == KindOfDouble;
case T::OptRes: if (initNull) return true;
// fallthrough
case T::Res: return tv.m_type == KindOfResource;
case T::OptObj: if (initNull) return true;
// fallthrough
case T::Obj: return tv.m_type == KindOfObject;
case T::OptSStr:
if (initNull) return true;
// fallthrough
case T::SStr:
return isStringType(tv.m_type) && tv.m_data.pstr->isStatic();
case T::OptStr:
if (initNull) return true;
// fallthrough
case T::Str:
return isStringType(tv.m_type);
case T::OptSArr:
if (initNull) return true;
// fallthrough
case T::SArr:
if (!isArrayType(tv.m_type) || !tv.m_data.parr->isStatic()) {
return false;
}
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::OptArr:
if (initNull) return true;
// fallthrough
case T::Arr:
if (!isArrayType(tv.m_type)) return false;
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::OptSVArr:
if (initNull) return true;
// fallthrough
case T::SVArr:
if (!isArrayType(tv.m_type) ||
!tv.m_data.parr->isStatic() ||
!tv.m_data.parr->isVArray()) {
return false;
}
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::OptVArr:
if (initNull) return true;
// fallthrough
case T::VArr:
if (!isArrayType(tv.m_type) || !tv.m_data.parr->isVArray()) return false;
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::OptSDArr:
if (initNull) return true;
// fallthrough
case T::SDArr:
if (!isArrayType(tv.m_type) ||
!tv.m_data.parr->isStatic() ||
!tv.m_data.parr->isDArray()) {
return false;
}
if (auto const arr = ty.array()) {
if (!tvMatchesArrayType(tv, arr)) return false;
}
return true;
case T::OptDArr:
if (initNull) return true;
//.........这里部分代码省略.........
示例13: arrayId
bool RepoAuthType::operator==(RepoAuthType o) const {
using T = Tag;
if (tag() != o.tag()) return false;
switch (tag()) {
case T::OptBool:
case T::OptInt:
case T::OptSStr:
case T::OptStr:
case T::OptDbl:
case T::OptRes:
case T::OptObj:
case T::OptArrKey:
case T::OptUncArrKey:
case T::Null:
case T::Cell:
case T::Ref:
case T::InitUnc:
case T::Unc:
case T::ArrKey:
case T::UncArrKey:
case T::InitCell:
case T::InitGen:
case T::Gen:
case T::Uninit:
case T::InitNull:
case T::Bool:
case T::Int:
case T::Dbl:
case T::Res:
case T::SStr:
case T::Str:
case T::Obj:
return true;
case T::SVec:
case T::Vec:
case T::OptSVec:
case T::OptVec:
case T::SDict:
case T::Dict:
case T::OptSDict:
case T::OptDict:
case T::SKeyset:
case T::Keyset:
case T::OptSKeyset:
case T::OptKeyset:
return true;
case T::OptSArr:
case T::OptArr:
case T::OptSVArr:
case T::OptVArr:
case T::OptSDArr:
case T::OptDArr:
// Can't currently have array() info.
return true;
case T::SArr:
case T::Arr:
case T::SVArr:
case T::VArr:
case T::SDArr:
case T::DArr:
// array id equals to either kInvalidArrayId for null array info, or a
// regular id. in each case, we just need to compare their id.
return arrayId() == o.arrayId();
case T::SubObj:
case T::ExactObj:
case T::OptSubObj:
case T::OptExactObj:
return clsName() == o.clsName();
}
not_reached();
}