| [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
 | 
|---|
| [201aeb9] | 11 | // Last Modified By : Peter A. Buhr
 | 
|---|
| [b66d14a] | 12 | // Last Modified On : Mon Jan 11 21:56:06 2021
 | 
|---|
 | 13 | // Update Count     : 74
 | 
|---|
| [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 | 
 | 
|---|
 | 24 | #include "CodeGen/OperatorTable.h"       // for OperatorInfo, operatorLookup
 | 
|---|
| [d7d9a60] | 25 | #include "Common/PassVisitor.h"
 | 
|---|
| [ff5caaf] | 26 | #include "Common/SemanticError.h"        // for SemanticError
 | 
|---|
 | 27 | #include "Common/utility.h"              // for toString
 | 
|---|
 | 28 | #include "ResolvExpr/TypeEnvironment.h"  // for TypeEnvironment
 | 
|---|
| [07de76b] | 29 | #include "SynTree/LinkageSpec.h"         // for Spec, isOverridable, AutoGen, Int...
 | 
|---|
| [ff5caaf] | 30 | #include "SynTree/Declaration.h"         // for TypeDecl, DeclarationWithType
 | 
|---|
 | 31 | #include "SynTree/Expression.h"          // for TypeExpr, Expression, operator<<
 | 
|---|
 | 32 | #include "SynTree/Type.h"                // for Type, ReferenceToType, Type::Fora...
 | 
|---|
| [51b73452] | 33 | 
 | 
|---|
| [1867c96] | 34 | #include "AST/Pass.hpp"
 | 
|---|
 | 35 | 
 | 
|---|
| [51b73452] | 36 | namespace SymTab {
 | 
|---|
| [d7d9a60] | 37 |         namespace Mangler {
 | 
|---|
 | 38 |                 namespace {
 | 
|---|
 | 39 |                         /// Mangles names to a unique C identifier
 | 
|---|
| [1867c96] | 40 |                         struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards {
 | 
|---|
 | 41 |                                 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
 | 
|---|
 | 42 |                                 Mangler_old( const Mangler_old & ) = delete;
 | 
|---|
| [d7d9a60] | 43 | 
 | 
|---|
| [6f096d2] | 44 |                                 void previsit( const BaseSyntaxNode * ) { visit_children = false; }
 | 
|---|
 | 45 | 
 | 
|---|
 | 46 |                                 void postvisit( const ObjectDecl * declaration );
 | 
|---|
 | 47 |                                 void postvisit( const FunctionDecl * declaration );
 | 
|---|
 | 48 |                                 void postvisit( const TypeDecl * declaration );
 | 
|---|
 | 49 | 
 | 
|---|
 | 50 |                                 void postvisit( const VoidType * voidType );
 | 
|---|
 | 51 |                                 void postvisit( const BasicType * basicType );
 | 
|---|
 | 52 |                                 void postvisit( const PointerType * pointerType );
 | 
|---|
 | 53 |                                 void postvisit( const ArrayType * arrayType );
 | 
|---|
 | 54 |                                 void postvisit( const ReferenceType * refType );
 | 
|---|
 | 55 |                                 void postvisit( const FunctionType * functionType );
 | 
|---|
 | 56 |                                 void postvisit( const StructInstType * aggregateUseType );
 | 
|---|
 | 57 |                                 void postvisit( const UnionInstType * aggregateUseType );
 | 
|---|
 | 58 |                                 void postvisit( const EnumInstType * aggregateUseType );
 | 
|---|
 | 59 |                                 void postvisit( const TypeInstType * aggregateUseType );
 | 
|---|
 | 60 |                                 void postvisit( const TraitInstType * inst );
 | 
|---|
 | 61 |                                 void postvisit( const TupleType * tupleType );
 | 
|---|
 | 62 |                                 void postvisit( const VarArgsType * varArgsType );
 | 
|---|
 | 63 |                                 void postvisit( const ZeroType * zeroType );
 | 
|---|
 | 64 |                                 void postvisit( const OneType * oneType );
 | 
|---|
 | 65 |                                 void postvisit( const QualifiedType * qualType );
 | 
|---|
| [d7d9a60] | 66 | 
 | 
|---|
| [22b5b87] | 67 |                                 std::string get_mangleName() { return mangleName; }
 | 
|---|
| [d7d9a60] | 68 |                           private:
 | 
|---|
| [22b5b87] | 69 |                                 std::string mangleName;         ///< Mangled name being constructed
 | 
|---|
| [052cd71] | 70 |                                 typedef std::map< std::string, std::pair< int, int > > VarMapType;
 | 
|---|
| [d7d9a60] | 71 |                                 VarMapType varNums;             ///< Map of type variables to indices
 | 
|---|
 | 72 |                                 int nextVarNum;                 ///< Next type variable index
 | 
|---|
 | 73 |                                 bool isTopLevel;                ///< Is the Mangler at the top level
 | 
|---|
 | 74 |                                 bool mangleOverridable;         ///< Specially mangle overridable built-in methods
 | 
|---|
 | 75 |                                 bool typeMode;                  ///< Produce a unique mangled name for a type
 | 
|---|
 | 76 |                                 bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
 | 
|---|
| [c0453ca3] | 77 |                                 bool inFunctionType = false;    ///< Include type qualifiers if false.
 | 
|---|
| [642bc83] | 78 |                                 bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
 | 
|---|
| [d7d9a60] | 79 | 
 | 
|---|
| [e1f7eef] | 80 |                           public:
 | 
|---|
| [6f096d2] | 81 |                                 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 | 
|---|
| [052cd71] | 82 |                                         int nextVarNum, const VarMapType& varNums );
 | 
|---|
| [ff5caaf] | 83 | 
 | 
|---|
| [e1f7eef] | 84 |                           private:
 | 
|---|
| [6f096d2] | 85 |                                 void mangleDecl( const DeclarationWithType * declaration );
 | 
|---|
 | 86 |                                 void mangleRef( const ReferenceToType * refType, std::string prefix );
 | 
|---|
| [d7d9a60] | 87 | 
 | 
|---|
| [6f096d2] | 88 |                                 void printQualifiers( const Type *type );
 | 
|---|
| [1867c96] | 89 |                         }; // Mangler_old
 | 
|---|
| [d7d9a60] | 90 |                 } // namespace
 | 
|---|
 | 91 | 
 | 
|---|
| [6f096d2] | 92 |                 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
 | 
|---|
| [1867c96] | 93 |                         PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );
 | 
|---|
| [d7d9a60] | 94 |                         maybeAccept( decl, mangler );
 | 
|---|
 | 95 |                         return mangler.pass.get_mangleName();
 | 
|---|
| [4aa0858] | 96 |                 }
 | 
|---|
| [d7d9a60] | 97 | 
 | 
|---|
| [6f096d2] | 98 |                 std::string mangleType( const Type * ty ) {
 | 
|---|
| [1867c96] | 99 |                         PassVisitor<Mangler_old> mangler( false, true, true );
 | 
|---|
| [d7d9a60] | 100 |                         maybeAccept( ty, mangler );
 | 
|---|
 | 101 |                         return mangler.pass.get_mangleName();
 | 
|---|
 | 102 |                 }
 | 
|---|
 | 103 | 
 | 
|---|
| [6f096d2] | 104 |                 std::string mangleConcrete( const Type * ty ) {
 | 
|---|
| [1867c96] | 105 |                         PassVisitor<Mangler_old> mangler( false, false, false );
 | 
|---|
| [d7d9a60] | 106 |                         maybeAccept( ty, mangler );
 | 
|---|
 | 107 |                         return mangler.pass.get_mangleName();
 | 
|---|
| [0dd3a2f] | 108 |                 }
 | 
|---|
| [d7d9a60] | 109 | 
 | 
|---|
 | 110 |                 namespace {
 | 
|---|
| [1867c96] | 111 |                         Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
 | 
|---|
| [6f096d2] | 112 |                                 : nextVarNum( 0 ), isTopLevel( true ),
 | 
|---|
 | 113 |                                 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 | 
|---|
| [ff5caaf] | 114 |                                 mangleGenericParams( mangleGenericParams ) {}
 | 
|---|
| [6f096d2] | 115 | 
 | 
|---|
 | 116 |                         Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 | 
|---|
| [052cd71] | 117 |                                 int nextVarNum, const VarMapType& varNums )
 | 
|---|
| [6f096d2] | 118 |                                 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
 | 
|---|
 | 119 |                                 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 | 
|---|
| [ff5caaf] | 120 |                                 mangleGenericParams( mangleGenericParams ) {}
 | 
|---|
| [d7d9a60] | 121 | 
 | 
|---|
| [6f096d2] | 122 |                         void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {
 | 
|---|
| [d7d9a60] | 123 |                                 bool wasTopLevel = isTopLevel;
 | 
|---|
 | 124 |                                 if ( isTopLevel ) {
 | 
|---|
 | 125 |                                         varNums.clear();
 | 
|---|
 | 126 |                                         nextVarNum = 0;
 | 
|---|
 | 127 |                                         isTopLevel = false;
 | 
|---|
 | 128 |                                 } // if
 | 
|---|
| [22b5b87] | 129 |                                 mangleName += Encoding::manglePrefix;
 | 
|---|
| [60a8062] | 130 |                                 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );
 | 
|---|
 | 131 |                                 if ( opInfo ) {
 | 
|---|
| [22b5b87] | 132 |                                         mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
 | 
|---|
| [d7d9a60] | 133 |                                 } else {
 | 
|---|
| [22b5b87] | 134 |                                         mangleName += std::to_string( declaration->name.size() ) + declaration->name;
 | 
|---|
| [d7d9a60] | 135 |                                 } // if
 | 
|---|
 | 136 |                                 maybeAccept( declaration->get_type(), *visitor );
 | 
|---|
 | 137 |                                 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
 | 
|---|
 | 138 |                                         // want to be able to override autogenerated and intrinsic routines,
 | 
|---|
 | 139 |                                         // so they need a different name mangling
 | 
|---|
 | 140 |                                         if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
 | 
|---|
| [22b5b87] | 141 |                                                 mangleName += Encoding::autogen;
 | 
|---|
| [d7d9a60] | 142 |                                         } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
 | 
