Changes in / [be567e9:69bafd2]
- Location:
- src
- Files:
-
- 3 added
- 13 edited
-
AST/CVQualifiers.hpp (added)
-
AST/Decl.hpp (modified) (4 diffs)
-
AST/Expr.hpp (modified) (2 diffs)
-
AST/FunctionSpec.hpp (modified) (1 diff)
-
AST/Fwd.hpp (modified) (2 diffs)
-
AST/Init.hpp (modified) (4 diffs)
-
AST/Node.hpp (modified) (4 diffs)
-
AST/Pass.hpp (modified) (1 diff)
-
AST/StorageClasses.hpp (modified) (1 diff)
-
AST/Type.cpp (added)
-
AST/Type.hpp (modified) (1 diff)
-
AST/TypeVar.hpp (added)
-
AST/Visitor.hpp (modified) (1 diff)
-
AST/porting.md (modified) (6 diffs)
-
InitTweak/InitTweak.cc (modified) (2 diffs)
-
InitTweak/InitTweak.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Decl.hpp
rbe567e9 r69bafd2 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 … … 140 140 class TypeDecl final : public NamedTypeDecl { 141 141 public: 142 /// type variable variants. otype is a specialized dtype 143 enum Kind { Dtype, Ftype, Ttype, NUMBER_OF_KINDS } kind; 142 TypeVar::Kind kind; 144 143 bool sized; 145 144 ptr<Type> init; … … 147 146 /// Data extracted from a type decl 148 147 struct Data { 149 Kind kind;148 TypeVar::Kind kind; 150 149 bool isComplete; 151 150 152 Data() : kind( ( Kind)-1 ), isComplete( false ) {}151 Data() : kind( (TypeVar::Kind)-1 ), isComplete( false ) {} 153 152 Data( TypeDecl* d ) : kind( d->kind ), isComplete( d->sized ) {} 154 Data( Kind k, bool c ) : kind( k ), isComplete( c ) {}153 Data( TypeVar::Kind k, bool c ) : kind( k ), isComplete( c ) {} 155 154 Data( const Data& d1, const Data& d2 ) 156 155 : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {} … … 163 162 164 163 TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b, 165 Kind k, bool s, Type* i = nullptr ) 166 : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == Ttype || s ), init( i ) {} 164 TypeVar::Kind k, bool s, Type* i = nullptr ) 165 : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeVar::Ttype || s ), 166 init( i ) {} 167 167 168 168 std::string typeString() const override; 169 169 /// Produces a name for generated code 170 170 std::string genTypeString() const; 171 172 /// convenience accessor to match Type::isComplete() 173 bool isComplete() { return sized; } 171 174 172 175 virtual const Decl * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Expr.hpp
rbe567e9 r69bafd2 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 virtual 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 virtual 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
rbe567e9 r69bafd2 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
rbe567e9 r69bafd2 118 118 class TupleType; 119 119 class TypeofType; 120 class AttrType;121 120 class VarArgsType; 122 121 class ZeroType; … … 335 334 inline void increment( const class TypeofType *, Node::ref_type ); 336 335 inline void decrement( const class TypeofType *, Node::ref_type ); 337 inline void increment( const class AttrType *, Node::ref_type );338 inline void decrement( const class AttrType *, Node::ref_type );339 336 inline void increment( const class VarArgsType *, Node::ref_type ); 340 337 inline void decrement( const class VarArgsType *, Node::ref_type ); -
src/AST/Init.hpp
rbe567e9 r69bafd2 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 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 virtual const Init * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Node.hpp
rbe567e9 r69bafd2 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 Node::ref_type o_ref_t >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 Node::ref_type o_ref_t >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 Node::ref_type o_ref_t >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 Node::ref_type o_ref_t >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; … … 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
rbe567e9 r69bafd2 167 167 virtual const ast::Type * visit( const ast::TupleType * ) override final; 168 168 virtual const ast::Type * visit( const ast::TypeofType * ) override final; 169 virtual const ast::Type * visit( const ast::AttrType * ) override final;170 169 virtual const ast::Type * visit( const ast::VarArgsType * ) override final; 171 170 virtual const ast::Type * visit( const ast::ZeroType * ) override final; -
src/AST/StorageClasses.hpp
rbe567e9 r69bafd2 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
rbe567e9 r69bafd2 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 public: 24 virtual const Type * accept( Visitor & v) const = 0; 25 }; 26 27 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const 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 const Type * accept( Visitor & v ) const override { return v.visit( this ); } 496 private: 497 GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; } 498 }; 28 499 29 500 //================================================================================================= 30 501 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency 31 /// remove only if there is a better solution 502 /// remove only if there is a better solution. 32 503 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with 33 504 /// 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 ); } 505 inline void increment( const class Type * node, Node::ref_type ref ) { node->increment( ref ); } 506 inline void decrement( const class Type * node, Node::ref_type ref ) { node->decrement( ref ); } 507 inline void increment( const class VoidType * node, Node::ref_type ref ) { node->increment( ref ); } 508 inline void decrement( const class VoidType * node, Node::ref_type ref ) { node->decrement( ref ); } 509 inline void increment( const class BasicType * node, Node::ref_type ref ) { node->increment( ref ); } 510 inline void decrement( const class BasicType * node, Node::ref_type ref ) { node->decrement( ref ); } 511 inline void increment( const class PointerType * node, Node::ref_type ref ) { node->increment( ref ); } 512 inline void decrement( const class PointerType * node, Node::ref_type ref ) { node->decrement( ref ); } 513 inline void increment( const class ArrayType * node, Node::ref_type ref ) { node->increment( ref ); } 514 inline void decrement( const class ArrayType * node, Node::ref_type ref ) { node->decrement( ref ); } 515 inline void increment( const class ReferenceType * node, Node::ref_type ref ) { node->increment( ref ); } 516 inline void decrement( const class ReferenceType * node, Node::ref_type ref ) { node->decrement( ref ); } 517 inline void increment( const class QualifiedType * node, Node::ref_type ref ) { node->increment( ref ); } 518 inline void decrement( const class QualifiedType * node, Node::ref_type ref ) { node->decrement( ref ); } 519 inline void increment( const class FunctionType * node, Node::ref_type ref ) { node->increment( ref ); } 520 inline void decrement( const class FunctionType * node, Node::ref_type ref ) { node->decrement( ref ); } 521 inline void increment( const class ReferenceToType * node, Node::ref_type ref ) { node->increment( ref ); } 522 inline void decrement( const class ReferenceToType * node, Node::ref_type ref ) { node->decrement( ref ); } 523 inline void increment( const class StructInstType * node, Node::ref_type ref ) { node->increment( ref ); } 524 inline void decrement( const class StructInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 525 inline void increment( const class UnionInstType * node, Node::ref_type ref ) { node->increment( ref ); } 526 inline void decrement( const class UnionInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 527 inline void increment( const class EnumInstType * node, Node::ref_type ref ) { node->increment( ref ); } 528 inline void decrement( const class EnumInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 529 inline void increment( const class TraitInstType * node, Node::ref_type ref ) { node->increment( ref ); } 530 inline void decrement( const class TraitInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 531 inline void increment( const class TypeInstType * node, Node::ref_type ref ) { node->increment( ref ); } 532 inline void decrement( const class TypeInstType * node, Node::ref_type ref ) { node->decrement( ref ); } 533 inline void increment( const class TupleType * node, Node::ref_type ref ) { node->increment( ref ); } 534 inline void decrement( const class TupleType * node, Node::ref_type ref ) { node->decrement( ref ); } 535 inline void increment( const class TypeofType * node, Node::ref_type ref ) { node->increment( ref ); } 536 inline void decrement( const class TypeofType * node, Node::ref_type ref ) { node->decrement( ref ); } 537 inline void increment( const class VarArgsType * node, Node::ref_type ref ) { node->increment( ref ); } 538 inline void decrement( const class VarArgsType * node, Node::ref_type ref ) { node->decrement( ref ); } 539 inline void increment( const class ZeroType * node, Node::ref_type ref ) { node->increment( ref ); } 540 inline void decrement( const class ZeroType * node, Node::ref_type ref ) { node->decrement( ref ); } 541 inline void increment( const class OneType * node, Node::ref_type ref ) { node->increment( ref ); } 542 inline void decrement( const class OneType * node, Node::ref_type ref ) { node->decrement( ref ); } 543 inline void increment( const class GlobalScopeType * node, Node::ref_type ref ) { node->increment( ref ); } 544 inline void decrement( const class GlobalScopeType * node, Node::ref_type ref ) { node->decrement( ref ); } 76 545 77 546 } -
src/AST/Visitor.hpp
rbe567e9 r69bafd2 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
rbe567e9 r69bafd2 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` … … 106 116 * does imply get_/set_ API, and some care about moving backward 107 117 118 `Init` 119 * `bool maybeConstruct` => `enum ConstructFlag { DoConstruct, MaybeConstruct }` 120 108 121 `Label` 109 122 * `get_statement()` exclusively used for code location, replaced with `CodeLocation` field … … 112 125 * **TODO** port copy operator 113 126 * Needs to be an almost-shallow clone, where the declarations are cloned only if needed 114 * **TODO** port DeclReplacer127 * **TODO** port `DeclReplacer` 115 128 * Still a `std::list` for children, rather than `std::vector` 116 129 * allows more-efficient splicing for purposes of later code generation 117 130 118 131 `Type` 132 * `CV::Qualifiers` moved to end of constructor parameter list, defaulted to `{}` 133 * `ReferenceToType` puts a defaulted list of attributes after qualifiers 119 134 * `forall` field split off into `ParameterizedType` subclass 120 135 * any type that needs it can inherit from `ParameterizedType` 136 * currently `FunctionType`, `ReferenceToType` 121 137 * `get_qualifiers()` replaced with accessor `qualifiers()` and mutator `set_qualifiers()` 122 * `get_CV()` replaced with `is_CV()` variants 138 * `get_const()` etc. replaced with `is_const()` etc. variants 139 * `referenceDepth()` now returns `unsigned` rather than `int` 123 140 * A number of features only supported on aggregates pushed down to `ReferenceToType`: 124 141 * `attributes`: per docs [1] GCC only supports type attributes on aggregates and typedefs 125 142 * suggest adding a `TypeWithAttributes` wrapper type if this proves insufficient 126 * `getAggr()` 127 * `genericSubstitution()` 143 * `getAggr()` => `aggr()` 144 * also now returns `const AggregateDecl *` 145 * `genericSubstitution()` moved to own visitor **TODO** write 128 146 129 147 `BasicType` 130 * does not inherit from `Type` to allow pointer inlining131 * moved `Kind` before qualifiers in constructor to allow for default132 148 * **TODO** move `kind`, `typeNames` into code generator 149 150 `ReferenceToType` 151 * deleted `get_baseParameters()` from children 152 * replace with `aggr() ? aggr()->parameters : nullptr` 153 * hoisted `lookup` implementation into parent, made non-virtual 154 * also changed to return vector rather than filling; change back if any great win for reuse 155 * `baseStruct` etc. renamed to `base` 156 157 `PointerType`/`ArrayType` 158 * `is_array()` => `isArray()` 159 * `bool isVarLen;` => `enum LengthFlag { FixedLen, VariableLen }; LengthFlag isVarLen;` 160 * `bool isStatic;` => `enum DimensionFlag { DynamicDim, StaticDim }; DimensionFlag isStatic;` 161 162 `FunctionType` 163 * `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;` 164 165 `TypeInstType` 166 * `bool isFtype` => `TypeVar::Kind kind` 167 168 `TypeofType` 169 * `bool is_basetypeof` => `enum Kind { Typeof, Basetypeof } kind;` 170 171 `TupleType` 172 * removed `value_type` typedef due to likely error 173 * if readded, should be `const Type *` 174 175 `AttrType` 176 * did not port due to deprecation of feature 177 * feature is `type@thing` e.g. `int@MAX` 133 178 134 179 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes -
src/InitTweak/InitTweak.cc
rbe567e9 r69bafd2 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
rbe567e9 r69bafd2 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.