Changes in / [8ad6533:ca37445]
- Location:
- src
- Files:
-
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r8ad6533 rca37445 203 203 204 204 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl, const std::string & kind ) { 205 genAttributes( aggDecl->get_attributes() );206 207 205 if( ! aggDecl->get_parameters().empty() && ! genC ) { 208 206 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); … … 213 211 } 214 212 215 output << kind << aggDecl->get_name(); 213 output << kind; 214 genAttributes( aggDecl->get_attributes() ); 215 output << aggDecl->get_name(); 216 216 217 217 if ( aggDecl->has_body() ) { … … 298 298 output << " }"; 299 299 } 300 } 301 302 void CodeGenerator::postvisit( StaticAssertDecl * assertDecl ) { 303 output << "_Static_assert("; 304 assertDecl->condition->accept( *visitor ); 305 output << ", "; 306 assertDecl->message->accept( *visitor ); 307 output << ")"; 300 308 } 301 309 -
src/CodeGen/CodeGenerator.h
r8ad6533 rca37445 42 42 void postvisit( FunctionDecl * ); 43 43 void postvisit( ObjectDecl * ); 44 void postvisit( UnionDecl *aggregateDecl ); 45 void postvisit( EnumDecl *aggregateDecl ); 46 void postvisit( TraitDecl *aggregateDecl ); 47 void postvisit( TypedefDecl *typeDecl ); 48 void postvisit( TypeDecl *typeDecl ); 44 void postvisit( UnionDecl * aggregateDecl ); 45 void postvisit( EnumDecl * aggregateDecl ); 46 void postvisit( TraitDecl * aggregateDecl ); 47 void postvisit( TypedefDecl * typeDecl ); 48 void postvisit( TypeDecl * typeDecl ); 49 void postvisit( StaticAssertDecl * assertDecl ); 49 50 50 51 //*** Initializer -
src/CodeGen/OperatorTable.cc
r8ad6533 rca37445 79 79 } // namespace 80 80 81 bool operatorLookup( std::string funcName, OperatorInfo &info ) {81 bool operatorLookup( const std::string & funcName, OperatorInfo & info ) { 82 82 static bool init = false; 83 83 if ( ! init ) { … … 100 100 return true; 101 101 } // if 102 } 103 104 bool isOperator( const std::string & funcName ) { 105 OperatorInfo info; 106 return operatorLookup( funcName, info ); 102 107 } 103 108 -
src/CodeGen/OperatorTable.h
r8ad6533 rca37445 41 41 }; 42 42 43 bool operatorLookup( std::string funcName, OperatorInfo &info ); 43 bool isOperator( const std::string & funcName ); 44 bool operatorLookup( const std::string & funcName, OperatorInfo & info ); 44 45 45 46 bool isConstructor( const std::string & ); -
src/Common/Debug.h
r8ad6533 rca37445 28 28 namespace Debug { 29 29 /// debug codegen a translation unit 30 static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {30 static inline void codeGen( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) { 31 31 #ifdef DEBUG 32 32 std::list< Declaration * > decls; … … 41 41 } // dump 42 42 43 static inline void treeDump( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) {43 static inline void treeDump( __attribute__((unused)) const std::list< Declaration * > & translationUnit, __attribute__((unused)) const std::string & label, __attribute__((unused)) LinkageSpec::Spec linkageFilter = LinkageSpec::Compiler ) { 44 44 #ifdef DEBUG 45 45 std::list< Declaration * > decls; -
src/Common/ErrorObjects.h
r8ad6533 rca37445 35 35 class SemanticErrorException : public std::exception { 36 36 public: 37 37 SemanticErrorException() = default; 38 38 SemanticErrorException( CodeLocation location, std::string error ); 39 39 ~SemanticErrorException() throw() {} -
src/Common/PassVisitor.h
r8ad6533 rca37445 66 66 virtual void visit( TypedefDecl * typeDecl ) override final; 67 67 virtual void visit( AsmDecl * asmDecl ) override final; 68 virtual void visit( StaticAssertDecl * assertDecl ) override final; 68 69 69 70 virtual void visit( CompoundStmt * compoundStmt ) override final; … … 161 162 virtual Declaration * mutate( TypedefDecl * typeDecl ) override final; 162 163 virtual AsmDecl * mutate( AsmDecl * asmDecl ) override final; 164 virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final; 163 165 164 166 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override final; -
src/Common/PassVisitor.impl.h
r8ad6533 rca37445 685 685 686 686 //-------------------------------------------------------------------------- 687 // StaticAssertDecl 688 template< typename pass_type > 689 void PassVisitor< pass_type >::visit( StaticAssertDecl * node ) { 690 VISIT_START( node ); 691 692 maybeAccept_impl( node->condition, *this ); 693 maybeAccept_impl( node->message , *this ); 694 695 VISIT_END( node ); 696 } 697 698 template< typename pass_type > 699 StaticAssertDecl * PassVisitor< pass_type >::mutate( StaticAssertDecl * node ) { 700 MUTATE_START( node ); 701 702 maybeMutate_impl( node->condition, *this ); 703 maybeMutate_impl( node->message , *this ); 704 705 MUTATE_END( StaticAssertDecl, node ); 706 } 707 708 //-------------------------------------------------------------------------- 687 709 // CompoundStmt 688 710 template< typename pass_type > … … 1490 1512 indexerScopedAccept( node->result, *this ); 1491 1513 maybeAccept_impl ( node->type , *this ); 1492 maybeAccept_impl ( node->member, *this );1493 1514 1494 1515 VISIT_END( node ); … … 1502 1523 indexerScopedMutate( node->result, *this ); 1503 1524 maybeMutate_impl ( node->type , *this ); 1504 maybeMutate_impl ( node->member, *this );1505 1525 1506 1526 MUTATE_END( Expression, node ); -
src/GenPoly/Lvalue.cc
r8ad6533 rca37445 45 45 Expression * mkDeref( Expression * arg ) { 46 46 if ( SymTab::dereferenceOperator ) { 47 // note: reference depth can be arbitrarily deep here, so peel off the outermost pointer/reference, not just pointer because they are effecitvely equivalent in this pass 47 48 VariableExpr * deref = new VariableExpr( SymTab::dereferenceOperator ); 48 49 deref->result = new PointerType( Type::Qualifiers(), deref->result ); … … 197 198 PRINT( 198 199 std::cerr << "pair<0>: " << arg << std::endl; 200 std::cerr << " -- " << arg->result << std::endl; 199 201 std::cerr << "pair<1>: " << formal << std::endl; 200 202 ) 201 203 if ( dynamic_cast<ReferenceType*>( formal ) ) { 202 if ( isIntrinsicReference( arg ) ) { // do not combine conditions, because that changes the meaning of the else if 203 if ( function->get_linkage() != LinkageSpec::Intrinsic ) { // intrinsic functions that turn pointers into references 204 // if argument is dereference or array subscript, the result isn't REALLY a reference, so it's not necessary to fix the argument 205 PRINT( 206 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 207 ) 208 arg = new AddressExpr( arg ); 209 } 210 } else if ( function->get_linkage() == LinkageSpec::Intrinsic ) { 211 // std::cerr << "===adding deref to arg" << std::endl; 212 // if the parameter is a reference, add a dereference to the reference-typed argument. 204 PRINT( 205 std::cerr << "===formal is reference" << std::endl; 206 ) 207 // TODO: it's likely that the second condition should be ... && ! isIntrinsicReference( arg ), but this requires investigation. 208 if ( function->get_linkage() != LinkageSpec::Intrinsic && isIntrinsicReference( arg ) ) { 209 // if argument is dereference or array subscript, the result isn't REALLY a reference, but non-intrinsic functions expect a reference: take address 210 PRINT( 211 std::cerr << "===is intrinsic arg in non-intrinsic call - adding address" << std::endl; 212 ) 213 arg = new AddressExpr( arg ); 214 } else if ( function->get_linkage() == LinkageSpec::Intrinsic && arg->result->referenceDepth() != 0 ) { 215 // argument is a 'real' reference, but function expects a C lvalue: add a dereference to the reference-typed argument 216 PRINT( 217 std::cerr << "===is non-intrinsic arg in intrinsic call - adding deref to arg" << std::endl; 218 ) 213 219 Type * baseType = InitTweak::getPointerBase( arg->result ); 214 220 assertf( baseType, "parameter is reference, arg must be pointer or reference: %s", toString( arg->result ).c_str() ); … … 217 223 arg->set_result( ptrType ); 218 224 arg = mkDeref( arg ); 225 assertf( arg->result->referenceDepth() == 0, "Reference types should have been eliminated from intrinsic function calls, but weren't: %s", toCString( arg->result ) ); 219 226 } 220 227 } -
src/Parser/DeclarationNode.cc
r8ad6533 rca37445 71 71 attr.expr = nullptr; 72 72 attr.type = nullptr; 73 74 assert.condition = nullptr; 75 assert.message = nullptr; 73 76 } 74 77 … … 88 91 // asmName, no delete, passed to next stage 89 92 delete initializer; 93 94 delete assert.condition; 95 delete assert.message; 90 96 } 91 97 … … 117 123 newnode->attr.expr = maybeClone( attr.expr ); 118 124 newnode->attr.type = maybeClone( attr.type ); 125 126 newnode->assert.condition = maybeClone( assert.condition ); 127 newnode->assert.message = maybeClone( assert.message ); 119 128 return newnode; 120 129 } // DeclarationNode::clone … … 434 443 return newnode; 435 444 } 445 446 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) { 447 DeclarationNode * newnode = new DeclarationNode; 448 newnode->assert.condition = condition; 449 newnode->assert.message = message; 450 return newnode; 451 } 452 436 453 437 454 void appendError( string & dst, const string & src ) { … … 1052 1069 } // if 1053 1070 1071 if ( assert.condition ) { 1072 return new StaticAssertDecl( maybeBuild< Expression >( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) ); 1073 } 1074 1054 1075 // SUE's cannot have function specifiers, either 1055 1076 // -
src/Parser/ParseNode.h
r8ad6533 rca37445 246 246 static DeclarationNode * newAttribute( std::string *, ExpressionNode * expr = nullptr ); // gcc attributes 247 247 static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement 248 static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message ); 248 249 249 250 DeclarationNode(); … … 313 314 Attr_t attr; 314 315 316 struct StaticAssert_t { 317 ExpressionNode * condition; 318 Expression * message; 319 }; 320 StaticAssert_t assert; 321 315 322 BuiltinType builtin; 316 323 -
src/Parser/parser.yy
r8ad6533 rca37445 1314 1314 static_assert: 1315 1315 STATICASSERT '(' constant_expression ',' string_literal ')' ';' // C11 1316 { SemanticError( yylloc, "Static assert is currently unimplemented." ); $$ = nullptr; }1316 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1317 1317 1318 1318 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function -
src/ResolvExpr/CommonType.cc
r8ad6533 rca37445 27 27 #include "typeops.h" // for isFtype 28 28 29 // #define DEBUG 29 #define DEBUG 30 #ifdef DEBUG 31 #define PRINT(x) x 32 #else 33 #define PRINT(x) 34 #endif 30 35 31 36 namespace ResolvExpr { … … 70 75 // need unify to bind type variables 71 76 if ( unify( t1, t2, env, have, need, newOpen, indexer, common ) ) { 72 // std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 77 PRINT( 78 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 79 ) 73 80 if ( (widenFirst || t2->get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) { 74 // std::cerr << "widen okay" << std::endl; 81 PRINT( 82 std::cerr << "widen okay" << std::endl; 83 ) 75 84 common->get_qualifiers() |= t1->get_qualifiers(); 76 85 common->get_qualifiers() |= t2->get_qualifiers(); … … 78 87 } 79 88 } 80 // std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl; 89 PRINT( 90 std::cerr << "exact unify failed: " << t1 << " " << t2 << std::endl; 91 ) 81 92 return nullptr; 82 93 } … … 94 105 // special case where one type has a reference depth of 1 larger than the other 95 106 if ( diff > 0 || diff < 0 ) { 96 // std::cerr << "reference depth diff: " << diff << std::endl; 107 PRINT( 108 std::cerr << "reference depth diff: " << diff << std::endl; 109 ) 97 110 Type * result = nullptr; 98 111 ReferenceType * ref1 = dynamic_cast< ReferenceType * >( type1 ); … … 109 122 if ( result && ref1 ) { 110 123 // formal is reference, so result should be reference 111 // std::cerr << "formal is reference; result should be reference" << std::endl; 124 PRINT( 125 std::cerr << "formal is reference; result should be reference" << std::endl; 126 ) 112 127 result = new ReferenceType( ref1->get_qualifiers(), result ); 113 128 } 114 // std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl; 129 PRINT( 130 std::cerr << "common type of reference [" << type1 << "] and [" << type2 << "] is [" << result << "]" << std::endl; 131 ) 115 132 return result; 116 133 } -
src/ResolvExpr/Resolver.cc
r8ad6533 rca37445 59 59 void previsit( TypeDecl *typeDecl ); 60 60 void previsit( EnumDecl * enumDecl ); 61 void previsit( StaticAssertDecl * assertDecl ); 61 62 62 63 void previsit( ArrayType * at ); … … 361 362 GuardValue( inEnumDecl ); 362 363 inEnumDecl = true; 364 } 365 366 void Resolver::previsit( StaticAssertDecl * assertDecl ) { 367 findIntegralExpression( assertDecl->condition, indexer ); 363 368 } 364 369 -
src/SymTab/Validate.cc
r8ad6533 rca37445 89 89 void previsit( StructDecl * aggregateDecl ); 90 90 void previsit( UnionDecl * aggregateDecl ); 91 void previsit( StaticAssertDecl * assertDecl ); 91 92 92 93 private: … … 296 297 } 297 298 298 bool isStructOrUnion( Declaration *decl ) {299 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) ;299 bool shouldHoist( Declaration *decl ) { 300 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 300 301 } 301 302 … … 310 311 } // if 311 312 // Always remove the hoisted aggregate from the inner structure. 312 GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, isStructOrUnion, false ); } );313 GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, shouldHoist, false ); } ); 313 314 } 314 315 … … 328 329 if ( inst->baseUnion ) { 329 330 declsToAddBefore.push_front( inst->baseUnion ); 331 } 332 } 333 334 void HoistStruct::previsit( StaticAssertDecl * assertDecl ) { 335 if ( parentAggr ) { 336 declsToAddBefore.push_back( assertDecl ); 330 337 } 331 338 } … … 630 637 forallFixer( pointer->base->forall, object ); 631 638 } // if 639 // ensure that operator names only apply to functions or function pointers 640 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { 641 SemanticError( object->location, toCString( "operator ", object->name.c_str(), " is not a function or function pointer." ) ); 642 } 632 643 object->fixUniqueId(); 633 644 } -
src/SynTree/Declaration.cc
r8ad6533 rca37445 81 81 82 82 83 StaticAssertDecl::StaticAssertDecl( Expression * condition, ConstantExpr * message ) : Declaration( "", Type::StorageClasses(), LinkageSpec::C ), condition( condition ), message( message ) { 84 } 85 86 StaticAssertDecl::StaticAssertDecl( const StaticAssertDecl & other ) : Declaration( other ), condition( maybeClone( other.condition ) ), message( maybeClone( other.message ) ) { 87 } 88 89 StaticAssertDecl::~StaticAssertDecl() { 90 delete condition; 91 delete message; 92 } 93 94 void StaticAssertDecl::print( std::ostream &os, Indenter indent ) const { 95 os << "Static Assert with condition: "; 96 condition->print( os, indent+1 ); 97 os << std::endl << indent << "and message: "; 98 message->print( os, indent+1 ); 99 os << std::endl; 100 } 101 102 void StaticAssertDecl::printShort( std::ostream &os, Indenter indent ) const { 103 print( os, indent ); 104 } 105 83 106 // Local Variables: // 84 107 // tab-width: 4 // -
src/SynTree/Declaration.h
r8ad6533 rca37445 365 365 }; 366 366 367 class StaticAssertDecl : public Declaration { 368 public: 369 Expression * condition; 370 ConstantExpr * message; // string literal 371 372 StaticAssertDecl( Expression * condition, ConstantExpr * message ); 373 StaticAssertDecl( const StaticAssertDecl & other ); 374 virtual ~StaticAssertDecl(); 375 376 virtual StaticAssertDecl * clone() const override { return new StaticAssertDecl( *this ); } 377 virtual void accept( Visitor &v ) override { v.visit( this ); } 378 virtual StaticAssertDecl * acceptMutator( Mutator &m ) override { return m.mutate( this ); } 379 virtual void print( std::ostream &os, Indenter indent = {} ) const override; 380 virtual void printShort( std::ostream &os, Indenter indent = {} ) const override; 381 }; 382 367 383 std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data ); 368 384 -
src/SynTree/Mutator.h
r8ad6533 rca37445 34 34 virtual Declaration * mutate( TypedefDecl * typeDecl ) = 0; 35 35 virtual AsmDecl * mutate( AsmDecl * asmDecl ) = 0; 36 virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0; 36 37 37 38 virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) = 0; -
src/SynTree/SynTree.h
r8ad6533 rca37445 38 38 class TypedefDecl; 39 39 class AsmDecl; 40 class StaticAssertDecl; 40 41 41 42 class Statement; -
src/SynTree/Visitor.h
r8ad6533 rca37445 36 36 virtual void visit( TypedefDecl * typeDecl ) = 0; 37 37 virtual void visit( AsmDecl * asmDecl ) = 0; 38 virtual void visit( StaticAssertDecl * assertDecl ) = 0; 38 39 39 40 virtual void visit( CompoundStmt * compoundStmt ) = 0; -
src/tests/.expect/references.txt
r8ad6533 rca37445 4 4 13 1 12 5 5 14 14 6 x = 6 ; x2 = 789 7 x = 6 ; x2 = 999 8 x = 12345 ; x2 = 999 9 x = 22222 ; x2 = 999 6 10 Default constructing a Y 7 11 Copy constructing a Y -
src/tests/operators.c
r8ad6533 rca37445 27 27 a(b); 28 28 a + b; 29 struct accumulator ?+?; // why not, eh?30 a + b;31 29 } 32 30 -
src/tests/references.c
r8ad6533 rca37445 46 46 47 47 int main() { 48 int x = 123456, *p1 = &x, **p2 = &p1, ***p3 = &p2,48 int x = 123456, x2 = 789, *p1 = &x, **p2 = &p1, ***p3 = &p2, 49 49 &r1 = x, &&r2 = r1, &&&r3 = r2; 50 50 ***p3 = 3; // change x 51 // ((int&)r3 = 3; // change x, ***r352 51 **p3 = &x; // change p1 53 // ((int*&)&r3) = &x; // change r1, (&*)**r354 52 *p3 = &p1; // change p2 55 // ((int**&)&&r3) = &p2; // change r2, (&(&*)*)*r356 // ((int***&)&&&r3) = p3; // change r3 to p3, (&(&(&*)*)*)r357 53 int y = 0, z = 11, & ar[3] = { x, y, z }; // initialize array of references 58 54 // &ar[1] = &z; // change reference array element … … 62 58 // sizeof( &ar[1] ) == sizeof( int *); // is true, i.e., the size of a reference 63 59 60 ((int*&)&r3) = &x; // change r1, (&*)**r3 61 x = 3; 64 62 // test that basic reference properties are true - r1 should be an alias for x 65 63 printf("%d %d %d\n", x, r1, &x == &r1); … … 76 74 changeRef( r1 ); 77 75 printf("%d %d\n", r1, x); 76 77 ((int&)r3) = 6; // change x, ***r3 78 printf("x = %d ; x2 = %d\n", x, x2); // check that x was changed 79 ((int*&)&r3) = &x2; // change r1 to refer to x2, (&*)**r3 80 ((int&)r3) = 999; // modify x2 81 printf("x = %d ; x2 = %d\n", x, x2); // check that x2 was changed 82 ((int**&)&&r3) = p2; // change r2, (&(&*)*)*r3 83 ((int&)r3) = 12345; // modify x 84 printf("x = %d ; x2 = %d\n", x, x2); // check that x was changed 85 ((int***&)&&&r3) = p3; // change r3 to p3, (&(&(&*)*)*)r3 86 ((int&)r3) = 22222; // modify x 87 printf("x = %d ; x2 = %d\n", x, x2); // check that x was changed 78 88 79 89 // test that reference members are not implicitly constructed/destructed/assigned
Note: See TracChangeset
for help on using the changeset viewer.