source: src/AST/Type.cpp @ 63d1ebe

ADTast-experimental
Last change on this file since 63d1ebe was 63d1ebe, checked in by Andrew Beach <ajbeach@…>, 19 months ago

Changed GenPoly::TypeVarMap? to use the same key type as ast::TypeSubstitution?.

  • Property mode set to 100644
File size: 6.5 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.cpp --
8//
9// Author           : Aaron B. Moss
10// Created On       : Mon May 13 15:00:00 2019
11// Last Modified By : Andrew Beach
12// Last Modified On : Thu Jul 23 14:16:00 2020
13// Update Count     : 5
14//
15
16#include "Type.hpp"
17
18#include <cassert>
19#include <utility>               // for move
20#include <vector>
21
22#include "Decl.hpp"
23#include "Init.hpp"
24#include "Inspect.hpp"
25#include "Common/utility.h"      // for copy, move
26#include "Tuples/Tuples.h"       // for isTtype
27
28namespace ast {
29
30const Type * Type::getComponent( unsigned i ) const {
31        assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i );
32        return this;
33}
34
35const Type * Type::stripDeclarator() const {
36        const Type * t;
37        const Type * a;
38        for ( t = this; (a = ast::getPointerBase( t )); t = a );
39        return t;
40}
41
42const Type * Type::stripReferences() const {
43        const Type * t;
44        const ReferenceType * r;
45        for ( t = this; (r = dynamic_cast<const ReferenceType *>(t) ); t = r->base );
46        return t;
47}
48
49// --- BasicType
50
51// GENERATED START, DO NOT EDIT
52// GENERATED BY BasicTypes-gen.cc
53const char * BasicType::typeNames[] = {
54        "_Bool",
55        "char",
56        "signed char",
57        "unsigned char",
58        "signed short int",
59        "unsigned short int",
60        "signed int",
61        "unsigned int",
62        "signed long int",
63        "unsigned long int",
64        "signed long long int",
65        "unsigned long long int",
66        "__int128",
67        "unsigned __int128",
68        "_Float16",
69        "_Float16 _Complex",
70        "_Float32",
71        "_Float32 _Complex",
72        "float",
73        "float _Complex",
74        "_Float32x",
75        "_Float32x _Complex",
76        "_Float64",
77        "_Float64 _Complex",
78        "double",
79        "double _Complex",
80        "_Float64x",
81        "_Float64x _Complex",
82        "__float80",
83        "_Float128",
84        "_Float128 _Complex",
85        "__float128",
86        "long double",
87        "long double _Complex",
88        "_Float128x",
89        "_Float128x _Complex",
90};
91// GENERATED END
92
93// --- FunctionType
94namespace {
95        bool containsTtype( const std::vector<ptr<Type>> & l ) {
96                if ( ! l.empty() ) {
97                        return Tuples::isTtype( l.back() );
98                }
99                return false;
100        }
101}
102
103bool FunctionType::isTtype() const {
104        return containsTtype( returns ) || containsTtype( params );
105}
106
107// --- BaseInstType
108
109std::vector<readonly<Decl>> BaseInstType::lookup( const std::string& name ) const {
110        assertf( aggr(), "Must have aggregate to perform lookup" );
111
112        std::vector<readonly<Decl>> found;
113        for ( const Decl * decl : aggr()->members ) {
114                if ( decl->name == name ) { found.emplace_back( decl ); }
115        }
116        return found;
117}
118
119// --- SueInstType (StructInstType, UnionInstType, EnumInstType)
120
121template<typename decl_t>
122SueInstType<decl_t>::SueInstType(
123        const base_type * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
124: BaseInstType( b->name, q, std::move(as) ), base( b ) {}
125
126template<typename decl_t>
127SueInstType<decl_t>::SueInstType(
128        const base_type * b, std::vector<ptr<Expr>> && params,
129        CV::Qualifiers q, std::vector<ptr<Attribute>> && as )
130: BaseInstType( b->name, std::move(params), q, std::move(as) ), base( b ) {}
131
132template<typename decl_t>
133bool SueInstType<decl_t>::isComplete() const {
134        return base ? base->body : false;
135}
136
137template class SueInstType<StructDecl>;
138template class SueInstType<UnionDecl>;
139template class SueInstType<EnumDecl>;
140
141// --- TraitInstType
142
143TraitInstType::TraitInstType(
144        const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )
145: BaseInstType( b->name, q, std::move(as) ), base( b ) {}
146
147// --- TypeInstType
148
149bool TypeInstType::operator==( const TypeInstType & other ) const {
150        return base == other.base
151                && formal_usage == other.formal_usage
152                && expr_id == other.expr_id;
153}
154
155TypeInstType::TypeInstType( const TypeDecl * b,
156        CV::Qualifiers q, std::vector<ptr<Attribute>> && as )
157: BaseInstType( b->name, q, std::move(as) ), base( b ), kind( b->kind ) {}
158
159void TypeInstType::set_base( const TypeDecl * b ) {
160        base = b;
161        kind = b->kind;
162}
163
164bool TypeInstType::isComplete() const { return base->sized; }
165
166std::string TypeInstType::TypeEnvKey::typeString() const {
167        return std::string("_") + std::to_string(formal_usage)
168                + "_" + std::to_string(expr_id) + "_" + base->name;
169}
170
171bool TypeInstType::TypeEnvKey::operator==(
172                const TypeInstType::TypeEnvKey & other ) const {
173        return base == other.base
174                && formal_usage == other.formal_usage
175                && expr_id == other.expr_id;
176}
177
178bool TypeInstType::TypeEnvKey::operator<(
179                const TypeInstType::TypeEnvKey & other ) const {
180        // TypeEnvKey ordering is an arbitrary total ordering.
181        // It doesn't mean anything but allows for a sorting.
182        if ( base < other.base ) {
183                return true;
184        } else if ( other.base < base ) {
185                return false;
186        } else if ( formal_usage < other.formal_usage ) {
187                return true;
188        } else if ( other.formal_usage < formal_usage ) {
189                return false;
190        } else {
191                return expr_id < other.expr_id;
192        }
193}
194
195// --- TupleType
196
197TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q )
198: Type( q ), types( std::move(ts) ), members() {
199        // This constructor is awkward. `TupleType` needs to contain objects so that members can be
200        // named, but members without initializer nodes end up getting constructors, which breaks
201        // things. This happens because the object decls have to be visited so that their types are
202        // kept in sync with the types listed here. Ultimately, the types listed here should perhaps
203        // be eliminated and replaced with a list-view over members. The temporary solution is to
204        // make a `ListInit` with `maybeConstructed = false`, so when the object is visited it is not
205        // constructed. Potential better solutions include:
206        //   a) Separate `TupleType` from its declarations, into `TupleDecl` and `Tuple{Inst?}Type`,
207        //      similar to the aggregate types.
208        //   b) Separate initializer nodes better, e.g. add a `MaybeConstructed` node that is replaced
209        //      by `genInit`, rather than the current boolean flag.
210        members.reserve( types.size() );
211        for ( const Type * ty : types ) {
212                members.emplace_back( new ObjectDecl{
213                        CodeLocation(), "", ty, new ListInit( CodeLocation(), {}, {}, NoConstruct ),
214                        Storage::Classes{}, Linkage::Cforall } );
215        }
216}
217
218bool isUnboundType(const Type * type) {
219        if (auto typeInst = dynamic_cast<const TypeInstType *>(type)) {
220                // xxx - look for a type name produced by renameTyVars.
221
222                // TODO: once TypeInstType representation is updated, it should properly check
223                // if the context id is filled. this is a temporary hack for now
224                return typeInst->formal_usage > 0;
225        }
226        return false;
227}
228
229}
230
231// Local Variables: //
232// tab-width: 4 //
233// mode: c++ //
234// compile-command: "make install" //
235// End: //
Note: See TracBrowser for help on using the repository browser.