| [0dd3a2f] | 1 | //
 | 
|---|
 | 2 | // Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
 | 
|---|
 | 3 | //
 | 
|---|
 | 4 | // The contents of this file are covered under the licence agreement in the
 | 
|---|
 | 5 | // file "LICENCE" distributed with Cforall.
 | 
|---|
 | 6 | //
 | 
|---|
| [8c49c0e] | 7 | // Mangler.cc --
 | 
|---|
| [0dd3a2f] | 8 | //
 | 
|---|
 | 9 | // Author           : Richard C. Bilson
 | 
|---|
 | 10 | // Created On       : Sun May 17 21:40:29 2015
 | 
|---|
| [0026d67] | 11 | // Last Modified By : Andrew Beach
 | 
|---|
 | 12 | // Last Modified On : Fri Oct 21 16:18:00 2022
 | 
|---|
 | 13 | // Update Count     : 75
 | 
|---|
| [0dd3a2f] | 14 | //
 | 
|---|
| [30f9072] | 15 | #include "Mangler.h"
 | 
|---|
| [0dd3a2f] | 16 | 
 | 
|---|
| [ff5caaf] | 17 | #include <algorithm>                     // for copy, transform
 | 
|---|
 | 18 | #include <cassert>                       // for assert, assertf
 | 
|---|
 | 19 | #include <functional>                    // for const_mem_fun_t, mem_fun
 | 
|---|
 | 20 | #include <iterator>                      // for ostream_iterator, back_insert_ite...
 | 
|---|
 | 21 | #include <list>                          // for _List_iterator, list, _List_const...
 | 
|---|
 | 22 | #include <string>                        // for string, char_traits, operator<<
 | 
|---|
 | 23 | 
 | 
|---|
| [a137d5a] | 24 | #include "AST/Pass.hpp"
 | 
|---|
| [ff5caaf] | 25 | #include "CodeGen/OperatorTable.h"       // for OperatorInfo, operatorLookup
 | 
|---|
| [9feb34b] | 26 | #include "Common/ToString.hpp"           // for toCString
 | 
|---|
| [ff5caaf] | 27 | #include "Common/SemanticError.h"        // for SemanticError
 | 
|---|
| [0dd3a2f] | 28 | 
 | 
