source: src/CodeGen/GenType.cc @ 1db21619

aaron-thesisarm-ehcleanup-dtorsctordeferred_resndemanglergc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newstringwith_gc
Last change on this file since 1db21619 was 1db21619, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

add CFA flag, remove -p from cc1, typedef on functions become function declarations, move isInline/isNoreturn to Declaration, cleaned up label code

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