|---|
| [22b5b87] | 143 |                                                 mangleName += Encoding::intrinsic;
 | 
|---|
| [d7d9a60] | 144 |                                         } else {
 | 
|---|
 | 145 |                                                 // if we add another kind of overridable function, this has to change
 | 
|---|
 | 146 |                                                 assert( false && "unknown overrideable linkage" );
 | 
|---|
 | 147 |                                         } // if
 | 
|---|
 | 148 |                                 }
 | 
|---|
 | 149 |                                 isTopLevel = wasTopLevel;
 | 
|---|
 | 150 |                         }
 | 
|---|
 | 151 | 
 | 
|---|
| [6f096d2] | 152 |                         void Mangler_old::postvisit( const ObjectDecl * declaration ) {
 | 
|---|
| [d7d9a60] | 153 |                                 mangleDecl( declaration );
 | 
|---|
 | 154 |                         }
 | 
|---|
 | 155 | 
 | 
|---|
| [6f096d2] | 156 |                         void Mangler_old::postvisit( const FunctionDecl * declaration ) {
 | 
|---|
| [d7d9a60] | 157 |                                 mangleDecl( declaration );
 | 
|---|
 | 158 |                         }
 | 
|---|
 | 159 | 
 | 
|---|
| [6f096d2] | 160 |                         void Mangler_old::postvisit( const VoidType * voidType ) {
 | 
|---|
| [d7d9a60] | 161 |                                 printQualifiers( voidType );
 | 
|---|
| [22b5b87] | 162 |                                 mangleName += Encoding::void_t;
 | 
|---|
| [d7d9a60] | 163 |                         }
 | 
|---|
 | 164 | 
 | 
|---|
| [6f096d2] | 165 |                         void Mangler_old::postvisit( const BasicType * basicType ) {
 | 
|---|
| [d7d9a60] | 166 |                                 printQualifiers( basicType );
 | 
|---|
| [6f096d2] | 167 |                                 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
 | 
|---|
| [22b5b87] | 168 |                                 mangleName += Encoding::basicTypes[ basicType->kind ];
 | 
|---|
| [d7d9a60] | 169 |                         }
 | 
|---|
 | 170 | 
 | 
|---|
| [6f096d2] | 171 |                         void Mangler_old::postvisit( const PointerType * pointerType ) {
 | 
|---|
| [d7d9a60] | 172 |                                 printQualifiers( pointerType );
 | 
|---|
| [3f024c9] | 173 |                                 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
 | 
|---|
| [22b5b87] | 174 |                                 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName += Encoding::pointer;
 | 
|---|
| [1da22500] | 175 |                                 maybeAccept( pointerType->base, *visitor );
 | 
|---|
| [d7d9a60] | 176 |                         }
 | 
|---|
 | 177 | 
 | 
|---|
| [6f096d2] | 178 |                         void Mangler_old::postvisit( const ArrayType * arrayType ) {
 | 
|---|
| [d7d9a60] | 179 |                                 // TODO: encode dimension
 | 
|---|
 | 180 |                                 printQualifiers( arrayType );
 | 
|---|
| [22b5b87] | 181 |                                 mangleName += Encoding::array + "0";
 | 
|---|
| [1da22500] | 182 |                                 maybeAccept( arrayType->base, *visitor );
 | 
|---|
| [d7d9a60] | 183 |                         }
 | 
|---|
 | 184 | 
 | 
|---|
| [6f096d2] | 185 |                         void Mangler_old::postvisit( const ReferenceType * refType ) {
 | 
|---|
| [c0453ca3] | 186 |                                 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
 | 
|---|
 | 187 |                                 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
 | 
|---|
 | 188 |                                 // by pretending every reference type is a function parameter.
 | 
|---|
 | 189 |                                 GuardValue( inFunctionType );
 | 
|---|
 | 190 |                                 inFunctionType = true;
 | 
|---|
| [d7d9a60] | 191 |                                 printQualifiers( refType );
 | 
|---|
| [1da22500] | 192 |                                 maybeAccept( refType->base, *visitor );
 | 
|---|
| [d7d9a60] | 193 |                         }
 | 
