- Timestamp:
- Dec 11, 2018, 2:42:27 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- 5307c33, 85acec94
- Parents:
- 1f690b3 (diff), 29207bf (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:
-
- 10 edited
-
Parser/DeclarationNode.cc (modified) (2 diffs)
-
Parser/ParseNode.h (modified) (2 diffs)
-
Parser/TypeData.cc (modified) (8 diffs)
-
Parser/TypeData.h (modified) (2 diffs)
-
Parser/lex.ll (modified) (2 diffs)
-
Parser/parser.yy (modified) (6 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (2 diffs)
-
ResolvExpr/ResolveTypeof.cc (modified) (1 diff)
-
SynTree/Type.h (modified) (1 diff)
-
SynTree/TypeofType.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/DeclarationNode.cc
r1f690b3 r90cfc16 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 14:56:54201813 // Update Count : 110 712 // Last Modified On : Thu Nov 1 20:54:26 2018 13 // Update Count : 1108 14 14 // 15 15 … … 402 402 } 403 403 404 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr ) {405 DeclarationNode * newnode = new DeclarationNode; 406 newnode->type = new TypeData( TypeData::Typeof );404 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) { 405 DeclarationNode * newnode = new DeclarationNode; 406 newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof ); 407 407 newnode->type->typeexpr = expr; 408 408 return newnode; -
src/Parser/ParseNode.h
r1f690b3 r90cfc16 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 4 09:39:40201813 // Update Count : 85 312 // Last Modified On : Thu Nov 1 20:54:53 2018 13 // Update Count : 854 14 14 // 15 15 … … 249 249 static DeclarationNode * newBitfield( ExpressionNode * size ); 250 250 static DeclarationNode * newTuple( DeclarationNode * members ); 251 static DeclarationNode * newTypeof( ExpressionNode * expr );251 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false ); 252 252 static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes 253 253 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes -
src/Parser/TypeData.cc
r1f690b3 r90cfc16 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 14:39:31201813 // Update Count : 62 212 // Last Modified On : Fri Nov 2 07:54:26 2018 13 // Update Count : 624 14 14 // 15 15 … … 96 96 break; 97 97 case Typeof: 98 case Basetypeof: 98 99 // typeexpr = new Typeof_t; 99 100 typeexpr = nullptr; … … 166 167 break; 167 168 case Typeof: 169 case Basetypeof: 168 170 // delete typeexpr->expr; 169 171 delete typeexpr; … … 245 247 break; 246 248 case Typeof: 249 case Basetypeof: 247 250 newtype->typeexpr = maybeClone( typeexpr ); 248 251 break; … … 419 422 } // if 420 423 break; 424 case Basetypeof: 425 os << "base-"; 426 #if defined(__GNUC__) && __GNUC__ >= 7 427 __attribute__((fallthrough)); 428 #endif 421 429 case Typeof: 422 430 os << "type-of expression "; … … 457 465 case Tuple: 458 466 case Typeof: 467 case Basetypeof: 459 468 case Builtin: 460 469 assertf(false, "Tried to get leaf name from kind without a name: %d", kind); … … 513 522 switch ( td->kind ) { 514 523 case TypeData::Unknown: 515 // fill in implicit int516 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );524 // fill in implicit int 525 return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); 517 526 case TypeData::Basic: 518 return buildBasicType( td );527 return buildBasicType( td ); 519 528 case TypeData::Pointer: 520 return buildPointer( td );529 return buildPointer( td ); 521 530 case TypeData::Array: 522 return buildArray( td );531 return buildArray( td ); 523 532 case TypeData::Reference: 524 return buildReference( td );533 return buildReference( td ); 525 534 case TypeData::Function: 526 return buildFunction( td );535 return buildFunction( td ); 527 536 case TypeData::AggregateInst: 528 return buildAggInst( td );537 return buildAggInst( td ); 529 538 case TypeData::EnumConstant: 530 // the name gets filled in later -- by SymTab::Validate531 return new EnumInstType( buildQualifiers( td ), "" );539 // the name gets filled in later -- by SymTab::Validate 540 return new EnumInstType( buildQualifiers( td ), "" ); 532 541 case TypeData::SymbolicInst: 533 return buildSymbolicInst( td );542 return buildSymbolicInst( td ); 534 543 case TypeData::Tuple: 535 return buildTuple( td );544 return buildTuple( td ); 536 545 case TypeData::Typeof: 537 return buildTypeof( td ); 546 case TypeData::Basetypeof: 547 return buildTypeof( td ); 538 548 case TypeData::Builtin: 539 if(td->builtintype == DeclarationNode::Zero) {540 return new ZeroType( noQualifiers );541 }542 else if(td->builtintype == DeclarationNode::One) {543 return new OneType( noQualifiers );544 }545 else {546 return new VarArgsType( buildQualifiers( td ) );547 }549 if (td->builtintype == DeclarationNode::Zero) { 550 return new ZeroType( noQualifiers ); 551 } 552 else if (td->builtintype == DeclarationNode::One) { 553 return new OneType( noQualifiers ); 554 } 555 else { 556 return new VarArgsType( buildQualifiers( td ) ); 557 } 548 558 case TypeData::GlobalScope: 549 return new GlobalScopeType();559 return new GlobalScopeType(); 550 560 case TypeData::Qualified: 551 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );561 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) ); 552 562 case TypeData::Symbolic: 553 563 case TypeData::Enum: 554 564 case TypeData::Aggregate: 555 assert( false );565 assert( false ); 556 566 } // switch 557 567 … … 929 939 930 940 TypeofType * buildTypeof( const TypeData * td ) { 931 assert( td->kind == TypeData::Typeof );941 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 932 942 assert( td->typeexpr ); 933 943 // assert( td->typeexpr->expr ); 934 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() ); 944 return new TypeofType{ 945 buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof }; 935 946 } // buildTypeof 936 947 -
src/Parser/TypeData.h
r1f690b3 r90cfc16 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 13:56:40201813 // Update Count : 19 512 // Last Modified On : Thu Nov 1 20:56:46 2018 13 // Update Count : 196 14 14 // 15 15 … … 27 27 struct TypeData { 28 28 enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 29 SymbolicInst, Tuple, Typeof, B uiltin, GlobalScope, Qualified, Unknown };29 SymbolicInst, Tuple, Typeof, Basetypeof, Builtin, GlobalScope, Qualified, Unknown }; 30 30 31 31 struct Aggregate_t { -
src/Parser/lex.ll
r1f690b3 r90cfc16 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed Aug 29 15:02:41201813 * Update Count : 68 612 * Last Modified On : Thu Nov 1 20:57:35 2018 13 * Update Count : 687 14 14 */ 15 15 … … 209 209 __attribute__ { KEYWORD_RETURN(ATTRIBUTE); } // GCC 210 210 auto { KEYWORD_RETURN(AUTO); } 211 basetypeof { KEYWORD_RETURN(BASETYPEOF); } // CFA 211 212 _Bool { KEYWORD_RETURN(BOOL); } // C99 212 213 break { KEYWORD_RETURN(BREAK); } -
src/Parser/parser.yy
r1f690b3 r90cfc16 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Aug 30 17:02:25201813 // Update Count : 40 2912 // Last Modified On : Thu Nov 8 18:08:23 2018 13 // Update Count : 4052 14 14 // 15 15 … … 186 186 } // fieldDecl 187 187 188 ExpressionNode *forInc( const OperKinds op ) {189 return new ExpressionNode( build_constantInteger( *new string( op == OperKinds::LThan || op == OperKinds::LEThan ? "1" : "-1" ) ) );190 } // forInc191 192 188 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 193 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr());189 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr()); 194 190 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 195 191 type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 196 192 } // if 197 193 return new ForCtrl( 198 distAttr( DeclarationNode::newTypeof( type ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),194 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 199 195 new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ), 200 new ExpressionNode( build_binary_val( OperKinds::PlusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) ); 196 new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 197 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) ); 198 } // forCtrl 199 200 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 201 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->get_expr()) ) { 202 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 203 } else { 204 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr; 205 } // if 201 206 } // forCtrl 202 207 … … 261 266 %token ZERO_T ONE_T // CFA 262 267 %token VALIST // GCC 263 %token TYPEOF LABEL// GCC268 %token TYPEOF BASETYPEOF LABEL // GCC 264 269 %token ENUM STRUCT UNION 265 270 %token EXCEPTION // CFA … … 636 641 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 637 642 | postfix_expression ARROW no_attr_identifier 638 { 639 $$ = new ExpressionNode( build_pfieldSel( $1, *$3 == "0" || *$3 == "1" ? build_constantInteger( *$3 ) : build_varref( $3 ) ) ); 640 } 643 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 641 644 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 642 645 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } … … 1137 1140 | FOR '(' push for_control_expression ')' statement pop 1138 1141 { $$ = new StatementNode( build_for( $4, $6 ) ); } 1142 | FOR '(' ')' statement // CFA => for ( ;; ) 1143 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), $4 ) ); } 1139 1144 ; 1140 1145 1141 1146 for_control_expression: 1142 comma_expression_opt // CFA 1143 { 1144 if ( ! $1 ) { // => for ( ;; ) 1145 $$ = new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ); 1146 } else { 1147 $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1148 OperKinds::LThan, $1->clone(), forInc( OperKinds::LThan ) ); 1149 } // if 1150 } 1147 comma_expression // CFA 1148 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1149 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1151 1150 | constant_expression inclexcl constant_expression // CFA 1152 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, forInc( $2) ); }1151 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1153 1152 | constant_expression inclexcl constant_expression '~' constant_expression // CFA 1154 1153 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); } 1155 | comma_expression_opt ';' comma_expression // CFA 1156 { 1157 if ( ! $1 ) { 1158 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr; 1159 } else if ( ! $3 ) { 1160 SemanticError( yylloc, "Missing loop range." ); $$ = nullptr; 1161 } else { 1162 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) { 1163 $$ = forCtrl( $3, new string( identifier->name ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1164 OperKinds::LThan, $3->clone(), forInc( OperKinds::LThan ) ); 1165 } else { 1166 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr; 1167 } // if 1168 } // if 1169 } 1170 | comma_expression_opt ';' constant_expression inclexcl constant_expression // CFA 1171 { 1172 if ( ! $1 ) { 1173 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr; 1174 } else { 1175 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) { 1176 $$ = forCtrl( $3, new string( identifier->name ), $3->clone(), $4, $5, forInc( $4 ) ); 1177 } else { 1178 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr; 1179 } // if 1180 } // if 1181 } 1182 | comma_expression_opt ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA 1183 { 1184 if ( ! $1 ) { 1185 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr; 1186 } else { 1187 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) { 1188 $$ = forCtrl( $3, new string( identifier->name ), $3->clone(), $4, $5, $7 ); 1189 } else { 1190 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr; 1191 } // if 1192 } // if 1193 } 1194 | comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt 1154 | comma_expression ';' comma_expression // CFA 1155 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1156 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1157 | comma_expression ';' constant_expression inclexcl constant_expression // CFA 1158 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1159 | comma_expression ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA 1160 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1161 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1195 1162 { $$ = new ForCtrl( $1, $3, $5 ); } 1163 | ';' comma_expression_opt ';' comma_expression_opt 1164 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); } 1196 1165 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1197 1166 { $$ = new ForCtrl( $1, $2, $4 ); } … … 1855 1824 1856 1825 indirect_type: 1857 TYPEOF '(' type ')' // GCC: typeof( x) y;1826 TYPEOF '(' type ')' // GCC: typeof( x ) y; 1858 1827 { $$ = $3; } 1859 | TYPEOF '(' comma_expression ')' // GCC: typeof( a+b) y;1828 | TYPEOF '(' comma_expression ')' // GCC: typeof( a+b ) y; 1860 1829 { $$ = DeclarationNode::newTypeof( $3 ); } 1861 | ATTR_TYPEGENname '(' type ')' // CFA: e.g., @type(x) y; 1830 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 1831 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 1832 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 1833 { $$ = DeclarationNode::newTypeof( $3, true ); } 1834 | ATTR_TYPEGENname '(' type ')' // CFA: e.g., @type( x ) y; 1862 1835 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1863 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type( a+b) y;1836 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type( a+b ) y; 1864 1837 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1865 1838 | ZERO_T // CFA -
src/ResolvExpr/AlternativeFinder.cc
r1f690b3 r90cfc16 10 10 // Created On : Sat May 16 23:52:08 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 17 11:19:39201813 // Update Count : 3 312 // Last Modified On : Thu Nov 1 21:00:56 2018 13 // Update Count : 34 14 14 // 15 15 … … 1344 1344 /// Gets name from untyped member expression (member must be NameExpr) 1345 1345 const std::string& get_member_name( UntypedMemberExpr *memberExpr ) { 1346 if ( dynamic_cast< ConstantExpr * >( memberExpr->get_member() ) ) { 1347 SemanticError( memberExpr, "Indexed access to struct fields unsupported: " ); 1348 } // if 1346 1349 NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() ); 1347 1350 assert( nameExpr ); -
src/ResolvExpr/ResolveTypeof.cc
r1f690b3 r90cfc16 67 67 std::cerr << std::endl; 68 68 #endif 69 if ( typeofType->expr ) { 69 // pass on null expression 70 if ( ! typeofType->expr ) return typeofType; 71 72 bool isBasetypeof = typeofType->is_basetypeof; 73 auto oldQuals = typeofType->get_qualifiers().val; 74 75 Type* newType; 76 if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) { 77 // typeof wrapping type 78 newType = tyExpr->type; 79 tyExpr->type = nullptr; 80 delete tyExpr; 81 } else { 82 // typeof wrapping expression 70 83 Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer ); 71 84 assert( newExpr->result && ! newExpr->result->isVoid() ); 72 Type *newType = newExpr->result;85 newType = newExpr->result; 73 86 newExpr->result = nullptr; 74 87 delete typeofType; 75 88 delete newExpr; 76 return newType; 77 } // if 78 return typeofType; 89 } 90 91 // clear qualifiers for base, combine with typeoftype quals in any case 92 if ( isBasetypeof ) { 93 // replace basetypeof(<enum>) by int 94 if ( dynamic_cast<EnumInstType*>(newType) ) { 95 Type* newerType = 96 new BasicType{ newType->get_qualifiers(), BasicType::SignedInt, 97 newType->attributes }; 98 delete newType; 99 newType = newerType; 100 } 101 newType->get_qualifiers().val 102 = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals; 103 } else { 104 newType->get_qualifiers().val |= oldQuals; 105 } 106 107 return newType; 79 108 } 80 109 } // namespace ResolvExpr -
src/SynTree/Type.h
r1f690b3 r90cfc16 598 598 class TypeofType : public Type { 599 599 public: 600 Expression *expr; 601 602 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 600 Expression *expr; ///< expression to take the type of 601 bool is_basetypeof; ///< true iff is basetypeof type 602 603 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 604 TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 605 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 603 606 TypeofType( const TypeofType& ); 604 607 virtual ~TypeofType(); -
src/SynTree/TypeofType.cc
r1f690b3 r90cfc16 23 23 class Attribute; 24 24 25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), expr( expr ) { 26 } 25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, 26 const std::list< Attribute * > & attributes ) 27 : Type( tq, attributes ), expr( expr ), is_basetypeof(false) {} 27 28 28 TypeofType::TypeofType( const TypeofType &other ) : Type( other ), expr( maybeClone( other.expr ) ) { 29 } 29 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, bool is_basetypeof, 30 const std::list< Attribute * > & attributes ) 31 : Type( tq, attributes ), expr( expr ), is_basetypeof( is_basetypeof ) {} 32 33 TypeofType::TypeofType( const TypeofType &other ) 34 : Type( other ), expr( maybeClone( other.expr ) ), is_basetypeof( other.is_basetypeof ) {} 30 35 31 36 TypeofType::~TypeofType() { … … 35 40 void TypeofType::print( std::ostream &os, Indenter indent ) const { 36 41 Type::print( os, indent ); 42 if ( is_basetypeof ) { os << "base-"; } 37 43 os << "type-of expression "; 38 44 if ( expr ) {
Note:
See TracChangeset
for help on using the changeset viewer.