source: src/CodeGen/GenType.cc @ cc79d97

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since cc79d97 was 5f2f2d7, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

fix constant types, remove unnecessary string copying, work on regression testing, fix several memory leaks

  • Property mode set to 100644
File size: 5.6 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 : Mon Jun  8 14:36:02 2015
13// Update Count     : 9
14//
15
16#include <sstream>
17#include <cassert>
18
19#include "GenType.h"
20#include "CodeGenerator.h"
21#include "SynTree/Visitor.h"
22#include "SynTree/Type.h"
23#include "SynTree/Expression.h"
24
25namespace CodeGen {
26        class GenType : public Visitor {
27          public:
28                GenType( const std::string &typeString );
29                std::string get_typeString() const { return typeString; }
30                void set_typeString( const std::string &newValue ) { typeString = newValue; }
31 
32                virtual void visit( FunctionType *funcType );
33                virtual void visit( VoidType *voidType );
34                virtual void visit( BasicType *basicType );
35                virtual void visit( PointerType *pointerType );
36                virtual void visit( ArrayType *arrayType );
37                virtual void visit( StructInstType *structInst );
38                virtual void visit( UnionInstType *unionInst );
39                virtual void visit( EnumInstType *enumInst );
40                virtual void visit( TypeInstType *typeInst );
41 
42          private:
43                void handleQualifiers( Type *type );
44                void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic );
45 
46                std::string typeString;
47        };
48
49        std::string genType( Type *type, const std::string &baseString ) {
50                GenType gt( baseString );
51                type->accept( gt );
52                return gt.get_typeString();
53        }
54
55        GenType::GenType( const std::string &typeString ) : typeString( typeString ) {}
56
57        void GenType::visit( VoidType *voidType ) {
58                typeString = "void " + typeString;
59                handleQualifiers( voidType );
60        }
61
62        void GenType::visit( BasicType *basicType ) {
63                BasicType::Kind kind = basicType->get_kind();
64                assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES );
65                typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString;
66                handleQualifiers( basicType );
67        }
68
69        void GenType::genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) {
70                std::ostringstream os;
71                if ( typeString != "" ) {
72                        if ( typeString[ 0 ] == '*' ) {
73                                os << "(" << typeString << ")";
74                        } else {
75                                os << typeString;
76                        } // if
77                } // if
78                os << "[";
79
80                if ( isStatic ) {
81                        os << "static ";
82                } // if
83                if ( qualifiers.isConst ) {
84                        os << "const ";
85                } // if
86                if ( qualifiers.isVolatile ) {
87                        os << "volatile ";
88                } // if
89                if ( qualifiers.isRestrict ) {
90                        os << "__restrict ";
91                } // if
92                if ( qualifiers.isAtomic ) {
93                        os << "_Atomic ";
94                } // if
95                if ( isVarLen ) {
96                        os << "*";
97                } // if
98                if ( dimension != 0 ) {
99                        CodeGenerator cg( os );
100                        dimension->accept( cg );
101                } // if
102                os << "]";
103
104                typeString = os.str();
105 
106                base->accept( *this );
107        }
108
109        void GenType::visit( PointerType *pointerType ) {
110                assert( pointerType->get_base() != 0);
111                if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
112                        genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
113                } else {
114                        handleQualifiers( pointerType );
115                        if ( typeString[ 0 ] == '?' ) {
116                                typeString = "* " + typeString;
117                        } else {
118                                typeString = "*" + typeString;
119                        } // if
120                        pointerType->get_base()->accept( *this );
121                } // if
122        }
123
124        void GenType::visit( ArrayType *arrayType ) {
125                genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
126        }
127
128        void GenType::visit( FunctionType *funcType ) {
129                std::ostringstream os;
130
131                if ( typeString != "" ) {
132                        if ( typeString[ 0 ] == '*' ) {
133                                os << "(" << typeString << ")";
134                        } else {
135                                os << typeString;
136                        } // if
137                } // if
138 
139                /************* parameters ***************/
140
141                const std::list<DeclarationWithType *> &pars = funcType->get_parameters();
142
143                if ( pars.empty() ) {
144                        if ( funcType->get_isVarArgs() ) {
145                                os << "()";
146                        } else {
147                                os << "(void)";
148                        } // if
149                } else {
150                        CodeGenerator cg( os );
151                        os << "(" ;
152
153                        cg.genCommaList( pars.begin(), pars.end() );
154
155                        if ( funcType->get_isVarArgs() ) {
156                                os << ", ...";
157                        } // if
158                        os << ")";
159                } // if
160 
161                typeString = os.str();
162
163                if ( funcType->get_returnVals().size() == 0 ) {
164                        typeString = "void " + typeString;
165                } else {
166                        funcType->get_returnVals().front()->get_type()->accept( *this );
167                } // if
168        }
169
170        void GenType::visit( StructInstType *structInst )  {
171                typeString = "struct " + structInst->get_name() + " " + typeString;
172                handleQualifiers( structInst );
173        }
174
175        void GenType::visit( UnionInstType *unionInst ) {
176                typeString = "union " + unionInst->get_name() + " " + typeString;
177                handleQualifiers( unionInst );
178        }
179
180        void GenType::visit( EnumInstType *enumInst ) {
181                typeString = "enum " + enumInst->get_name() + " " + typeString;
182                handleQualifiers( enumInst );
183        }
184
185        void GenType::visit( TypeInstType *typeInst ) {
186                typeString = typeInst->get_name() + " " + typeString;
187                handleQualifiers( typeInst );
188        }
189
190        void GenType::handleQualifiers( Type *type ) {
191                if ( type->get_isConst() ) {
192                        typeString = "const " + typeString;
193                } // if
194                if ( type->get_isVolatile() ) {
195                        typeString = "volatile " + typeString;
196                } // if
197                if ( type->get_isRestrict() ) {
198                        typeString = "__restrict " + typeString;
199                } // if
200                if ( type->get_isAtomic() ) {
201                        typeString = "_Atomic " + typeString;
202                } // if
203        }
204} // namespace CodeGen
205
206// Local Variables: //
207// tab-width: 4 //
208// mode: c++ //
209// compile-command: "make install" //
210// End: //
Note: See TracBrowser for help on using the repository browser.