|---|
 | 194 | 
 | 
|---|
 | 195 |                         namespace {
 | 
|---|
 | 196 |                                 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
 | 
|---|
 | 197 |                                         std::list< Type* > ret;
 | 
|---|
 | 198 |                                         std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
 | 
|---|
 | 199 |                                                                         std::mem_fun( &DeclarationWithType::get_type ) );
 | 
|---|
 | 200 |                                         return ret;
 | 
|---|
 | 201 |                                 }
 | 
|---|
 | 202 |                         }
 | 
|---|
 | 203 | 
 | 
|---|
| [6f096d2] | 204 |                         void Mangler_old::postvisit( const FunctionType * functionType ) {
 | 
|---|
| [d7d9a60] | 205 |                                 printQualifiers( functionType );
 | 
|---|
| [22b5b87] | 206 |                                 mangleName += Encoding::function;
 | 
|---|
| [c0453ca3] | 207 |                                 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
 | 
|---|
 | 208 |                                 // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
 | 
|---|
 | 209 |                                 // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
 | 
|---|
 | 210 |                                 GuardValue( inFunctionType );
 | 
|---|
 | 211 |                                 inFunctionType = true;
 | 
|---|
| [96812c0] | 212 |                                 std::list< Type* > returnTypes = getTypes( functionType->returnVals );
 | 
|---|
| [22b5b87] | 213 |                                 if (returnTypes.empty()) mangleName += Encoding::void_t;
 | 
|---|
| [d1e0979] | 214 |                                 else acceptAll( returnTypes, *visitor );
 | 
|---|
| [22b5b87] | 215 |                                 mangleName += "_";
 | 
|---|
| [96812c0] | 216 |                                 std::list< Type* > paramTypes = getTypes( functionType->parameters );
 | 
|---|
| [d7d9a60] | 217 |                                 acceptAll( paramTypes, *visitor );
 | 
|---|
| [22b5b87] | 218 |                                 mangleName += "_";
 | 
|---|
| [d7d9a60] | 219 |                         }
 | 
|---|
 | 220 | 
 | 
|---|
| [6f096d2] | 221 |                         void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {
 | 
|---|
| [d7d9a60] | 222 |                                 printQualifiers( refType );
 | 
|---|
 | 223 | 
 | 
|---|
| [22b5b87] | 224 |                                 mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
 | 
|---|
| [d7d9a60] | 225 | 
 | 
|---|
 | 226 |                                 if ( mangleGenericParams ) {
 | 
|---|
| [6f096d2] | 227 |                                         const std::list< Expression* > & params = refType->parameters;
 | 
|---|
| [d7d9a60] | 228 |                                         if ( ! params.empty() ) {
 | 
|---|
| [22b5b87] | 229 |                                                 mangleName += "_";
 | 
|---|
| [6f096d2] | 230 |                                                 for ( const Expression * param : params ) {
 | 
|---|
 | 231 |                                                         const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );
 | 
|---|
 | 232 |                                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
 | 
|---|
| [96812c0] | 233 |                                                         maybeAccept( paramType->type, *visitor );
 | 
|---|
| [d7d9a60] | 234 |                                                 }
 | 
|---|
| [22b5b87] | 235 |                                                 mangleName += "_";
 | 
|---|
| [d7d9a60] | 236 |                                         }
 | 
|---|
| [e35f30a] | 237 |                                 }
 | 
|---|
| [d7d9a60] | 238 |                         }
 | 
|---|
 | 239 | 
 | 
|---|
| [6f096d2] | 240 |                         void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {
 | 
|---|
| [7804e2a] | 241 |                                 mangleRef( aggregateUseType, Encoding::struct_t );
 | 
|---|
| [d7d9a60] | 242 |                         }
 | 
|---|
 | 243 | 
 | 
|---|
| [6f096d2] | 244 |                         void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {
 | 
|---|
| [7804e2a] | 245 |                                 mangleRef( aggregateUseType, Encoding::union_t );
 | 
|---|
| [d7d9a60] | 246 |                         }
 | 
|---|
 | 247 | 
 | 
|---|
| [6f096d2] | 248 |                         void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {
 | 
|---|
| [7804e2a] | 249 |                                 mangleRef( aggregateUseType, Encoding::enum_t );
 | 
|---|
| [d7d9a60] | 250 |                         }
 | 
|---|
 | 251 | 
 | 
|---|
| [6f096d2] | 252 |                         void Mangler_old::postvisit( const TypeInstType * typeInst ) {
 | 
|---|
| [d7d9a60] | 253 |                                 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
 | 
|---|
 | 254 |                                 if ( varNum == varNums.end() ) {
 | 
|---|
| [d8cb7df] | 255 |                                         mangleRef( typeInst, Encoding::type );
 | 
|---|
| [d7d9a60] | 256 |                                 } else {
 | 
|---|
 | 257 |                                         printQualifiers( typeInst );
 | 
|---|
| [0e761e40] | 258 |                                         // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
 | 
|---|
 | 259 |                                         //   forall(dtype T) void f(T);
 | 
|---|
 | 260 |                                         //   forall(dtype S) void f(S);
 | 
|---|
 | 261 |                                         // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
 | 
|---|
 | 262 |                                         // are first found and prefixing with the appropriate encoding for the type class.
 | 
|---|
| [0e73845] | 263 |                                         assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
 | 
|---|
| [22b5b87] | 264 |                                         mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
 | 
|---|
| [d7d9a60] | 265 |                                 } // if
 | 
|---|
 | 266 |                         }
 | 
|---|
 | 267 | 
 | 
|---|
| [6f096d2] | 268 |                         void Mangler_old::postvisit( const TraitInstType * inst ) {
 | 
|---|
| [f465f0e] | 269 |                                 printQualifiers( inst );
 | 
|---|
| [22b5b87] | 270 |                                 mangleName += std::to_string( inst->name.size() ) + inst->name;
 | 
|---|
| [f465f0e] | 271 |                         }
 | 
|---|
 | 272 | 
 | 
|---|
| [6f096d2] | 273 |                         void Mangler_old::postvisit( const TupleType * tupleType ) {
 | 
|---|
| [d7d9a60] | 274 |                                 printQualifiers( tupleType );
 | 
|---|
| [22b5b87] | 275 |                                 mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
 | 
|---|
| [d7d9a60] | 276 |                                 acceptAll( tupleType->types, *visitor );
 | 
|---|
| [8360977] | 277 |                         }
 | 
|---|
| [d7d9a60] | 278 | 
 | 
|---|
| [6f096d2] | 279 |                         void Mangler_old::postvisit( const VarArgsType * varArgsType ) {
 | 
|---|
| [d7d9a60] | 280 |                                 printQualifiers( varArgsType );
 | 
|---|
| [642bc83] | 281 |                                 static const std::string vargs = "__builtin_va_list";
 | 
|---|
| [22b5b87] | 282 |                                 mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
 | 
|---|
| [d7d9a60] | 283 |                         }
 | 
