source: src/AST/Decl.hpp @ 10a9479d

Last change on this file since 10a9479d was 90be0cf, checked in by Andrew Beach <ajbeach@…>, 8 weeks ago

Moved some methods out of EnumDecl?. These were calculations and the ast types are supposed to be data focused so they should either go with utility functions or to their use site. I tried the use site.

  • Property mode set to 100644
File size: 15.0 KB
RevLine 
[2bb4a01]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// Decl.hpp --
8//
9// Author           : Aaron B. Moss
10// Created On       : Thu May 9 10:00:00 2019
[7edd5c1]11// Last Modified By : Andrew Beach
[3e94a23]12// Last Modified On : Wed Apr  5 10:42:00 2023
13// Update Count     : 35
[2bb4a01]14//
15
16#pragma once
17
[d76c588]18#include <iosfwd>
[a300e4a]19#include <string>              // for string, to_string
20#include <unordered_map>
[2bb4a01]21#include <vector>
[07de76b]22#include <algorithm>
[2bb4a01]23
[a300e4a]24#include "FunctionSpec.hpp"
[2bb4a01]25#include "Fwd.hpp"             // for UniqueId
26#include "LinkageSpec.hpp"
27#include "Node.hpp"            // for ptr, readonly
28#include "ParseNode.hpp"
29#include "StorageClasses.hpp"
30#include "Visitor.hpp"
31
[f3cc5b6]32// Must be included in *all* AST classes; should be #undef'd at the end of the file
[99da267]33#define MUTATE_FRIEND \
[91a72ef]34        template<typename node_t> friend node_t * mutate(const node_t * node); \
[99da267]35        template<typename node_t> friend node_t * shallowCopy(const node_t * node);
[f3cc5b6]36
[2bb4a01]37namespace ast {
[a300e4a]38
[2bb4a01]39/// Base declaration class
40class Decl : public ParseNode {
41public:
42        std::string name;
43        Storage::Classes storage;
44        Linkage::Spec linkage;
45        UniqueId uniqueId = 0;
46        bool extension = false;
47
[14cebb7a]48        Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
[2bb4a01]49                Linkage::Spec linkage )
50        : ParseNode( loc ), name( name ), storage( storage ), linkage( linkage ) {}
51
52        /// Ensures this node has a unique ID
53        void fixUniqueId();
54
[23f99e1]55        const Decl * accept( Visitor & v ) const override = 0;
[2bb4a01]56private:
[23f99e1]57        Decl * clone() const override = 0;
[f3cc5b6]58        MUTATE_FRIEND
[2bb4a01]59};
60
61/// Typed declaration base class
62class DeclWithType : public Decl {
63public:
64        /// Represents the type with all types and typedefs expanded.
65        std::string mangleName;
[14cebb7a]66        /// Stores the scope level at which the variable was declared.
[2bb4a01]67        /// Used to access shadowed identifiers.
68        int scopeLevel = 0;
69
70        std::vector<ptr<Attribute>> attributes;
[a300e4a]71        Function::Specs funcSpec;
[2bb4a01]72        ptr<Expr> asmName;
73        bool isDeleted = false;
[16ba4a6f]74        bool isTypeFixed = false;
[85855b0]75        bool isHidden = false;
[2bb4a01]76
[14cebb7a]77        DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
[2bb4a01]78                Linkage::Spec linkage, std::vector<ptr<Attribute>>&& attrs, Function::Specs fs )
[14cebb7a]79        : Decl( loc, name, storage, linkage ), mangleName(), attributes( std::move(attrs) ),
[a300e4a]80                funcSpec(fs), asmName() {}
[14cebb7a]81
[a300e4a]82        std::string scopedMangleName() const { return mangleName + "_" + std::to_string(scopeLevel); }
83
84        /// Get type of this declaration. May be generated by subclass
[6d51bd7]85        virtual const Type * get_type() const = 0;
[a300e4a]86        /// Set type of this declaration. May be verified by subclass
[e0e9a0b]87        virtual void set_type( const Type * ) = 0;
[a300e4a]88
[23f99e1]89        const DeclWithType * accept( Visitor & v ) const override = 0;
[a300e4a]90private:
[23f99e1]91        DeclWithType * clone() const override = 0;
[f3cc5b6]92        MUTATE_FRIEND
[a300e4a]93};
94
[77a3f41]95/// Object declaration `Foo foo = 42;`
96class ObjectDecl final : public DeclWithType {
97public:
98        ptr<Type> type;
99        ptr<Init> init;
100        ptr<Expr> bitfieldWidth;
101
[e67991f]102        ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type,
103                const Init * init = nullptr, Storage::Classes storage = {},
[e8616b6]104                Linkage::Spec linkage = Linkage::Cforall, const Expr * bitWd = nullptr,
[2a8f0c1]105                std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
[14cebb7a]106        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
[77a3f41]107          init( init ), bitfieldWidth( bitWd ) {}
[14cebb7a]108
[77a3f41]109        const Type* get_type() const override { return type; }
[e0e9a0b]110        void set_type( const Type * ty ) override { type = ty; }
[77a3f41]111
[23f99e1]112        const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); }
[77a3f41]113private:
[23f99e1]114        ObjectDecl * clone() const override { return new ObjectDecl{ *this }; }
[f3cc5b6]115        MUTATE_FRIEND
[23f99e1]116};
117
[3e94a23]118/// Function variable arguments flag
119enum ArgumentFlag { FixedArgs, VariableArgs };
120
[2d6add4]121/// Function declaration `int foo()`
[a1da039]122class FunctionDecl final : public DeclWithType {
[23f99e1]123public:
[a00a2c1]124        std::vector<ptr<TypeDecl>> type_params;
125        std::vector<ptr<DeclWithType>> assertions;
[b859f59]126        std::vector<ptr<DeclWithType>> params;
127        std::vector<ptr<DeclWithType>> returns;
[954c954]128        // declared type, derived from parameter declarations
[23f99e1]129        ptr<FunctionType> type;
[b8ab91a]130        /// Null for the forward declaration of a function.
[23f99e1]131        ptr<CompoundStmt> stmts;
[d76c588]132        std::vector< ptr<Expr> > withExprs;
[23f99e1]133
[37273c8]134        /// Monomorphic Function Constructor:
135        FunctionDecl( const CodeLocation & locaction, const std::string & name,
[954c954]136                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
[3992098]137                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
[3e94a23]138                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, ArgumentFlag isVarArgs = FixedArgs );
[7edd5c1]139
[37273c8]140        /// Polymorphic Function Constructor:
[7edd5c1]141        FunctionDecl( const CodeLocation & location, const std::string & name,
142                std::vector<ptr<TypeDecl>>&& forall, std::vector<ptr<DeclWithType>>&& assertions,
143                std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,
[3992098]144                CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
[3e94a23]145                std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}, ArgumentFlag isVarArgs = FixedArgs );
[23f99e1]146
[8a5530c]147        const Type * get_type() const override;
[e0e9a0b]148        void set_type( const Type * t ) override;
[23f99e1]149
150        bool has_body() const { return stmts; }
151
[07de76b]152        const DeclWithType * accept( Visitor & v ) const override { return v.visit( this ); }
[23f99e1]153private:
154        FunctionDecl * clone() const override { return new FunctionDecl( *this ); }
[f3cc5b6]155        MUTATE_FRIEND
[77a3f41]156};
157
[360b2e13]158/// Base class for named type aliases
159class NamedTypeDecl : public Decl {
160public:
161        ptr<Type> base;
162        std::vector<ptr<DeclWithType>> assertions;
163
[7030dab]164        NamedTypeDecl(
[e0e9a0b]165                const CodeLocation & loc, const std::string & name, Storage::Classes storage,
166                const Type * b, Linkage::Spec spec = Linkage::Cforall )
[6a45bd78]167        : Decl( loc, name, storage, spec ), base( b ), assertions() {}
[360b2e13]168
169        /// Produces a name for the kind of alias
[312029a]170        virtual const char * typeString() const = 0;
[360b2e13]171
172private:
173        NamedTypeDecl* clone() const override = 0;
[f3cc5b6]174        MUTATE_FRIEND
[360b2e13]175};
176
177/// Cforall type variable: `dtype T`
178class TypeDecl final : public NamedTypeDecl {
[07de76b]179  public:
[6e50a6b]180        enum Kind { Dtype, DStype, Otype, Ftype, Ttype, Dimension, NUMBER_OF_KINDS };
[07de76b]181
182        Kind kind;
[360b2e13]183        bool sized;
184        ptr<Type> init;
185
[7030dab]186        TypeDecl(
187                const CodeLocation & loc, const std::string & name, Storage::Classes storage,
[e3bc51c]188                const Type * b, TypeDecl::Kind k, bool s, const Type * i = nullptr )
189        : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeDecl::Ttype || s ),
[9e1d485]190          init( i ) {}
[360b2e13]191
[312029a]192        const char * typeString() const override;
[360b2e13]193        /// Produces a name for generated code
[312029a]194        const char * genTypeString() const;
[360b2e13]195
[9e1d485]196        /// convenience accessor to match Type::isComplete()
[3606fe4]197        bool isComplete() const { return sized; }
[9e1d485]198
[23f99e1]199        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
[07de76b]200  private:
[23f99e1]201        TypeDecl * clone() const override { return new TypeDecl{ *this }; }
[f3cc5b6]202        MUTATE_FRIEND
[360b2e13]203};
204
[93c10de]205/// Data extracted from a TypeDecl.
206struct TypeData {
207        TypeDecl::Kind kind;
208        bool isComplete;
209
210        TypeData() : kind( TypeDecl::NUMBER_OF_KINDS ), isComplete( false ) {}
211        TypeData( const TypeDecl * d ) : kind( d->kind ), isComplete( d->sized ) {}
212        TypeData( TypeDecl::Kind k, bool c ) : kind( k ), isComplete( c ) {}
213        TypeData( const TypeData & d1, const TypeData & d2 )
214                : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {}
215
216        bool operator==( const TypeData & o ) const { return kind == o.kind && isComplete == o.isComplete; }
217        bool operator!=( const TypeData & o ) const { return !(*this == o); }
218};
219
220std::ostream & operator<< ( std::ostream &, const TypeData & );
[d76c588]221
[360b2e13]222/// C-style typedef `typedef Foo Bar`
223class TypedefDecl final : public NamedTypeDecl {
224public:
[e0115286]225        TypedefDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
[360b2e13]226                Type* b, Linkage::Spec spec = Linkage::Cforall )
227        : NamedTypeDecl( loc, name, storage, b, spec ) {}
228
[312029a]229        const char * typeString() const override { return "typedef"; }
[360b2e13]230
[23f99e1]231        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
[360b2e13]232private:
[23f99e1]233        TypedefDecl * clone() const override { return new TypedefDecl{ *this }; }
[f3cc5b6]234        MUTATE_FRIEND
[360b2e13]235};
236
[a300e4a]237/// Aggregate type declaration base class
238class AggregateDecl : public Decl {
239public:
[312029a]240        enum Aggregate { Struct, Union, Enum, Exception, Trait, Generator, Coroutine, Monitor, Thread, NoAggregate };
241        static const char * aggrString( Aggregate aggr );
242
[a300e4a]243        std::vector<ptr<Decl>> members;
[54e41b3]244        std::vector<ptr<TypeDecl>> params;
[a300e4a]245        std::vector<ptr<Attribute>> attributes;
246        bool body = false;
247        readonly<AggregateDecl> parent = {};
248
[14cebb7a]249        AggregateDecl( const CodeLocation& loc, const std::string& name,
[a300e4a]250                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
[54e41b3]251        : Decl( loc, name, Storage::Classes{}, linkage ), members(), params(),
[a300e4a]252          attributes( std::move(attrs) ) {}
[14cebb7a]253
[a300e4a]254        AggregateDecl* set_body( bool b ) { body = b; return this; }
255
[ed3935da]256        /// Produces a name for the kind of aggregate
[312029a]257        virtual const char * typeString() const = 0;
[ed3935da]258
[f3cc5b6]259private:
260        AggregateDecl * clone() const override = 0;
261        MUTATE_FRIEND
[a300e4a]262};
263
264/// struct declaration `struct Foo { ... };`
265class StructDecl final : public AggregateDecl {
266public:
[312029a]267        Aggregate kind;
[a300e4a]268
[14cebb7a]269        StructDecl( const CodeLocation& loc, const std::string& name,
[312029a]270                Aggregate kind = Struct,
[a300e4a]271                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
272        : AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {}
273
[3cc1111]274        bool is_coroutine() const { return kind == Coroutine; }
275        bool is_generator() const { return kind == Generator; }
276        bool is_monitor  () const { return kind == Monitor  ; }
277        bool is_thread   () const { return kind == Thread   ; }
[a300e4a]278
[23f99e1]279        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
[ed3935da]280
[312029a]281        const char * typeString() const override { return aggrString( kind ); }
[ed3935da]282
[a300e4a]283private:
[23f99e1]284        StructDecl * clone() const override { return new StructDecl{ *this }; }
[f3cc5b6]285        MUTATE_FRIEND
[a300e4a]286};
287
288/// union declaration `union Foo { ... };`
289class UnionDecl final : public AggregateDecl {
290public:
[14cebb7a]291        UnionDecl( const CodeLocation& loc, const std::string& name,
[a300e4a]292                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
293        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
294
[23f99e1]295        const Decl * accept( Visitor& v ) const override { return v.visit( this ); }
[ed3935da]296
[312029a]297        const char * typeString() const override { return aggrString( Union ); }
[ed3935da]298
[a300e4a]299private:
[23f99e1]300        UnionDecl * clone() const override { return new UnionDecl{ *this }; }
[f3cc5b6]301        MUTATE_FRIEND
[a300e4a]302};
303
[90be0cf]304/// Enumeration attribute kind.
[af746cc]305enum class EnumAttribute{ Value, Posn, Label };
[90be0cf]306
[a300e4a]307/// enum declaration `enum Foo { ... };`
308class EnumDecl final : public AggregateDecl {
309public:
[5ccc733]310        // isCfa indicated if the enum has a declaration like:
[94c98f0e]311        // enum (type_optional) Name {...}
[5ccc733]312        bool isCfa;
[8c55d34]313        // if isCfa == true && base.get() == nullptr, it is a "opaque" enum
[a1da039]314        ptr<Type> base;
[e4d7c1c]315        enum class EnumHiding { Visible, Hide } hide;
[85855b0]316        std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums
317
[5ccc733]318        EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false,
[b0d9ff7]319                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall,
[e4d7c1c]320                Type const * base = nullptr, EnumHiding hide = EnumHiding::Hide,
[7b71402]321                std::unordered_map< std::string, long long > enumValues = std::unordered_map< std::string, long long >() )
[5ccc733]322        : AggregateDecl( loc, name, std::move(attrs), linkage ), isCfa(isCfa), base(base), hide(hide), enumValues(enumValues) {}
[a300e4a]323
324        /// gets the integer value for this enumerator, returning true iff value found
[f135b50]325        // Maybe it is not used in producing the enum value
[9d6e7fa9]326        bool valueOf( const Decl * enumerator, long long& value ) const;
[a300e4a]327
[23f99e1]328        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
[ed3935da]329
[312029a]330        const char * typeString() const override { return aggrString( Enum ); }
[ed3935da]331
[5ccc733]332        bool isTyped() const;
[8c55d34]333        bool isOpaque() const;
[a300e4a]334private:
[23f99e1]335        EnumDecl * clone() const override { return new EnumDecl{ *this }; }
[f3cc5b6]336        MUTATE_FRIEND
[a300e4a]337
338        /// Map from names to enumerator values; kept private for lazy initialization
339        mutable std::unordered_map< std::string, long long > enumValues;
340};
341
342/// trait declaration `trait Foo( ... ) { ... };`
343class TraitDecl final : public AggregateDecl {
344public:
[14cebb7a]345        TraitDecl( const CodeLocation& loc, const std::string& name,
[a300e4a]346                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
347        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
348
[23f99e1]349        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
[ed3935da]350
[312029a]351        const char * typeString() const override { return "trait"; }
[ed3935da]352
[a300e4a]353private:
[23f99e1]354        TraitDecl * clone() const override { return new TraitDecl{ *this }; }
[f3cc5b6]355        MUTATE_FRIEND
[2bb4a01]356};
357
[e67991f]358/// With statement `with (...) ...`
[6a0b043]359/// This is a statement lexically, but a Decl is needed for the SymbolTable.
[e67991f]360class WithStmt final : public Decl {
361public:
362        std::vector<ptr<Expr>> exprs;
363        ptr<Stmt> stmt;
364
365        WithStmt( const CodeLocation & loc, std::vector<ptr<Expr>> && exprs, const Stmt * stmt )
366        : Decl(loc, "", Storage::Auto, Linkage::Cforall), exprs(std::move(exprs)), stmt(stmt) {}
367
368        const Decl * accept( Visitor & v ) const override { return v.visit( this ); }
369private:
370        WithStmt * clone() const override { return new WithStmt{ *this }; }
371        MUTATE_FRIEND
372};
373
[94c98f0e]374/// Assembly declaration: `asm ... ( "..." : ... )`
[a1da039]375class AsmDecl final : public Decl {
[23f99e1]376public:
377        ptr<AsmStmt> stmt;
378
[07de76b]379        AsmDecl( const CodeLocation & loc, AsmStmt * stmt )
[a1da039]380        : Decl( loc, "", {}, Linkage::C ), stmt(stmt) {}
[23f99e1]381
[07de76b]382        const AsmDecl * accept( Visitor & v ) const override { return v.visit( this ); }
[23f99e1]383private:
[07de76b]384        AsmDecl * clone() const override { return new AsmDecl( *this ); }
[f3cc5b6]385        MUTATE_FRIEND
[23f99e1]386};
387
[2d019af]388/// C-preprocessor directive `#...`
[a1da039]389class DirectiveDecl final : public Decl {
[2d019af]390public:
391        ptr<DirectiveStmt> stmt;
392
393        DirectiveDecl( const CodeLocation & loc, DirectiveStmt * stmt )
[a1da039]394        : Decl( loc, "", {}, Linkage::C ), stmt(stmt) {}
[2d019af]395
396        const DirectiveDecl * accept( Visitor & v ) const override { return v.visit( this ); }
397private:
398        DirectiveDecl * clone() const override { return new DirectiveDecl( *this ); }
399        MUTATE_FRIEND
400};
401
[19a8c40]402/// Static Assertion `_Static_assert( ... , ... );`
[a1da039]403class StaticAssertDecl final : public Decl {
[23f99e1]404public:
[112fe04]405        ptr<Expr> cond;
[23f99e1]406        ptr<ConstantExpr> msg;   // string literal
407
408        StaticAssertDecl( const CodeLocation & loc, const Expr * condition, const ConstantExpr * msg )
[a1da039]409        : Decl( loc, "", {}, Linkage::C ), cond( condition ), msg( msg ) {}
[23f99e1]410
[07de76b]411        const StaticAssertDecl * accept( Visitor & v ) const override { return v.visit( this ); }
[23f99e1]412private:
413        StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); }
[f3cc5b6]414        MUTATE_FRIEND
[23f99e1]415};
[e0115286]416
[19a8c40]417/// Inline Member Declaration `inline TypeName;`
[71806e0]418class InlineMemberDecl final : public DeclWithType {
[e874605]419public:
420        ptr<Type> type;
421
[71806e0]422        InlineMemberDecl( const CodeLocation & loc, const std::string & name, const Type * type,
[e874605]423                Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
424                std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
425        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ) {}
426
427        const Type * get_type() const override { return type; }
428        void set_type( const Type * ty ) override { type = ty; }
429
430        const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); }
431private:
[71806e0]432        InlineMemberDecl * clone() const override { return new InlineMemberDecl{ *this }; }
[e874605]433        MUTATE_FRIEND
434};
[19a8c40]435
[2bb4a01]436}
437
[f3cc5b6]438#undef MUTATE_FRIEND
439
[2bb4a01]440// Local Variables: //
441// tab-width: 4 //
442// mode: c++ //
443// compile-command: "make install" //
444// End: //
Note: See TracBrowser for help on using the repository browser.