source: translator/Parser/DeclarationNode.cc @ a0d9f94

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 a0d9f94 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

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