|---|
 | 284 | 
 | 
|---|
| [6f096d2] | 285 |                         void Mangler_old::postvisit( const ZeroType * ) {
 | 
|---|
| [22b5b87] | 286 |                                 mangleName += Encoding::zero;
 | 
|---|
| [d7d9a60] | 287 |                         }
 | 
|---|
 | 288 | 
 | 
|---|
| [6f096d2] | 289 |                         void Mangler_old::postvisit( const OneType * ) {
 | 
|---|
| [22b5b87] | 290 |                                 mangleName += Encoding::one;
 | 
|---|
| [d7d9a60] | 291 |                         }
 | 
|---|
 | 292 | 
 | 
|---|
| [6f096d2] | 293 |                         void Mangler_old::postvisit( const QualifiedType * qualType ) {
 | 
|---|
| [642bc83] | 294 |                                 bool inqual = inQualifiedType;
 | 
|---|
 | 295 |                                 if (! inqual ) {
 | 
|---|
 | 296 |                                         // N marks the start of a qualified type
 | 
|---|
 | 297 |                                         inQualifiedType = true;
 | 
|---|
| [22b5b87] | 298 |                                         mangleName += Encoding::qualifiedTypeStart;
 | 
|---|
| [642bc83] | 299 |                                 }
 | 
|---|
| [e73becf] | 300 |                                 maybeAccept( qualType->parent, *visitor );
 | 
|---|
 | 301 |                                 maybeAccept( qualType->child, *visitor );
 | 
|---|
| [642bc83] | 302 |                                 if ( ! inqual ) {
 | 
|---|
 | 303 |                                         // E marks the end of a qualified type
 | 
|---|
 | 304 |                                         inQualifiedType = false;
 | 
|---|
| [22b5b87] | 305 |                                         mangleName += Encoding::qualifiedTypeEnd;
 | 
|---|
| [642bc83] | 306 |                                 }
 | 
|---|
| [e73becf] | 307 |                         }
 | 
|---|
 | 308 | 
 | 
|---|
| [6f096d2] | 309 |                         void Mangler_old::postvisit( const TypeDecl * decl ) {
 | 
|---|
| [0e761e40] | 310 |                                 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
 | 
|---|
 | 311 |                                 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
 | 
|---|
 | 312 |                                 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
 | 
|---|
 | 313 |                                 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
 | 
|---|
 | 314 |                                 // aside from the assert false.
 | 
|---|
| [b66d14a] | 315 |                                 assertf( false, "Mangler_old should not visit typedecl: %s", toCString(decl));
 | 
|---|
| [6f096d2] | 316 |                                 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
 | 
|---|
| [22b5b87] | 317 |                                 mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
 | 
|---|
| [d7d9a60] | 318 |                         }
 | 
|---|
 | 319 | 
 | 
|---|
 | 320 |                         __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
 | 
|---|
 | 321 |                                 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
 | 
|---|
 | 322 |                                         os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
 | 
|---|
| [0dd3a2f] | 323 |                                 } // for
 | 
|---|
| [d7d9a60] | 324 |                         }
 | 
|---|
 | 325 | 
 | 
|---|
| [6f096d2] | 326 |                         void Mangler_old::printQualifiers( const Type * type ) {
 | 
|---|
| [d7d9a60] | 327 |                                 // skip if not including qualifiers
 | 
|---|
 | 328 |                                 if ( typeMode ) return;
 | 
|---|
| [6f096d2] | 329 |                                 if ( ! type->forall.empty() ) {
 | 
|---|
| [d7d9a60] | 330 |                                         std::list< std::string > assertionNames;
 | 
|---|
| [0e73845] | 331 |                                         int dcount = 0, fcount = 0, vcount = 0, acount = 0;
 | 
|---|
| [22b5b87] | 332 |                                         mangleName += Encoding::forall;
 | 
|---|
| [6f096d2] | 333 |                                         for ( const TypeDecl * i : type->forall ) {
 | 
|---|
 | 334 |                                                 switch ( i->kind ) {
 | 
|---|
| [d7d9a60] | 335 |                                                   case TypeDecl::Dtype:
 | 
|---|
 | 336 |                                                         dcount++;
 | 
|---|
 | 337 |                                                         break;
 | 
|---|
 | 338 |                                                   case TypeDecl::Ftype:
 | 
|---|
 | 339 |                                                         fcount++;
 | 
|---|
 | 340 |                                                         break;
 | 
|---|
 | 341 |                                                   case TypeDecl::Ttype:
 | 
|---|
 | 342 |                                                         vcount++;
 | 
|---|
 | 343 |                                                         break;
 | 
|---|
 | 344 |                                                   default:
 | 
|---|
| [b66d14a] | 345 |                                                         assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[i->kind].c_str() );
 | 
|---|
| [d7d9a60] | 346 |                                                 } // switch
 | 
|---|
| [6f096d2] | 347 |                                                 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
 | 
|---|
 | 348 |                                                 for ( const DeclarationWithType * assert : i->assertions ) {
 | 
|---|
 | 349 |                                                         PassVisitor<Mangler_old> sub_mangler(
 | 
|---|
| [052cd71] | 350 |                                                                 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
 | 
|---|
| [6f096d2] | 351 |                                                         assert->accept( sub_mangler );
 | 
|---|
| [ff5caaf] | 352 |                                                         assertionNames.push_back( sub_mangler.pass.get_mangleName() );
 | 
|---|
| [0e73845] | 353 |                                                         acount++;
 | 
|---|
| [d7d9a60] | 354 |                                                 } // for
 | 
|---|
 | 355 |                                         } // for
 | 
|---|
| [22b5b87] | 356 |                                         mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
 | 
|---|
 | 357 |                                         for(const auto & a : assertionNames) mangleName += a;
 | 
|---|
 | 358 | //                                      std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
 | 
|---|
 | 359 |                                         mangleName += "_";
 | 
|---|
| [d7d9a60] | 360 |                                 } // if
 | 
|---|
| [c0453ca3] | 361 |                                 if ( ! inFunctionType ) {
 | 
|---|
 | 362 |                                         // these qualifiers do not distinguish the outermost type of a function parameter
 | 
|---|
 | 363 |                                         if ( type->get_const() ) {
 | 
|---|
| [22b5b87] | 364 |                                                 mangleName += Encoding::qualifiers.at(Type::Const);
 | 
|---|
| [c0453ca3] | 365 |                                         } // if
 | 
|---|
 | 366 |                                         if ( type->get_volatile() ) {
 | 
|---|
| [22b5b87] | 367 |                                                 mangleName += Encoding::qualifiers.at(Type::Volatile);
 | 
|---|
| [c0453ca3] | 368 |                                         } // if
 | 
|---|
 | 369 |                                         // Removed due to restrict not affecting function compatibility in GCC
 | 
|---|
 | 370 |                                         // if ( type->get_isRestrict() ) {
 | 
|---|
| [22b5b87] | 371 |                                         //      mangleName += "E";
 | 
|---|
| [c0453ca3] | 372 |                                         // } // if
 | 
|---|
 | 373 |                                         if ( type->get_atomic() ) {
 | 
|---|
| [22b5b87] | 374 |                                                 mangleName += Encoding::qualifiers.at(Type::Atomic);
 | 
|---|
| [c0453ca3] | 375 |                                         } // if
 | 
|---|
 | 376 |                                 }
 | 
|---|
| [d7d9a60] | 377 |                                 if ( type->get_mutex() ) {
 | 
|---|
| [22b5b87] | 378 |                                         mangleName += Encoding::qualifiers.at(Type::Mutex);
 | 
|---|
| [d7d9a60] | 379 |                                 } // if
 | 
|---|
| [c0453ca3] | 380 |                                 if ( inFunctionType ) {
 | 
|---|
 | 381 |                                         // turn off inFunctionType so that types can be differentiated for nested qualifiers
 | 
|---|
 | 382 |                                         GuardValue( inFunctionType );
 | 
|---|
 | 383 |                                         inFunctionType = false;
 | 
|---|
 | 384 |                                 }
 | 
|---|
| [d7d9a60] | 385 |                         }
 | 
