Changeset 6e1e2d0 for src/Parser
- Timestamp:
- May 1, 2023, 4:19:09 PM (14 months ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- c083c3d
- Parents:
- a50fdfb (diff), 985b624 (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/Parser
- Files:
-
- 4 added
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
ra50fdfb r6e1e2d0 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T ue Apr 4 10:28:00 202313 // Update Count : 139 212 // Last Modified On : Thr Apr 20 11:46:00 2023 13 // Update Count : 1393 14 14 // 15 16 #include "DeclarationNode.h" 15 17 16 18 #include <cassert> // for assert, assertf, strict_dynamic_cast … … 34 36 #include "Common/UniqueName.h" // for UniqueName 35 37 #include "Common/utility.h" // for maybeClone 36 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 38 #include "Parser/ExpressionNode.h" // for ExpressionNode 39 #include "Parser/InitializerNode.h"// for InitializerNode 40 #include "Parser/StatementNode.h" // for StatementNode 37 41 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 38 42 #include "TypedefTable.h" // for TypedefTable … … 999 1003 } 1000 1004 1001 void buildList( const DeclarationNode * firstNode, 1005 // If a typedef wraps an anonymous declaration, name the inner declaration 1006 // so it has a consistent name across translation units. 1007 static void nameTypedefedDecl( 1008 DeclarationNode * innerDecl, 1009 const DeclarationNode * outerDecl ) { 1010 TypeData * outer = outerDecl->type; 1011 assert( outer ); 1012 // First make sure this is a typedef: 1013 if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) { 1014 return; 1015 } 1016 TypeData * inner = innerDecl->type; 1017 assert( inner ); 1018 // Always clear any CVs associated with the aggregate: 1019 inner->qualifiers.reset(); 1020 // Handle anonymous aggregates: typedef struct { int i; } foo 1021 if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) { 1022 delete inner->aggregate.name; 1023 inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name ); 1024 inner->aggregate.anon = false; 1025 assert( outer->base ); 1026 delete outer->base->aggInst.aggregate->aggregate.name; 1027 outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name ); 1028 outer->base->aggInst.aggregate->aggregate.anon = false; 1029 outer->base->aggInst.aggregate->qualifiers.reset(); 1030 // Handle anonymous enumeration: typedef enum { A, B, C } foo 1031 } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) { 1032 delete inner->enumeration.name; 1033 inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name ); 1034 inner->enumeration.anon = false; 1035 assert( outer->base ); 1036 delete outer->base->aggInst.aggregate->enumeration.name; 1037 outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name ); 1038 outer->base->aggInst.aggregate->enumeration.anon = false; 1039 // No qualifiers.reset() here. 1040 } 1041 } 1042 1043 // This code handles a special issue with the attribute transparent_union. 1044 // 1045 // typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union )) 1046 // 1047 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are 1048 // aligned. However, the attribute transparent_union must be moved from the typedef_name to 1049 // alias union U. Currently, this is the only know attribute that must be moved from typedef to 1050 // alias. 1051 static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) { 1052 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) { 1053 // Is the typedef alias a union aggregate? 1054 if ( nullptr == unionDecl ) return; 1055 1056 // If typedef is an alias for a union, then its alias type was hoisted above and remembered. 1057 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) { 1058 auto instType = ast::mutate( unionInstType ); 1059 // Remove all transparent_union attributes from typedef and move to alias union. 1060 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { 1061 assert( *attr ); 1062 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) { 1063 unionDecl->attributes.emplace_back( attr->release() ); 1064 attr = instType->attributes.erase( attr ); 1065 } else { 1066 attr++; 1067 } 1068 } 1069 typedefDecl->base = instType; 1070 } 1071 } 1072 } 1073 1074 // Get the non-anonymous name of the instance type of the declaration, 1075 // if one exists. 1076 static const std::string * getInstTypeOfName( ast::Decl * decl ) { 1077 if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1078 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) { 1079 if ( aggr->name.find("anonymous") == std::string::npos ) { 1080 return &aggr->name; 1081 } 1082 } 1083 } 1084 return nullptr; 1085 } 1086 1087 void buildList( DeclarationNode * firstNode, 1002 1088 std::vector<ast::ptr<ast::Decl>> & outputList ) { 1003 1089 SemanticErrorException errors; 1004 1090 std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList ); 1005 1091 1006 for ( const DeclarationNode * cur = firstNode ; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next()) ) {1092 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) { 1007 1093 try { 1008 bool extracted = false, anon= false;1009 ast:: AggregateDecl * unionDecl = nullptr;1094 bool extracted_named = false; 1095 ast::UnionDecl * unionDecl = nullptr; 1010 1096 1011 1097 if ( DeclarationNode * extr = cur->extractAggregate() ) { 1012 // Handle the case where a SUE declaration is contained within an object or type declaration.1013 1014 1098 assert( cur->type ); 1015 // Replace anonymous SUE name with typedef name to prevent anonymous naming problems across translation units. 1016 if ( cur->type->kind == TypeData::Symbolic && cur->type->symbolic.isTypedef ) { 1017 assert( extr->type ); 1018 // Handle anonymous aggregates: typedef struct { int i; } foo 1019 extr->type->qualifiers.reset(); // clear any CVs associated with the aggregate 1020 if ( extr->type->kind == TypeData::Aggregate && extr->type->aggregate.anon ) { 1021 delete extr->type->aggregate.name; 1022 extr->type->aggregate.name = new string( "__anonymous_" + *cur->name ); 1023 extr->type->aggregate.anon = false; 1024 assert( cur->type->base ); 1025 if ( cur->type->base ) { 1026 delete cur->type->base->aggInst.aggregate->aggregate.name; 1027 cur->type->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *cur->name ); 1028 cur->type->base->aggInst.aggregate->aggregate.anon = false; 1029 cur->type->base->aggInst.aggregate->qualifiers.reset(); 1030 } // if 1031 } // if 1032 // Handle anonymous enumeration: typedef enum { A, B, C } foo 1033 if ( extr->type->kind == TypeData::Enum && extr->type->enumeration.anon ) { 1034 delete extr->type->enumeration.name; 1035 extr->type->enumeration.name = new string( "__anonymous_" + *cur->name ); 1036 extr->type->enumeration.anon = false; 1037 assert( cur->type->base ); 1038 if ( cur->type->base ) { 1039 delete cur->type->base->aggInst.aggregate->enumeration.name; 1040 cur->type->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *cur->name ); 1041 cur->type->base->aggInst.aggregate->enumeration.anon = false; 1042 } // if 1043 } // if 1044 } // if 1045 1046 ast::Decl * decl = extr->build(); 1047 if ( decl ) { 1099 nameTypedefedDecl( extr, cur ); 1100 1101 if ( ast::Decl * decl = extr->build() ) { 1048 1102 // Remember the declaration if it is a union aggregate ? 1049 1103 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 1050 1104 1051 decl->location = cur->location;1052 1105 *out++ = decl; 1053 1106 1054 1107 // need to remember the cases where a declaration contains an anonymous aggregate definition 1055 extracted = true;1056 1108 assert( extr->type ); 1057 1109 if ( extr->type->kind == TypeData::Aggregate ) { 1058 1110 // typedef struct { int A } B is the only case? 1059 anon =extr->type->aggregate.anon;1111 extracted_named = !extr->type->aggregate.anon; 1060 1112 } else if ( extr->type->kind == TypeData::Enum ) { 1061 1113 // typedef enum { A } B is the only case? 1062 anon = extr->type->enumeration.anon; 1114 extracted_named = !extr->type->enumeration.anon; 1115 } else { 1116 extracted_named = true; 1063 1117 } 1064 1118 } // if … … 1066 1120 } // if 1067 1121 1068 ast::Decl * decl = cur->build(); 1069 if ( decl ) { 1070 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) { 1071 if ( unionDecl ) { // is the typedef alias a union aggregate ? 1072 // This code handles a special issue with the attribute transparent_union. 1073 // 1074 // typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union )) 1075 // 1076 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are 1077 // aligned. However, the attribute transparent_union must be moved from the typedef_name to 1078 // alias union U. Currently, this is the only know attribute that must be moved from typedef to 1079 // alias. 1080 1081 // If typedef is an alias for a union, then its alias type was hoisted above and remembered. 1082 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) { 1083 auto instType = ast::mutate( unionInstType ); 1084 // Remove all transparent_union attributes from typedef and move to alias union. 1085 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { // forward order 1086 assert( *attr ); 1087 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) { 1088 unionDecl->attributes.emplace_back( attr->release() ); 1089 attr = instType->attributes.erase( attr ); 1090 } else { 1091 attr++; 1092 } // if 1093 } // for 1094 typedefDecl->base = instType; 1095 } // if 1096 } // if 1122 if ( ast::Decl * decl = cur->build() ) { 1123 moveUnionAttribute( decl, unionDecl ); 1124 1125 if ( "" == decl->name && !cur->get_inLine() ) { 1126 // Don't include anonymous declaration for named aggregates, 1127 // but do include them for anonymous aggregates, e.g.: 1128 // struct S { 1129 // struct T { int x; }; // no anonymous member 1130 // struct { int y; }; // anonymous member 1131 // struct T; // anonymous member 1132 // }; 1133 if ( extracted_named ) { 1134 continue; 1135 } 1136 1137 if ( auto name = getInstTypeOfName( decl ) ) { 1138 // Temporary: warn about anonymous member declarations of named types, since 1139 // this conflicts with the syntax for the forward declaration of an anonymous type. 1140 SemanticWarning( cur->location, Warning::AggrForwardDecl, name->c_str() ); 1141 } 1097 1142 } // if 1098 1099 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.: 1100 // struct S { 1101 // struct T { int x; }; // no anonymous member 1102 // struct { int y; }; // anonymous member 1103 // struct T; // anonymous member 1104 // }; 1105 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 1106 if ( decl->name == "" ) { 1107 if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1108 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) { 1109 if ( aggr->name.find("anonymous") == std::string::npos ) { 1110 if ( ! cur->get_inLine() ) { 1111 // temporary: warn about anonymous member declarations of named types, since 1112 // this conflicts with the syntax for the forward declaration of an anonymous type 1113 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() ); 1114 } // if 1115 } // if 1116 } // if 1117 } // if 1118 } // if 1119 decl->location = cur->location; 1120 *out++ = decl; 1121 } // if 1143 *out++ = decl; 1122 1144 } // if 1123 } catch ( SemanticErrorException & e ) {1145 } catch ( SemanticErrorException & e ) { 1124 1146 errors.append( e ); 1125 1147 } // try … … 1132 1154 1133 1155 // currently only builds assertions, function parameters, and return values 1134 void buildList( constDeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) { 1135 1157 SemanticErrorException errors; 1136 1158 std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList ); 1137 1159 1138 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next()) ) {1160 for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) { 1139 1161 try { 1140 1162 ast::Decl * decl = cur->build(); 1141 assert ( decl);1163 assertf( decl, "buildList: build for ast::DeclWithType." ); 1142 1164 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1143 1165 dwt->location = cur->location; … … 1168 1190 ); 1169 1191 *out++ = obj; 1192 } else { 1193 assertf( false, "buildList: Could not convert to ast::DeclWithType." ); 1170 1194 } // if 1171 } catch ( SemanticErrorException & e ) {1195 } catch ( SemanticErrorException & e ) { 1172 1196 errors.append( e ); 1173 1197 } // try … … 1183 1207 SemanticErrorException errors; 1184 1208 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList ); 1185 const DeclarationNode * cur = firstNode; 1186 1187 while ( cur ) { 1209 1210 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) { 1188 1211 try { 1189 1212 * out++ = cur->buildType(); 1190 } catch ( SemanticErrorException & e ) {1213 } catch ( SemanticErrorException & e ) { 1191 1214 errors.append( e ); 1192 1215 } // try 1193 cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); 1194 } // while 1216 } // for 1195 1217 1196 1218 if ( ! errors.isEmpty() ) { -
src/Parser/ExpressionNode.cc
ra50fdfb r6e1e2d0 13 13 // Update Count : 1083 14 14 // 15 16 #include "ExpressionNode.h" 15 17 16 18 #include <cassert> // for assert … … 25 27 #include "Common/SemanticError.h" // for SemanticError 26 28 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 27 #include "ParseNode.h" // for ExpressionNode, maybeMoveBuildType 29 #include "DeclarationNode.h" // for DeclarationNode 30 #include "InitializerNode.h" // for InitializerNode 28 31 #include "parserutility.h" // for notZeroExpr 29 32 … … 699 702 } // build_binary_val 700 703 701 ast::Expr * build_binary_ptr( const CodeLocation & location,702 OperKinds op,703 ExpressionNode * expr_node1,704 ExpressionNode * expr_node2 ) {705 return build_binary_val( location, op, expr_node1, expr_node2 );706 } // build_binary_ptr707 708 704 ast::Expr * build_cond( const CodeLocation & location, 709 705 ExpressionNode * expr_node1, -
src/Parser/InitializerNode.cc
ra50fdfb r6e1e2d0 14 14 // 15 15 16 #include "InitializerNode.h" 17 16 18 #include <iostream> // for operator<<, ostream, basic_ostream 17 19 #include <list> // for list 18 20 #include <string> // for operator<<, string 19 20 using namespace std;21 21 22 22 #include "AST/Expr.hpp" // for Expr … … 24 24 #include "Common/SemanticError.h" // for SemanticError 25 25 #include "Common/utility.h" // for maybeBuild 26 #include "ParseNode.h" // for InitializerNode, ExpressionNode 26 #include "ExpressionNode.h" // for ExpressionNode 27 #include "DeclarationNode.h" // for buildList 28 29 using namespace std; 27 30 28 31 static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) { -
src/Parser/ParseNode.h
ra50fdfb r6e1e2d0 38 38 class DeclarationWithType; 39 39 class Initializer; 40 class InitializerNode; 40 41 class ExpressionNode; 41 42 struct StatementNode; … … 80 81 }; // ParseNode 81 82 82 //##############################################################################83 84 class InitializerNode : public ParseNode {85 public:86 InitializerNode( ExpressionNode *, bool aggrp = false, ExpressionNode * des = nullptr );87 InitializerNode( InitializerNode *, bool aggrp = false, ExpressionNode * des = nullptr );88 InitializerNode( bool isDelete );89 ~InitializerNode();90 virtual InitializerNode * clone() const { assert( false ); return nullptr; }91 92 ExpressionNode * get_expression() const { return expr; }93 94 InitializerNode * set_designators( ExpressionNode * des ) { designator = des; return this; }95 ExpressionNode * get_designators() const { return designator; }96 97 InitializerNode * set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }98 bool get_maybeConstructed() const { return maybeConstructed; }99 100 bool get_isDelete() const { return isDelete; }101 102 InitializerNode * next_init() const { return kids; }103 104 void print( std::ostream & os, int indent = 0 ) const;105 void printOneLine( std::ostream & ) const;106 107 virtual ast::Init * build() const;108 private:109 ExpressionNode * expr;110 bool aggregate;111 ExpressionNode * designator; // may be list112 InitializerNode * kids;113 bool maybeConstructed;114 bool isDelete;115 }; // InitializerNode116 117 //##############################################################################118 119 class ExpressionNode final : public ParseNode {120 public:121 ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {}122 virtual ~ExpressionNode() {}123 virtual ExpressionNode * clone() const override {124 if ( nullptr == expr ) return nullptr;125 return static_cast<ExpressionNode*>(126 (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) ));127 }128 129 bool get_extension() const { return extension; }130 ExpressionNode * set_extension( bool exten ) { extension = exten; return this; }131 132 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {133 os << expr.get();134 }135 void printOneLine( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const {}136 137 template<typename T>138 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }139 140 ast::Expr * build() const {141 ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release();142 node->set_extension( this->get_extension() );143 node->location = this->location;144 return node;145 }146 147 // Public because of lifetime implications (what lifetime implications?)148 std::unique_ptr<ast::Expr> expr;149 private:150 bool extension = false;151 }; // ExpressionNode152 153 83 // Must harmonize with OperName. 154 84 enum class OperKinds { … … 169 99 }; 170 100 171 // These 4 routines modify the string:172 ast::Expr * build_constantInteger( const CodeLocation &, std::string & );173 ast::Expr * build_constantFloat( const CodeLocation &, std::string & );174 ast::Expr * build_constantChar( const CodeLocation &, std::string & );175 ast::Expr * build_constantStr( const CodeLocation &, std::string & );176 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str );177 ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str );178 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str );179 ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts );180 181 ast::NameExpr * build_varref( const CodeLocation &, const std::string * name );182 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name );183 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name );184 ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name );185 186 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );187 ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node );188 ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );189 ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );190 ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );191 ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member );192 ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );193 ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag );194 ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node );195 ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );196 ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );197 ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );198 ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr );199 ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node );200 ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids );201 202 //##############################################################################203 204 struct TypeData;205 206 struct DeclarationNode : public ParseNode {207 // These enumerations must harmonize with their names in DeclarationNode.cc.208 enum BasicType {209 Void, Bool, Char, Int, Int128,210 Float, Double, LongDouble, uuFloat80, uuFloat128,211 uFloat16, uFloat32, uFloat32x, uFloat64, uFloat64x, uFloat128, uFloat128x,212 NoBasicType213 };214 static const char * basicTypeNames[];215 enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message216 static const char * complexTypeNames[];217 enum Signedness { Signed, Unsigned, NoSignedness };218 static const char * signednessNames[];219 enum Length { Short, Long, LongLong, NoLength };220 static const char * lengthNames[];221 enum BuiltinType { Valist, AutoType, Zero, One, NoBuiltinType };222 static const char * builtinTypeNames[];223 224 static DeclarationNode * newStorageClass( ast::Storage::Classes );225 static DeclarationNode * newFuncSpecifier( ast::Function::Specs );226 static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );227 static DeclarationNode * newBasicType( BasicType );228 static DeclarationNode * newComplexType( ComplexType );229 static DeclarationNode * newSignedNess( Signedness );230 static DeclarationNode * newLength( Length );231 static DeclarationNode * newBuiltinType( BuiltinType );232 static DeclarationNode * newForall( DeclarationNode * );233 static DeclarationNode * newFromTypedef( const std::string * );234 static DeclarationNode * newFromGlobalScope();235 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );236 static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );237 static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );238 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );239 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );240 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init );241 static DeclarationNode * newEnumInLine( const std::string name );242 static DeclarationNode * newName( const std::string * );243 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );244 static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );245 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );246 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );247 static DeclarationNode * newTypeDecl( const std::string * name, DeclarationNode * typeParams );248 static DeclarationNode * newPointer( DeclarationNode * qualifiers, OperKinds kind );249 static DeclarationNode * newArray( ExpressionNode * size, DeclarationNode * qualifiers, bool isStatic );250 static DeclarationNode * newVarArray( DeclarationNode * qualifiers );251 static DeclarationNode * newBitfield( ExpressionNode * size );252 static DeclarationNode * newTuple( DeclarationNode * members );253 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false );254 static DeclarationNode * newVtableType( DeclarationNode * expr );255 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes256 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement257 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement258 static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );259 260 DeclarationNode();261 ~DeclarationNode();262 DeclarationNode * clone() const override;263 264 DeclarationNode * addQualifiers( DeclarationNode * );265 void checkQualifiers( const TypeData *, const TypeData * );266 void checkSpecifiers( DeclarationNode * );267 DeclarationNode * copySpecifiers( DeclarationNode * );268 DeclarationNode * addType( DeclarationNode * );269 DeclarationNode * addTypedef();270 DeclarationNode * addEnumBase( DeclarationNode * );271 DeclarationNode * addAssertions( DeclarationNode * );272 DeclarationNode * addName( std::string * );273 DeclarationNode * addAsmName( DeclarationNode * );274 DeclarationNode * addBitfield( ExpressionNode * size );275 DeclarationNode * addVarArgs();276 DeclarationNode * addFunctionBody( StatementNode * body, ExpressionNode * with = nullptr );277 DeclarationNode * addOldDeclList( DeclarationNode * list );278 DeclarationNode * setBase( TypeData * newType );279 DeclarationNode * copyAttribute( DeclarationNode * attr );280 DeclarationNode * addPointer( DeclarationNode * qualifiers );281 DeclarationNode * addArray( DeclarationNode * array );282 DeclarationNode * addNewPointer( DeclarationNode * pointer );283 DeclarationNode * addNewArray( DeclarationNode * array );284 DeclarationNode * addParamList( DeclarationNode * list );285 DeclarationNode * addIdList( DeclarationNode * list ); // old-style functions286 DeclarationNode * addInitializer( InitializerNode * init );287 DeclarationNode * addTypeInitializer( DeclarationNode * init );288 289 DeclarationNode * cloneType( std::string * newName );290 DeclarationNode * cloneBaseType( DeclarationNode * newdecl );291 292 DeclarationNode * appendList( DeclarationNode * node ) {293 return (DeclarationNode *)set_last( node );294 }295 296 virtual void print( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;297 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;298 299 ast::Decl * build() const;300 ast::Type * buildType() const;301 302 ast::Linkage::Spec get_linkage() const { return linkage; }303 DeclarationNode * extractAggregate() const;304 bool has_enumeratorValue() const { return (bool)enumeratorValue; }305 ExpressionNode * consume_enumeratorValue() const { return const_cast<DeclarationNode *>(this)->enumeratorValue.release(); }306 307 bool get_extension() const { return extension; }308 DeclarationNode * set_extension( bool exten ) { extension = exten; return this; }309 310 bool get_inLine() const { return inLine; }311 DeclarationNode * set_inLine( bool inL ) { inLine = inL; return this; }312 313 DeclarationNode * get_last() { return (DeclarationNode *)ParseNode::get_last(); }314 315 struct Variable_t {316 // const std::string * name;317 ast::TypeDecl::Kind tyClass;318 DeclarationNode * assertions;319 DeclarationNode * initializer;320 };321 Variable_t variable;322 323 struct StaticAssert_t {324 ExpressionNode * condition;325 ast::Expr * message;326 };327 StaticAssert_t assert;328 329 BuiltinType builtin = NoBuiltinType;330 331 TypeData * type = nullptr;332 333 bool inLine = false;334 bool enumInLine = false;335 ast::Function::Specs funcSpecs;336 ast::Storage::Classes storageClasses;337 338 ExpressionNode * bitfieldWidth = nullptr;339 std::unique_ptr<ExpressionNode> enumeratorValue;340 bool hasEllipsis = false;341 ast::Linkage::Spec linkage;342 ast::Expr * asmName = nullptr;343 std::vector<ast::ptr<ast::Attribute>> attributes;344 InitializerNode * initializer = nullptr;345 bool extension = false;346 std::string error;347 StatementNode * asmStmt = nullptr;348 StatementNode * directiveStmt = nullptr;349 350 static UniqueName anonymous;351 }; // DeclarationNode352 353 ast::Type * buildType( TypeData * type );354 355 static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {356 ast::Type * ret = orig ? orig->buildType() : nullptr;357 delete orig;358 return ret;359 }360 361 //##############################################################################362 363 struct StatementNode final : public ParseNode {364 StatementNode() :365 stmt( nullptr ), clause( nullptr ) {}366 StatementNode( ast::Stmt * stmt ) :367 stmt( stmt ), clause( nullptr ) {}368 StatementNode( ast::StmtClause * clause ) :369 stmt( nullptr ), clause( clause ) {}370 StatementNode( DeclarationNode * decl );371 virtual ~StatementNode() {}372 373 virtual StatementNode * clone() const final { assert( false ); return nullptr; }374 ast::Stmt * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }375 376 virtual StatementNode * add_label(377 const CodeLocation & location,378 const std::string * name,379 DeclarationNode * attr = nullptr ) {380 stmt->labels.emplace_back( location,381 *name,382 attr ? std::move( attr->attributes )383 : std::vector<ast::ptr<ast::Attribute>>{} );384 delete attr;385 delete name;386 return this;387 }388 389 virtual StatementNode * append_last_case( StatementNode * );390 391 virtual void print( std::ostream & os, __attribute__((unused)) int indent = 0 ) const override {392 os << stmt.get() << std::endl;393 }394 395 std::unique_ptr<ast::Stmt> stmt;396 std::unique_ptr<ast::StmtClause> clause;397 }; // StatementNode398 399 ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl );400 401 struct CondCtl {402 CondCtl( DeclarationNode * decl, ExpressionNode * condition ) :403 init( decl ? new StatementNode( decl ) : nullptr ), condition( condition ) {}404 405 StatementNode * init;406 ExpressionNode * condition;407 };408 409 struct ForCtrl {410 ForCtrl( StatementNode * stmt, ExpressionNode * condition, ExpressionNode * change ) :411 init( stmt ), condition( condition ), change( change ) {}412 413 StatementNode * init;414 ExpressionNode * condition;415 ExpressionNode * change;416 };417 418 ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ );419 ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );420 ast::CaseClause * build_case( ExpressionNode * ctl );421 ast::CaseClause * build_default( const CodeLocation & );422 ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );423 ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );424 ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );425 ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind );426 ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind );427 ast::Stmt * build_computedgoto( ExpressionNode * ctl );428 ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl );429 ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl );430 ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl );431 ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );432 ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );433 ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );434 ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt );435 ast::Stmt * build_compound( const CodeLocation &, StatementNode * first );436 StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first );437 ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );438 ast::Stmt * build_directive( const CodeLocation &, std::string * directive );439 ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Type );440 ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );441 ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );442 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );443 ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation &, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );444 ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation &, ExpressionNode * when, StatementNode * stmt );445 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation &, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );446 ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation &, ast::WaitUntilStmt::ClauseNode * root );447 ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );448 ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );449 450 //##############################################################################451 452 template<typename AstType, typename NodeType,453 template<typename, typename...> class Container, typename... Args>454 void buildList( const NodeType * firstNode,455 Container<ast::ptr<AstType>, Args...> & output ) {456 SemanticErrorException errors;457 std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );458 const NodeType * cur = firstNode;459 460 while ( cur ) {461 try {462 if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) {463 *out++ = result;464 } else {465 assertf(false, __PRETTY_FUNCTION__ );466 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );467 } // if468 } catch( SemanticErrorException & e ) {469 errors.append( e );470 } // try471 const ParseNode * temp = cur->get_next();472 // Should not return nullptr, then it is non-homogeneous:473 cur = dynamic_cast<const NodeType *>( temp );474 if ( !cur && temp ) {475 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );476 } // if477 } // while478 if ( ! errors.isEmpty() ) {479 throw errors;480 } // if481 }482 483 // in DeclarationNode.cc484 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList );485 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList );486 void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );487 488 template<typename AstType, typename NodeType,489 template<typename, typename...> class Container, typename... Args>490 void buildMoveList( const NodeType * firstNode,491 Container<ast::ptr<AstType>, Args...> & output ) {492 buildList<AstType, NodeType, Container, Args...>( firstNode, output );493 delete firstNode;494 }495 496 // in ParseNode.cc497 101 std::ostream & operator<<( std::ostream & out, const ParseNode * node ); 498 102 -
src/Parser/RunParser.cpp
ra50fdfb r6e1e2d0 20 20 #include "CodeTools/TrackLoc.h" // for fillLocations 21 21 #include "Common/CodeLocationTools.hpp" // for forceFillCodeLocations 22 #include "Parser/ ParseNode.h"// for DeclarationNode, buildList22 #include "Parser/DeclarationNode.h" // for DeclarationNode, buildList 23 23 #include "Parser/TypedefTable.h" // for TypedefTable 24 24 -
src/Parser/StatementNode.cc
ra50fdfb r6e1e2d0 11 11 // Created On : Sat May 16 14:59:41 2015 12 12 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 4 11:40:00 202314 // Update Count : 42 713 // Last Modified On : Tue Apr 11 10:16:00 2023 14 // Update Count : 428 15 15 // 16 17 #include "StatementNode.h" 16 18 17 19 #include <cassert> // for assert, strict_dynamic_cast, assertf … … 23 25 #include "Common/SemanticError.h" // for SemanticError 24 26 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 25 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 27 #include "DeclarationNode.h" // for DeclarationNode 28 #include "ExpressionNode.h" // for ExpressionNode 26 29 #include "parserutility.h" // for notZeroExpr 27 30 … … 29 32 30 33 using namespace std; 34 35 // Some helpers for cases that really want a single node but check for lists. 36 static const ast::Stmt * buildMoveSingle( StatementNode * node ) { 37 std::vector<ast::ptr<ast::Stmt>> list; 38 buildMoveList( node, list ); 39 assertf( list.size() == 1, "CFA Internal Error: Extra/Missing Nodes" ); 40 return list.front().release(); 41 } 42 43 static const ast::Stmt * buildMoveOptional( StatementNode * node ) { 44 std::vector<ast::ptr<ast::Stmt>> list; 45 buildMoveList( node, list ); 46 assertf( list.size() <= 1, "CFA Internal Error: Extra Nodes" ); 47 return list.empty() ? nullptr : list.front().release(); 48 } 31 49 32 50 StatementNode::StatementNode( DeclarationNode * decl ) { … … 53 71 } // StatementNode::StatementNode 54 72 55 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) { 56 StatementNode * prev = this; 73 StatementNode * StatementNode::add_label( 74 const CodeLocation & location, 75 const std::string * name, 76 DeclarationNode * attr ) { 77 stmt->labels.emplace_back( location, 78 *name, 79 attr ? std::move( attr->attributes ) 80 : std::vector<ast::ptr<ast::Attribute>>{} ); 81 delete attr; 82 delete name; 83 return this; 84 } 85 86 ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) { 87 ClauseNode * prev = this; 57 88 // find end of list and maintain previous pointer 58 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 59 StatementNode * node = strict_dynamic_cast< StatementNode * >(curr); 60 assert( nullptr == node->stmt.get() ); 89 for ( ClauseNode * curr = prev; curr != nullptr; curr = (ClauseNode *)curr->get_next() ) { 90 ClauseNode * node = strict_dynamic_cast< ClauseNode * >(curr); 61 91 assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) ); 62 92 prev = curr; 63 93 } // for 94 ClauseNode * node = dynamic_cast< ClauseNode * >(prev); 64 95 // convert from StatementNode list to Statement list 65 StatementNode * node = dynamic_cast< StatementNode * >(prev);66 96 std::vector<ast::ptr<ast::Stmt>> stmts; 67 97 buildMoveList( stmt, stmts ); … … 73 103 stmts.clear(); 74 104 return this; 75 } // StatementNode::append_last_case105 } // ClauseNode::append_last_case 76 106 77 107 ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) { … … 97 127 for ( ast::ptr<ast::Stmt> & stmt : inits ) { 98 128 // build the && of all of the declared variables compared against 0 99 //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );100 129 auto declStmt = stmt.strict_as<ast::DeclStmt>(); 101 //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );102 130 auto dwt = declStmt->decl.strict_as<ast::DeclWithType>(); 103 131 ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) ); … … 113 141 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 114 142 115 std::vector<ast::ptr<ast::Stmt>> aststmt; 116 buildMoveList( then, aststmt ); 117 assert( aststmt.size() == 1 ); 118 ast::Stmt const * astthen = aststmt.front().release(); 119 120 ast::Stmt const * astelse = nullptr; 121 if ( else_ ) { 122 std::vector<ast::ptr<ast::Stmt>> aststmt; 123 buildMoveList( else_, aststmt ); 124 assert( aststmt.size() == 1 ); 125 astelse = aststmt.front().release(); 126 } // if 143 ast::Stmt const * astthen = buildMoveSingle( then ); 144 ast::Stmt const * astelse = buildMoveOptional( else_ ); 127 145 128 146 return new ast::IfStmt( location, astcond, astthen, astelse, … … 131 149 } // build_if 132 150 133 // Temporary work around. Split StmtClause off from StatementNode. 134 template<typename clause_t> 135 static void buildMoveClauseList( StatementNode * firstNode, 136 std::vector<ast::ptr<clause_t>> & output ) { 137 SemanticErrorException errors; 138 std::back_insert_iterator<std::vector<ast::ptr<clause_t>>> 139 out( output ); 140 StatementNode * cur = firstNode; 141 142 while ( cur ) { 143 try { 144 auto clause = cur->clause.release(); 145 if ( auto result = dynamic_cast<clause_t *>( clause ) ) { 146 *out++ = result; 147 } else { 148 assertf(false, __PRETTY_FUNCTION__ ); 149 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." ); 150 } // if 151 } catch( SemanticErrorException & e ) { 152 errors.append( e ); 153 } // try 154 ParseNode * temp = cur->get_next(); 155 // Should not return nullptr, then it is non-homogeneous: 156 cur = dynamic_cast<StatementNode *>( temp ); 157 if ( !cur && temp ) { 158 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 159 } // if 160 } // while 161 if ( ! errors.isEmpty() ) { 162 throw errors; 163 } // if 164 // Usually in the wrapper. 165 delete firstNode; 166 } 167 168 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) { 151 ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) { 169 152 std::vector<ast::ptr<ast::CaseClause>> aststmt; 170 buildMove ClauseList( stmt, aststmt );153 buildMoveList( stmt, aststmt ); 171 154 // If it is not a switch it is a choose statement. 172 155 if ( ! isSwitch ) { … … 190 173 } // build_switch 191 174 192 ast::CaseClause * build_case( ExpressionNode * ctl ) {175 ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) { 193 176 // stmt starts empty and then added to 194 177 auto expr = maybeMoveBuild( ctl ); 195 return new ast::CaseClause( expr->location, expr, {} );178 return new ast::CaseClause( location, expr, {} ); 196 179 } // build_case 197 180 … … 205 188 ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set 206 189 207 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty208 buildMoveList( stmt, aststmt );209 assert( aststmt.size() == 1 );210 211 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty212 buildMoveList( else_, astelse );213 assert( astelse.size() <= 1 );214 215 190 return new ast::WhileDoStmt( location, 216 191 astcond, 217 aststmt.front(),218 astelse.empty() ? nullptr : astelse.front().release(),192 buildMoveSingle( stmt ), 193 buildMoveOptional( else_ ), 219 194 std::move( astinit ), 220 false195 ast::While 221 196 ); 222 197 } // build_while 223 198 224 199 ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) { 225 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty226 buildMoveList( stmt, aststmt );227 assert( aststmt.size() == 1 ); // compound created if empty228 229 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty230 buildMoveList( else_, astelse );231 assert( astelse.size() <= 1 );232 233 200 // do-while cannot have declarations in the contitional, so init is always empty 234 201 return new ast::WhileDoStmt( location, 235 202 notZeroExpr( maybeMoveBuild( ctl ) ), 236 aststmt.front(),237 astelse.empty() ? nullptr : astelse.front().release(),203 buildMoveSingle( stmt ), 204 buildMoveOptional( else_ ), 238 205 {}, 239 true206 ast::DoWhile 240 207 ); 241 208 } // build_do_while … … 251 218 astincr = maybeMoveBuild( forctl->change ); 252 219 delete forctl; 253 254 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty255 buildMoveList( stmt, aststmt );256 assert( aststmt.size() == 1 );257 258 std::vector<ast::ptr<ast::Stmt>> astelse; // else clause, maybe empty259 buildMoveList( else_, astelse );260 assert( astelse.size() <= 1 );261 220 262 221 return new ast::ForStmt( location, … … 264 223 astcond, 265 224 astincr, 266 aststmt.front(),267 astelse.empty() ? nullptr : astelse.front().release()225 buildMoveSingle( stmt ), 226 buildMoveOptional( else_ ) 268 227 ); 269 228 } // build_for … … 326 285 } // build_resume_at 327 286 328 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {287 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) { 329 288 std::vector<ast::ptr<ast::CatchClause>> aststmt; 330 buildMove ClauseList( catch_, aststmt );289 buildMoveList( catch_, aststmt ); 331 290 ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) ); 332 291 ast::FinallyClause * finallyBlock = nullptr; … … 342 301 343 302 ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) { 344 std::vector<ast::ptr<ast::Stmt>> aststmt;345 buildMoveList( body, aststmt );346 assert( aststmt.size() == 1 );347 303 return new ast::CatchClause( location, 348 304 kind, 349 305 maybeMoveBuild( decl ), 350 306 maybeMoveBuild( cond ), 351 aststmt.front().release()307 buildMoveSingle( body ) 352 308 ); 353 309 } // build_catch 354 310 355 311 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 356 std::vector<ast::ptr<ast::Stmt>> aststmt;357 buildMoveList( stmt, aststmt );358 assert( aststmt.size() == 1 );359 312 return new ast::FinallyClause( location, 360 aststmt.front().strict_as<ast::CompoundStmt>() 313 strict_dynamic_cast<const ast::CompoundStmt *>( 314 buildMoveSingle( stmt ) 315 ) 361 316 ); 362 317 } // build_finally 363 318 364 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) { 365 std::vector<ast::ptr<ast::Stmt>> stmts; 366 buildMoveList( then, stmts ); 367 ast::CompoundStmt const * then2 = nullptr; 368 if(!stmts.empty()) { 369 assert( stmts.size() == 1 ); 370 then2 = stmts.front().strict_as<ast::CompoundStmt>(); 371 } 372 auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None ); 373 node->type = type; 374 return node; 319 ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Kind kind ) { 320 return new ast::SuspendStmt( location, 321 strict_dynamic_cast<const ast::CompoundStmt *, nullptr>( 322 buildMoveOptional( then ) 323 ), 324 kind 325 ); 375 326 } // build_suspend 376 327 … … 525 476 526 477 // Question 527 ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr* instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {478 ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) { 528 479 std::vector<ast::ptr<ast::Expr>> out, in; 529 480 std::vector<ast::ptr<ast::ConstantExpr>> clob; … … 533 484 buildMoveList( clobber, clob ); 534 485 return new ast::AsmStmt( location, 535 voltile,536 instruction,486 is_volatile, 487 maybeMoveBuild( instruction ), 537 488 std::move( out ), 538 489 std::move( in ), -
src/Parser/TypeData.cc
ra50fdfb r6e1e2d0 24 24 #include "Common/SemanticError.h" // for SemanticError 25 25 #include "Common/utility.h" // for splice, spliceBegin 26 #include "Parser/ parserutility.h" // for maybeCopy, maybeBuild, maybeMoveB...27 #include "Parser/ ParseNode.h" // for DeclarationNode, ExpressionNode26 #include "Parser/ExpressionNode.h" // for ExpressionNode 27 #include "Parser/StatementNode.h" // for StatementNode 28 28 29 29 class Attribute; … … 1397 1397 std::move( attributes ), 1398 1398 funcSpec, 1399 isVarArgs1399 (isVarArgs) ? ast::VariableArgs : ast::FixedArgs 1400 1400 ); 1401 1401 buildList( td->function.withExprs, decl->withExprs ); -
src/Parser/TypeData.h
ra50fdfb r6e1e2d0 16 16 #pragma once 17 17 18 #include <iosfwd> 19 #include <list> 20 #include <string> 18 #include <iosfwd> // for ostream 19 #include <list> // for list 20 #include <string> // for string 21 21 22 #include "AST/Type.hpp" 23 #include " ParseNode.h" // for DeclarationNode, DeclarationNode::Ag...22 #include "AST/Type.hpp" // for Type 23 #include "DeclarationNode.h" // for DeclarationNode 24 24 25 25 struct TypeData { -
src/Parser/TypedefTable.cc
ra50fdfb r6e1e2d0 16 16 17 17 #include "TypedefTable.h" 18 #include <cassert> // for assert 19 #include <iostream> 18 19 #include <cassert> // for assert 20 #include <string> // for string 21 #include <iostream> // for iostream 22 23 #include "ExpressionNode.h" // for LabelNode 24 #include "ParserTypes.h" // for Token 25 #include "StatementNode.h" // for CondCtl, ForCtrl 26 // This (generated) header must come late as it is missing includes. 27 #include "parser.hh" // for IDENTIFIER, TYPEDEFname, TYPEGENname 28 20 29 using namespace std; 21 30 22 31 #if 0 23 32 #define debugPrint( code ) code 33 34 static const char *kindName( int kind ) { 35 switch ( kind ) { 36 case IDENTIFIER: return "identifier"; 37 case TYPEDIMname: return "typedim"; 38 case TYPEDEFname: return "typedef"; 39 case TYPEGENname: return "typegen"; 40 default: 41 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl; 42 abort(); 43 } // switch 44 } // kindName 24 45 #else 25 46 #define debugPrint( code ) 26 47 #endif 27 28 using namespace std; // string, iostream29 30 debugPrint(31 static const char *kindName( int kind ) {32 switch ( kind ) {33 case IDENTIFIER: return "identifier";34 case TYPEDIMname: return "typedim";35 case TYPEDEFname: return "typedef";36 case TYPEGENname: return "typegen";37 default:38 cerr << "Error: cfa-cpp internal error, invalid kind of identifier" << endl;39 abort();40 } // switch41 } // kindName42 );43 48 44 49 TypedefTable::~TypedefTable() { … … 78 83 typedefTable.addToEnclosingScope( name, kind, "MTD" ); 79 84 } // if 85 } // TypedefTable::makeTypedef 86 87 void TypedefTable::makeTypedef( const string & name ) { 88 return makeTypedef( name, TYPEDEFname ); 80 89 } // TypedefTable::makeTypedef 81 90 -
src/Parser/TypedefTable.h
ra50fdfb r6e1e2d0 19 19 20 20 #include "Common/ScopedMap.h" // for ScopedMap 21 #include "ParserTypes.h"22 #include "parser.hh" // for IDENTIFIER, TYPEDEFname, TYPEGENname23 21 24 22 class TypedefTable { 25 23 struct Note { size_t level; bool forall; }; 26 24 typedef ScopedMap< std::string, int, Note > KindTable; 27 KindTable kindTable; 25 KindTable kindTable; 28 26 unsigned int level = 0; 29 27 public: … … 33 31 bool existsCurr( const std::string & identifier ) const; 34 32 int isKind( const std::string & identifier ) const; 35 void makeTypedef( const std::string & name, int kind = TYPEDEFname ); 33 void makeTypedef( const std::string & name, int kind ); 34 void makeTypedef( const std::string & name ); 36 35 void addToScope( const std::string & identifier, int kind, const char * ); 37 36 void addToEnclosingScope( const std::string & identifier, int kind, const char * ); -
src/Parser/lex.ll
ra50fdfb r6e1e2d0 44 44 45 45 #include "config.h" // configure info 46 #include "DeclarationNode.h" // for DeclarationNode 47 #include "ExpressionNode.h" // for LabelNode 48 #include "InitializerNode.h" // for InitializerNode 46 49 #include "ParseNode.h" 50 #include "ParserTypes.h" // for Token 51 #include "StatementNode.h" // for CondCtl, ForCtrl 47 52 #include "TypedefTable.h" 53 // This (generated) header must come late as it is missing includes. 54 #include "parser.hh" // generated info 48 55 49 56 string * build_postfix_name( string * name ); -
src/Parser/module.mk
ra50fdfb r6e1e2d0 21 21 SRC += \ 22 22 Parser/DeclarationNode.cc \ 23 Parser/DeclarationNode.h \ 23 24 Parser/ExpressionNode.cc \ 25 Parser/ExpressionNode.h \ 24 26 Parser/InitializerNode.cc \ 27 Parser/InitializerNode.h \ 25 28 Parser/lex.ll \ 26 29 Parser/ParseNode.cc \ … … 33 36 Parser/RunParser.hpp \ 34 37 Parser/StatementNode.cc \ 38 Parser/StatementNode.h \ 35 39 Parser/TypeData.cc \ 36 40 Parser/TypeData.h \ -
src/Parser/parser.yy
ra50fdfb r6e1e2d0 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Andrew Beach12 // Last Modified On : Tue Apr 4 14:02:00202313 // Update Count : 63 2911 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Apr 26 16:45:37 2023 13 // Update Count : 6330 14 14 // 15 15 … … 48 48 using namespace std; 49 49 50 #include "SynTree/Declaration.h" 51 #include "ParseNode.h" 50 #include "SynTree/Type.h" // for Type 51 #include "DeclarationNode.h" // for DeclarationNode, ... 52 #include "ExpressionNode.h" // for ExpressionNode, ... 53 #include "InitializerNode.h" // for InitializerNode, ... 54 #include "ParserTypes.h" 55 #include "StatementNode.h" // for build_... 52 56 #include "TypedefTable.h" 53 57 #include "TypeData.h" 54 #include "SynTree/LinkageSpec.h"55 58 #include "Common/SemanticError.h" // error_str 56 59 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... … … 297 300 %union { 298 301 Token tok; 299 ParseNode * pn; 300 ExpressionNode * en; 302 ExpressionNode * expr; 301 303 DeclarationNode * decl; 302 304 ast::AggregateDecl::Aggregate aggKey; 303 305 ast::TypeDecl::Kind tclass; 304 StatementNode * sn; 306 StatementNode * stmt; 307 ClauseNode * clause; 305 308 ast::WaitForStmt * wfs; 306 ast::WaitUntilStmt::ClauseNode * wuscn; 307 ast::Expr * constant; 309 ast::WaitUntilStmt::ClauseNode * wucn; 308 310 CondCtl * ifctl; 309 ForCtrl * fctl; 310 OperKinds compop; 311 LabelNode * label; 312 InitializerNode * in; 313 OperKinds op; 311 ForCtrl * forctl; 312 LabelNode * labels; 313 InitializerNode * init; 314 OperKinds oper; 314 315 std::string * str; 315 bool flag;316 EnumHiding hide;317 ast::ExceptionKind catch_kind;316 bool is_volatile; 317 EnumHiding enum_hiding; 318 ast::ExceptionKind except_kind; 318 319 ast::GenericExpr * genexpr; 319 320 } … … 381 382 %type<tok> identifier identifier_at identifier_or_type_name attr_name 382 383 %type<tok> quasi_keyword 383 %type< constant> string_literal384 %type<expr> string_literal 384 385 %type<str> string_literal_list 385 386 386 %type< hide> hide_opt visible_hide_opt387 %type<enum_hiding> hide_opt visible_hide_opt 387 388 388 389 // expressions 389 %type<e n> constant390 %type<e n> tuple tuple_expression_list391 %type<op > ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator392 %type<e n> primary_expression postfix_expression unary_expression393 %type<e n> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression394 %type<e n> shift_expression relational_expression equality_expression395 %type<e n> AND_expression exclusive_OR_expression inclusive_OR_expression396 %type<e n> logical_AND_expression logical_OR_expression397 %type<e n> conditional_expression constant_expression assignment_expression assignment_expression_opt398 %type<e n> comma_expression comma_expression_opt399 %type<e n> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt390 %type<expr> constant 391 %type<expr> tuple tuple_expression_list 392 %type<oper> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator 393 %type<expr> primary_expression postfix_expression unary_expression 394 %type<expr> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression 395 %type<expr> shift_expression relational_expression equality_expression 396 %type<expr> AND_expression exclusive_OR_expression inclusive_OR_expression 397 %type<expr> logical_AND_expression logical_OR_expression 398 %type<expr> conditional_expression constant_expression assignment_expression assignment_expression_opt 399 %type<expr> comma_expression comma_expression_opt 400 %type<expr> argument_expression_list_opt argument_expression_list argument_expression default_initializer_opt 400 401 %type<ifctl> conditional_declaration 401 %type<f ctl> for_control_expression for_control_expression_list402 %type< compop> upupeq updown updowneq downupdowneq403 %type<e n> subrange402 %type<forctl> for_control_expression for_control_expression_list 403 %type<oper> upupeq updown updowneq downupdowneq 404 %type<expr> subrange 404 405 %type<decl> asm_name_opt 405 %type<e n> asm_operands_opt asm_operands_list asm_operand406 %type<label > label_list407 %type<e n> asm_clobbers_list_opt408 %type< flag> asm_volatile_opt409 %type<e n> handler_predicate_opt406 %type<expr> asm_operands_opt asm_operands_list asm_operand 407 %type<labels> label_list 408 %type<expr> asm_clobbers_list_opt 409 %type<is_volatile> asm_volatile_opt 410 %type<expr> handler_predicate_opt 410 411 %type<genexpr> generic_association generic_assoc_list 411 412 412 413 // statements 413 %type<sn> statement labeled_statement compound_statement 414 %type<sn> statement_decl statement_decl_list statement_list_nodecl 415 %type<sn> selection_statement if_statement 416 %type<sn> switch_clause_list_opt switch_clause_list 417 %type<en> case_value 418 %type<sn> case_clause case_value_list case_label case_label_list 419 %type<sn> iteration_statement jump_statement 420 %type<sn> expression_statement asm_statement 421 %type<sn> with_statement 422 %type<en> with_clause_opt 423 %type<sn> exception_statement handler_clause finally_clause 424 %type<catch_kind> handler_key 425 %type<sn> mutex_statement 426 %type<en> when_clause when_clause_opt waitfor waituntil timeout 427 %type<sn> waitfor_statement waituntil_statement 414 %type<stmt> statement labeled_statement compound_statement 415 %type<stmt> statement_decl statement_decl_list statement_list_nodecl 416 %type<stmt> selection_statement if_statement 417 %type<clause> switch_clause_list_opt switch_clause_list 418 %type<expr> case_value 419 %type<clause> case_clause case_value_list case_label case_label_list 420 %type<stmt> iteration_statement jump_statement 421 %type<stmt> expression_statement asm_statement 422 %type<stmt> with_statement 423 %type<expr> with_clause_opt 424 %type<stmt> exception_statement 425 %type<clause> handler_clause finally_clause 426 %type<except_kind> handler_key 427 %type<stmt> mutex_statement 428 %type<expr> when_clause when_clause_opt waitfor waituntil timeout 429 %type<stmt> waitfor_statement waituntil_statement 428 430 %type<wfs> wor_waitfor_clause 429 %type<wu scn> waituntil_clause wand_waituntil_clause wor_waituntil_clause431 %type<wucn> waituntil_clause wand_waituntil_clause wor_waituntil_clause 430 432 431 433 // declarations … … 439 441 %type<decl> assertion assertion_list assertion_list_opt 440 442 441 %type<e n> bit_subrange_size_opt bit_subrange_size443 %type<expr> bit_subrange_size_opt bit_subrange_size 442 444 443 445 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type … … 452 454 453 455 %type<decl> enumerator_list enum_type enum_type_nobody 454 %type<in > enumerator_value_opt456 %type<init> enumerator_value_opt 455 457 456 458 %type<decl> external_definition external_definition_list external_definition_list_opt … … 459 461 460 462 %type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract 461 %type<e n> field field_name_list field_name fraction_constants_opt463 %type<expr> field field_name_list field_name fraction_constants_opt 462 464 463 465 %type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr … … 508 510 %type<decl> type_parameter type_parameter_list type_initializer_opt 509 511 510 %type<e n> type_parameters_opt type_list array_type_list512 %type<expr> type_parameters_opt type_list array_type_list 511 513 512 514 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list … … 519 521 520 522 // initializers 521 %type<in > initializer initializer_list_opt initializer_opt523 %type<init> initializer initializer_list_opt initializer_opt 522 524 523 525 // designators 524 %type<e n> designator designator_list designation526 %type<expr> designator designator_list designation 525 527 526 528 … … 644 646 645 647 string_literal: 646 string_literal_list { $$ = build_constantStr( yylloc, *$1); }648 string_literal_list { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); } 647 649 ; 648 650 … … 739 741 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 740 742 | string_literal '[' assignment_expression ']' // "abc"[3], 3["abc"] 741 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }743 { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); } 742 744 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 743 745 { … … 757 759 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 758 760 | string_literal '`' identifier // CFA, postfix call 759 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), new ExpressionNode( $1 )) ); }761 { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); } 760 762 | postfix_expression '.' identifier 761 763 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } … … 857 859 | constant 858 860 | string_literal 859 { $$ = new ExpressionNode( $1 ); }861 { $$ = $1; } 860 862 | EXTENSION cast_expression // GCC 861 863 { $$ = $2->set_extension( true ); } … … 1260 1262 1261 1263 case_value_list: // CFA 1262 case_value { $$ = new StatementNode( build_case($1 ) ); }1264 case_value { $$ = new ClauseNode( build_case( yylloc, $1 ) ); } 1263 1265 // convert case list, e.g., "case 1, 3, 5:" into "case 1: case 3: case 5" 1264 | case_value_list ',' case_value { $$ = (StatementNode *)($1->set_last( new StatementNode( build_case( $3 )) ) ); }1266 | case_value_list ',' case_value { $$ = $1->set_last( new ClauseNode( build_case( yylloc, $3 ) ) ); } 1265 1267 ; 1266 1268 … … 1271 1273 | CASE case_value_list error // syntax error 1272 1274 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1273 | DEFAULT ':' { $$ = new StatementNode( build_default( yylloc ) ); }1275 | DEFAULT ':' { $$ = new ClauseNode( build_default( yylloc ) ); } 1274 1276 // A semantic check is required to ensure only one default clause per switch/choose statement. 1275 1277 | DEFAULT error // syntax error … … 1279 1281 case_label_list: // CFA 1280 1282 case_label 1281 | case_label_list case_label { $$ = (StatementNode *)( $1->set_last( $2 )); }1283 | case_label_list case_label { $$ = $1->set_last( $2 ); } 1282 1284 ; 1283 1285 … … 1296 1298 { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); } 1297 1299 | switch_clause_list case_label_list statement_list_nodecl 1298 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 )) ) ) ); }1300 { $$ = $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ); } 1299 1301 ; 1300 1302 … … 1679 1681 1680 1682 waituntil: 1681 WAITUNTIL '(' c ast_expression ')'1683 WAITUNTIL '(' comma_expression ')' 1682 1684 { $$ = $3; } 1683 1685 ; … … 1736 1738 handler_clause: 1737 1739 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1738 { $$ = new StatementNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }1740 { $$ = new ClauseNode( build_catch( yylloc, $1, $4, $6, $8 ) ); } 1739 1741 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement 1740 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }1742 { $$ = $1->set_last( new ClauseNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); } 1741 1743 ; 1742 1744 … … 1755 1757 1756 1758 finally_clause: 1757 FINALLY compound_statement { $$ = new StatementNode( build_finally( yylloc, $2 ) ); }1759 FINALLY compound_statement { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); } 1758 1760 ; 1759 1761 … … 1813 1815 asm_operand: // GCC 1814 1816 string_literal '(' constant_expression ')' 1815 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }1817 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1816 1818 | '[' IDENTIFIER ']' string_literal '(' constant_expression ')' 1817 1819 { 1818 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) );1820 $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, maybeMoveBuild( $4 ), maybeMoveBuild( $6 ) ) ); 1819 1821 delete $2.str; 1820 1822 } … … 1825 1827 { $$ = nullptr; } // use default argument 1826 1828 | string_literal 1827 { $$ = new ExpressionNode( $1 ); }1829 { $$ = $1; } 1828 1830 | asm_clobbers_list_opt ',' string_literal 1829 { $$ = (ExpressionNode *)( $1->set_last( new ExpressionNode( $3 ) )); }1831 { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); } 1830 1832 ; 1831 1833 … … 1899 1901 static_assert: 1900 1902 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1901 { $$ = DeclarationNode::newStaticAssert( $3, $5); }1903 { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); } 1902 1904 | STATICASSERT '(' constant_expression ')' ';' // CFA 1903 1905 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); } … … 3329 3331 { 3330 3332 DeclarationNode * name = new DeclarationNode(); 3331 name->asmName = $3;3333 name->asmName = maybeMoveBuild( $3 ); 3332 3334 $$ = name->addQualifiers( $5 ); 3333 3335 } -
src/Parser/parserutility.h
ra50fdfb r6e1e2d0 24 24 25 25 template< typename T > 26 static inline auto maybeBuild( const T *orig ) -> decltype(orig->build()) {26 static inline auto maybeBuild( T * orig ) -> decltype(orig->build()) { 27 27 return (orig) ? orig->build() : nullptr; 28 28 } 29 29 30 30 template< typename T > 31 static inline auto maybeMoveBuild( const T *orig ) -> decltype(orig->build()) {31 static inline auto maybeMoveBuild( T * orig ) -> decltype(orig->build()) { 32 32 auto ret = maybeBuild<T>(orig); 33 33 delete orig;
Note: See TracChangeset
for help on using the changeset viewer.