source: src/Parser/DeclarationNode.h@ 924534e

Last change on this file since 924534e was dc3fbe5, checked in by Andrew Beach <ajbeach@…>, 21 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.