|---|
| [22b5b87] | 386 |                 } // namespace
 | 
|---|
| [d7d9a60] | 387 |         } // namespace Mangler
 | 
|---|
| [0dd3a2f] | 388 | } // namespace SymTab
 | 
|---|
 | 389 | 
 | 
|---|
| [d76c588] | 390 | namespace Mangle {
 | 
|---|
| [1867c96] | 391 |         namespace {
 | 
|---|
 | 392 |                 /// Mangles names to a unique C identifier
 | 
|---|
 | 393 |                 struct Mangler_new : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler_new>, public ast::WithGuards {
 | 
|---|
 | 394 |                         Mangler_new( Mangle::Mode mode );
 | 
|---|
 | 395 |                         Mangler_new( const Mangler_new & ) = delete;
 | 
|---|
 | 396 | 
 | 
|---|
| [1346914] | 397 |                         void previsit( const ast::Node * ) { visit_children = false; }
 | 
|---|
 | 398 | 
 | 
|---|
 | 399 |                         void postvisit( const ast::ObjectDecl * declaration );
 | 
|---|
 | 400 |                         void postvisit( const ast::FunctionDecl * declaration );
 | 
|---|
 | 401 |                         void postvisit( const ast::TypeDecl * declaration );
 | 
|---|
 | 402 | 
 | 
|---|
 | 403 |                         void postvisit( const ast::VoidType * voidType );
 | 
|---|
 | 404 |                         void postvisit( const ast::BasicType * basicType );
 | 
|---|
 | 405 |                         void postvisit( const ast::PointerType * pointerType );
 | 
|---|
 | 406 |                         void postvisit( const ast::ArrayType * arrayType );
 | 
|---|
 | 407 |                         void postvisit( const ast::ReferenceType * refType );
 | 
|---|
 | 408 |                         void postvisit( const ast::FunctionType * functionType );
 | 
|---|
 | 409 |                         void postvisit( const ast::StructInstType * aggregateUseType );
 | 
|---|
 | 410 |                         void postvisit( const ast::UnionInstType * aggregateUseType );
 | 
|---|
 | 411 |                         void postvisit( const ast::EnumInstType * aggregateUseType );
 | 
|---|
 | 412 |                         void postvisit( const ast::TypeInstType * aggregateUseType );
 | 
|---|
 | 413 |                         void postvisit( const ast::TraitInstType * inst );
 | 
|---|
 | 414 |                         void postvisit( const ast::TupleType * tupleType );
 | 
|---|
 | 415 |                         void postvisit( const ast::VarArgsType * varArgsType );
 | 
|---|
 | 416 |                         void postvisit( const ast::ZeroType * zeroType );
 | 
|---|
 | 417 |                         void postvisit( const ast::OneType * oneType );
 | 
|---|
 | 418 |                         void postvisit( const ast::QualifiedType * qualType );
 | 
|---|
| [1867c96] | 419 | 
 | 
|---|
| [22b5b87] | 420 |                         std::string get_mangleName() { return mangleName; }
 | 
|---|
| [1867c96] | 421 |                   private:
 | 
|---|
| [22b5b87] | 422 |                         std::string mangleName;         ///< Mangled name being constructed
 | 
|---|
| [1867c96] | 423 |                         typedef std::map< std::string, std::pair< int, int > > VarMapType;
 | 
|---|
 | 424 |                         VarMapType varNums;             ///< Map of type variables to indices
 | 
|---|
 | 425 |                         int nextVarNum;                 ///< Next type variable index
 | 
|---|
 | 426 |                         bool isTopLevel;                ///< Is the Mangler at the top level
 | 
|---|
 | 427 |                         bool mangleOverridable;         ///< Specially mangle overridable built-in methods
 | 
|---|
 | 428 |                         bool typeMode;                  ///< Produce a unique mangled name for a type
 | 
|---|
 | 429 |                         bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
 | 
|---|
 | 430 |                         bool inFunctionType = false;    ///< Include type qualifiers if false.
 | 
|---|
 | 431 |                         bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
 | 
|---|
 | 432 | 
 | 
|---|
 | 433 |                   private:
 | 
|---|
| [6f096d2] | 434 |                         Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 | 
|---|
| [1867c96] | 435 |                                 int nextVarNum, const VarMapType& varNums );
 | 
|---|
 | 436 |                         friend class ast::Pass<Mangler_new>;
 | 
|---|
 | 437 | 
 | 
|---|
 | 438 |                   private:
 | 
|---|
| [1346914] | 439 |                         void mangleDecl( const ast::DeclWithType *declaration );
 | 
|---|
| [98e8b3b] | 440 |                         void mangleRef( const ast::BaseInstType *refType, std::string prefix );
 | 
|---|
| [1867c96] | 441 | 
 | 
|---|
| [1346914] | 442 |                         void printQualifiers( const ast::Type *type );
 | 
|---|
| [1867c96] | 443 |                 }; // Mangler_new
 | 
|---|
 | 444 |         } // namespace
 | 
|---|
 | 445 | 
 | 
|---|
 | 446 | 
 | 
|---|
| [d76c588] | 447 |         std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
 | 
|---|
| [1867c96] | 448 |                 ast::Pass<Mangler_new> mangler( mode );
 | 
|---|
 | 449 |                 maybeAccept( decl, mangler );
 | 
|---|
| [7ff3e522] | 450 |                 return mangler.core.get_mangleName();
 | 
|---|
| [d76c588] | 451 |         }
 | 
|---|
| [1867c96] | 452 | 
 | 
|---|
 | 453 |         namespace {
 | 
|---|
 | 454 |                 Mangler_new::Mangler_new( Mangle::Mode mode )
 | 
|---|
| [6f096d2] | 455 |                         : nextVarNum( 0 ), isTopLevel( true ),
 | 
|---|
| [1867c96] | 456 |                         mangleOverridable  ( ! mode.no_overrideable   ),
 | 
|---|
| [6f096d2] | 457 |                         typeMode           (   mode.type              ),
 | 
|---|
| [1867c96] | 458 |                         mangleGenericParams( ! mode.no_generic_params ) {}
 | 
|---|
| [6f096d2] | 459 | 
 | 
|---|
 | 460 |                 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
 | 
|---|
| [1867c96] | 461 |                         int nextVarNum, const VarMapType& varNums )
 | 
