source: src/CodeGen/GenType.cc @ 71bd8c6

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglergc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newstringwith_gc
Last change on this file since 71bd8c6 was 71bd8c6, checked in by Rob Schluntz <rschlunt@…>, 6 years ago

fix isVarLen in array types, fix loss of typedef when variable of aggregate type is declared, fix duplicate typedef with arrays of constant size

  • Property mode set to 100644
File size: 5.7 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 : Rob Schluntz
12// Last Modified On : Wed Jul 08 16:08:24 2015
13// Update Count     : 10
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 ( dimension != 0 ) {
96                        CodeGenerator cg( os );
97                        dimension->accept( cg );
98                } else if ( isVarLen ) {
99                        // no dimension expression on a VLA
100                        // means it came in with the * token
101                        os << "*";
102                } // if
103                os << "]";
104
105                typeString = os.str();
106 
107                base->accept( *this );
108        }
109
110        void GenType::visit( PointerType *pointerType ) {
111                assert( pointerType->get_base() != 0);
112                if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->get_dimension() ) {
113                        genArray( pointerType->get_qualifiers(), pointerType->get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );
114                } else {
115                        handleQualifiers( pointerType );
116                        if ( typeString[ 0 ] == '?' ) {
117                                typeString = "* " + typeString;
118                        } else {
119                                typeString = "*" + typeString;
120                        } // if
121                        pointerType->get_base()->accept( *this );
122                } // if
123        }
124
125        void GenType::visit( ArrayType *arrayType ) {
126                genArray( arrayType->get_qualifiers(), arrayType->get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );
127        }
128
129        void GenType::visit( FunctionType *funcType ) {
130                std::ostringstream os;
131
132                if ( typeString != "" ) {
133                        if ( typeString[ 0 ] == '*' ) {
134                                os << "(" << typeString << ")";
135                        } else {
136                                os << typeString;
137                        } // if
138                } // if
139 
140                /************* parameters ***************/
141
142                const std::list<DeclarationWithType *> &pars = funcType->get_parameters();
143
144                if ( pars.empty() ) {
145                        if ( funcType->get_isVarArgs() ) {
146                                os << "()";
147                        } else {
148                                os << "(void)";
149                        } // if
150                } else {
151                        CodeGenerator cg( os );
152                        os << "(" ;
153
154                        cg.genCommaList( pars.begin(), pars.end() );
155
156                        if ( funcType->get_isVarArgs() ) {
157                                os << ", ...";
158                        } // if
159                        os << ")";
160                } // if
161 
162                typeString = os.str();
163
164                if ( funcType->get_returnVals().size() == 0 ) {
165                        typeString = "void " + typeString;
166                } else {
167                        funcType->get_returnVals().front()->get_type()->accept( *this );
168                } // if
169        }
170
171        void GenType::visit( StructInstType *structInst )  {
172                typeString = "struct " + structInst->get_name() + " " + typeString;
173                handleQualifiers( structInst );
174        }
175
176        void GenType::visit( UnionInstType *unionInst ) {
177                typeString = "union " + unionInst->get_name() + " " + typeString;
178                handleQualifiers( unionInst );
179        }
180
181        void GenType::visit( EnumInstType *enumInst ) {
182                typeString = "enum " + enumInst->get_name() + " " + typeString;
183                handleQualifiers( enumInst );
184        }
185
186        void GenType::visit( TypeInstType *typeInst ) {
187                typeString = typeInst->get_name() + " " + typeString;
188                handleQualifiers( typeInst );
189        }
190
191        void GenType::handleQualifiers( Type *type ) {
192                if ( type->get_isConst() ) {
193                        typeString = "const " + typeString;
194                } // if
195                if ( type->get_isVolatile() ) {
196                        typeString = "volatile " + typeString;
197                } // if
198                if ( type->get_isRestrict() ) {
199                        typeString = "__restrict " + typeString;
200                } // if
201                if ( type->get_isAtomic() ) {
202                        typeString = "_Atomic " + typeString;
203                } // if
204        }
205} // namespace CodeGen
206
207// Local Variables: //
208// tab-width: 4 //
209// mode: c++ //
210// compile-command: "make install" //
211// End: //
Note: See TracBrowser for help on using the repository browser.