static IntentTag constIntentForType(Type* t) { if (isSyncType(t) || isRecordWrappedType(t) || // domain, array, or distribution isRecord(t) || // may eventually want to decide based on size is_string_type(t)) { return INTENT_CONST_REF; } else if (is_bool_type(t) || is_int_type(t) || is_uint_type(t) || is_real_type(t) || is_imag_type(t) || is_complex_type(t) || is_enum_type(t) || isClass(t) || isUnion(t) || isAtomicType(t) || t == dtOpaque || t == dtTaskID || t == dtFile || t == dtTaskList || t == dtNil || t == dtStringC || t == dtStringCopy || t->symbol->hasFlag(FLAG_EXTERN)) { return INTENT_CONST_IN; } INT_FATAL(t, "Unhandled type in constIntentForType()"); return INTENT_CONST; }
IntentTag blankIntentForType(Type* t) { if (isSyncType(t) || isAtomicType(t) || t->symbol->hasFlag(FLAG_ARRAY)) { return INTENT_REF; } else if (is_bool_type(t) || is_int_type(t) || is_uint_type(t) || is_real_type(t) || is_imag_type(t) || is_complex_type(t) || is_enum_type(t) || is_string_type(t) || t == dtStringC || t == dtStringCopy || isClass(t) || isRecord(t) || isUnion(t) || t == dtTaskID || t == dtFile || t == dtTaskList || t == dtNil || t == dtOpaque || t->symbol->hasFlag(FLAG_DOMAIN) || t->symbol->hasFlag(FLAG_DISTRIBUTION) || t->symbol->hasFlag(FLAG_EXTERN)) { return constIntentForType(t); } INT_FATAL(t, "Unhandled type in blankIntentForType()"); return INTENT_BLANK; }
bool StructDef::printStructureStreamHelper(std::ostream& out) const { if (isUnion()) out << "union "; else out << "struct "; if (tag) out << "__cpustruct_" << *tag << " "; out << "{\n"; for (int j=0; j < nComponents; j++) { if(!components[j]->printStructureStreamInternals(out)) return false; Decl *decl = components[j]->next; while (decl != NULL) { out << ", "; if(!decl->printStructureStreamInternals(out)) return false; decl = decl->next; } out << ";\n"; } out << "}\n"; return true; }
bool isSubtypeOf(const Type& a, const Type& b) { // make sure they are both in the same environment auto& environment = a.getTypeEnvironment(); assert(environment.isType(a) && environment.isType(b)); // first check - a type is a sub-type of itself if (a == b) return true; // check for predefined types if (b == environment.getNumberType()) return isNumberType(a); if (b == environment.getSymbolType()) return isSymbolType(a); // check primitive type chains if (isA<PrimitiveType>(a)) { if (isSubtypeOf(as<PrimitiveType>(a).getBaseType(), b)){ return true; } } // next - if b is a union type if (isUnion(b)) { return isSubType(a, as<UnionType>(b)); } // done return false; }
// o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o+o void StructDef::print(std::ostream& out, Symbol *name, int level) const { if (isUnion()) out << "union "; else out << "struct "; if (tag) out << *tag << " "; out << "{\n"; for (int j=0; j < nComponents; j++) { indent(out,level+1); components[j]->print(out,true,level+1); Decl *decl = components[j]->next; while (decl != NULL) { out << ", "; decl->print(out,false,level+1); decl = decl->next; } out << ";\n"; } indent(out,level); out << "}"; if (name) out << " " << *name; }
string IndexedStructType::buildTypeSignature(const string &pointerSig) { string sig; if (m_isArgStack) { sig += "__argstack "; } else { if (m_explicitAlign > 0) { sig += "__align("; sig += CUtil::toString(m_explicitAlign); sig += ") "; } if (m_pack != 8) { sig += "__pack("; sig += CUtil::toString(m_pack); sig += ") "; } } sig += isUnion() ? "_union {" : "_struct {"; //sig += "struct {"; string sep; for (size_t i = 0; i < m_itemTypes.size(); i ++) { sig += sep + m_itemTypes[i]->getTypeSignature(); sep = ", "; } sig += "}"; sig += pointerSig; return sig; }
TypeSet getGreatestCommonSubtypes(const Type& a, const Type& b) { // make sure they are in the same type environment assert(a.getTypeEnvironment().isType(a) && a.getTypeEnvironment().isType(b)); // if they are equal it is easy if (a == b) { return TypeSet(a); } // equally simple - check whether one is a sub-type of the other if (isSubtypeOf(a,b)) { return TypeSet(a); } if (isSubtypeOf(b,a)) { return TypeSet(b); } // last option: if both are unions with common sub-types TypeSet res; if (isUnion(a) && isUnion(b)) { // collect common sub-types of union types struct collector : public TypeVisitor<void> { const Type& b; TypeSet& res; collector(const Type& b, TypeSet& res) : b(b), res(res) {} void visit(const Type& type) const { if (isSubtypeOf(type, b)) { res.insert(type); } else { TypeVisitor<void>::visit(type); } } void visitUnionType(const UnionType& type) const { for(const auto& cur : type.getElementTypes()) visit(*cur); } }; // collect all common sub-types collector(b,res).visit(a); } // otherwise there is no common super type return res; }
void ProTypeUnionAccessCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; Finder->addMatcher( memberExpr(hasObjectExpression(hasType(recordDecl(isUnion())))) .bind("expr"), this); }
bool argMustUseCPtr(Type* type) { if (isUnion(type)) return true; if (isRecord(type) && // TODO: why are ref types being created with AGGREGATE_RECORD? !type->symbol->hasFlag(FLAG_REF) && !type->symbol->hasEitherFlag(FLAG_WIDE_REF, FLAG_WIDE_CLASS)) return true; return false; }
void RedundantMemberInitCheck::registerMatchers(MatchFinder *Finder) { auto Construct = cxxConstructExpr( hasDeclaration(cxxConstructorDecl(hasParent( cxxRecordDecl(unless(isTriviallyDefaultConstructible())))))) .bind("construct"); Finder->addMatcher( cxxConstructorDecl( unless(isDelegatingConstructor()), ofClass(unless( anyOf(isUnion(), ast_matchers::isTemplateInstantiation()))), forEachConstructorInitializer( cxxCtorInitializer(isWritten(), withInitializer(ignoringImplicit(Construct)), unless(forField(hasType(isConstQualified())))) .bind("init"))), this); }
bool UserDefinedXQType::isSuperTypeOf( const TypeManager* tm, const XQType* subType, const QueryLoc& loc) const { if (isUnion() && isGenAtomicAny() && subType->isAtomicAny()) { std::vector<xqtref_t>::const_iterator ite = m_unionItemTypes.begin(); std::vector<xqtref_t>::const_iterator end = m_unionItemTypes.end(); for (; ite != end; ++ite) { if (TypeOps::is_subtype(tm, *subType, *(*ite), loc)) return true; } return false; } if (subType->type_kind() != XQType::USER_DEFINED_KIND) return false; const UserDefinedXQType* subtype = static_cast<const UserDefinedXQType*>(subType); do { if (getUDTKind() == subtype->getUDTKind() && getQName()->equals(subtype->getQName())) { return true; } subType = subtype->getBaseType().getp(); if (subType->type_kind() != XQType::USER_DEFINED_KIND) return false; subtype = static_cast<const UserDefinedXQType*>(subType); } while (subtype != NULL); return false; }
IntentTag blankIntentForType(Type* t) { IntentTag retval = INTENT_BLANK; if (isSyncType(t) || isAtomicType(t) || t->symbol->hasFlag(FLAG_DEFAULT_INTENT_IS_REF) || t->symbol->hasFlag(FLAG_ARRAY)) { retval = INTENT_REF; } else if (is_bool_type(t) || is_int_type(t) || is_uint_type(t) || is_real_type(t) || is_imag_type(t) || is_complex_type(t) || is_enum_type(t) || t == dtStringC || t == dtStringCopy || t == dtCVoidPtr || t == dtCFnPtr || isClass(t) || isRecord(t) || isUnion(t) || t == dtTaskID || t == dtFile || t == dtNil || t == dtOpaque || t->symbol->hasFlag(FLAG_DOMAIN) || t->symbol->hasFlag(FLAG_DISTRIBUTION) || t->symbol->hasFlag(FLAG_EXTERN)) { retval = constIntentForType(t); } else { INT_FATAL(t, "Unhandled type in blankIntentForType()"); } return retval; }
void buildDefaultFunctions() { build_chpl_entry_points(); SET_LINENO(rootModule); // todo - remove reset_ast_loc() calls below? std::vector<BaseAST*> asts; collect_asts(rootModule, asts); for_vector(BaseAST, ast, asts) { if (TypeSymbol* type = toTypeSymbol(ast)) { // Here we build default functions that are always generated (even when // the type symbol has FLAG_NO_DEFAULT_FUNCTIONS attached). if (AggregateType* ct = toAggregateType(type->type)) { buildFieldAccessorFunctions(ct); if (!ct->symbol->hasFlag(FLAG_REF)) buildDefaultDestructor(ct); // Classes should use the nil:<type> _defaultOf method unless they // do not inherit from object. For those types and records, call // we need a more complicated _defaultOf method generated by the // compiler if (!ct->isClass() || ct->symbol->hasFlag(FLAG_NO_OBJECT)) build_record_init_function(ct); } if (type->hasFlag(FLAG_NO_DEFAULT_FUNCTIONS)) continue; // Here we build default functions that respect the "no default // functions" pragma. if (AggregateType* ct = toAggregateType(type->type)) { buildDefaultReadWriteFunctions(ct); if (isRecord(ct)) { if (!isRecordWrappedType(ct)) { build_record_equality_function(ct); build_record_inequality_function(ct); } build_record_assignment_function(ct); build_record_cast_function(ct); build_record_copy_function(ct); build_record_hash_function(ct); } if (isUnion(ct)) build_union_assignment_function(ct); } else if (EnumType* et = toEnumType(type->type)) { //buildDefaultReadFunction(et); buildStringCastFunction(et); build_enum_cast_function(et); build_enum_assignment_function(et); build_enum_first_function(et); build_enum_enumerate_function(et); } else { // The type is a simple type. // Other simple types are handled explicitly in the module code. // But to avoid putting a catch-all case there to implement assignment // for extern types that are simple (as far as we can tell), we build // definitions for those assignments here. if (type->hasFlag(FLAG_EXTERN)) { build_extern_init_function(type->type); build_extern_assignment_function(type->type); } } } } }