Changes in src/Parser/DeclarationNode.cc [45e753c:e4d7c1c]
- File:
-
- 1 edited
-
src/Parser/DeclarationNode.cc (modified) (45 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
r45e753c re4d7c1c 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Apr 20 11:46:00 202313 // Update Count : 1 39311 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Aug 8 17:07:00 2022 13 // Update Count : 1185 14 14 // 15 16 #include "DeclarationNode.h"17 15 18 16 #include <cassert> // for assert, assertf, strict_dynamic_cast … … 23 21 #include <string> // for string, operator+, allocator, char... 24 22 25 #include "AST/Attribute.hpp" // for Attribute26 #include "AST/Copy.hpp" // for shallowCopy27 #include "AST/Decl.hpp" // for Decl28 #include "AST/Expr.hpp" // for Expr29 #include "AST/Print.hpp" // for print30 #include "AST/Stmt.hpp" // for AsmStmt, DirectiveStmt31 #include "AST/StorageClasses.hpp" // for Storage::Class32 #include "AST/Type.hpp" // for Type33 #include "Common/CodeLocation.h" // for CodeLocation34 #include "Common/Iterate.hpp" // for reverseIterate35 23 #include "Common/SemanticError.h" // for SemanticError 36 24 #include "Common/UniqueName.h" // for UniqueName 37 #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 25 #include "Common/utility.h" // for maybeClone, maybeBuild, CodeLocation 26 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 27 #include "SynTree/LinkageSpec.h" // for Spec, linkageName, Cforall 28 #include "SynTree/Attribute.h" // for Attribute 29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration 30 #include "SynTree/Expression.h" // for Expression, ConstantExpr 31 #include "SynTree/Statement.h" // for AsmStmt 32 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Type::... 41 33 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 42 34 #include "TypedefTable.h" // for TypedefTable … … 49 41 50 42 // These must harmonize with the corresponding DeclarationNode enumerations. 51 const char * DeclarationNode::basicTypeNames[] = { 52 "void", "_Bool", "char", "int", "int128", 53 "float", "double", "long double", "float80", "float128", 54 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" 55 }; 56 const char * DeclarationNode::complexTypeNames[] = { 57 "_Complex", "NoComplexTypeNames", "_Imaginary" 58 }; // Imaginary unsupported => parse, but make invisible and print error message 59 const char * DeclarationNode::signednessNames[] = { 60 "signed", "unsigned", "NoSignednessNames" 61 }; 62 const char * DeclarationNode::lengthNames[] = { 63 "short", "long", "long long", "NoLengthNames" 64 }; 65 const char * DeclarationNode::builtinTypeNames[] = { 66 "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" 67 }; 43 const char * DeclarationNode::basicTypeNames[] = { "void", "_Bool", "char", "int", "int128", 44 "float", "double", "long double", "float80", "float128", 45 "_float16", "_float32", "_float32x", "_float64", "_float64x", "_float128", "_float128x", "NoBasicTypeNames" }; 46 const char * DeclarationNode::complexTypeNames[] = { "_Complex", "NoComplexTypeNames", "_Imaginary" }; // Imaginary unsupported => parse, but make invisible and print error message 47 const char * DeclarationNode::signednessNames[] = { "signed", "unsigned", "NoSignednessNames" }; 48 const char * DeclarationNode::lengthNames[] = { "short", "long", "long long", "NoLengthNames" }; 49 const char * DeclarationNode::builtinTypeNames[] = { "__builtin_va_list", "__auto_type", "zero_t", "one_t", "NoBuiltinTypeNames" }; 68 50 69 51 UniqueName DeclarationNode::anonymous( "__anonymous" ); 70 52 71 extern ast::Linkage::Spec linkage; // defined in parser.yy53 extern LinkageSpec::Spec linkage; // defined in parser.yy 72 54 73 55 DeclarationNode::DeclarationNode() : … … 75 57 76 58 // variable.name = nullptr; 77 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;59 variable.tyClass = TypeDecl::NUMBER_OF_KINDS; 78 60 variable.assertions = nullptr; 79 61 variable.initializer = nullptr; 80 62 63 // attr.name = nullptr; 64 attr.expr = nullptr; 65 attr.type = nullptr; 66 81 67 assert.condition = nullptr; 82 68 assert.message = nullptr; … … 84 70 85 71 DeclarationNode::~DeclarationNode() { 72 // delete attr.name; 73 delete attr.expr; 74 delete attr.type; 75 86 76 // delete variable.name; 87 77 delete variable.assertions; 88 78 delete variable.initializer; 89 79 90 // delete type;80 // delete type; 91 81 delete bitfieldWidth; 92 82 … … 113 103 newnode->hasEllipsis = hasEllipsis; 114 104 newnode->linkage = linkage; 115 newnode->asmName = maybeC opy( asmName );116 newnode->attributes = attributes;105 newnode->asmName = maybeClone( asmName ); 106 cloneAll( attributes, newnode->attributes ); 117 107 newnode->initializer = maybeClone( initializer ); 118 108 newnode->extension = extension; … … 125 115 newnode->variable.initializer = maybeClone( variable.initializer ); 126 116 117 // newnode->attr.name = attr.name ? new string( *attr.name ) : nullptr; 118 newnode->attr.expr = maybeClone( attr.expr ); 119 newnode->attr.type = maybeClone( attr.type ); 120 127 121 newnode->assert.condition = maybeClone( assert.condition ); 128 newnode->assert.message = maybeC opy( assert.message );122 newnode->assert.message = maybeClone( assert.message ); 129 123 return newnode; 130 124 } // DeclarationNode::clone … … 136 130 } // if 137 131 138 if ( linkage != ast::Linkage::Cforall ) {139 os << ast::Linkage::name( linkage ) << " ";140 } // if 141 142 ast::print( os, storageClasses );143 ast::print( os, funcSpecs );132 if ( linkage != LinkageSpec::Cforall ) { 133 os << LinkageSpec::name( linkage ) << " "; 134 } // if 135 136 storageClasses.print( os ); 137 funcSpecs.print( os ); 144 138 145 139 if ( type ) { … … 160 154 } // if 161 155 162 if ( ! attributes.empty() ) { 163 os << string( indent + 2, ' ' ) << "with attributes " << endl; 164 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) { 165 os << string( indent + 4, ' ' ) << attr->name.c_str() << endl; 166 } // for 167 } // if 156 for ( Attribute * attr: reverseIterate( attributes ) ) { 157 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str(); 158 } // for 168 159 169 160 os << endl; … … 177 168 } 178 169 179 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {170 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) { 180 171 DeclarationNode * newnode = new DeclarationNode; 181 172 newnode->storageClasses = sc; … … 183 174 } // DeclarationNode::newStorageClass 184 175 185 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {176 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) { 186 177 DeclarationNode * newnode = new DeclarationNode; 187 178 newnode->funcSpecs = fs; … … 189 180 } // DeclarationNode::newFuncSpecifier 190 181 191 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {182 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) { 192 183 DeclarationNode * newnode = new DeclarationNode; 193 184 newnode->type = new TypeData(); … … 249 240 } 250 241 251 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {242 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 252 243 DeclarationNode * newnode = new DeclarationNode; 253 244 newnode->type = new TypeData( TypeData::Aggregate ); 254 245 newnode->type->aggregate.kind = kind; 255 newnode->type->aggregate.anon = name == nullptr; 256 newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 246 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 257 247 newnode->type->aggregate.actuals = actuals; 258 248 newnode->type->aggregate.fields = fields; … … 260 250 newnode->type->aggregate.tagged = false; 261 251 newnode->type->aggregate.parent = nullptr; 252 newnode->type->aggregate.anon = name == nullptr; 262 253 return newnode; 263 254 } // DeclarationNode::newAggregate … … 266 257 DeclarationNode * newnode = new DeclarationNode; 267 258 newnode->type = new TypeData( TypeData::Enum ); 268 newnode->type->enumeration.anon = name == nullptr; 269 newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 259 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 270 260 newnode->type->enumeration.constants = constants; 271 261 newnode->type->enumeration.body = body; 262 newnode->type->enumeration.anon = name == nullptr; 272 263 newnode->type->enumeration.typed = typed; 273 264 newnode->type->enumeration.hiding = hiding; 274 if ( base && base->type ) {265 if ( base && base->type) { 275 266 newnode->type->base = base->type; 276 267 } // if … … 278 269 return newnode; 279 270 } // DeclarationNode::newEnum 271 272 280 273 281 274 DeclarationNode * DeclarationNode::newName( const string * name ) { … … 330 323 } // DeclarationNode::newFromTypeGen 331 324 332 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {325 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) { 333 326 DeclarationNode * newnode = newName( name ); 334 327 newnode->type = nullptr; … … 342 335 newnode->type = new TypeData( TypeData::Aggregate ); 343 336 newnode->type->aggregate.name = name; 344 newnode->type->aggregate.kind = ast::AggregateDecl::Trait;337 newnode->type->aggregate.kind = AggregateDecl::Trait; 345 338 newnode->type->aggregate.params = params; 346 339 newnode->type->aggregate.fields = asserts; … … 352 345 newnode->type = new TypeData( TypeData::AggregateInst ); 353 346 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate ); 354 newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;347 newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait; 355 348 newnode->type->aggInst.aggregate->aggregate.name = name; 356 349 newnode->type->aggInst.params = params; … … 387 380 newnode->type->array.dimension = size; 388 381 newnode->type->array.isStatic = isStatic; 389 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType< ast::ConstantExpr *>() ) {382 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) { 390 383 newnode->type->array.isVarLen = false; 391 384 } else { … … 457 450 DeclarationNode * newnode = new DeclarationNode; 458 451 newnode->type = nullptr; 459 std:: vector<ast::ptr<ast::Expr>> exprs;452 std::list< Expression * > exprs; 460 453 buildList( expr, exprs ); 461 newnode->attributes.push_back( 462 new ast::Attribute( *name, std::move( exprs ) ) ); 454 newnode->attributes.push_back( new Attribute( *name, exprs ) ); 463 455 delete name; 464 456 return newnode; … … 477 469 } 478 470 479 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr* message ) {471 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) { 480 472 DeclarationNode * newnode = new DeclarationNode; 481 473 newnode->assert.condition = condition; … … 484 476 } 485 477 486 static void appendError( string & dst, const string & src ) { 478 479 void appendError( string & dst, const string & src ) { 487 480 if ( src.empty() ) return; 488 481 if ( dst.empty() ) { dst = src; return; } … … 491 484 492 485 void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) { 493 const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 494 const ast::CV::Qualifiers duplicates = qsrc & qdst; 495 496 if ( duplicates.any() ) { 497 std::stringstream str; 498 str << "duplicate "; 499 ast::print( str, duplicates ); 500 str << "qualifier(s)"; 501 appendError( error, str.str() ); 486 const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization 487 488 if ( (qsrc & qdst).any() ) { // duplicates ? 489 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates 490 if ( qsrc[i] && qdst[i] ) { 491 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] ); 492 } // if 493 } // for 502 494 } // for 503 495 } // DeclarationNode::checkQualifiers 504 496 505 497 void DeclarationNode::checkSpecifiers( DeclarationNode * src ) { 506 ast::Function::Specs fsDups = funcSpecs & src->funcSpecs; 507 if ( fsDups.any() ) { 508 std::stringstream str; 509 str << "duplicate "; 510 ast::print( str, fsDups ); 511 str << "function specifier(s)"; 512 appendError( error, str.str() ); 513 } // if 514 515 // Skip if everything is unset. 516 if ( storageClasses.any() && src->storageClasses.any() ) { 517 ast::Storage::Classes dups = storageClasses & src->storageClasses; 518 // Check for duplicates. 519 if ( dups.any() ) { 520 std::stringstream str; 521 str << "duplicate "; 522 ast::print( str, dups ); 523 str << "storage class(es)"; 524 appendError( error, str.str() ); 525 // Check for conflicts. 526 } else if ( !src->storageClasses.is_threadlocal_any() ) { 527 std::stringstream str; 528 str << "conflicting "; 529 ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) ); 530 str << "& "; 531 ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) ); 532 str << "storage classes"; 533 appendError( error, str.str() ); 534 // FIX to preserve invariant of one basic storage specifier 535 src->storageClasses.reset(); 536 } 498 if ( (funcSpecs & src->funcSpecs).any() ) { // duplicates ? 499 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates 500 if ( funcSpecs[i] && src->funcSpecs[i] ) { 501 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] ); 502 } // if 503 } // for 504 } // if 505 506 if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ? 507 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ? 508 for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates 509 if ( storageClasses[i] && src->storageClasses[i] ) { 510 appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] ); 511 } // if 512 } // for 513 // src is the new item being added and has a single bit 514 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ? 515 appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] + 516 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] ); 517 src->storageClasses.reset(); // FIX to preserve invariant of one basic storage specifier 518 } // if 537 519 } // if 538 520 … … 544 526 storageClasses |= q->storageClasses; 545 527 546 std::vector<ast::ptr<ast::Attribute>> tmp; 547 tmp.reserve( q->attributes.size() ); 548 for ( auto const & attr : q->attributes ) { 549 tmp.emplace_back( ast::shallowCopy( attr.get() ) ); 550 } 551 spliceBegin( attributes, tmp ); 552 528 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 529 attributes.push_front( attr->clone() ); 530 } // for 553 531 return this; 554 532 } // DeclarationNode::copySpecifiers … … 598 576 599 577 checkQualifiers( type, q->type ); 600 if ( (builtin == Zero || builtin == One) && q->type->qualifiers. any()&& error.length() == 0 ) {601 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] );578 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.val != 0 && error.length() == 0 ) { 579 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, Type::QualifiersNames[ilog2( q->type->qualifiers.val )], builtinTypeNames[builtin] ); 602 580 } // if 603 581 addQualifiersToType( q->type, type ); … … 620 598 } else { 621 599 switch ( dst->kind ) { 622 case TypeData::Unknown:600 case TypeData::Unknown: 623 601 src->qualifiers |= dst->qualifiers; 624 602 dst = src; 625 603 src = nullptr; 626 604 break; 627 case TypeData::Basic:605 case TypeData::Basic: 628 606 dst->qualifiers |= src->qualifiers; 629 607 if ( src->kind != TypeData::Unknown ) { … … 653 631 } // if 654 632 break; 655 default:633 default: 656 634 switch ( src->kind ) { 657 case TypeData::Aggregate:658 case TypeData::Enum:635 case TypeData::Aggregate: 636 case TypeData::Enum: 659 637 dst->base = new TypeData( TypeData::AggregateInst ); 660 638 dst->base->aggInst.aggregate = src; … … 665 643 src = nullptr; 666 644 break; 667 default:645 default: 668 646 if ( dst->forall ) { 669 647 dst->forall->appendList( src->forall ); … … 736 714 737 715 DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) { 738 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {739 if ( variable.assertions ) {740 variable.assertions->appendList( assertions );741 } else {742 variable.assertions = assertions;743 } // if744 return this;716 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 717 if ( variable.assertions ) { 718 variable.assertions->appendList( assertions ); 719 } else { 720 variable.assertions = assertions; 721 } // if 722 return this; 745 723 } // if 746 724 747 725 assert( type ); 748 726 switch ( type->kind ) { 749 case TypeData::Symbolic:727 case TypeData::Symbolic: 750 728 if ( type->symbolic.assertions ) { 751 729 type->symbolic.assertions->appendList( assertions ); … … 754 732 } // if 755 733 break; 756 default:734 default: 757 735 assert( false ); 758 736 } // switch … … 818 796 DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) { 819 797 if ( a ) { 820 spliceBegin( attributes, a->attributes ); 798 for ( Attribute *attr: reverseIterate( a->attributes ) ) { 799 attributes.push_front( attr ); 800 } // for 821 801 a->attributes.clear(); 822 802 } // if … … 851 831 if ( type ) { 852 832 switch ( type->kind ) { 853 case TypeData::Aggregate:854 case TypeData::Enum:833 case TypeData::Aggregate: 834 case TypeData::Enum: 855 835 p->type->base = new TypeData( TypeData::AggregateInst ); 856 836 p->type->base->aggInst.aggregate = type; … … 861 841 break; 862 842 863 default:843 default: 864 844 p->type->base = type; 865 845 } // switch … … 883 863 884 864 DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) { 885 if ( ! a ) return this;865 if ( ! a ) return this; 886 866 assert( a->type->kind == TypeData::Array ); 887 867 TypeData * lastArray = findLast( a->type ); 888 868 if ( type ) { 889 869 switch ( type->kind ) { 890 case TypeData::Aggregate:891 case TypeData::Enum:870 case TypeData::Aggregate: 871 case TypeData::Enum: 892 872 lastArray->base = new TypeData( TypeData::AggregateInst ); 893 873 lastArray->base->aggInst.aggregate = type; … … 897 877 lastArray->base->qualifiers |= type->qualifiers; 898 878 break; 899 default:879 default: 900 880 lastArray->base = type; 901 881 } // switch … … 939 919 940 920 DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) { 941 assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );921 assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." ); 942 922 variable.initializer = init; 943 923 return this; … … 1003 983 } 1004 984 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, 1088 std::vector<ast::ptr<ast::Decl>> & outputList ) { 985 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 1089 986 SemanticErrorException errors; 1090 std::back_insert_iterator< std::vector<ast::ptr<ast::Decl>>> out( outputList );1091 1092 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur) ) {987 std::back_insert_iterator< std::list< Declaration * > > out( outputList ); 988 989 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1093 990 try { 1094 bool extracted_named = false; 1095 ast::UnionDecl * unionDecl = nullptr; 1096 991 bool extracted = false; 992 bool anon = false; 1097 993 if ( DeclarationNode * extr = cur->extractAggregate() ) { 1098 assert( cur->type ); 1099 nameTypedefedDecl( extr, cur ); 1100 1101 if ( ast::Decl * decl = extr->build() ) { 1102 // Remember the declaration if it is a union aggregate ? 1103 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 1104 1105 *out++ = decl; 994 // handle the case where a structure declaration is contained within an object or type declaration 995 Declaration * decl = extr->build(); 996 if ( decl ) { 997 // hoist the structure declaration 998 decl->location = cur->location; 999 * out++ = decl; 1106 1000 1107 1001 // need to remember the cases where a declaration contains an anonymous aggregate definition 1002 extracted = true; 1108 1003 assert( extr->type ); 1109 1004 if ( extr->type->kind == TypeData::Aggregate ) { 1110 // typedef struct { int A } B is the only case? 1111 extracted_named = !extr->type->aggregate.anon; 1005 anon = extr->type->aggregate.anon; 1112 1006 } else if ( extr->type->kind == TypeData::Enum ) { 1113 // typedef enum { A } B is the only case? 1114 extracted_named = !extr->type->enumeration.anon; 1115 } else { 1116 extracted_named = true; 1007 // xxx - is it useful to have an implicit anonymous enum member? 1008 anon = extr->type->enumeration.anon; 1117 1009 } 1118 1010 } // if … … 1120 1012 } // if 1121 1013 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 } 1014 Declaration * decl = cur->build(); 1015 if ( decl ) { 1016 // don't include anonymous declaration for named aggregates, but do include them for anonymous aggregates, e.g.: 1017 // struct S { 1018 // struct T { int x; }; // no anonymous member 1019 // struct { int y; }; // anonymous member 1020 // struct T; // anonymous member 1021 // }; 1022 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 1023 if ( decl->name == "" ) { 1024 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) { 1025 if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) { 1026 if ( aggr->name.find("anonymous") == std::string::npos ) { 1027 if ( ! cur->get_inLine() ) { 1028 // temporary: warn about anonymous member declarations of named types, since 1029 // this conflicts with the syntax for the forward declaration of an anonymous type 1030 SemanticWarning( cur->location, Warning::AggrForwardDecl, aggr->name.c_str() ); 1031 } // if 1032 } // if 1033 } // if 1034 } // if 1035 } // if 1036 decl->location = cur->location; 1037 *out++ = decl; 1142 1038 } // if 1143 *out++ = decl;1144 1039 } // if 1145 } catch ( SemanticErrorException & e ) {1040 } catch( SemanticErrorException & e ) { 1146 1041 errors.append( e ); 1147 1042 } // try … … 1154 1049 1155 1050 // currently only builds assertions, function parameters, and return values 1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {1051 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) { 1157 1052 SemanticErrorException errors; 1158 std::back_insert_iterator< std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );1159 1160 for ( const DeclarationNode * cur = firstNode; cur; cur = strict_next( cur) ) {1053 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList ); 1054 1055 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1161 1056 try { 1162 ast::Decl* decl = cur->build();1163 assert f( decl, "buildList: build for ast::DeclWithType.");1164 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {1057 Declaration * decl = cur->build(); 1058 assert( decl ); 1059 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 1165 1060 dwt->location = cur->location; 1166 1061 *out++ = dwt; 1167 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {1062 } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) { 1168 1063 // e.g., int foo(struct S) {} 1169 auto inst = new ast::StructInstType(agg->name );1170 auto obj = new ast::ObjectDecl( cur->location, "", inst);1171 obj->l inkage = linkage;1064 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name ); 1065 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1066 obj->location = cur->location; 1172 1067 *out++ = obj; 1173 1068 delete agg; 1174 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {1069 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) { 1175 1070 // e.g., int foo(union U) {} 1176 auto inst = new ast::UnionInstType( agg->name ); 1177 auto obj = new ast::ObjectDecl( cur->location, 1178 "", inst, nullptr, ast::Storage::Classes(), 1179 linkage ); 1071 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name ); 1072 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1073 obj->location = cur->location; 1180 1074 *out++ = obj; 1181 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {1075 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) { 1182 1076 // e.g., int foo(enum E) {} 1183 auto inst = new ast::EnumInstType( agg->name ); 1184 auto obj = new ast::ObjectDecl( cur->location, 1185 "", 1186 inst, 1187 nullptr, 1188 ast::Storage::Classes(), 1189 linkage 1190 ); 1077 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name ); 1078 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr ); 1079 obj->location = cur->location; 1191 1080 *out++ = obj; 1192 } else {1193 assertf( false, "buildList: Could not convert to ast::DeclWithType." );1194 1081 } // if 1195 } catch ( SemanticErrorException & e ) {1082 } catch( SemanticErrorException & e ) { 1196 1083 errors.append( e ); 1197 1084 } // try … … 1203 1090 } // buildList 1204 1091 1205 void buildTypeList( const DeclarationNode * firstNode, 1206 std::vector<ast::ptr<ast::Type>> & outputList ) { 1092 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1207 1093 SemanticErrorException errors; 1208 std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList ); 1209 1210 for ( const DeclarationNode * cur = firstNode ; cur ; cur = strict_next( cur ) ) { 1094 std::back_insert_iterator< std::list< Type * > > out( outputList ); 1095 const DeclarationNode * cur = firstNode; 1096 1097 while ( cur ) { 1211 1098 try { 1212 1099 * out++ = cur->buildType(); 1213 } catch ( SemanticErrorException & e ) {1100 } catch( SemanticErrorException & e ) { 1214 1101 errors.append( e ); 1215 1102 } // try 1216 } // for 1103 cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); 1104 } // while 1217 1105 1218 1106 if ( ! errors.isEmpty() ) { … … 1221 1109 } // buildTypeList 1222 1110 1223 ast::Decl* DeclarationNode::build() const {1111 Declaration * DeclarationNode::build() const { 1224 1112 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1225 1113 1226 1114 if ( asmStmt ) { 1227 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() ); 1228 return new ast::AsmDecl( stmt->location, stmt ); 1115 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) ); 1229 1116 } // if 1230 1117 if ( directiveStmt ) { 1231 auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() ); 1232 return new ast::DirectiveDecl( stmt->location, stmt ); 1233 } // if 1234 1235 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 1118 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) ); 1119 } // if 1120 1121 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 1236 1122 // otype is internally converted to dtype + otype parameters 1237 static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };1238 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );1123 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension }; 1124 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." ); 1239 1125 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." ); 1240 ast::TypeDecl * ret = new ast::TypeDecl( location, 1241 *name, 1242 ast::Storage::Classes(), 1243 (ast::Type *)nullptr, 1244 kindMap[ variable.tyClass ], 1245 variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype, 1246 variable.initializer ? variable.initializer->buildType() : nullptr 1247 ); 1248 buildList( variable.assertions, ret->assertions ); 1126 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr ); 1127 buildList( variable.assertions, ret->get_assertions() ); 1249 1128 return ret; 1250 1129 } // if … … 1268 1147 } // if 1269 1148 bool isDelete = initializer && initializer->get_isDelete(); 1270 ast::Decl * decl = buildDecl( 1271 type, 1272 name ? *name : string( "" ), 1273 storageClasses, 1274 maybeBuild( bitfieldWidth ), 1275 funcSpecs, 1276 linkage, 1277 asmName, 1278 isDelete ? nullptr : maybeBuild( initializer ), 1279 copy( attributes ) 1280 )->set_extension( extension ); 1149 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 1281 1150 if ( isDelete ) { 1282 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );1151 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl ); 1283 1152 dwt->isDeleted = true; 1284 1153 } … … 1287 1156 1288 1157 if ( assert.condition ) { 1289 auto cond = maybeBuild( assert.condition ); 1290 auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) ); 1291 return new ast::StaticAssertDecl( location, cond, msg ); 1158 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 1292 1159 } 1293 1160 … … 1300 1167 } // if 1301 1168 if ( enumInLine ) { 1302 return new ast::InlineMemberDecl( location, 1303 *name, (ast::Type*)nullptr, storageClasses, linkage ); 1169 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1304 1170 } // if 1305 1171 assertf( name, "ObjectDecl must a have name\n" ); 1306 auto ret = new ast::ObjectDecl( location, 1307 *name, 1308 (ast::Type*)nullptr, 1309 maybeBuild( initializer ), 1310 storageClasses, 1311 linkage, 1312 maybeBuild( bitfieldWidth ) 1313 ); 1314 ret->asmName = asmName; 1315 ret->extension = extension; 1316 return ret; 1317 } 1318 1319 ast::Type * DeclarationNode::buildType() const { 1172 return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension ); 1173 } 1174 1175 Type * DeclarationNode::buildType() const { 1320 1176 assert( type ); 1321 1177 1178 if ( attr.expr ) { 1179 return new AttrType( buildQualifiers( type ), *name, attr.expr->build(), attributes ); 1180 } else if ( attr.type ) { 1181 return new AttrType( buildQualifiers( type ), *name, attr.type->buildType(), attributes ); 1182 } // if 1183 1322 1184 switch ( type->kind ) { 1323 case TypeData::Enum: 1324 case TypeData::Aggregate: { 1325 ast::BaseInstType * ret = 1326 buildComAggInst( type, copy( attributes ), linkage ); 1327 buildList( type->aggregate.actuals, ret->params ); 1328 return ret; 1329 } 1330 case TypeData::Symbolic: { 1331 ast::TypeInstType * ret = new ast::TypeInstType( 1332 *type->symbolic.name, 1333 // This is just a default, the true value is not known yet. 1334 ast::TypeDecl::Dtype, 1335 buildQualifiers( type ), 1336 copy( attributes ) ); 1337 buildList( type->symbolic.actuals, ret->params ); 1338 return ret; 1339 } 1340 default: 1341 ast::Type * simpletypes = typebuild( type ); 1342 // copy because member is const 1343 simpletypes->attributes = attributes; 1185 case TypeData::Enum: 1186 case TypeData::Aggregate: { 1187 ReferenceToType * ret = buildComAggInst( type, attributes, linkage ); 1188 buildList( type->aggregate.actuals, ret->get_parameters() ); 1189 return ret; 1190 } 1191 case TypeData::Symbolic: { 1192 TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes ); 1193 buildList( type->symbolic.actuals, ret->get_parameters() ); 1194 return ret; 1195 } 1196 default: 1197 Type * simpletypes = typebuild( type ); 1198 simpletypes->get_attributes() = attributes; // copy because member is const 1344 1199 return simpletypes; 1345 1200 } // switch
Note:
See TracChangeset
for help on using the changeset viewer.