- Timestamp:
- Feb 25, 2023, 6:45:44 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 601bd9e
- Parents:
- ce44c5f (diff), 2d028003 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Fwd.hpp
rce44c5f rd964c39 15 15 16 16 #pragma once 17 18 template<typename> struct bitfield; 17 19 18 20 #include "AST/Node.hpp" … … 147 149 class TranslationGlobal; 148 150 151 // For the following types, only use the using type. 152 namespace CV { 153 struct qualifier_flags; 154 using Qualifiers = bitfield<qualifier_flags>; 149 155 } 156 namespace Function { 157 struct spec_flags; 158 using Specs = bitfield<spec_flags>; 159 } 160 namespace Storage { 161 struct class_flags; 162 using Classes = bitfield<class_flags>; 163 } 164 namespace Linkage { 165 struct spec_flags; 166 using Spec = bitfield<spec_flags>; 167 } 168 169 } -
src/AST/Print.cpp
rce44c5f rd964c39 29 29 namespace ast { 30 30 31 template <typename C, typename... T> 32 constexpr array<C,sizeof...(T)> make_array(T&&... values) 33 { 34 return array<C,sizeof...(T)>{ 35 std::forward<T>(values)... 36 }; 31 namespace { 32 33 template<typename C, typename... T> 34 constexpr array<C, sizeof...(T)> make_array( T&&... values ) { 35 return array<C, sizeof...(T)>{ std::forward<T>( values )... }; 36 } 37 38 namespace Names { 39 static constexpr auto FuncSpecifiers = make_array<const char*>( 40 "inline", "_Noreturn", "fortran" 41 ); 42 43 static constexpr auto StorageClasses = make_array<const char*>( 44 "extern", "static", "auto", "register", "__thread", "_Thread_local" 45 ); 46 47 static constexpr auto Qualifiers = make_array<const char*>( 48 "const", "restrict", "volatile", "mutex", "_Atomic" 49 ); 50 } 51 52 template<typename bits_t, size_t N> 53 void print( ostream & os, const bits_t & bits, 54 const array<const char *, N> & names ) { 55 if ( !bits.any() ) return; 56 for ( size_t i = 0 ; i < N ; i += 1 ) { 57 if ( bits[i] ) { 58 os << names[i] << ' '; 59 } 60 } 37 61 } 38 62 … … 80 104 static const char* Names[]; 81 105 82 struct Names {83 static constexpr auto FuncSpecifiers = make_array<const char*>(84 "inline", "_Noreturn", "fortran"85 );86 87 static constexpr auto StorageClasses = make_array<const char*>(88 "extern", "static", "auto", "register", "__thread", "_Thread_local"89 );90 91 static constexpr auto Qualifiers = make_array<const char*>(92 "const", "restrict", "volatile", "mutex", "_Atomic"93 );94 };95 96 template<typename storage_t, size_t N>97 void print(const storage_t & storage, const array<const char *, N> & Names ) {98 if ( storage.any() ) {99 for ( size_t i = 0; i < Names.size(); i += 1 ) {100 if ( storage[i] ) {101 os << Names[i] << ' ';102 }103 }104 }105 }106 107 void print( const ast::Function::Specs & specs ) {108 print(specs, Names::FuncSpecifiers);109 }110 111 void print( const ast::Storage::Classes & storage ) {112 print(storage, Names::StorageClasses);113 }114 115 void print( const ast::CV::Qualifiers & qualifiers ) {116 print(qualifiers, Names::Qualifiers);117 }118 119 106 void print( const std::vector<ast::Label> & labels ) { 120 107 if ( labels.empty() ) return; … … 230 217 } 231 218 232 print(node->storage );219 ast::print( os, node->storage ); 233 220 os << node->typeString(); 234 221 … … 272 259 273 260 void preprint( const ast::Type * node ) { 274 print(node->qualifiers );261 ast::print( os, node->qualifiers ); 275 262 } 276 263 … … 278 265 print( node->forall ); 279 266 print( node->assertions ); 280 print(node->qualifiers );267 ast::print( os, node->qualifiers ); 281 268 } 282 269 283 270 void preprint( const ast::BaseInstType * node ) { 284 271 print( node->attributes ); 285 print(node->qualifiers );272 ast::print( os, node->qualifiers ); 286 273 } 287 274 … … 294 281 } 295 282 296 print(node->storage );283 ast::print( os, node->storage ); 297 284 298 285 if ( node->type ) { … … 338 325 if ( ! short_mode ) printAll( node->attributes ); 339 326 340 print( node->storage ); 341 print( node->funcSpec ); 342 343 327 ast::print( os, node->storage ); 328 ast::print( os, node->funcSpec ); 344 329 345 330 if ( node->type && node->isTypeFixed ) { … … 1627 1612 }; 1628 1613 1614 } // namespace 1615 1629 1616 void print( ostream & os, const ast::Node * node, Indenter indent ) { 1630 1617 Printer printer { os, indent, false }; … … 1637 1624 } 1638 1625 1639 // Annoyingly these needed to be defined out of line to avoid undefined references. 1640 // The size here needs to be explicit but at least the compiler will produce an error 1641 // if the wrong size is specified 1642 constexpr array<const char*, 3> Printer::Names::FuncSpecifiers; 1643 constexpr array<const char*, 6> Printer::Names::StorageClasses; 1644 constexpr array<const char*, 5> Printer::Names::Qualifiers; 1626 void print( ostream & os, Function::Specs specs ) { 1627 print( os, specs, Names::FuncSpecifiers ); 1645 1628 } 1629 1630 void print( ostream & os, Storage::Classes storage ) { 1631 print( os, storage, Names::StorageClasses ); 1632 } 1633 1634 void print( ostream & os, CV::Qualifiers qualifiers ) { 1635 print( os, qualifiers, Names::Qualifiers ); 1636 } 1637 1638 } // namespace ast -
src/AST/Print.hpp
rce44c5f rd964c39 16 16 #pragma once 17 17 18 #include <iostream> 19 #include <utility> // for forward 18 #include <iosfwd> 20 19 21 #include "AST/ Node.hpp"20 #include "AST/Fwd.hpp" 22 21 #include "Common/Indenter.h" 23 22 24 23 namespace ast { 25 26 class Decl;27 24 28 25 /// Print a node with the given indenter … … 44 41 } 45 42 43 /// Print each cv-qualifier used in the set, followed by a space. 44 void print( std::ostream & os, CV::Qualifiers ); 45 /// Print each function specifier used in the set, followed by a space. 46 void print( std::ostream & os, Function::Specs ); 47 /// Print each storage class used in the set, followed by a space. 48 void print( std::ostream & os, Storage::Classes ); 49 46 50 } -
src/Common/SemanticError.h
rce44c5f rd964c39 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 2 10:59:10202313 // Update Count : 3 612 // Last Modified On : Sat Feb 25 12:01:31 2023 13 // Update Count : 37 14 14 // 15 15 … … 56 56 {"self-assign" , Severity::Warn , "self assignment of expression: %s" }, 57 57 {"reference-conversion" , Severity::Warn , "rvalue to reference conversion of rvalue: %s" }, 58 {"qualifiers-zero_t-one_t" , Severity::Warn , "questionable use of type qualifier %swith %s" },58 {"qualifiers-zero_t-one_t" , Severity::Warn , "questionable use of type qualifier(s) with %s" }, 59 59 {"aggregate-forward-decl" , Severity::Warn , "forward declaration of nested aggregate: %s" }, 60 60 {"superfluous-decl" , Severity::Warn , "declaration does not allocate storage: %s" }, -
src/Parser/DeclarationNode.cc
rce44c5f rd964c39 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Feb 16 14:12:03202313 // Update Count : 1 38812 // Last Modified On : Sat Feb 25 12:15:40 2023 13 // Update Count : 1404 14 14 // 15 15 … … 254 254 newnode->type->enumeration.typed = typed; 255 255 newnode->type->enumeration.hiding = hiding; 256 if ( base && base->type ) {256 if ( base && base->type ) { 257 257 newnode->type->base = base->type; 258 258 } // if … … 567 567 568 568 checkQualifiers( type, q->type ); 569 if ( (builtin == Zero || builtin == One) && q->type->qualifiers. val != 0&& error.length() == 0 ) {570 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )],builtinTypeNames[builtin] );569 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) { 570 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] ); 571 571 } // if 572 572 addQualifiersToType( q->type, type ); … … 984 984 985 985 if ( DeclarationNode * extr = cur->extractAggregate() ) { 986 // handle the case where a structure declaration is contained within an object or type declaration 986 // Handle the case where a SUE declaration is contained within an object or type declaration. 987 988 assert( cur->type ); 989 // Replace anonymous SUE name with typedef name to prevent anonymous naming problems across translation units. 990 if ( cur->type->kind == TypeData::Symbolic && cur->type->symbolic.isTypedef ) { 991 assert( extr->type ); 992 // Handle anonymous aggregates: typedef struct { int i; } foo 993 extr->type->qualifiers.reset(); // clear any CVs associated with the aggregate 994 if ( extr->type->kind == TypeData::Aggregate && extr->type->aggregate.anon ) { 995 delete extr->type->aggregate.name; 996 extr->type->aggregate.name = new string( "__anonymous_" + *cur->name ); 997 extr->type->aggregate.anon = false; 998 assert( cur->type->base ); 999 if ( cur->type->base ) { 1000 delete cur->type->base->aggInst.aggregate->aggregate.name; 1001 cur->type->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *cur->name ); 1002 cur->type->base->aggInst.aggregate->aggregate.anon = false; 1003 cur->type->base->aggInst.aggregate->qualifiers.reset(); 1004 } // if 1005 } // if 1006 // Handle anonymous enumeration: typedef enum { A, B, C } foo 1007 if ( extr->type->kind == TypeData::Enum && extr->type->enumeration.anon ) { 1008 delete extr->type->enumeration.name; 1009 extr->type->enumeration.name = new string( "__anonymous_" + *cur->name ); 1010 extr->type->enumeration.anon = false; 1011 assert( cur->type->base ); 1012 if ( cur->type->base ) { 1013 delete cur->type->base->aggInst.aggregate->enumeration.name; 1014 cur->type->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *cur->name ); 1015 cur->type->base->aggInst.aggregate->enumeration.anon = false; 1016 } // if 1017 } // if 1018 } // if 987 1019 988 1020 Declaration * decl = extr->build(); -
src/Parser/TypeData.h
rce44c5f rd964c39 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Feb 19 09:09:39202313 // Update Count : 20 412 // Last Modified On : Fri Feb 24 14:25:02 2023 13 // Update Count : 205 14 14 // 15 15 … … 41 41 }; 42 42 43 struct AggInst_t { 43 struct AggInst_t { // handles SUE 44 44 TypeData * aggregate = nullptr; 45 45 ExpressionNode * params = nullptr; -
src/Parser/parser.yy
rce44c5f rd964c39 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Feb 20 11:31:26 202313 // Update Count : 5 89612 // Last Modified On : Sat Feb 25 13:23:16 2023 13 // Update Count : 5989 14 14 // 15 15 … … 1173 1173 comma_expression_opt ';' 1174 1174 { $$ = new StatementNode( build_expr( $1 ) ); } 1175 | MUTEX '(' ')' comma_expression ';'1176 { $$ = new StatementNode( build_mutex( nullptr, new StatementNode( build_expr( $4 ) ) ) ); }1177 1175 ; 1178 1176 … … 1282 1280 { 1283 1281 $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); 1284 SemanticWarning( yylloc, Warning::SuperfluousElse , "");1282 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1285 1283 } 1286 1284 | WHILE '(' conditional_declaration ')' statement %prec THEN … … 1293 1291 { 1294 1292 $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); 1295 SemanticWarning( yylloc, Warning::SuperfluousElse , "");1293 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1296 1294 } 1297 1295 | DO statement WHILE '(' comma_expression ')' ';' … … 1304 1302 { 1305 1303 $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), maybe_build_compound( $4 ) ) ); 1306 SemanticWarning( yylloc, Warning::SuperfluousElse , "");1304 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1307 1305 } 1308 1306 | FOR '(' for_control_expression_list ')' statement %prec THEN … … 1584 1582 ; 1585 1583 1586 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so change syntax to "with mutex".1584 // If MUTEX becomes a general qualifier, there are shift/reduce conflicts, so possibly change syntax to "with mutex". 1587 1585 mutex_statement: 1588 MUTEX '(' argument_expression_list ')' statement 1589 { $$ = new StatementNode( build_mutex( $3, $5 ) ); } 1586 MUTEX '(' argument_expression_list_opt ')' statement 1587 { 1588 if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; } 1589 $$ = new StatementNode( build_mutex( $3, $5 ) ); 1590 } 1590 1591 ; 1591 1592 … … 1941 1942 // if type_specifier is an anon aggregate => name 1942 1943 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" ); 1943 $$ = $3->addType( $2 )->addTypedef(); 1944 $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3 1944 1945 } 1945 1946 | typedef_declaration pop ',' push declarator … … 1985 1986 { 1986 1987 assert( $1->type ); 1987 if ( $1->type->qualifiers.val != 0 ) { 1988 SemanticError( yylloc, "Useless type qualifier in empty declaration." ); $$ = nullptr; 1988 if ( $1->type->qualifiers.any() ) { // CV qualifiers ? 1989 SemanticError( yylloc, "Useless type qualifier(s) in empty declaration." ); $$ = nullptr; 1990 } 1991 // enums are never empty declarations because there must have at least one enumeration. 1992 if ( $1->type->kind == TypeData::AggregateInst && $1->storageClasses.any() ) { // storage class ? 1993 SemanticError( yylloc, "Useless storage qualifier(s) in empty aggregate declaration." ); $$ = nullptr; 1989 1994 } 1990 1995 } … … 2006 2011 | sue_declaration_specifier invalid_types 2007 2012 { 2008 SemanticError( yylloc, 2009 ::toString( "Missing ';' after end of ", 2010 $1->type->enumeration.name ? "enum" : AggregateDecl::aggrString( $1->type->aggregate.kind ), 2011 " declaration" ) ); 2013 SemanticError( yylloc, ::toString( "Missing ';' after end of ", 2014 $1->type->enumeration.name ? "enum" : AggregateDecl::aggrString( $1->type->aggregate.kind ), 2015 " declaration" ) ); 2012 2016 $$ = nullptr; 2013 2017 } … … 2588 2592 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2589 2593 { 2590 if ( $3->storageClasses.val != 0 || $3->type->qualifiers. val != 0)2594 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.any() ) 2591 2595 { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2592 2596 … … 2599 2603 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2600 2604 { 2601 if ( $3->storageClasses. val != 0|| $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); }2605 if ( $3->storageClasses.any() || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2602 2606 typedefTable.makeTypedef( *$6 ); 2603 2607 } … … 2986 2990 TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' '}' 2987 2991 { 2988 SemanticWarning( yylloc, Warning::DeprecTraitSyntax , "");2992 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 2989 2993 $$ = DeclarationNode::newTrait( $2, $4, nullptr ); 2990 2994 } … … 2993 2997 | TRAIT identifier_or_type_name '(' type_parameter_list ')' '{' push trait_declaration_list pop '}' 2994 2998 { 2995 SemanticWarning( yylloc, Warning::DeprecTraitSyntax , "");2999 SemanticWarning( yylloc, Warning::DeprecTraitSyntax ); 2996 3000 $$ = DeclarationNode::newTrait( $2, $4, $8 ); 2997 3001 } … … 3058 3062 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 3059 3063 | declaration 3064 { 3065 // Variable declarations of anonymous types requires creating a unique type-name across multiple translation 3066 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is 3067 // disallowed at the moment. 3068 if ( $1->linkage == LinkageSpec::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) { 3069 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) { 3070 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr; 3071 } else if ( $1->type->aggInst.aggregate->aggregate.anon ) { // handles struct or union 3072 SemanticError( yylloc, "extern anonymous struct/union is currently unimplemented." ); $$ = nullptr; 3073 } 3074 } 3075 } 3060 3076 | IDENTIFIER IDENTIFIER 3061 3077 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } … … 3103 3119 | type_qualifier_list 3104 3120 { 3105 if ( $1->type->qualifiers. val) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3121 if ( $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3106 3122 if ( $1->type->forall ) forall = true; // remember generic type 3107 3123 } … … 3114 3130 | declaration_qualifier_list 3115 3131 { 3116 if ( $1->type && $1->type->qualifiers. val) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3132 if ( $1->type && $1->type->qualifiers.any() ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3117 3133 if ( $1->type && $1->type->forall ) forall = true; // remember generic type 3118 3134 } … … 3125 3141 | declaration_qualifier_list type_qualifier_list 3126 3142 { 3127 if ( ($1->type && $1->type->qualifiers. val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3143 if ( ($1->type && $1->type->qualifiers.any()) || ($2->type && $2->type->qualifiers.any()) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3128 3144 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3129 3145 }
Note:
See TracChangeset
for help on using the changeset viewer.