Changeset b110bcc for src/Parser/DeclarationNode.cc
- Timestamp:
- Apr 21, 2023, 5:36:12 PM (2 years ago)
- Branches:
- ADT, master
- Children:
- 28f8f15, 6e4c44d
- Parents:
- 2ed94a9 (diff), 699a97d (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
r2ed94a9 rb110bcc 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Aug 8 17:07:00 202213 // Update Count : 1 18511 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Apr 20 11:46:00 2023 13 // Update Count : 1393 14 14 // 15 16 #include "DeclarationNode.h" 15 17 16 18 #include <cassert> // for assert, assertf, strict_dynamic_cast … … 21 23 #include <string> // for string, operator+, allocator, char... 22 24 25 #include "AST/Attribute.hpp" // for Attribute 26 #include "AST/Copy.hpp" // for shallowCopy 27 #include "AST/Decl.hpp" // for Decl 28 #include "AST/Expr.hpp" // for Expr 29 #include "AST/Print.hpp" // for print 30 #include "AST/Stmt.hpp" // for AsmStmt, DirectiveStmt 31 #include "AST/StorageClasses.hpp" // for Storage::Class 32 #include "AST/Type.hpp" // for Type 33 #include "Common/CodeLocation.h" // for CodeLocation 34 #include "Common/Iterate.hpp" // for reverseIterate 23 35 #include "Common/SemanticError.h" // for SemanticError 24 36 #include "Common/UniqueName.h" // for UniqueName 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::... 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 33 41 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 34 42 #include "TypedefTable.h" // for TypedefTable … … 41 49 42 50 // These must harmonize with the corresponding DeclarationNode enumerations. 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" }; 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 }; 50 68 51 69 UniqueName DeclarationNode::anonymous( "__anonymous" ); 52 70 53 extern LinkageSpec::Spec linkage; // defined in parser.yy71 extern ast::Linkage::Spec linkage; // defined in parser.yy 54 72 55 73 DeclarationNode::DeclarationNode() : … … 57 75 58 76 // variable.name = nullptr; 59 variable.tyClass = TypeDecl::NUMBER_OF_KINDS;77 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS; 60 78 variable.assertions = nullptr; 61 79 variable.initializer = nullptr; 62 80 63 // attr.name = nullptr;64 attr.expr = nullptr;65 attr.type = nullptr;66 67 81 assert.condition = nullptr; 68 82 assert.message = nullptr; … … 70 84 71 85 DeclarationNode::~DeclarationNode() { 72 // delete attr.name;73 delete attr.expr;74 delete attr.type;75 76 86 // delete variable.name; 77 87 delete variable.assertions; 78 88 delete variable.initializer; 79 89 80 // 90 // delete type; 81 91 delete bitfieldWidth; 82 92 … … 103 113 newnode->hasEllipsis = hasEllipsis; 104 114 newnode->linkage = linkage; 105 newnode->asmName = maybeC lone( asmName );106 cloneAll( attributes, newnode->attributes );115 newnode->asmName = maybeCopy( asmName ); 116 newnode->attributes = attributes; 107 117 newnode->initializer = maybeClone( initializer ); 108 118 newnode->extension = extension; … … 115 125 newnode->variable.initializer = maybeClone( variable.initializer ); 116 126 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 121 127 newnode->assert.condition = maybeClone( assert.condition ); 122 newnode->assert.message = maybeC lone( assert.message );128 newnode->assert.message = maybeCopy( assert.message ); 123 129 return newnode; 124 130 } // DeclarationNode::clone … … 130 136 } // if 131 137 132 if ( linkage != LinkageSpec::Cforall ) {133 os << LinkageSpec::name( linkage ) << " ";134 } // if 135 136 storageClasses.print( os );137 funcSpecs.print( os );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 ); 138 144 139 145 if ( type ) { … … 154 160 } // if 155 161 156 for ( Attribute * attr: reverseIterate( attributes ) ) { 157 os << string( indent + 2, ' ' ) << "attr " << attr->name.c_str(); 158 } // for 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 159 168 160 169 os << endl; … … 168 177 } 169 178 170 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {179 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) { 171 180 DeclarationNode * newnode = new DeclarationNode; 172 181 newnode->storageClasses = sc; … … 174 183 } // DeclarationNode::newStorageClass 175 184 176 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {185 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) { 177 186 DeclarationNode * newnode = new DeclarationNode; 178 187 newnode->funcSpecs = fs; … … 180 189 } // DeclarationNode::newFuncSpecifier 181 190 182 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {191 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) { 183 192 DeclarationNode * newnode = new DeclarationNode; 184 193 newnode->type = new TypeData(); … … 240 249 } 241 250 242 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {251 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 243 252 DeclarationNode * newnode = new DeclarationNode; 244 253 newnode->type = new TypeData( TypeData::Aggregate ); 245 254 newnode->type->aggregate.kind = kind; 246 newnode->type->aggregate.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 255 newnode->type->aggregate.anon = name == nullptr; 256 newnode->type->aggregate.name = newnode->type->aggregate.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 247 257 newnode->type->aggregate.actuals = actuals; 248 258 newnode->type->aggregate.fields = fields; … … 250 260 newnode->type->aggregate.tagged = false; 251 261 newnode->type->aggregate.parent = nullptr; 252 newnode->type->aggregate.anon = name == nullptr;253 262 return newnode; 254 263 } // DeclarationNode::newAggregate … … 257 266 DeclarationNode * newnode = new DeclarationNode; 258 267 newnode->type = new TypeData( TypeData::Enum ); 259 newnode->type->enumeration.name = name == nullptr ? new string( DeclarationNode::anonymous.newName() ) : name; 268 newnode->type->enumeration.anon = name == nullptr; 269 newnode->type->enumeration.name = newnode->type->enumeration.anon ? new string( DeclarationNode::anonymous.newName() ) : name; 260 270 newnode->type->enumeration.constants = constants; 261 271 newnode->type->enumeration.body = body; 262 newnode->type->enumeration.anon = name == nullptr;263 272 newnode->type->enumeration.typed = typed; 264 273 newnode->type->enumeration.hiding = hiding; 265 if ( base && base->type ) {274 if ( base && base->type ) { 266 275 newnode->type->base = base->type; 267 276 } // if … … 269 278 return newnode; 270 279 } // DeclarationNode::newEnum 271 272 273 280 274 281 DeclarationNode * DeclarationNode::newName( const string * name ) { … … 323 330 } // DeclarationNode::newFromTypeGen 324 331 325 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {332 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) { 326 333 DeclarationNode * newnode = newName( name ); 327 334 newnode->type = nullptr; … … 335 342 newnode->type = new TypeData( TypeData::Aggregate ); 336 343 newnode->type->aggregate.name = name; 337 newnode->type->aggregate.kind = AggregateDecl::Trait;344 newnode->type->aggregate.kind = ast::AggregateDecl::Trait; 338 345 newnode->type->aggregate.params = params; 339 346 newnode->type->aggregate.fields = asserts; … … 345 352 newnode->type = new TypeData( TypeData::AggregateInst ); 346 353 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate ); 347 newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;354 newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait; 348 355 newnode->type->aggInst.aggregate->aggregate.name = name; 349 356 newnode->type->aggInst.params = params; … … 380 387 newnode->type->array.dimension = size; 381 388 newnode->type->array.isStatic = isStatic; 382 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType< ConstantExpr *>() ) {389 if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) { 383 390 newnode->type->array.isVarLen = false; 384 391 } else { … … 450 457 DeclarationNode * newnode = new DeclarationNode; 451 458 newnode->type = nullptr; 452 std:: list< Expression *> exprs;459 std::vector<ast::ptr<ast::Expr>> exprs; 453 460 buildList( expr, exprs ); 454 newnode->attributes.push_back( new Attribute( *name, exprs ) ); 461 newnode->attributes.push_back( 462 new ast::Attribute( *name, std::move( exprs ) ) ); 455 463 delete name; 456 464 return newnode; … … 469 477 } 470 478 471 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression* message ) {479 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) { 472 480 DeclarationNode * newnode = new DeclarationNode; 473 481 newnode->assert.condition = condition; … … 476 484 } 477 485 478 479 void appendError( string & dst, const string & src ) { 486 static void appendError( string & dst, const string & src ) { 480 487 if ( src.empty() ) return; 481 488 if ( dst.empty() ) { dst = src; return; } … … 484 491 485 492 void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) { 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 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() ); 494 502 } // for 495 503 } // DeclarationNode::checkQualifiers 496 504 497 505 void DeclarationNode::checkSpecifiers( DeclarationNode * src ) { 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 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 } 519 537 } // if 520 538 … … 526 544 storageClasses |= q->storageClasses; 527 545 528 for ( Attribute * attr: reverseIterate( q->attributes ) ) { 529 attributes.push_front( attr->clone() ); 530 } // for 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 531 553 return this; 532 554 } // DeclarationNode::copySpecifiers … … 576 598 577 599 checkQualifiers( type, q->type ); 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] );600 if ( (builtin == Zero || builtin == One) && q->type->qualifiers.any() && error.length() == 0 ) { 601 SemanticWarning( yylloc, Warning::BadQualifiersZeroOne, builtinTypeNames[builtin] ); 580 602 } // if 581 603 addQualifiersToType( q->type, type ); … … 598 620 } else { 599 621 switch ( dst->kind ) { 600 622 case TypeData::Unknown: 601 623 src->qualifiers |= dst->qualifiers; 602 624 dst = src; 603 625 src = nullptr; 604 626 break; 605 627 case TypeData::Basic: 606 628 dst->qualifiers |= src->qualifiers; 607 629 if ( src->kind != TypeData::Unknown ) { … … 631 653 } // if 632 654 break; 633 655 default: 634 656 switch ( src->kind ) { 635 636 657 case TypeData::Aggregate: 658 case TypeData::Enum: 637 659 dst->base = new TypeData( TypeData::AggregateInst ); 638 660 dst->base->aggInst.aggregate = src; … … 643 665 src = nullptr; 644 666 break; 645 667 default: 646 668 if ( dst->forall ) { 647 669 dst->forall->appendList( src->forall ); … … 714 736 715 737 DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) { 716 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {717 718 719 720 721 722 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 } // if 744 return this; 723 745 } // if 724 746 725 747 assert( type ); 726 748 switch ( type->kind ) { 727 749 case TypeData::Symbolic: 728 750 if ( type->symbolic.assertions ) { 729 751 type->symbolic.assertions->appendList( assertions ); … … 732 754 } // if 733 755 break; 734 756 default: 735 757 assert( false ); 736 758 } // switch … … 796 818 DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) { 797 819 if ( a ) { 798 for ( Attribute *attr: reverseIterate( a->attributes ) ) { 799 attributes.push_front( attr ); 800 } // for 820 spliceBegin( attributes, a->attributes ); 801 821 a->attributes.clear(); 802 822 } // if … … 831 851 if ( type ) { 832 852 switch ( type->kind ) { 833 834 853 case TypeData::Aggregate: 854 case TypeData::Enum: 835 855 p->type->base = new TypeData( TypeData::AggregateInst ); 836 856 p->type->base->aggInst.aggregate = type; … … 841 861 break; 842 862 843 863 default: 844 864 p->type->base = type; 845 865 } // switch … … 863 883 864 884 DeclarationNode * DeclarationNode::addNewArray( DeclarationNode * a ) { 865 885 if ( ! a ) return this; 866 886 assert( a->type->kind == TypeData::Array ); 867 887 TypeData * lastArray = findLast( a->type ); 868 888 if ( type ) { 869 889 switch ( type->kind ) { 870 871 890 case TypeData::Aggregate: 891 case TypeData::Enum: 872 892 lastArray->base = new TypeData( TypeData::AggregateInst ); 873 893 lastArray->base->aggInst.aggregate = type; … … 877 897 lastArray->base->qualifiers |= type->qualifiers; 878 898 break; 879 899 default: 880 900 lastArray->base = type; 881 901 } // switch … … 919 939 920 940 DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) { 921 assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );941 assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." ); 922 942 variable.initializer = init; 923 943 return this; … … 983 1003 } 984 1004 985 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 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 ) { 986 1089 SemanticErrorException errors; 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()) ) {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 ) ) { 990 1093 try { 991 bool extracted = false; 992 bool anon = false; 1094 bool extracted_named = false; 1095 ast::UnionDecl * unionDecl = nullptr; 1096 993 1097 if ( DeclarationNode * extr = cur->extractAggregate() ) { 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; 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; 1000 1106 1001 1107 // need to remember the cases where a declaration contains an anonymous aggregate definition 1002 extracted = true;1003 1108 assert( extr->type ); 1004 1109 if ( extr->type->kind == TypeData::Aggregate ) { 1005 anon = extr->type->aggregate.anon; 1110 // typedef struct { int A } B is the only case? 1111 extracted_named = !extr->type->aggregate.anon; 1006 1112 } else if ( extr->type->kind == TypeData::Enum ) { 1007 // xxx - is it useful to have an implicit anonymous enum member? 1008 anon = extr->type->enumeration.anon; 1113 // typedef enum { A } B is the only case? 1114 extracted_named = !extr->type->enumeration.anon; 1115 } else { 1116 extracted_named = true; 1009 1117 } 1010 1118 } // if … … 1012 1120 } // if 1013 1121 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; 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 } 1038 1142 } // if 1143 *out++ = decl; 1039 1144 } // if 1040 } catch ( SemanticErrorException & e ) {1145 } catch ( SemanticErrorException & e ) { 1041 1146 errors.append( e ); 1042 1147 } // try … … 1049 1154 1050 1155 // currently only builds assertions, function parameters, and return values 1051 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType *> & outputList ) {1156 void buildList( DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) { 1052 1157 SemanticErrorException errors; 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()) ) {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 ) ) { 1056 1161 try { 1057 Declaration* decl = cur->build();1058 assert ( decl);1059 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {1162 ast::Decl * decl = cur->build(); 1163 assertf( decl, "buildList: build for ast::DeclWithType." ); 1164 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1060 1165 dwt->location = cur->location; 1061 1166 *out++ = dwt; 1062 } else if ( StructDecl * agg = dynamic_cast< StructDecl *>( decl ) ) {1167 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) { 1063 1168 // e.g., int foo(struct S) {} 1064 StructInstType * inst = new StructInstType( Type::Qualifiers(),agg->name );1065 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr);1066 obj->l ocation = cur->location;1169 auto inst = new ast::StructInstType( agg->name ); 1170 auto obj = new ast::ObjectDecl( cur->location, "", inst ); 1171 obj->linkage = linkage; 1067 1172 *out++ = obj; 1068 1173 delete agg; 1069 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl *>( decl ) ) {1174 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) { 1070 1175 // e.g., int foo(union U) {} 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; 1176 auto inst = new ast::UnionInstType( agg->name ); 1177 auto obj = new ast::ObjectDecl( cur->location, 1178 "", inst, nullptr, ast::Storage::Classes(), 1179 linkage ); 1074 1180 *out++ = obj; 1075 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl *>( decl ) ) {1181 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) { 1076 1182 // e.g., int foo(enum E) {} 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; 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 ); 1080 1191 *out++ = obj; 1192 } else { 1193 assertf( false, "buildList: Could not convert to ast::DeclWithType." ); 1081 1194 } // if 1082 } catch ( SemanticErrorException & e ) {1195 } catch ( SemanticErrorException & e ) { 1083 1196 errors.append( e ); 1084 1197 } // try … … 1090 1203 } // buildList 1091 1204 1092 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1205 void buildTypeList( const DeclarationNode * firstNode, 1206 std::vector<ast::ptr<ast::Type>> & outputList ) { 1093 1207 SemanticErrorException errors; 1094 std::back_insert_iterator< std::list< Type * > > out( outputList ); 1095 const DeclarationNode * cur = firstNode; 1096 1097 while ( cur ) { 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 ) ) { 1098 1211 try { 1099 1212 * out++ = cur->buildType(); 1100 } catch ( SemanticErrorException & e ) {1213 } catch ( SemanticErrorException & e ) { 1101 1214 errors.append( e ); 1102 1215 } // try 1103 cur = dynamic_cast< DeclarationNode * >( cur->get_next() ); 1104 } // while 1216 } // for 1105 1217 1106 1218 if ( ! errors.isEmpty() ) { … … 1109 1221 } // buildTypeList 1110 1222 1111 Declaration* DeclarationNode::build() const {1223 ast::Decl * DeclarationNode::build() const { 1112 1224 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1113 1225 1114 1226 if ( asmStmt ) { 1115 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) ); 1227 auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() ); 1228 return new ast::AsmDecl( stmt->location, stmt ); 1116 1229 } // if 1117 1230 if ( directiveStmt ) { 1118 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) ); 1119 } // if 1120 1121 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { 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 ) { 1122 1236 // otype is internally converted to dtype + otype parameters 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." );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." ); 1125 1239 assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." ); 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() ); 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 ); 1128 1249 return ret; 1129 1250 } // if … … 1147 1268 } // if 1148 1269 bool isDelete = initializer && initializer->get_isDelete(); 1149 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild< Expression >( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild< Initializer >(initializer), attributes )->set_extension( extension ); 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 ); 1150 1281 if ( isDelete ) { 1151 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );1282 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl ); 1152 1283 dwt->isDeleted = true; 1153 1284 } … … 1156 1287 1157 1288 if ( assert.condition ) { 1158 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 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 ); 1159 1292 } 1160 1293 … … 1167 1300 } // if 1168 1301 if ( enumInLine ) { 1169 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1302 return new ast::InlineMemberDecl( location, 1303 *name, (ast::Type*)nullptr, storageClasses, linkage ); 1170 1304 } // if 1171 1305 assertf( name, "ObjectDecl must a have name\n" ); 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 { 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 { 1176 1320 assert( type ); 1177 1321 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 } // if1183 1184 1322 switch ( type->kind ) { 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 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; 1199 1344 return simpletypes; 1200 1345 } // switch
Note:
See TracChangeset
for help on using the changeset viewer.