source: translator/Parser/DeclarationNode.cc @ d11f789

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since d11f789 was 8c17ab0, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

add quoted identifiers, add compilation include directory, reformatted some files

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