// // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // Type.cpp -- // // Author : Aaron B. Moss // Created On : Mon May 13 15:00:00 2019 // Last Modified By : Aaron B. Moss // Last Modified On : Mon May 13 15:00:00 2019 // Update Count : 1 // #include "Type.hpp" #include #include // for move #include #include "Decl.hpp" #include "Init.hpp" #include "InitTweak/InitTweak.h" // for getPointerBase #include "Tuples/Tuples.h" // for isTtype namespace ast { const Type * Type::getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; } const Type * Type::stripDeclarator() { const Type * t; const Type * a; for ( t = this; (a = InitTweak::getPointerBase( t )); t = a ); return t; } const Type * Type::stripReferences() { const Type * t; const ReferenceType * r; for ( t = this; (r = dynamic_cast(t) ); t = r->base ); return t; } // --- BasicType const char *BasicType::typeNames[] = { "_Bool", "char", "signed char", "unsigned char", "signed short int", "unsigned short int", "signed int", "unsigned int", "signed long int", "unsigned long int", "signed long long int", "unsigned long long int", "__int128", "unsigned __int128", "_Float16", "_Float16 _Complex", "_Float32", "_Float32 _Complex", "float", "float _Complex", "_Float32x", "_Float32x _Complex", "_Float64", "_Float64 _Complex", "double", "double _Complex", "_Float64x", "_Float64x _Complex", "__float80", "_Float128", "_Float128 _Complex", "__float128", "long double", "long double _Complex", "_Float128x", "_Float128x _Complex", }; static_assert( sizeof(BasicType::typeNames)/sizeof(BasicType::typeNames[0]) == BasicType::NUMBER_OF_BASIC_TYPES, "Each basic type name should have a corresponding kind enum value" ); // --- FunctionType namespace { bool containsTtype( const std::vector> & l ) { if ( ! l.empty() ) { return Tuples::isTtype( l.back()->get_type() ); } return false; } } bool FunctionType::isTtype() const { return containsTtype( returns ) || containsTtype( params ); } // --- ReferenceToType std::vector> ReferenceToType::lookup( const std::string& name ) const { assertf( aggr(), "Must have aggregate to perform lookup" ); std::vector> found; for ( const Decl * decl : aggr()->members ) { if ( decl->name == name ) { found.emplace_back( decl ); } } return found; } // --- StructInstType StructInstType::StructInstType( const StructDecl * b, CV::Qualifiers q, std::vector>&& as ) : ReferenceToType( b->name, q, std::move(as) ), base( b ) {} bool StructInstType::isComplete() const { return base ? base->body : false; } // --- UnionInstType UnionInstType::UnionInstType( const UnionDecl * b, CV::Qualifiers q, std::vector>&& as ) : ReferenceToType( b->name, q, std::move(as) ), base( b ) {} bool UnionInstType::isComplete() const { return base ? base->body : false; } // --- EnumInstType EnumInstType::EnumInstType( const EnumDecl * b, CV::Qualifiers q, std::vector>&& as ) : ReferenceToType( b->name, q, std::move(as) ), base( b ) {} bool EnumInstType::isComplete() const { return base ? base->body : false; } // --- TraitInstType TraitInstType::TraitInstType( const TraitDecl * b, CV::Qualifiers q, std::vector>&& as ) : ReferenceToType( b->name, q, std::move(as) ), base( b ) {} // --- TypeInstType void TypeInstType::set_base( const TypeDecl * b ) { base = b; kind = b->kind; } bool TypeInstType::isComplete() const { return base->sized; } // --- TupleType TupleType::TupleType( std::vector> && ts, CV::Qualifiers q ) : Type( q ), types( std::move(ts) ), members() { // This constructor is awkward. `TupleType` needs to contain objects so that members can be // named, but members without initializer nodes end up getting constructors, which breaks // things. This happens because the object decls have to be visited so that their types are // kept in sync with the types listed here. Ultimately, the types listed here should perhaps // be eliminated and replaced with a list-view over members. The temporary solution is to // make a `ListInit` with `maybeConstructed = false`, so when the object is visited it is not // constructed. Potential better solutions include: // a) Separate `TupleType` from its declarations, into `TupleDecl` and `Tuple{Inst?}Type`, // similar to the aggregate types. // b) Separate initializer nodes better, e.g. add a `MaybeConstructed` node that is replaced // by `genInit`, rather than the current boolean flag. members.reserve( types.size() ); for ( const Type * ty : types ) { members.emplace_back( new ObjectDecl{ CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, MaybeConstruct ), Storage::Classes{}, Linkage::Cforall } ); } } } // Local Variables: // // tab-width: 4 // // mode: c++ // // compile-command: "make install" // // End: //