- Timestamp:
- Apr 28, 2021, 4:56:50 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 8d66610
- Parents:
- feacef9 (diff), b7fd2db6 (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. - Location:
- src
- Files:
-
- 35 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rfeacef9 r5407cdc 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu May 09 15::37::05 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Nov 12 10:07:00 202013 // Update Count : 3 411 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:43:51 2021 13 // Update Count : 36 14 14 // 15 15 … … 327 327 const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final { 328 328 auto decl = new AsmDecl( get<AsmStmt>().accept1( node->stmt ) ); 329 declPostamble( decl, node ); 330 return nullptr; 331 } 332 333 const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final { 334 auto decl = new DirectiveDecl( get<DirectiveStmt>().accept1( node->stmt ) ); 329 335 declPostamble( decl, node ); 330 336 return nullptr; … … 1769 1775 } 1770 1776 1777 virtual void visit( const DirectiveDecl * old ) override final { 1778 auto decl = new ast::DirectiveDecl{ 1779 old->location, 1780 GET_ACCEPT_1(stmt, DirectiveStmt) 1781 }; 1782 decl->extension = old->extension; 1783 decl->uniqueId = old->uniqueId; 1784 decl->storage = { old->storageClasses.val }; 1785 1786 this->node = decl; 1787 } 1788 1771 1789 virtual void visit( const StaticAssertDecl * old ) override final { 1772 1790 auto decl = new ast::StaticAssertDecl{ -
src/AST/Decl.hpp
rfeacef9 r5407cdc 10 10 // Created On : Thu May 9 10:00:00 2019 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 11 20:48:38202113 // Update Count : 3 012 // Last Modified On : Fri Mar 12 18:25:05 2021 13 // Update Count : 32 14 14 // 15 15 … … 365 365 }; 366 366 367 /// C-preprocessor directive `#...` 368 class DirectiveDecl : public Decl { 369 public: 370 ptr<DirectiveStmt> stmt; 371 372 DirectiveDecl( const CodeLocation & loc, DirectiveStmt * stmt ) 373 : Decl( loc, "", {}, {} ), stmt(stmt) {} 374 375 const DirectiveDecl * accept( Visitor & v ) const override { return v.visit( this ); } 376 private: 377 DirectiveDecl * clone() const override { return new DirectiveDecl( *this ); } 378 MUTATE_FRIEND 379 }; 380 367 381 class StaticAssertDecl : public Decl { 368 382 public: -
src/AST/Expr.cpp
rfeacef9 r5407cdc 260 260 } 261 261 262 ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & str ) { 263 const Type * charType = new BasicType( BasicType::Char ); 264 // Adjust the length of the string for the terminator. 265 const Expr * strSize = from_ulong( loc, str.size() + 1 ); 266 const Type * strType = new ArrayType( charType, strSize, FixedLen, StaticDim ); 267 const std::string strValue = "\"" + str + "\""; 268 return new ConstantExpr( loc, strType, strValue, std::nullopt ); 269 } 270 262 271 ConstantExpr * ConstantExpr::null( const CodeLocation & loc, const Type * ptrType ) { 263 272 return new ConstantExpr{ -
src/AST/Expr.hpp
rfeacef9 r5407cdc 438 438 long long int intValue() const; 439 439 440 /// generates a boolean constant of the given bool440 /// Generates a boolean constant of the given bool. 441 441 static ConstantExpr * from_bool( const CodeLocation & loc, bool b ); 442 /// generates an integer constant of the given int442 /// Generates an integer constant of the given int. 443 443 static ConstantExpr * from_int( const CodeLocation & loc, int i ); 444 /// generates an integer constant of the given unsigned long int444 /// Generates an integer constant of the given unsigned long int. 445 445 static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i ); 446 /// generates a null pointer value for the given type. void * if omitted. 446 /// Generates a string constant from the given string (char type, unquoted string). 447 static ConstantExpr * from_string( const CodeLocation & loc, const std::string & string ); 448 /// Generates a null pointer value for the given type. void * if omitted. 447 449 static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr ); 448 450 -
src/AST/Fwd.hpp
rfeacef9 r5407cdc 9 9 // Author : Andrew Beach 10 10 // Created On : Wed May 8 16:05:00 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr Jul 23 14:15:00 202013 // Update Count : 211 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:37:39 2021 13 // Update Count : 4 14 14 // 15 15 … … 35 35 class TypedefDecl; 36 36 class AsmDecl; 37 class DirectiveDecl; 37 38 class StaticAssertDecl; 38 39 -
src/AST/Node.cpp
rfeacef9 r5407cdc 9 9 // Author : Thierry Delisle 10 10 // Created On : Thu May 16 14:16:00 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Fri Jun 5 10:21:00 202013 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:25:06 2021 13 // Update Count : 2 14 14 // 15 15 … … 130 130 template class ast::ptr_base< ast::AsmDecl, ast::Node::ref_type::weak >; 131 131 template class ast::ptr_base< ast::AsmDecl, ast::Node::ref_type::strong >; 132 template class ast::ptr_base< ast::DirectiveDecl, ast::Node::ref_type::weak >; 133 template class ast::ptr_base< ast::DirectiveDecl, ast::Node::ref_type::strong >; 132 134 template class ast::ptr_base< ast::StaticAssertDecl, ast::Node::ref_type::weak >; 133 135 template class ast::ptr_base< ast::StaticAssertDecl, ast::Node::ref_type::strong >; -
src/AST/Pass.hpp
rfeacef9 r5407cdc 139 139 const ast::Decl * visit( const ast::TypedefDecl * ) override final; 140 140 const ast::AsmDecl * visit( const ast::AsmDecl * ) override final; 141 const ast::DirectiveDecl * visit( const ast::DirectiveDecl * ) override final; 141 142 const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * ) override final; 142 143 const ast::CompoundStmt * visit( const ast::CompoundStmt * ) override final; -
src/AST/Pass.impl.hpp
rfeacef9 r5407cdc 646 646 647 647 //-------------------------------------------------------------------------- 648 // DirectiveDecl 649 template< typename core_t > 650 const ast::DirectiveDecl * ast::Pass< core_t >::visit( const ast::DirectiveDecl * node ) { 651 VISIT_START( node ); 652 653 VISIT( 654 maybe_accept( node, &DirectiveDecl::stmt ); 655 ) 656 657 VISIT_END( DirectiveDecl, node ); 658 } 659 660 //-------------------------------------------------------------------------- 648 661 // StaticAssertDecl 649 662 template< typename core_t > -
src/AST/Print.cpp
rfeacef9 r5407cdc 387 387 388 388 virtual const ast::AsmDecl * visit( const ast::AsmDecl * node ) override final { 389 safe_print( node->stmt ); 390 return node; 391 } 392 393 virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * node ) override final { 389 394 safe_print( node->stmt ); 390 395 return node; -
src/AST/Type.cpp
rfeacef9 r5407cdc 105 105 } 106 106 107 // --- BaseInstType 108 107 109 std::vector<readonly<Decl>> BaseInstType::lookup( const std::string& name ) const { 108 110 assertf( aggr(), "Must have aggregate to perform lookup" ); … … 119 121 template<typename decl_t> 120 122 SueInstType<decl_t>::SueInstType( 121 const decl_t* b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as )122 : BaseInstType( b->name, q, move(as) ), base( b ) {}123 const base_type * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 124 : BaseInstType( b->name, q, std::move(as) ), base( b ) {} 123 125 124 126 template<typename decl_t> … … 142 144 const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 143 145 : BaseInstType( b->name, q, move(as) ), base( b ) {} 146 147 // --- TypeInstType 144 148 145 149 void TypeInstType::set_base( const TypeDecl * b ) { -
src/AST/Visitor.hpp
rfeacef9 r5407cdc 9 9 // Author : Andrew Beach 10 10 // Created On : Thr May 9 15:28:00 2019 11 // Last Modified By : Andrew Beach12 // Last Modified On : Thr May 9 15:33:00 201913 // Update Count : 011 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:25:07 2021 13 // Update Count : 1 14 14 // 15 15 … … 31 31 virtual const ast::Decl * visit( const ast::TypedefDecl * ) = 0; 32 32 virtual const ast::AsmDecl * visit( const ast::AsmDecl * ) = 0; 33 virtual const ast::DirectiveDecl * visit( const ast::DirectiveDecl * ) = 0; 33 34 virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl * ) = 0; 34 35 virtual const ast::CompoundStmt * visit( const ast::CompoundStmt * ) = 0; -
src/CodeGen/CodeGenerator.cc
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Feb 16 08:32:48 202013 // Update Count : 53 212 // Last Modified On : Fri Mar 12 19:00:42 2021 13 // Update Count : 536 14 14 // 15 15 #include "CodeGenerator.h" … … 935 935 if ( asmStmt->get_instruction() ) asmStmt->get_instruction()->accept( *visitor ); 936 936 output << " )"; 937 } 938 939 void CodeGenerator::postvisit( DirectiveDecl * directiveDecl ) { 940 output << endl << directiveDecl->get_stmt()->directive; // endl prevents spaces before directive 937 941 } 938 942 -
src/CodeGen/CodeGenerator.h
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Feb 16 03:58:31 202013 // Update Count : 6 212 // Last Modified On : Fri Mar 12 18:35:38 2021 13 // Update Count : 63 14 14 // 15 15 … … 105 105 void postvisit( DirectiveStmt * ); 106 106 void postvisit( AsmDecl * ); // special: statement in declaration context 107 void postvisit( DirectiveDecl * ); // special: statement in declaration context 107 108 void postvisit( IfStmt * ); 108 109 void postvisit( SwitchStmt * ); -
src/Common/CodeLocationTools.cpp
rfeacef9 r5407cdc 9 9 // Author : Andrew Beach 10 10 // Created On : Fri Dec 4 15:42:00 2020 11 // Last Modified By : Andrew Beach12 // Last Modified On : Wed Dec 9 9:42:00 202013 // Update Count : 111 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 12 18:35:37 2021 13 // Update Count : 2 14 14 // 15 15 … … 102 102 macro(TypedefDecl, Decl) \ 103 103 macro(AsmDecl, AsmDecl) \ 104 macro(DirectiveDecl, DirectiveDecl) \ 104 105 macro(StaticAssertDecl, StaticAssertDecl) \ 105 106 macro(CompoundStmt, CompoundStmt) \ -
src/Common/PassVisitor.h
rfeacef9 r5407cdc 77 77 virtual void visit( AsmDecl * asmDecl ) override final; 78 78 virtual void visit( const AsmDecl * asmDecl ) override final; 79 virtual void visit( DirectiveDecl * directiveDecl ) override final; 80 virtual void visit( const DirectiveDecl * directiveDecl ) override final; 79 81 virtual void visit( StaticAssertDecl * assertDecl ) override final; 80 82 virtual void visit( const StaticAssertDecl * assertDecl ) override final; … … 261 263 virtual Declaration * mutate( TypedefDecl * typeDecl ) override final; 262 264 virtual AsmDecl * mutate( AsmDecl * asmDecl ) override final; 265 virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) override final; 263 266 virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final; 264 267 -
src/Common/PassVisitor.impl.h
rfeacef9 r5407cdc 973 973 974 974 //-------------------------------------------------------------------------- 975 // DirectiveDecl 976 template< typename pass_type > 977 void PassVisitor< pass_type >::visit( DirectiveDecl * node ) { 978 VISIT_START( node ); 979 980 maybeAccept_impl( node->stmt, *this ); 981 982 VISIT_END( node ); 983 } 984 985 template< typename pass_type > 986 void PassVisitor< pass_type >::visit( const DirectiveDecl * node ) { 987 VISIT_START( node ); 988 989 maybeAccept_impl( node->stmt, *this ); 990 991 VISIT_END( node ); 992 } 993 994 template< typename pass_type > 995 DirectiveDecl * PassVisitor< pass_type >::mutate( DirectiveDecl * node ) { 996 MUTATE_START( node ); 997 998 maybeMutate_impl( node->stmt, *this ); 999 1000 MUTATE_END( DirectiveDecl, node ); 1001 } 1002 1003 //-------------------------------------------------------------------------- 975 1004 // StaticAssertDecl 976 1005 template< typename pass_type > -
src/Concurrency/Keywords.cc
rfeacef9 r5407cdc 42 42 43 43 namespace Concurrency { 44 inline static std::string getTypeIdName( std::string const & exception_name ) { 45 return exception_name.empty() ? std::string() : Virtual::typeIdType( exception_name ); 46 } 44 47 inline static std::string getVTableName( std::string const & exception_name ) { 45 return exception_name.empty() ? std::string() : Virtual::vtableTypeName( exception_name);48 return exception_name.empty() ? std::string() : Virtual::vtableTypeName( exception_name ); 46 49 } 47 50 … … 75 78 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), 76 79 context_error( context_error ), exception_name( exception_name ), 80 typeid_name( getTypeIdName( exception_name ) ), 77 81 vtable_name( getVTableName( exception_name ) ), 78 82 needs_main( needs_main ), cast_target( cast_target ) {} … … 84 88 85 89 void handle( StructDecl * ); 90 void addTypeId( StructDecl * ); 86 91 void addVtableForward( StructDecl * ); 87 92 FunctionDecl * forwardDeclare( StructDecl * ); … … 99 104 const std::string context_error; 100 105 const std::string exception_name; 106 const std::string typeid_name; 101 107 const std::string vtable_name; 102 108 bool needs_main; … … 106 112 FunctionDecl * dtor_decl = nullptr; 107 113 StructDecl * except_decl = nullptr; 114 StructDecl * typeid_decl = nullptr; 108 115 StructDecl * vtable_decl = nullptr; 109 116 }; … … 393 400 except_decl = decl; 394 401 } 402 else if ( !typeid_decl && typeid_name == decl->name && decl->body ) { 403 typeid_decl = decl; 404 } 395 405 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) { 396 406 vtable_decl = decl; … … 404 414 if ( type_decl && isDestructorFor( decl, type_decl ) ) 405 415 dtor_decl = decl; 406 else if ( vtable_name.empty() ) 407 ; 408 else if( !decl->has_body() ) 416 else if ( vtable_name.empty() || !decl->has_body() ) 409 417 ; 410 418 else if ( auto param = isMainFor( decl, cast_target ) ) { … … 418 426 std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) }; 419 427 ObjectDecl * vtable_object = Virtual::makeVtableInstance( 428 "_default_vtable_object_declaration", 420 429 vtable_decl->makeInst( poly_args ), struct_type, nullptr ); 421 430 declsToAddAfter.push_back( vtable_object ); 431 declsToAddAfter.push_back( 432 new ObjectDecl( 433 Virtual::concurrentDefaultVTableName(), 434 Type::Const, 435 LinkageSpec::Cforall, 436 /* bitfieldWidth */ nullptr, 437 new ReferenceType( Type::Const, vtable_object->type->clone() ), 438 new SingleInit( new VariableExpr( vtable_object ) ) 439 ) 440 ); 422 441 declsToAddAfter.push_back( Virtual::makeGetExceptionFunction( 423 442 vtable_object, except_decl->makeInst( std::move( poly_args ) ) … … 448 467 if( !dtor_decl ) SemanticError( decl, context_error ); 449 468 450 addVtableForward( decl ); 469 if ( !exception_name.empty() ) { 470 if( !typeid_decl ) SemanticError( decl, context_error ); 471 if( !vtable_decl ) SemanticError( decl, context_error ); 472 473 addTypeId( decl ); 474 addVtableForward( decl ); 475 } 451 476 FunctionDecl * func = forwardDeclare( decl ); 452 477 ObjectDecl * field = addField( decl ); … … 454 479 } 455 480 481 void ConcurrentSueKeyword::addTypeId( StructDecl * decl ) { 482 assert( typeid_decl ); 483 StructInstType typeid_type( Type::Const, typeid_decl ); 484 typeid_type.parameters.push_back( new TypeExpr( 485 new StructInstType( noQualifiers, decl ) 486 ) ); 487 declsToAddBefore.push_back( Virtual::makeTypeIdInstance( &typeid_type ) ); 488 } 489 456 490 void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) { 457 if ( vtable_decl ) { 458 std::list< Expression * > poly_args = { 459 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 460 }; 461 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 462 vtable_decl->makeInst( poly_args ), 463 except_decl->makeInst( poly_args ) 464 ) ); 465 declsToAddBefore.push_back( Virtual::makeVtableForward( 466 vtable_decl->makeInst( move( poly_args ) ) ) ); 467 // Its only an error if we want a vtable and don't have one. 468 } else if ( ! vtable_name.empty() ) { 469 SemanticError( decl, context_error ); 470 } 491 assert( vtable_decl ); 492 std::list< Expression * > poly_args = { 493 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 494 }; 495 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 496 vtable_decl->makeInst( poly_args ), 497 except_decl->makeInst( poly_args ) 498 ) ); 499 ObjectDecl * vtable_object = Virtual::makeVtableForward( 500 "_default_vtable_object_declaration", 501 vtable_decl->makeInst( move( poly_args ) ) ); 502 declsToAddBefore.push_back( vtable_object ); 503 declsToAddBefore.push_back( 504 new ObjectDecl( 505 Virtual::concurrentDefaultVTableName(), 506 Type::Const, 507 LinkageSpec::Cforall, 508 /* bitfieldWidth */ nullptr, 509 new ReferenceType( Type::Const, vtable_object->type->clone() ), 510 /* init */ nullptr 511 ) 512 ); 471 513 } 472 514 -
src/Parser/DeclarationNode.cc
rfeacef9 r5407cdc 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 11 20:58:07202113 // Update Count : 11 3712 // Last Modified On : Tue Mar 23 08:44:08 2021 13 // Update Count : 1149 14 14 // 15 15 … … 167 167 } 168 168 169 DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) {170 DeclarationNode * newnode = new DeclarationNode;171 newnode->name = name;172 newnode->type = new TypeData( TypeData::Function );173 newnode->type->function.params = param;174 newnode->type->function.body = body;175 176 if ( ret ) {177 newnode->type->base = ret->type;178 ret->type = nullptr;179 delete ret;180 } // if181 182 return newnode;183 } // DeclarationNode::newFunction184 185 186 169 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) { 187 170 DeclarationNode * newnode = new DeclarationNode; … … 237 220 return newnode; 238 221 } // DeclarationNode::newForall 239 240 DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) {241 DeclarationNode * newnode = new DeclarationNode;242 newnode->type = new TypeData( TypeData::SymbolicInst );243 newnode->type->symbolic.name = name;244 newnode->type->symbolic.isTypedef = true;245 newnode->type->symbolic.params = nullptr;246 return newnode;247 } // DeclarationNode::newFromTypedef248 222 249 223 DeclarationNode * DeclarationNode::newFromGlobalScope() { … … 289 263 } // DeclarationNode::newEnum 290 264 265 DeclarationNode * DeclarationNode::newName( const string * name ) { 266 DeclarationNode * newnode = new DeclarationNode; 267 assert( ! newnode->name ); 268 newnode->name = name; 269 return newnode; 270 } // DeclarationNode::newName 271 291 272 DeclarationNode * DeclarationNode::newEnumConstant( const string * name, ExpressionNode * constant ) { 292 DeclarationNode * newnode = new DeclarationNode; 293 newnode->name = name; 273 DeclarationNode * newnode = newName( name ); 294 274 newnode->enumeratorValue.reset( constant ); 295 275 return newnode; 296 276 } // DeclarationNode::newEnumConstant 297 277 298 DeclarationNode * DeclarationNode::newName( const string * name ) { 299 DeclarationNode * newnode = new DeclarationNode; 300 newnode->name = name; 301 return newnode; 302 } // DeclarationNode::newName 278 DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) { 279 DeclarationNode * newnode = new DeclarationNode; 280 newnode->type = new TypeData( TypeData::SymbolicInst ); 281 newnode->type->symbolic.name = name; 282 newnode->type->symbolic.isTypedef = true; 283 newnode->type->symbolic.params = nullptr; 284 return newnode; 285 } // DeclarationNode::newFromTypedef 303 286 304 287 DeclarationNode * DeclarationNode::newFromTypeGen( const string * name, ExpressionNode * params ) { … … 312 295 313 296 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) { 314 DeclarationNode * newnode = new DeclarationNode;297 DeclarationNode * newnode = newName( name ); 315 298 newnode->type = nullptr; 316 assert( ! newnode->name );317 // newnode->variable.name = name;318 newnode->name = name;319 299 newnode->variable.tyClass = tc; 320 300 newnode->variable.assertions = nullptr; … … 343 323 344 324 DeclarationNode * DeclarationNode::newTypeDecl( const string * name, DeclarationNode * typeParams ) { 345 DeclarationNode * newnode = new DeclarationNode; 346 newnode->name = name; 325 DeclarationNode * newnode = newName( name ); 347 326 newnode->type = new TypeData( TypeData::Symbolic ); 348 327 newnode->type->symbolic.isTypedef = false; … … 417 396 } // DeclarationNode::newBuiltinType 418 397 398 DeclarationNode * DeclarationNode::newFunction( const string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body ) { 399 DeclarationNode * newnode = newName( name ); 400 newnode->type = new TypeData( TypeData::Function ); 401 newnode->type->function.params = param; 402 newnode->type->function.body = body; 403 404 if ( ret ) { 405 newnode->type->base = ret->type; 406 ret->type = nullptr; 407 delete ret; 408 } // if 409 410 return newnode; 411 } // DeclarationNode::newFunction 412 419 413 DeclarationNode * DeclarationNode::newAttribute( const string * name, ExpressionNode * expr ) { 420 414 DeclarationNode * newnode = new DeclarationNode; … … 424 418 newnode->attributes.push_back( new Attribute( *name, exprs ) ); 425 419 delete name; 420 return newnode; 421 } 422 423 DeclarationNode * DeclarationNode::newDirectiveStmt( StatementNode * stmt ) { 424 DeclarationNode * newnode = new DeclarationNode; 425 newnode->directiveStmt = stmt; 426 426 return newnode; 427 427 } … … 879 879 } 880 880 881 DeclarationNode * DeclarationNode::cloneType( string * n ewName ) {882 DeclarationNode * newnode = new DeclarationNode;881 DeclarationNode * DeclarationNode::cloneType( string * name ) { 882 DeclarationNode * newnode = newName( name ); 883 883 newnode->type = maybeClone( type ); 884 884 newnode->copySpecifiers( this ); 885 assert( newName );886 newnode->name = newName;887 885 return newnode; 888 886 } … … 1072 1070 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) ); 1073 1071 } // if 1072 if ( directiveStmt ) { 1073 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) ); 1074 } // if 1074 1075 1075 1076 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) { -
src/Parser/ParseNode.h
rfeacef9 r5407cdc 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Jan 3 18:23:01202113 // Update Count : 89 612 // Last Modified On : Fri Mar 12 15:19:04 2021 13 // Update Count : 897 14 14 // 15 15 … … 249 249 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false ); 250 250 static DeclarationNode * newAttribute( const std::string *, ExpressionNode * expr = nullptr ); // gcc attributes 251 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement 251 252 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement 252 253 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message ); … … 345 346 std::string error; 346 347 StatementNode * asmStmt = nullptr; 348 StatementNode * directiveStmt = nullptr; 347 349 348 350 static UniqueName anonymous; -
src/Parser/TypeData.h
rfeacef9 r5407cdc 7 7 // TypeData.h -- 8 8 // 9 // Author : Rodolfo G. Esteves9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Dec 13 23:42:35 201913 // Update Count : 19912 // Last Modified On : Sat Mar 27 09:05:35 2021 13 // Update Count : 200 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <iosfwd> 19 #include <list> 20 #include <string> 18 #include <iosfwd> // for ostream 19 #include <list> // for list 20 #include <string> // for string 21 21 22 #include "ParseNode.h" 23 #include "SynTree/LinkageSpec.h" 24 #include "SynTree/Type.h" 25 #include "SynTree/SynTree.h" 22 #include "ParseNode.h" // for DeclarationNode, DeclarationNode::Ag... 23 #include "SynTree/LinkageSpec.h" // for Spec 24 #include "SynTree/Type.h" // for Type, ReferenceToType (ptr only) 25 #include "SynTree/SynTree.h" // for Visitor Nodes 26 26 27 27 struct TypeData { … … 33 33 const std::string * name = nullptr; 34 34 DeclarationNode * params = nullptr; 35 ExpressionNode * actuals = nullptr; 35 ExpressionNode * actuals = nullptr; // holds actual parameters later applied to AggInst 36 36 DeclarationNode * fields = nullptr; 37 37 bool body; … … 62 62 63 63 struct Function_t { 64 mutable DeclarationNode * params = nullptr; 65 mutable DeclarationNode * idList = nullptr; 64 mutable DeclarationNode * params = nullptr; // mutables modified in buildKRFunction 65 mutable DeclarationNode * idList = nullptr; // old-style 66 66 mutable DeclarationNode * oldDeclList = nullptr; 67 67 StatementNode * body = nullptr; 68 ExpressionNode * withExprs = nullptr; 68 ExpressionNode * withExprs = nullptr; // expressions from function's with_clause 69 69 }; 70 70 -
src/Parser/TypedefTable.cc
rfeacef9 r5407cdc 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 15 08:06:36 202013 // Update Count : 2 5912 // Last Modified On : Mon Mar 15 20:56:47 2021 13 // Update Count : 260 14 14 // 15 15 … … 89 89 debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl ); 90 90 auto ret = kindTable.insertAt( scope, identifier, kind ); 91 if ( ! ret.second ) ret.first->second = kind; // exists => update91 if ( ! ret.second ) ret.first->second = kind; // exists => update 92 92 } // TypedefTable::addToEnclosingScope 93 93 -
src/Parser/lex.ll
rfeacef9 r5407cdc 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : T ue Oct 6 18:15:41 202013 * Update Count : 7 4312 * Last Modified On : Thu Apr 1 13:22:31 2021 13 * Update Count : 754 14 14 */ 15 15 … … 221 221 break { KEYWORD_RETURN(BREAK); } 222 222 case { KEYWORD_RETURN(CASE); } 223 catch { KEYWORD_RETURN(CATCH); } // CFA224 catchResume { KEYWORD_RETURN(CATCHRESUME); } // CFA223 catch { QKEYWORD_RETURN(CATCH); } // CFA 224 catchResume { QKEYWORD_RETURN(CATCHRESUME); } // CFA 225 225 char { KEYWORD_RETURN(CHAR); } 226 226 choose { KEYWORD_RETURN(CHOOSE); } // CFA … … 247 247 fallthrough { KEYWORD_RETURN(FALLTHROUGH); } // CFA 248 248 fallthru { KEYWORD_RETURN(FALLTHRU); } // CFA 249 finally { KEYWORD_RETURN(FINALLY); } // CFA 249 finally { QKEYWORD_RETURN(FINALLY); } // CFA 250 fixup { QKEYWORD_RETURN(FIXUP); } // CFA 250 251 float { KEYWORD_RETURN(FLOAT); } 251 252 __float80 { KEYWORD_RETURN(uuFLOAT80); } // GCC … … 287 288 or { QKEYWORD_RETURN(WOR); } // CFA 288 289 otype { KEYWORD_RETURN(OTYPE); } // CFA 290 recover { QKEYWORD_RETURN(RECOVER); } // CFA 289 291 register { KEYWORD_RETURN(REGISTER); } 292 report { KEYWORD_RETURN(THROWRESUME); } // CFA 290 293 restrict { KEYWORD_RETURN(RESTRICT); } // C99 291 294 __restrict { KEYWORD_RETURN(RESTRICT); } // GCC … … 315 318 __typeof { KEYWORD_RETURN(TYPEOF); } // GCC 316 319 __typeof__ { KEYWORD_RETURN(TYPEOF); } // GCC 320 typeid { KEYWORD_RETURN(TYPEID); } // GCC 317 321 union { KEYWORD_RETURN(UNION); } 318 322 __uint128_t { KEYWORD_RETURN(UINT128); } // GCC … … 324 328 __volatile { KEYWORD_RETURN(VOLATILE); } // GCC 325 329 __volatile__ { KEYWORD_RETURN(VOLATILE); } // GCC 326 waitfor { KEYWORD_RETURN(WAITFOR); } 327 when { KEYWORD_RETURN(WHEN); } 330 vtable { KEYWORD_RETURN(VTABLE); } // CFA 331 waitfor { KEYWORD_RETURN(WAITFOR); } // CFA 332 when { KEYWORD_RETURN(WHEN); } // CFA 328 333 while { KEYWORD_RETURN(WHILE); } 329 334 with { KEYWORD_RETURN(WITH); } // CFA -
src/Parser/parser.yy
rfeacef9 r5407cdc 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 3 18:30:12202113 // Update Count : 4 70012 // Last Modified On : Mon Apr 26 18:41:54 2021 13 // Update Count : 4990 14 14 // 15 15 … … 32 32 // 33 33 // 1. designation with and without '=' (use ':' instead) 34 // 2. attributes not allowed in parenthesis of declarator 34 35 35 // 36 36 // All of the syntactic extensions for GCC C are marked with the comment "GCC". The second extensions are for Cforall … … 211 211 } // forCtrl 212 212 213 bool forall = false , yyy = false;// aggregate have one or more forall qualifiers ?213 bool forall = false; // aggregate have one or more forall qualifiers ? 214 214 215 215 // https://www.gnu.org/software/bison/manual/bison.html#Location-Type … … 264 264 %token RESTRICT // C99 265 265 %token ATOMIC // C11 266 %token FORALL MUTEX VIRTUAL COERCE// CFA266 %token FORALL MUTEX VIRTUAL VTABLE COERCE // CFA 267 267 %token VOID CHAR SHORT INT LONG FLOAT DOUBLE SIGNED UNSIGNED 268 268 %token BOOL COMPLEX IMAGINARY // C99 … … 270 270 %token uFLOAT16 uFLOAT32 uFLOAT32X uFLOAT64 uFLOAT64X uFLOAT128 // GCC 271 271 %token ZERO_T ONE_T // CFA 272 %token VALIST // GCC 273 %token AUTO_TYPE // GCC 274 %token TYPEOF BASETYPEOF LABEL // GCC 272 %token SIZEOF TYPEOF VALIST AUTO_TYPE // GCC 273 %token OFFSETOF BASETYPEOF TYPEID // CFA 275 274 %token ENUM STRUCT UNION 276 275 %token EXCEPTION // CFA 277 276 %token GENERATOR COROUTINE MONITOR THREAD // CFA 278 277 %token OTYPE FTYPE DTYPE TTYPE TRAIT // CFA 279 %token SIZEOF OFFSETOF280 278 // %token RESUME // CFA 279 %token LABEL // GCC 281 280 %token SUSPEND // CFA 282 281 %token ATTRIBUTE EXTENSION // GCC 283 282 %token IF ELSE SWITCH CASE DEFAULT DO WHILE FOR BREAK CONTINUE GOTO RETURN 284 %token CHOOSE DISABLE ENABLE FALLTHRU FALLTHROUGH TRY CATCH CATCHRESUME FINALLY THROW THROWRESUME AT WITH WHEN WAITFOR // CFA 283 %token CHOOSE FALLTHRU FALLTHROUGH WITH WHEN WAITFOR // CFA 284 %token DISABLE ENABLE TRY THROW THROWRESUME AT // CFA 285 285 %token ASM // C99, extension ISO/IEC 9899:1999 Section J.5.10(1) 286 286 %token ALIGNAS ALIGNOF GENERIC STATICASSERT // C11 287 287 288 288 // names and constants: lexer differentiates between identifier and typedef names 289 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDEFnameTYPEGENname290 %token<tok> TIMEOUT WOR291 %token<tok> INTEGERconstant CHARACTERconstantSTRINGliteral289 %token<tok> IDENTIFIER QUOTED_IDENTIFIER TYPEDEFname TYPEGENname 290 %token<tok> TIMEOUT WOR CATCH RECOVER CATCHRESUME FIXUP FINALLY // CFA 291 %token<tok> INTEGERconstant CHARACTERconstant STRINGliteral 292 292 %token<tok> DIRECTIVE 293 293 // Floating point constant is broken into three kinds of tokens because of the ambiguity with tuple indexing and … … 321 321 %type<en> constant 322 322 %type<en> tuple tuple_expression_list 323 %type<op> ptrref_operator unary_operator assignment_operator 323 %type<op> ptrref_operator unary_operator assignment_operator simple_assignment_operator compound_assignment_operator 324 324 %type<en> primary_expression postfix_expression unary_expression 325 325 %type<en> cast_expression_list cast_expression exponential_expression multiplicative_expression additive_expression … … 373 373 374 374 %type<decl> basic_declaration_specifier basic_type_name basic_type_specifier direct_type indirect_type 375 %type<decl> vtable vtable_opt default_opt 375 376 376 377 %type<decl> trait_declaration trait_declaration_list trait_declaring_list trait_specifier … … 428 429 429 430 %type<decl> type_declaration_specifier type_type_specifier type_name typegen_name 430 %type<decl> typedef typedef_declaration typedef_expression431 %type<decl> typedef_name typedef_declaration typedef_expression 431 432 432 433 %type<decl> variable_type_redeclarator type_ptr type_array type_function … … 440 441 441 442 %type<decl> type_qualifier type_qualifier_name forall type_qualifier_list_opt type_qualifier_list 442 %type<decl> type_specifier type_specifier_nobody enum_specifier_nobody443 %type<decl> type_specifier type_specifier_nobody 443 444 444 445 %type<decl> variable_declarator variable_ptr variable_array variable_function 445 446 %type<decl> variable_abstract_declarator variable_abstract_ptr variable_abstract_array variable_abstract_function 446 447 447 %type<decl> attribute_list_opt attribute_list attribute _opt attributeattribute_name_list attribute_name448 %type<decl> attribute_list_opt attribute_list attribute attribute_name_list attribute_name 448 449 449 450 // initializers … … 462 463 // Order of these lines matters (low-to-high precedence). THEN is left associative over WOR/TIMEOUT/ELSE, WOR is left 463 464 // associative over TIMEOUT/ELSE, and TIMEOUT is left associative over ELSE. 464 %precedence THEN // rule precedence for IF/WAITFOR statement 465 %precedence WOR // token precedence for start of WOR in WAITFOR statement 466 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement 467 %precedence ELSE // token precedence for start of else clause in IF/WAITFOR statement 465 %precedence THEN // rule precedence for IF/WAITFOR statement 466 %precedence WOR // token precedence for start of WOR in WAITFOR statement 467 %precedence TIMEOUT // token precedence for start of TIMEOUT in WAITFOR statement 468 %precedence CATCH // token precedence for start of TIMEOUT in WAITFOR statement 469 %precedence RECOVER // token precedence for start of TIMEOUT in WAITFOR statement 470 %precedence CATCHRESUME // token precedence for start of TIMEOUT in WAITFOR statement 471 %precedence FIXUP // token precedence for start of TIMEOUT in WAITFOR statement 472 %precedence FINALLY // token precedence for start of TIMEOUT in WAITFOR statement 473 %precedence ELSE // token precedence for start of else clause in IF/WAITFOR statement 474 468 475 469 476 // Handle shift/reduce conflict for generic type by shifting the '(' token. For example, this string is ambiguous: … … 544 551 TIMEOUT 545 552 | WOR 553 | CATCH 554 | RECOVER 555 | CATCHRESUME 556 | FIXUP 557 | FINALLY 546 558 ; 547 559 … … 774 786 | OFFSETOF '(' type_no_function ',' identifier ')' 775 787 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); } 788 | TYPEID '(' type_no_function ')' 789 { 790 SemanticError( yylloc, "typeid name is currently unimplemented." ); $$ = nullptr; 791 // $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); 792 } 776 793 ; 777 794 … … 795 812 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); } 796 813 | '(' aggregate_control '&' ')' cast_expression // CFA 814 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 815 | '(' aggregate_control '*' ')' cast_expression // CFA 797 816 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); } 798 817 | '(' VIRTUAL ')' cast_expression // CFA … … 939 958 940 959 assignment_operator: 960 simple_assignment_operator 961 | compound_assignment_operator 962 ; 963 964 simple_assignment_operator: 941 965 '=' { $$ = OperKinds::Assign; } 942 | ATassign { $$ = OperKinds::AtAssn; } 943 | EXPassign { $$ = OperKinds::ExpAssn; } 966 | ATassign { $$ = OperKinds::AtAssn; } // CFA 967 ; 968 969 compound_assignment_operator: 970 EXPassign { $$ = OperKinds::ExpAssn; } 944 971 | MULTassign { $$ = OperKinds::MulAssn; } 945 972 | DIVassign { $$ = OperKinds::DivAssn; } … … 1019 1046 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 1020 1047 | '{' push 1021 local_label_declaration_opt // GCC, local labels 1048 local_label_declaration_opt // GCC, local labels appear at start of block 1022 1049 statement_decl_list // C99, intermix declarations and statements 1023 1050 pop '}' … … 1217 1244 | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA 1218 1245 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1246 1247 | comma_expression ';' TYPEDEFname // CFA, array type 1248 { 1249 SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr; 1250 $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr ); 1251 } 1219 1252 1220 1253 // There is a S/R conflicit if ~ and -~ are factored out. … … 1366 1399 1367 1400 exception_statement: 1368 TRY compound_statement handler_clause 1401 TRY compound_statement handler_clause %prec THEN 1369 1402 { $$ = new StatementNode( build_try( $2, $3, 0 ) ); } 1370 1403 | TRY compound_statement finally_clause … … 1389 1422 handler_key: 1390 1423 CATCH { $$ = CatchStmt::Terminate; } 1424 | RECOVER { $$ = CatchStmt::Terminate; } 1391 1425 | CATCHRESUME { $$ = CatchStmt::Resume; } 1426 | FIXUP { $$ = CatchStmt::Resume; } 1392 1427 ; 1393 1428 … … 1741 1776 ; 1742 1777 1743 enum_specifier_nobody: // type specifier - {...}1744 // Preclude SUE declarations in restricted scopes (see type_specifier_nobody)1745 basic_type_specifier1746 | sue_type_specifier_nobody1747 ;1748 1749 1778 type_qualifier_list_opt: // GCC, used in asm_statement 1750 1779 // empty … … 1766 1795 type_qualifier: 1767 1796 type_qualifier_name 1768 | attribute 1797 | attribute // trick handles most atrribute locations 1769 1798 ; 1770 1799 … … 1874 1903 | AUTO_TYPE 1875 1904 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::AutoType ); } 1905 | vtable 1906 ; 1907 1908 vtable_opt: 1909 // empty 1910 { $$ = nullptr; } 1911 | vtable; 1912 ; 1913 1914 vtable: 1915 VTABLE '(' type_list ')' default_opt 1916 { SemanticError( yylloc, "vtable is currently unimplemented." ); $$ = nullptr; } 1917 ; 1918 1919 default_opt: 1920 // empty 1921 { $$ = nullptr; } 1922 | DEFAULT 1923 { SemanticError( yylloc, "vtable default is currently unimplemented." ); $$ = nullptr; } 1876 1924 ; 1877 1925 … … 2025 2073 '{' field_declaration_list_opt '}' type_parameters_opt 2026 2074 { $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); } 2027 | aggregate_key attribute_list_opt type_name 2028 { 2029 // for type_name can be a qualified type name S.T, in which case only the last name in the chain needs a typedef (other names in the chain should already have one) 2030 typedefTable.makeTypedef( *$3->type->leafName(), forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef 2075 | aggregate_key attribute_list_opt TYPEDEFname // unqualified type name 2076 { 2077 typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef 2031 2078 forall = false; // reset 2032 2079 } 2033 2080 '{' field_declaration_list_opt '}' type_parameters_opt 2034 { $$ = DeclarationNode::newAggregate( $1, $3->type->symbolic.name, $8, $6, true )->addQualifiers( $2 ); } 2081 { 2082 DeclarationNode::newFromTypedef( $3 ); 2083 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); 2084 } 2085 | aggregate_key attribute_list_opt TYPEGENname // unqualified type name 2086 { 2087 typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef 2088 forall = false; // reset 2089 } 2090 '{' field_declaration_list_opt '}' type_parameters_opt 2091 { 2092 DeclarationNode::newFromTypeGen( $3, nullptr ); 2093 $$ = DeclarationNode::newAggregate( $1, $3, $8, $6, true )->addQualifiers( $2 ); 2094 } 2035 2095 | aggregate_type_nobody 2036 2096 ; … … 2069 2129 2070 2130 aggregate_data: 2071 STRUCT 2072 { yyy = true;$$ = AggregateDecl::Struct; }2131 STRUCT vtable_opt 2132 { $$ = AggregateDecl::Struct; } 2073 2133 | UNION 2074 { yyy = true;$$ = AggregateDecl::Union; }2134 { $$ = AggregateDecl::Union; } 2075 2135 | EXCEPTION // CFA 2076 // { yyy = true;$$ = AggregateDecl::Exception; }2077 { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }2136 { $$ = AggregateDecl::Exception; } 2137 // { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2078 2138 ; 2079 2139 2080 2140 aggregate_control: // CFA 2081 2141 MONITOR 2082 { yyy = true;$$ = AggregateDecl::Monitor; }2142 { $$ = AggregateDecl::Monitor; } 2083 2143 | MUTEX STRUCT 2084 { yyy = true;$$ = AggregateDecl::Monitor; }2144 { $$ = AggregateDecl::Monitor; } 2085 2145 | GENERATOR 2086 { yyy = true;$$ = AggregateDecl::Generator; }2146 { $$ = AggregateDecl::Generator; } 2087 2147 | MUTEX GENERATOR 2088 2148 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2089 2149 | COROUTINE 2090 { yyy = true;$$ = AggregateDecl::Coroutine; }2150 { $$ = AggregateDecl::Coroutine; } 2091 2151 | MUTEX COROUTINE 2092 2152 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } 2093 2153 | THREAD 2094 { yyy = true;$$ = AggregateDecl::Thread; }2154 { $$ = AggregateDecl::Thread; } 2095 2155 | MUTEX THREAD 2096 2156 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; } … … 2188 2248 ; 2189 2249 2190 // Cannot use attribute_list_opt because of ambiguity with enum_specifier_nobody, which already parses attribute.2191 // Hence, only a single attribute is allowed after the "ENUM".2192 2250 enum_type: // enum 2193 ENUM attribute_ opt '{' enumerator_list comma_opt '}'2251 ENUM attribute_list_opt '{' enumerator_list comma_opt '}' 2194 2252 { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); } 2195 | ENUM attribute_ opt identifier2253 | ENUM attribute_list_opt identifier 2196 2254 { typedefTable.makeTypedef( *$3 ); } 2197 2255 '{' enumerator_list comma_opt '}' 2198 2256 { $$ = DeclarationNode::newEnum( $3, $6, true )->addQualifiers( $2 ); } 2199 | ENUM attribute_ opt typedef // enum cannot be generic2257 | ENUM attribute_list_opt typedef_name // unqualified type name 2200 2258 '{' enumerator_list comma_opt '}' 2201 2259 { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); } 2202 | ENUM enum_specifier_nobody '{' enumerator_list comma_opt '}' 2203 // { $$ = DeclarationNode::newEnum( nullptr, $4, true ); } 2204 { SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; } 2205 | ENUM enum_specifier_nobody declarator '{' enumerator_list comma_opt '}' 2206 // { 2207 // typedefTable.makeTypedef( *$3->name ); 2208 // $$ = DeclarationNode::newEnum( nullptr, $5, true ); 2209 // } 2210 { SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; } 2260 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}' 2261 { 2262 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2263 SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; 2264 } 2265 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt 2266 { 2267 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2268 typedefTable.makeTypedef( *$6 ); 2269 } 2270 '{' enumerator_list comma_opt '}' 2271 { 2272 SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; 2273 } 2274 | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt '{' enumerator_list comma_opt '}' 2275 { 2276 if ( $3->storageClasses.val != 0 || $3->type->qualifiers.val != 0 ) { SemanticError( yylloc, "storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." ); } 2277 typedefTable.makeTypedef( *$6->name ); 2278 SemanticError( yylloc, "Typed enumeration is currently unimplemented." ); $$ = nullptr; 2279 } 2211 2280 | enum_type_nobody 2212 2281 ; 2213 2282 2214 2283 enum_type_nobody: // enum - {...} 2215 ENUM attribute_opt identifier 2216 { 2217 typedefTable.makeTypedef( *$3 ); 2218 $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); 2219 } 2220 | ENUM attribute_opt type_name // enum cannot be generic 2221 { 2222 typedefTable.makeTypedef( *$3->type->symbolic.name ); 2223 $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); 2224 } 2284 ENUM attribute_list_opt identifier 2285 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, 0, false )->addQualifiers( $2 ); } 2286 | ENUM attribute_list_opt type_name // qualified type name 2287 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, 0, false )->addQualifiers( $2 ); } 2225 2288 ; 2226 2289 … … 2228 2291 identifier_or_type_name enumerator_value_opt 2229 2292 { $$ = DeclarationNode::newEnumConstant( $1, $2 ); } 2293 | INLINE type_name 2294 { $$ = DeclarationNode::newEnumConstant( new string("inline"), nullptr ); } 2230 2295 | enumerator_list ',' identifier_or_type_name enumerator_value_opt 2231 2296 { $$ = $1->appendList( DeclarationNode::newEnumConstant( $3, $4 ) ); } 2297 | enumerator_list ',' INLINE type_name enumerator_value_opt 2298 { $$ = $1->appendList( DeclarationNode::newEnumConstant( new string("inline"), nullptr ) ); } 2232 2299 ; 2233 2300 … … 2237 2304 // | '=' constant_expression 2238 2305 // { $$ = $2; } 2239 | '='initializer2306 | simple_assignment_operator initializer 2240 2307 { $$ = $2->get_expression(); } // FIX ME: enum only deals with constant_expression 2241 2308 ; … … 2365 2432 // empty 2366 2433 { $$ = nullptr; } 2367 | '=' initializer 2368 { $$ = $2; } 2369 | '=' VOID 2370 { $$ = new InitializerNode( true ); } 2371 | ATassign initializer 2372 { $$ = $2->set_maybeConstructed( false ); } 2434 | simple_assignment_operator initializer { $$ = $1 == OperKinds::Assign ? $2 : $2->set_maybeConstructed( false ); } 2435 | '=' VOID { $$ = new InitializerNode( true ); } 2373 2436 ; 2374 2437 … … 2626 2689 2627 2690 external_definition: 2628 declaration 2691 DIRECTIVE 2692 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 2693 | declaration 2629 2694 | external_function_definition 2630 2695 | EXTENSION external_definition // GCC, multiple __extension__ allowed, meaning unknown … … 2634 2699 } 2635 2700 | ASM '(' string_literal ')' ';' // GCC, global assembler statement 2636 { 2637 $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); 2638 } 2701 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, 0 ) ) ); } 2639 2702 | EXTERN STRINGliteral // C++-style linkage specifier 2640 2703 { … … 2782 2845 ; 2783 2846 2784 attribute_opt:2785 // empty2786 { $$ = nullptr; }2787 | attribute2788 ;2789 2790 2847 attribute: // GCC 2791 2848 ATTRIBUTE '(' '(' attribute_name_list ')' ')' … … 2849 2906 // declaring an array of functions versus a pointer to an array of functions. 2850 2907 2908 paren_identifier: 2909 identifier 2910 { $$ = DeclarationNode::newName( $1 ); } 2911 | '(' paren_identifier ')' // redundant parenthesis 2912 { $$ = $2; } 2913 ; 2914 2851 2915 variable_declarator: 2852 2916 paren_identifier attribute_list_opt … … 2859 2923 ; 2860 2924 2861 paren_identifier:2862 identifier2863 { $$ = DeclarationNode::newName( $1 ); }2864 | '(' paren_identifier ')' // redundant parenthesis2865 { $$ = $2; }2866 ;2867 2868 2925 variable_ptr: 2869 2926 ptrref_operator variable_declarator … … 2871 2928 | ptrref_operator type_qualifier_list variable_declarator 2872 2929 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 2873 | '(' variable_ptr ')' attribute_list_opt 2874 { $$ = $2->addQualifiers( $4 ); } // redundant parenthesis 2930 | '(' variable_ptr ')' attribute_list_opt // redundant parenthesis 2931 { $$ = $2->addQualifiers( $4 ); } 2932 | '(' attribute_list variable_ptr ')' attribute_list_opt // redundant parenthesis 2933 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 2875 2934 ; 2876 2935 … … 2880 2939 | '(' variable_ptr ')' array_dimension 2881 2940 { $$ = $2->addArray( $4 ); } 2882 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 2941 | '(' attribute_list variable_ptr ')' array_dimension 2942 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 2943 | '(' variable_array ')' multi_array_dimension // redundant parenthesis 2883 2944 { $$ = $2->addArray( $4 ); } 2945 | '(' attribute_list variable_array ')' multi_array_dimension // redundant parenthesis 2946 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 2884 2947 | '(' variable_array ')' // redundant parenthesis 2885 2948 { $$ = $2; } 2949 | '(' attribute_list variable_array ')' // redundant parenthesis 2950 { $$ = $3->addQualifiers( $2 ); } 2886 2951 ; 2887 2952 … … 2889 2954 '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2890 2955 { $$ = $2->addParamList( $6 ); } 2956 | '(' attribute_list variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 2957 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 2891 2958 | '(' variable_function ')' // redundant parenthesis 2892 2959 { $$ = $2; } 2960 | '(' attribute_list variable_function ')' // redundant parenthesis 2961 { $$ = $3->addQualifiers( $2 ); } 2893 2962 ; 2894 2963 … … 2910 2979 | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')' 2911 2980 { $$ = $2->addParamList( $6 ); } 2981 | '(' attribute_list function_ptr ')' '(' push parameter_type_list_opt pop ')' 2982 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 2912 2983 | '(' function_no_ptr ')' // redundant parenthesis 2913 2984 { $$ = $2; } 2985 | '(' attribute_list function_no_ptr ')' // redundant parenthesis 2986 { $$ = $3->addQualifiers( $2 ); } 2914 2987 ; 2915 2988 … … 2919 2992 | ptrref_operator type_qualifier_list function_declarator 2920 2993 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 2921 | '(' function_ptr ')' 2922 { $$ = $2; } 2994 | '(' function_ptr ')' attribute_list_opt 2995 { $$ = $2->addQualifiers( $4 ); } 2996 | '(' attribute_list function_ptr ')' attribute_list_opt 2997 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 2923 2998 ; 2924 2999 … … 2926 3001 '(' function_ptr ')' array_dimension 2927 3002 { $$ = $2->addArray( $4 ); } 3003 | '(' attribute_list function_ptr ')' array_dimension 3004 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 2928 3005 | '(' function_array ')' multi_array_dimension // redundant parenthesis 2929 3006 { $$ = $2->addArray( $4 ); } 3007 | '(' attribute_list function_array ')' multi_array_dimension // redundant parenthesis 3008 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 2930 3009 | '(' function_array ')' // redundant parenthesis 2931 3010 { $$ = $2; } 3011 | '(' attribute_list function_array ')' // redundant parenthesis 3012 { $$ = $3->addQualifiers( $2 ); } 2932 3013 ; 2933 3014 … … 2950 3031 | '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')' 2951 3032 { $$ = $2->addParamList( $6 ); } 3033 | '(' attribute_list KR_function_ptr ')' '(' push parameter_type_list_opt pop ')' 3034 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 2952 3035 | '(' KR_function_no_ptr ')' // redundant parenthesis 2953 3036 { $$ = $2; } 3037 | '(' attribute_list KR_function_no_ptr ')' // redundant parenthesis 3038 { $$ = $3->addQualifiers( $2 ); } 2954 3039 ; 2955 3040 … … 2961 3046 | '(' KR_function_ptr ')' 2962 3047 { $$ = $2; } 3048 | '(' attribute_list KR_function_ptr ')' 3049 { $$ = $3->addQualifiers( $2 ); } 2963 3050 ; 2964 3051 … … 2966 3053 '(' KR_function_ptr ')' array_dimension 2967 3054 { $$ = $2->addArray( $4 ); } 3055 | '(' attribute_list KR_function_ptr ')' array_dimension 3056 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 2968 3057 | '(' KR_function_array ')' multi_array_dimension // redundant parenthesis 2969 3058 { $$ = $2->addArray( $4 ); } 3059 | '(' attribute_list KR_function_array ')' multi_array_dimension // redundant parenthesis 3060 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 2970 3061 | '(' KR_function_array ')' // redundant parenthesis 2971 3062 { $$ = $2; } 3063 | '(' attribute_list KR_function_array ')' // redundant parenthesis 3064 { $$ = $3->addQualifiers( $2 ); } 2972 3065 ; 2973 3066 … … 2981 3074 // The pattern precludes declaring an array of functions versus a pointer to an array of functions, and returning arrays 2982 3075 // and functions versus pointers to arrays and functions. 3076 3077 paren_type: 3078 typedef_name 3079 { 3080 // hide type name in enclosing scope by variable name 3081 typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" ); 3082 } 3083 | '(' paren_type ')' 3084 { $$ = $2; } 3085 ; 2983 3086 2984 3087 variable_type_redeclarator: … … 2992 3095 ; 2993 3096 2994 paren_type:2995 typedef2996 // hide type name in enclosing scope by variable name2997 {2998 // if ( ! typedefTable.existsCurr( *$1->name ) ) {2999 typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" );3000 // } else {3001 // SemanticError( yylloc, string("'") + *$1->name + "' redeclared as different kind of symbol." ); $$ = nullptr;3002 // } // if3003 }3004 | '(' paren_type ')'3005 { $$ = $2; }3006 ;3007 3008 3097 type_ptr: 3009 3098 ptrref_operator variable_type_redeclarator … … 3011 3100 | ptrref_operator type_qualifier_list variable_type_redeclarator 3012 3101 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3013 | '(' type_ptr ')' attribute_list_opt 3014 { $$ = $2->addQualifiers( $4 ); } // redundant parenthesis 3102 | '(' type_ptr ')' attribute_list_opt // redundant parenthesis 3103 { $$ = $2->addQualifiers( $4 ); } 3104 | '(' attribute_list type_ptr ')' attribute_list_opt // redundant parenthesis 3105 { $$ = $3->addQualifiers( $2 )->addQualifiers( $5 ); } 3015 3106 ; 3016 3107 … … 3020 3111 | '(' type_ptr ')' array_dimension 3021 3112 { $$ = $2->addArray( $4 ); } 3113 | '(' attribute_list type_ptr ')' array_dimension 3114 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3022 3115 | '(' type_array ')' multi_array_dimension // redundant parenthesis 3023 3116 { $$ = $2->addArray( $4 ); } 3117 | '(' attribute_list type_array ')' multi_array_dimension // redundant parenthesis 3118 { $$ = $3->addQualifiers( $2 )->addArray( $5 ); } 3024 3119 | '(' type_array ')' // redundant parenthesis 3025 3120 { $$ = $2; } 3121 | '(' attribute_list type_array ')' // redundant parenthesis 3122 { $$ = $3->addQualifiers( $2 ); } 3026 3123 ; 3027 3124 … … 3031 3128 | '(' type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3032 3129 { $$ = $2->addParamList( $6 ); } 3130 | '(' attribute_list type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3131 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); } 3033 3132 | '(' type_function ')' // redundant parenthesis 3034 3133 { $$ = $2; } 3134 | '(' attribute_list type_function ')' // redundant parenthesis 3135 { $$ = $3->addQualifiers( $2 ); } 3035 3136 ; 3036 3137 … … 3057 3158 | ptrref_operator type_qualifier_list identifier_parameter_declarator 3058 3159 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3059 | '(' identifier_parameter_ptr ')' attribute_list_opt 3160 | '(' identifier_parameter_ptr ')' attribute_list_opt // redundant parenthesis 3060 3161 { $$ = $2->addQualifiers( $4 ); } 3061 3162 ; … … 3091 3192 3092 3193 type_parameter_redeclarator: 3093 typedef attribute_list_opt3194 typedef_name attribute_list_opt 3094 3195 { $$ = $1->addQualifiers( $2 ); } 3095 | '&' MUTEX typedef attribute_list_opt3196 | '&' MUTEX typedef_name attribute_list_opt 3096 3197 { $$ = $3->addPointer( DeclarationNode::newPointer( DeclarationNode::newTypeQualifier( Type::Mutex ), OperKinds::AddressOf ) )->addQualifiers( $4 ); } 3097 3198 | type_parameter_ptr … … 3102 3203 ; 3103 3204 3104 typedef :3205 typedef_name: 3105 3206 TYPEDEFname 3106 3207 { $$ = DeclarationNode::newName( $1 ); } … … 3114 3215 | ptrref_operator type_qualifier_list type_parameter_redeclarator 3115 3216 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3116 | '(' type_parameter_ptr ')' attribute_list_opt 3217 | '(' type_parameter_ptr ')' attribute_list_opt // redundant parenthesis 3117 3218 { $$ = $2->addQualifiers( $4 ); } 3118 3219 ; 3119 3220 3120 3221 type_parameter_array: 3121 typedef array_parameter_dimension3222 typedef_name array_parameter_dimension 3122 3223 { $$ = $1->addArray( $2 ); } 3123 3224 | '(' type_parameter_ptr ')' array_parameter_dimension … … 3126 3227 3127 3228 type_parameter_function: 3128 typedef '(' push parameter_type_list_opt pop ')'// empty parameter list OBSOLESCENT (see 3)3229 typedef_name '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) 3129 3230 { $$ = $1->addParamList( $4 ); } 3130 3231 | '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3) … … 3255 3356 | ptrref_operator type_qualifier_list abstract_parameter_declarator 3256 3357 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3257 | '(' abstract_parameter_ptr ')' attribute_list_opt 3358 | '(' abstract_parameter_ptr ')' attribute_list_opt // redundant parenthesis 3258 3359 { $$ = $2->addQualifiers( $4 ); } 3259 3360 ; … … 3334 3435 | ptrref_operator type_qualifier_list variable_abstract_declarator 3335 3436 { $$ = $3->addPointer( DeclarationNode::newPointer( $2, $1 ) ); } 3336 | '(' variable_abstract_ptr ')' attribute_list_opt 3437 | '(' variable_abstract_ptr ')' attribute_list_opt // redundant parenthesis 3337 3438 { $$ = $2->addQualifiers( $4 ); } 3338 3439 ; -
src/ResolvExpr/CurrentObject.cc
rfeacef9 r5407cdc 925 925 if ( auto aggr = dynamic_cast< const BaseInstType * >( type ) ) { 926 926 if ( auto sit = dynamic_cast< const StructInstType * >( aggr ) ) { 927 assert( sit->base ); 927 928 return new StructIterator{ loc, sit }; 928 929 } else if ( auto uit = dynamic_cast< const UnionInstType * >( aggr ) ) { 930 assert( uit->base ); 929 931 return new UnionIterator{ loc, uit }; 930 932 } else { -
src/SynTree/Constant.cc
rfeacef9 r5407cdc 42 42 } 43 43 44 Constant Constant::from_string( const std::string & str ) { 45 Type * charType = new BasicType( noQualifiers, BasicType::Char ); 46 // Adjust the length of the string for the terminator. 47 Expression * strSize = new ConstantExpr( Constant::from_ulong( str.size() + 1 ) ); 48 Type * strType = new ArrayType( noQualifiers, charType, strSize, false, false ); 49 const std::string strValue = "\"" + str + "\""; 50 return Constant( strType, strValue, std::nullopt ); 51 } 52 44 53 Constant Constant::null( Type * ptrtype ) { 45 54 if ( nullptr == ptrtype ) { -
src/SynTree/Constant.h
rfeacef9 r5407cdc 47 47 /// generates an integer constant of the given unsigned long int 48 48 static Constant from_ulong( unsigned long i ); 49 /// generates a string constant from the given string (char type, unquoted string) 50 static Constant from_string( const std::string & string ); 49 51 50 52 /// generates a null pointer value for the given type. void * if omitted. -
src/SynTree/Declaration.cc
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 11 16:39:56 201913 // Update Count : 3 612 // Last Modified On : Fri Mar 12 18:35:39 2021 13 // Update Count : 37 14 14 // 15 15 … … 66 66 67 67 68 DirectiveDecl::DirectiveDecl( DirectiveStmt *stmt ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), stmt( stmt ) { 69 } 70 71 DirectiveDecl::DirectiveDecl( const DirectiveDecl &other ) : Declaration( other ), stmt( maybeClone( other.stmt ) ) { 72 } 73 74 DirectiveDecl::~DirectiveDecl() { 75 delete stmt; 76 } 77 78 void DirectiveDecl::print( std::ostream &os, Indenter indent ) const { 79 stmt->print( os, indent ); 80 } 81 82 void DirectiveDecl::printShort( std::ostream &os, Indenter indent ) const { 83 stmt->print( os, indent ); 84 } 85 86 68 87 StaticAssertDecl::StaticAssertDecl( Expression * condition, ConstantExpr * message ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), condition( condition ), message( message ) { 69 88 } -
src/SynTree/Declaration.h
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 11 20:48:39202113 // Update Count : 15 812 // Last Modified On : Fri Mar 12 18:35:36 2021 13 // Update Count : 159 14 14 // 15 15 … … 400 400 }; 401 401 402 class DirectiveDecl : public Declaration { 403 public: 404 DirectiveStmt * stmt; 405 406 DirectiveDecl( DirectiveStmt * stmt ); 407 DirectiveDecl( const DirectiveDecl & other ); 408 virtual ~DirectiveDecl(); 409 410 DirectiveStmt * get_stmt() { return stmt; } 411 void set_stmt( DirectiveStmt * newValue ) { stmt = newValue; } 412 413 virtual DirectiveDecl * clone() const override { return new DirectiveDecl( *this ); } 414 virtual void accept( Visitor & v ) override { v.visit( this ); } 415 virtual void accept( Visitor & v ) const override { v.visit( this ); } 416 virtual DirectiveDecl * acceptMutator( Mutator & m ) override { return m.mutate( this ); } 417 virtual void print( std::ostream & os, Indenter indent = {} ) const override; 418 virtual void printShort( std::ostream & os, Indenter indent = {} ) const override; 419 }; 420 402 421 class StaticAssertDecl : public Declaration { 403 422 public: -
src/SynTree/Mutator.h
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:37:46 201913 // Update Count : 1 712 // Last Modified On : Fri Mar 12 18:35:36 2021 13 // Update Count : 18 14 14 // 15 15 #pragma once … … 34 34 virtual Declaration * mutate( TypedefDecl * typeDecl ) = 0; 35 35 virtual AsmDecl * mutate( AsmDecl * asmDecl ) = 0; 36 virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) = 0; 36 37 virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0; 37 38 -
src/SynTree/SynTree.h
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:37:45 201913 // Update Count : 1 212 // Last Modified On : Fri Mar 12 18:56:44 2021 13 // Update Count : 13 14 14 // 15 15 … … 36 36 class TypedefDecl; 37 37 class AsmDecl; 38 class DirectiveDecl; 38 39 class StaticAssertDecl; 39 40 -
src/SynTree/Visitor.h
rfeacef9 r5407cdc 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Jul 25 22:21:49 201913 // Update Count : 1 412 // Last Modified On : Fri Mar 12 18:35:35 2021 13 // Update Count : 15 14 14 // 15 15 … … 45 45 virtual void visit( AsmDecl * node ) { visit( const_cast<const AsmDecl *>(node) ); } 46 46 virtual void visit( const AsmDecl * asmDecl ) = 0; 47 virtual void visit( DirectiveDecl * node ) { visit( const_cast<const DirectiveDecl *>(node) ); } 48 virtual void visit( const DirectiveDecl * directiveDecl ) = 0; 47 49 virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); } 48 50 virtual void visit( const StaticAssertDecl * assertDecl ) = 0; -
src/Virtual/ExpandCasts.cc
rfeacef9 r5407cdc 32 32 namespace Virtual { 33 33 34 static bool is_prefix( const std::string & prefix, const std::string& entire ) { 35 size_t const p_size = prefix.size(); 36 return (p_size < entire.size() && prefix == entire.substr(0, p_size)); 37 } 38 39 static bool is_type_id_object( const ObjectDecl * objectDecl ) { 40 const std::string & objectName = objectDecl->name; 41 return is_prefix( "__cfatid_", objectName ); 42 } 43 34 44 // Indented until the new ast code gets added. 35 45 … … 66 76 }; 67 77 68 /* Currently virtual depends on the rather brittle name matching between69 * a (strict/explicate) virtual type, its vtable type and the vtable70 * instance.71 * A stronger implementation, would probably keep track of those triads72 * and use that information to create better error messages.73 */74 75 namespace {76 77 std::string get_vtable_name( std::string const & name ) {78 return name + "_vtable";79 }80 81 std::string get_vtable_inst_name( std::string const & name ) {82 return std::string("_") + get_vtable_name( name ) + "_instance";83 }84 85 std::string get_vtable_name_root( std::string const & name ) {86 return name.substr(0, name.size() - 7 );87 }88 89 std::string get_vtable_inst_name_root( std::string const & name ) {90 return get_vtable_name_root( name.substr(1, name.size() - 10 ) );91 }92 93 bool is_vtable_inst_name( std::string const & name ) {94 return 17 < name.size() &&95 name == get_vtable_inst_name( get_vtable_inst_name_root( name ) );96 }97 98 } // namespace99 100 78 class VirtualCastCore { 101 Type * pointer_to_pvt(int level_of_indirection) {79 CastExpr * cast_to_type_id( Expression * expr, int level_of_indirection ) { 102 80 Type * type = new StructInstType( 103 81 Type::Qualifiers( Type::Const ), pvt_decl ); … … 105 83 type = new PointerType( noQualifiers, type ); 106 84 } 107 return type;85 return new CastExpr( expr, type ); 108 86 } 109 87 … … 141 119 142 120 void VirtualCastCore::premutate( ObjectDecl * objectDecl ) { 143 if ( is_vtable_inst_name( objectDecl->get_name() ) ) { 144 if ( ObjectDecl * existing = indexer.insert( objectDecl ) ) { 145 std::string msg = "Repeated instance of virtual table, original found at: "; 146 msg += existing->location.filename; 147 msg += ":" + toString( existing->location.first_line ); 148 SemanticError( objectDecl->location, msg ); 149 } 121 if ( is_type_id_object( objectDecl ) ) { 122 // Multiple definitions should be fine because of linkonce. 123 indexer.insert( objectDecl ); 150 124 } 151 125 } … … 170 144 } 171 145 172 /// Get the virtual table type used in a virtual cast. 173 Type * getVirtualTableType( const VirtualCastExpr * castExpr ) { 174 const Type * objectType; 175 if ( auto target = dynamic_cast<const PointerType *>( castExpr->result ) ) { 176 objectType = target->base; 177 } else if ( auto target = dynamic_cast<const ReferenceType *>( castExpr->result ) ) { 178 objectType = target->base; 146 /// Get the base type from a pointer or reference. 147 const Type * getBaseType( const Type * type ) { 148 if ( auto target = dynamic_cast<const PointerType *>( type ) ) { 149 return target->base; 150 } else if ( auto target = dynamic_cast<const ReferenceType *>( type ) ) { 151 return target->base; 179 152 } else { 180 castError( castExpr, "Virtual cast type must be a pointer or reference type." ); 181 } 182 assert( objectType ); 183 184 const StructInstType * structType = dynamic_cast<const StructInstType *>( objectType ); 185 if ( nullptr == structType ) { 186 castError( castExpr, "Virtual cast type must refer to a structure type." ); 187 } 188 const StructDecl * structDecl = structType->baseStruct; 189 assert( structDecl ); 190 191 const ObjectDecl * fieldDecl = nullptr; 192 if ( 0 < structDecl->members.size() ) { 193 const Declaration * memberDecl = structDecl->members.front(); 153 return nullptr; 154 } 155 } 156 157 /* Attempt to follow the "head" field of the structure to get the... 158 * Returns nullptr on error, otherwise owner must free returned node. 159 */ 160 StructInstType * followHeadPointerType( 161 const StructInstType * oldType, 162 const std::string& fieldName, 163 const CodeLocation& errorLocation ) { 164 165 // First section of the function is all about trying to fill this variable in. 166 StructInstType * newType = nullptr; 167 { 168 const StructDecl * oldDecl = oldType->baseStruct; 169 assert( oldDecl ); 170 171 // Helper function for throwing semantic errors. 172 auto throwError = [&fieldName, &errorLocation, &oldDecl](const std::string& message) { 173 const std::string& context = "While following head pointer of " + 174 oldDecl->name + " named '" + fieldName + "': "; 175 SemanticError( errorLocation, context + message ); 176 }; 177 178 if ( oldDecl->members.empty() ) { 179 throwError( "Type has no fields." ); 180 } 181 const Declaration * memberDecl = oldDecl->members.front(); 194 182 assert( memberDecl ); 195 fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl ); 196 if ( fieldDecl && fieldDecl->name != "virtual_table" ) { 197 fieldDecl = nullptr; 198 } 199 } 200 if ( nullptr == fieldDecl ) { 201 castError( castExpr, "Virtual cast type must have a leading virtual_table field." ); 202 } 203 const PointerType * fieldType = dynamic_cast<const PointerType *>( fieldDecl->type ); 204 if ( nullptr == fieldType ) { 205 castError( castExpr, "Virtual cast type virtual_table field is not a pointer." ); 206 } 207 assert( fieldType->base ); 208 auto virtualStructType = dynamic_cast<const StructInstType *>( fieldType->base ); 209 assert( virtualStructType ); 210 211 // Here is the type, but if it is polymorphic it will have lost information. 212 // (Always a clone so that it may always be deleted.) 213 StructInstType * virtualType = virtualStructType->clone(); 214 if ( ! structType->parameters.empty() ) { 215 deleteAll( virtualType->parameters ); 216 virtualType->parameters.clear(); 217 cloneAll( structType->parameters, virtualType->parameters ); 218 } 219 return virtualType; 183 const ObjectDecl * fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl ); 184 assert( fieldDecl ); 185 if ( fieldName != fieldDecl->name ) { 186 throwError( "Head field did not have expected name." ); 187 } 188 189 const Type * fieldType = fieldDecl->type; 190 if ( nullptr == fieldType ) { 191 throwError( "Could not get head field." ); 192 } 193 const PointerType * ptrType = dynamic_cast<const PointerType *>( fieldType ); 194 if ( nullptr == ptrType ) { 195 throwError( "First field is not a pointer type." ); 196 } 197 assert( ptrType->base ); 198 newType = dynamic_cast<StructInstType *>( ptrType->base ); 199 if ( nullptr == newType ) { 200 throwError( "First field does not point to a structure type." ); 201 } 202 } 203 204 // Now we can look into copying it. 205 newType = newType->clone(); 206 if ( ! oldType->parameters.empty() ) { 207 deleteAll( newType->parameters ); 208 newType->parameters.clear(); 209 cloneAll( oldType->parameters, newType->parameters ); 210 } 211 return newType; 212 } 213 214 /// Get the type-id type from a virtual type. 215 StructInstType * getTypeIdType( const Type * type, const CodeLocation& errorLocation ) { 216 const StructInstType * typeInst = dynamic_cast<const StructInstType *>( type ); 217 if ( nullptr == typeInst ) { 218 return nullptr; 219 } 220 StructInstType * tableInst = 221 followHeadPointerType( typeInst, "virtual_table", errorLocation ); 222 if ( nullptr == tableInst ) { 223 return nullptr; 224 } 225 StructInstType * typeIdInst = 226 followHeadPointerType( tableInst, "__cfavir_typeid", errorLocation ); 227 delete tableInst; 228 return typeIdInst; 220 229 } 221 230 … … 228 237 assert( pvt_decl ); 229 238 230 const Type * vtable_type = getVirtualTableType( castExpr ); 231 ObjectDecl * table = indexer.lookup( vtable_type ); 232 if ( nullptr == table ) { 233 SemanticError( castLocation( castExpr ), 234 "Could not find virtual table instance." ); 239 const Type * base_type = getBaseType( castExpr->result ); 240 if ( nullptr == base_type ) { 241 castError( castExpr, "Virtual cast target must be a pointer or reference type." ); 242 } 243 const Type * type_id_type = getTypeIdType( base_type, castLocation( castExpr ) ); 244 if ( nullptr == type_id_type ) { 245 castError( castExpr, "Ill formed virtual cast target type." ); 246 } 247 ObjectDecl * type_id = indexer.lookup( type_id_type ); 248 delete type_id_type; 249 if ( nullptr == type_id ) { 250 castError( castExpr, "Virtual cast does not target a virtual type." ); 235 251 } 236 252 237 253 Expression * result = new CastExpr( 238 254 new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), { 239 new CastExpr( 240 new AddressExpr( new VariableExpr( table ) ), 241 pointer_to_pvt(1) 242 ), 243 new CastExpr( 244 castExpr->get_arg(), 245 pointer_to_pvt(2) 246 ) 255 cast_to_type_id( new AddressExpr( new VariableExpr( type_id ) ), 1 ), 256 cast_to_type_id( castExpr->get_arg(), 2 ), 247 257 } ), 248 258 castExpr->get_result()->clone() … … 252 262 castExpr->set_result( nullptr ); 253 263 delete castExpr; 254 delete vtable_type;255 264 return result; 256 265 } -
src/Virtual/Tables.cc
rfeacef9 r5407cdc 10 10 // Created On : Mon Aug 31 11:11:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Sep 3 14:56:00 202013 // Update Count : 012 // Last Modified On : Wed Apr 21 15:36:00 2021 13 // Update Count : 2 14 14 // 15 15 … … 22 22 namespace Virtual { 23 23 24 std::string typeIdType( std::string const & type_name ) { 25 return "__cfatid_struct_" + type_name; 26 } 27 28 std::string typeIdName( std::string const & type_name ) { 29 return "__cfatid_" + type_name; 30 } 31 32 static std::string typeIdTypeToInstance( std::string const & type_name ) { 33 return typeIdName(type_name.substr(16)); 34 } 35 24 36 std::string vtableTypeName( std::string const & name ) { 25 37 return name + "_vtable"; 26 38 } 27 39 40 std::string baseTypeName( std::string const & vtable_type_name ) { 41 return vtable_type_name.substr(0, vtable_type_name.size() - 7); 42 } 43 28 44 std::string instanceName( std::string const & name ) { 29 45 return std::string("_") + name + "_instance"; … … 32 48 std::string vtableInstanceName( std::string const & name ) { 33 49 return instanceName( vtableTypeName( name ) ); 50 } 51 52 std::string concurrentDefaultVTableName() { 53 return "_default_vtable"; 34 54 } 35 55 … … 41 61 42 62 static ObjectDecl * makeVtableDeclaration( 63 std::string const & name, 43 64 StructInstType * type, Initializer * init ) { 44 std::string const & name = instanceName( type->name );45 65 Type::StorageClasses storage = noStorageClasses; 46 66 if ( nullptr == init ) { … … 57 77 } 58 78 59 ObjectDecl * makeVtableForward( StructInstType * type ) {79 ObjectDecl * makeVtableForward( std::string const & name, StructInstType * type ) { 60 80 assert( type ); 61 return makeVtableDeclaration( type, nullptr );81 return makeVtableDeclaration( name, type, nullptr ); 62 82 } 63 83 64 84 ObjectDecl * makeVtableInstance( 65 StructInstType * vtableType, Type * objectType, Initializer * init ) { 85 std::string const & name, StructInstType * vtableType, 86 Type * objectType, Initializer * init ) { 66 87 assert( vtableType ); 67 88 assert( objectType ); … … 81 102 inits.push_back( 82 103 new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) ); 104 } else if ( std::string( "__cfavir_typeid" ) == field->name ) { 105 std::string const & baseType = baseTypeName( vtableType->name ); 106 std::string const & typeId = typeIdName( baseType ); 107 inits.push_back( new SingleInit( new AddressExpr( new NameExpr( typeId ) ) ) ); 83 108 } else if ( std::string( "size" ) == field->name ) { 84 109 inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) ); … … 95 120 assert(false); 96 121 } 97 return makeVtableDeclaration( vtableType, init );122 return makeVtableDeclaration( name, vtableType, init ); 98 123 } 99 124 … … 147 172 } 148 173 149 } 174 Attribute * linkonce( const std::string & subsection ) { 175 const std::string section = ".gnu.linkonce." + subsection; 176 return new Attribute( "section", { 177 new ConstantExpr( Constant::from_string( section ) ), 178 } ); 179 } 180 181 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) { 182 assert( typeIdType ); 183 StructInstType * type = typeIdType->clone(); 184 type->tq.is_const = true; 185 std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name ); 186 return new ObjectDecl( 187 typeid_name, 188 noStorageClasses, 189 LinkageSpec::Cforall, 190 /* bitfieldWidth */ nullptr, 191 type, 192 new ListInit( { new SingleInit( 193 new AddressExpr( new NameExpr( "__cfatid_exception_t" ) ) 194 ) } ), 195 { linkonce( typeid_name ) }, 196 noFuncSpecifiers 197 ); 198 } 199 200 } -
src/Virtual/Tables.h
rfeacef9 r5407cdc 10 10 // Created On : Mon Aug 31 11:07:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Sep 1 14:29:00 202013 // Update Count : 012 // Last Modified On : Wed Apr 21 10:30:00 2021 13 // Update Count : 2 14 14 // 15 15 … … 22 22 namespace Virtual { 23 23 24 std::string typeIdType( std::string const & type_name ); 25 std::string typeIdName( std::string const & type_name ); 24 26 std::string vtableTypeName( std::string const & type_name ); 25 27 std::string instanceName( std::string const & vtable_name ); 26 28 std::string vtableInstanceName( std::string const & type_name ); 29 std::string concurrentDefaultVTableName(); 27 30 bool isVTableInstanceName( std::string const & name ); 28 31 29 ObjectDecl * makeVtableForward( StructInstType * vtableType ); 32 ObjectDecl * makeVtableForward( 33 std::string const & name, StructInstType * vtableType ); 30 34 /* Create a forward declaration of a vtable of the given type. 31 35 * vtableType node is consumed. 32 36 */ 33 37 34 ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType, 38 ObjectDecl * makeVtableInstance( 39 std::string const & name, 40 StructInstType * vtableType, Type * objectType, 35 41 Initializer * init = nullptr ); 36 42 /* Create an initialized definition of a vtable. … … 50 56 */ 51 57 58 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ); 59 /* Build an instance of the type-id from the type of the type-id. 60 * TODO: Should take the parent type. Currently locked to the exception_t. 61 */ 62 52 63 } -
src/main.cc
rfeacef9 r5407cdc 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Feb 8 21:10:16202113 // Update Count : 6 4212 // Last Modified On : Sat Mar 6 15:49:00 2021 13 // Update Count : 656 14 14 // 15 15 … … 101 101 static string PreludeDirector = ""; 102 102 103 static void parse_cmdline( int argc, char * argv[] );103 static void parse_cmdline( int argc, char * argv[] ); 104 104 static void parse( FILE * input, LinkageSpec::Spec linkage, bool shouldExit = false ); 105 105 static void dump( list< Declaration * > & translationUnit, ostream & out = cout ); 106 static void dump( ast::TranslationUnit && transUnit, ostream & out = cout ); 106 107 107 108 static void backtrace( int start ) { // skip first N stack frames … … 158 159 #define SIGPARMS int sig __attribute__(( unused )), siginfo_t * sfp __attribute__(( unused )), ucontext_t * cxt __attribute__(( unused )) 159 160 160 static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) {161 static void Signal( int sig, void (* handler)(SIGPARMS), int flags ) { 161 162 struct sigaction act; 162 163 … … 165 166 166 167 if ( sigaction( sig, &act, nullptr ) == -1 ) { 167 cerr << "* CFA runtimeerror* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl;168 cerr << "*cfa-cpp compilation error* problem installing signal handler, error(" << errno << ") " << strerror( errno ) << endl; 168 169 _exit( EXIT_FAILURE ); 169 170 } // if … … 349 350 PASS( "Resolve", ResolvExpr::resolve( transUnit ) ); 350 351 if ( exprp ) { 351 translationUnit = convert( move( transUnit ) ); 352 dump( translationUnit ); 352 dump( move( transUnit ) ); 353 353 return EXIT_SUCCESS; 354 354 } // if … … 421 421 delete output; 422 422 } // if 423 } catch ( SemanticErrorException & e ) {423 } catch ( SemanticErrorException & e ) { 424 424 if ( errorp ) { 425 425 cerr << "---AST at error:---" << endl; … … 432 432 } // if 433 433 return EXIT_FAILURE; 434 } catch ( UnimplementedError & e ) {434 } catch ( UnimplementedError & e ) { 435 435 cout << "Sorry, " << e.get_what() << " is not currently implemented" << endl; 436 436 if ( output != &cout ) { … … 438 438 } // if 439 439 return EXIT_FAILURE; 440 } catch ( CompilerError & e ) {440 } catch ( CompilerError & e ) { 441 441 cerr << "Compiler Error: " << e.get_what() << endl; 442 442 cerr << "(please report bugs to [REDACTED])" << endl; … … 445 445 } // if 446 446 return EXIT_FAILURE; 447 } catch ( std::bad_alloc & ) { 448 cerr << "*cfa-cpp compilation error* std::bad_alloc" << endl; 449 backtrace( 1 ); 450 abort(); 447 451 } catch ( ... ) { 448 452 exception_ptr eptr = current_exception(); … … 451 455 rethrow_exception(eptr); 452 456 } else { 453 cerr << " Exception Uncaught and Unknown" << endl;454 } // if 455 } catch( const exception& e) {456 cerr << " Uncaught Exception \"" << e.what() << "\"\n";457 cerr << "*cfa-cpp compilation error* exception uncaught and unknown" << endl; 458 } // if 459 } catch( const exception & e ) { 460 cerr << "*cfa-cpp compilation error* uncaught exception \"" << e.what() << "\"\n"; 457 461 } // try 458 462 return EXIT_FAILURE; … … 544 548 enum { printoptsSize = sizeof( printopts ) / sizeof( printopts[0] ) }; 545 549 546 static void usage( char * argv[] ) {550 static void usage( char * argv[] ) { 547 551 cout << "Usage: " << argv[0] << " [options] [input-file (default stdin)] [output-file (default stdout)], where options are:" << endl; 548 552 int i = 0, j = 1; // j skips starting colon … … 732 736 } // dump 733 737 738 static void dump( ast::TranslationUnit && transUnit, ostream & out ) { 739 std::list< Declaration * > translationUnit = convert( move( transUnit ) ); 740 dump( translationUnit, out ); 741 } 742 734 743 // Local Variables: // 735 744 // tab-width: 4 //
Note:
See TracChangeset
for help on using the changeset viewer.