source: translator/SymTab/Validate.cc @ 91b216b4

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

initial commit

  • Property mode set to 100644
File size: 27.3 KB
Line 
1/*
2 * This file is part of the Cforall project
3 *
4 * $Id: Validate.cc,v 1.22 2005/08/29 20:14:18 rcbilson Exp $
5 *
6 */
7
8/*
9   The "validate" phase of translation is used to take a syntax tree and convert it into a
10   standard form that aims to be as regular in structure as possible.  Some assumptions can be
11   made regarding the state of the tree after this pass is complete, including:
12
13   - No nested structure or union definitions; any in the input are "hoisted" to the level of
14     the containing struct or union.
15
16   - All enumeration constants have type EnumInstType.
17
18   - The type "void" never occurs in lists of function parameter or return types; neither do
19     tuple types.  A function taking no arguments has no argument types, and tuples are flattened.
20
21   - No context instances exist; they are all replaced by the set of declarations signified by
22     the context, instantiated by the particular set of type arguments.
23
24   - Every declaration is assigned a unique id.
25
26   - No typedef declarations or instances exist; the actual type is substituted for each instance.
27
28   - Each type, struct, and union definition is followed by an appropriate assignment operator.
29
30   - Each use of a struct or union is connected to a complete definition of that struct or union,
31     even if that definition occurs later in the input.
32*/
33
34#include <list>
35#include <iterator>
36#include "Validate.h"
37#include "SynTree/Visitor.h"
38#include "SynTree/Mutator.h"
39#include "SynTree/Type.h"
40#include "SynTree/Statement.h"
41#include "Indexer.h"
42#include "SynTree/TypeSubstitution.h"
43#include "FixFunction.h"
44#include "ImplementationType.h"
45#include "utility.h"
46#include "UniqueName.h"
47#include "AddVisit.h"
48
49
50#define debugPrint(x) if( doDebug ) { std::cout << x; }
51
52namespace SymTab {
53
54class HoistStruct : public Visitor
55{
56public:
57  static void hoistStruct( std::list< Declaration* > &translationUnit );
58 
59  std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
60 
61  virtual void visit(StructDecl *aggregateDecl);
62  virtual void visit(UnionDecl *aggregateDecl);
63
64  virtual void visit(CompoundStmt *compoundStmt);
65  virtual void visit(IfStmt *ifStmt);
66  virtual void visit(WhileStmt *whileStmt);
67  virtual void visit(ForStmt *forStmt);
68  virtual void visit(SwitchStmt *switchStmt);
69  virtual void visit(ChooseStmt *chooseStmt);
70  virtual void visit(CaseStmt *caseStmt);
71  virtual void visit(CatchStmt *catchStmt);
72 
73private:
74  HoistStruct();
75
76  template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
77
78  std::list< Declaration* > declsToAdd;
79  bool inStruct;
80};
81
82class Pass1 : public Visitor
83{
84  typedef Visitor Parent;
85  virtual void visit( EnumDecl *aggregateDecl);
86  virtual void visit( FunctionType *func );
87};
88 
89class Pass2 : public Indexer
90{
91  typedef Indexer Parent;
92
93public:
94  Pass2( bool doDebug, const Indexer *indexer );
95
96private:
97  virtual void visit( StructInstType *structInst );
98  virtual void visit( UnionInstType *unionInst );
99  virtual void visit( ContextInstType *contextInst );
100  virtual void visit( StructDecl *structDecl );
101  virtual void visit( UnionDecl *unionDecl );
102  virtual void visit( TypeInstType *typeInst );
103
104  const Indexer *indexer;
105 
106  typedef std::map< std::string, std::list< StructInstType* > > ForwardStructsType;
107  typedef std::map< std::string, std::list< UnionInstType* > > ForwardUnionsType;
108  ForwardStructsType forwardStructs;
109  ForwardUnionsType forwardUnions;
110};
111
112class Pass3 : public Indexer
113{
114  typedef Indexer Parent;
115
116public:
117  Pass3( const Indexer *indexer );
118
119private:
120  virtual void visit( ObjectDecl *object );
121  virtual void visit( FunctionDecl *func );
122
123  const Indexer *indexer;
124};
125
126class AddStructAssignment : public Visitor
127{
128public:
129  static void addStructAssignment( std::list< Declaration* > &translationUnit );
130
131  std::list< Declaration* > &get_declsToAdd() { return declsToAdd; }
132 
133  virtual void visit( StructDecl *structDecl );
134  virtual void visit( UnionDecl *structDecl );
135  virtual void visit( TypeDecl *typeDecl );
136  virtual void visit( ContextDecl *ctxDecl );
137
138  virtual void visit( FunctionType *ftype );
139  virtual void visit( PointerType *ftype );
140 
141  virtual void visit(CompoundStmt *compoundStmt);
142  virtual void visit(IfStmt *ifStmt);
143  virtual void visit(WhileStmt *whileStmt);
144  virtual void visit(ForStmt *forStmt);
145  virtual void visit(SwitchStmt *switchStmt);
146  virtual void visit(ChooseStmt *chooseStmt);
147  virtual void visit(CaseStmt *caseStmt);
148  virtual void visit(CatchStmt *catchStmt);
149 
150private:
151  template< typename StmtClass > void visitStatement(StmtClass *stmt);
152 
153  std::list< Declaration* > declsToAdd;
154  std::set< std::string > structsDone;
155};
156
157class EliminateTypedef : public Mutator
158{
159public:
160  static void eliminateTypedef( std::list< Declaration* > &translationUnit );
161 
162private:
163  virtual Declaration* mutate(TypedefDecl *typeDecl);
164  virtual TypeDecl* mutate(TypeDecl *typeDecl);
165  virtual DeclarationWithType* mutate(FunctionDecl *funcDecl);
166  virtual ObjectDecl* mutate(ObjectDecl *objDecl);
167  virtual CompoundStmt* mutate(CompoundStmt *compoundStmt);
168  virtual Type* mutate(TypeInstType *aggregateUseType);
169  virtual Expression* mutate(CastExpr *castExpr);
170 
171  std::map< std::string, TypedefDecl* > typedefNames;
172};
173
174void 
175validate( std::list< Declaration* > &translationUnit, bool doDebug, const Indexer *indexer )
176{
177  Pass1 pass1;
178  Pass2 pass2( doDebug, indexer );
179  Pass3 pass3( indexer );
180  EliminateTypedef::eliminateTypedef( translationUnit );
181  HoistStruct::hoistStruct( translationUnit );
182  acceptAll( translationUnit, pass1 );
183  acceptAll( translationUnit, pass2 );
184  AddStructAssignment::addStructAssignment( translationUnit );
185  acceptAll( translationUnit, pass3 );
186}
187
188void
189validateType( Type *type, const Indexer *indexer )
190{
191  Pass1 pass1;
192  Pass2 pass2( false, indexer );
193  Pass3 pass3( indexer );
194  type->accept( pass1 );
195  type->accept( pass2 );
196  type->accept( pass3 );
197}
198
199template< typename Visitor >
200void
201acceptAndAdd( std::list< Declaration* > &translationUnit, Visitor &visitor, bool addBefore )
202{
203  std::list< Declaration* >::iterator i = translationUnit.begin();
204  while( i != translationUnit.end() ) {
205    (*i)->accept( visitor );
206    std::list< Declaration* >::iterator next = i;
207    next++;
208    if( !visitor.get_declsToAdd().empty() ) {
209      translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
210    }
211    i = next;
212  }
213}
214
215/* static class method */
216void 
217HoistStruct::hoistStruct( std::list< Declaration* > &translationUnit )
218{
219  HoistStruct hoister;
220  acceptAndAdd( translationUnit, hoister, true );
221}
222
223HoistStruct::HoistStruct()
224  : inStruct( false )
225{
226}
227
228void
229filter( std::list< Declaration* > &declList, bool (*pred)( Declaration* ), bool doDelete )
230{
231  std::list< Declaration* >::iterator i = declList.begin();
232  while( i != declList.end() ) {
233    std::list< Declaration* >::iterator next = i;
234    ++next;
235    if( pred( *i ) ) {
236      if( doDelete ) {
237        delete *i;
238      }
239      declList.erase( i );
240    }
241    i = next;
242  }
243}
244
245bool
246isStructOrUnion( Declaration *decl )
247{
248  return dynamic_cast< StructDecl* >( decl ) || dynamic_cast< UnionDecl* >( decl );
249}
250
251template< typename AggDecl >
252void
253HoistStruct::handleAggregate( AggDecl *aggregateDecl )
254{
255  if( inStruct ) {
256    declsToAdd.push_back( aggregateDecl );
257    Visitor::visit( aggregateDecl );
258  } else {
259    inStruct = true;
260    Visitor::visit( aggregateDecl );
261    inStruct = false;
262    filter( aggregateDecl->get_members(), isStructOrUnion, false );
263  }
264}
265
266void 
267HoistStruct::visit(StructDecl *aggregateDecl)
268{
269  handleAggregate( aggregateDecl );
270}
271
272void 
273HoistStruct::visit(UnionDecl *aggregateDecl)
274{
275  handleAggregate( aggregateDecl );
276}
277
278void
279HoistStruct::visit(CompoundStmt *compoundStmt)
280{
281  addVisit( compoundStmt, *this );
282}
283
284void
285HoistStruct::visit(IfStmt *ifStmt)
286{
287  addVisit( ifStmt, *this );
288}
289
290void
291HoistStruct::visit(WhileStmt *whileStmt)
292{
293  addVisit( whileStmt, *this );
294}
295
296void
297HoistStruct::visit(ForStmt *forStmt)
298{
299  addVisit( forStmt, *this );
300}
301
302void
303HoistStruct::visit(SwitchStmt *switchStmt)
304{
305  addVisit( switchStmt, *this );
306}
307
308void
309HoistStruct::visit(ChooseStmt *switchStmt)
310{
311  addVisit( switchStmt, *this );
312}
313
314void
315HoistStruct::visit(CaseStmt *caseStmt)
316{
317  addVisit( caseStmt, *this );
318}
319
320void
321HoistStruct::visit(CatchStmt *cathStmt)
322{
323  addVisit( cathStmt, *this );
324}
325
326void 
327Pass1::visit( EnumDecl *enumDecl)
328{
329  // Set the type of each member of the enumeration to be EnumConstant
330 
331  for( std::list< Declaration* >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
332    ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
333    assert( obj );
334    obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false ), enumDecl->get_name() ) );
335  }
336  Parent::visit( enumDecl );
337}
338
339namespace {
340template< typename DWTIterator >
341void
342fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func )
343{
344  // the only case in which "void" is valid is where it is the only one in the list; then
345  // it should be removed entirely
346  // other fix ups are handled by the FixFunction class
347  if( begin == end ) return;
348  FixFunction fixer;
349  DWTIterator i = begin;
350  *i = (*i)->acceptMutator( fixer );
351  if( fixer.get_isVoid() ) {
352    DWTIterator j = i;
353    ++i;
354    func->get_parameters().erase( j );
355    if( i != end ) { 
356      throw SemanticError( "invalid type void in function type ", func );
357    }
358  } else {
359    ++i;
360    for( ; i != end; ++i ) {
361      FixFunction fixer;
362      *i = (*i)->acceptMutator( fixer );
363      if( fixer.get_isVoid() ) {
364        throw SemanticError( "invalid type void in function type ", func );
365      }
366    }
367  }
368}
369}
370
371void 
372Pass1::visit( FunctionType *func )
373{
374  // Fix up parameters and return types
375  fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
376  fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
377  Visitor::visit( func );
378}
379
380Pass2::Pass2( bool doDebug, const Indexer *other_indexer )
381  : Indexer( doDebug )
382{
383  if( other_indexer ) {
384    indexer = other_indexer;
385  } else {
386    indexer = this;
387  }
388}
389
390void 
391Pass2::visit( StructInstType *structInst )
392{
393  Parent::visit( structInst );
394  StructDecl *st = indexer->lookupStruct( structInst->get_name() );
395  // it's not a semantic error if the struct is not found, just an implicit forward declaration
396  if( st ) {
397    assert( !structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || !st->get_members().empty() );
398    structInst->set_baseStruct( st );
399  }
400  if( !st || st->get_members().empty() ) {
401    // use of forward declaration
402    forwardStructs[ structInst->get_name() ].push_back( structInst );
403  }
404}
405
406void 
407Pass2::visit( UnionInstType *unionInst )
408{
409  Parent::visit( unionInst );
410  UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
411  // it's not a semantic error if the union is not found, just an implicit forward declaration
412  if( un ) {
413    unionInst->set_baseUnion( un );
414  }
415  if( !un || un->get_members().empty() ) {
416    // use of forward declaration
417    forwardUnions[ unionInst->get_name() ].push_back( unionInst );
418  }
419}
420
421void 
422Pass2::visit( ContextInstType *contextInst )
423{
424  Parent::visit( contextInst );
425  ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
426  if( !ctx ) {
427    throw SemanticError( "use of undeclared context " + contextInst->get_name() );
428  }
429  for( std::list< TypeDecl* >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
430    for( std::list< DeclarationWithType* >::const_iterator assert = (*i)->get_assertions().begin(); assert != (*i)->get_assertions().end(); ++assert ) {
431      if( ContextInstType *otherCtx = dynamic_cast< ContextInstType* >(*assert) ) {
432        cloneAll( otherCtx->get_members(), contextInst->get_members() );
433      } else {
434        contextInst->get_members().push_back( (*assert)->clone() );
435      }
436    }
437  }
438  applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) );
439}
440
441void 
442Pass2::visit( StructDecl *structDecl )
443{
444  if( !structDecl->get_members().empty() ) {
445    ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
446    if( fwds != forwardStructs.end() ) {
447      for( std::list< StructInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
448        (*inst)->set_baseStruct( structDecl );
449      }
450      forwardStructs.erase( fwds );
451    }
452  }
453  Indexer::visit( structDecl );
454}
455
456void 
457Pass2::visit( UnionDecl *unionDecl )
458{
459  if( !unionDecl->get_members().empty() ) {
460    ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
461    if( fwds != forwardUnions.end() ) {
462      for( std::list< UnionInstType* >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
463        (*inst)->set_baseUnion( unionDecl );
464      }
465      forwardUnions.erase( fwds );
466    }
467  }
468  Indexer::visit( unionDecl );
469}
470
471void 
472Pass2::visit( TypeInstType *typeInst )
473{
474  if( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
475    if( TypeDecl *typeDecl = dynamic_cast< TypeDecl* >( namedTypeDecl ) ) {
476      typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
477    }
478  }
479}
480
481Pass3::Pass3( const Indexer *other_indexer )
482  : Indexer( false )
483{
484  if( other_indexer ) {
485    indexer = other_indexer;
486  } else {
487    indexer = this;
488  }
489}
490
491void 
492forallFixer( Type *func )
493{
494  // Fix up assertions
495  for( std::list< TypeDecl* >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
496    std::list< DeclarationWithType* > toBeDone, nextRound;
497    toBeDone.splice( toBeDone.end(), (*type)->get_assertions() );
498    while( !toBeDone.empty() ) {
499      for( std::list< DeclarationWithType* >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
500        if( ContextInstType *ctx = dynamic_cast< ContextInstType* >( (*assertion)->get_type() ) ) {
501          for( std::list< Declaration* >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
502            DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i );
503            assert( dwt );
504            nextRound.push_back( dwt->clone() );
505          }
506          delete ctx;
507        } else {
508          FixFunction fixer;
509          *assertion = (*assertion)->acceptMutator( fixer );
510          if( fixer.get_isVoid() ) {
511            throw SemanticError( "invalid type void in assertion of function ", func );
512          }
513          (*type)->get_assertions().push_back( *assertion );
514        }
515      }
516      toBeDone.clear();
517      toBeDone.splice( toBeDone.end(), nextRound );
518    }
519  }
520}
521
522void 
523Pass3::visit( ObjectDecl *object )
524{
525  forallFixer( object->get_type() );
526  if( PointerType *pointer = dynamic_cast< PointerType* >( object->get_type() ) ) {
527    forallFixer( pointer->get_base() );
528  }
529  Parent::visit( object );
530  object->fixUniqueId();
531}
532
533void 
534Pass3::visit( FunctionDecl *func )
535{
536  forallFixer( func->get_type() );
537  Parent::visit( func );
538  func->fixUniqueId();
539}
540
541static const std::list< std::string > noLabels;
542
543/* static class method */
544void
545AddStructAssignment::addStructAssignment( std::list< Declaration* > &translationUnit )
546{
547  AddStructAssignment visitor;
548  acceptAndAdd( translationUnit, visitor, false );
549}
550
551template< typename OutputIterator >
552void
553makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out )
554{
555  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
556 
557  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
558  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
559 
560  // do something special for unnamed members
561  Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
562  assignExpr->get_args().push_back( dstselect );
563 
564  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
565  assignExpr->get_args().push_back( srcselect );
566 
567  *out++ = new ExprStmt( noLabels, assignExpr );
568}
569
570template< typename OutputIterator >
571void
572makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out )
573{
574  static UniqueName indexName( "_index" );
575 
576  // for a flexible array member nothing is done -- user must define own assignment
577  if( !array->get_dimension() ) return;
578 
579  ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
580  *out++ = new DeclStmt( noLabels, index );
581 
582  UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
583  init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
584  init->get_args().push_back( new NameExpr( "0" ) );
585  Statement *initStmt = new ExprStmt( noLabels, init );
586 
587  UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
588  cond->get_args().push_back( new VariableExpr( index ) );
589  cond->get_args().push_back( array->get_dimension()->clone() );
590 
591  UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
592  inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
593 
594  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
595 
596  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
597  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
598 
599  Expression *dstselect = new MemberExpr( member, derefExpr );
600  UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
601  dstIndex->get_args().push_back( dstselect );
602  dstIndex->get_args().push_back( new VariableExpr( index ) );
603  assignExpr->get_args().push_back( dstIndex );
604 
605  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
606  UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
607  srcIndex->get_args().push_back( srcselect );
608  srcIndex->get_args().push_back( new VariableExpr( index ) );
609  assignExpr->get_args().push_back( srcIndex );
610 
611  *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
612}
613
614Declaration*
615makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType )
616{
617  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
618 
619  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
620  assignType->get_returnVals().push_back( returnVal );
621 
622  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
623  assignType->get_parameters().push_back( dstParam );
624 
625  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
626  assignType->get_parameters().push_back( srcParam );
627 
628  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
629  assignDecl->fixUniqueId();
630 
631  for( std::list< Declaration* >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
632    if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *member ) ) {
633      if( ArrayType *array = dynamic_cast< ArrayType* >( dwt->get_type() ) ) {
634        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
635      } else {
636        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
637      }
638    }
639  }
640  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
641 
642  return assignDecl;
643}
644
645Declaration*
646makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType )
647{
648  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
649 
650  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
651  assignType->get_returnVals().push_back( returnVal );
652 
653  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
654  assignType->get_parameters().push_back( dstParam );
655 
656  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
657  assignType->get_parameters().push_back( srcParam );
658 
659  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
660  assignDecl->fixUniqueId();
661 
662  UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
663  copy->get_args().push_back( new VariableExpr( dstParam ) );
664  copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
665  copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
666
667  assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
668  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
669 
670  return assignDecl;
671}
672
673void
674AddStructAssignment::visit( StructDecl *structDecl )
675{
676  if( !structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
677    StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
678    structInst->set_baseStruct( structDecl );
679    declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
680    structsDone.insert( structDecl->get_name() );
681  }
682}
683
684void
685AddStructAssignment::visit( UnionDecl *unionDecl )
686{
687  if( !unionDecl->get_members().empty() ) {
688    UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
689    unionInst->set_baseUnion( unionDecl );
690    declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
691  }
692}
693
694void
695AddStructAssignment::visit( TypeDecl *typeDecl )
696{
697  CompoundStmt *stmts = 0;
698  TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
699  typeInst->set_baseType( typeDecl );
700  ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
701  ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
702  if( typeDecl->get_base() ) {
703    stmts = new CompoundStmt( std::list< Label >() );
704    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
705    assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
706    assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
707    stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
708  }
709  FunctionType *type = new FunctionType( Type::Qualifiers(), false );
710  type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
711  type->get_parameters().push_back( dst );
712  type->get_parameters().push_back( src );
713  FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
714  declsToAdd.push_back( func );
715}
716
717void
718addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i )
719{
720  if( !declsToAdd.empty() ) {
721    for( std::list< Declaration* >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
722      statements.insert( i, new DeclStmt( noLabels, *decl ) );
723    }
724    declsToAdd.clear();
725  }
726}
727
728void
729AddStructAssignment::visit(FunctionType *)
730{
731  // ensure that we don't add assignment ops for types defined
732  // as part of the function
733}
734
735void
736AddStructAssignment::visit(PointerType *)
737{
738  // ensure that we don't add assignment ops for types defined
739  // as part of the pointer
740}
741
742void
743AddStructAssignment::visit(ContextDecl *)
744{
745  // ensure that we don't add assignment ops for types defined
746  // as part of the context
747}
748
749template< typename StmtClass >
750inline void
751AddStructAssignment::visitStatement(StmtClass *stmt)
752{
753  std::set< std::string > oldStructs = structsDone;
754  addVisit( stmt, *this );
755  structsDone = oldStructs;
756}
757
758void
759AddStructAssignment::visit(CompoundStmt *compoundStmt)
760{
761  visitStatement( compoundStmt );
762}
763
764void
765AddStructAssignment::visit(IfStmt *ifStmt)
766{
767  visitStatement( ifStmt );
768}
769
770void
771AddStructAssignment::visit(WhileStmt *whileStmt)
772{
773  visitStatement( whileStmt );
774}
775
776void
777AddStructAssignment::visit(ForStmt *forStmt)
778{
779  visitStatement( forStmt );
780}
781
782void
783AddStructAssignment::visit(SwitchStmt *switchStmt)
784{
785  visitStatement( switchStmt );
786}
787
788void
789AddStructAssignment::visit(ChooseStmt *switchStmt)
790{
791  visitStatement( switchStmt );
792}
793
794void
795AddStructAssignment::visit(CaseStmt *caseStmt)
796{
797  visitStatement( caseStmt );
798}
799
800void
801AddStructAssignment::visit(CatchStmt *cathStmt)
802{
803  visitStatement( cathStmt );
804}
805
806bool
807isTypedef( Declaration *decl )
808{
809  return dynamic_cast< TypedefDecl* >( decl );
810}
811
812
813/* static class method */
814void 
815EliminateTypedef::eliminateTypedef( std::list< Declaration* > &translationUnit )
816{
817  EliminateTypedef eliminator;
818  mutateAll( translationUnit, eliminator );
819  filter( translationUnit, isTypedef, true );
820}
821
822Type*
823EliminateTypedef::mutate( TypeInstType *typeInst )
824{
825  std::map< std::string, TypedefDecl* >::const_iterator def = typedefNames.find( typeInst->get_name() );
826  if( def != typedefNames.end() ) {
827    Type *ret = def->second->get_base()->clone();
828    ret->get_qualifiers() += typeInst->get_qualifiers();
829    delete typeInst;
830    return ret;
831  }
832  return typeInst;
833}
834
835Declaration*
836EliminateTypedef::mutate( TypedefDecl *tyDecl )
837{
838  Declaration *ret = Mutator::mutate( tyDecl );
839  typedefNames[ tyDecl->get_name() ] = tyDecl;
840  if( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl* >( tyDecl->get_base() ) ) {
841    tyDecl->set_base( 0 );
842    delete tyDecl;
843    return aggDecl;
844  } else {
845    return ret;
846  }
847}
848
849TypeDecl*
850EliminateTypedef::mutate(TypeDecl *typeDecl)
851{
852  std::map< std::string, TypedefDecl* >::iterator i = typedefNames.find( typeDecl->get_name() );
853  if( i != typedefNames.end() ) {
854    typedefNames.erase( i ) ;
855  }
856  return typeDecl;
857}
858
859DeclarationWithType*
860EliminateTypedef::mutate(FunctionDecl *funcDecl)
861{
862  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
863  DeclarationWithType *ret = Mutator::mutate( funcDecl );
864  typedefNames = oldNames;
865  return ret;
866}
867
868ObjectDecl*
869EliminateTypedef::mutate(ObjectDecl *objDecl)
870{
871  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
872  ObjectDecl *ret = Mutator::mutate( objDecl );
873  typedefNames = oldNames;
874  return ret;
875}
876
877Expression*
878EliminateTypedef::mutate(CastExpr *castExpr)
879{
880  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
881  Expression *ret = Mutator::mutate( castExpr );
882  typedefNames = oldNames;
883  return ret;
884}
885
886CompoundStmt * 
887EliminateTypedef::mutate( CompoundStmt *compoundStmt )
888{
889  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
890  CompoundStmt *ret = Mutator::mutate( compoundStmt );
891  std::list< Statement* >::iterator i = compoundStmt->get_kids().begin();
892  while( i != compoundStmt->get_kids().end() ) {
893    std::list< Statement* >::iterator next = i;
894    ++next;
895    if( DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *i ) ) {
896      if( dynamic_cast< TypedefDecl* >( declStmt->get_decl() ) ) {
897        delete *i;
898        compoundStmt->get_kids().erase( i );
899      }
900    }
901    i = next;
902  }
903  typedefNames = oldNames;
904  return ret;
905}
906
907} // namespace SymTab
Note: See TracBrowser for help on using the repository browser.