source: src/Parser/ExpressionNode.cc @ bf4b4cf

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since bf4b4cf was bf4b4cf, checked in by Rob Schluntz <rschlunt@…>, 4 years ago

Remove argName from Expression.

If named arguments are ever considered again, they should be added in UntypedExpr? (and maybe also ApplicationExpr?) to avoid unnecessary fields in every Expression. Like designators on initializers, it should be much easier to work with argument names at the call expression level.

  • Property mode set to 100644
File size: 20.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// ExpressionNode.cc --
8//
9// Author           : Peter A. Buhr
10// Created On       : Sat May 16 13:17:07 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Tue Sep 26 11:23:36 2017
13// Update Count     : 780
14//
15
16#include <cassert>                 // for assert
17#include <stdio.h>                 // for sscanf, size_t
18#include <climits>                 // for LLONG_MAX, LONG_MAX, INT_MAX, UINT...
19#include <list>                    // for list
20#include <sstream>                 // for basic_istream::operator>>, basic_i...
21#include <string>                  // for string, operator+, operator==
22
23#include "Common/SemanticError.h"  // for SemanticError
24#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild, CodeLo...
25#include "ParseNode.h"             // for ExpressionNode, maybeMoveBuildType
26#include "SynTree/Constant.h"      // for Constant
27#include "SynTree/Declaration.h"   // for EnumDecl, StructDecl, UnionDecl
28#include "SynTree/Expression.h"    // for Expression, ConstantExpr, NameExpr
29#include "SynTree/Statement.h"     // for CompoundStmt, Statement
30#include "SynTree/Type.h"          // for BasicType, Type, Type::Qualifiers
31#include "parserutility.h"         // for notZeroExpr
32
33class Initializer;
34
35using namespace std;
36
37//##############################################################################
38
39// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
40//
41//              prefix action constant action suffix
42//
43// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
44//
45//              constant BEGIN CONT ...
46//              <CONT>(...)? BEGIN 0 ... // possible empty suffix
47//
48// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
49// type.
50
51extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
52
53static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
54static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
55static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
56static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
57static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
58static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
59static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
60static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
61
62static const char * lnthsInt[2][6] = {
63        { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", },
64        { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", }
65}; // lnthsInt
66
67static inline void checkLNInt( string & str, int & lnth, int & size ) {
68        string::size_type posn = str.find_first_of( "lL" ), start = posn;
69  if ( posn == string::npos ) return;
70        size = 4;                                                                                       // assume largest size
71        posn += 1;                                                                                      // advance to size
72        if ( str[posn] == '8' ) {                                                       // 8
73                lnth = 0;
74        } else if ( str[posn] == '1' ) {
75                posn += 1;
76                if ( str[posn] == '6' ) {                                               // 16
77                        lnth = 1;
78                } else {                                                                                // 128
79                        posn += 1;
80                        lnth = 5;
81                } // if
82        } else {
83                if ( str[posn] == '3' ) {                                               // 32
84                        lnth = 2;
85                } else if ( str[posn] == '6' ) {                                // 64
86                        lnth = 3;
87                } else {
88                        assertf( false, "internal error, bad integral length %s", str.c_str() );
89                } // if
90                posn += 1;
91        } // if
92        str.erase( start, posn - start + 1 );                           // remove length suffix
93} // checkLNInt
94
95static void sepNumeric( string & str, string & units ) {
96        string::size_type posn = str.find_first_of( "`" );
97        if ( posn != string::npos ) {
98                units = "?" + str.substr( posn );                               // extract units
99                str.erase( posn );                                                              // remove units
100        } // if
101} // sepNumeric
102
103Expression * build_constantInteger( string & str ) {
104        static const BasicType::Kind kind[2][6] = {
105                // short (h) must be before char (hh)
106                { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
107                { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
108        };
109
110        string units;
111        sepNumeric( str, units );                                                       // separate constant from units
112
113        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
114        int size;                                                                                       // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
115        int lnth = -1;                                                                          // literal length
116
117        unsigned long long int v;                                                       // converted integral value
118        size_t last = str.length() - 1;                                         // last character of constant
119        Expression * ret;
120
121        // special constants
122        if ( str == "0" ) {
123                ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) );
124                goto CLEANUP;
125        } // if
126        if ( str == "1" ) {
127                ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) );
128                goto CLEANUP;
129        } // if
130
131        if ( str[0] == '0' ) {                                                          // octal/hex constant ?
132                dec = false;
133                if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
134                        sscanf( (char *)str.c_str(), "%llx", &v );
135                        //printf( "%llx %llu\n", v, v );
136                } else {                                                                                // octal constant
137                        sscanf( (char *)str.c_str(), "%llo", &v );
138                        //printf( "%llo %llu\n", v, v );
139                } // if
140        } else {                                                                                        // decimal constant ?
141                sscanf( (char *)str.c_str(), "%llu", &v );
142                //printf( "%llu %llu\n", v, v );
143        } // if
144
145        if ( v <= INT_MAX ) {                                                           // signed int
146                size = 2;
147        } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
148                size = 2;
149                Unsigned = true;                                                                // unsigned
150        } else if ( v <= LONG_MAX ) {                                           // signed long int
151                size = 3;
152        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
153                size = 3;
154                Unsigned = true;                                                                // unsigned long int
155        } else if ( v <= LLONG_MAX ) {                                          // signed long long int
156                size = 4;
157        } else {                                                                                        // unsigned long long int
158                size = 4;
159                Unsigned = true;                                                                // unsigned long long int
160        } // if
161
162        // At least one digit in integer constant, so safe to backup while looking for suffix.
163
164        if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
165                Unsigned = true;
166                if ( checkL( str[last - 1] ) ) {                                // suffix 'l' ?
167                        size = 3;
168                        if ( checkL( str[last - 2] ) ) {                        // suffix "ll" ?
169                                size = 4;
170                        } // if
171                } else if ( checkH( str[last - 1] ) ) {                 // suffix 'h' ?
172                        size = 0;
173                        if ( checkH( str[last - 2] ) ) {                        // suffix "hh" ?
174                                size = 1;
175                        } // if
176                        str.erase( last - size - 1, size + 1 );         // remove 'h'/"hh"
177                } else {                                                                                // suffix "ln" ?
178                        checkLNInt( str, lnth, size );
179                } // if
180        } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
181                size = 3;
182                if ( checkL( str[last - 1] ) ) {                                // suffix 'll' ?
183                        size = 4;
184                        if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
185                                Unsigned = true;
186                        } // if
187                } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
188                        Unsigned = true;
189                } // if
190        } else if ( checkH( str[ last ] ) ) {                           // suffix 'h' ?
191                size = 0;
192                if ( checkH( str[last - 1] ) ) {                                // suffix "hh" ?
193                        size = 1;
194                        if ( checkU( str[last - 2] ) ) {                        // suffix 'u' ?
195                                Unsigned = true;
196                        } // if
197                } else if ( checkU( str[last - 1] ) ) {                 // suffix 'u' ?
198                        Unsigned = true;
199                } // if
200                str.erase( last - size, size + 1 );                             // remove 'h'/"hh"
201        } else if ( checkZ( str[last] ) ) {                                     // suffix 'z' ?
202                lnth = 4;
203                str.erase( last, 1 );                                                   // remove 'z'
204        } else {                                                                                        // suffix "ln" ?
205                checkLNInt( str, lnth, size );
206        } // if
207
208        assert( 0 <= size && size < 6 );
209        ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
210        if ( size < 2 ) {                                                                       // hh or h, less than int ?
211                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
212                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
213        } else if ( lnth != -1 ) {                                                      // explicit length ?
214                if ( lnth == 5 ) {                                                              // int128 ?
215                        size = 5;
216                        ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
217                } else {
218                        ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ) );
219                } // if
220        } // if
221  CLEANUP:
222        if ( units.length() != 0 ) {
223                ret = new UntypedExpr( new NameExpr( units ), { ret } );
224        } // if
225
226        delete &str;                                                                            // created by lex
227        return ret;
228} // build_constantInteger
229
230
231static inline void checkLNFloat( string & str, int & lnth, int & size ) {
232        string::size_type posn = str.find_first_of( "lL" ), start = posn;
233  if ( posn == string::npos ) return;
234        size = 2;                                                                                       // assume largest size
235        lnth = 0;
236        posn += 1;                                                                                      // advance to size
237        if ( str[posn] == '3' ) {                                                       // 32
238                size = 0;
239        } else if ( str[posn] == '6' ) {                                        // 64
240                size = 1;
241        } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128
242                size = 2;
243                if ( str[posn] == '1' ) posn += 1;
244        } else {
245                assertf( false, "internal error, bad floating point length %s", str.c_str() );
246        } // if
247        posn += 1;
248        str.erase( start, posn - start + 1 );                           // remove length suffix
249} // checkLNFloat
250
251
252Expression * build_constantFloat( string & str ) {
253        static const BasicType::Kind kind[2][3] = {
254                { BasicType::Float, BasicType::Double, BasicType::LongDouble },
255                { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
256        };
257
258        string units;
259        sepNumeric( str, units );                                                       // separate constant from units
260
261        bool complx = false;                                                            // real, complex
262        int size = 1;                                                                           // 0 => float, 1 => double, 2 => long double
263        int lnth = -1;                                                                          // literal length
264        // floating-point constant has minimum of 2 characters: 1. or .1
265        size_t last = str.length() - 1;
266        double v;
267
268        sscanf( str.c_str(), "%lg", &v );
269
270        if ( checkI( str[last] ) ) {                                            // imaginary ?
271                complx = true;
272                last -= 1;                                                                              // backup one character
273        } // if
274
275        if ( checkF( str[last] ) ) {                                            // float ?
276                size = 0;
277        } else if ( checkD( str[last] ) ) {                                     // double ?
278                size = 1;
279        } else if ( checkL( str[last] ) ) {                                     // long double ?
280                size = 2;
281        } else {
282                size = 1;                                                                               // double (default)
283                checkLNFloat( str, lnth, size );
284        } // if
285        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
286                complx = true;
287        } // if
288
289        assert( 0 <= size && size < 3 );
290        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
291        if ( lnth != -1 ) {                                                                     // explicit length ?
292                ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ) );
293        } // if
294        if ( units.length() != 0 ) {
295                ret = new UntypedExpr( new NameExpr( units ), { ret } );
296        } // if
297
298        delete &str;                                                                            // created by lex
299        return ret;
300} // build_constantFloat
301
302static void sepString( string & str, string & units, char delimit ) {
303        string::size_type posn = str.find_last_of( delimit ) + 1;
304        if ( posn != str.length() ) {
305                units = "?" + str.substr( posn );                               // extract units
306                str.erase( posn );                                                              // remove units
307        } // if
308} // sepString
309
310Expression * build_constantChar( string & str ) {
311        string units;                                                                           // units
312        sepString( str, units, '\'' );                                          // separate constant from units
313
314        Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
315        if ( units.length() != 0 ) {
316                ret = new UntypedExpr( new NameExpr( units ), { ret } );
317        } // if
318
319        delete &str;                                                                            // created by lex
320        return ret;
321} // build_constantChar
322
323Expression * build_constantStr( string & str ) {
324        string units;                                                                           // units
325        sepString( str, units, '"' );                                           // separate constant from units
326
327        Type * strtype;
328        switch ( str[0] ) {                                                                     // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1
329          case 'u':
330                if ( str[1] == '8' ) goto Default;                              // utf-8 characters => array of char
331                // lookup type of associated typedef
332                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char16_t", false );
333                break;
334          case 'U':
335                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char32_t", false );
336                break;
337          case 'L':
338                strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "wchar_t", false );
339                break;
340          Default:                                                                                      // char default string type
341          default:
342                strtype = new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char );
343        } // switch
344        ArrayType * at = new ArrayType( noQualifiers, strtype,
345                                                                        new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
346                                                                        false, false );
347        Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
348        if ( units.length() != 0 ) {
349                ret = new UntypedExpr( new NameExpr( units ), { ret } );
350        } // if
351
352        delete &str;                                                                            // created by lex
353        return ret;
354} // build_constantStr
355
356Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
357        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
358        Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
359        delete &str;
360        return ret;
361} // build_field_name_FLOATING_FRACTIONconstant
362
363Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
364        if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
365        Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
366        delete &str;
367        return ret;
368} // build_field_name_FLOATING_DECIMALconstant
369
370Expression * build_field_name_FLOATINGconstant( const string & str ) {
371        // str is of the form A.B -> separate at the . and return member expression
372        int a, b;
373        char dot;
374        stringstream ss( str );
375        ss >> a >> dot >> b;
376        UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
377        delete &str;
378        return ret;
379} // build_field_name_FLOATINGconstant
380
381Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
382        if ( fracts ) {
383                if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
384                        memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
385                        return memberExpr;
386                } else {
387                        return new UntypedMemberExpr( fracts, fieldName );
388                } // if
389        } // if
390        return fieldName;
391} // make_field_name_fraction_constants
392
393Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
394        return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
395} // build_field_name_fraction_constants
396
397NameExpr * build_varref( const string * name ) {
398        NameExpr * expr = new NameExpr( *name );
399        delete name;
400        return expr;
401} // build_varref
402
403// TODO: get rid of this and OperKinds and reuse code from OperatorTable
404static const char * OperName[] = {                                              // must harmonize with OperKinds
405        // diadic
406        "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?\\?", "?*?", "?/?", "?%?", "||", "&&",
407        "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
408        "?=?", "?@=?", "?\\=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
409        "?[?]", "...",
410        // monadic
411        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--",
412}; // OperName
413
414Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
415        Type * targetType = maybeMoveBuildType( decl_node );
416        if ( dynamic_cast< VoidType * >( targetType ) ) {
417                delete targetType;
418                return new CastExpr( maybeMoveBuild< Expression >(expr_node) );
419        } else {
420                return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType );
421        } // if
422} // build_cast
423
424Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
425        return new VirtualCastExpr( maybeMoveBuild< Expression >( expr_node ), maybeMoveBuildType( decl_node ) );
426} // build_virtual_cast
427
428Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) {
429        return new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
430} // build_fieldSel
431
432Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) {
433        UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
434        deref->location = expr_node->location;
435        deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
436        UntypedMemberExpr * ret = new UntypedMemberExpr( member, deref );
437        return ret;
438} // build_pfieldSel
439
440Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) {
441        Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
442        delete member;
443        return ret;
444} // build_offsetOf
445
446Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) {
447        return new LogicalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), notZeroExpr( maybeMoveBuild< Expression >(expr_node2) ), kind );
448} // build_and_or
449
450Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
451        list< Expression * > args;
452        args.push_back( maybeMoveBuild< Expression >(expr_node) );
453        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
454} // build_unary_val
455
456Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
457        list< Expression * > args;
458        args.push_back(  maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
459        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
460} // build_unary_ptr
461
462Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
463        list< Expression * > args;
464        args.push_back( maybeMoveBuild< Expression >(expr_node1) );
465        args.push_back( maybeMoveBuild< Expression >(expr_node2) );
466        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
467} // build_binary_val
468
469Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
470        list< Expression * > args;
471        args.push_back( maybeMoveBuild< Expression >(expr_node1) );
472        args.push_back( maybeMoveBuild< Expression >(expr_node2) );
473        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
474} // build_binary_ptr
475
476Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) {
477        return new ConditionalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), maybeMoveBuild< Expression >(expr_node2), maybeMoveBuild< Expression >(expr_node3) );
478} // build_cond
479
480Expression * build_tuple( ExpressionNode * expr_node ) {
481        list< Expression * > exprs;
482        buildMoveList( expr_node, exprs );
483        return new UntypedTupleExpr( exprs );;
484} // build_tuple
485
486Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
487        list< Expression * > args;
488        buildMoveList( expr_node, args );
489        return new UntypedExpr( maybeMoveBuild< Expression >(function), args );
490} // build_func
491
492Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) {
493        Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type
494        if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
495                return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild< Initializer >(kids) );
496        // these types do not have associated type information
497        } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
498                if ( newDeclStructDecl->has_body() ) {
499                        return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild< Initializer >(kids) );
500                } else {
501                        return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
502                } // if
503        } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
504                if ( newDeclUnionDecl->has_body() ) {
505                        return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild< Initializer >(kids) );
506                } else {
507                        return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
508                } // if
509        } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
510                if ( newDeclEnumDecl->has_body() ) {
511                        return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild< Initializer >(kids) );
512                } else {
513                        return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
514                } // if
515        } else {
516                assert( false );
517        } // if
518} // build_compoundLiteral
519
520// Local Variables: //
521// tab-width: 4 //
522// mode: c++ //
523// compile-command: "make install" //
524// End: //
Note: See TracBrowser for help on using the repository browser.