Changeset cdbab55 for src/SymTab
- Timestamp:
- Aug 21, 2018, 2:24:29 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:
- 2a6292d
- Parents:
- 2b79a70 (diff), efa8b6a (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/SymTab
- Files:
-
- 3 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Mangler.cc
r2b79a70 rcdbab55 73 73 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 74 74 bool inFunctionType = false; ///< Include type qualifiers if false. 75 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type 75 76 76 77 void mangleDecl( DeclarationWithType *declaration ); … … 110 111 isTopLevel = false; 111 112 } // if 112 mangleName << "__";113 mangleName << Encoding::manglePrefix; 113 114 CodeGen::OperatorInfo opInfo; 114 115 if ( operatorLookup( declaration->get_name(), opInfo ) ) { 115 mangleName << opInfo.outputName ;116 mangleName << opInfo.outputName.size() << opInfo.outputName; 116 117 } else { 117 mangleName << declaration->get_name(); 118 } // if 119 mangleName << "__"; 118 mangleName << declaration->name.size() << declaration->name; 119 } // if 120 120 maybeAccept( declaration->get_type(), *visitor ); 121 121 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) { … … 123 123 // so they need a different name mangling 124 124 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) { 125 mangleName << "autogen__";125 mangleName << Encoding::autogen; 126 126 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) { 127 mangleName << "intrinsic__";127 mangleName << Encoding::intrinsic; 128 128 } else { 129 129 // if we add another kind of overridable function, this has to change … … 144 144 void Mangler::postvisit( VoidType * voidType ) { 145 145 printQualifiers( voidType ); 146 mangleName << "v";146 mangleName << Encoding::void_t; 147 147 } 148 148 149 149 void Mangler::postvisit( BasicType * basicType ) { 150 static const char *btLetter[] = {151 "b", // Bool152 "c", // Char153 "Sc", // SignedChar154 "Uc", // UnsignedChar155 "s", // ShortSignedInt156 "Us", // ShortUnsignedInt157 "i", // SignedInt158 "Ui", // UnsignedInt159 "l", // LongSignedInt160 "Ul", // LongUnsignedInt161 "q", // LongLongSignedInt162 "Uq", // LongLongUnsignedInt163 "f", // Float164 "d", // Double165 "r", // LongDouble166 "Xf", // FloatComplex167 "Xd", // DoubleComplex168 "Xr", // LongDoubleComplex169 "If", // FloatImaginary170 "Id", // DoubleImaginary171 "Ir", // LongDoubleImaginary172 "w", // SignedInt128173 "Uw", // UnsignedInt128174 "x", // Float80175 "y", // Float128176 };177 static_assert(178 sizeof(btLetter)/sizeof(btLetter[0]) == BasicType::NUMBER_OF_BASIC_TYPES,179 "Each basic type kind should have a corresponding mangler letter"180 );181 182 150 printQualifiers( basicType ); 183 assert ( basicType->get_kind() < sizeof(btLetter)/sizeof(btLetter[0]) );184 mangleName << btLetter[ basicType->get_kind() ];151 assertf( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind() ); 152 mangleName << Encoding::basicTypes[ basicType->get_kind() ]; 185 153 } 186 154 … … 188 156 printQualifiers( pointerType ); 189 157 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers 190 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";158 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer; 191 159 maybeAccept( pointerType->base, *visitor ); 192 160 } … … 195 163 // TODO: encode dimension 196 164 printQualifiers( arrayType ); 197 mangleName << "A0";165 mangleName << Encoding::array << "0"; 198 166 maybeAccept( arrayType->base, *visitor ); 199 167 } … … 220 188 void Mangler::postvisit( FunctionType * functionType ) { 221 189 printQualifiers( functionType ); 222 mangleName << "F";190 mangleName << Encoding::function; 223 191 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters, 224 192 // since qualifiers on outermost parameter type do not differentiate function types, e.g., … … 227 195 inFunctionType = true; 228 196 std::list< Type* > returnTypes = getTypes( functionType->returnVals ); 229 acceptAll( returnTypes, *visitor ); 197 if (returnTypes.empty()) mangleName << Encoding::void_t; 198 else acceptAll( returnTypes, *visitor ); 230 199 mangleName << "_"; 231 200 std::list< Type* > paramTypes = getTypes( functionType->parameters ); … … 237 206 printQualifiers( refType ); 238 207 239 mangleName << ( refType->name.length() + prefix.length() ) << prefix<< refType->name;208 mangleName << prefix << refType->name.length() << refType->name; 240 209 241 210 if ( mangleGenericParams ) { … … 254 223 255 224 void Mangler::postvisit( StructInstType * aggregateUseType ) { 256 mangleRef( aggregateUseType, "s");225 mangleRef( aggregateUseType, Encoding::struct_t ); 257 226 } 258 227 259 228 void Mangler::postvisit( UnionInstType * aggregateUseType ) { 260 mangleRef( aggregateUseType, "u");229 mangleRef( aggregateUseType, Encoding::union_t ); 261 230 } 262 231 263 232 void Mangler::postvisit( EnumInstType * aggregateUseType ) { 264 mangleRef( aggregateUseType, "e");233 mangleRef( aggregateUseType, Encoding::enum_t ); 265 234 } 266 235 … … 268 237 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 269 238 if ( varNum == varNums.end() ) { 270 mangleRef( typeInst, "t");239 mangleRef( typeInst, Encoding::type ); 271 240 } else { 272 241 printQualifiers( typeInst ); 273 std::ostringstream numStream; 274 numStream << varNum->second.first; 275 switch ( (TypeDecl::Kind )varNum->second.second ) { 276 case TypeDecl::Dtype: 277 mangleName << "d"; 278 break; 279 case TypeDecl::Ftype: 280 mangleName << "f"; 281 break; 282 case TypeDecl::Ttype: 283 mangleName << "tVARGS"; 284 break; 285 default: 286 assert( false ); 287 } // switch 288 mangleName << numStream.str(); 242 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g. 243 // forall(dtype T) void f(T); 244 // forall(dtype S) void f(S); 245 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they 246 // are first found and prefixing with the appropriate encoding for the type class. 247 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second ); 248 mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first; 289 249 } // if 290 250 } … … 292 252 void Mangler::postvisit( TraitInstType * inst ) { 293 253 printQualifiers( inst ); 294 mangleName << "_Y" << inst->name << "_";254 mangleName << inst->name.size() << inst->name; 295 255 } 296 256 297 257 void Mangler::postvisit( TupleType * tupleType ) { 298 258 printQualifiers( tupleType ); 299 mangleName << "T";259 mangleName << Encoding::tuple << tupleType->types.size(); 300 260 acceptAll( tupleType->types, *visitor ); 301 mangleName << "_";302 261 } 303 262 304 263 void Mangler::postvisit( VarArgsType * varArgsType ) { 305 264 printQualifiers( varArgsType ); 306 mangleName << "VARGS"; 265 static const std::string vargs = "__builtin_va_list"; 266 mangleName << Encoding::type << vargs.size() << vargs; 307 267 } 308 268 309 269 void Mangler::postvisit( ZeroType * ) { 310 mangleName << "Z";270 mangleName << Encoding::zero; 311 271 } 312 272 313 273 void Mangler::postvisit( OneType * ) { 314 mangleName << "O";274 mangleName << Encoding::one; 315 275 } 316 276 317 277 void Mangler::postvisit( QualifiedType * qualType ) { 278 bool inqual = inQualifiedType; 279 if (! inqual ) { 280 // N marks the start of a qualified type 281 inQualifiedType = true; 282 mangleName << Encoding::qualifiedTypeStart; 283 } 318 284 maybeAccept( qualType->parent, *visitor ); 319 mangleName << "__";320 285 maybeAccept( qualType->child, *visitor ); 286 if ( ! inqual ) { 287 // E marks the end of a qualified type 288 inQualifiedType = false; 289 mangleName << Encoding::qualifiedTypeEnd; 290 } 321 291 } 322 292 323 293 void Mangler::postvisit( TypeDecl * decl ) { 324 static const char *typePrefix[] = { "BT", "BD", "BF" }; 325 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name; 294 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 295 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. 296 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply 297 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed 298 // aside from the assert false. 299 assertf(false, "Mangler should not visit typedecl: %s", toCString(decl)); 300 assertf( decl->get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind() ); 301 mangleName << Encoding::typeVariables[ decl->get_kind() ] << ( decl->name.length() ) << decl->name; 326 302 } 327 303 … … 337 313 if ( ! type->get_forall().empty() ) { 338 314 std::list< std::string > assertionNames; 339 int tcount = 0, dcount = 0, fcount = 0, vcount = 0;340 mangleName << "A";315 int dcount = 0, fcount = 0, vcount = 0, acount = 0; 316 mangleName << Encoding::forall; 341 317 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { 342 318 switch ( (*i)->get_kind() ) { … … 361 337 (*assert)->accept( sub_mangler ); 362 338 assertionNames.push_back( sub_mangler.pass.mangleName.str() ); 339 acount++; 363 340 } // for 364 341 } // for 365 mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";342 mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_"; 366 343 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 367 344 mangleName << "_"; … … 370 347 // these qualifiers do not distinguish the outermost type of a function parameter 371 348 if ( type->get_const() ) { 372 mangleName << "C";349 mangleName << Encoding::qualifiers.at(Type::Const); 373 350 } // if 374 351 if ( type->get_volatile() ) { 375 mangleName << "V";352 mangleName << Encoding::qualifiers.at(Type::Volatile); 376 353 } // if 377 354 // Removed due to restrict not affecting function compatibility in GCC … … 380 357 // } // if 381 358 if ( type->get_atomic() ) { 382 mangleName << "A";359 mangleName << Encoding::qualifiers.at(Type::Atomic); 383 360 } // if 384 361 } 385 362 if ( type->get_mutex() ) { 386 mangleName << "M";363 mangleName << Encoding::qualifiers.at(Type::Mutex); 387 364 } // if 388 365 if ( type->get_lvalue() ) { 389 366 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues 390 mangleName << "L";367 mangleName << Encoding::qualifiers.at(Type::Lvalue); 391 368 } 392 369 -
src/SymTab/Mangler.h
r2b79a70 rcdbab55 24 24 #include "SynTree/Visitor.h" // for Visitor, maybeAccept 25 25 26 // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling 27 // The CFA name mangling scheme is based closely on the itanium C++ name mangling scheme, with the following key differences: 28 // * Variable names are also mangled to include type information, not just functions 29 // * CFA does not have template expansion, so the rules for function specialization do not apply. 30 // * CFA instead has to handle type parameters and assertion parameters. 31 // * Currently name compression is not implemented. 32 26 33 namespace SymTab { 27 34 namespace Mangler { … … 33 40 /// Mangle ignoring generic type parameters 34 41 std::string mangleConcrete( Type* ty ); 42 43 namespace Encoding { 44 extern const std::string manglePrefix; 45 extern const std::string basicTypes[]; 46 extern const std::map<int, std::string> qualifiers; 47 48 extern const std::string void_t; 49 extern const std::string zero; 50 extern const std::string one; 51 52 extern const std::string function; 53 extern const std::string tuple; 54 extern const std::string pointer; 55 extern const std::string array; 56 extern const std::string qualifiedTypeStart; 57 extern const std::string qualifiedTypeEnd; 58 59 extern const std::string forall; 60 extern const std::string typeVariables[]; 61 62 extern const std::string struct_t; 63 extern const std::string union_t; 64 extern const std::string enum_t; 65 extern const std::string type; 66 67 extern const std::string autogen; 68 extern const std::string intrinsic; 69 }; 35 70 } // Mangler 36 71 } // SymTab 72 73 extern "C" { 74 char * cforall_demangle(const char *, int); 75 } 37 76 38 77 // Local Variables: // -
src/SymTab/module.mk
r2b79a70 rcdbab55 17 17 SRC += SymTab/Indexer.cc \ 18 18 SymTab/Mangler.cc \ 19 SymTab/ManglerCommon.cc \ 19 20 SymTab/Validate.cc \ 20 21 SymTab/FixFunction.cc \
Note:
See TracChangeset
for help on using the changeset viewer.