|---|
| [6f096d2] | 462 |                         : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
 | 
|---|
 | 463 |                         mangleOverridable( mangleOverridable ), typeMode( typeMode ),
 | 
|---|
| [1867c96] | 464 |                         mangleGenericParams( mangleGenericParams ) {}
 | 
|---|
 | 465 | 
 | 
|---|
| [1346914] | 466 |                 void Mangler_new::mangleDecl( const ast::DeclWithType * decl ) {
 | 
|---|
| [1867c96] | 467 |                         bool wasTopLevel = isTopLevel;
 | 
|---|
 | 468 |                         if ( isTopLevel ) {
 | 
|---|
 | 469 |                                 varNums.clear();
 | 
|---|
 | 470 |                                 nextVarNum = 0;
 | 
|---|
 | 471 |                                 isTopLevel = false;
 | 
|---|
 | 472 |                         } // if
 | 
|---|
| [22b5b87] | 473 |                         mangleName += Encoding::manglePrefix;
 | 
|---|
| [60a8062] | 474 |                         const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
 | 
|---|
 | 475 |                         if ( opInfo ) {
 | 
|---|
| [22b5b87] | 476 |                                 mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;
 | 
|---|
| [1867c96] | 477 |                         } else {
 | 
|---|
| [22b5b87] | 478 |                                 mangleName += std::to_string( decl->name.size() ) + decl->name;
 | 
|---|
| [1867c96] | 479 |                         } // if
 | 
|---|
 | 480 |                         maybeAccept( decl->get_type(), *visitor );
 | 
|---|
 | 481 |                         if ( mangleOverridable && decl->linkage.is_overrideable ) {
 | 
|---|
 | 482 |                                 // want to be able to override autogenerated and intrinsic routines,
 | 
|---|
 | 483 |                                 // so they need a different name mangling
 | 
|---|
 | 484 |                                 if ( decl->linkage == ast::Linkage::AutoGen ) {
 | 
|---|
| [22b5b87] | 485 |                                         mangleName += Encoding::autogen;
 | 
|---|
| [1867c96] | 486 |                                 } else if ( decl->linkage == ast::Linkage::Intrinsic ) {
 | 
|---|
| [22b5b87] | 487 |                                         mangleName += Encoding::intrinsic;
 | 
|---|
| [1867c96] | 488 |                                 } else {
 | 
|---|
 | 489 |                                         // if we add another kind of overridable function, this has to change
 | 
|---|
 | 490 |                                         assert( false && "unknown overrideable linkage" );
 | 
|---|
 | 491 |                                 } // if
 | 
|---|
 | 492 |                         }
 | 
|---|
 | 493 |                         isTopLevel = wasTopLevel;
 | 
|---|
 | 494 |                 }
 | 
|---|
 | 495 | 
 | 
|---|
| [1346914] | 496 |                 void Mangler_new::postvisit( const ast::ObjectDecl * decl ) {
 | 
|---|
| [1867c96] | 497 |                         mangleDecl( decl );
 | 
|---|
 | 498 |                 }
 | 
|---|
 | 499 | 
 | 
|---|
| [1346914] | 500 |                 void Mangler_new::postvisit( const ast::FunctionDecl * decl ) {
 | 
|---|
| [1867c96] | 501 |                         mangleDecl( decl );
 | 
|---|
 | 502 |                 }
 | 
|---|
 | 503 | 
 | 
|---|
| [1346914] | 504 |                 void Mangler_new::postvisit( const ast::VoidType * voidType ) {
 | 
|---|
| [1867c96] | 505 |                         printQualifiers( voidType );
 | 
|---|
| [22b5b87] | 506 |                         mangleName += Encoding::void_t;
 | 
|---|
| [1867c96] | 507 |                 }
 | 
|---|
 | 508 | 
 | 
|---|
| [1346914] | 509 |                 void Mangler_new::postvisit( const ast::BasicType * basicType ) {
 | 
|---|
| [1867c96] | 510 |                         printQualifiers( basicType );
 | 
|---|
 | 511 |                         assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
 | 
|---|
| [22b5b87] | 512 |                         mangleName += Encoding::basicTypes[ basicType->kind ];
 | 
|---|
| [1867c96] | 513 |                 }
 | 
|---|
 | 514 | 
 | 
|---|
| [1346914] | 515 |                 void Mangler_new::postvisit( const ast::PointerType * pointerType ) {
 | 
|---|
| [1867c96] | 516 |                         printQualifiers( pointerType );
 | 
|---|
 | 517 |                         // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
 | 
|---|
| [22b5b87] | 518 |                         if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName += Encoding::pointer;
 | 
|---|
| [1867c96] | 519 |                         maybe_accept( pointerType->base.get(), *visitor );
 | 
|---|
 | 520 |                 }
 | 
|---|
 | 521 | 
 | 
|---|
| [1346914] | 522 |                 void Mangler_new::postvisit( const ast::ArrayType * arrayType ) {
 | 
|---|
| [1867c96] | 523 |                         // TODO: encode dimension
 | 
|---|
 | 524 |                         printQualifiers( arrayType );
 | 
|---|
| [22b5b87] | 525 |                         mangleName += Encoding::array + "0";
 | 
|---|
| [1867c96] | 526 |                         maybeAccept( arrayType->base.get(), *visitor );
 | 
|---|
 | 527 |                 }
 | 
|---|
 | 528 | 
 | 
|---|
| [1346914] | 529 |                 void Mangler_new::postvisit( const ast::ReferenceType * refType ) {
 | 
|---|
| [1867c96] | 530 |                         // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
 | 
|---|
 | 531 |                         // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
 | 
|---|
 | 532 |                         // by pretending every reference type is a function parameter.
 | 
|---|
 | 533 |                         GuardValue( inFunctionType );
 | 
|---|
 | 534 |                         inFunctionType = true;
 | 
|---|
 | 535 |                         printQualifiers( refType );
 | 
|---|
 | 536 |                         maybeAccept( refType->base.get(), *visitor );
 | 
|---|
 | 537 |                 }
 | 
|---|
 | 538 | 
 | 
|---|
| [1346914] | 539 |                 inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
 | 
|---|
 | 540 |                         std::vector< ast::ptr< ast::Type > > ret;
 | 
|---|
 | 541 |                         std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
 | 
|---|
 | 542 |                                                         std::mem_fun( &ast::DeclWithType::get_type ) );
 | 
|---|
 | 543 |                         return ret;
 | 
|---|
| [1867c96] | 544 |                 }
 | 
|---|
 | 545 | 
 | 
|---|
| [1346914] | 546 |                 void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
 | 
|---|
| [1867c96] | 547 |                         printQualifiers( functionType );
 | 
|---|
| [22b5b87] | 548 |                         mangleName += Encoding::function;
 | 
|---|
| [1867c96] | 549 |                         // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
 | 
|---|
 | 550 |                         // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
 | 
