source: src/Parser/DeclarationNode.cc@ 8f6f47d7

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 8f6f47d7 was 8f6f47d7, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

more refactoring of parser code

  • Property mode set to 100644
File size: 30.1 KB
RevLine 
[b87a5ed]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//
[974906e2]7// DeclarationNode.cc --
[b87a5ed]8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 12:34:05 2015
[8e9cbb2]11// Last Modified By : Peter A. Buhr
[8f6f47d7]12// Last Modified On : Mon Aug 29 15:55:12 2016
13// Update Count : 311
[b87a5ed]14//
15
[51b73452]16#include <string>
17#include <list>
18#include <iterator>
19#include <algorithm>
20#include <cassert>
21
22#include "TypeData.h"
[bdd516a]23
[68cd1ce]24#include "SynTree/Declaration.h"
25#include "SynTree/Expression.h"
[51b73452]26
[de62360d]27#include "TypedefTable.h"
28extern TypedefTable typedefTable;
29
[51b73452]30using namespace std;
31
[bdd516a]32// These must remain in the same order as the corresponding DeclarationNode enumerations.
[68cd1ce]33const char *DeclarationNode::storageName[] = { "extern", "static", "auto", "register", "inline", "fortran", "_Noreturn", "_Thread_local", "" };
[bdd516a]34const char *DeclarationNode::qualifierName[] = { "const", "restrict", "volatile", "lvalue", "_Atomic" };
[90c3b1c]35const char *DeclarationNode::basicTypeName[] = { "char", "int", "float", "double", "void", "_Bool", "_Complex", "_Imaginary", };
[68cd1ce]36const char *DeclarationNode::modifierName[] = { "signed", "unsigned", "short", "long" };
37const char *DeclarationNode::aggregateName[] = { "struct", "union", "context" };
[51b73452]38const char *DeclarationNode::typeClassName[] = { "type", "dtype", "ftype" };
[90c3b1c]39const char *DeclarationNode::builtinTypeName[] = { "__builtin_va_list" };
[51b73452]40
41UniqueName DeclarationNode::anonymous( "__anonymous" );
42
[8b7ee09]43extern LinkageSpec::Spec linkage; // defined in parser.yy
[51b73452]44
[3848e0e]45DeclarationNode *DeclarationNode::clone() const {
[b87a5ed]46 DeclarationNode *newnode = new DeclarationNode;
47 newnode->type = maybeClone( type );
48 newnode->name = name;
[13e3b50]49 newnode->storageClass = storageClass;
50 newnode->isInline = isInline;
51 newnode->isNoreturn = isNoreturn;
[f39096c]52 newnode->bitfieldWidth = maybeClone( bitfieldWidth );
[b87a5ed]53 newnode->hasEllipsis = hasEllipsis;
[f39096c]54 newnode->initializer = maybeClone( initializer );
[7880579]55 newnode->set_next( maybeClone( get_next() ) );
[b87a5ed]56 newnode->linkage = linkage;
57 return newnode;
[984dce6]58} // DeclarationNode::clone
[3848e0e]59
[13e3b50]60DeclarationNode::DeclarationNode()
61 : type( 0 )
62 , storageClass( NoStorageClass )
63 , isInline( false )
64 , isNoreturn( false )
65 , bitfieldWidth( 0 )
66 , initializer( 0 )
67 , hasEllipsis( false )
68 , linkage( ::linkage )
69 , extension( false )
70 , error() {
[3848e0e]71}
72
73DeclarationNode::~DeclarationNode() {
[b87a5ed]74 delete type;
75 delete bitfieldWidth;
76 delete initializer;
[3848e0e]77}
78
79bool DeclarationNode::get_hasEllipsis() const {
[b87a5ed]80 return hasEllipsis;
[3848e0e]81}
82
83void DeclarationNode::print( std::ostream &os, int indent ) const {
[59db689]84 os << string( indent, ' ' );
[b87a5ed]85 if ( name == "" ) {
86 os << "unnamed: ";
87 } else {
88 os << name << ": ";
[68cd1ce]89 } // if
[51b73452]90
[b87a5ed]91 if ( linkage != LinkageSpec::Cforall ) {
92 os << LinkageSpec::toString( linkage ) << " ";
[68cd1ce]93 } // if
[3848e0e]94
[c1c1112]95 if ( storageClass != NoStorageClass ) os << DeclarationNode::storageName[storageClass] << ' ';
96 if ( isInline ) os << DeclarationNode::storageName[Inline] << ' ';
97 if ( isNoreturn ) os << DeclarationNode::storageName[Noreturn] << ' ';
[b87a5ed]98 if ( type ) {
99 type->print( os, indent );
100 } else {
101 os << "untyped entity ";
[68cd1ce]102 } // if
[3848e0e]103
[b87a5ed]104 if ( bitfieldWidth ) {
[59db689]105 os << endl << string( indent + 2, ' ' ) << "with bitfield width ";
[b87a5ed]106 bitfieldWidth->printOneLine( os );
[68cd1ce]107 } // if
[3848e0e]108
[b87a5ed]109 if ( initializer != 0 ) {
[59db689]110 os << endl << string( indent + 2, ' ' ) << "with initializer ";
[b87a5ed]111 initializer->printOneLine( os );
[974906e2]112 os << " maybe constructed? " << initializer->get_maybeConstructed();
113
[68cd1ce]114 } // if
[3848e0e]115
[b87a5ed]116 os << endl;
[51b73452]117}
118
[3848e0e]119void DeclarationNode::printList( std::ostream &os, int indent ) const {
[b87a5ed]120 ParseNode::printList( os, indent );
121 if ( hasEllipsis ) {
122 os << string( indent, ' ' ) << "and a variable number of other arguments" << endl;
[68cd1ce]123 } // if
[51b73452]124}
125
[d9a0e76]126DeclarationNode *DeclarationNode::newFunction( std::string *name, DeclarationNode *ret, DeclarationNode *param, StatementNode *body, bool newStyle ) {
[b87a5ed]127 DeclarationNode *newnode = new DeclarationNode;
128 newnode->name = assign_strptr( name );
[3848e0e]129
[b87a5ed]130 newnode->type = new TypeData( TypeData::Function );
[8f6f47d7]131 newnode->type->function.params = param;
132 newnode->type->function.newStyle = newStyle;
133 newnode->type->function.body = body;
[984dce6]134 typedefTable.addToEnclosingScope( newnode->name, TypedefTable::ID );
[3848e0e]135
[b87a5ed]136 if ( body ) {
[8f6f47d7]137 newnode->type->function.hasBody = true;
[68cd1ce]138 } // if
[51b73452]139
[b87a5ed]140 if ( ret ) {
141 newnode->type->base = ret->type;
142 ret->type = 0;
143 delete ret;
[68cd1ce]144 } // if
[51b73452]145
[b87a5ed]146 return newnode;
[984dce6]147} // DeclarationNode::newFunction
[3848e0e]148
[c1c1112]149DeclarationNode * DeclarationNode::newQualifier( Qualifier q ) {
[b87a5ed]150 DeclarationNode *newnode = new DeclarationNode;
151 newnode->type = new TypeData();
[c1c1112]152 newnode->type->qualifiers[ q ] = 1;
[b87a5ed]153 return newnode;
[984dce6]154} // DeclarationNode::newQualifier
[3848e0e]155
[c1c1112]156DeclarationNode * DeclarationNode::newForall( DeclarationNode *forall ) {
[b87a5ed]157 DeclarationNode *newnode = new DeclarationNode;
[c1c1112]158 newnode->type = new TypeData( TypeData::Unknown );
159 newnode->type->forall = forall;
160 return newnode;
161} // DeclarationNode::newForall
162
163DeclarationNode * DeclarationNode::newStorageClass( DeclarationNode::StorageClass sc ) {
164 DeclarationNode *newnode = new DeclarationNode;
165 //switch (sc) {
166 // case Inline: newnode->isInline = true; break;
167 // case Noreturn: newnode->isNoreturn = true; break;
168 // default: newnode->storageClass = sc; break;
169 //}
170 newnode->storageClass = sc;
[b87a5ed]171 return newnode;
[984dce6]172} // DeclarationNode::newStorageClass
[3848e0e]173
[c1c1112]174DeclarationNode * DeclarationNode::newBasicType( BasicType bt ) {
[b87a5ed]175 DeclarationNode *newnode = new DeclarationNode;
176 newnode->type = new TypeData( TypeData::Basic );
[8f6f47d7]177 newnode->type->basic.typeSpec.push_back( bt );
[b87a5ed]178 return newnode;
[984dce6]179} // DeclarationNode::newBasicType
[3848e0e]180
[c1c1112]181DeclarationNode * DeclarationNode::newModifier( Modifier mod ) {
[b87a5ed]182 DeclarationNode *newnode = new DeclarationNode;
183 newnode->type = new TypeData( TypeData::Basic );
[8f6f47d7]184 newnode->type->basic.modifiers.push_back( mod );
[b87a5ed]185 return newnode;
[984dce6]186} // DeclarationNode::newModifier
[3848e0e]187
[c1c1112]188DeclarationNode * DeclarationNode::newFromTypedef( std::string *name ) {
[b87a5ed]189 DeclarationNode *newnode = new DeclarationNode;
190 newnode->type = new TypeData( TypeData::SymbolicInst );
[8f6f47d7]191 newnode->type->symbolic.name = assign_strptr( name );
192 newnode->type->symbolic.isTypedef = true;
193 newnode->type->symbolic.params = 0;
[b87a5ed]194 return newnode;
[984dce6]195} // DeclarationNode::newFromTypedef
[3848e0e]196
[c1c1112]197DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const std::string *name, ExpressionNode *actuals, DeclarationNode *fields, bool body ) {
[b87a5ed]198 DeclarationNode *newnode = new DeclarationNode;
199 newnode->type = new TypeData( TypeData::Aggregate );
[8f6f47d7]200 newnode->type->aggregate.kind = kind;
201 newnode->type->aggregate.name = assign_strptr( name );
202 if ( newnode->type->aggregate.name == "" ) { // anonymous aggregate ?
203 newnode->type->aggregate.name = anonymous.newName();
204 } // if
205 newnode->type->aggregate.actuals = actuals;
206 newnode->type->aggregate.fields = fields;
207 newnode->type->aggregate.body = body;
[b87a5ed]208 return newnode;
[984dce6]209} // DeclarationNode::newAggregate
[3848e0e]210
211DeclarationNode *DeclarationNode::newEnum( std::string *name, DeclarationNode *constants ) {
[b87a5ed]212 DeclarationNode *newnode = new DeclarationNode;
213 newnode->name = assign_strptr( name );
214 newnode->type = new TypeData( TypeData::Enum );
[8f6f47d7]215 newnode->type->enumeration.name = newnode->name;
216 if ( newnode->type->enumeration.name == "" ) { // anonymous enumeration ?
217 newnode->type->enumeration.name = DeclarationNode::anonymous.newName();
[68cd1ce]218 } // if
[8f6f47d7]219 newnode->type->enumeration.constants = constants;
[b87a5ed]220 return newnode;
[984dce6]221} // DeclarationNode::newEnum
[3848e0e]222
[59db689]223DeclarationNode *DeclarationNode::newEnumConstant( std::string *name, ExpressionNode *constant ) {
[b87a5ed]224 DeclarationNode *newnode = new DeclarationNode;
225 newnode->name = assign_strptr( name );
[4f147cc]226 newnode->enumeratorValue.reset( constant );
[984dce6]227 typedefTable.addToEnclosingScope( newnode->name, TypedefTable::ID );
[b87a5ed]228 return newnode;
[984dce6]229} // DeclarationNode::newEnumConstant
[3848e0e]230
[59db689]231DeclarationNode *DeclarationNode::newName( std::string *name ) {
[b87a5ed]232 DeclarationNode *newnode = new DeclarationNode;
233 newnode->name = assign_strptr( name );
234 return newnode;
[984dce6]235} // DeclarationNode::newName
[3848e0e]236
[59db689]237DeclarationNode *DeclarationNode::newFromTypeGen( std::string *name, ExpressionNode *params ) {
[b87a5ed]238 DeclarationNode *newnode = new DeclarationNode;
239 newnode->type = new TypeData( TypeData::SymbolicInst );
[8f6f47d7]240 newnode->type->symbolic.name = assign_strptr( name );
241 newnode->type->symbolic.isTypedef = false;
242 newnode->type->symbolic.actuals = params;
[b87a5ed]243 return newnode;
[984dce6]244} // DeclarationNode::newFromTypeGen
[3848e0e]245
[59db689]246DeclarationNode *DeclarationNode::newTypeParam( TypeClass tc, std::string *name ) {
[b87a5ed]247 DeclarationNode *newnode = new DeclarationNode;
248 newnode->name = assign_strptr( name );
249 newnode->type = new TypeData( TypeData::Variable );
[8f6f47d7]250 newnode->type->variable.tyClass = tc;
251 newnode->type->variable.name = newnode->name;
[b87a5ed]252 return newnode;
[984dce6]253} // DeclarationNode::newTypeParam
[3848e0e]254
[4040425]255DeclarationNode *DeclarationNode::newTrait( std::string *name, DeclarationNode *params, DeclarationNode *asserts ) {
[b87a5ed]256 DeclarationNode *newnode = new DeclarationNode;
257 newnode->type = new TypeData( TypeData::Aggregate );
[8f6f47d7]258 newnode->type->aggregate.kind = Trait;
259 newnode->type->aggregate.params = params;
260 newnode->type->aggregate.fields = asserts;
261 newnode->type->aggregate.name = assign_strptr( name );
[b87a5ed]262 return newnode;
[984dce6]263} // DeclarationNode::newTrait
[3848e0e]264
[4040425]265DeclarationNode *DeclarationNode::newTraitUse( std::string *name, ExpressionNode *params ) {
[b87a5ed]266 DeclarationNode *newnode = new DeclarationNode;
267 newnode->type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]268 newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
269 newnode->type->aggInst.aggregate->aggregate.kind = Trait;
270 newnode->type->aggInst.aggregate->aggregate.name = assign_strptr( name );
271 newnode->type->aggInst.params = params;
[b87a5ed]272 return newnode;
[984dce6]273} // DeclarationNode::newTraitUse
[3848e0e]274
275DeclarationNode *DeclarationNode::newTypeDecl( std::string *name, DeclarationNode *typeParams ) {
[b87a5ed]276 DeclarationNode *newnode = new DeclarationNode;
277 newnode->name = assign_strptr( name );
278 newnode->type = new TypeData( TypeData::Symbolic );
[8f6f47d7]279 newnode->type->symbolic.isTypedef = false;
280 newnode->type->symbolic.params = typeParams;
281 newnode->type->symbolic.name = newnode->name;
[b87a5ed]282 return newnode;
[984dce6]283} // DeclarationNode::newTypeDecl
[3848e0e]284
285DeclarationNode *DeclarationNode::newPointer( DeclarationNode *qualifiers ) {
[b87a5ed]286 DeclarationNode *newnode = new DeclarationNode;
287 newnode->type = new TypeData( TypeData::Pointer );
288 return newnode->addQualifiers( qualifiers );
[984dce6]289} // DeclarationNode::newPointer
[3848e0e]290
291DeclarationNode *DeclarationNode::newArray( ExpressionNode *size, DeclarationNode *qualifiers, bool isStatic ) {
[b87a5ed]292 DeclarationNode *newnode = new DeclarationNode;
293 newnode->type = new TypeData( TypeData::Array );
[8f6f47d7]294 newnode->type->array.dimension = size;
295 newnode->type->array.isStatic = isStatic;
296 if ( newnode->type->array.dimension == 0 || newnode->type->array.dimension->isExpressionType<ConstantExpr *>() ) {
297 newnode->type->array.isVarLen = false;
[71bd8c6]298 } else {
[8f6f47d7]299 newnode->type->array.isVarLen = true;
[71bd8c6]300 } // if
[b87a5ed]301 return newnode->addQualifiers( qualifiers );
[984dce6]302} // DeclarationNode::newArray
[3848e0e]303
304DeclarationNode *DeclarationNode::newVarArray( DeclarationNode *qualifiers ) {
[b87a5ed]305 DeclarationNode *newnode = new DeclarationNode;
306 newnode->type = new TypeData( TypeData::Array );
[8f6f47d7]307 newnode->type->array.dimension = 0;
308 newnode->type->array.isStatic = false;
309 newnode->type->array.isVarLen = true;
[b87a5ed]310 return newnode->addQualifiers( qualifiers );
[3848e0e]311}
312
313DeclarationNode *DeclarationNode::newBitfield( ExpressionNode *size ) {
[b87a5ed]314 DeclarationNode *newnode = new DeclarationNode;
315 newnode->bitfieldWidth = size;
316 return newnode;
[3848e0e]317}
318
319DeclarationNode *DeclarationNode::newTuple( DeclarationNode *members ) {
[b87a5ed]320 DeclarationNode *newnode = new DeclarationNode;
321 newnode->type = new TypeData( TypeData::Tuple );
[8f6f47d7]322 newnode->type->tuple = members;
[b87a5ed]323 return newnode;
[3848e0e]324}
325
326DeclarationNode *DeclarationNode::newTypeof( ExpressionNode *expr ) {
[b87a5ed]327 DeclarationNode *newnode = new DeclarationNode;
328 newnode->type = new TypeData( TypeData::Typeof );
[8f6f47d7]329 newnode->type->typeexpr = expr;
[b87a5ed]330 return newnode;
[3848e0e]331}
332
[8f6f47d7]333DeclarationNode * DeclarationNode::newBuiltinType( BuiltinType bt ) {
334 DeclarationNode *newnode = new DeclarationNode;
335 newnode->type = new TypeData( TypeData::Builtin );
336 newnode->builtin = bt;
337 return newnode;
338} // DeclarationNode::newBuiltinType
339
[3848e0e]340DeclarationNode *DeclarationNode::newAttr( std::string *name, ExpressionNode *expr ) {
[b87a5ed]341 DeclarationNode *newnode = new DeclarationNode;
342 newnode->type = new TypeData( TypeData::Attr );
[8f6f47d7]343 newnode->type->attr.name = assign_strptr( name );
344 newnode->type->attr.expr = expr;
[b87a5ed]345 return newnode;
[3848e0e]346}
347
348DeclarationNode *DeclarationNode::newAttr( std::string *name, DeclarationNode *type ) {
[b87a5ed]349 DeclarationNode *newnode = new DeclarationNode;
350 newnode->type = new TypeData( TypeData::Attr );
[8f6f47d7]351 newnode->type->attr.name = assign_strptr( name );
352 newnode->type->attr.type = type;
[b87a5ed]353 return newnode;
[3848e0e]354}
355
356static void addQualifiersToType( TypeData *&src, TypeData *dst ) {
[b87a5ed]357 if ( src && dst ) {
358 if ( src->forall && dst->kind == TypeData::Function ) {
359 if ( dst->forall ) {
360 dst->forall->appendList( src->forall );
361 } else {
362 dst->forall = src->forall;
[68cd1ce]363 } // if
[b87a5ed]364 src->forall = 0;
[68cd1ce]365 } // if
[b87a5ed]366 if ( dst->base ) {
367 addQualifiersToType( src, dst->base );
368 } else if ( dst->kind == TypeData::Function ) {
369 dst->base = src;
370 src = 0;
371 } else {
[c1c1112]372 dst->qualifiers |= src->qualifiers;
[68cd1ce]373 } // if
374 } // if
[3848e0e]375}
[974906e2]376
[413ad05]377void DeclarationNode::checkQualifiers( const TypeData *src, const TypeData *dst ) {
[c1c1112]378 TypeData::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers;
379
380 if ( (qsrc & qdst).any() ) { // common bits between qualifier masks ?
381 error = "duplicate qualifier ";
382 int j = 0; // separator detector
383 for ( int i = 0; i < DeclarationNode::NoOfQualifier; i += 1 ) {
384 if ( qsrc[i] & qdst[i] ) { // find specific qualifiers in common
385 if ( j > 0 ) error += ", ";
386 error += DeclarationNode::qualifierName[i];
387 j += 1;
388 } // if
389 } // for
390 error += " in declaration of ";
391 } // if
392} // DeclarationNode::checkQualifiers
393
[3848e0e]394DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
[b87a5ed]395 if ( q ) {
[13e3b50]396 copyStorageClasses(q);
[b87a5ed]397 if ( q->type ) {
398 if ( ! type ) {
399 type = new TypeData;
[c1c1112]400 } else {
401 checkQualifiers( q->type, type );
[68cd1ce]402 } // if
[b87a5ed]403 addQualifiersToType( q->type, type );
404 if ( q->type && q->type->forall ) {
405 if ( type->forall ) {
406 type->forall->appendList( q->type->forall );
407 } else {
[68cd1ce]408 if ( type->kind == TypeData::Aggregate ) {
[8f6f47d7]409 type->aggregate.params = q->type->forall;
[721f17a]410 // change implicit typedef from TYPEDEFname to TYPEGENname
[8f6f47d7]411 typedefTable.changeKind( type->aggregate.name, TypedefTable::TG );
[68cd1ce]412 } else {
413 type->forall = q->type->forall;
414 } // if
415 } // if
[b87a5ed]416 q->type->forall = 0;
[68cd1ce]417 } // if
418 } // if
419 } // if
[b87a5ed]420 delete q;
421 return this;
[3848e0e]422}
423
424DeclarationNode *DeclarationNode::copyStorageClasses( DeclarationNode *q ) {
[13e3b50]425 isInline = isInline || q->isInline;
426 isNoreturn = isNoreturn || q->isNoreturn;
[c1c1112]427 if ( storageClass == NoStorageClass ) {
[13e3b50]428 storageClass = q->storageClass;
[c1c1112]429 } else if ( q->storageClass != NoStorageClass ) {
[13e3b50]430 q->error = "invalid combination of storage classes in declaration of ";
[c1c1112]431 } // if
432 if ( error.empty() ) error = q->error;
[b87a5ed]433 return this;
[3848e0e]434}
435
436static void addTypeToType( TypeData *&src, TypeData *&dst ) {
[b87a5ed]437 if ( src && dst ) {
438 if ( src->forall && dst->kind == TypeData::Function ) {
439 if ( dst->forall ) {
440 dst->forall->appendList( src->forall );
441 } else {
442 dst->forall = src->forall;
[68cd1ce]443 } // if
[b87a5ed]444 src->forall = 0;
[68cd1ce]445 } // if
[b87a5ed]446 if ( dst->base ) {
447 addTypeToType( src, dst->base );
448 } else {
449 switch ( dst->kind ) {
450 case TypeData::Unknown:
[c1c1112]451 src->qualifiers |= dst->qualifiers;
[b87a5ed]452 dst = src;
453 src = 0;
454 break;
455 case TypeData::Basic:
[c1c1112]456 dst->qualifiers |= src->qualifiers;
[b87a5ed]457 if ( src->kind != TypeData::Unknown ) {
458 assert( src->kind == TypeData::Basic );
[8f6f47d7]459 dst->basic.modifiers.splice( dst->basic.modifiers.end(), src->basic.modifiers );
460 dst->basic.typeSpec.splice( dst->basic.typeSpec.end(), src->basic.typeSpec );
[68cd1ce]461 } // if
[b87a5ed]462 break;
463 default:
464 switch ( src->kind ) {
465 case TypeData::Aggregate:
466 case TypeData::Enum:
467 dst->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]468 dst->base->aggInst.aggregate = src;
[b87a5ed]469 if ( src->kind == TypeData::Aggregate ) {
[8f6f47d7]470 dst->base->aggInst.params = maybeClone( src->aggregate.actuals );
[68cd1ce]471 } // if
[c1c1112]472 dst->base->qualifiers |= src->qualifiers;
[b87a5ed]473 src = 0;
474 break;
475 default:
476 if ( dst->forall ) {
477 dst->forall->appendList( src->forall );
478 } else {
479 dst->forall = src->forall;
[68cd1ce]480 } // if
[b87a5ed]481 src->forall = 0;
482 dst->base = src;
483 src = 0;
[68cd1ce]484 } // switch
485 } // switch
486 } // if
487 } // if
[3848e0e]488}
489
490DeclarationNode *DeclarationNode::addType( DeclarationNode *o ) {
[b87a5ed]491 if ( o ) {
[13e3b50]492 copyStorageClasses( o );
[b87a5ed]493 if ( o->type ) {
494 if ( ! type ) {
495 if ( o->type->kind == TypeData::Aggregate || o->type->kind == TypeData::Enum ) {
496 type = new TypeData( TypeData::AggregateInst );
[8f6f47d7]497 type->aggInst.aggregate = o->type;
[b87a5ed]498 if ( o->type->kind == TypeData::Aggregate ) {
[8f6f47d7]499 type->aggInst.params = maybeClone( o->type->aggregate.actuals );
[68cd1ce]500 } // if
[c1c1112]501 type->qualifiers |= o->type->qualifiers;
[b87a5ed]502 } else {
503 type = o->type;
[68cd1ce]504 } // if
[b87a5ed]505 o->type = 0;
506 } else {
507 addTypeToType( o->type, type );
[68cd1ce]508 } // if
509 } // if
[b87a5ed]510 if ( o->bitfieldWidth ) {
511 bitfieldWidth = o->bitfieldWidth;
[68cd1ce]512 } // if
[71bd8c6]513
514 // there may be typedefs chained onto the type
[1d4580a]515 if ( o->get_next() ) {
516 set_last( o->get_next()->clone() );
[1db21619]517 } // if
[68cd1ce]518 } // if
[b87a5ed]519 delete o;
520 return this;
[3848e0e]521}
522
523DeclarationNode *DeclarationNode::addTypedef() {
[b87a5ed]524 TypeData *newtype = new TypeData( TypeData::Symbolic );
[8f6f47d7]525 newtype->symbolic.params = 0;
526 newtype->symbolic.isTypedef = true;
527 newtype->symbolic.name = name;
[b87a5ed]528 newtype->base = type;
529 type = newtype;
530 return this;
[3848e0e]531}
532
[59db689]533DeclarationNode *DeclarationNode::addAssertions( DeclarationNode *assertions ) {
[b87a5ed]534 assert( type );
535 switch ( type->kind ) {
536 case TypeData::Symbolic:
[8f6f47d7]537 if ( type->symbolic.assertions ) {
538 type->symbolic.assertions->appendList( assertions );
[b87a5ed]539 } else {
[8f6f47d7]540 type->symbolic.assertions = assertions;
[68cd1ce]541 } // if
[b87a5ed]542 break;
543 case TypeData::Variable:
[8f6f47d7]544 if ( type->variable.assertions ) {
545 type->variable.assertions->appendList( assertions );
[b87a5ed]546 } else {
[8f6f47d7]547 type->variable.assertions = assertions;
[68cd1ce]548 } // if
[b87a5ed]549 break;
550 default:
551 assert( false );
[68cd1ce]552 } // switch
[974906e2]553
[b87a5ed]554 return this;
[51b73452]555}
556
[59db689]557DeclarationNode *DeclarationNode::addName( std::string *newname ) {
[b87a5ed]558 name = assign_strptr( newname );
559 return this;
[51b73452]560}
561
[3848e0e]562DeclarationNode *DeclarationNode::addBitfield( ExpressionNode *size ) {
[b87a5ed]563 bitfieldWidth = size;
564 return this;
[51b73452]565}
566
[3848e0e]567DeclarationNode *DeclarationNode::addVarArgs() {
[b87a5ed]568 assert( type );
569 hasEllipsis = true;
570 return this;
[51b73452]571}
572
[3848e0e]573DeclarationNode *DeclarationNode::addFunctionBody( StatementNode *body ) {
[b87a5ed]574 assert( type );
575 assert( type->kind == TypeData::Function );
[8f6f47d7]576 assert( type->function.body == 0 );
577 type->function.body = body;
578 type->function.hasBody = true;
[b87a5ed]579 return this;
[51b73452]580}
581
[3848e0e]582DeclarationNode *DeclarationNode::addOldDeclList( DeclarationNode *list ) {
[b87a5ed]583 assert( type );
584 assert( type->kind == TypeData::Function );
[8f6f47d7]585 assert( type->function.oldDeclList == 0 );
586 type->function.oldDeclList = list;
[b87a5ed]587 return this;
[51b73452]588}
589
[68cd1ce]590static void setBase( TypeData *&type, TypeData *newType ) {
[b87a5ed]591 if ( type ) {
592 TypeData *prevBase = type;
593 TypeData *curBase = type->base;
[a32b204]594 while ( curBase != 0 ) {
[b87a5ed]595 prevBase = curBase;
596 curBase = curBase->base;
[68cd1ce]597 } // while
[b87a5ed]598 prevBase->base = newType;
599 } else {
600 type = newType;
[68cd1ce]601 } // if
[3848e0e]602}
603
604DeclarationNode *DeclarationNode::addPointer( DeclarationNode *p ) {
[b87a5ed]605 if ( p ) {
606 assert( p->type->kind == TypeData::Pointer );
607 setBase( type, p->type );
608 p->type = 0;
609 delete p;
[68cd1ce]610 } // if
[b87a5ed]611 return this;
[3848e0e]612}
613
614DeclarationNode *DeclarationNode::addArray( DeclarationNode *a ) {
[b87a5ed]615 if ( a ) {
616 assert( a->type->kind == TypeData::Array );
617 setBase( type, a->type );
618 a->type = 0;
619 delete a;
[68cd1ce]620 } // if
[b87a5ed]621 return this;
[51b73452]622}
623
[3848e0e]624DeclarationNode *DeclarationNode::addNewPointer( DeclarationNode *p ) {
[b87a5ed]625 if ( p ) {
626 assert( p->type->kind == TypeData::Pointer );
627 if ( type ) {
628 switch ( type->kind ) {
629 case TypeData::Aggregate:
630 case TypeData::Enum:
631 p->type->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]632 p->type->base->aggInst.aggregate = type;
[b87a5ed]633 if ( type->kind == TypeData::Aggregate ) {
[8f6f47d7]634 p->type->base->aggInst.params = maybeClone( type->aggregate.actuals );
[68cd1ce]635 } // if
[c1c1112]636 p->type->base->qualifiers |= type->qualifiers;
[b87a5ed]637 break;
638
639 default:
640 p->type->base = type;
[68cd1ce]641 } // switch
[b87a5ed]642 type = 0;
[68cd1ce]643 } // if
[b87a5ed]644 delete this;
645 return p;
646 } else {
647 return this;
[68cd1ce]648 } // if
[51b73452]649}
650
[3848e0e]651static TypeData *findLast( TypeData *a ) {
[b87a5ed]652 assert( a );
653 TypeData *cur = a;
[a32b204]654 while ( cur->base ) {
[b87a5ed]655 cur = cur->base;
[68cd1ce]656 } // while
[b87a5ed]657 return cur;
[3848e0e]658}
659
660DeclarationNode *DeclarationNode::addNewArray( DeclarationNode *a ) {
[b87a5ed]661 if ( a ) {
662 assert( a->type->kind == TypeData::Array );
663 TypeData *lastArray = findLast( a->type );
[974906e2]664 if ( type ) {
[b87a5ed]665 switch ( type->kind ) {
666 case TypeData::Aggregate:
667 case TypeData::Enum:
668 lastArray->base = new TypeData( TypeData::AggregateInst );
[8f6f47d7]669 lastArray->base->aggInst.aggregate = type;
[b87a5ed]670 if ( type->kind == TypeData::Aggregate ) {
[8f6f47d7]671 lastArray->base->aggInst.params = maybeClone( type->aggregate.actuals );
[68cd1ce]672 } // if
[c1c1112]673 lastArray->base->qualifiers |= type->qualifiers;
[b87a5ed]674 break;
675 default:
676 lastArray->base = type;
[68cd1ce]677 } // switch
[b87a5ed]678 type = 0;
[68cd1ce]679 } // if
[b87a5ed]680 delete this;
681 return a;
682 } else {
683 return this;
[68cd1ce]684 } // if
[51b73452]685}
[3848e0e]686
687DeclarationNode *DeclarationNode::addParamList( DeclarationNode *params ) {
[b87a5ed]688 TypeData *ftype = new TypeData( TypeData::Function );
[8f6f47d7]689 ftype->function.params = params;
[b87a5ed]690 setBase( type, ftype );
691 return this;
[3848e0e]692}
693
694static TypeData *addIdListToType( TypeData *type, DeclarationNode *ids ) {
[b87a5ed]695 if ( type ) {
696 if ( type->kind != TypeData::Function ) {
697 type->base = addIdListToType( type->base, ids );
698 } else {
[8f6f47d7]699 type->function.idList = ids;
[68cd1ce]700 } // if
[b87a5ed]701 return type;
[3848e0e]702 } else {
[b87a5ed]703 TypeData *newtype = new TypeData( TypeData::Function );
[8f6f47d7]704 newtype->function.idList = ids;
[b87a5ed]705 return newtype;
[68cd1ce]706 } // if
[3848e0e]707}
[974906e2]708
[3848e0e]709DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
[b87a5ed]710 type = addIdListToType( type, ids );
711 return this;
[3848e0e]712}
713
714DeclarationNode *DeclarationNode::addInitializer( InitializerNode *init ) {
[b87a5ed]715 //assert
716 initializer = init;
717 return this;
[3848e0e]718}
719
720DeclarationNode *DeclarationNode::cloneBaseType( string *newName ) {
[b87a5ed]721 DeclarationNode *newnode = new DeclarationNode;
722 TypeData *srcType = type;
[a32b204]723 while ( srcType->base ) {
[b87a5ed]724 srcType = srcType->base;
[68cd1ce]725 } // while
[b87a5ed]726 newnode->type = maybeClone( srcType );
727 if ( newnode->type->kind == TypeData::AggregateInst ) {
728 // don't duplicate members
[8f6f47d7]729 if ( newnode->type->aggInst.aggregate->kind == TypeData::Enum ) {
730 delete newnode->type->aggInst.aggregate->enumeration.constants;
731 newnode->type->aggInst.aggregate->enumeration.constants = 0;
[b87a5ed]732 } else {
[8f6f47d7]733 assert( newnode->type->aggInst.aggregate->kind == TypeData::Aggregate );
734 delete newnode->type->aggInst.aggregate->aggregate.fields;
735 newnode->type->aggInst.aggregate->aggregate.fields = 0;
[68cd1ce]736 } // if
737 } // if
[b87a5ed]738 newnode->type->forall = maybeClone( type->forall );
[13e3b50]739 newnode->copyStorageClasses( this );
[b87a5ed]740 newnode->name = assign_strptr( newName );
741 return newnode;
[3848e0e]742}
743
744DeclarationNode *DeclarationNode::cloneBaseType( DeclarationNode *o ) {
[b87a5ed]745 if ( o ) {
[13e3b50]746 o->copyStorageClasses( this );
[b87a5ed]747 if ( type ) {
748 TypeData *srcType = type;
[a32b204]749 while ( srcType->base ) {
[b87a5ed]750 srcType = srcType->base;
[68cd1ce]751 } // while
[b87a5ed]752 TypeData *newType = srcType->clone();
753 if ( newType->kind == TypeData::AggregateInst ) {
754 // don't duplicate members
[8f6f47d7]755 if ( newType->aggInst.aggregate->kind == TypeData::Enum ) {
756 delete newType->aggInst.aggregate->enumeration.constants;
757 newType->aggInst.aggregate->enumeration.constants = 0;
[b87a5ed]758 } else {
[8f6f47d7]759 assert( newType->aggInst.aggregate->kind == TypeData::Aggregate );
760 delete newType->aggInst.aggregate->aggregate.fields;
761 newType->aggInst.aggregate->aggregate.fields = 0;
[68cd1ce]762 } // if
763 } // if
[b87a5ed]764 newType->forall = maybeClone( type->forall );
765 if ( ! o->type ) {
766 o->type = newType;
767 } else {
768 addTypeToType( newType, o->type );
769 delete newType;
[68cd1ce]770 } // if
771 } // if
772 } // if
[b87a5ed]773 return o;
[3848e0e]774}
775
776DeclarationNode *DeclarationNode::cloneType( string *newName ) {
[b87a5ed]777 DeclarationNode *newnode = new DeclarationNode;
778 newnode->type = maybeClone( type );
[13e3b50]779 newnode->copyStorageClasses( this );
[b87a5ed]780 newnode->name = assign_strptr( newName );
781 return newnode;
[3848e0e]782}
783
784DeclarationNode *DeclarationNode::cloneType( DeclarationNode *o ) {
[b87a5ed]785 if ( o ) {
[13e3b50]786 o->copyStorageClasses( this );
[b87a5ed]787 if ( type ) {
788 TypeData *newType = type->clone();
789 if ( ! o->type ) {
790 o->type = newType;
791 } else {
792 addTypeToType( newType, o->type );
793 delete newType;
[68cd1ce]794 } // if
795 } // if
796 } // if
[2037f82]797 delete o;
[b87a5ed]798 return o;
[51b73452]799}
800
[3848e0e]801DeclarationNode *DeclarationNode::extractAggregate() const {
[b87a5ed]802 if ( type ) {
[413ad05]803 TypeData *ret = typeextractAggregate( type );
[b87a5ed]804 if ( ret ) {
805 DeclarationNode *newnode = new DeclarationNode;
806 newnode->type = ret;
807 return newnode;
[843054c2]808 } // if
809 } // if
810 return 0;
[3848e0e]811}
812
[a61fea9a]813void buildList( const DeclarationNode *firstNode, std::list< Declaration * > &outputList ) {
[b87a5ed]814 SemanticError errors;
[7880579]815 std::back_insert_iterator< std::list< Declaration * > > out( outputList );
[b87a5ed]816 const DeclarationNode *cur = firstNode;
[a32b204]817 while ( cur ) {
[b87a5ed]818 try {
819 if ( DeclarationNode *extr = cur->extractAggregate() ) {
820 // handle the case where a structure declaration is contained within an object or type declaration
821 Declaration *decl = extr->build();
822 if ( decl ) {
823 *out++ = decl;
[843054c2]824 } // if
[f39096c]825 delete extr;
[843054c2]826 } // if
[b87a5ed]827 Declaration *decl = cur->build();
828 if ( decl ) {
829 *out++ = decl;
[843054c2]830 } // if
[b87a5ed]831 } catch( SemanticError &e ) {
832 errors.append( e );
[843054c2]833 } // try
[7880579]834 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
[843054c2]835 } // while
[b87a5ed]836 if ( ! errors.isEmpty() ) {
837 throw errors;
[843054c2]838 } // if
[3848e0e]839}
840
[7880579]841void buildList( const DeclarationNode *firstNode, std::list< DeclarationWithType * > &outputList ) {
[b87a5ed]842 SemanticError errors;
[7880579]843 std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
[b87a5ed]844 const DeclarationNode *cur = firstNode;
[a32b204]845 while ( cur ) {
[b87a5ed]846 try {
[3848e0e]847/// if ( DeclarationNode *extr = cur->extractAggregate() ) {
[51b73452]848/// // handle the case where a structure declaration is contained within an object or type
849/// // declaration
850/// Declaration *decl = extr->build();
[3848e0e]851/// if ( decl ) {
852/// *out++ = decl;
[51b73452]853/// }
854/// }
[b87a5ed]855 Declaration *decl = cur->build();
856 if ( decl ) {
[7880579]857 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
[b87a5ed]858 *out++ = dwt;
[7880579]859 } else if ( StructDecl *agg = dynamic_cast< StructDecl * >( decl ) ) {
[b87a5ed]860 StructInstType *inst = new StructInstType( Type::Qualifiers(), agg->get_name() );
[68cd1ce]861 *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
[b87a5ed]862 delete agg;
[7880579]863 } else if ( UnionDecl *agg = dynamic_cast< UnionDecl * >( decl ) ) {
[b87a5ed]864 UnionInstType *inst = new UnionInstType( Type::Qualifiers(), agg->get_name() );
[68cd1ce]865 *out++ = new ObjectDecl( "", DeclarationNode::NoStorageClass, linkage, 0, inst, 0 );
[843054c2]866 } // if
867 } // if
[b87a5ed]868 } catch( SemanticError &e ) {
869 errors.append( e );
[843054c2]870 } // try
[7880579]871 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
[843054c2]872 } // while
[b87a5ed]873 if ( ! errors.isEmpty() ) {
874 throw errors;
[843054c2]875 } // if
[3848e0e]876}
877
[7880579]878void buildTypeList( const DeclarationNode *firstNode, std::list< Type * > &outputList ) {
[b87a5ed]879 SemanticError errors;
[7880579]880 std::back_insert_iterator< std::list< Type * > > out( outputList );
[b87a5ed]881 const DeclarationNode *cur = firstNode;
[a32b204]882 while ( cur ) {
[b87a5ed]883 try {
884 *out++ = cur->buildType();
885 } catch( SemanticError &e ) {
886 errors.append( e );
[843054c2]887 } // try
[7880579]888 cur = dynamic_cast< DeclarationNode * >( cur->get_next() );
[843054c2]889 } // while
[b87a5ed]890 if ( ! errors.isEmpty() ) {
891 throw errors;
[843054c2]892 } // if
[51b73452]893}
894
[3848e0e]895Declaration *DeclarationNode::build() const {
[c1c1112]896 if ( ! error.empty() ) throw SemanticError( error, this );
[843054c2]897 if ( type ) {
[413ad05]898 return buildDecl( type, name, storageClass, maybeBuild< Expression >( bitfieldWidth ), isInline, isNoreturn, linkage, maybeBuild< Initializer >(initializer) )->set_extension( extension );
[843054c2]899 } // if
[13e3b50]900 if ( ! isInline && ! isNoreturn ) {
901 return (new ObjectDecl( name, storageClass, linkage, maybeBuild< Expression >( bitfieldWidth ), 0, maybeBuild< Initializer >( initializer ) ))->set_extension( extension );
[843054c2]902 } // if
[de62360d]903 throw SemanticError( "invalid function specifier in declaration of ", this );
[51b73452]904}
905
[3848e0e]906Type *DeclarationNode::buildType() const {
[b87a5ed]907 assert( type );
[974906e2]908
[b87a5ed]909 switch ( type->kind ) {
910 case TypeData::Enum:
[8f6f47d7]911 return new EnumInstType( buildQualifiers( type ), type->enumeration.name );
[b87a5ed]912 case TypeData::Aggregate: {
913 ReferenceToType *ret;
[8f6f47d7]914 switch ( type->aggregate.kind ) {
[b87a5ed]915 case DeclarationNode::Struct:
[8f6f47d7]916 ret = new StructInstType( buildQualifiers( type ), type->aggregate.name );
[b87a5ed]917 break;
918 case DeclarationNode::Union:
[8f6f47d7]919 ret = new UnionInstType( buildQualifiers( type ), type->aggregate.name );
[b87a5ed]920 break;
[4040425]921 case DeclarationNode::Trait:
[8f6f47d7]922 ret = new TraitInstType( buildQualifiers( type ), type->aggregate.name );
[b87a5ed]923 break;
924 default:
925 assert( false );
926 } // switch
[8f6f47d7]927 buildList( type->aggregate.actuals, ret->get_parameters() );
[b87a5ed]928 return ret;
929 }
930 case TypeData::Symbolic: {
[8f6f47d7]931 TypeInstType *ret = new TypeInstType( buildQualifiers( type ), type->symbolic.name, false );
932 buildList( type->symbolic.actuals, ret->get_parameters() );
[b87a5ed]933 return ret;
934 }
935 default:
[413ad05]936 return typebuild( type );
[b87a5ed]937 } // switch
[3848e0e]938}
939
[13e3b50]940// DeclarationNode::StorageClass DeclarationNode::buildStorageClass() const {
941// DeclarationNode::StorageClass ret = DeclarationNode::NoStorageClass;
942// for ( std::list< DeclarationNode::StorageClass >::const_iterator i = storageClasses.begin(); i != storageClasses.end(); ++i ) {
943// if ( *i == DeclarationNode::Inline || *i == DeclarationNode::Noreturn ) continue; // ignore function specifiers
944// if ( ret != DeclarationNode::NoStorageClass ) { // already have a valid storage class ?
945// throw SemanticError( "invalid combination of storage classes in declaration of ", this );
946// } // if
947// ret = *i;
948// } // for
949// return ret;
950// }
951
952// bool DeclarationNode::buildFuncSpecifier( DeclarationNode::StorageClass key ) const {
953// std::list< DeclarationNode::StorageClass >::const_iterator first = std::find( storageClasses.begin(), storageClasses.end(), key );
954// if ( first == storageClasses.end() ) return false; // not found
955// first = std::find( ++first, storageClasses.end(), key ); // found
956// if ( first == storageClasses.end() ) return true; // not found again
957// throw SemanticError( "duplicate function specifier in declaration of ", this );
958// }
[b87a5ed]959
960// Local Variables: //
961// tab-width: 4 //
962// mode: c++ //
963// compile-command: "make install" //
964// End: //
Note: See TracBrowser for help on using the repository browser.