source: translator/SymTab/Validate.cc@ 51b73452

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string stuck-waitfor-destruct with_gc
Last change on this file since 51b73452 was 51b73452, checked in by Peter A. Buhr <pabuhr@…>, 12 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.