|---|
| [d76c588] | 29 | namespace Mangle {
 | 
|---|
| [1867c96] | 30 | 
 | 
|---|
| [b0845f9] | 31 | namespace {
 | 
|---|
 | 32 | 
 | 
|---|
 | 33 | /// Mangles names to a unique C identifier.
 | 
|---|
 | 34 | struct Mangler : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler>, public ast::WithGuards {
 | 
|---|
 | 35 |         Mangler( Mangle::Mode mode );
 | 
|---|
 | 36 |         Mangler( const Mangler & ) = delete;
 | 
|---|
 | 37 | 
 | 
|---|
 | 38 |         void previsit( const ast::Node * ) { visit_children = false; }
 | 
|---|
 | 39 | 
 | 
|---|
 | 40 |         void postvisit( const ast::ObjectDecl * declaration );
 | 
|---|
 | 41 |         void postvisit( const ast::FunctionDecl * declaration );
 | 
|---|
 | 42 |         void postvisit( const ast::TypeDecl * declaration );
 | 
|---|
 | 43 | 
 | 
|---|
 | 44 |         void postvisit( const ast::VoidType * voidType );
 | 
|---|
 | 45 |         void postvisit( const ast::BasicType * basicType );
 | 
|---|
 | 46 |         void postvisit( const ast::PointerType * pointerType );
 | 
|---|
 | 47 |         void postvisit( const ast::ArrayType * arrayType );
 | 
|---|
 | 48 |         void postvisit( const ast::ReferenceType * refType );
 | 
|---|
 | 49 |         void postvisit( const ast::FunctionType * functionType );
 | 
|---|
 | 50 |         void postvisit( const ast::StructInstType * aggregateUseType );
 | 
|---|
 | 51 |         void postvisit( const ast::UnionInstType * aggregateUseType );
 | 
|---|
 | 52 |         void postvisit( const ast::EnumInstType * aggregateUseType );
 | 
|---|
 | 53 |         void postvisit( const ast::TypeInstType * aggregateUseType );
 | 
|---|
 | 54 |         void postvisit( const ast::TraitInstType * inst );
 | 
|---|
 | 55 |         void postvisit( const ast::TupleType * tupleType );
 | 
|---|
 | 56 |         void postvisit( const ast::VarArgsType * varArgsType );
 | 
|---|
 | 57 |         void postvisit( const ast::ZeroType * zeroType );
 | 
|---|
 | 58 |         void postvisit( const ast::OneType * oneType );
 | 
|---|
 | 59 |         void postvisit( const ast::QualifiedType * qualType );
 | 
|---|
| [af746cc] | 60 |         void postvisit( const ast::EnumAttrType * posType );
 | 
|---|
| [0522ebe] | 61 | 
 | 
|---|
| [b0845f9] | 62 |         /// The result is the current constructed mangled name.
 | 
|---|
 | 63 |         std::string result() const { return mangleName; }
 | 
|---|
 | 64 | private:
 | 
|---|
 | 65 |         std::string mangleName;         ///< Mangled name being constructed
 | 
|---|
 | 66 |         typedef std::map< std::string, std::pair< int, int > > VarMapType;
 | 
|---|
 | 67 |         VarMapType varNums;             ///< Map of type variables to indices
 | 
|---|
 | 68 |         int nextVarNum;                 ///< Next type variable index
 | 
|---|
 | 69 |         bool isTopLevel;                ///< Is the Mangler at the top level
 | 
|---|
 | 70 |         bool mangleOverridable;         ///< Specially mangle overridable built-in methods
 | 
|---|
 | 71 |         bool typeMode;                  ///< Produce a unique mangled name for a type
 | 
|---|
 | 72 |         bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
 | 
|---|
 | 73 |         bool inFunctionType = false;    ///< Include type qualifiers if false.
 | 
|---|
 | 74 |         bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
 | 
|---|
 | 75 | 
 | 
|---|
 | 76 | private:
 | 
|---|
 | 77 |         Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 | 
|---|
 | 78 |                 int nextVarNum, const VarMapType& varNums );
 | 
|---|
 | 79 |         friend class ast::Pass<Mangler>;
 | 
|---|
 | 80 | 
 | 
|---|
 | 81 | private:
 | 
|---|
 | 82 |         void mangleDecl( const ast::DeclWithType *declaration );
 | 
|---|
 | 83 |         void mangleRef( const ast::BaseInstType *refType, const std::string & prefix );
 | 
|---|
 | 84 | 
 | 
|---|
 | 85 |         void printQualifiers( const ast::Type *type );
 | 
|---|
 | 86 | }; // Mangler
 | 
|---|
 | 87 | 
 | 
|---|
 | 88 | Mangler::Mangler( Mangle::Mode mode )
 | 
|---|
 | 89 |         : nextVarNum( 0 ), isTopLevel( true ),
 | 
|---|
 | 90 |         mangleOverridable  ( ! mode.no_overrideable   ),
 | 
|---|
 | 91 |         typeMode           (   mode.type              ),
 | 
|---|
 | 92 |         mangleGenericParams( ! mode.no_generic_params ) {}
 | 
|---|
 | 93 | 
 | 
|---|
 | 94 | Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 | 
|---|
 | 95 |         int nextVarNum, const VarMapType& varNums )
 | 
|---|
 | 96 |         : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
 | 
|---|
 | 97 |         mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 | 
|---|
 | 98 |         mangleGenericParams( mangleGenericParams ) {}
 | 
|---|
 | 99 | 
 | 
|---|
 | 100 | void Mangler::mangleDecl( const ast::DeclWithType * decl ) {
 | 
|---|
 | 101 |         bool wasTopLevel = isTopLevel;
 | 
|---|
 | 102 |         if ( isTopLevel ) {
 | 
|---|
 | 103 |                 varNums.clear();
 | 
|---|
 | 104 |                 nextVarNum = 0;
 | 
|---|
 | 105 |                 isTopLevel = false;
 | 
|---|
 | 106 |         }
 | 
|---|
 | 107 |         mangleName += Encoding::manglePrefix;
 | 
|---|
 | 108 |         if ( auto opInfo = CodeGen::operatorLookup( decl->name ) ) {
 | 
|---|
 | 109 |                 mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
 | 
|---|
 | 110 |         } else {
 | 
|---|
 | 111 |                 mangleName += std::to_string( decl->name.size() ) + decl->name;
 | 
|---|
 | 112 |         }
 | 
|---|
 | 113 |         decl->get_type()->accept( *visitor );
 | 
|---|
 | 114 |         if ( mangleOverridable && decl->linkage.is_overrideable ) {
 | 
|---|
 | 115 |                 // want to be able to override autogenerated and intrinsic routines,
 | 
|---|
 | 116 |                 // so they need a different name mangling
 | 
|---|
 | 117 |                 if ( decl->linkage == ast::Linkage::AutoGen ) {
 | 
|---|
 | 118 |                         mangleName += Encoding::autogen;
 | 
|---|
 | 119 |                 } else if ( decl->linkage == ast::Linkage::Intrinsic ) {
 | 
|---|
 | 120 |                         mangleName += Encoding::intrinsic;
 | 
|---|
 | 121 |                 } else {
 | 
|---|
 | 122 |                         // if we add another kind of overridable function, this has to change
 | 
|---|
 | 123 |                         assert( false && "unknown overrideable linkage" );
 | 
|---|
| [1867c96] | 124 |                 }
 | 
|---|
| [b0845f9] | 125 |         }
 | 
|---|
 | 126 |         isTopLevel = wasTopLevel;
 | 
|---|
 | 127 | }
 | 
