source: src/Parser/DeclarationNode.h @ 44adf1b

Last change on this file since 44adf1b was dc3fbe5, checked in by Andrew Beach <ajbeach@…>, 4 months ago

Factored out the ParseNode?'s next field into a new child type. This is only type safe when used in the given one level curiously reoccurring template pattern, as it is now. This allowed most of the intermedate helpers to be removed.

  • Property mode set to 100644
File size: 9.1 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// DeclarationNode.h --
8//
9// Author           : Andrew Beach
10// Created On       : Wed Apr  5 11:38:00 2023
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Feb 17 09:24:12 2024
13// Update Count     : 4
14//
15
16#pragma once
17
18#include "ParseNode.h"
19
20struct TypeData;
21struct InitializerNode;
22
23struct DeclarationNode final : public ParseList<DeclarationNode> {
24        // These enumerations must harmonize with their names in DeclarationNode.cc.
25        enum BasicType {
26                Void, Bool, Char, Int, Int128,
27                Float, Double, LongDouble, uuFloat80, uuFloat128,
28                uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x,
29                NoBasicType
30        };
31        static const char * basicTypeNames[];
32        enum ComplexType { Complex, NoComplexType, Imaginary };
33        // Imaginary unsupported => parse, but make invisible and print error message
34        static const char * complexTypeNames[];
35        enum Signedness { Signed, Unsigned, NoSignedness };
36        static const char * signednessNames[];
37        enum Length { Short, Long, LongLong, NoLength };
38        static const char * lengthNames[];
39        enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };
40        static const char * builtinTypeNames[];
41
42        static DeclarationNode * newStorageClass( ast::Storage::Classes );
43        static DeclarationNode * newFuncSpecifier( ast::Function::Specs );
44        static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );
45        static DeclarationNode * newBasicType( BasicType );
46        static DeclarationNode * newComplexType( ComplexType );
47        static DeclarationNode * newSignedNess( Signedness );
48        static DeclarationNode * newLength( Length );
49        static DeclarationNode * newBuiltinType( BuiltinType );
50        static DeclarationNode * newForall( DeclarationNode * );
51        static DeclarationNode * newFromTypedef( const std::string * );
52        static DeclarationNode * newFromGlobalScope();
53        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
54        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
55        static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
56        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
57        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
58        static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );
59        static DeclarationNode * newEnumInLine( const std::string name );
60        static DeclarationNode * newName( const std::string * );
61        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
62        static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );
63        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
64        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
65        static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );
66        static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );
67        static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );
68        static DeclarationNode * newVarArray( DeclarationNode * qualifiers );
69        static DeclarationNode * newBitfield( ExpressionNode * size );
70        static DeclarationNode * newTuple( DeclarationNode * members );
71        static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );
72        static DeclarationNode * newVtableType( DeclarationNode * expr );
73        static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes
74        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
75        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
76        static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
77
78        DeclarationNode();
79        ~DeclarationNode();
80        DeclarationNode * clone() const override;
81
82        DeclarationNode * addQualifiers( DeclarationNode * );
83        void checkQualifiers( const TypeData *, const TypeData * );
84        void checkSpecifiers( DeclarationNode * );
85        DeclarationNode * copySpecifiers( DeclarationNode *, bool = true );
86        DeclarationNode * addType( DeclarationNode *, bool = true );
87        DeclarationNode * addTypedef();
88        DeclarationNode * addEnumBase( DeclarationNode * );
89        DeclarationNode * addAssertions( DeclarationNode * );
90        DeclarationNode * addName( std::string * );
91        DeclarationNode * addAsmName( DeclarationNode * );
92        DeclarationNode * addBitfield( ExpressionNode * size );
93        DeclarationNode * addVarArgs();
94        DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );
95        DeclarationNode * addOldDeclList( DeclarationNode * list );
96        DeclarationNode * setBase( TypeData * newType );
97        DeclarationNode * copyAttribute( DeclarationNode * attr );
98        DeclarationNode * addPointer( DeclarationNode * qualifiers );
99        DeclarationNode * addArray( DeclarationNode * array );
100        DeclarationNode * addNewPointer( DeclarationNode * pointer );
101        DeclarationNode * addNewArray( DeclarationNode * array );
102        DeclarationNode * addParamList( DeclarationNode * list );
103        DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions
104        DeclarationNode * addInitializer( InitializerNode * init );
105        DeclarationNode * addTypeInitializer( DeclarationNode * init );
106
107        DeclarationNode * cloneType( std::string * newName );
108        DeclarationNode * cloneBaseType( DeclarationNode * newdecl, bool = true );
109
110        virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
111        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
112
113        ast::Decl * build() const;
114        ast::Type * buildType() const;
115
116        ast::Linkage::Spec get_linkage() const { return linkage; }
117        DeclarationNode * extractAggregate() const;
118        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
119        ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }
120
121        bool get_extension() const { return extension; }
122        DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }
123
124        bool get_inLine() const { return inLine; }
125        DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }
126
127        const std::string * name = nullptr;
128
129        struct Variable_t {
130//              const std::string * name;
131                ast::TypeDecl::Kind tyClass;
132                DeclarationNode * assertions;
133                DeclarationNode * initializer;
134        };
135        Variable_t variable;
136
137        struct StaticAssert_t {
138                ExpressionNode * condition;
139                ast::Expr * message;
140        };
141        StaticAssert_t assert;
142
143        BuiltinType builtin = NoBuiltinType;
144
145        TypeData * type = nullptr;
146
147        bool inLine = false;
148        bool enumInLine = false;
149        ast::Function::Specs funcSpecs;
150        ast::Storage::Classes storageClasses;
151
152        ExpressionNode * bitfieldWidth = nullptr;
153        std::unique_ptr<ExpressionNode> enumeratorValue;
154        bool hasEllipsis = false;
155        ast::Linkage::Spec linkage;
156        ast::Expr * asmName = nullptr;
157        std::vector<ast::ptr<ast::Attribute>> attributes;
158        InitializerNode * initializer = nullptr;
159        bool extension = false;
160        std::string error;
161        StatementNode * asmStmt = nullptr;
162        StatementNode * directiveStmt = nullptr;
163
164        static UniqueName anonymous;
165}; // DeclarationNode
166
167ast::Type * buildType( TypeData * type );
168
169static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {
170        ast::Type * ret = orig ? orig->buildType() : nullptr;
171        delete orig;
172        return ret;
173}
174
175// This generic buildList is here along side its overloads.
176template<typename AstType, typename NodeType,
177                template<typename, typename...> class Container, typename... Args>
178void buildList( NodeType * firstNode,
179                Container<ast::ptr<AstType>, Args...> & output ) {
180        SemanticErrorException errors;
181        std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );
182
183        for ( NodeType * cur = firstNode ; cur ; cur = cur->next ) {
184                try {
185                        AstType * node = dynamic_cast<AstType *>( maybeBuild( cur ) );
186                        assertf( node, "buildList: Did not build node of correct type." );
187                        *out++ = node;
188                } catch ( SemanticErrorException & e ) {
189                        errors.append( e );
190                } // try
191        } // for
192        if ( ! errors.isEmpty() ) {
193                throw errors;
194        } // if
195}
196
197void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList );
198void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList );
199void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );
200
201template<typename AstType, typename NodeType,
202                template<typename, typename...> class Container, typename... Args>
203void buildMoveList( NodeType * firstNode,
204                Container<ast::ptr<AstType>, Args...> & output ) {
205        buildList<AstType, NodeType, Container, Args...>( firstNode, output );
206        delete firstNode;
207}
Note: See TracBrowser for help on using the repository browser.