source: translator/CodeGen/GenType.cc @ f7f6785

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 f7f6785 was 17cd4eb, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

fixed restrict, fixed parameter copy, introduced name table for types, changed variable after to string

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