Changes in / [1e97287:89c2f7c9]
- Location:
- src
- Files:
-
- 3 added
- 13 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Decl.hpp
r1e97287 r89c2f7c9 26 26 #include "ParseNode.hpp" 27 27 #include "StorageClasses.hpp" 28 #include "Type .hpp" // for Type, ptr<Type>28 #include "TypeVar.hpp" 29 29 #include "Visitor.hpp" 30 30 #include "Parser/ParseNode.h" // for DeclarationNode::Aggregate … … 166 166 class TypeDecl final : public NamedTypeDecl { 167 167 public: 168 /// type variable variants. otype is a specialized dtype 169 enum Kind { Dtype, Ftype, Ttype, NUMBER_OF_KINDS } kind; 168 TypeVar::Kind kind; 170 169 bool sized; 171 170 ptr<Type> init; … … 173 172 /// Data extracted from a type decl 174 173 struct Data { 175 Kind kind;174 TypeVar::Kind kind; 176 175 bool isComplete; 177 176 178 Data() : kind( ( Kind)-1 ), isComplete( false ) {}177 Data() : kind( (TypeVar::Kind)-1 ), isComplete( false ) {} 179 178 Data( TypeDecl* d ) : kind( d->kind ), isComplete( d->sized ) {} 180 Data( Kind k, bool c ) : kind( k ), isComplete( c ) {}179 Data( TypeVar::Kind k, bool c ) : kind( k ), isComplete( c ) {} 181 180 Data( const Data& d1, const Data& d2 ) 182 181 : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {} … … 189 188 190 189 TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b, 191 Kind k, bool s, Type* i = nullptr ) 192 : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == Ttype || s ), init( i ) {} 190 TypeVar::Kind k, bool s, Type* i = nullptr ) 191 : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeVar::Ttype || s ), 192 init( i ) {} 193 193 194 194 std::string typeString() const override; 195 195 /// Produces a name for generated code 196 196 std::string genTypeString() const; 197 198 /// convenience accessor to match Type::isComplete() 199 bool isComplete() { return sized; } 197 200 198 201 const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Expr.hpp
r1e97287 r89c2f7c9 23 23 #include "Fwd.hpp" // for UniqueId 24 24 #include "ParseNode.hpp" 25 #include " Type.hpp" // for ptr<Type>25 #include "Visitor.hpp" 26 26 27 27 namespace ast { … … 117 117 bool extension = false; 118 118 119 Expr(const CodeLocation & loc ) : ParseNode( loc ), result(), env(), inferred() {}120 121 Expr * set_extension( bool ex ) { extension = ex; return this; }122 123 const Expr * accept( Visitor& v ) const override = 0;119 Expr(const CodeLocation & loc ) : ParseNode( loc ), result(), env(), inferred() {} 120 121 Expr * set_extension( bool ex ) { extension = ex; return this; } 122 123 virtual const Expr * accept( Visitor & v ) const override = 0; 124 124 private: 125 125 Expr * clone() const override = 0; 126 }; 127 128 /// A type used as an expression (e.g. a type generator parameter) 129 class TypeExpr final : public Expr { 130 public: 131 ptr<Type> type; 132 133 TypeExpr( const CodeLocation & loc, const Type * t ) : Expr(loc), type(t) {} 134 135 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } 136 private: 137 TypeExpr * clone() const override { return new TypeExpr{ *this }; } 126 138 }; 127 139 -
src/AST/FunctionSpec.hpp
r1e97287 r89c2f7c9 43 43 }; 44 44 45 constexpr spec_flags( unsigned int val ) : val(val) {}45 constexpr spec_flags( unsigned int val = 0 ) : val(val) {} 46 46 }; 47 47 -
src/AST/Fwd.hpp
r1e97287 r89c2f7c9 116 116 class TupleType; 117 117 class TypeofType; 118 class AttrType;119 118 class VarArgsType; 120 119 class ZeroType; … … 329 328 inline void increment( const class TypeofType *, Node::ref_type ); 330 329 inline void decrement( const class TypeofType *, Node::ref_type ); 331 inline void increment( const class AttrType *, Node::ref_type );332 inline void decrement( const class AttrType *, Node::ref_type );333 330 inline void increment( const class VarArgsType *, Node::ref_type ); 334 331 inline void decrement( const class VarArgsType *, Node::ref_type ); -
src/AST/Init.hpp
r1e97287 r89c2f7c9 42 42 }; 43 43 44 /// Flag for whether to construct from initialzier 45 enum ConstructFlag { DoConstruct, MaybeConstruct }; 46 44 47 /// Object initializer base class 45 48 class Init : public ParseNode { 46 49 public: 47 boolmaybeConstructed;50 ConstructFlag maybeConstructed; 48 51 49 Init( const CodeLocation& loc, boolmc ) : ParseNode( loc ), maybeConstructed( mc ) {}52 Init( const CodeLocation& loc, ConstructFlag mc ) : ParseNode( loc ), maybeConstructed( mc ) {} 50 53 51 54 const Init * accept( Visitor& v ) const override = 0; … … 60 63 ptr<Expr> value; 61 64 62 SingleInit( const CodeLocation& loc, Expr* val, bool mc = false)65 SingleInit( const CodeLocation& loc, Expr* val, ConstructFlag mc = DoConstruct ) 63 66 : Init( loc, mc ), value( val ) {} 64 67 … … 82 85 83 86 ListInit( const CodeLocation& loc, std::vector<ptr<Init>>&& is, 84 std::vector<ptr<Designation>>&& ds = {}, bool mc = false);87 std::vector<ptr<Designation>>&& ds = {}, ConstructFlag mc = DoConstruct ); 85 88 86 89 using iterator = std::vector<ptr<Init>>::iterator; … … 112 115 113 116 ConstructorInit( const CodeLocation& loc, Stmt* ctor, Stmt* dtor, Init* init ) 114 : Init( loc, true), ctor( ctor ), dtor( dtor ), init( init ) {}117 : Init( loc, DoConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {} 115 118 116 119 const Init * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Node.hpp
r1e97287 r89c2f7c9 94 94 std::ostream& operator<< ( std::ostream& out, const Node* node ); 95 95 96 // Base class for the smart pointer types97 // should never really be used.98 template< typename node_t, enum Node::ref_type ref_t >96 /// Base class for the smart pointer types 97 /// should never really be used. 98 template< typename node_t, enum Node::ref_type ref_t > 99 99 class ptr_base { 100 100 public: 101 101 ptr_base() : node(nullptr) {} 102 ptr_base( const node_t * n ) : node(n) { if( !node ) increment(node, ref_t); }102 ptr_base( const node_t * n ) : node(n) { if( node ) increment(node, ref_t); } 103 103 ~ptr_base() { if( node ) decrement(node, ref_t); } 104 104 105 template< enum 105 template< enum Node::ref_type o_ref_t > 106 106 ptr_base( const ptr_base<node_t, o_ref_t> & o ) : node(o.node) { 107 if( !node ) return; 108 increment(node, ref_t); 107 if( node ) increment(node, ref_t); 109 108 } 110 109 111 template< enum 110 template< enum Node::ref_type o_ref_t > 112 111 ptr_base( ptr_base<node_t, o_ref_t> && o ) : node(o.node) { 113 112 if( node ) increment(node, ref_t); … … 120 119 } 121 120 122 template< enum 121 template< enum Node::ref_type o_ref_t > 123 122 ptr_base & operator=( const ptr_base<node_t, o_ref_t> & o ) { 124 123 assign(o.node); … … 126 125 } 127 126 128 template< enum 127 template< enum Node::ref_type o_ref_t > 129 128 ptr_base & operator=( ptr_base<node_t, o_ref_t> && o ) { 130 if(o.node == node) return *this;131 129 assign(o.node); 132 130 return *this; … … 137 135 const node_t & operator* () const { return *node; } 138 136 explicit operator bool() const { return node; } 139 operator const node_t * () const { return node; }137 operator const node_t * () const { return node; } 140 138 141 139 template<typename o_node_t> 142 const o_node_t * as() const { return dynamic_cast< o_node_t *>(node); }140 const o_node_t * as() const { return dynamic_cast<const o_node_t *>(node); } 143 141 144 142 using ptr = const node_t *; 145 143 146 144 private: 147 void assign( const node_t * other ) {145 void assign( const node_t * other ) { 148 146 if( other ) increment(other, ref_t); 149 147 if( node ) decrement(node , ref_t); -
src/AST/Pass.hpp
r1e97287 r89c2f7c9 167 167 const ast::Type * visit( const ast::TupleType * ) override final; 168 168 const ast::Type * visit( const ast::TypeofType * ) override final; 169 const ast::Type * visit( const ast::AttrType * ) override final;170 169 const ast::Type * visit( const ast::VarArgsType * ) override final; 171 170 const ast::Type * visit( const ast::ZeroType * ) override final; -
src/AST/StorageClasses.hpp
r1e97287 r89c2f7c9 47 47 }; 48 48 49 constexpr class_flags( unsigned int val ) : val(val) {}49 constexpr class_flags( unsigned int val = 0 ) : val(val) {} 50 50 }; 51 51 -
src/AST/Type.hpp
r1e97287 r89c2f7c9 16 16 #pragma once 17 17 18 #include "Node.hpp" 18 #include <cassert> 19 #include <cstddef> // for nullptr_t 20 #include <cstdint> // for uintptr_t 21 #include <utility> // for move 22 #include <vector> 23 24 #include "CVQualifiers.hpp" 25 #include "Decl.hpp" 26 #include "Fwd.hpp" 27 #include "Node.hpp" // for Node, ptr 28 #include "TypeVar.hpp" 29 #include "Visitor.hpp" 19 30 20 31 namespace ast { 21 32 22 33 class Type : public Node { 23 public: 24 virtual const Type * accept( Visitor & v) const = 0; 25 }; 26 27 34 CV::Qualifiers tq; 35 public: 36 Type( CV::Qualifiers q = {} ) : tq(q) {} 37 38 CV::Qualifiers qualifiers() const { return tq; } 39 bool is_const() const { return tq.is_const; } 40 bool is_volatile() const { return tq.is_volatile; } 41 bool is_restrict() const { return tq.is_restrict; } 42 bool is_lvalue() const { return tq.is_lvalue; } 43 bool is_mutex() const { return tq.is_mutex; } 44 bool is_atomic() const { return tq.is_atomic; } 45 46 void set_qualifiers( CV::Qualifiers q ) { tq = q; } 47 void set_const( bool v ) { tq.is_const = v; } 48 void set_restrict( bool v ) { tq.is_restrict = v; } 49 void set_lvalue( bool v ) { tq.is_lvalue = v; } 50 void set_mutex( bool v ) { tq.is_mutex = v; } 51 void set_atomic( bool v ) { tq.is_atomic = v; } 52 53 /// How many elemental types are represented by this type 54 virtual unsigned size() const { return 1; } 55 /// Is this a void type? 56 virtual bool isVoid() const { return size() == 0; } 57 /// Get the i'th component of this type 58 virtual const Type * getComponent( unsigned i ); 59 60 /// type without outer pointers and arrays 61 const Type * stripDeclarator(); 62 /// type without outer references 63 const Type * stripReferences(); 64 /// number of reference occuring consecutively on the outermost layer of this type 65 /// (i.e. do not count references nested within other types) 66 virtual unsigned referenceDepth() const { return 0; } 67 /// true iff type is complete type (i.e. compiler knows the size, alignment, and layout) 68 virtual bool isComplete() const { return true; } 69 70 virtual const Type * accept( Visitor & v ) const override = 0; 71 private: 72 virtual Type * clone() const override = 0; 73 }; 74 75 /// `void` 76 class VoidType final : public Type { 77 public: 78 VoidType( CV::Qualifiers q = {} ) : Type( q ) {} 79 80 unsigned size() const override { return 0; } 81 bool isVoid() const override { return true; } 82 bool isComplete() const override { return false; } 83 84 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 85 private: 86 VoidType * clone() const override { return new VoidType{ *this }; } 87 }; 88 89 /// Built-in arithmetic type 90 class BasicType final : public Type { 91 public: 92 // GENERATED START, DO NOT EDIT 93 // GENERATED BY BasicTypes-gen.cc 94 enum Kind { 95 Bool, 96 Char, 97 SignedChar, 98 UnsignedChar, 99 ShortSignedInt, 100 ShortUnsignedInt, 101 SignedInt, 102 UnsignedInt, 103 LongSignedInt, 104 LongUnsignedInt, 105 LongLongSignedInt, 106 LongLongUnsignedInt, 107 SignedInt128, 108 UnsignedInt128, 109 uFloat16, 110 uFloat16Complex, 111 uFloat32, 112 uFloat32Complex, 113 Float, 114 FloatComplex, 115 uFloat32x, 116 uFloat32xComplex, 117 uFloat64, 118 uFloat64Complex, 119 Double, 120 DoubleComplex, 121 uFloat64x, 122 uFloat64xComplex, 123 uuFloat80, 124 uFloat128, 125 uFloat128Complex, 126 uuFloat128, 127 LongDouble, 128 LongDoubleComplex, 129 uFloat128x, 130 uFloat128xComplex, 131 NUMBER_OF_BASIC_TYPES 132 } kind; 133 // GENERATED END 134 135 /// xxx -- MAX_INTEGER_TYPE should probably be in BasicTypes-gen.cc, rather than hardcoded here 136 enum { MAX_INTEGER_TYPE = UnsignedInt128 }; 137 138 /// string names of basic types; generated to match with Kind 139 static const char *typeNames[]; 140 141 BasicType( Kind k, CV::Qualifiers q = {} ) : Type(q), kind(k) {} 142 143 /// Check if this type represents an integer type 144 bool isInteger() const { return (unsigned)kind <= (unsigned)MAX_INTEGER_TYPE; } 145 146 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 147 private: 148 BasicType * clone() const override { return new BasicType{ *this }; } 149 }; 150 151 /// Pointer/array variable length? 152 enum LengthFlag { FixedLen, VariableLen }; 153 154 /// Pointer/array static dimension? 155 enum DimensionFlag { DynamicDim, StaticDim }; 156 157 /// Pointer type `T*` 158 class PointerType final : public Type { 159 public: 160 ptr<Type> base; 161 162 // In C99, pointer types can be qualified in many ways, e.g. `int a[ static 3 ]` 163 ptr<Expr> dimension; 164 LengthFlag isVarLen = FixedLen; 165 DimensionFlag isStatic = DynamicDim; 166 167 PointerType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b), dimension() {} 168 PointerType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s, 169 CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {} 170 171 // true if this pointer is actually an array 172 bool isArray() const { return isVarLen || isStatic || dimension; } 173 174 bool isComplete() const override { return ! isVarLen; } 175 176 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 177 private: 178 PointerType * clone() const override { return new PointerType{ *this }; } 179 }; 180 181 /// Array type `T[]` 182 class ArrayType final : public Type { 183 public: 184 ptr<Type> base; 185 ptr<Expr> dimension; 186 LengthFlag isVarLen; 187 DimensionFlag isStatic; 188 189 ArrayType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s, 190 CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {} 191 192 // array types are complete if they have a dimension expression or are 193 // VLAs ('*' in parameter declaration), and incomplete otherwise. 194 // See 6.7.6.2 195 bool isComplete() const override { return dimension || isVarLen; } 196 197 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 198 private: 199 ArrayType * clone() const override { return new ArrayType{ *this }; } 200 }; 201 202 /// Reference type `T&` 203 class ReferenceType final : public Type { 204 public: 205 ptr<Type> base; 206 207 ReferenceType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b) {} 208 209 unsigned referenceDepth() const override { return base->referenceDepth() + 1; } 210 211 // Since reference types act like value types, their size is the size of the base. 212 // This makes it simple to cast the empty tuple to a reference type, since casts that increase 213 // the number of values are disallowed. 214 unsigned size() const override { return base->size(); } 215 216 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 217 private: 218 ReferenceType * clone() const override { return new ReferenceType{ *this }; } 219 }; 220 221 /// Qualified type `P.C` 222 class QualifiedType final : public Type { 223 public: 224 ptr<Type> parent; 225 ptr<Type> child; 226 227 QualifiedType( const Type * p, const Type * c, CV::Qualifiers q = {} ) 228 : Type(q), parent(p), child(c) {} 229 230 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 231 private: 232 QualifiedType * clone() const override { return new QualifiedType{ *this }; } 233 }; 234 235 /// Base type for potentially forall-qualified types 236 class ParameterizedType : public Type { 237 public: 238 using ForallList = std::vector<ptr<TypeDecl>>; 239 240 ForallList forall; 241 242 ParameterizedType( ForallList&& fs = {}, CV::Qualifiers q = {} ) 243 : Type(q), forall(std::move(fs)) {} 244 ParameterizedType( CV::Qualifiers q ) : Type(q), forall() {} 245 246 private: 247 virtual ParameterizedType * clone() const override = 0; 248 }; 249 250 /// Function variable arguments flag 251 enum ArgumentFlag { FixedArgs, VariableArgs }; 252 253 /// Type of a function `[R1, R2](*)(P1, P2, P3)` 254 class FunctionType final : public ParameterizedType { 255 public: 256 std::vector<ptr<DeclWithType>> returnVals; 257 std::vector<ptr<DeclWithType>> parameters; 258 259 /// Does the function accept a variable number of arguments following the arguments specified 260 /// in the parameters list. 261 /// This could be because of 262 /// - an ellipsis in a prototype declaration 263 /// - an unprototyped declaration 264 ArgumentFlag isVarArgs; 265 266 FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} ) 267 : ParameterizedType(q), returnVals(), parameters(), isVarArgs(va) {} 268 269 /// true if either the parameters or return values contain a tttype 270 bool isTtype() const; 271 /// true if function parameters are unconstrained by prototype 272 bool isUnprototyped() const { return isVarArgs && parameters.size() == 0; } 273 274 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 275 private: 276 FunctionType * clone() const override { return new FunctionType{ *this }; } 277 }; 278 279 /// base class for types that refer to types declared elsewhere (aggregates and typedefs) 280 class ReferenceToType : public ParameterizedType { 281 public: 282 std::vector<ptr<Expr>> parameters; 283 std::vector<ptr<Attribute>> attributes; 284 std::string name; 285 bool hoistType = false; 286 287 ReferenceToType( const std::string& n, CV::Qualifiers q = {}, 288 std::vector<ptr<Attribute>> && as = {} ) 289 : ParameterizedType(q), parameters(), attributes(std::move(as)), name(n) {} 290 291 /// Gets aggregate declaration this type refers to 292 virtual const AggregateDecl * aggr() const = 0; 293 /// Looks up member declarations with given name 294 std::vector<readonly<Decl>> lookup( const std::string & name ) const; 295 296 private: 297 virtual ReferenceToType * clone() const override = 0; 298 299 protected: 300 /// Name for the kind of type this is 301 virtual std::string typeString() const = 0; 302 }; 303 304 /// instance of struct type 305 class StructInstType final : public ReferenceToType { 306 public: 307 readonly<StructDecl> base; 308 309 StructInstType( const std::string& n, CV::Qualifiers q = {}, 310 std::vector<ptr<Attribute>> && as = {} ) 311 : ReferenceToType( n, q, std::move(as) ), base() {} 312 StructInstType( const StructDecl * b, CV::Qualifiers q = {}, 313 std::vector<ptr<Attribute>> && as = {} ); 314 315 bool isComplete() const override; 316 317 const StructDecl * aggr() const override { return base; } 318 319 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 320 private: 321 StructInstType * clone() const override { return new StructInstType{ *this }; } 322 323 std::string typeString() const override { return "struct"; } 324 }; 325 326 /// instance of union type 327 class UnionInstType final : public ReferenceToType { 328 public: 329 readonly<UnionDecl> base; 330 331 UnionInstType( const std::string& n, CV::Qualifiers q = {}, 332 std::vector<ptr<Attribute>> && as = {} ) 333 : ReferenceToType( n, q, std::move(as) ), base() {} 334 UnionInstType( const UnionDecl * b, CV::Qualifiers q = {}, 335 std::vector<ptr<Attribute>> && as = {} ); 336 337 bool isComplete() const override; 338 339 const UnionDecl * aggr() const override { return base; } 340 341 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 342 private: 343 UnionInstType * clone() const override { return new UnionInstType{ *this }; } 344 345 std::string typeString() const override { return "union"; } 346 }; 347 348 /// instance of enum type 349 class EnumInstType final : public ReferenceToType { 350 public: 351 readonly<EnumDecl> base; 352 353 EnumInstType( const std::string& n, CV::Qualifiers q = {}, 354 std::vector<ptr<Attribute>> && as = {} ) 355 : ReferenceToType( n, q, std::move(as) ), base() {} 356 EnumInstType( const EnumDecl * b, CV::Qualifiers q = {}, 357 std::vector<ptr<Attribute>> && as = {} ); 358 359 bool isComplete() const override; 360 361 const EnumDecl * aggr() const override { return base; } 362 363 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 364 private: 365 EnumInstType * clone() const override { return new EnumInstType{ *this }; } 366 367 std::string typeString() const override { return "enum"; } 368 }; 369 370 /// instance of trait type 371 class TraitInstType final : public ReferenceToType { 372 public: 373 readonly<TraitDecl> base; 374 375 TraitInstType( const std::string& n, CV::Qualifiers q = {}, 376 std::vector<ptr<Attribute>> && as = {} ) 377 : ReferenceToType( n, q, std::move(as) ), base() {} 378 TraitInstType( const TraitDecl * b, CV::Qualifiers q = {}, 379 std::vector<ptr<Attribute>> && as = {} ); 380 381 // not meaningful for TraitInstType 382 bool isComplete() const override { assert(false); } 383 384 const TraitDecl * aggr() const override { return base; } 385 386 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 387 private: 388 TraitInstType * clone() const override { return new TraitInstType{ *this }; } 389 390 std::string typeString() const override { return "trait"; } 391 }; 392 393 /// instance of named type alias (typedef or variable) 394 class TypeInstType final : public ReferenceToType { 395 public: 396 readonly<TypeDecl> base; 397 TypeVar::Kind kind; 398 399 TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {}, 400 std::vector<ptr<Attribute>> && as = {} ) 401 : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {} 402 TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {}, 403 std::vector<ptr<Attribute>> && as = {} ) 404 : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {} 405 406 /// sets `base`, updating `kind` correctly 407 void set_base( const TypeDecl * ); 408 409 bool isComplete() const override; 410 411 // not meaningful for TypeInstType 412 const AggregateDecl * aggr() const override { assert(false); } 413 414 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 415 private: 416 TypeInstType * clone() const override { return new TypeInstType{ *this }; } 417 418 std::string typeString() const override { return "type"; } 419 }; 420 421 /// tuple type e.g. `[int, char]` 422 class TupleType final : public Type { 423 public: 424 std::vector<ptr<Type>> types; 425 std::vector<ptr<Decl>> members; 426 427 TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q = {} ); 428 429 // collection simulation 430 using iterator = std::vector<ptr<Type>>::const_iterator; 431 iterator begin() const { return types.begin(); } 432 iterator end() const { return types.end(); } 433 434 unsigned size() const override { return types.size(); } 435 436 const Type * getComponent( unsigned i ) override { 437 assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d", 438 i, size() ); 439 return *(begin()+i); 440 } 441 442 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 443 private: 444 TupleType * clone() const override { return new TupleType{ *this }; } 445 }; 446 447 /// Type of unresolved `typeof()` expression 448 class TypeofType : public Type { 449 public: 450 ptr<Expr> expr; 451 enum Kind { Typeof, Basetypeof } kind; 452 453 TypeofType( const Expr * e, Kind k = Typeof, CV::Qualifiers q = {} ) 454 : Type(q), expr(e), kind(k) {} 455 456 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 457 private: 458 TypeofType * clone() const override { return new TypeofType{ *this }; } 459 }; 460 461 /// GCC built-in varargs type 462 class VarArgsType final : public Type { 463 public: 464 VarArgsType( CV::Qualifiers q = {} ) : Type( q ) {} 465 466 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 467 private: 468 VarArgsType * clone() const override { return new VarArgsType{ *this }; } 469 }; 470 471 /// Type of zero constant `0` 472 class ZeroType final : public Type { 473 public: 474 ZeroType( CV::Qualifiers q = {} ) : Type( q ) {} 475 476 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 477 private: 478 ZeroType * clone() const override { return new ZeroType{ *this }; } 479 }; 480 481 /// Type of one constant `1` 482 class OneType final : public Type { 483 public: 484 OneType( CV::Qualifiers q = {} ) : Type( q ) {} 485 486 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 487 private: 488 OneType * clone() const override { return new OneType{ *this }; } 489 }; 490 491 /// Parent type for scope-qualified types at global scope 492 class GlobalScopeType final : public Type { 493 public: 494 GlobalScopeType( CV::Qualifiers q = {} ) : Type( q ) {} 495 496 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 497 private: 498 GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; } 499 }; 28 500 29 501 //================================================================================================= 30 502 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency 31 /// remove only if there is a better solution 503 /// remove only if there is a better solution. 32 504 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with 33 505 /// forward declarations 34 inline void increment( const class Type * /*node*/, Node::ref_type /*ref*/ ) { /*node->increment( ref );*/ } 35 inline void decrement( const class Type * /*node*/, Node::ref_type /*ref*/ ) { /*node->decrement( ref );*/ } 36 // inline void increment( const class VoidType * node, Node::ref_type ref ) { node->increment( ref ); } 37 // inline void decrement( const class VoidType * node, Node::ref_type ref ) { node->decrement( ref ); } 38 // inline void increment( const class BasicType * node, Node::ref_type ref ) { node->increment( ref ); } 39 // inline void decrement( const class BasicType * node, Node::ref_type ref ) { node->decrement( ref ); } 40 // inline void increment( const class PointerType * node, Node::ref_type ref ) { node->increment( ref ); } 41 // inline void decrement( const class PointerType * node, Node::ref_type ref ) { node->decrement( ref ); } 42 // inline void increment( const class ArrayType * node, Node::ref_type ref ) { node->increment( ref ); } 43 // inline void decrement( const class ArrayType * node, Node::ref_type ref ) { node->decrement( ref ); } 44 // inline void increment( const class ReferenceType * node, Node::ref_type ref ) { node->increment( ref ); } 45 // inline void decrement( const class ReferenceType * node, Node::ref_type ref ) { node->decrement( ref ); } 46 // inline void increment( const class QualifiedType * node, Node::ref_type ref ) { node->increment( ref ); } 47 // inline void decrement( const class QualifiedType * node, Node::ref_type ref ) { node->decrement( ref ); } 48 // inline void increment( const class FunctionType * node, Node::ref_type ref ) { node->increment( ref ); } 49 // inline void decrement( const class FunctionType * node, Node::ref_type ref ) { node->decrement( ref ); } 50 // inline void increment( const class ReferenceToType * node, Node::ref_type ref ) { node->increment( ref ); } 51 // inline void decrement( const class ReferenceToType * node, Node::ref_type ref ) { node->decrement( ref ); } 52 // inline void increment( const class StructInstType * node, Node::ref_type ref ) { node->increment( ref ); } 53 // inline void decrement( const class StructInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 54 // inline void increment( const class UnionInstType * node, Node::ref_type ref ) { node->increment( ref ); } 55 // inline void decrement( const class UnionInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 56 // inline void increment( const class EnumInstType * node, Node::ref_type ref ) { node->increment( ref ); } 57 // inline void decrement( const class EnumInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 58 // inline void increment( const class TraitInstType * node, Node::ref_type ref ) { node->increment( ref ); } 59 // inline void decrement( const class TraitInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 60 // inline void increment( const class TypeInstType * node, Node::ref_type ref ) { node->increment( ref ); } 61 // inline void decrement( const class TypeInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 62 // inline void increment( const class TupleType * node, Node::ref_type ref ) { node->increment( ref ); } 63 // inline void decrement( const class TupleType * node, Node::ref_type ref ) { node->decrement( ref ); } 64 // inline void increment( const class TypeofType * node, Node::ref_type ref ) { node->increment( ref ); } 65 // inline void decrement( const class TypeofType * node, Node::ref_type ref ) { node->decrement( ref ); } 66 // inline void increment( const class AttrType * node, Node::ref_type ref ) { node->increment( ref ); } 67 // inline void decrement( const class AttrType * node, Node::ref_type ref ) { node->decrement( ref ); } 68 // inline void increment( const class VarArgsType * node, Node::ref_type ref ) { node->increment( ref ); } 69 // inline void decrement( const class VarArgsType * node, Node::ref_type ref ) { node->decrement( ref ); } 70 // inline void increment( const class ZeroType * node, Node::ref_type ref ) { node->increment( ref ); } 71 // inline void decrement( const class ZeroType * node, Node::ref_type ref ) { node->decrement( ref ); } 72 // inline void increment( const class OneType * node, Node::ref_type ref ) { node->increment( ref ); } 73 // inline void decrement( const class OneType * node, Node::ref_type ref ) { node->decrement( ref ); } 74 // inline void increment( const class GlobalScopeType * node, Node::ref_type ref ) { node->increment( ref ); } 75 // inline void decrement( const class GlobalScopeType * node, Node::ref_type ref ) { node->decrement( ref ); } 506 inline void increment( const class Type * node, Node::ref_type ref ) { node->increment( ref ); } 507 inline void decrement( const class Type * node, Node::ref_type ref ) { node->decrement( ref ); } 508 inline void increment( const class VoidType * node, Node::ref_type ref ) { node->increment( ref ); } 509 inline void decrement( const class VoidType * node, Node::ref_type ref ) { node->decrement( ref ); } 510 inline void increment( const class BasicType * node, Node::ref_type ref ) { node->increment( ref ); } 511 inline void decrement( const class BasicType * node, Node::ref_type ref ) { node->decrement( ref ); } 512 inline void increment( const class PointerType * node, Node::ref_type ref ) { node->increment( ref ); } 513 inline void decrement( const class PointerType * node, Node::ref_type ref ) { node->decrement( ref ); } 514 inline void increment( const class ArrayType * node, Node::ref_type ref ) { node->increment( ref ); } 515 inline void decrement( const class ArrayType * node, Node::ref_type ref ) { node->decrement( ref ); } 516 inline void increment( const class ReferenceType * node, Node::ref_type ref ) { node->increment( ref ); } 517 inline void decrement( const class ReferenceType * node, Node::ref_type ref ) { node->decrement( ref ); } 518 inline void increment( const class QualifiedType * node, Node::ref_type ref ) { node->increment( ref ); } 519 inline void decrement( const class QualifiedType * node, Node::ref_type ref ) { node->decrement( ref ); } 520 inline void increment( const class FunctionType * node, Node::ref_type ref ) { node->increment( ref ); } 521 inline void decrement( const class FunctionType * node, Node::ref_type ref ) { node->decrement( ref ); } 522 inline void increment( const class ReferenceToType * node, Node::ref_type ref ) { node->increment( ref ); } 523 inline void decrement( const class ReferenceToType * node, Node::ref_type ref ) { node->decrement( ref ); } 524 inline void increment( const class StructInstType * node, Node::ref_type ref ) { node->increment( ref ); } 525 inline void decrement( const class StructInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 526 inline void increment( const class UnionInstType * node, Node::ref_type ref ) { node->increment( ref ); } 527 inline void decrement( const class UnionInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 528 inline void increment( const class EnumInstType * node, Node::ref_type ref ) { node->increment( ref ); } 529 inline void decrement( const class EnumInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 530 inline void increment( const class TraitInstType * node, Node::ref_type ref ) { node->increment( ref ); } 531 inline void decrement( const class TraitInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 532 inline void increment( const class TypeInstType * node, Node::ref_type ref ) { node->increment( ref ); } 533 inline void decrement( const class TypeInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 534 inline void increment( const class TupleType * node, Node::ref_type ref ) { node->increment( ref ); } 535 inline void decrement( const class TupleType * node, Node::ref_type ref ) { node->decrement( ref ); } 536 inline void increment( const class TypeofType * node, Node::ref_type ref ) { node->increment( ref ); } 537 inline void decrement( const class TypeofType * node, Node::ref_type ref ) { node->decrement( ref ); } 538 inline void increment( const class VarArgsType * node, Node::ref_type ref ) { node->increment( ref ); } 539 inline void decrement( const class VarArgsType * node, Node::ref_type ref ) { node->decrement( ref ); } 540 inline void increment( const class ZeroType * node, Node::ref_type ref ) { node->increment( ref ); } 541 inline void decrement( const class ZeroType * node, Node::ref_type ref ) { node->decrement( ref ); } 542 inline void increment( const class OneType * node, Node::ref_type ref ) { node->increment( ref ); } 543 inline void decrement( const class OneType * node, Node::ref_type ref ) { node->decrement( ref ); } 544 inline void increment( const class GlobalScopeType * node, Node::ref_type ref ) { node->increment( ref ); } 545 inline void decrement( const class GlobalScopeType * node, Node::ref_type ref ) { node->decrement( ref ); } 76 546 77 547 } -
src/AST/Visitor.hpp
r1e97287 r89c2f7c9 104 104 virtual const ast::Type * visit( const ast::TupleType * ) = 0; 105 105 virtual const ast::Type * visit( const ast::TypeofType * ) = 0; 106 virtual const ast::Type * visit( const ast::AttrType * ) = 0;107 106 virtual const ast::Type * visit( const ast::VarArgsType * ) = 0; 108 107 virtual const ast::Type * visit( const ast::ZeroType * ) = 0; -
src/AST/porting.md
r1e97287 r89c2f7c9 36 36 * allows compiler to optimize virtual calls to static calls if given static type 37 37 38 Pulled `FuncSpecifiers` and `StorageClasses` out of `Type` into their own headers38 Pulled `FuncSpecifiers`, `StorageClasses`, `CVQualifiers` out of `Type` into their own headers 39 39 * Made `BFCommon` a `MakeBitfield` macro in its own header 40 40 * added default and field-init constructors to macro … … 70 70 * `Initializer` => `ast::Init` 71 71 * `Statement` => `ast::Stmt` 72 * any field names should follow a similar renaming 72 73 * because they don't really belong to `Type` (and for consistency with `Linkage::Spec`): 73 74 * `Type::StorageClasses` => `ast::Storage::Classes` 74 75 * `Type::Extern` etc. => `ast::Storage::Extern` etc. 76 * `Type::FuncSpecifiers` => `ast::Function::Specs` 77 * `Type::Inline` etc. => `ast::Function::Inline` etc. 78 * `Type::Qualifiers` => `ast::CV::Qualifiers` 79 * `Type::Const` etc. => `ast::CV::Const` 80 * couldn't break name-dependency loop without pulling `Qualifiers` out of `Type` 75 81 * `LinkageSpec::Spec` => `ast::Linkage::Spec` 76 82 * `LinkageSpec::Mangle` etc. => `ast::Linkage::Mangle` etc. … … 79 85 * `LinkageSpec::isMangled(Spec)` etc. => `Spec.is_mangled` etc. 80 86 * `LinkageSpec::Intrinsic` etc. => `ast::Linkage::Intrinsic` etc. 87 * Boolean constructor parameters get replaced with a dedicated flag enum: 88 * e.g. `bool isVarLen;` => `enum LengthFlag { FixedLen, VariableLen };` `LengthFlag isVarLen;` 89 * field can be *read* in the existing boolean contexts, but requires documentation to write 90 * suggest naming all flag enums `FooFlag` to hint at boolean nature 81 91 82 92 ## Specific Nodes ## … … 97 107 98 108 `TypeDecl` 99 * stripped `isComplete()` accessor in favour of direct access to `sized`109 * moved `TypeDecl::Kind` to `ast::TypeVar::Kind` 100 110 101 111 `EnumDecl` … … 105 115 * Merged `inferParams`/`resnSlots` into union, as suggested by comment in old version 106 116 * does imply get_/set_ API, and some care about moving backward 117 118 `Init` 119 * `bool maybeConstruct` => `enum ConstructFlag { DoConstruct, MaybeConstruct }` 107 120 108 121 `Label` … … 129 142 * **TODO** port copy operator 130 143 * Needs to be an almost-shallow clone, where the declarations are cloned only if needed 131 * **TODO** port DeclReplacer144 * **TODO** port `DeclReplacer` 132 145 * Still a `std::list` for children, rather than `std::vector` 133 146 * allows more-efficient splicing for purposes of later code generation 134 147 135 148 `Type` 149 * `CV::Qualifiers` moved to end of constructor parameter list, defaulted to `{}` 150 * `ReferenceToType` puts a defaulted list of attributes after qualifiers 136 151 * `forall` field split off into `ParameterizedType` subclass 137 152 * any type that needs it can inherit from `ParameterizedType` 153 * currently `FunctionType`, `ReferenceToType` 138 154 * `get_qualifiers()` replaced with accessor `qualifiers()` and mutator `set_qualifiers()` 139 * `get_CV()` replaced with `is_CV()` variants 155 * `get_const()` etc. replaced with `is_const()` etc. variants 156 * `referenceDepth()` now returns `unsigned` rather than `int` 140 157 * A number of features only supported on aggregates pushed down to `ReferenceToType`: 141 158 * `attributes`: per docs [1] GCC only supports type attributes on aggregates and typedefs 142 159 * suggest adding a `TypeWithAttributes` wrapper type if this proves insufficient 143 * `getAggr()` 144 * `genericSubstitution()` 160 * `getAggr()` => `aggr()` 161 * also now returns `const AggregateDecl *` 162 * `genericSubstitution()` moved to own visitor **TODO** write 145 163 146 164 `BasicType` 147 * does not inherit from `Type` to allow pointer inlining148 * moved `Kind` before qualifiers in constructor to allow for default149 165 * **TODO** move `kind`, `typeNames` into code generator 166 167 `ReferenceToType` 168 * deleted `get_baseParameters()` from children 169 * replace with `aggr() ? aggr()->parameters : nullptr` 170 * hoisted `lookup` implementation into parent, made non-virtual 171 * also changed to return vector rather than filling; change back if any great win for reuse 172 * `baseStruct` etc. renamed to `base` 173 174 `PointerType`/`ArrayType` 175 * `is_array()` => `isArray()` 176 * `bool isVarLen;` => `enum LengthFlag { FixedLen, VariableLen }; LengthFlag isVarLen;` 177 * `bool isStatic;` => `enum DimensionFlag { DynamicDim, StaticDim }; DimensionFlag isStatic;` 178 179 `FunctionType` 180 * `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;` 181 182 `TypeInstType` 183 * `bool isFtype` => `TypeVar::Kind kind` 184 185 `TypeofType` 186 * `bool is_basetypeof` => `enum Kind { Typeof, Basetypeof } kind;` 187 188 `TupleType` 189 * removed `value_type` typedef due to likely error 190 * if readded, should be `const Type *` 191 192 `AttrType` 193 * did not port due to deprecation of feature 194 * feature is `type@thing` e.g. `int@MAX` 150 195 151 196 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes -
src/InitTweak/InitTweak.cc
r1e97287 r89c2f7c9 5 5 #include <memory> // for __shared_ptr 6 6 7 #include "AST/Type.hpp" 7 8 #include "Common/PassVisitor.h" 8 9 #include "Common/SemanticError.h" // for SemanticError … … 513 514 } 514 515 } 516 const ast::Type* getPointerBase( const ast::Type* t ) { 517 assert(!"needs to build Type.cpp before inclusion"); 518 // if ( const ast::PointerType* p = dynamic_cast< const ast::PointerType* >( t ) ) { 519 // return p->base; 520 // } else if ( const ast::ArrayType* a = dynamic_cast< const ast::ArrayType* >( t ) ) { 521 // return a->base; 522 // } else if ( const ast::ReferenceType* r = dynamic_cast< const ast::ReferenceType* >( t ) ) { 523 // return r->base; 524 // } else return nullptr; 525 } 515 526 516 527 Type * isPointerType( Type * type ) { -
src/InitTweak/InitTweak.h
r1e97287 r89c2f7c9 20 20 #include <string> // for string, allocator 21 21 22 #include "AST/Fwd.hpp" // for AST nodes 22 23 #include "SynTree/SynTree.h" // for Visitor Nodes 23 24 … … 83 84 /// returns the base type of a PointerType or ArrayType, else returns NULL 84 85 Type * getPointerBase( Type * ); 86 const ast::Type* getPointerBase( const ast::Type* ); 85 87 86 88 /// returns the argument if it is a PointerType or ArrayType, else returns NULL
Note: See TracChangeset
for help on using the changeset viewer.