|---|
 | 128 | 
 | 
|---|
 | 129 | void Mangler::postvisit( const ast::ObjectDecl * decl ) {
 | 
|---|
 | 130 |         mangleDecl( decl );
 | 
|---|
 | 131 | }
 | 
|---|
 | 132 | 
 | 
|---|
 | 133 | void Mangler::postvisit( const ast::FunctionDecl * decl ) {
 | 
|---|
 | 134 |         mangleDecl( decl );
 | 
|---|
 | 135 | }
 | 
|---|
 | 136 | 
 | 
|---|
 | 137 | void Mangler::postvisit( const ast::VoidType * voidType ) {
 | 
|---|
 | 138 |         printQualifiers( voidType );
 | 
|---|
 | 139 |         mangleName += Encoding::void_t;
 | 
|---|
 | 140 | }
 | 
|---|
 | 141 | 
 | 
|---|
 | 142 | void Mangler::postvisit( const ast::BasicType * basicType ) {
 | 
|---|
 | 143 |         printQualifiers( basicType );
 | 
|---|
| [7a780ad] | 144 |         assertf( basicType->kind < ast::BasicKind::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
 | 
|---|
| [b0845f9] | 145 |         mangleName += Encoding::basicTypes[ basicType->kind ];
 | 
|---|
 | 146 | }
 | 
|---|
 | 147 | 
 | 
|---|
 | 148 | void Mangler::postvisit( const ast::PointerType * pointerType ) {
 | 
|---|
 | 149 |         printQualifiers( pointerType );
 | 
|---|
 | 150 |         // Mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers.
 | 
|---|
 | 151 |         if ( !pointerType->base.as<ast::FunctionType>() ) mangleName += Encoding::pointer;
 | 
|---|
 | 152 |         maybe_accept( pointerType->base.get(), *visitor );
 | 
|---|
 | 153 | }
 | 
|---|
 | 154 | 
 | 
|---|
 | 155 | void Mangler::postvisit( const ast::ArrayType * arrayType ) {
 | 
|---|
 | 156 |         // TODO: encode dimension
 | 
|---|
 | 157 |         printQualifiers( arrayType );
 | 
|---|
 | 158 |         mangleName += Encoding::array + "0";
 | 
|---|
 | 159 |         arrayType->base->accept( *visitor );
 | 
|---|
 | 160 | }
 | 
|---|
 | 161 | 
 | 
|---|
 | 162 | void Mangler::postvisit( const ast::ReferenceType * refType ) {
 | 
|---|
 | 163 |         // Don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
 | 
|---|
 | 164 |         // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
 | 
|---|
 | 165 |         // by pretending every reference type is a function parameter.
 | 
|---|
 | 166 |         GuardValue( inFunctionType ) = true;
 | 
|---|
 | 167 |         printQualifiers( refType );
 | 
|---|
 | 168 |         refType->base->accept( *visitor );
 | 
|---|
 | 169 | }
 | 
|---|
 | 170 | 
 | 
|---|
 | 171 | void Mangler::postvisit( const ast::FunctionType * functionType ) {
 | 
|---|
 | 172 |         printQualifiers( functionType );
 | 
|---|
 | 173 |         mangleName += Encoding::function;
 | 
|---|
 | 174 |         // Turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
 | 
|---|
 | 175 |         // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
 | 
|---|
 | 176 |         // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different.
 | 
|---|
 | 177 |         GuardValue( inFunctionType ) = true;
 | 
|---|
 | 178 |         if (functionType->returns.empty()) mangleName += Encoding::void_t;
 | 
|---|
 | 179 |         else accept_each( functionType->returns, *visitor );
 | 
|---|
 | 180 |         mangleName += "_";
 | 
|---|
 | 181 |         accept_each( functionType->params, *visitor );
 | 
|---|
 | 182 |         mangleName += "_";
 | 
|---|
 | 183 | }
 | 
|---|
 | 184 | 
 | 
|---|
 | 185 | void Mangler::mangleRef(
 | 
|---|
 | 186 |                 const ast::BaseInstType * refType, const std::string & prefix ) {
 | 
|---|
 | 187 |         printQualifiers( refType );
 | 
|---|
 | 188 | 
 | 
|---|
 | 189 |         mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
 | 
|---|
 | 190 | 
 | 
|---|
 | 191 |         if ( mangleGenericParams && ! refType->params.empty() ) {
 | 
|---|
 | 192 |                 mangleName += "_";
 | 
|---|
 | 193 |                 for ( const ast::Expr * param : refType->params ) {
 | 
|---|
 | 194 |                         auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
 | 
|---|
 | 195 |                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
 | 
|---|
 | 196 |                         paramType->type->accept( *visitor );
 | 
|---|
| [1867c96] | 197 |                 }
 | 
|---|
| [b0845f9] | 198 |                 mangleName += "_";
 | 
|---|
 | 199 |         }
 | 
|---|
 | 200 | }
 | 
|---|
 | 201 | 
 | 
|---|
 | 202 | void Mangler::postvisit( const ast::StructInstType * aggregateUseType ) {
 | 
|---|
 | 203 |         mangleRef( aggregateUseType, Encoding::struct_t );
 | 
|---|
 | 204 | }
 | 
|---|
 | 205 | 
 | 
|---|
 | 206 | void Mangler::postvisit( const ast::UnionInstType * aggregateUseType ) {
 | 
|---|
 | 207 |         mangleRef( aggregateUseType, Encoding::union_t );
 | 
|---|
 | 208 | }
 | 
|---|
 | 209 | 
 | 
|---|
 | 210 | void Mangler::postvisit( const ast::EnumInstType * aggregateUseType ) {
 | 
|---|
 | 211 |         mangleRef( aggregateUseType, Encoding::enum_t );
 | 
|---|
 | 212 | }
 | 
|---|
 | 213 | 
 | 
|---|
 | 214 | void Mangler::postvisit( const ast::TypeInstType * typeInst ) {
 | 
|---|
 | 215 |         VarMapType::iterator varNum = varNums.find( typeInst->name );
 | 
|---|
 | 216 |         if ( varNum == varNums.end() ) {
 | 
|---|
 | 217 |                 mangleRef( typeInst, Encoding::type );
 | 
|---|
 | 218 |         } else {
 | 
|---|
 | 219 |                 printQualifiers( typeInst );
 | 
|---|
 | 220 |                 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
 | 
|---|
 | 221 |                 //   forall(dtype T) void f(T);
 | 
|---|
 | 222 |                 //   forall(dtype S) void f(S);
 | 
|---|
 | 223 |                 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
 | 
|---|
 | 224 |                 // are first found and prefixing with the appropriate encoding for the type class.
 | 
|---|
 | 225 |                 assertf( varNum->second.second < ast::TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
 | 
|---|
 | 226 |                 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
 | 
|---|
 | 227 |         }
 | 
|---|
 | 228 | }
 | 
|---|
 | 229 | 
 | 
|---|
 | 230 | void Mangler::postvisit( const ast::TraitInstType * inst ) {
 | 
|---|
 | 231 |         printQualifiers( inst );
 | 
|---|
 | 232 |         mangleName += std::to_string( inst->name.size() ) + inst->name;
 | 
|---|
 | 233 | }
 | 
|---|
 | 234 | 
 | 
|---|
 | 235 | void Mangler::postvisit( const ast::TupleType * tupleType ) {
 | 
|---|
 | 236 |         printQualifiers( tupleType );
 | 
|---|
 | 237 |         mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
 | 
|---|
 | 238 |         accept_each( tupleType->types, *visitor );
 | 
|---|
 | 239 | }
 | 
|---|
 | 240 | 
 | 
|---|
 | 241 | void Mangler::postvisit( const ast::VarArgsType * varArgsType ) {
 | 
|---|
 | 242 |         printQualifiers( varArgsType );
 | 
|---|
 | 243 |         static const std::string vargs = "__builtin_va_list";
 | 
|---|
 | 244 |         mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
 | 
|---|
 | 245 | }
 | 
|---|
 | 246 | 
 | 
|---|
 | 247 | void Mangler::postvisit( const ast::ZeroType * ) {
 | 
|---|
 | 248 |         mangleName += Encoding::zero;
 | 
|---|
 | 249 | }
 | 
|---|
 | 250 | 
 | 
|---|
 | 251 | void Mangler::postvisit( const ast::OneType * ) {
 | 
|---|
 | 252 |         mangleName += Encoding::one;
 | 
|---|
 | 253 | }
 | 
|---|
 | 254 | 
 | 
|---|
 | 255 | void Mangler::postvisit( const ast::QualifiedType * qualType ) {
 | 
|---|
 | 256 |         bool inqual = inQualifiedType;
 | 
|---|
 | 257 |         if ( !inqual ) {
 | 
|---|
 | 258 |                 // N marks the start of a qualified type.
 | 
|---|
 | 259 |                 inQualifiedType = true;
 | 
|---|
 | 260 |                 mangleName += Encoding::qualifiedTypeStart;
 | 
|---|
 | 261 |         }
 | 
|---|
 | 262 |         qualType->parent->accept( *visitor );
 | 
|---|
 | 263 |         qualType->child->accept( *visitor );
 | 
|---|
 | 264 |         if ( !inqual ) {
 | 
|---|
 | 265 |                 // E marks the end of a qualified type.
 | 
|---|
 | 266 |                 inQualifiedType = false;
 | 
|---|
 | 267 |                 mangleName += Encoding::qualifiedTypeEnd;
 | 
|---|
 | 268 |         }
 | 
|---|
 | 269 | }
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 | void Mangler::postvisit( const ast::TypeDecl * decl ) {
 | 
|---|
 | 272 |         // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
 | 
|---|
 | 273 |         // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
 | 
|---|
 | 274 |         // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
 | 
|---|
 | 275 |         // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
 | 
|---|
 | 276 |         // aside from the assert false.
 | 
|---|
 | 277 |         assertf(false, "Mangler should not visit typedecl: %s", toCString(decl));
 | 
|---|
 | 278 |         assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
 | 
|---|
 | 279 |         mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
 | 
|---|
 | 280 | }
 | 
|---|
 | 281 | 
 | 
|---|
| [af746cc] | 282 | void Mangler::postvisit( const ast::EnumAttrType * enumAttr ) {
 | 
|---|
 | 283 |         postvisit( enumAttr->instance );
 | 
|---|
 | 284 |         // mangleName += "_pos";
 | 
|---|
| [fc1a3e2] | 285 |         switch ( enumAttr->attr )
 | 
|---|
 | 286 |         {
 | 
|---|
 | 287 |                 case ast::EnumAttribute::Label:
 | 
|---|
 | 288 |                         mangleName += "_label_";
 | 
|---|
 | 289 |                         break;
 | 
|---|
 | 290 |                 case ast::EnumAttribute::Posn:
 | 
|---|
| [af746cc] | 291 |                         mangleName += "_posn_";
 | 
|---|
| [fc1a3e2] | 292 |                         break;
 | 
|---|
 | 293 |                 case ast::EnumAttribute::Value:
 | 
|---|
 | 294 |                         mangleName += "_value_";
 | 
|---|
 | 295 |                         break;
 | 
|---|
 | 296 |         }
 | 
|---|
| [af746cc] | 297 | 
 | 
|---|
| [0522ebe] | 298 | }
 | 
|---|
 | 299 | 
 | 
|---|
| [b0845f9] | 300 | // For debugging:
 | 
|---|
 | 301 | __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
 | 
|---|
 | 302 |         for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
 | 
|---|
 | 303 |                 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
 | 
|---|
 | 304 |         }
 | 
|---|
 | 305 | }
 | 
