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

File:
1 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() ) {
Note: See TracChangeset for help on using the changeset viewer.