|---|
 | 551 |                         // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
 | 
|---|
 | 552 |                         GuardValue( inFunctionType );
 | 
|---|
 | 553 |                         inFunctionType = true;
 | 
|---|
| [22b5b87] | 554 |                         if (functionType->returns.empty()) mangleName += Encoding::void_t;
 | 
|---|
| [954c954] | 555 |                         else accept_each( functionType->returns, *visitor );
 | 
|---|
| [22b5b87] | 556 |                         mangleName += "_";
 | 
|---|
| [954c954] | 557 |                         accept_each( functionType->params, *visitor );
 | 
|---|
| [22b5b87] | 558 |                         mangleName += "_";
 | 
|---|
| [1867c96] | 559 |                 }
 | 
|---|
 | 560 | 
 | 
|---|
| [98e8b3b] | 561 |                 void Mangler_new::mangleRef( const ast::BaseInstType * refType, std::string prefix ) {
 | 
|---|
| [1867c96] | 562 |                         printQualifiers( refType );
 | 
|---|
 | 563 | 
 | 
|---|
| [22b5b87] | 564 |                         mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;
 | 
|---|
| [1867c96] | 565 | 
 | 
|---|
 | 566 |                         if ( mangleGenericParams ) {
 | 
|---|
| [1346914] | 567 |                                 if ( ! refType->params.empty() ) {
 | 
|---|
| [22b5b87] | 568 |                                         mangleName += "_";
 | 
|---|
| [1346914] | 569 |                                         for ( const ast::Expr * param : refType->params ) {
 | 
|---|
 | 570 |                                                 auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
 | 
|---|
 | 571 |                                                 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
 | 
|---|
| [1867c96] | 572 |                                                 maybeAccept( paramType->type.get(), *visitor );
 | 
|---|
 | 573 |                                         }
 | 
|---|
| [22b5b87] | 574 |                                         mangleName += "_";
 | 
|---|
| [1867c96] | 575 |                                 }
 | 
|---|
 | 576 |                         }
 | 
|---|
 | 577 |                 }
 | 
|---|
 | 578 | 
 | 
|---|
| [1346914] | 579 |                 void Mangler_new::postvisit( const ast::StructInstType * aggregateUseType ) {
 | 
|---|
| [1867c96] | 580 |                         mangleRef( aggregateUseType, Encoding::struct_t );
 | 
|---|
 | 581 |                 }
 | 
|---|
 | 582 | 
 | 
|---|
| [1346914] | 583 |                 void Mangler_new::postvisit( const ast::UnionInstType * aggregateUseType ) {
 | 
|---|
| [1867c96] | 584 |                         mangleRef( aggregateUseType, Encoding::union_t );
 | 
|---|
 | 585 |                 }
 | 
|---|
 | 586 | 
 | 
|---|
| [1346914] | 587 |                 void Mangler_new::postvisit( const ast::EnumInstType * aggregateUseType ) {
 | 
|---|
| [1867c96] | 588 |                         mangleRef( aggregateUseType, Encoding::enum_t );
 | 
|---|
 | 589 |                 }
 | 
|---|
 | 590 | 
 | 
|---|
| [1346914] | 591 |                 void Mangler_new::postvisit( const ast::TypeInstType * typeInst ) {
 | 
|---|
| [1867c96] | 592 |                         VarMapType::iterator varNum = varNums.find( typeInst->name );
 | 
|---|
 | 593 |                         if ( varNum == varNums.end() ) {
 | 
|---|
 | 594 |                                 mangleRef( typeInst, Encoding::type );
 | 
|---|
 | 595 |                         } else {
 | 
|---|
 | 596 |                                 printQualifiers( typeInst );
 | 
|---|
 | 597 |                                 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
 | 
|---|
 | 598 |                                 //   forall(dtype T) void f(T);
 | 
|---|
 | 599 |                                 //   forall(dtype S) void f(S);
 | 
|---|
 | 600 |                                 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
 | 
|---|
 | 601 |                                 // are first found and prefixing with the appropriate encoding for the type class.
 | 
|---|
 | 602 |                                 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
 | 
|---|
| [22b5b87] | 603 |                                 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );
 | 
|---|
| [1867c96] | 604 |                         } // if
 | 
|---|
 | 605 |                 }
 | 
|---|
 | 606 | 
 | 
|---|
| [1346914] | 607 |                 void Mangler_new::postvisit( const ast::TraitInstType * inst ) {
 | 
|---|
| [1867c96] | 608 |                         printQualifiers( inst );
 | 
|---|
| [22b5b87] | 609 |                         mangleName += std::to_string( inst->name.size() ) + inst->name;
 | 
|---|
| [1867c96] | 610 |                 }
 | 
|---|
 | 611 | 
 | 
|---|
| [1346914] | 612 |                 void Mangler_new::postvisit( const ast::TupleType * tupleType ) {
 | 
|---|
| [1867c96] | 613 |                         printQualifiers( tupleType );
 | 
|---|
| [22b5b87] | 614 |                         mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );
 | 
|---|
| [1346914] | 615 |                         accept_each( tupleType->types, *visitor );
 | 
|---|
| [1867c96] | 616 |                 }
 | 
|---|
 | 617 | 
 | 
|---|
| [1346914] | 618 |                 void Mangler_new::postvisit( const ast::VarArgsType * varArgsType ) {
 | 
|---|
| [1867c96] | 619 |                         printQualifiers( varArgsType );
 | 
|---|
 | 620 |                         static const std::string vargs = "__builtin_va_list";
 | 
|---|
| [22b5b87] | 621 |                         mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;
 | 
|---|
| [1867c96] | 622 |                 }
 | 
|---|
 | 623 | 
 | 
|---|
| [1346914] | 624 |                 void Mangler_new::postvisit( const ast::ZeroType * ) {
 | 
|---|
| [22b5b87] | 625 |                         mangleName += Encoding::zero;
 | 
|---|
| [1867c96] | 626 |                 }
 | 
|---|
 | 627 | 
 | 
|---|
| [1346914] | 628 |                 void Mangler_new::postvisit( const ast::OneType * ) {
 | 
|---|
| [22b5b87] | 629 |                         mangleName += Encoding::one;
 | 
|---|
| [1867c96] | 630 |                 }
 | 
|---|
 | 631 | 
 | 
|---|
| [1346914] | 632 |                 void Mangler_new::postvisit( const ast::QualifiedType * qualType ) {
 | 
|---|
| [1867c96] | 633 |                         bool inqual = inQualifiedType;
 | 
|---|
 | 634 |                         if (! inqual ) {
 | 
|---|
 | 635 |                                 // N marks the start of a qualified type
 | 
|---|
 | 636 |                                 inQualifiedType = true;
 | 
|---|
| [22b5b87] | 637 |                                 mangleName += Encoding::qualifiedTypeStart;
 | 
|---|
| [1867c96] | 638 |                         }
 | 
|---|
 | 639 |                         maybeAccept( qualType->parent.get(), *visitor );
 | 
|---|
 | 640 |                         maybeAccept( qualType->child.get(), *visitor );
 | 
|---|
 | 641 |                         if ( ! inqual ) {
 | 
|---|
 | 642 |                                 // E marks the end of a qualified type
 | 
|---|
 | 643 |                                 inQualifiedType = false;
 | 
|---|
| [22b5b87] | 644 |                                 mangleName += Encoding::qualifiedTypeEnd;
 | 
|---|
| [1867c96] | 645 |                         }
 | 
|---|
 | 646 |                 }
 | 