|---|
 | 306 | 
 | 
|---|
 | 307 | void Mangler::printQualifiers( const ast::Type * type ) {
 | 
|---|
 | 308 |         // Skip if not including qualifiers:
 | 
|---|
 | 309 |         if ( typeMode ) return;
 | 
|---|
 | 310 |         auto funcType = dynamic_cast<const ast::FunctionType *>( type );
 | 
|---|
 | 311 |         if ( funcType && !funcType->forall.empty() ) {
 | 
|---|
 | 312 |                 std::list< std::string > assertionNames;
 | 
|---|
 | 313 |                 int dcount = 0, fcount = 0, vcount = 0, acount = 0;
 | 
|---|
 | 314 |                 mangleName += Encoding::forall;
 | 
|---|
 | 315 |                 for ( auto & decl : funcType->forall ) {
 | 
|---|
 | 316 |                         switch ( decl->kind ) {
 | 
|---|
 | 317 |                         case ast::TypeDecl::Dtype:
 | 
|---|
 | 318 |                                 dcount++;
 | 
|---|
 | 319 |                                 break;
 | 
|---|
 | 320 |                         case ast::TypeDecl::Ftype:
 | 
|---|
 | 321 |                                 fcount++;
 | 
|---|
 | 322 |                                 break;
 | 
|---|
 | 323 |                         case ast::TypeDecl::Ttype:
 | 
|---|
 | 324 |                                 vcount++;
 | 
|---|
 | 325 |                                 break;
 | 
|---|
 | 326 |                         default:
 | 
|---|
 | 327 |                                 assertf( false, "unimplemented kind for type variable %s", Encoding::typeVariables[decl->kind].c_str() );
 | 
|---|
| [1867c96] | 328 |                         }
 | 
|---|
| [b0845f9] | 329 |                         varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
 | 
|---|
| [1867c96] | 330 |                 }
 | 
|---|
| [b0845f9] | 331 |                 for ( auto & assert : funcType->assertions ) {
 | 
|---|
 | 332 |                         assertionNames.push_back( ast::Pass<Mangler>::read(
 | 
|---|
 | 333 |                                 assert->var.get(),
 | 
|---|
 | 334 |                                 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) );
 | 
|---|
 | 335 |                         acount++;
 | 
|---|
| [1867c96] | 336 |                 }
 | 
|---|
| [b0845f9] | 337 |                 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
 | 
|---|
 | 338 |                 for ( const auto & a : assertionNames ) mangleName += a;
 | 
|---|
 | 339 |                 mangleName += "_";
 | 
|---|
 | 340 |         }
 | 
|---|
 | 341 |         if ( !inFunctionType ) {
 | 
|---|
 | 342 |                 // These qualifiers do not distinguish the outermost type of a function parameter.
 | 
|---|
 | 343 |                 if ( type->is_const() ) {
 | 
|---|
 | 344 |                         mangleName += Encoding::qualifiers.at( ast::CV::Const );
 | 
|---|
| [1867c96] | 345 |                 }
 | 
|---|
| [b0845f9] | 346 |                 if ( type->is_volatile() ) {
 | 
|---|
 | 347 |                         mangleName += Encoding::qualifiers.at( ast::CV::Volatile );
 | 
|---|
| [1867c96] | 348 |                 }
 | 
|---|
| [b0845f9] | 349 |                 if ( type->is_atomic() ) {
 | 
|---|
 | 350 |                         mangleName += Encoding::qualifiers.at( ast::CV::Atomic );
 | 
|---|
| [1867c96] | 351 |                 }
 | 
|---|
| [b0845f9] | 352 |         }
 | 
|---|
 | 353 |         if ( type->is_mutex() ) {
 | 
|---|
 | 354 |                 mangleName += Encoding::qualifiers.at( ast::CV::Mutex );
 | 
|---|
 | 355 |         }
 | 
|---|
 | 356 |         if ( inFunctionType ) {
 | 
|---|
 | 357 |                 // Turn off inFunctionType so that types can be differentiated for nested qualifiers.
 | 
|---|
 | 358 |                 GuardValue( inFunctionType ) = false;
 | 
|---|
 | 359 |         }
 | 
|---|
 | 360 | }
 | 
|---|
| [1867c96] | 361 | 
 | 
|---|
| [8984003] | 362 | } // namespace
 | 
|---|
| [1867c96] | 363 | 
 | 
|---|
| [b0845f9] | 364 | std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
 | 
|---|
 | 365 |         return ast::Pass<Mangler>::read( decl, mode );
 | 
|---|
 | 366 | }
 | 
|---|
| [1867c96] | 367 | 
 | 
|---|
| [d76c588] | 368 | } // namespace Mangle
 | 
|---|
 | 369 | 
 | 
|---|
| [0dd3a2f] | 370 | // Local Variables: //
 | 
|---|
 | 371 | // tab-width: 4 //
 | 
|---|
 | 372 | // mode: c++ //
 | 
|---|
 | 373 | // compile-command: "make install" //
 | 
|---|
 | 374 | // End: //
 | 
|---|