source: src/AST/Type.hpp@ aba20d2

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since aba20d2 was ee574a2, checked in by Aaron Moss <a3moss@…>, 6 years ago

Port CommonType to new AST

  • Property mode set to 100644
File size: 16.4 KB
Line 
1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
7// Type.hpp --
8//
9// Author : Aaron B. Moss
10// Created On : Thu May 9 10:00:00 2019
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Thu May 9 10:00:00 2019
13// Update Count : 1
14//
15
16#pragma once
17
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" // for AggregateDecl subclasses
26#include "Fwd.hpp"
27#include "Node.hpp" // for Node, ptr, ptr_base
28#include "TypeVar.hpp"
29#include "Visitor.hpp"
30
31// Must be included in *all* AST classes; should be #undef'd at the end of the file
32#define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node);
33
34namespace ast {
35
36class Type : public Node {
37public:
38 CV::Qualifiers qualifiers;
39
40 Type( CV::Qualifiers q = {} ) : qualifiers(q) {}
41
42 bool is_const() const { return qualifiers.is_const; }
43 bool is_volatile() const { return qualifiers.is_volatile; }
44 bool is_restrict() const { return qualifiers.is_restrict; }
45 bool is_lvalue() const { return qualifiers.is_lvalue; }
46 bool is_mutex() const { return qualifiers.is_mutex; }
47 bool is_atomic() const { return qualifiers.is_atomic; }
48
49 Type * set_const( bool v ) { qualifiers.is_const = v; return this; }
50 Type * set_volatile( bool v ) { qualifiers.is_volatile = v; return this; }
51 Type * set_restrict( bool v ) { qualifiers.is_restrict = v; return this; }
52 Type * set_lvalue( bool v ) { qualifiers.is_lvalue = v; return this; }
53 Type * set_mutex( bool v ) { qualifiers.is_mutex = v; return this; }
54 Type * set_atomic( bool v ) { qualifiers.is_atomic = v; return this; }
55
56 /// How many elemental types are represented by this type
57 virtual unsigned size() const { return 1; }
58 /// Is this a void type?
59 virtual bool isVoid() const { return size() == 0; }
60 /// Get the i'th component of this type
61 virtual const Type * getComponent( unsigned i ) const;
62
63 /// type without outer pointers and arrays
64 const Type * stripDeclarator() const;
65 /// type without outer references
66 const Type * stripReferences() const;
67 /// number of reference occuring consecutively on the outermost layer of this type
68 /// (i.e. do not count references nested within other types)
69 virtual unsigned referenceDepth() const { return 0; }
70 /// true iff type is complete type (i.e. compiler knows the size, alignment, and layout)
71 virtual bool isComplete() const { return true; }
72
73 virtual const Type * accept( Visitor & v ) const override = 0;
74private:
75 virtual Type * clone() const override = 0;
76 MUTATE_FRIEND
77};
78
79/// Clear/reset the qualifiers on this type, cloning only if necessary
80template< enum Node::ref_type ref_t >
81void reset_qualifiers( ptr_base< Type, ref_t > & p, CV::Qualifiers q = {} ) {
82 if ( p->qualifiers.val != q.val ) p.get_and_mutate()->qualifiers = q;
83}
84
85/// Add the specified qualifiers to this type, cloning only if necessary
86template< enum Node::ref_type ref_t >
87void add_qualifiers( ptr_base< Type, ref_t > & p, CV::Qualifiers q ) {
88 if ( ( p->qualifiers.val & q.val ) != q.val ) p.get_and_mutate()->qualifiers |= q;
89}
90
91/// Remove the specified qualifiers from this type, cloning only if necessary
92template< enum Node::ref_type ref_t >
93void remove_qualifiers( ptr_base< Type, ref_t > & p, CV::Qualifiers q ) {
94 if ( ( p->qualifiers.val & q.val ) != 0 ) p.get_and_mutate()->qualifiers -= q;
95}
96
97/// `void`
98class VoidType final : public Type {
99public:
100 VoidType( CV::Qualifiers q = {} ) : Type( q ) {}
101
102 unsigned size() const override { return 0; }
103 bool isVoid() const override { return true; }
104 bool isComplete() const override { return false; }
105
106 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
107private:
108 VoidType * clone() const override { return new VoidType{ *this }; }
109 MUTATE_FRIEND
110};
111
112/// Built-in arithmetic type
113class BasicType final : public Type {
114public:
115 // GENERATED START, DO NOT EDIT
116 // GENERATED BY BasicTypes-gen.cc
117 enum Kind {
118 Bool,
119 Char,
120 SignedChar,
121 UnsignedChar,
122 ShortSignedInt,
123 ShortUnsignedInt,
124 SignedInt,
125 UnsignedInt,
126 LongSignedInt,
127 LongUnsignedInt,
128 LongLongSignedInt,
129 LongLongUnsignedInt,
130 SignedInt128,
131 UnsignedInt128,
132 uFloat16,
133 uFloat16Complex,
134 uFloat32,
135 uFloat32Complex,
136 Float,
137 FloatComplex,
138 uFloat32x,
139 uFloat32xComplex,
140 uFloat64,
141 uFloat64Complex,
142 Double,
143 DoubleComplex,
144 uFloat64x,
145 uFloat64xComplex,
146 uuFloat80,
147 uFloat128,
148 uFloat128Complex,
149 uuFloat128,
150 LongDouble,
151 LongDoubleComplex,
152 uFloat128x,
153 uFloat128xComplex,
154 NUMBER_OF_BASIC_TYPES
155 } kind;
156 // GENERATED END
157
158 /// xxx -- MAX_INTEGER_TYPE should probably be in BasicTypes-gen.cc, rather than hardcoded here
159 enum { MAX_INTEGER_TYPE = UnsignedInt128 };
160
161 /// string names of basic types; generated to match with Kind
162 static const char *typeNames[];
163
164 BasicType( Kind k, CV::Qualifiers q = {} ) : Type(q), kind(k) {}
165
166 /// Check if this type represents an integer type
167 bool isInteger() const { return (unsigned)kind <= (unsigned)MAX_INTEGER_TYPE; }
168
169 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
170private:
171 BasicType * clone() const override { return new BasicType{ *this }; }
172 MUTATE_FRIEND
173};
174
175/// Pointer/array variable length?
176enum LengthFlag { FixedLen, VariableLen };
177
178/// Pointer/array static dimension?
179enum DimensionFlag { DynamicDim, StaticDim };
180
181/// Pointer type `T*`
182class PointerType final : public Type {
183public:
184 ptr<Type> base;
185
186 // In C99, pointer types can be qualified in many ways, e.g. `int a[ static 3 ]`
187 ptr<Expr> dimension;
188 LengthFlag isVarLen = FixedLen;
189 DimensionFlag isStatic = DynamicDim;
190
191 PointerType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b), dimension() {}
192 PointerType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
193 CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
194
195 // true if this pointer is actually an array
196 bool isArray() const { return isVarLen || isStatic || dimension; }
197
198 bool isComplete() const override { return ! isVarLen; }
199
200 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
201private:
202 PointerType * clone() const override { return new PointerType{ *this }; }
203 MUTATE_FRIEND
204};
205
206/// Array type `T[]`
207class ArrayType final : public Type {
208public:
209 ptr<Type> base;
210 ptr<Expr> dimension;
211 LengthFlag isVarLen;
212 DimensionFlag isStatic;
213
214 ArrayType( const Type * b, const Expr * d, LengthFlag vl, DimensionFlag s,
215 CV::Qualifiers q = {} ) : Type(q), base(b), dimension(d), isVarLen(vl), isStatic(s) {}
216
217 // array types are complete if they have a dimension expression or are
218 // VLAs ('*' in parameter declaration), and incomplete otherwise.
219 // See 6.7.6.2
220 bool isComplete() const override { return dimension || isVarLen; }
221
222 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
223private:
224 ArrayType * clone() const override { return new ArrayType{ *this }; }
225 MUTATE_FRIEND
226};
227
228/// Reference type `T&`
229class ReferenceType final : public Type {
230public:
231 ptr<Type> base;
232
233 ReferenceType( const Type * b, CV::Qualifiers q = {} ) : Type(q), base(b) {}
234
235 unsigned referenceDepth() const override { return base->referenceDepth() + 1; }
236
237 // Since reference types act like value types, their size is the size of the base.
238 // This makes it simple to cast the empty tuple to a reference type, since casts that increase
239 // the number of values are disallowed.
240 unsigned size() const override { return base->size(); }
241
242 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
243private:
244 ReferenceType * clone() const override { return new ReferenceType{ *this }; }
245 MUTATE_FRIEND
246};
247
248/// Qualified type `P.C`
249class QualifiedType final : public Type {
250public:
251 ptr<Type> parent;
252 ptr<Type> child;
253
254 QualifiedType( const Type * p, const Type * c, CV::Qualifiers q = {} )
255 : Type(q), parent(p), child(c) {}
256
257 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
258private:
259 QualifiedType * clone() const override { return new QualifiedType{ *this }; }
260 MUTATE_FRIEND
261};
262
263/// Base type for potentially forall-qualified types
264class ParameterizedType : public Type {
265public:
266 using ForallList = std::vector<ptr<TypeDecl>>;
267
268 ForallList forall;
269
270 ParameterizedType( ForallList&& fs = {}, CV::Qualifiers q = {} )
271 : Type(q), forall(std::move(fs)) {}
272 ParameterizedType( CV::Qualifiers q ) : Type(q), forall() {}
273
274private:
275 virtual ParameterizedType * clone() const override = 0;
276 MUTATE_FRIEND
277};
278
279/// Function variable arguments flag
280enum ArgumentFlag { FixedArgs, VariableArgs };
281
282/// Type of a function `[R1, R2](*)(P1, P2, P3)`
283class FunctionType final : public ParameterizedType {
284public:
285 std::vector<ptr<DeclWithType>> returns;
286 std::vector<ptr<DeclWithType>> params;
287
288 /// Does the function accept a variable number of arguments following the arguments specified
289 /// in the parameters list.
290 /// This could be because of
291 /// - an ellipsis in a prototype declaration
292 /// - an unprototyped declaration
293 ArgumentFlag isVarArgs;
294
295 FunctionType( ArgumentFlag va = FixedArgs, CV::Qualifiers q = {} )
296 : ParameterizedType(q), returns(), params(), isVarArgs(va) {}
297
298 /// true if either the parameters or return values contain a tttype
299 bool isTtype() const;
300 /// true if function parameters are unconstrained by prototype
301 bool isUnprototyped() const { return isVarArgs && params.size() == 0; }
302
303 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
304private:
305 FunctionType * clone() const override { return new FunctionType{ *this }; }
306 MUTATE_FRIEND
307};
308
309/// base class for types that refer to types declared elsewhere (aggregates and typedefs)
310class ReferenceToType : public ParameterizedType {
311public:
312 std::vector<ptr<Expr>> params;
313 std::vector<ptr<Attribute>> attributes;
314 std::string name;
315 bool hoistType = false;
316
317 ReferenceToType( const std::string& n, CV::Qualifiers q = {},
318 std::vector<ptr<Attribute>> && as = {} )
319 : ParameterizedType(q), params(), attributes(std::move(as)), name(n) {}
320
321 /// Gets aggregate declaration this type refers to
322 virtual const AggregateDecl * aggr() const = 0;
323 /// Looks up member declarations with given name
324 std::vector<readonly<Decl>> lookup( const std::string & name ) const;
325
326private:
327 virtual ReferenceToType * clone() const override = 0;
328 MUTATE_FRIEND
329};
330
331/// instance of struct type
332class StructInstType final : public ReferenceToType {
333public:
334 readonly<StructDecl> base;
335
336 StructInstType( const std::string& n, CV::Qualifiers q = {},
337 std::vector<ptr<Attribute>> && as = {} )
338 : ReferenceToType( n, q, std::move(as) ), base() {}
339 StructInstType( const StructDecl * b, CV::Qualifiers q = {},
340 std::vector<ptr<Attribute>> && as = {} );
341
342 bool isComplete() const override;
343
344 const StructDecl * aggr() const override { return base; }
345
346 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
347private:
348 StructInstType * clone() const override { return new StructInstType{ *this }; }
349 MUTATE_FRIEND
350};
351
352/// instance of union type
353class UnionInstType final : public ReferenceToType {
354public:
355 readonly<UnionDecl> base;
356
357 UnionInstType( const std::string& n, CV::Qualifiers q = {},
358 std::vector<ptr<Attribute>> && as = {} )
359 : ReferenceToType( n, q, std::move(as) ), base() {}
360 UnionInstType( const UnionDecl * b, CV::Qualifiers q = {},
361 std::vector<ptr<Attribute>> && as = {} );
362
363 bool isComplete() const override;
364
365 const UnionDecl * aggr() const override { return base; }
366
367 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
368private:
369 UnionInstType * clone() const override { return new UnionInstType{ *this }; }
370 MUTATE_FRIEND
371};
372
373/// instance of enum type
374class EnumInstType final : public ReferenceToType {
375public:
376 readonly<EnumDecl> base;
377
378 EnumInstType( const std::string& n, CV::Qualifiers q = {},
379 std::vector<ptr<Attribute>> && as = {} )
380 : ReferenceToType( n, q, std::move(as) ), base() {}
381 EnumInstType( const EnumDecl * b, CV::Qualifiers q = {},
382 std::vector<ptr<Attribute>> && as = {} );
383
384 bool isComplete() const override;
385
386 const EnumDecl * aggr() const override { return base; }
387
388 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
389private:
390 EnumInstType * clone() const override { return new EnumInstType{ *this }; }
391 MUTATE_FRIEND
392};
393
394/// instance of trait type
395class TraitInstType final : public ReferenceToType {
396public:
397 readonly<TraitDecl> base;
398
399 TraitInstType( const std::string& n, CV::Qualifiers q = {},
400 std::vector<ptr<Attribute>> && as = {} )
401 : ReferenceToType( n, q, std::move(as) ), base() {}
402 TraitInstType( const TraitDecl * b, CV::Qualifiers q = {},
403 std::vector<ptr<Attribute>> && as = {} );
404
405 // not meaningful for TraitInstType
406 bool isComplete() const override { assert(false); }
407
408 const TraitDecl * aggr() const override { return base; }
409
410 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
411private:
412 TraitInstType * clone() const override { return new TraitInstType{ *this }; }
413 MUTATE_FRIEND
414};
415
416/// instance of named type alias (typedef or variable)
417class TypeInstType final : public ReferenceToType {
418public:
419 readonly<TypeDecl> base;
420 TypeVar::Kind kind;
421
422 TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {},
423 std::vector<ptr<Attribute>> && as = {} )
424 : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {}
425 TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {},
426 std::vector<ptr<Attribute>> && as = {} )
427 : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {}
428
429 /// sets `base`, updating `kind` correctly
430 void set_base( const TypeDecl * );
431
432 bool isComplete() const override;
433
434 // not meaningful for TypeInstType
435 const AggregateDecl * aggr() const override { assert(false); }
436
437 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
438private:
439 TypeInstType * clone() const override { return new TypeInstType{ *this }; }
440 MUTATE_FRIEND
441};
442
443/// tuple type e.g. `[int, char]`
444class TupleType final : public Type {
445public:
446 std::vector<ptr<Type>> types;
447 std::vector<ptr<Decl>> members;
448
449 TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q = {} );
450
451 // collection simulation
452 using iterator = std::vector<ptr<Type>>::const_iterator;
453 iterator begin() const { return types.begin(); }
454 iterator end() const { return types.end(); }
455
456 unsigned size() const override { return types.size(); }
457
458 const Type * getComponent( unsigned i ) const override {
459 assertf( i < size(), "TupleType::getComponent: index %d must be less than size %d",
460 i, size() );
461 return *(begin()+i);
462 }
463
464 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
465private:
466 TupleType * clone() const override { return new TupleType{ *this }; }
467 MUTATE_FRIEND
468};
469
470/// Type of unresolved `typeof()` expression
471class TypeofType : public Type {
472public:
473 ptr<Expr> expr;
474 enum Kind { Typeof, Basetypeof } kind;
475
476 TypeofType( const Expr * e, Kind k = Typeof, CV::Qualifiers q = {} )
477 : Type(q), expr(e), kind(k) {}
478
479 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
480private:
481 TypeofType * clone() const override { return new TypeofType{ *this }; }
482 MUTATE_FRIEND
483};
484
485/// GCC built-in varargs type
486class VarArgsType final : public Type {
487public:
488 VarArgsType( CV::Qualifiers q = {} ) : Type( q ) {}
489
490 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
491private:
492 VarArgsType * clone() const override { return new VarArgsType{ *this }; }
493 MUTATE_FRIEND
494};
495
496/// Type of zero constant `0`
497class ZeroType final : public Type {
498public:
499 ZeroType( CV::Qualifiers q = {} ) : Type( q ) {}
500
501 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
502private:
503 ZeroType * clone() const override { return new ZeroType{ *this }; }
504 MUTATE_FRIEND
505};
506
507/// Type of one constant `1`
508class OneType final : public Type {
509public:
510 OneType( CV::Qualifiers q = {} ) : Type( q ) {}
511
512 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
513private:
514 OneType * clone() const override { return new OneType{ *this }; }
515 MUTATE_FRIEND
516};
517
518/// Parent type for scope-qualified types at global scope
519class GlobalScopeType final : public Type {
520public:
521 GlobalScopeType() : Type() {}
522
523 const Type * accept( Visitor & v ) const override { return v.visit( this ); }
524private:
525 GlobalScopeType * clone() const override { return new GlobalScopeType{ *this }; }
526 MUTATE_FRIEND
527};
528
529}
530
531#undef MUTATE_FRIEND
532
533// Local Variables: //
534// tab-width: 4 //
535// mode: c++ //
536// compile-command: "make install" //
537// End: //
Note: See TracBrowser for help on using the repository browser.