|---|
 | 647 | 
 | 
|---|
| [1346914] | 648 |                 void Mangler_new::postvisit( const ast::TypeDecl * decl ) {
 | 
|---|
| [1867c96] | 649 |                         // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
 | 
|---|
 | 650 |                         // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
 | 
|---|
 | 651 |                         // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
 | 
|---|
 | 652 |                         // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
 | 
|---|
 | 653 |                         // aside from the assert false.
 | 
|---|
 | 654 |                         assertf(false, "Mangler_new should not visit typedecl: %s", toCString(decl));
 | 
|---|
| [07de76b] | 655 |                         assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
 | 
|---|
| [22b5b87] | 656 |                         mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;
 | 
|---|
| [1867c96] | 657 |                 }
 | 
|---|
 | 658 | 
 | 
|---|
 | 659 |                 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
 | 
|---|
 | 660 |                         for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
 | 
|---|
 | 661 |                                 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
 | 
|---|
 | 662 |                         } // for
 | 
|---|
 | 663 |                 }
 | 
|---|
 | 664 | 
 | 
|---|
| [1346914] | 665 |                 void Mangler_new::printQualifiers( const ast::Type * type ) {
 | 
|---|
| [1867c96] | 666 |                         // skip if not including qualifiers
 | 
|---|
 | 667 |                         if ( typeMode ) return;
 | 
|---|
| [361bf01] | 668 |                         if ( auto ptype = dynamic_cast< const ast::FunctionType * >(type) ) {
 | 
|---|
| [1867c96] | 669 |                                 if ( ! ptype->forall.empty() ) {
 | 
|---|
 | 670 |                                         std::list< std::string > assertionNames;
 | 
|---|
 | 671 |                                         int dcount = 0, fcount = 0, vcount = 0, acount = 0;
 | 
|---|
| [22b5b87] | 672 |                                         mangleName += Encoding::forall;
 | 
|---|
| [3e5dd913] | 673 |                                         for ( auto & decl : ptype->forall ) {
 | 
|---|
| [1346914] | 674 |                                                 switch ( decl->kind ) {
 | 
|---|
| [b66d14a] | 675 |                                                   case ast::TypeDecl::Kind::Dtype:
 | 
|---|
| [1867c96] | 676 |                                                         dcount++;
 | 
|---|
 | 677 |                                                         break;
 | 
|---|
| [b66d14a] | 678 |                                                   case ast::TypeDecl::Kind::Ftype:
 | 
|---|
| [1867c96] | 679 |                                                         fcount++;
 | 
|---|
 | 680 |                                                         break;
 | 
|---|
| [b66d14a] | 681 |                                                   case ast::TypeDecl::Kind::Ttype:
 | 
|---|
| [1867c96] | 682 |                                                         vcount++;
 | 
|---|
 | 683 |                                                         break;
 | 
|---|
| [b66d14a] | 684 |                                                   default:
 | 
|---|
 | 685 |                                                         assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[decl->kind].c_str() );
 | 
|---|
| [1867c96] | 686 |                                                 } // switch
 | 
|---|
| [1346914] | 687 |                                                 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
 | 
|---|
| [3e5dd913] | 688 |                                         } // for
 | 
|---|
 | 689 |                                         for ( auto & assert : ptype->assertions ) {
 | 
|---|
 | 690 |                                                 ast::Pass<Mangler_new> sub_mangler(
 | 
|---|
 | 691 |                                                         mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
 | 
|---|
 | 692 |                                                 assert->var->accept( sub_mangler );
 | 
|---|
 | 693 |                                                 assertionNames.push_back( sub_mangler.core.get_mangleName() );
 | 
|---|
 | 694 |                                                 acount++;
 | 
|---|
| [1867c96] | 695 |                                         } // for
 | 
|---|
| [22b5b87] | 696 |                                         mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";
 | 
|---|
 | 697 |                                         for(const auto & a : assertionNames) mangleName += a;
 | 
|---|
 | 698 | //                                      std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
 | 
|---|
 | 699 |                                         mangleName += "_";
 | 
|---|
| [1867c96] | 700 |                                 } // if
 | 
|---|
 | 701 |                         } // if
 | 
|---|
 | 702 |                         if ( ! inFunctionType ) {
 | 
|---|
 | 703 |                                 // these qualifiers do not distinguish the outermost type of a function parameter
 | 
|---|
 | 704 |                                 if ( type->is_const() ) {
 | 
|---|
| [22b5b87] | 705 |                                         mangleName += Encoding::qualifiers.at(Type::Const);
 | 
|---|
| [1867c96] | 706 |                                 } // if
 | 
|---|
 | 707 |                                 if ( type->is_volatile() ) {
 | 
|---|
| [22b5b87] | 708 |                                         mangleName += Encoding::qualifiers.at(Type::Volatile);
 | 
|---|
| [1867c96] | 709 |                                 } // if
 | 
|---|
 | 710 |                                 // Removed due to restrict not affecting function compatibility in GCC
 | 
|---|
 | 711 |                                 // if ( type->get_isRestrict() ) {
 | 
|---|
| [22b5b87] | 712 |                                 //      mangleName += "E";
 | 
|---|
| [1867c96] | 713 |                                 // } // if
 | 
|---|
 | 714 |                                 if ( type->is_atomic() ) {
 | 
|---|
| [22b5b87] | 715 |                                         mangleName += Encoding::qualifiers.at(Type::Atomic);
 | 
|---|
| [1867c96] | 716 |                                 } // if
 | 
|---|
 | 717 |                         }
 | 
|---|
 | 718 |                         if ( type->is_mutex() ) {
 | 
|---|
| [22b5b87] | 719 |                                 mangleName += Encoding::qualifiers.at(Type::Mutex);
 | 
|---|
| [1867c96] | 720 |                         } // if
 | 
|---|
 | 721 |                         if ( inFunctionType ) {
 | 
|---|
 | 722 |                                 // turn off inFunctionType so that types can be differentiated for nested qualifiers
 | 
|---|
 | 723 |                                 GuardValue( inFunctionType );
 | 
|---|
 | 724 |                                 inFunctionType = false;
 | 
|---|
 | 725 |                         }
 | 
|---|
 | 726 |                 }
 | 
|---|
 | 727 |         }       // namespace
 | 
|---|
| [d76c588] | 728 | } // namespace Mangle
 | 
|---|
 | 729 | 
 | 
|---|
| [0dd3a2f] | 730 | // Local Variables: //
 | 
|---|
 | 731 | // tab-width: 4 //
 | 
|---|
 | 732 | // mode: c++ //
 | 
|---|
 | 733 | // compile-command: "make install" //
 | 
|---|
 | 734 | // End: //
 | 
|---|