source: src/CodeGen/GenType.cc @ c0aa336

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since c0aa336 was c0aa336, checked in by Peter A. Buhr <pabuhr@…>, 5 years ago

third attempt at gcc attributes

  • Property mode set to 100644
File size: 6.8 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// GenType.cc --
8//
9// Author           : Richard C. Bilson
10// Created On       : Mon May 18 07:44:20 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Thu Feb  2 13:53:43 2017
13// Update Count     : 20
14//
15
16#include <sstream>
17#include <cassert>
18
19#include "GenType.h"
20#include "CodeGenerator.h"
21
22#include "SynTree/Declaration.h"
23#include "SynTree/Expression.h"
24#include "SynTree/Type.h"
25#include "SynTree/Visitor.h"
26
27namespace CodeGen {
28        class GenType : public Visitor {
29          public:
30                GenType( const std::string &typeString, bool mangle = true );
31                std::string get_typeString() const { return typeString; }
32                void set_typeString( const std::string &newValue ) { typeString = newValue; }
33
34                virtual void visit( FunctionType *funcType );
35                virtual void visit( VoidType *voidType );
36                virtual void visit( BasicType *basicType );
37                virtual void visit( PointerType *pointerType );
38                virtual void visit( ArrayType *arrayType );
39                virtual void visit( StructInstType *structInst );
40                virtual void visit( UnionInstType *unionInst );
41                virtual void visit( EnumInstType *enumInst );
42                virtual void visit( TypeInstType *typeInst );
43                virtual void visit( TupleType * tupleType );
44                virtual void visit( VarArgsType *varArgsType );
45                virtual void visit( ZeroType *zeroType );
46                virtual void visit( OneType *oneType );
47
48          private:
49                void handleQualifiers( Type *type );
50                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
51
52                std::string typeString;
53                bool mangle = true;
54        };
55
56        std::string genType( Type *type, const std::string &baseString, bool mangle ) {
57                GenType gt( baseString, mangle );
58                std::ostringstream os;
59               
60                if ( ! type->get_attributes().empty() ) {
61                        CodeGenerator cg( os, mangle );
62                        cg.genAttributes( type->get_attributes() );
63                } // if
64
65                type->accept( gt );
66                return os.str() + gt.get_typeString();
67        }
68
69        GenType::GenType( const std::string &typeString, bool mangle ) : typeString( typeString ), mangle( mangle ) {}
70
71        void GenType::visit( VoidType *voidType ) {
72                typeString = "void " + typeString;
73                handleQualifiers( voidType );
74        }
75
76        void GenType::visit( BasicType *basicType ) {
77                BasicType::Kind kind = basicType->get_kind();
78                assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
79                typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
80                handleQualifiers( basicType );
81        }
82
83        void GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) {
84                std::ostringstream os;
85                if ( typeString != "" ) {
86                        if ( typeString[ 0 ] == '*' ) {
87                                os << "(" << typeString << ")";
88                        } else {
89                                os << typeString;
90                        } // if
91                } // if
92                os << "[";
93
94                if ( isStatic ) {
95                        os << "static ";
96                } // if
97                if ( qualifiers.isConst ) {
98                        os << "const ";
99                } // if
100                if ( qualifiers.isVolatile ) {
101                        os << "volatile ";
102                } // if
103                if ( qualifiers.isRestrict ) {
104                        os << "__restrict ";
105                } // if
106                if ( qualifiers.isAtomic ) {
107                        os << "_Atomic ";
108                } // if
109                if ( dimension != 0 ) {
110                        CodeGenerator cg( os, mangle );
111                        dimension->accept( cg );
112                } else if ( isVarLen ) {
113                        // no dimension expression on a VLA means it came in with the * token
114                        os << "*";
115                } // if
116                os << "]";
117
118                typeString = os.str();
119
120                base->accept( *this );
121        }
122
123        void GenType::visit( PointerType *pointerType ) {
124                assert( pointerType->get_base() != 0);
125                if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
126                        genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
127                } else {
128                        handleQualifiers( pointerType );
129                        if ( typeString[ 0 ] == '?' ) {
130                                typeString = "* " + typeString;
131                        } else {
132                                typeString = "*" + typeString;
133                        } // if
134                        pointerType->get_base()->accept( *this );
135                } // if
136        }
137
138        void GenType::visit( ArrayType *arrayType ) {
139                genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
140        }
141
142        void GenType::visit( FunctionType *funcType ) {
143                std::ostringstream os;
144
145                if ( typeString != "" ) {
146                        if ( typeString[ 0 ] == '*' ) {
147                                os << "(" << typeString << ")";
148                        } else {
149                                os << typeString;
150                        } // if
151                } // if
152
153                /************* parameters ***************/
154
155                const std::list<DeclarationWithType *> &pars = funcType->get_parameters();
156
157                if ( pars.empty() ) {
158                        if ( funcType->get_isVarArgs() ) {
159                                os << "()";
160                        } else {
161                                os << "(void)";
162                        } // if
163                } else {
164                        CodeGenerator cg( os, mangle );
165                        os << "(" ;
166
167                        cg.genCommaList( pars.begin(), pars.end() );
168
169                        if ( funcType->get_isVarArgs() ) {
170                                os << ", ...";
171                        } // if
172                        os << ")";
173                } // if
174
175                typeString = os.str();
176
177                if ( funcType->get_returnVals().size() == 0 ) {
178                        typeString = "void " + typeString;
179                } else {
180                        funcType->get_returnVals().front()->get_type()->accept( *this );
181                } // if
182        }
183
184        void GenType::visit( StructInstType *structInst )  {
185                typeString = "struct " + structInst->get_name() + " " + typeString;
186                handleQualifiers( structInst );
187        }
188
189        void GenType::visit( UnionInstType *unionInst ) {
190                typeString = "union " + unionInst->get_name() + " " + typeString;
191                handleQualifiers( unionInst );
192        }
193
194        void GenType::visit( EnumInstType *enumInst ) {
195                typeString = "enum " + enumInst->get_name() + " " + typeString;
196                handleQualifiers( enumInst );
197        }
198
199        void GenType::visit( TypeInstType *typeInst ) {
200                typeString = typeInst->get_name() + " " + typeString;
201                handleQualifiers( typeInst );
202        }
203
204        void GenType::visit( TupleType * tupleType ) {
205                assertf( ! mangle, "Tuple types should not make it to Code Gen." );
206                Visitor::visit( tupleType );
207        }
208
209        void GenType::visit( VarArgsType *varArgsType ) {
210                typeString = "__builtin_va_list " + typeString;
211                handleQualifiers( varArgsType );
212        }
213
214        void GenType::visit( ZeroType *zeroType ) {
215                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
216                typeString = "long int " + typeString;
217                handleQualifiers( zeroType );
218        }
219
220        void GenType::visit( OneType *oneType ) {
221                // ideally these wouldn't hit codegen at all, but should be safe to make them ints
222                typeString = "long int " + typeString;
223                handleQualifiers( oneType );
224        }
225
226        void GenType::handleQualifiers( Type *type ) {
227                if ( type->get_isConst() ) {
228                        typeString = "const " + typeString;
229                } // if
230                if ( type->get_isVolatile() ) {
231                        typeString = "volatile " + typeString;
232                } // if
233                if ( type->get_isRestrict() ) {
234                        typeString = "__restrict " + typeString;
235                } // if
236                if ( type->get_isAtomic() ) {
237                        typeString = "_Atomic " + typeString;
238                } // if
239        }
240} // namespace CodeGen
241
242// Local Variables: //
243// tab-width: 4 //
244// mode: c++ //
245// compile-command: "make install" //
246// End: //
Note: See TracBrowser for help on using the repository browser.