Changeset 642bc83
- Timestamp:
- Aug 2, 2018, 11:09:03 AM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- 4285544e
- Parents:
- 3bbd012
- Location:
- src/SymTab
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Mangler.cc
r3bbd012 r642bc83 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 << nameSeparator; 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::voidType; 147 147 } 148 148 149 149 void Mangler::postvisit( BasicType * basicType ) { 150 150 printQualifiers( basicType ); 151 assert( basicType->get_kind() < numBtLetter);152 mangleName << btLetter[ basicType->get_kind() ];151 assert( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES ); 152 mangleName << Encoding::basicTypes[ basicType->get_kind() ]; 153 153 } 154 154 … … 156 156 printQualifiers( pointerType ); 157 157 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers 158 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << "P";158 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer; 159 159 maybeAccept( pointerType->base, *visitor ); 160 160 } … … 163 163 // TODO: encode dimension 164 164 printQualifiers( arrayType ); 165 mangleName << "A0";165 mangleName << Encoding::array << "0"; 166 166 maybeAccept( arrayType->base, *visitor ); 167 167 } … … 188 188 void Mangler::postvisit( FunctionType * functionType ) { 189 189 printQualifiers( functionType ); 190 mangleName << "F";190 mangleName << Encoding::function; 191 191 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters, 192 192 // since qualifiers on outermost parameter type do not differentiate function types, e.g., … … 195 195 inFunctionType = true; 196 196 std::list< Type* > returnTypes = getTypes( functionType->returnVals ); 197 if (returnTypes.empty()) mangleName << "v";197 if (returnTypes.empty()) mangleName << Encoding::voidType; 198 198 else acceptAll( returnTypes, *visitor ); 199 199 mangleName << "_"; … … 206 206 printQualifiers( refType ); 207 207 208 mangleName << ( refType->name.length() + prefix.length() ) << prefix<< refType->name;208 mangleName << prefix << refType->name.length() << refType->name; 209 209 210 210 if ( mangleGenericParams ) { … … 261 261 void Mangler::postvisit( TraitInstType * inst ) { 262 262 printQualifiers( inst ); 263 mangleName << "_Y" << inst->name << "_";263 mangleName << inst->name.size() << inst->name; 264 264 } 265 265 266 266 void Mangler::postvisit( TupleType * tupleType ) { 267 267 printQualifiers( tupleType ); 268 mangleName << "T";268 mangleName << Encoding::tuple << tupleType->types.size(); 269 269 acceptAll( tupleType->types, *visitor ); 270 mangleName << "_";271 270 } 272 271 273 272 void Mangler::postvisit( VarArgsType * varArgsType ) { 274 273 printQualifiers( varArgsType ); 275 mangleName << "VARGS"; 274 static const std::string vargs = "__builtin_va_list"; 275 mangleName << vargs.size() << vargs; 276 276 } 277 277 278 278 void Mangler::postvisit( ZeroType * ) { 279 mangleName << "Z";279 mangleName << Encoding::zero; 280 280 } 281 281 282 282 void Mangler::postvisit( OneType * ) { 283 mangleName << "O";283 mangleName << Encoding::one; 284 284 } 285 285 286 286 void Mangler::postvisit( QualifiedType * qualType ) { 287 bool inqual = inQualifiedType; 288 if (! inqual ) { 289 // N marks the start of a qualified type 290 inQualifiedType = true; 291 mangleName << Encoding::qualifiedTypeStart; 292 } 287 293 maybeAccept( qualType->parent, *visitor ); 288 mangleName << "__";289 294 maybeAccept( qualType->child, *visitor ); 295 if ( ! inqual ) { 296 // E marks the end of a qualified type 297 inQualifiedType = false; 298 mangleName << Encoding::qualifiedTypeEnd; 299 } 290 300 } 291 301 … … 339 349 // these qualifiers do not distinguish the outermost type of a function parameter 340 350 if ( type->get_const() ) { 341 mangleName << "C";351 mangleName << Encoding::qualifiers.at(Type::Const); 342 352 } // if 343 353 if ( type->get_volatile() ) { 344 mangleName << "V";354 mangleName << Encoding::qualifiers.at(Type::Volatile); 345 355 } // if 346 356 // Removed due to restrict not affecting function compatibility in GCC … … 349 359 // } // if 350 360 if ( type->get_atomic() ) { 351 mangleName << "A";361 mangleName << Encoding::qualifiers.at(Type::Atomic); 352 362 } // if 353 363 } 354 364 if ( type->get_mutex() ) { 355 mangleName << "M";365 mangleName << Encoding::qualifiers.at(Type::Mutex); 356 366 } // if 357 367 if ( type->get_lvalue() ) { 358 368 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues 359 mangleName << "L";369 mangleName << Encoding::qualifiers.at(Type::Lvalue); 360 370 } 361 371 -
src/SymTab/Mangler.h
r3bbd012 r642bc83 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 { … … 34 41 std::string mangleConcrete( Type* ty ); 35 42 36 extern const char *btLetter[]; 37 extern const int numBtLetter; 38 extern const std::map<int, const char *> qualifierLetter; 39 extern const std::string nameSeparator; 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 voidType; 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 autogen; 60 extern const std::string intrinsic; 61 }; 40 62 } // Mangler 41 63 } // SymTab -
src/SymTab/ManglerCommon.cc
r3bbd012 r642bc83 19 19 namespace SymTab { 20 20 namespace Mangler { 21 const char * btLetter[] = { 22 "b", // Bool 23 "c", // Char 24 "Sc", // SignedChar 25 "Uc", // UnsignedChar 26 "s", // ShortSignedInt 27 "Us", // ShortUnsignedInt 28 "i", // SignedInt 29 "Ui", // UnsignedInt 30 "l", // LongSignedInt 31 "Ul", // LongUnsignedInt 32 "q", // LongLongSignedInt 33 "Uq", // LongLongUnsignedInt 34 "f", // Float 35 "d", // Double 36 "r", // LongDouble 37 "Xf", // FloatComplex 38 "Xd", // DoubleComplex 39 "Xr", // LongDoubleComplex 40 "If", // FloatImaginary 41 "Id", // DoubleImaginary 42 "Ir", // LongDoubleImaginary 43 "w", // SignedInt128 44 "Uw", // UnsignedInt128 45 "x", // Float80 46 "y", // Float128 47 }; 48 const int numBtLetter = sizeof(btLetter)/sizeof(btLetter[0]); 49 static_assert( 50 numBtLetter == BasicType::NUMBER_OF_BASIC_TYPES, 51 "Each basic type kind should have a corresponding mangler letter" 52 ); 21 namespace Encoding { 22 const std::string manglePrefix = "_X"; 53 23 54 const std::map<int, const char *> qualifierLetter = { 55 { Type::Const, "C" }, 56 { Type::Volatile, "V" }, 57 { Type::Atomic, "A" }, // A = Atomic, A0 = Array and forall parameter... 58 { Type::Mutex, "M" }, 59 { Type::Lvalue, "L" }, 60 }; 24 const std::string basicTypes[] = { 25 "b", // Bool 26 "c", // Char 27 "a", // SignedChar 28 "h", // UnsignedChar 29 "s", // ShortSignedInt 30 "t", // ShortUnsignedInt 31 "i", // SignedInt 32 "j", // UnsignedInt 33 "l", // LongSignedInt 34 "m", // LongUnsignedInt 35 "x", // LongLongSignedInt 36 "y", // LongLongUnsignedInt 37 "f", // Float 38 "d", // Double 39 "e", // LongDouble 40 "Cf", // FloatComplex 41 "Cd", // DoubleComplex 42 "Ce", // LongDoubleComplex 43 // Note: imaginary is not an overloadable type in C++ 44 "If", // FloatImaginary 45 "Id", // DoubleImaginary 46 "Ie", // LongDoubleImaginary 47 "n", // SignedInt128 48 "o", // UnsignedInt128 49 "Dq", // Float80 -- TODO: itanium says Float80 and LongDouble both encode to "e", but doing this causes problems with constructing long double, because the cost tables are incorrect 50 "g", // Float128 51 // "z", // ellipsis 52 // "Dd" // # IEEE 754r decimal floating point (64 bits) 53 // "De" // # IEEE 754r decimal floating point (128 bits) 54 // "Df" // # IEEE 754r decimal floating point (32 bits) 55 // "Dh" // # IEEE 754r half-precision floating point (16 bits) 56 // "DF"N_ // # ISO/IEC TS 18661 binary floating point type _FloatN (N bits) 57 // "Di" // char32_t 58 // "Ds" // char16_t 59 }; 60 static_assert( 61 sizeof(basicTypes)/sizeof(basicTypes[0]) == BasicType::NUMBER_OF_BASIC_TYPES, 62 "Each basic type kind should have a corresponding mangler letter" 63 ); 61 64 62 const std::string nameSeparator = "__cfa__"; 65 const std::map<int, std::string> qualifiers = { 66 { Type::Const, "C" }, 67 { Type::Volatile, "V" }, 68 { Type::Atomic, "A" }, // A = Atomic, A0 = Array and forall parameter... 69 { Type::Mutex, "M" }, 70 { Type::Lvalue, "L" }, 71 }; 72 73 const std::string voidType = "v"; 74 const std::string zero = "Z"; 75 const std::string one = "O"; 76 77 const std::string function = "F"; 78 const std::string tuple = "T"; 79 const std::string pointer = "P"; 80 const std::string array = "A"; 81 const std::string qualifiedTypeStart = "N"; 82 const std::string qualifiedTypeEnd = "E"; 83 84 const std::string autogen = "autogen__"; 85 const std::string intrinsic = "intrinsic__"; 86 } // namespace Encoding 63 87 } // namespace Mangler 64 88 } // namespace SymTab
Note: See TracChangeset
for help on using the changeset viewer.