- Timestamp:
- Apr 12, 2021, 5:16:45 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:
- a1b9bc3
- Parents:
- 56c8b86 (diff), 73f4d08 (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:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.cpp
r56c8b86 rfe63ae6 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
r56c8b86 rfe63ae6 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/Concurrency/Keywords.cc
r56c8b86 rfe63ae6 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 }; … … 392 399 else if ( !except_decl && exception_name == decl->name && decl->body ) { 393 400 except_decl = decl; 401 } 402 else if ( !typeid_decl && typeid_name == decl->name && decl->body ) { 403 typeid_decl = decl; 394 404 } 395 405 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) { … … 448 458 if( !dtor_decl ) SemanticError( decl, context_error ); 449 459 450 addVtableForward( decl ); 460 if ( !exception_name.empty() ) { 461 if( !typeid_decl ) SemanticError( decl, context_error ); 462 if( !vtable_decl ) SemanticError( decl, context_error ); 463 464 addTypeId( decl ); 465 addVtableForward( decl ); 466 } 451 467 FunctionDecl * func = forwardDeclare( decl ); 452 468 ObjectDecl * field = addField( decl ); … … 454 470 } 455 471 472 void ConcurrentSueKeyword::addTypeId( StructDecl * decl ) { 473 assert( typeid_decl ); 474 StructInstType typeid_type( Type::Const, typeid_decl ); 475 typeid_type.parameters.push_back( new TypeExpr( 476 new StructInstType( noQualifiers, decl ) 477 ) ); 478 declsToAddBefore.push_back( Virtual::makeTypeIdInstance( &typeid_type ) ); 479 } 480 456 481 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 } 482 assert( vtable_decl ); 483 std::list< Expression * > poly_args = { 484 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 485 }; 486 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 487 vtable_decl->makeInst( poly_args ), 488 except_decl->makeInst( poly_args ) 489 ) ); 490 declsToAddBefore.push_back( Virtual::makeVtableForward( 491 vtable_decl->makeInst( move( poly_args ) ) ) ); 471 492 } 472 493 -
src/SynTree/Constant.cc
r56c8b86 rfe63ae6 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
r56c8b86 rfe63ae6 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/Virtual/ExpandCasts.cc
r56c8b86 rfe63ae6 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
r56c8b86 rfe63ae6 10 10 // Created On : Mon Aug 31 11:11:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T ue Sep 3 14:56:00 202013 // Update Count : 012 // Last Modified On : Thr Apr 8 15:51:00 2021 13 // Update Count : 1 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"; 38 } 39 40 std::string baseTypeName( std::string const & vtable_type_name ) { 41 return vtable_type_name.substr(0, vtable_type_name.size() - 7); 26 42 } 27 43 … … 81 97 inits.push_back( 82 98 new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) ); 99 } else if ( std::string( "__cfavir_typeid" ) == field->name ) { 100 std::string const & baseType = baseTypeName( vtableType->name ); 101 std::string const & typeId = typeIdName( baseType ); 102 inits.push_back( new SingleInit( new AddressExpr( new NameExpr( typeId ) ) ) ); 83 103 } else if ( std::string( "size" ) == field->name ) { 84 104 inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) ); … … 147 167 } 148 168 169 ObjectDecl * makeTypeIdForward() { 170 return nullptr; 149 171 } 172 173 Attribute * linkonce( const std::string & subsection ) { 174 const std::string section = ".gnu.linkonce." + subsection; 175 return new Attribute( "section", { 176 new ConstantExpr( Constant::from_string( section ) ), 177 } ); 178 } 179 180 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) { 181 assert( typeIdType ); 182 StructInstType * type = typeIdType->clone(); 183 type->tq.is_const = true; 184 std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name ); 185 return new ObjectDecl( 186 typeid_name, 187 noStorageClasses, 188 LinkageSpec::Cforall, 189 /* bitfieldWidth */ nullptr, 190 type, 191 new ListInit( { new SingleInit( 192 new AddressExpr( new NameExpr( "__cfatid_exception_t" ) ) 193 ) } ), 194 { linkonce( typeid_name ) }, 195 noFuncSpecifiers 196 ); 197 } 198 199 } -
src/Virtual/Tables.h
r56c8b86 rfe63ae6 10 10 // Created On : Mon Aug 31 11:07:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T ue Sep 1 14:29:00 202013 // Update Count : 012 // Last Modified On : Thr Apr 8 15:55:00 2021 13 // Update Count : 1 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 ); … … 50 52 */ 51 53 54 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ); 55 /* Build an instance of the type-id from the type of the type-id. 56 * TODO: Should take the parent type. Currently locked to the exception_t. 57 */ 58 52 59 }
Note:
See TracChangeset
for help on using the changeset viewer.