source: src/SymTab/Mangler.cc @ 8135d4c

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 8135d4c was 8135d4c, checked in by Rob Schluntz <rschlunt@…>, 7 years ago

Merge branch 'master' into references

  • Property mode set to 100644
File size: 10.0 KB
Line 
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//
7// Mangler.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Sun May 17 21:40:29 2015
11// Last Modified By : Andrew Beach
12// Last Modified On : Wed Jun 28 15:31:00 2017
13// Update Count     : 21
14//
15#include "Mangler.h"
16
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
25#include "Common/SemanticError.h"   // for SemanticError
26#include "Common/utility.h"         // for toString
27#include "Parser/LinkageSpec.h"     // for Spec, isOverridable, AutoGen, Int...
28#include "SynTree/Declaration.h"    // for TypeDecl, DeclarationWithType
29#include "SynTree/Expression.h"     // for TypeExpr, Expression, operator<<
30#include "SynTree/Type.h"           // for Type, ReferenceToType, Type::Fora...
31
32namespace SymTab {
33        std::string Mangler::mangleType( Type *ty ) {
34                Mangler mangler( false, true );
35                maybeAccept( ty, mangler );
36                return mangler.get_mangleName();
37        }
38
39        Mangler::Mangler( bool mangleOverridable, bool typeMode )
40                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ) {}
41
42        Mangler::Mangler( const Mangler &rhs ) : mangleName() {
43                varNums = rhs.varNums;
44                nextVarNum = rhs.nextVarNum;
45                isTopLevel = rhs.isTopLevel;
46                mangleOverridable = rhs.mangleOverridable;
47                typeMode = rhs.typeMode;
48        }
49
50        void Mangler::mangleDecl( DeclarationWithType *declaration ) {
51                bool wasTopLevel = isTopLevel;
52                if ( isTopLevel ) {
53                        varNums.clear();
54                        nextVarNum = 0;
55                        isTopLevel = false;
56                } // if
57                mangleName << "__";
58                CodeGen::OperatorInfo opInfo;
59                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
60                        mangleName << opInfo.outputName;
61                } else {
62                        mangleName << declaration->get_name();
63                } // if
64                mangleName << "__";
65                maybeAccept( declaration->get_type(), *this );
66                if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
67                        // want to be able to override autogenerated and intrinsic routines,
68                        // so they need a different name mangling
69                        if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
70                                mangleName << "autogen__";
71                        } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
72                                mangleName << "intrinsic__";
73                        } else {
74                                // if we add another kind of overridable function, this has to change
75                                assert( false && "unknown overrideable linkage" );
76                        } // if
77                }
78                isTopLevel = wasTopLevel;
79        }
80
81        void Mangler::visit( ObjectDecl *declaration ) {
82                mangleDecl( declaration );
83        }
84
85        void Mangler::visit( FunctionDecl *declaration ) {
86                mangleDecl( declaration );
87        }
88
89        void Mangler::visit( VoidType *voidType ) {
90                printQualifiers( voidType );
91                mangleName << "v";
92        }
93
94        void Mangler::visit( BasicType *basicType ) {
95                static const char *btLetter[] = {
96                        "b",    // Bool
97                        "c",    // Char
98                        "Sc",   // SignedChar
99                        "Uc",   // UnsignedChar
100                        "s",    // ShortSignedInt
101                        "Us",   // ShortUnsignedInt
102                        "i",    // SignedInt
103                        "Ui",   // UnsignedInt
104                        "l",    // LongSignedInt
105                        "Ul",   // LongUnsignedInt
106                        "q",    // LongLongSignedInt
107                        "Uq",   // LongLongUnsignedInt
108                        "f",    // Float
109                        "d",    // Double
110                        "r",    // LongDouble
111                        "Xf",   // FloatComplex
112                        "Xd",   // DoubleComplex
113                        "Xr",   // LongDoubleComplex
114                        "If",   // FloatImaginary
115                        "Id",   // DoubleImaginary
116                        "Ir",   // LongDoubleImaginary
117                };
118
119                printQualifiers( basicType );
120                mangleName << btLetter[ basicType->get_kind() ];
121        }
122
123        void Mangler::visit( PointerType *pointerType ) {
124                printQualifiers( pointerType );
125                mangleName << "P";
126                maybeAccept( pointerType->get_base(), *this );
127        }
128
129        void Mangler::visit( ArrayType *arrayType ) {
130                // TODO: encode dimension
131                printQualifiers( arrayType );
132                mangleName << "A0";
133                maybeAccept( arrayType->get_base(), *this );
134        }
135
136        void Mangler::visit( ReferenceType *refType ) {
137                printQualifiers( refType );
138                mangleName << "R";
139                maybeAccept( refType->get_base(), *this );
140        }
141
142        namespace {
143                inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
144                        std::list< Type* > ret;
145                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
146                                                        std::mem_fun( &DeclarationWithType::get_type ) );
147                        return ret;
148                }
149        }
150
151        void Mangler::visit( FunctionType *functionType ) {
152                printQualifiers( functionType );
153                mangleName << "F";
154                std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
155                acceptAll( returnTypes, *this );
156                mangleName << "_";
157                std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
158                acceptAll( paramTypes, *this );
159                mangleName << "_";
160        }
161
162        void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
163                printQualifiers( refType );
164
165                mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
166        }
167
168        void Mangler::mangleGenericRef( ReferenceToType *refType, std::string prefix ) {
169                printQualifiers( refType );
170
171                std::ostringstream oldName( mangleName.str() );
172                mangleName.clear();
173
174                mangleName << prefix << refType->get_name();
175
176                std::list< Expression* >& params = refType->get_parameters();
177                if ( ! params.empty() ) {
178                        mangleName << "_";
179                        for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
180                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
181                                assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
182                                maybeAccept( paramType->get_type(), *this );
183                        }
184                        mangleName << "_";
185                }
186
187                oldName << mangleName.str().length() << mangleName.str();
188                mangleName.str( oldName.str() );
189        }
190
191        void Mangler::visit( StructInstType *aggregateUseType ) {
192                if ( typeMode ) mangleGenericRef( aggregateUseType, "s" );
193                else mangleRef( aggregateUseType, "s" );
194        }
195
196        void Mangler::visit( UnionInstType *aggregateUseType ) {
197                if ( typeMode ) mangleGenericRef( aggregateUseType, "u" );
198                else mangleRef( aggregateUseType, "u" );
199        }
200
201        void Mangler::visit( EnumInstType *aggregateUseType ) {
202                mangleRef( aggregateUseType, "e" );
203        }
204
205        void Mangler::visit( TypeInstType *typeInst ) {
206                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
207                if ( varNum == varNums.end() ) {
208                        mangleRef( typeInst, "t" );
209                } else {
210                        printQualifiers( typeInst );
211                        std::ostringstream numStream;
212                        numStream << varNum->second.first;
213                        switch ( (TypeDecl::Kind )varNum->second.second ) {
214                          case TypeDecl::Any:
215                                mangleName << "t";
216                                break;
217                          case TypeDecl::Dtype:
218                                mangleName << "d";
219                                break;
220                          case TypeDecl::Ftype:
221                                mangleName << "f";
222                                break;
223                                case TypeDecl::Ttype:
224                                mangleName << "tVARGS";
225                                break;
226                                default:
227                                assert( false );
228                        } // switch
229                        mangleName << numStream.str();
230                } // if
231        }
232
233        void Mangler::visit( TupleType *tupleType ) {
234                printQualifiers( tupleType );
235                mangleName << "T";
236                acceptAll( tupleType->get_types(), *this );
237                mangleName << "_";
238        }
239
240        void Mangler::visit( VarArgsType *varArgsType ) {
241                printQualifiers( varArgsType );
242                mangleName << "VARGS";
243        }
244
245        void Mangler::visit( __attribute__((unused)) ZeroType *zeroType ) {
246                mangleName << "Z";
247        }
248
249        void Mangler::visit( __attribute__((unused)) OneType *oneType ) {
250                mangleName << "O";
251        }
252
253        void Mangler::visit( TypeDecl *decl ) {
254                static const char *typePrefix[] = { "BT", "BD", "BF" };
255                mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
256        }
257
258        void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
259                for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
260                        os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
261                } // for
262        }
263
264        void Mangler::printQualifiers( Type *type ) {
265                // skip if not including qualifiers
266                if ( typeMode ) return;
267
268                if ( ! type->get_forall().empty() ) {
269                        std::list< std::string > assertionNames;
270                        int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
271                        mangleName << "A";
272                        for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
273                                switch ( (*i)->get_kind() ) {
274                                  case TypeDecl::Any:
275                                        tcount++;
276                                        break;
277                                  case TypeDecl::Dtype:
278                                        dcount++;
279                                        break;
280                                  case TypeDecl::Ftype:
281                                        fcount++;
282                                        break;
283                                  case TypeDecl::Ttype:
284                                        vcount++;
285                                        break;
286                                  default:
287                                        assert( false );
288                                } // switch
289                                varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
290                                for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
291                                        Mangler sub_mangler( mangleOverridable, typeMode );
292                                        sub_mangler.nextVarNum = nextVarNum;
293                                        sub_mangler.isTopLevel = false;
294                                        sub_mangler.varNums = varNums;
295                                        (*assert)->accept( sub_mangler );
296                                        assertionNames.push_back( sub_mangler.mangleName.str() );
297                                } // for
298                        } // for
299                        mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
300                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
301                        mangleName << "_";
302                } // if
303                if ( type->get_const() ) {
304                        mangleName << "C";
305                } // if
306                if ( type->get_volatile() ) {
307                        mangleName << "V";
308                } // if
309                // Removed due to restrict not affecting function compatibility in GCC
310//              if ( type->get_isRestrict() ) {
311//                      mangleName << "E";
312//              } // if
313                if ( type->get_lvalue() ) {
314                        mangleName << "L";
315                } // if
316                if ( type->get_atomic() ) {
317                        mangleName << "A";
318                } // if
319        }
320} // namespace SymTab
321
322// Local Variables: //
323// tab-width: 4 //
324// mode: c++ //
325// compile-command: "make install" //
326// End: //
Note: See TracBrowser for help on using the repository browser.