Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/DeclarationNode.cc

    r45e753c rbb7422a  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Apr 20 11:46:00 2023
    13 // Update Count     : 1393
     12// Last Modified On : Tue Apr  4 10:28:00 2023
     13// Update Count     : 1392
    1414//
    15 
    16 #include "DeclarationNode.h"
    1715
    1816#include <cassert>                 // for assert, assertf, strict_dynamic_cast
     
    3634#include "Common/UniqueName.h"     // for UniqueName
    3735#include "Common/utility.h"        // for maybeClone
    38 #include "Parser/ExpressionNode.h" // for ExpressionNode
    39 #include "Parser/InitializerNode.h"// for InitializerNode
    40 #include "Parser/StatementNode.h"  // for StatementNode
     36#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
    4137#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    4238#include "TypedefTable.h"          // for TypedefTable
     
    1003999}
    10041000
    1005 // If a typedef wraps an anonymous declaration, name the inner declaration
    1006 // so it has a consistent name across translation units.
    1007 static void nameTypedefedDecl(
    1008                 DeclarationNode * innerDecl,
    1009                 const DeclarationNode * outerDecl ) {
    1010         TypeData * outer = outerDecl->type;
    1011         assert( outer );
    1012         // First make sure this is a typedef:
    1013         if ( outer->kind != TypeData::Symbolic || !outer->symbolic.isTypedef ) {
    1014                 return;
    1015         }
    1016         TypeData * inner = innerDecl->type;
    1017         assert( inner );
    1018         // Always clear any CVs associated with the aggregate:
    1019         inner->qualifiers.reset();
    1020         // Handle anonymous aggregates: typedef struct { int i; } foo
    1021         if ( inner->kind == TypeData::Aggregate && inner->aggregate.anon ) {
    1022                 delete inner->aggregate.name;
    1023                 inner->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
    1024                 inner->aggregate.anon = false;
    1025                 assert( outer->base );
    1026                 delete outer->base->aggInst.aggregate->aggregate.name;
    1027                 outer->base->aggInst.aggregate->aggregate.name = new string( "__anonymous_" + *outerDecl->name );
    1028                 outer->base->aggInst.aggregate->aggregate.anon = false;
    1029                 outer->base->aggInst.aggregate->qualifiers.reset();
    1030         // Handle anonymous enumeration: typedef enum { A, B, C } foo
    1031         } else if ( inner->kind == TypeData::Enum && inner->enumeration.anon ) {
    1032                 delete inner->enumeration.name;
    1033                 inner->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
    1034                 inner->enumeration.anon = false;
    1035                 assert( outer->base );
    1036                 delete outer->base->aggInst.aggregate->enumeration.name;
    1037                 outer->base->aggInst.aggregate->enumeration.name = new string( "__anonymous_" + *outerDecl->name );
    1038                 outer->base->aggInst.aggregate->enumeration.anon = false;
    1039                 // No qualifiers.reset() here.
    1040         }
    1041 }
    1042 
    1043 // This code handles a special issue with the attribute transparent_union.
    1044 //
    1045 //    typedef union U { int i; } typedef_name __attribute__(( aligned(16) )) __attribute__(( transparent_union ))
    1046 //
    1047 // Here the attribute aligned goes with the typedef_name, so variables declared of this type are
    1048 // aligned.  However, the attribute transparent_union must be moved from the typedef_name to
    1049 // alias union U.  Currently, this is the only know attribute that must be moved from typedef to
    1050 // alias.
    1051 static void moveUnionAttribute( ast::Decl * decl, ast::UnionDecl * unionDecl ) {
    1052         if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {
    1053                 // Is the typedef alias a union aggregate?
    1054                 if ( nullptr == unionDecl ) return;
    1055 
    1056                 // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
    1057                 if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {
    1058                         auto instType = ast::mutate( unionInstType );
    1059                         // Remove all transparent_union attributes from typedef and move to alias union.
    1060                         for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) {
    1061                                 assert( *attr );
    1062                                 if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
    1063                                         unionDecl->attributes.emplace_back( attr->release() );
    1064                                         attr = instType->attributes.erase( attr );
    1065                                 } else {
    1066                                         attr++;
    1067                                 }
    1068                         }
    1069                         typedefDecl->base = instType;
    1070                 }
    1071         }
    1072 }
    1073 
    1074 // Get the non-anonymous name of the instance type of the declaration,
    1075 // if one exists.
    1076 static const std::string * getInstTypeOfName( ast::Decl * decl ) {
    1077         if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    1078                 if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) {
    1079                         if ( aggr->name.find("anonymous") == std::string::npos ) {
    1080                                 return &aggr->name;
    1081                         }
    1082                 }
    1083         }
    1084         return nullptr;
    1085 }
    1086 
    1087 void buildList( DeclarationNode * firstNode,
     1001void buildList( const DeclarationNode * firstNode,
    10881002                std::vector<ast::ptr<ast::Decl>> & outputList ) {
    10891003        SemanticErrorException errors;
    10901004        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
    10911005
    1092         for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
     1006        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    10931007                try {
    1094                         bool extracted_named = false;
    1095                         ast::UnionDecl * unionDecl = nullptr;
     1008                        bool extracted = false, anon = false;
     1009                        ast::AggregateDecl * unionDecl = nullptr;
    10961010
    10971011                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
     1012                                // Handle the case where a SUE declaration is contained within an object or type declaration.
     1013
    10981014                                assert( cur->type );
    1099                                 nameTypedefedDecl( extr, cur );
    1100 
    1101                                 if ( ast::Decl * decl = extr->build() ) {
     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 ) {
    11021048                                        // Remember the declaration if it is a union aggregate ?
    11031049                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
    11041050
     1051                                        decl->location = cur->location;
    11051052                                        *out++ = decl;
    11061053
    11071054                                        // need to remember the cases where a declaration contains an anonymous aggregate definition
     1055                                        extracted = true;
    11081056                                        assert( extr->type );
    11091057                                        if ( extr->type->kind == TypeData::Aggregate ) {
    11101058                                                // typedef struct { int A } B is the only case?
    1111                                                 extracted_named = !extr->type->aggregate.anon;
     1059                                                anon = extr->type->aggregate.anon;
    11121060                                        } else if ( extr->type->kind == TypeData::Enum ) {
    11131061                                                // typedef enum { A } B is the only case?
    1114                                                 extracted_named = !extr->type->enumeration.anon;
    1115                                         } else {
    1116                                                 extracted_named = true;
     1062                                                anon = extr->type->enumeration.anon;
    11171063                                        }
    11181064                                } // if
     
    11201066                        } // if
    11211067
    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                                         }
     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
    11421097                                } // if
    1143                                 *out++ = decl;
     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
    11441122                        } // if
    1145                 } catch ( SemanticErrorException & e ) {
     1123                } catch( SemanticErrorException & e ) {
    11461124                        errors.append( e );
    11471125                } // try
     
    11541132
    11551133// currently only builds assertions, function parameters, and return values
    1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
     1134void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
    11571135        SemanticErrorException errors;
    11581136        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
    11591137
    1160         for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur ) ) {
     1138        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    11611139                try {
    11621140                        ast::Decl * decl = cur->build();
    1163                         assertf( decl, "buildList: build for ast::DeclWithType." );
     1141                        assert( decl );
    11641142                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    11651143                                dwt->location = cur->location;
     
    11901168                                );
    11911169                                *out++ = obj;
    1192                         } else {
    1193                                 assertf( false, "buildList: Could not convert to ast::DeclWithType." );
    11941170                        } // if
    1195                 } catch ( SemanticErrorException & e ) {
     1171                } catch( SemanticErrorException & e ) {
    11961172                        errors.append( e );
    11971173                } // try
     
    12071183        SemanticErrorException errors;
    12081184        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
    1209 
    1210         for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) {
     1185        const DeclarationNode * cur = firstNode;
     1186
     1187        while ( cur ) {
    12111188                try {
    12121189                        * out++ = cur->buildType();
    1213                 } catch ( SemanticErrorException & e ) {
     1190                } catch( SemanticErrorException & e ) {
    12141191                        errors.append( e );
    12151192                } // try
    1216         } // for
     1193                cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
     1194        } // while
    12171195
    12181196        if ( ! errors.isEmpty() ) {
Note: See TracChangeset for help on using the changeset viewer.