source: translator/SymTab/Validate.cc @ 134b86a

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 134b86a was 134b86a, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

add compiler flag to driver, update examples, fix unnamed bit fields

  • Property mode set to 100644
File size: 27.5 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  ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member ); // PAB: unnamed bit fields are not copied
556  if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
557
558  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
559 
560  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
561  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
562 
563  // do something special for unnamed members
564  Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
565  assignExpr->get_args().push_back( dstselect );
566 
567  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
568  assignExpr->get_args().push_back( srcselect );
569 
570  *out++ = new ExprStmt( noLabels, assignExpr );
571}
572
573template< typename OutputIterator >
574void
575makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out )
576{
577  static UniqueName indexName( "_index" );
578 
579  // for a flexible array member nothing is done -- user must define own assignment
580  if( !array->get_dimension() ) return;
581 
582  ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
583  *out++ = new DeclStmt( noLabels, index );
584 
585  UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
586  init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
587  init->get_args().push_back( new NameExpr( "0" ) );
588  Statement *initStmt = new ExprStmt( noLabels, init );
589 
590  UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
591  cond->get_args().push_back( new VariableExpr( index ) );
592  cond->get_args().push_back( array->get_dimension()->clone() );
593 
594  UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
595  inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
596 
597  UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
598 
599  UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
600  derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
601 
602  Expression *dstselect = new MemberExpr( member, derefExpr );
603  UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
604  dstIndex->get_args().push_back( dstselect );
605  dstIndex->get_args().push_back( new VariableExpr( index ) );
606  assignExpr->get_args().push_back( dstIndex );
607 
608  Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
609  UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
610  srcIndex->get_args().push_back( srcselect );
611  srcIndex->get_args().push_back( new VariableExpr( index ) );
612  assignExpr->get_args().push_back( srcIndex );
613 
614  *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
615}
616
617Declaration*
618makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType )
619{
620  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
621 
622  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
623  assignType->get_returnVals().push_back( returnVal );
624 
625  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
626  assignType->get_parameters().push_back( dstParam );
627 
628  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
629  assignType->get_parameters().push_back( srcParam );
630 
631  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
632  assignDecl->fixUniqueId();
633 
634  for( std::list< Declaration* >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
635    if( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *member ) ) {
636      if( ArrayType *array = dynamic_cast< ArrayType* >( dwt->get_type() ) ) {
637        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
638      } else {
639        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
640      }
641    }
642  }
643  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
644 
645  return assignDecl;
646}
647
648Declaration*
649makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType )
650{
651  FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
652 
653  ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
654  assignType->get_returnVals().push_back( returnVal );
655 
656  ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
657  assignType->get_parameters().push_back( dstParam );
658 
659  ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
660  assignType->get_parameters().push_back( srcParam );
661 
662  FunctionDecl *assignDecl = new FunctionDecl( "?=?", Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
663  assignDecl->fixUniqueId();
664 
665  UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
666  copy->get_args().push_back( new VariableExpr( dstParam ) );
667  copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
668  copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
669
670  assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
671  assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
672 
673  return assignDecl;
674}
675
676void
677AddStructAssignment::visit( StructDecl *structDecl )
678{
679  if( !structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
680    StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
681    structInst->set_baseStruct( structDecl );
682    declsToAdd.push_back( makeStructAssignment( structDecl, structInst ) );
683    structsDone.insert( structDecl->get_name() );
684  }
685}
686
687void
688AddStructAssignment::visit( UnionDecl *unionDecl )
689{
690  if( !unionDecl->get_members().empty() ) {
691    UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
692    unionInst->set_baseUnion( unionDecl );
693    declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst ) );
694  }
695}
696
697void
698AddStructAssignment::visit( TypeDecl *typeDecl )
699{
700  CompoundStmt *stmts = 0;
701  TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
702  typeInst->set_baseType( typeDecl );
703  ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
704  ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
705  if( typeDecl->get_base() ) {
706    stmts = new CompoundStmt( std::list< Label >() );
707    UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
708    assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
709    assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
710    stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
711  }
712  FunctionType *type = new FunctionType( Type::Qualifiers(), false );
713  type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
714  type->get_parameters().push_back( dst );
715  type->get_parameters().push_back( src );
716  FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
717  declsToAdd.push_back( func );
718}
719
720void
721addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i )
722{
723  if( !declsToAdd.empty() ) {
724    for( std::list< Declaration* >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
725      statements.insert( i, new DeclStmt( noLabels, *decl ) );
726    }
727    declsToAdd.clear();
728  }
729}
730
731void
732AddStructAssignment::visit(FunctionType *)
733{
734  // ensure that we don't add assignment ops for types defined
735  // as part of the function
736}
737
738void
739AddStructAssignment::visit(PointerType *)
740{
741  // ensure that we don't add assignment ops for types defined
742  // as part of the pointer
743}
744
745void
746AddStructAssignment::visit(ContextDecl *)
747{
748  // ensure that we don't add assignment ops for types defined
749  // as part of the context
750}
751
752template< typename StmtClass >
753inline void
754AddStructAssignment::visitStatement(StmtClass *stmt)
755{
756  std::set< std::string > oldStructs = structsDone;
757  addVisit( stmt, *this );
758  structsDone = oldStructs;
759}
760
761void
762AddStructAssignment::visit(CompoundStmt *compoundStmt)
763{
764  visitStatement( compoundStmt );
765}
766
767void
768AddStructAssignment::visit(IfStmt *ifStmt)
769{
770  visitStatement( ifStmt );
771}
772
773void
774AddStructAssignment::visit(WhileStmt *whileStmt)
775{
776  visitStatement( whileStmt );
777}
778
779void
780AddStructAssignment::visit(ForStmt *forStmt)
781{
782  visitStatement( forStmt );
783}
784
785void
786AddStructAssignment::visit(SwitchStmt *switchStmt)
787{
788  visitStatement( switchStmt );
789}
790
791void
792AddStructAssignment::visit(ChooseStmt *switchStmt)
793{
794  visitStatement( switchStmt );
795}
796
797void
798AddStructAssignment::visit(CaseStmt *caseStmt)
799{
800  visitStatement( caseStmt );
801}
802
803void
804AddStructAssignment::visit(CatchStmt *cathStmt)
805{
806  visitStatement( cathStmt );
807}
808
809bool
810isTypedef( Declaration *decl )
811{
812  return dynamic_cast< TypedefDecl* >( decl );
813}
814
815
816/* static class method */
817void 
818EliminateTypedef::eliminateTypedef( std::list< Declaration* > &translationUnit )
819{
820  EliminateTypedef eliminator;
821  mutateAll( translationUnit, eliminator );
822  filter( translationUnit, isTypedef, true );
823}
824
825Type*
826EliminateTypedef::mutate( TypeInstType *typeInst )
827{
828  std::map< std::string, TypedefDecl* >::const_iterator def = typedefNames.find( typeInst->get_name() );
829  if( def != typedefNames.end() ) {
830    Type *ret = def->second->get_base()->clone();
831    ret->get_qualifiers() += typeInst->get_qualifiers();
832    delete typeInst;
833    return ret;
834  }
835  return typeInst;
836}
837
838Declaration*
839EliminateTypedef::mutate( TypedefDecl *tyDecl )
840{
841  Declaration *ret = Mutator::mutate( tyDecl );
842  typedefNames[ tyDecl->get_name() ] = tyDecl;
843  if( AggregateDecl *aggDecl = dynamic_cast< AggregateDecl* >( tyDecl->get_base() ) ) {
844    tyDecl->set_base( 0 );
845    delete tyDecl;
846    return aggDecl;
847  } else {
848    return ret;
849  }
850}
851
852TypeDecl*
853EliminateTypedef::mutate(TypeDecl *typeDecl)
854{
855  std::map< std::string, TypedefDecl* >::iterator i = typedefNames.find( typeDecl->get_name() );
856  if( i != typedefNames.end() ) {
857    typedefNames.erase( i ) ;
858  }
859  return typeDecl;
860}
861
862DeclarationWithType*
863EliminateTypedef::mutate(FunctionDecl *funcDecl)
864{
865  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
866  DeclarationWithType *ret = Mutator::mutate( funcDecl );
867  typedefNames = oldNames;
868  return ret;
869}
870
871ObjectDecl*
872EliminateTypedef::mutate(ObjectDecl *objDecl)
873{
874  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
875  ObjectDecl *ret = Mutator::mutate( objDecl );
876  typedefNames = oldNames;
877  return ret;
878}
879
880Expression*
881EliminateTypedef::mutate(CastExpr *castExpr)
882{
883  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
884  Expression *ret = Mutator::mutate( castExpr );
885  typedefNames = oldNames;
886  return ret;
887}
888
889CompoundStmt * 
890EliminateTypedef::mutate( CompoundStmt *compoundStmt )
891{
892  std::map< std::string, TypedefDecl* > oldNames = typedefNames;
893  CompoundStmt *ret = Mutator::mutate( compoundStmt );
894  std::list< Statement* >::iterator i = compoundStmt->get_kids().begin();
895  while( i != compoundStmt->get_kids().end() ) {
896    std::list< Statement* >::iterator next = i;
897    ++next;
898    if( DeclStmt *declStmt = dynamic_cast< DeclStmt* >( *i ) ) {
899      if( dynamic_cast< TypedefDecl* >( declStmt->get_decl() ) ) {
900        delete *i;
901        compoundStmt->get_kids().erase( i );
902      }
903    }
904    i = next;
905  }
906  typedefNames = oldNames;
907  return ret;
908}
909
910} // namespace SymTab
Note: See TracBrowser for help on using the repository browser.