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