Changeset 6e1e2d0 for src/Parser


Ignore:
Timestamp:
May 1, 2023, 4:19:09 PM (14 months ago)
Author:
caparsons <caparson@…>
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.
Message:

resolved merge conflicts

Location:
src/Parser
Files:
4 added
14 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    ra50fdfb r6e1e2d0  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr  4 10:28:00 2023
    13 // Update Count     : 1392
     12// Last Modified On : Thr Apr 20 11:46:00 2023
     13// Update Count     : 1393
    1414//
     15
     16#include "DeclarationNode.h"
    1517
    1618#include <cassert>                 // for assert, assertf, strict_dynamic_cast
     
    3436#include "Common/UniqueName.h"     // for UniqueName
    3537#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
    3741#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    3842#include "TypedefTable.h"          // for TypedefTable
     
    9991003}
    10001004
    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.
     1007static 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.
     1051static 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.
     1076static 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
     1087void buildList( DeclarationNode * firstNode,
    10021088                std::vector<ast::ptr<ast::Decl>> & outputList ) {
    10031089        SemanticErrorException errors;
    10041090        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
    10051091
    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 ) ) {
    10071093                try {
    1008                         bool extracted = false, anon = false;
    1009                         ast::AggregateDecl * unionDecl = nullptr;
     1094                        bool extracted_named = false;
     1095                        ast::UnionDecl * unionDecl = nullptr;
    10101096
    10111097                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
    1012                                 // Handle the case where a SUE declaration is contained within an object or type declaration.
    1013 
    10141098                                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() ) {
    10481102                                        // Remember the declaration if it is a union aggregate ?
    10491103                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
    10501104
    1051                                         decl->location = cur->location;
    10521105                                        *out++ = decl;
    10531106
    10541107                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
    1055                                         extracted = true;
    10561108                                        assert( extr->type );
    10571109                                        if ( extr->type->kind == TypeData::Aggregate ) {
    10581110                                                // typedef struct { int A } B is the only case?
    1059                                                 anon = extr->type->aggregate.anon;
     1111                                                extracted_named = !extr->type->aggregate.anon;
    10601112                                        } else if ( extr->type->kind == TypeData::Enum ) {
    10611113                                                // 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;
    10631117                                        }
    10641118                                } // if
     
    10661120                        } // if
    10671121
    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                                        }
    10971142                                } // 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;
    11221144                        } // if
    1123                 } catch( SemanticErrorException & e ) {
     1145                } catch ( SemanticErrorException & e ) {
    11241146                        errors.append( e );
    11251147                } // try
     
    11321154
    11331155// currently only builds assertions, function parameters, and return values
    1134 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
     1156void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
    11351157        SemanticErrorException errors;
    11361158        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
    11371159
    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 ) ) {
    11391161                try {
    11401162                        ast::Decl * decl = cur->build();
    1141                         assert( decl );
     1163                        assertf( decl, "buildList: build for ast::DeclWithType." );
    11421164                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    11431165                                dwt->location = cur->location;
     
    11681190                                );
    11691191                                *out++ = obj;
     1192                        } else {
     1193                                assertf( false, "buildList: Could not convert to ast::DeclWithType." );
    11701194                        } // if
    1171                 } catch( SemanticErrorException & e ) {
     1195                } catch ( SemanticErrorException & e ) {
    11721196                        errors.append( e );
    11731197                } // try
     
    11831207        SemanticErrorException errors;
    11841208        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 ) ) {
    11881211                try {
    11891212                        * out++ = cur->buildType();
    1190                 } catch( SemanticErrorException & e ) {
     1213                } catch ( SemanticErrorException & e ) {
    11911214                        errors.append( e );
    11921215                } // try
    1193                 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
    1194         } // while
     1216        } // for
    11951217
    11961218        if ( ! errors.isEmpty() ) {
  • src/Parser/ExpressionNode.cc

    ra50fdfb r6e1e2d0  
    1313// Update Count     : 1083
    1414//
     15
     16#include "ExpressionNode.h"
    1517
    1618#include <cassert>                 // for assert
     
    2527#include "Common/SemanticError.h"  // for SemanticError
    2628#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
    2831#include "parserutility.h"         // for notZeroExpr
    2932
     
    699702} // build_binary_val
    700703
    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_ptr
    707 
    708704ast::Expr * build_cond( const CodeLocation & location,
    709705                ExpressionNode * expr_node1,
  • src/Parser/InitializerNode.cc

    ra50fdfb r6e1e2d0  
    1414//
    1515
     16#include "InitializerNode.h"
     17
    1618#include <iostream>                // for operator<<, ostream, basic_ostream
    1719#include <list>                    // for list
    1820#include <string>                  // for operator<<, string
    19 
    20 using namespace std;
    2121
    2222#include "AST/Expr.hpp"            // for Expr
     
    2424#include "Common/SemanticError.h"  // for SemanticError
    2525#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
     29using namespace std;
    2730
    2831static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) {
  • src/Parser/ParseNode.h

    ra50fdfb r6e1e2d0  
    3838class DeclarationWithType;
    3939class Initializer;
     40class InitializerNode;
    4041class ExpressionNode;
    4142struct StatementNode;
     
    8081}; // ParseNode
    8182
    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 list
    112         InitializerNode * kids;
    113         bool maybeConstructed;
    114         bool isDelete;
    115 }; // InitializerNode
    116 
    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 }; // ExpressionNode
    152 
    15383// Must harmonize with OperName.
    15484enum class OperKinds {
     
    16999};
    170100
    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                 NoBasicType
    213         };
    214         static const char * basicTypeNames[];
    215         enum ComplexType { Complex, NoComplexType, Imaginary }; // Imaginary unsupported => parse, but make invisible and print error message
    216         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 attributes
    256         static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
    257         static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    258         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 functions
    286         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 }; // DeclarationNode
    352 
    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 }; // StatementNode
    398 
    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                         } // if
    468                 } catch( SemanticErrorException & e ) {
    469                         errors.append( e );
    470                 } // try
    471                 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                 } // if
    477         } // while
    478         if ( ! errors.isEmpty() ) {
    479                 throw errors;
    480         } // if
    481 }
    482 
    483 // in DeclarationNode.cc
    484 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.cc
    497101std::ostream & operator<<( std::ostream & out, const ParseNode * node );
    498102
  • src/Parser/RunParser.cpp

    ra50fdfb r6e1e2d0  
    2020#include "CodeTools/TrackLoc.h"             // for fillLocations
    2121#include "Common/CodeLocationTools.hpp"     // for forceFillCodeLocations
    22 #include "Parser/ParseNode.h"               // for DeclarationNode, buildList
     22#include "Parser/DeclarationNode.h"         // for DeclarationNode, buildList
    2323#include "Parser/TypedefTable.h"            // for TypedefTable
    2424
  • src/Parser/StatementNode.cc

    ra50fdfb r6e1e2d0  
    1111// Created On       : Sat May 16 14:59:41 2015
    1212// Last Modified By : Andrew Beach
    13 // Last Modified On : Tue Apr  4 11:40:00 2023
    14 // Update Count     : 427
     13// Last Modified On : Tue Apr 11 10:16:00 2023
     14// Update Count     : 428
    1515//
     16
     17#include "StatementNode.h"
    1618
    1719#include <cassert>                 // for assert, strict_dynamic_cast, assertf
     
    2325#include "Common/SemanticError.h"  // for SemanticError
    2426#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
    2629#include "parserutility.h"         // for notZeroExpr
    2730
     
    2932
    3033using namespace std;
     34
     35// Some helpers for cases that really want a single node but check for lists.
     36static 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
     43static 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}
    3149
    3250StatementNode::StatementNode( DeclarationNode * decl ) {
     
    5371} // StatementNode::StatementNode
    5472
    55 StatementNode * StatementNode::append_last_case( StatementNode * stmt ) {
    56         StatementNode * prev = this;
     73StatementNode * 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
     86ClauseNode * ClauseNode::append_last_case( StatementNode * stmt ) {
     87        ClauseNode * prev = this;
    5788        // 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);
    6191                assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
    6292                prev = curr;
    6393        } // for
     94        ClauseNode * node = dynamic_cast< ClauseNode * >(prev);
    6495        // convert from StatementNode list to Statement list
    65         StatementNode * node = dynamic_cast< StatementNode * >(prev);
    6696        std::vector<ast::ptr<ast::Stmt>> stmts;
    6797        buildMoveList( stmt, stmts );
     
    73103        stmts.clear();
    74104        return this;
    75 } // StatementNode::append_last_case
     105} // ClauseNode::append_last_case
    76106
    77107ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
     
    97127                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
    98128                        // build the && of all of the declared variables compared against 0
    99                         //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );
    100129                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
    101                         //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );
    102130                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
    103131                        ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     
    113141        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    114142
    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_ );
    127145
    128146        return new ast::IfStmt( location, astcond, astthen, astelse,
     
    131149} // build_if
    132150
    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 ) {
     151ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, ClauseNode * stmt ) {
    169152        std::vector<ast::ptr<ast::CaseClause>> aststmt;
    170         buildMoveClauseList( stmt, aststmt );
     153        buildMoveList( stmt, aststmt );
    171154        // If it is not a switch it is a choose statement.
    172155        if ( ! isSwitch ) {
     
    190173} // build_switch
    191174
    192 ast::CaseClause * build_case( ExpressionNode * ctl ) {
     175ast::CaseClause * build_case( const CodeLocation & location, ExpressionNode * ctl ) {
    193176        // stmt starts empty and then added to
    194177        auto expr = maybeMoveBuild( ctl );
    195         return new ast::CaseClause( expr->location, expr, {} );
     178        return new ast::CaseClause( location, expr, {} );
    196179} // build_case
    197180
     
    205188        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    206189
    207         std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
    208         buildMoveList( stmt, aststmt );
    209         assert( aststmt.size() == 1 );
    210 
    211         std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
    212         buildMoveList( else_, astelse );
    213         assert( astelse.size() <= 1 );
    214 
    215190        return new ast::WhileDoStmt( location,
    216191                astcond,
    217                 aststmt.front(),
    218                 astelse.empty() ? nullptr : astelse.front().release(),
     192                buildMoveSingle( stmt ),
     193                buildMoveOptional( else_ ),
    219194                std::move( astinit ),
    220                 false
     195                ast::While
    221196        );
    222197} // build_while
    223198
    224199ast::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 empty
    226         buildMoveList( stmt, aststmt );
    227         assert( aststmt.size() == 1 );                                          // compound created if empty
    228 
    229         std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
    230         buildMoveList( else_, astelse );
    231         assert( astelse.size() <= 1 );
    232 
    233200        // do-while cannot have declarations in the contitional, so init is always empty
    234201        return new ast::WhileDoStmt( location,
    235202                notZeroExpr( maybeMoveBuild( ctl ) ),
    236                 aststmt.front(),
    237                 astelse.empty() ? nullptr : astelse.front().release(),
     203                buildMoveSingle( stmt ),
     204                buildMoveOptional( else_ ),
    238205                {},
    239                 true
     206                ast::DoWhile
    240207        );
    241208} // build_do_while
     
    251218        astincr = maybeMoveBuild( forctl->change );
    252219        delete forctl;
    253 
    254         std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
    255         buildMoveList( stmt, aststmt );
    256         assert( aststmt.size() == 1 );
    257 
    258         std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
    259         buildMoveList( else_, astelse );
    260         assert( astelse.size() <= 1 );
    261220
    262221        return new ast::ForStmt( location,
     
    264223                astcond,
    265224                astincr,
    266                 aststmt.front(),
    267                 astelse.empty() ? nullptr : astelse.front().release()
     225                buildMoveSingle( stmt ),
     226                buildMoveOptional( else_ )
    268227        );
    269228} // build_for
     
    326285} // build_resume_at
    327286
    328 ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
     287ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, ClauseNode * catch_, ClauseNode * finally_ ) {
    329288        std::vector<ast::ptr<ast::CatchClause>> aststmt;
    330         buildMoveClauseList( catch_, aststmt );
     289        buildMoveList( catch_, aststmt );
    331290        ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
    332291        ast::FinallyClause * finallyBlock = nullptr;
     
    342301
    343302ast::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 );
    347303        return new ast::CatchClause( location,
    348304                kind,
    349305                maybeMoveBuild( decl ),
    350306                maybeMoveBuild( cond ),
    351                 aststmt.front().release()
     307                buildMoveSingle( body )
    352308        );
    353309} // build_catch
    354310
    355311ast::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 );
    359312        return new ast::FinallyClause( location,
    360                 aststmt.front().strict_as<ast::CompoundStmt>()
     313                strict_dynamic_cast<const ast::CompoundStmt *>(
     314                        buildMoveSingle( stmt )
     315                )
    361316        );
    362317} // build_finally
    363318
    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;
     319ast::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        );
    375326} // build_suspend
    376327
     
    525476
    526477// Question
    527 ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     478ast::Stmt * build_asm( const CodeLocation & location, bool is_volatile, ExpressionNode * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    528479        std::vector<ast::ptr<ast::Expr>> out, in;
    529480        std::vector<ast::ptr<ast::ConstantExpr>> clob;
     
    533484        buildMoveList( clobber, clob );
    534485        return new ast::AsmStmt( location,
    535                 voltile,
    536                 instruction,
     486                is_volatile,
     487                maybeMoveBuild( instruction ),
    537488                std::move( out ),
    538489                std::move( in ),
  • src/Parser/TypeData.cc

    ra50fdfb r6e1e2d0  
    2424#include "Common/SemanticError.h"  // for SemanticError
    2525#include "Common/utility.h"        // for splice, spliceBegin
    26 #include "Parser/parserutility.h"  // for maybeCopy, maybeBuild, maybeMoveB...
    27 #include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
     26#include "Parser/ExpressionNode.h" // for ExpressionNode
     27#include "Parser/StatementNode.h"  // for StatementNode
    2828
    2929class Attribute;
     
    13971397                std::move( attributes ),
    13981398                funcSpec,
    1399                 isVarArgs
     1399                (isVarArgs) ? ast::VariableArgs : ast::FixedArgs
    14001400        );
    14011401        buildList( td->function.withExprs, decl->withExprs );
  • src/Parser/TypeData.h

    ra50fdfb r6e1e2d0  
    1616#pragma once
    1717
    18 #include <iosfwd>                                                                               // for ostream
    19 #include <list>                                                                                 // for list
    20 #include <string>                                                                               // for string
     18#include <iosfwd>                                   // for ostream
     19#include <list>                                     // for list
     20#include <string>                                   // for string
    2121
    22 #include "AST/Type.hpp"                                                                 // for Type
    23 #include "ParseNode.h"                                                                  // for DeclarationNode, DeclarationNode::Ag...
     22#include "AST/Type.hpp"                             // for Type
     23#include "DeclarationNode.h"                        // for DeclarationNode
    2424
    2525struct TypeData {
  • src/Parser/TypedefTable.cc

    ra50fdfb r6e1e2d0  
    1616
    1717#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
    2029using namespace std;
    2130
    2231#if 0
    2332#define debugPrint( code ) code
     33
     34static 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
    2445#else
    2546#define debugPrint( code )
    2647#endif
    27 
    28 using namespace std;                                                                    // string, iostream
    29 
    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                 } // switch
    41         } // kindName
    42 );
    4348
    4449TypedefTable::~TypedefTable() {
     
    7883                typedefTable.addToEnclosingScope( name, kind, "MTD" );
    7984        } // if
     85} // TypedefTable::makeTypedef
     86
     87void TypedefTable::makeTypedef( const string & name ) {
     88        return makeTypedef( name, TYPEDEFname );
    8089} // TypedefTable::makeTypedef
    8190
  • src/Parser/TypedefTable.h

    ra50fdfb r6e1e2d0  
    1919
    2020#include "Common/ScopedMap.h"                                                   // for ScopedMap
    21 #include "ParserTypes.h"
    22 #include "parser.hh"                                                                    // for IDENTIFIER, TYPEDEFname, TYPEGENname
    2321
    2422class TypedefTable {
    2523        struct Note { size_t level; bool forall; };
    2624        typedef ScopedMap< std::string, int, Note > KindTable;
    27         KindTable kindTable;   
     25        KindTable kindTable;
    2826        unsigned int level = 0;
    2927  public:
     
    3331        bool existsCurr( const std::string & identifier ) const;
    3432        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 );
    3635        void addToScope( const std::string & identifier, int kind, const char * );
    3736        void addToEnclosingScope( const std::string & identifier, int kind, const char * );
  • src/Parser/lex.ll

    ra50fdfb r6e1e2d0  
    4444
    4545#include "config.h"                                                                             // configure info
     46#include "DeclarationNode.h"                            // for DeclarationNode
     47#include "ExpressionNode.h"                             // for LabelNode
     48#include "InitializerNode.h"                            // for InitializerNode
    4649#include "ParseNode.h"
     50#include "ParserTypes.h"                                // for Token
     51#include "StatementNode.h"                              // for CondCtl, ForCtrl
    4752#include "TypedefTable.h"
     53// This (generated) header must come late as it is missing includes.
     54#include "parser.hh"                                    // generated info
    4855
    4956string * build_postfix_name( string * name );
  • src/Parser/module.mk

    ra50fdfb r6e1e2d0  
    2121SRC += \
    2222       Parser/DeclarationNode.cc \
     23       Parser/DeclarationNode.h \
    2324       Parser/ExpressionNode.cc \
     25       Parser/ExpressionNode.h \
    2426       Parser/InitializerNode.cc \
     27       Parser/InitializerNode.h \
    2528       Parser/lex.ll \
    2629       Parser/ParseNode.cc \
     
    3336       Parser/RunParser.hpp \
    3437       Parser/StatementNode.cc \
     38       Parser/StatementNode.h \
    3539       Parser/TypeData.cc \
    3640       Parser/TypeData.h \
  • src/Parser/parser.yy

    ra50fdfb r6e1e2d0  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr  4 14:02:00 2023
    13 // Update Count     : 6329
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Wed Apr 26 16:45:37 2023
     13// Update Count     : 6330
    1414//
    1515
     
    4848using namespace std;
    4949
    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_...
    5256#include "TypedefTable.h"
    5357#include "TypeData.h"
    54 #include "SynTree/LinkageSpec.h"
    5558#include "Common/SemanticError.h"                                               // error_str
    5659#include "Common/utility.h"                                                             // for maybeMoveBuild, maybeBuild, CodeLo...
     
    297300%union {
    298301        Token tok;
    299         ParseNode * pn;
    300         ExpressionNode * en;
     302        ExpressionNode * expr;
    301303        DeclarationNode * decl;
    302304        ast::AggregateDecl::Aggregate aggKey;
    303305        ast::TypeDecl::Kind tclass;
    304         StatementNode * sn;
     306        StatementNode * stmt;
     307        ClauseNode * clause;
    305308        ast::WaitForStmt * wfs;
    306     ast::WaitUntilStmt::ClauseNode * wuscn;
    307         ast::Expr * constant;
     309    ast::WaitUntilStmt::ClauseNode * wucn;
    308310        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;
    314315        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;
    318319        ast::GenericExpr * genexpr;
    319320}
     
    381382%type<tok> identifier                                   identifier_at                           identifier_or_type_name         attr_name
    382383%type<tok> quasi_keyword
    383 %type<constant> string_literal
     384%type<expr> string_literal
    384385%type<str> string_literal_list
    385386
    386 %type<hide> hide_opt                                    visible_hide_opt
     387%type<enum_hiding> hide_opt                                     visible_hide_opt
    387388
    388389// expressions
    389 %type<en> constant
    390 %type<en> tuple                                                 tuple_expression_list
    391 %type<op> ptrref_operator                               unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
    392 %type<en> primary_expression                    postfix_expression                      unary_expression
    393 %type<en> cast_expression_list                  cast_expression                         exponential_expression          multiplicative_expression       additive_expression
    394 %type<en> shift_expression                              relational_expression           equality_expression
    395 %type<en> AND_expression                                exclusive_OR_expression         inclusive_OR_expression
    396 %type<en> logical_AND_expression                logical_OR_expression
    397 %type<en> conditional_expression                constant_expression                     assignment_expression           assignment_expression_opt
    398 %type<en> comma_expression                              comma_expression_opt
    399 %type<en> argument_expression_list_opt  argument_expression_list        argument_expression                     default_initializer_opt
     390%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
    400401%type<ifctl> conditional_declaration
    401 %type<fctl> for_control_expression              for_control_expression_list
    402 %type<compop> upupeq updown updowneq downupdowneq
    403 %type<en> subrange
     402%type<forctl> for_control_expression            for_control_expression_list
     403%type<oper> upupeq updown updowneq downupdowneq
     404%type<expr> subrange
    404405%type<decl> asm_name_opt
    405 %type<en> asm_operands_opt                              asm_operands_list                       asm_operand
    406 %type<label> label_list
    407 %type<en> asm_clobbers_list_opt
    408 %type<flag> asm_volatile_opt
    409 %type<en> handler_predicate_opt
     406%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
    410411%type<genexpr> generic_association              generic_assoc_list
    411412
    412413// 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
    428430%type<wfs> wor_waitfor_clause
    429 %type<wuscn> waituntil_clause                   wand_waituntil_clause       wor_waituntil_clause
     431%type<wucn> waituntil_clause                    wand_waituntil_clause       wor_waituntil_clause
    430432
    431433// declarations
     
    439441%type<decl> assertion assertion_list assertion_list_opt
    440442
    441 %type<en> bit_subrange_size_opt bit_subrange_size
     443%type<expr> bit_subrange_size_opt bit_subrange_size
    442444
    443445%type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type
     
    452454
    453455%type<decl> enumerator_list enum_type enum_type_nobody
    454 %type<in> enumerator_value_opt
     456%type<init> enumerator_value_opt
    455457
    456458%type<decl> external_definition external_definition_list external_definition_list_opt
     
    459461
    460462%type<decl> field_declaration_list_opt field_declaration field_declaring_list_opt field_declarator field_abstract_list_opt field_abstract
    461 %type<en> field field_name_list field_name fraction_constants_opt
     463%type<expr> field field_name_list field_name fraction_constants_opt
    462464
    463465%type<decl> external_function_definition function_definition function_array function_declarator function_no_ptr function_ptr
     
    508510%type<decl> type_parameter type_parameter_list type_initializer_opt
    509511
    510 %type<en> type_parameters_opt type_list array_type_list
     512%type<expr> type_parameters_opt type_list array_type_list
    511513
    512514%type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list
     
    519521
    520522// initializers
    521 %type<in>  initializer initializer_list_opt initializer_opt
     523%type<init>  initializer initializer_list_opt initializer_opt
    522524
    523525// designators
    524 %type<en>  designator designator_list designation
     526%type<expr>  designator designator_list designation
    525527
    526528
     
    644646
    645647string_literal:
    646         string_literal_list                                                     { $$ = build_constantStr( yylloc, *$1 ); }
     648        string_literal_list                                                     { $$ = new ExpressionNode( build_constantStr( yylloc, *$1 ) ); }
    647649        ;
    648650
     
    739741                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    740742        | 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 ) ); }
    742744        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    743745                {
     
    757759                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    758760        | 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 ) ); }
    760762        | postfix_expression '.' identifier
    761763                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
     
    857859        | constant
    858860        | string_literal
    859                 { $$ = new ExpressionNode( $1 ); }
     861                { $$ = $1; }
    860862        | EXTENSION cast_expression                                                     // GCC
    861863                { $$ = $2->set_extension( true ); }
     
    12601262
    12611263case_value_list:                                                                                // CFA
    1262         case_value                                                                      { $$ = new StatementNode( build_case( $1 ) ); }
     1264        case_value                                                                      { $$ = new ClauseNode( build_case( yylloc, $1 ) ); }
    12631265                // 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 ) ) ); }
    12651267        ;
    12661268
     
    12711273        | CASE case_value_list error                                            // syntax error
    12721274                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1273         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default( yylloc ) ); }
     1275        | DEFAULT ':'                                                           { $$ = new ClauseNode( build_default( yylloc ) ); }
    12741276                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12751277        | DEFAULT error                                                                         //  syntax error
     
    12791281case_label_list:                                                                                // CFA
    12801282        case_label
    1281         | case_label_list case_label                            { $$ = (StatementNode *)( $1->set_last( $2 )); }
     1283        | case_label_list case_label                            { $$ = $1->set_last( $2 ); }
    12821284        ;
    12831285
     
    12961298                { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
    12971299        | 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 ) ) ) ); }
    12991301        ;
    13001302
     
    16791681
    16801682waituntil:
    1681         WAITUNTIL '(' cast_expression ')'
     1683        WAITUNTIL '(' comma_expression ')'
    16821684                { $$ = $3; }
    16831685        ;
     
    17361738handler_clause:
    17371739        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 ) ); }
    17391741        | 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 ) ) ); }
    17411743        ;
    17421744
     
    17551757
    17561758finally_clause:
    1757         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( yylloc, $2 ) ); }
     1759        FINALLY compound_statement                                      { $$ = new ClauseNode( build_finally( yylloc, $2 ) ); }
    17581760        ;
    17591761
     
    18131815asm_operand:                                                                                    // GCC
    18141816        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 ) ) ); }
    18161818        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    18171819                {
    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 ) ) );
    18191821                        delete $2.str;
    18201822                }
     
    18251827                { $$ = nullptr; }                                                               // use default argument
    18261828        | string_literal
    1827                 { $$ = new ExpressionNode( $1 ); }
     1829                { $$ = $1; }
    18281830        | asm_clobbers_list_opt ',' string_literal
    1829                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( $3 ) )); }
     1831                { $$ = (ExpressionNode *)( $1->set_last( $3 ) ); }
    18301832        ;
    18311833
     
    18991901static_assert:
    19001902        STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11
    1901                 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
     1903                { $$ = DeclarationNode::newStaticAssert( $3, maybeMoveBuild( $5 ) ); }
    19021904        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    19031905                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
     
    33293331                {
    33303332                        DeclarationNode * name = new DeclarationNode();
    3331                         name->asmName = $3;
     3333                        name->asmName = maybeMoveBuild( $3 );
    33323334                        $$ = name->addQualifiers( $5 );
    33333335                }
  • src/Parser/parserutility.h

    ra50fdfb r6e1e2d0  
    2424
    2525template< typename T >
    26 static inline auto maybeBuild( const T *orig ) -> decltype(orig->build()) {
     26static inline auto maybeBuild( T * orig ) -> decltype(orig->build()) {
    2727        return (orig) ? orig->build() : nullptr;
    2828}
    2929
    3030template< typename T >
    31 static inline auto maybeMoveBuild( const T *orig ) -> decltype(orig->build()) {
     31static inline auto maybeMoveBuild( T * orig ) -> decltype(orig->build()) {
    3232        auto ret = maybeBuild<T>(orig);
    3333        delete orig;
Note: See TracChangeset for help on using the changeset viewer.