source: src/Parser/DeclarationNode.cc@ 7a69460

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new stuck-waitfor-destruct with_gc
Last change on this file since 7a69460 was a5a71d0, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

Merge branch 'fix-memory-error' into ctor

Conflicts:

src/CodeGen/CodeGenerator.cc
src/Makefile.in
src/Parser/DeclarationNode.cc
src/Parser/ParseNode.h
src/Parser/TypeData.cc
src/Parser/parser.cc
src/Parser/parser.yy
src/ResolvExpr/Resolver.cc
src/SymTab/Validate.cc
src/SynTree/Declaration.h
src/SynTree/Mutator.cc
src/SynTree/Mutator.h
src/SynTree/SynTree.h
src/SynTree/Visitor.cc
src/SynTree/Visitor.h
src/libcfa/prelude.cf

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