Changeset 0dd3a2f for translator/SymTab


Ignore:
Timestamp:
May 18, 2015, 11:20:23 AM (11 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
51587aa
Parents:
a32b204
Message:

licencing: third groups of files

Location:
translator/SymTab
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • translator/SymTab/AddVisit.h

    ra32b204 r0dd3a2f  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AddVisit.h,v 1.2 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
    7 
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AddVisit.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 16:14:32 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 16:16:38 2015
     13// Update Count     : 3
     14//
    815
    916namespace SymTab {
     17        void addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i );
    1018
    11 void addDecls( std::list< Declaration* > &declsToAdd, std::list< Statement* > &statements, std::list< Statement* >::iterator i );
     19        template< typename Visitor >
     20        inline void addVisitStatementList( std::list< Statement* > &statements, Visitor &visitor ) {
     21                for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     22                        addDecls( visitor.get_declsToAdd(), statements, i );
     23                        (*i)->accept( visitor );
     24                } // for
     25                addDecls( visitor.get_declsToAdd(), statements, statements.end() );
     26        }
    1227
    13 template< typename Visitor >
    14 inline void
    15 addVisitStatementList( std::list< Statement* > &statements, Visitor &visitor )
    16 {
    17   for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    18     addDecls( visitor.get_declsToAdd(), statements, i );
    19     (*i)->accept( visitor );
    20   }
    21   addDecls( visitor.get_declsToAdd(), statements, statements.end() );
    22 }
    23 
    24 template< typename Visitor >
    25 inline void
    26 addVisitStatement( Statement *stmt, Visitor &visitor )
    27 {
    28   maybeAccept( stmt, visitor );
     28        template< typename Visitor >
     29        inline void addVisitStatement( Statement *stmt, Visitor &visitor ) {
     30                maybeAccept( stmt, visitor );
    2931///   if ( ! declsToAdd.empty() ) {
    3032///     CompoundStmt *compound = new CompoundStmt( noLabels );
     
    3234///     addDecls( declsToAdd, compound->get_kids(), compound->get_kids().end() );
    3335///   }
    34 }
     36        }
    3537
    36 template< typename Visitor >
    37 inline void
    38 addVisit(CompoundStmt *compoundStmt, Visitor &visitor)
    39 {
    40   addVisitStatementList( compoundStmt->get_kids(), visitor );
    41 }
     38        template< typename Visitor >
     39        inline void addVisit(CompoundStmt *compoundStmt, Visitor &visitor) {
     40                addVisitStatementList( compoundStmt->get_kids(), visitor );
     41        }
    4242
    43 template< typename Visitor >
    44 inline void
    45 addVisit(IfStmt *ifStmt, Visitor &visitor)
    46 {
    47   addVisitStatement( ifStmt->get_thenPart(), visitor );
    48   addVisitStatement( ifStmt->get_elsePart(), visitor );
    49   maybeAccept( ifStmt->get_condition(), visitor );
    50 }
     43        template< typename Visitor >
     44        inline void addVisit(IfStmt *ifStmt, Visitor &visitor) {
     45                addVisitStatement( ifStmt->get_thenPart(), visitor );
     46                addVisitStatement( ifStmt->get_elsePart(), visitor );
     47                maybeAccept( ifStmt->get_condition(), visitor );
     48        }
    5149
    52 template< typename Visitor >
    53 inline void
    54 addVisit(WhileStmt *whileStmt, Visitor &visitor)
    55 {
    56   addVisitStatement( whileStmt->get_body(), visitor );
    57   maybeAccept( whileStmt->get_condition(), visitor );
    58 }
     50        template< typename Visitor >
     51        inline void addVisit(WhileStmt *whileStmt, Visitor &visitor) {
     52                addVisitStatement( whileStmt->get_body(), visitor );
     53                maybeAccept( whileStmt->get_condition(), visitor );
     54        }
    5955
    60 template< typename Visitor >
    61 inline void
    62 addVisit(ForStmt *forStmt, Visitor &visitor)
    63 {
    64   addVisitStatement( forStmt->get_body(), visitor );
    65   maybeAccept( forStmt->get_initialization(), visitor );
    66   maybeAccept( forStmt->get_condition(), visitor );
    67   maybeAccept( forStmt->get_increment(), visitor );
    68 }
     56        template< typename Visitor >
     57        inline void addVisit(ForStmt *forStmt, Visitor &visitor) {
     58                addVisitStatement( forStmt->get_body(), visitor );
     59                maybeAccept( forStmt->get_initialization(), visitor );
     60                maybeAccept( forStmt->get_condition(), visitor );
     61                maybeAccept( forStmt->get_increment(), visitor );
     62        }
    6963
    70 template< typename Visitor >
    71 inline void
    72 addVisit(SwitchStmt *switchStmt, Visitor &visitor)
    73 {
    74   addVisitStatementList( switchStmt->get_branches(), visitor );
    75   maybeAccept( switchStmt->get_condition(), visitor );
    76 }
     64        template< typename Visitor >
     65        inline void addVisit(SwitchStmt *switchStmt, Visitor &visitor) {
     66                addVisitStatementList( switchStmt->get_branches(), visitor );
     67                maybeAccept( switchStmt->get_condition(), visitor );
     68        }
    7769
    78 template< typename Visitor >
    79 inline void
    80 addVisit(ChooseStmt *switchStmt, Visitor &visitor)
    81 {
    82   addVisitStatementList( switchStmt->get_branches(), visitor );
    83   maybeAccept( switchStmt->get_condition(), visitor );
    84 }
     70        template< typename Visitor >
     71        inline void addVisit(ChooseStmt *switchStmt, Visitor &visitor) {
     72                addVisitStatementList( switchStmt->get_branches(), visitor );
     73                maybeAccept( switchStmt->get_condition(), visitor );
     74        }
    8575
    86 template< typename Visitor >
    87 inline void
    88 addVisit(CaseStmt *caseStmt, Visitor &visitor)
    89 {
    90   addVisitStatementList( caseStmt->get_statements(), visitor );
    91   maybeAccept( caseStmt->get_condition(), visitor );
    92 }
     76        template< typename Visitor >
     77        inline void addVisit(CaseStmt *caseStmt, Visitor &visitor) {
     78                addVisitStatementList( caseStmt->get_statements(), visitor );
     79                maybeAccept( caseStmt->get_condition(), visitor );
     80        }
    9381
    94 template< typename Visitor >
    95 inline void
    96 addVisit(CatchStmt *cathStmt, Visitor &visitor)
    97 {
    98   addVisitStatement( cathStmt->get_body(), visitor );
    99   maybeAccept( cathStmt->get_decl(), visitor );
    100 }
     82        template< typename Visitor >
     83        inline void addVisit(CatchStmt *cathStmt, Visitor &visitor) {
     84                addVisitStatement( cathStmt->get_body(), visitor );
     85                maybeAccept( cathStmt->get_decl(), visitor );
     86        }
     87} // namespace SymTab
    10188
    102 } // namespace SymTab
     89// Local Variables: //
     90// tab-width: 4 //
     91// mode: c++ //
     92// compile-command: "make install" //
     93// End: //
  • translator/SymTab/AggregateTable.h

    ra32b204 r0dd3a2f  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: AggregateTable.h,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// AggregateTable.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 16:17:26 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 16:19:29 2015
     13// Update Count     : 4
     14//
    715
    8 #ifndef SYMTAB_AGGREGATETABLE_H
    9 #define SYMTAB_AGGREGATETABLE_H
     16#ifndef AGGREGATETABLE_H
     17#define AGGREGATETABLE_H
    1018
    1119#include <map>
     
    1826
    1927namespace SymTab {
     28        template< class AggregateDeclClass >
     29        class AggregateTableConflictFunction : public std::binary_function< AggregateDeclClass *, AggregateDeclClass *, AggregateDeclClass *> {
     30          public:
     31                AggregateDeclClass *operator()( AggregateDeclClass *existing, AggregateDeclClass *added ) {
     32                        if ( existing->get_members().empty() ) {
     33                                return added;
     34                        } else if ( ! added->get_members().empty() ) {
     35                                throw SemanticError( "redeclaration of ", added );
     36                        } // if
     37                        return existing;
     38                }
     39        };
    2040
    21 template< class AggregateDeclClass >
    22 class AggregateTableConflictFunction : public std::binary_function< AggregateDeclClass*, AggregateDeclClass*, AggregateDeclClass* >
    23 {
    24 public:
    25   AggregateDeclClass *operator()( AggregateDeclClass *existing, AggregateDeclClass *added )
    26   {
    27     if ( existing->get_members().empty() ) {
    28       return added;
    29     } else if ( ! added->get_members().empty() ) {
    30       throw SemanticError( "redeclaration of ", added );
    31     }
    32     return existing;
    33   }
    34  
    35 };
    36 
    37 typedef StackTable< StructDecl, AggregateTableConflictFunction< StructDecl > > StructTable;
    38 typedef StackTable< EnumDecl, AggregateTableConflictFunction< EnumDecl > > EnumTable;
    39 typedef StackTable< UnionDecl, AggregateTableConflictFunction< UnionDecl > > UnionTable;
    40 typedef StackTable< ContextDecl, AggregateTableConflictFunction< ContextDecl > > ContextTable;
    41 
     41        typedef StackTable< StructDecl, AggregateTableConflictFunction< StructDecl > > StructTable;
     42        typedef StackTable< EnumDecl, AggregateTableConflictFunction< EnumDecl > > EnumTable;
     43        typedef StackTable< UnionDecl, AggregateTableConflictFunction< UnionDecl > > UnionTable;
     44        typedef StackTable< ContextDecl, AggregateTableConflictFunction< ContextDecl > > ContextTable;
    4245} // namespace SymTab
    4346
    44 #endif /* #ifndef SYMTAB_AGGREGATETABLE_H */
     47#endif // AGGREGATETABLE_H
     48
     49// Local Variables: //
     50// tab-width: 4 //
     51// mode: c++ //
     52// compile-command: "make install" //
     53// End: //
  • translator/SymTab/FixFunction.cc

    ra32b204 r0dd3a2f  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// FixFunction.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 16:19:49 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 16:22:54 2015
     13// Update Count     : 2
     14//
     15
    116#include "FixFunction.h"
    217#include "SynTree/Declaration.h"
     
    621
    722namespace SymTab {
     23        FixFunction::FixFunction() : isVoid( false ) {
     24        }
    825
    9 FixFunction::FixFunction()
    10   : isVoid( false )
    11 {
    12 }
     26        DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) {
     27                ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
     28                delete functionDecl;
     29                return pointer;
     30        }
    1331
    14 DeclarationWithType*
    15 FixFunction::mutate(FunctionDecl *functionDecl)
    16 {
    17   ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClass(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type()->clone() ), 0 );
    18   delete functionDecl;
    19   return pointer;
    20 }
     32        Type * FixFunction::mutate(VoidType *voidType) {
     33                isVoid = true;
     34                return voidType;
     35        }
    2136
    22 Type*
    23 FixFunction::mutate(VoidType *voidType)
    24 {
    25   isVoid = true;
    26   return voidType;
    27 }
     37        Type * FixFunction::mutate(BasicType *basicType) {
     38                return basicType;
     39        }
    2840
    29 Type*
    30 FixFunction::mutate(BasicType *basicType)
    31 {
    32   return basicType;
    33 }
     41        Type * FixFunction::mutate(PointerType *pointerType) {
     42                return pointerType;
     43        }
    3444
    35 Type*
    36 FixFunction::mutate(PointerType *pointerType)
    37 {
    38   return pointerType;
    39 }
     45        Type * FixFunction::mutate(ArrayType *arrayType) {
     46                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
     47                delete arrayType;
     48                return pointerType;
     49        }
    4050
    41 Type*
    42 FixFunction::mutate(ArrayType *arrayType)
    43 {
    44   PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), maybeClone( arrayType->get_base()->clone() ), maybeClone( arrayType->get_dimension() ), arrayType->get_isVarLen(), arrayType->get_isStatic() );
    45   delete arrayType;
    46   return pointerType;
    47 }
     51        Type * FixFunction::mutate(StructInstType *aggregateUseType) {
     52                return aggregateUseType;
     53        }
    4854
    49 Type*
    50 FixFunction::mutate(StructInstType *aggregateUseType)
    51 {
    52   return aggregateUseType;
    53 }
     55        Type * FixFunction::mutate(UnionInstType *aggregateUseType) {
     56                return aggregateUseType;
     57        }
    5458
    55 Type*
    56 FixFunction::mutate(UnionInstType *aggregateUseType)
    57 {
    58   return aggregateUseType;
    59 }
     59        Type * FixFunction::mutate(EnumInstType *aggregateUseType) {
     60                return aggregateUseType;
     61        }
    6062
    61 Type*
    62 FixFunction::mutate(EnumInstType *aggregateUseType)
    63 {
    64   return aggregateUseType;
    65 }
     63        Type * FixFunction::mutate(ContextInstType *aggregateUseType) {
     64                return aggregateUseType;
     65        }
    6666
    67 Type*
    68 FixFunction::mutate(ContextInstType *aggregateUseType)
    69 {
    70   return aggregateUseType;
    71 }
     67        Type * FixFunction::mutate(TypeInstType *aggregateUseType) {
     68                return aggregateUseType;
     69        }
    7270
    73 Type*
    74 FixFunction::mutate(TypeInstType *aggregateUseType)
    75 {
    76   return aggregateUseType;
    77 }
     71        Type * FixFunction::mutate(TupleType *tupleType) {
     72                return tupleType;
     73        }
     74} // namespace SymTab
    7875
    79 Type*
    80 FixFunction::mutate(TupleType *tupleType)
    81 {
    82   return tupleType;
    83 }
    84 
    85 
    86 } // namespace SymTab
     76// Local Variables: //
     77// tab-width: 4 //
     78// mode: c++ //
     79// compile-command: "make install" //
     80// End: //
  • translator/SymTab/FixFunction.h

    ra32b204 r0dd3a2f  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: FixFunction.h,v 1.3 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// FixFunction.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 17:02:08 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 17:03:43 2015
     13// Update Count     : 2
     14//
    715
    8 #ifndef SYMTAB_FIXFUNCTION_H
    9 #define SYMTAB_FIXFUNCTION_H
     16#ifndef FIXFUNCTION_H
     17#define FIXFUNCTION_H
    1018
    1119#include "SynTree/Mutator.h"
    1220
    1321namespace SymTab {
     22        class FixFunction : public Mutator {
     23                typedef Mutator Parent;
     24          public:
     25                FixFunction();
    1426
    15 class FixFunction : public Mutator
    16 {
    17   typedef Mutator Parent;
     27                bool get_isVoid() const { return isVoid; }
     28                void set_isVoid( bool newValue ) { isVoid = newValue; }
     29          private:
     30                virtual DeclarationWithType* mutate(FunctionDecl *functionDecl);
    1831
    19 public:
    20   FixFunction();
    21 
    22   bool get_isVoid() const { return isVoid; }
    23   void set_isVoid( bool newValue ) { isVoid = newValue; }
    24 
    25 private:
    26   virtual DeclarationWithType* mutate(FunctionDecl *functionDecl);
    27 
    28   virtual Type* mutate(VoidType *voidType);
    29   virtual Type* mutate(BasicType *basicType);
    30   virtual Type* mutate(PointerType *pointerType);
    31   virtual Type* mutate(ArrayType *arrayType);
    32   virtual Type* mutate(StructInstType *aggregateUseType);
    33   virtual Type* mutate(UnionInstType *aggregateUseType);
    34   virtual Type* mutate(EnumInstType *aggregateUseType);
    35   virtual Type* mutate(ContextInstType *aggregateUseType);
    36   virtual Type* mutate(TypeInstType *aggregateUseType);
    37   virtual Type* mutate(TupleType *tupleType);
     32                virtual Type* mutate(VoidType *voidType);
     33                virtual Type* mutate(BasicType *basicType);
     34                virtual Type* mutate(PointerType *pointerType);
     35                virtual Type* mutate(ArrayType *arrayType);
     36                virtual Type* mutate(StructInstType *aggregateUseType);
     37                virtual Type* mutate(UnionInstType *aggregateUseType);
     38                virtual Type* mutate(EnumInstType *aggregateUseType);
     39                virtual Type* mutate(ContextInstType *aggregateUseType);
     40                virtual Type* mutate(TypeInstType *aggregateUseType);
     41                virtual Type* mutate(TupleType *tupleType);
    3842 
    39   bool isVoid;
    40 };
    41 
     43                bool isVoid;
     44        };
    4245} // namespace SymTab
    4346
    44 #endif /* #ifndef SYMTAB_FIXFUNCTION_H */
     47#endif // FIXFUNCTION_H
     48
     49// Local Variables: //
     50// tab-width: 4 //
     51// mode: c++ //
     52// compile-command: "make install" //
     53// End: //
  • translator/SymTab/IdTable.cc

    ra32b204 r0dd3a2f  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: IdTable.cc,v 1.6 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// IdTable.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 17:04:02 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 17:07:43 2015
     13// Update Count     : 3
     14//
    715
    816#include <cassert>
     
    1826
    1927namespace SymTab {
     28        IdTable::IdTable() : scopeLevel( 0 ) {
     29        }
    2030
    21 IdTable::IdTable()
    22   : scopeLevel( 0 )
    23 {
    24 }
     31        void IdTable::enterScope() {
     32                scopeLevel++;
     33        }
    2534
    26 void
    27 IdTable::enterScope()
    28 {
    29   scopeLevel++;
    30 }
     35        void IdTable::leaveScope() {
     36                for ( OuterTableType::iterator outer = table.begin(); outer != table.end(); ++outer ) {
     37                        for ( InnerTableType::iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
     38                                std::stack< DeclEntry >& entry = inner->second;
     39                                if ( ! entry.empty() && entry.top().second == scopeLevel ) {
     40                                        entry.pop();
     41                                } // if
     42                        } // for
     43                } // for
    3144
    32 void
    33 IdTable::leaveScope()
    34 {
    35   for ( OuterTableType::iterator outer = table.begin(); outer != table.end(); ++outer ) {
    36     for ( InnerTableType::iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
    37       std::stack< DeclEntry >& entry = inner->second;
    38       if ( ! entry.empty() && entry.top().second == scopeLevel ) {
    39         entry.pop();
    40       }
    41     }
    42   }
    43      
    44   scopeLevel--;
    45   assert( scopeLevel >= 0 );
    46 }
     45                scopeLevel--;
     46                assert( scopeLevel >= 0 );
     47        }
    4748
    48 void
    49 IdTable::addDecl( DeclarationWithType *decl )
    50 {
    51   const string &name = decl->get_name();
    52   string manglename;
    53   if ( decl->get_linkage() == LinkageSpec::C ) {
    54     manglename = name;
    55   } else {
    56     manglename = Mangler::mangle( decl );
    57   }
    58   InnerTableType &declTable = table[ name ];
    59   InnerTableType::iterator it = declTable.find( manglename );
    60   if ( it == declTable.end() ) {
    61     declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
    62   } else {
    63     std::stack< DeclEntry >& entry = it->second;
    64     if ( ! entry.empty() && entry.top().second == scopeLevel ) {
    65       if ( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) {
    66         FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl );
    67         FunctionDecl *old = dynamic_cast< FunctionDecl* >( entry.top().first );
    68         if ( newentry && old && newentry->get_statements() && old->get_statements() ) {
    69           throw SemanticError( "duplicate function definition for ", decl );
    70         } else {
    71           ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl );
    72           ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( entry.top().first );
    73           if ( newobj && oldobj && newobj->get_init() && oldobj->get_init() ) {
    74             throw SemanticError( "duplicate definition for ", decl );
    75           }
    76         }
    77       } else {
    78         throw SemanticError( "duplicate definition for ", decl );
    79       }
    80     } else {
    81       declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
    82     }
    83   }
    84   // ensure the set of routines with C linkage cannot be overloaded
    85   for ( InnerTableType::iterator i = declTable.begin(); i != declTable.end(); ++i ) {
    86     if ( ! i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
    87         InnerTableType::iterator j = i;
    88         for ( j++; j != declTable.end(); ++j ) {
    89           if ( ! j->second.empty() && j->second.top().first->get_linkage() == LinkageSpec::C ) {
    90             throw SemanticError( "invalid overload of C function " );
    91           }
     49        void IdTable::addDecl( DeclarationWithType *decl ) {
     50                const string &name = decl->get_name();
     51                string manglename;
     52                if ( decl->get_linkage() == LinkageSpec::C ) {
     53                        manglename = name;
     54                } else {
     55                        manglename = Mangler::mangle( decl );
     56                } // if
     57
     58                InnerTableType &declTable = table[ name ];
     59                InnerTableType::iterator it = declTable.find( manglename );
     60
     61                if ( it == declTable.end() ) {
     62                        declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
     63                } else {
     64                        std::stack< DeclEntry >& entry = it->second;
     65                        if ( ! entry.empty() && entry.top().second == scopeLevel ) {
     66                                if ( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) {
     67                                        FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl );
     68                                        FunctionDecl *old = dynamic_cast< FunctionDecl* >( entry.top().first );
     69                                        if ( newentry && old && newentry->get_statements() && old->get_statements() ) {
     70                                                throw SemanticError( "duplicate function definition for ", decl );
     71                                        } else {
     72                                                ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl );
     73                                                ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( entry.top().first );
     74                                                if ( newobj && oldobj && newobj->get_init() && oldobj->get_init() ) {
     75                                                        throw SemanticError( "duplicate definition for ", decl );
     76                                                } // if
     77                                        } // if
     78                                } else {
     79                                        throw SemanticError( "duplicate definition for ", decl );
     80                                } // if
     81                        } else {
     82                                declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
     83                        } // if
     84                } // if
     85                // ensure the set of routines with C linkage cannot be overloaded
     86                for ( InnerTableType::iterator i = declTable.begin(); i != declTable.end(); ++i ) {
     87                        if ( ! i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
     88                                InnerTableType::iterator j = i;
     89                                for ( j++; j != declTable.end(); ++j ) {
     90                                        if ( ! j->second.empty() && j->second.top().first->get_linkage() == LinkageSpec::C ) {
     91                                                throw SemanticError( "invalid overload of C function " );
     92                                        } // if
     93                                } // for
     94                        } // if
     95                } // for
    9296        }
    93     }
    94   }
    95 }
    9697
    97 void
    98 IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const
    99 {
    100   OuterTableType::const_iterator outer = table.find( id );
    101   if ( outer == table.end() ) return;
    102   const InnerTableType &declTable = outer->second;
    103   for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
    104     const std::stack< DeclEntry >& entry = it->second;
    105     if ( ! entry.empty() ) {
    106       decls.push_back( entry.top().first );
    107     }
    108   }
    109 }
     98        void IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const {
     99                OuterTableType::const_iterator outer = table.find( id );
     100                if ( outer == table.end() ) return;
     101                const InnerTableType &declTable = outer->second;
     102                for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
     103                        const std::stack< DeclEntry >& entry = it->second;
     104                        if ( ! entry.empty() ) {
     105                                decls.push_back( entry.top().first );
     106                        } // if
     107                } // for
     108        }
    110109
    111 DeclarationWithType* IdTable::lookupId( const std::string &id) const {
    112    DeclarationWithType* result = 0;
    113    int depth = -1;
     110        DeclarationWithType * IdTable::lookupId( const std::string &id) const {
     111                DeclarationWithType* result = 0;
     112                int depth = -1;
    114113
    115    OuterTableType::const_iterator outer = table.find( id );
    116    if ( outer == table.end() ) return 0;
    117    const InnerTableType &declTable = outer->second;
    118    for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
    119      const std::stack< DeclEntry >& entry = it->second;
    120      if ( ! entry.empty() && entry.top().second > depth ) {
    121        result = entry.top().first;
    122        depth = entry.top().second;
    123      }
    124    }
    125    return result;
    126 }
     114                OuterTableType::const_iterator outer = table.find( id );
     115                if ( outer == table.end() ) return 0;
     116                const InnerTableType &declTable = outer->second;
     117                for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
     118                        const std::stack< DeclEntry >& entry = it->second;
     119                        if ( ! entry.empty() && entry.top().second > depth ) {
     120                                result = entry.top().first;
     121                                depth = entry.top().second;
     122                        } // if
     123                } // for
     124                return result;
     125        }
    127126
    128 void
    129 IdTable::dump( std::ostream &os ) const
    130 {
    131   for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
    132     for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
     127        void IdTable::dump( std::ostream &os ) const {
     128                for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
     129                        for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
    133130#if 0
    134       const std::stack< DeclEntry >& entry = inner->second;
    135       if ( ! entry.empty() ) { // && entry.top().second == scopeLevel ) {
    136         os << outer->first << " (" << inner->first << ") (" << entry.top().second << ")" << std::endl;
    137       } else {
    138         os << outer->first << " (" << inner->first << ") ( entry-empty)" << std::endl;
    139       }
     131                                const std::stack< DeclEntry >& entry = inner->second;
     132                                if ( ! entry.empty() ) { // && entry.top().second == scopeLevel ) {
     133                                        os << outer->first << " (" << inner->first << ") (" << entry.top().second << ")" << std::endl;
     134                                } else {
     135                                        os << outer->first << " (" << inner->first << ") ( entry-empty)" << std::endl;
     136                                } // if
    140137#endif
    141138#if 0
    142       std::stack<DeclEntry> stack = inner->second;
    143       os << "dumping a stack" << std::endl;
    144       while (! stack.empty()) {
    145         DeclEntry d = stack.top();
    146         os << outer->first << " (" << inner->first << ") (" << d.second << ") " << std::endl;
    147         stack.pop();
    148       }
     139                                std::stack<DeclEntry> stack = inner->second;
     140                                os << "dumping a stack" << std::endl;
     141                                while (! stack.empty()) {
     142                                        DeclEntry d = stack.top();
     143                                        os << outer->first << " (" << inner->first << ") (" << d.second << ") " << std::endl;
     144                                        stack.pop();
     145                                } // while
    149146#endif
    150     }
    151   }
     147                        } // for
     148                } // for
    152149#if 0
    153   for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
    154     for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
    155       const std::stack< DeclEntry >& entry = inner->second;
    156       if ( ! entry.empty() && entry.top().second == scopeLevel ) {
    157         os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
    158       }
    159     }
    160   }
     150                for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
     151                        for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
     152                                const std::stack< DeclEntry >& entry = inner->second;
     153                                if ( ! entry.empty() && entry.top().second == scopeLevel ) {
     154                                        os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
     155                                } // if
     156                        } // for
     157                } // for
    161158#endif
    162 }
     159        }
     160} // namespace SymTab
    163161
    164 
    165 } // namespace SymTab
     162// Local Variables: //
     163// tab-width: 4 //
     164// mode: c++ //
     165// compile-command: "make install" //
     166// End: //
  • translator/SymTab/IdTable.h

    ra32b204 r0dd3a2f  
    1 #ifndef SYMTAB_IDTABLE_H
    2 #define SYMTAB_IDTABLE_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// IdTable.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:30:02 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:31:45 2015
     13// Update Count     : 3
     14//
     15
     16#ifndef IDTABLE_H
     17#define IDTABLE_H
    318
    419#include <iostream>
     
    1227    class IdTable {
    1328      public:
    14         IdTable();
     29                IdTable();
    1530 
    16         void enterScope();
    17         void leaveScope();
    18         void addDecl( DeclarationWithType *decl );
    19         void lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const;
    20         DeclarationWithType* lookupId( const std::string &id) const;
     31                void enterScope();
     32                void leaveScope();
     33                void addDecl( DeclarationWithType *decl );
     34                void lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const;
     35                DeclarationWithType* lookupId( const std::string &id) const;
    2136 
    22         void dump( std::ostream &os ) const; // debugging
     37                void dump( std::ostream &os ) const;                    // debugging
     38      private:
     39                typedef std::pair< DeclarationWithType*, int > DeclEntry;
     40                typedef std::map< std::string, std::stack< DeclEntry > > InnerTableType;
     41                typedef std::map< std::string, InnerTableType > OuterTableType;
    2342
    24       private:
    25         typedef std::pair< DeclarationWithType*, int > DeclEntry;
    26         typedef std::map< std::string, std::stack< DeclEntry > > InnerTableType;
    27         typedef std::map< std::string, InnerTableType > OuterTableType;
    28 
    29         OuterTableType table;
    30         int scopeLevel;
     43                OuterTableType table;
     44                int scopeLevel;
    3145    };
    3246} // namespace SymTab
    3347
    34 #endif // SYMTAB_IDTABLE_H
     48#endif // IDTABLE_H
     49
     50// Local Variables: //
     51// tab-width: 4 //
     52// mode: c++ //
     53// compile-command: "make install" //
     54// End: //
  • translator/SymTab/ImplementationType.cc

    ra32b204 r0dd3a2f  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: ImplementationType.cc,v 1.4 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ImplementationType.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:32:01 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:34:40 2015
     13// Update Count     : 2
     14//
    715
    816#include "ImplementationType.h"
     
    1523
    1624namespace SymTab {
     25        class ImplementationType : public Visitor {
     26          public:
     27                ImplementationType( const SymTab::Indexer &indexer );
    1728
    18 class ImplementationType : public Visitor
    19 {
    20 public:
    21   ImplementationType( const SymTab::Indexer &indexer );
    22  
    23   Type *get_result() { return result; }
     29                Type *get_result() { return result; }
     30          private:
     31                virtual void visit(VoidType *voidType);
     32                virtual void visit(BasicType *basicType);
     33                virtual void visit(PointerType *pointerType);
     34                virtual void visit(ArrayType *arrayType);
     35                virtual void visit(FunctionType *functionType);
     36                virtual void visit(StructInstType *aggregateUseType);
     37                virtual void visit(UnionInstType *aggregateUseType);
     38                virtual void visit(EnumInstType *aggregateUseType);
     39                virtual void visit(ContextInstType *aggregateUseType);
     40                virtual void visit(TypeInstType *aggregateUseType);
     41                virtual void visit(TupleType *tupleType);
    2442
    25 private:
    26   virtual void visit(VoidType *voidType);
    27   virtual void visit(BasicType *basicType);
    28   virtual void visit(PointerType *pointerType);
    29   virtual void visit(ArrayType *arrayType);
    30   virtual void visit(FunctionType *functionType);
    31   virtual void visit(StructInstType *aggregateUseType);
    32   virtual void visit(UnionInstType *aggregateUseType);
    33   virtual void visit(EnumInstType *aggregateUseType);
    34   virtual void visit(ContextInstType *aggregateUseType);
    35   virtual void visit(TypeInstType *aggregateUseType);
    36   virtual void visit(TupleType *tupleType);
     43                Type *result;                   // synthesized
     44                const SymTab::Indexer &indexer;
     45        };
    3746
    38   Type *result;                 // synthesized
    39   const SymTab::Indexer &indexer;
    40 };
     47        Type * implementationType( Type *type, const SymTab::Indexer& indexer ) {
     48                ImplementationType implementor( indexer );
     49                type->accept( implementor );
     50                if ( implementor.get_result() == 0 ) {
     51                        return type->clone();
     52                } else {
     53                        return implementor.get_result();
     54                } // if
     55        }
    4156
    42 Type*
    43 implementationType( Type *type, const SymTab::Indexer& indexer )
    44 {
    45   ImplementationType implementor( indexer );
    46   type->accept( implementor );
    47   if ( implementor.get_result() == 0 ) {
    48     return type->clone();
    49   } else {
    50     return implementor.get_result();
    51   }
    52 }
     57        ImplementationType::ImplementationType( const SymTab::Indexer &indexer ) : result( 0 ), indexer( indexer ) {
     58        }
    5359
    54 ImplementationType::ImplementationType( const SymTab::Indexer &indexer )
    55   : result( 0 ), indexer( indexer )
    56 {
    57 }
     60        void ImplementationType::visit(VoidType *voidType) {
     61        }
    5862
    59 void
    60 ImplementationType::visit(VoidType *voidType)
    61 {
    62 }
     63        void ImplementationType::visit(BasicType *basicType) {
     64        }
    6365
    64 void
    65 ImplementationType::visit(BasicType *basicType)
    66 {
    67 }
     66        void ImplementationType::visit(PointerType *pointerType) {
     67                PointerType *newType = pointerType->clone();
     68                newType->set_base( implementationType( pointerType->get_base(), indexer ) );
     69                result = newType;
     70        }
    6871
    69 void
    70 ImplementationType::visit(PointerType *pointerType)
    71 {
    72   PointerType *newType = pointerType->clone();
    73   newType->set_base( implementationType( pointerType->get_base(), indexer ) );
    74   result = newType;
    75 }
     72        void ImplementationType::visit(ArrayType *arrayType) {
     73                ArrayType *newType = arrayType->clone();
     74                newType->set_base( implementationType( arrayType->get_base(), indexer ) );
     75                result = newType;
     76        }
    7677
    77 void
    78 ImplementationType::visit(ArrayType *arrayType)
    79 {
    80   ArrayType *newType = arrayType->clone();
    81   newType->set_base( implementationType( arrayType->get_base(), indexer ) );
    82   result = newType;
    83 }
    84 
    85 void
    86 ImplementationType::visit(FunctionType *functionType)
    87 {
     78        void ImplementationType::visit(FunctionType *functionType) {
    8879///   FunctionType *newType = functionType->clone();
    8980///   for ( std::list< DeclarationWithType* >::iterator i = newType->get_parameters().begin(); i != newType->get_parameters().end(); ++i ) {
     
    9384///     i->set_type( implementationType( i->get_type(), indexer ) );
    9485///   }
    95 }
     86        }
    9687
    97 void
    98 ImplementationType::visit(StructInstType *aggregateUseType)
    99 {
    100 }
     88        void ImplementationType::visit(StructInstType *aggregateUseType) {
     89        }
    10190
    102 void
    103 ImplementationType::visit(UnionInstType *aggregateUseType)
    104 {
    105 }
     91        void ImplementationType::visit(UnionInstType *aggregateUseType) {
     92        }
    10693
    107 void
    108 ImplementationType::visit(EnumInstType *aggregateUseType)
    109 {
    110 }
     94        void ImplementationType::visit(EnumInstType *aggregateUseType) {
     95        }
    11196
    112 void
    113 ImplementationType::visit(ContextInstType *aggregateUseType)
    114 {
    115 }
     97        void ImplementationType::visit(ContextInstType *aggregateUseType) {
     98        }
    11699
    117 void
    118 ImplementationType::visit(TypeInstType *inst)
    119 {
    120   NamedTypeDecl *typeDecl = indexer.lookupType( inst->get_name() );
    121   if ( typeDecl && typeDecl->get_base() ) {
    122     Type *base = implementationType( typeDecl->get_base(), indexer );
    123     base->get_qualifiers() += inst->get_qualifiers();
    124     result = base;
    125   }
    126 }
     100        void ImplementationType::visit(TypeInstType *inst) {
     101                NamedTypeDecl *typeDecl = indexer.lookupType( inst->get_name() );
     102                if ( typeDecl && typeDecl->get_base() ) {
     103                        Type *base = implementationType( typeDecl->get_base(), indexer );
     104                        base->get_qualifiers() += inst->get_qualifiers();
     105                        result = base;
     106                } // if
     107        }
    127108
    128 void
    129 ImplementationType::visit(TupleType *tupleType)
    130 {
    131   TupleType *newType = new TupleType( Type::Qualifiers() );
    132   for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
    133     Type *implType = implementationType( *i, indexer );
    134     implType->get_qualifiers() += tupleType->get_qualifiers();
    135     newType->get_types().push_back( implType );
    136   }
    137   result = newType;
    138 }
     109        void ImplementationType::visit(TupleType *tupleType) {
     110                TupleType *newType = new TupleType( Type::Qualifiers() );
     111                for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
     112                        Type *implType = implementationType( *i, indexer );
     113                        implType->get_qualifiers() += tupleType->get_qualifiers();
     114                        newType->get_types().push_back( implType );
     115                } // for
     116                result = newType;
     117        }
     118} // namespace SymTab
    139119
    140 } // namespace SymTab
     120// Local Variables: //
     121// tab-width: 4 //
     122// mode: c++ //
     123// compile-command: "make install" //
     124// End: //
  • translator/SymTab/ImplementationType.h

    ra32b204 r0dd3a2f  
    1 /*
    2  * This file is part of the Cforall project
    3  *
    4  * $Id: ImplementationType.h,v 1.3 2005/08/29 20:14:17 rcbilson Exp $
    5  *
    6  */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// ImplementationType.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:35:41 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:37:15 2015
     13// Update Count     : 2
     14//
    715
    8 #ifndef SYMTAB_IMPLEMENTATIONTYPE_H
    9 #define SYMTAB_IMPLEMENTATIONTYPE_H
     16#ifndef IMPLEMENTATIONTYPE_H
     17#define IMPLEMENTATIONTYPE_H
    1018
    1119#include "SynTree/SynTree.h"
     
    1321
    1422namespace SymTab {
     23        Type *implementationType( Type *, const SymTab::Indexer &indexer );
    1524
    16 Type *implementationType( Type *, const SymTab::Indexer &indexer );
    17 
    18 template< typename InputIterator, typename OutputIterator >
    19 void
    20 implementationTypeList( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer )
    21 {
    22   while ( begin != end ) {
    23     *out++ = implementationType( *begin++, indexer );
    24   }
    25 }
    26 
     25        template< typename InputIterator, typename OutputIterator >
     26        void implementationTypeList( InputIterator begin, InputIterator end, OutputIterator out, const SymTab::Indexer &indexer ) {
     27                while ( begin != end ) {
     28                        *out++ = implementationType( *begin++, indexer );
     29                } // while
     30        }
    2731} // namespace SymTab
    2832
    29 #endif /* #ifndef SYMTAB_IMPLEMENTATIONTYPE_H */
     33#endif // IMPLEMENTATIONTYPE_H
     34
     35// Local Variables: //
     36// tab-width: 4 //
     37// mode: c++ //
     38// compile-command: "make install" //
     39// End: //
  • translator/SymTab/Indexer.cc

    ra32b204 r0dd3a2f  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Indexer.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:37:33 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:38:44 2015
     13// Update Count     : 2
     14//
     15
    116#include "SynTree/Declaration.h"
    217#include "SynTree/Type.h"
     
    1631
    1732    void Indexer::visit( ObjectDecl *objectDecl ) {
    18         maybeAccept( objectDecl->get_type(), *this );
    19         maybeAccept( objectDecl->get_init(), *this );
    20         maybeAccept( objectDecl->get_bitfieldWidth(), *this );
    21         if ( objectDecl->get_name() != "" ) {
    22             debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
    23             idTable.addDecl( objectDecl );
    24         }
     33                maybeAccept( objectDecl->get_type(), *this );
     34                maybeAccept( objectDecl->get_init(), *this );
     35                maybeAccept( objectDecl->get_bitfieldWidth(), *this );
     36                if ( objectDecl->get_name() != "" ) {
     37                        debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
     38                        idTable.addDecl( objectDecl );
     39                } // if
    2540    }
    2641
    2742    void Indexer::visit( FunctionDecl *functionDecl ) {
    28         if ( functionDecl->get_name() == "" ) return;
    29         debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
    30         idTable.addDecl( functionDecl );
    31         enterScope();
    32         maybeAccept( functionDecl->get_functionType(), *this );
    33         acceptAll( functionDecl->get_oldDecls(), *this );
    34         maybeAccept( functionDecl->get_statements(), *this );
    35         leaveScope();
     43                if ( functionDecl->get_name() == "" ) return;
     44                debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
     45                idTable.addDecl( functionDecl );
     46                enterScope();
     47                maybeAccept( functionDecl->get_functionType(), *this );
     48                acceptAll( functionDecl->get_oldDecls(), *this );
     49                maybeAccept( functionDecl->get_statements(), *this );
     50                leaveScope();
    3651    }
    3752
     
    5671
    5772    void Indexer::visit( TypeDecl *typeDecl ) {
    58         // see A NOTE ON THE ORDER OF TRAVERSAL, above
    59         // note that assertions come after the type is added to the symtab, since they aren't part
    60         // of the type proper and may depend on the type itself
    61         enterScope();
    62         acceptAll( typeDecl->get_parameters(), *this );
    63         maybeAccept( typeDecl->get_base(), *this );
    64         leaveScope();
    65         debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
    66         typeTable.add( typeDecl );
    67         acceptAll( typeDecl->get_assertions(), *this );
     73                // see A NOTE ON THE ORDER OF TRAVERSAL, above
     74                // note that assertions come after the type is added to the symtab, since they aren't part
     75                // of the type proper and may depend on the type itself
     76                enterScope();
     77                acceptAll( typeDecl->get_parameters(), *this );
     78                maybeAccept( typeDecl->get_base(), *this );
     79                leaveScope();
     80                debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
     81                typeTable.add( typeDecl );
     82                acceptAll( typeDecl->get_assertions(), *this );
    6883    }
    6984
    7085    void Indexer::visit( TypedefDecl *typeDecl ) {
    71         enterScope();
    72         acceptAll( typeDecl->get_parameters(), *this );
    73         maybeAccept( typeDecl->get_base(), *this );
    74         leaveScope();
    75         debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
    76         typeTable.add( typeDecl );
     86                enterScope();
     87                acceptAll( typeDecl->get_parameters(), *this );
     88                maybeAccept( typeDecl->get_base(), *this );
     89                leaveScope();
     90                debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
     91                typeTable.add( typeDecl );
    7792    }
    7893
    7994    void Indexer::visit( StructDecl *aggregateDecl ) {
    80         // make up a forward declaration and add it before processing the members
    81         StructDecl fwdDecl( aggregateDecl->get_name() );
    82         cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    83         debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
    84         structTable.add( &fwdDecl );
    85  
    86         enterScope();
    87         acceptAll( aggregateDecl->get_parameters(), *this );
    88         acceptAll( aggregateDecl->get_members(), *this );
    89         leaveScope();
    90  
    91         debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
    92         // this addition replaces the forward declaration
    93         structTable.add( aggregateDecl );
     95                // make up a forward declaration and add it before processing the members
     96                StructDecl fwdDecl( aggregateDecl->get_name() );
     97                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
     98                debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
     99                structTable.add( &fwdDecl );
     100 
     101                enterScope();
     102                acceptAll( aggregateDecl->get_parameters(), *this );
     103                acceptAll( aggregateDecl->get_members(), *this );
     104                leaveScope();
     105 
     106                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
     107                // this addition replaces the forward declaration
     108                structTable.add( aggregateDecl );
    94109    }
    95110
    96111    void Indexer::visit( UnionDecl *aggregateDecl ) {
    97         // make up a forward declaration and add it before processing the members
    98         UnionDecl fwdDecl( aggregateDecl->get_name() );
    99         cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    100         debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
    101         unionTable.add( &fwdDecl );
    102  
    103         enterScope();
    104         acceptAll( aggregateDecl->get_parameters(), *this );
    105         acceptAll( aggregateDecl->get_members(), *this );
    106         leaveScope();
    107  
    108         debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
    109         unionTable.add( aggregateDecl );
     112                // make up a forward declaration and add it before processing the members
     113                UnionDecl fwdDecl( aggregateDecl->get_name() );
     114                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
     115                debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
     116                unionTable.add( &fwdDecl );
     117 
     118                enterScope();
     119                acceptAll( aggregateDecl->get_parameters(), *this );
     120                acceptAll( aggregateDecl->get_members(), *this );
     121                leaveScope();
     122 
     123                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
     124                unionTable.add( aggregateDecl );
    110125    }
    111126
    112127    void Indexer::visit( EnumDecl *aggregateDecl ) {
    113         debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
    114         enumTable.add( aggregateDecl );
    115         // unlike structs, contexts, and unions, enums inject their members into the global scope
    116         acceptAll( aggregateDecl->get_members(), *this );
     128                debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
     129                enumTable.add( aggregateDecl );
     130                // unlike structs, contexts, and unions, enums inject their members into the global scope
     131                acceptAll( aggregateDecl->get_members(), *this );
    117132    }
    118133
    119134    void Indexer::visit( ContextDecl *aggregateDecl ) {
    120         enterScope();
    121         acceptAll( aggregateDecl->get_parameters(), *this );
    122         acceptAll( aggregateDecl->get_members(), *this );
    123         leaveScope();
    124  
    125         debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
    126         contextTable.add( aggregateDecl );
     135                enterScope();
     136                acceptAll( aggregateDecl->get_parameters(), *this );
     137                acceptAll( aggregateDecl->get_members(), *this );
     138                leaveScope();
     139 
     140                debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
     141                contextTable.add( aggregateDecl );
    127142    }
    128143
    129144    void Indexer::visit( CompoundStmt *compoundStmt ) {
    130         enterScope();
    131         acceptAll( compoundStmt->get_kids(), *this );
    132         leaveScope();
     145                enterScope();
     146                acceptAll( compoundStmt->get_kids(), *this );
     147                leaveScope();
    133148    }
    134149
    135150    void Indexer::visit( ContextInstType *contextInst ) {
    136         acceptAll( contextInst->get_parameters(), *this );
    137         acceptAll( contextInst->get_members(), *this );
     151                acceptAll( contextInst->get_parameters(), *this );
     152                acceptAll( contextInst->get_members(), *this );
    138153    }
    139154
    140155    void Indexer::visit( StructInstType *structInst ) {
    141         if ( ! structTable.lookup( structInst->get_name() ) ) {
    142             debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
    143             structTable.add( structInst->get_name() );
    144         }
    145         enterScope();
    146         acceptAll( structInst->get_parameters(), *this );
    147         leaveScope();
     156                if ( ! structTable.lookup( structInst->get_name() ) ) {
     157                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
     158                        structTable.add( structInst->get_name() );
     159                }
     160                enterScope();
     161                acceptAll( structInst->get_parameters(), *this );
     162                leaveScope();
    148163    }
    149164
    150165    void Indexer::visit( UnionInstType *unionInst ) {
    151         if ( ! unionTable.lookup( unionInst->get_name() ) ) {
    152             debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
    153             unionTable.add( unionInst->get_name() );
    154         }
    155         enterScope();
    156         acceptAll( unionInst->get_parameters(), *this );
    157         leaveScope();
     166                if ( ! unionTable.lookup( unionInst->get_name() ) ) {
     167                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
     168                        unionTable.add( unionInst->get_name() );
     169                }
     170                enterScope();
     171                acceptAll( unionInst->get_parameters(), *this );
     172                leaveScope();
    158173    }
    159174
     
    167182
    168183    void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
    169         idTable.lookupId( id, list );
     184                idTable.lookupId( id, list );
    170185    }
    171186
    172187    DeclarationWithType* Indexer::lookupId( const std::string &id) const {
    173         return idTable.lookupId(id);
     188                return idTable.lookupId(id);
    174189    }
    175190
    176191    NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
    177         return typeTable.lookup( id );
     192                return typeTable.lookup( id );
    178193    }
    179194
    180195    StructDecl *Indexer::lookupStruct( const std::string &id ) const {
    181         return structTable.lookup( id );
     196                return structTable.lookup( id );
    182197    }
    183198
    184199    EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
    185         return enumTable.lookup( id );
     200                return enumTable.lookup( id );
    186201    }
    187202
    188203    UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
    189         return unionTable.lookup( id );
     204                return unionTable.lookup( id );
    190205    }
    191206
    192207    ContextDecl  * Indexer::lookupContext( const std::string &id ) const {
    193         return contextTable.lookup( id );
     208                return contextTable.lookup( id );
    194209    }
    195210
    196211    void Indexer::enterScope() {
    197         if ( doDebug ) {
    198             std::cout << "--- Entering scope" << std::endl;
    199         }
    200         idTable.enterScope();
    201         typeTable.enterScope();
    202         structTable.enterScope();
    203         enumTable.enterScope();
    204         unionTable.enterScope();
    205         contextTable.enterScope();
     212                if ( doDebug ) {
     213                        std::cout << "--- Entering scope" << std::endl;
     214                }
     215                idTable.enterScope();
     216                typeTable.enterScope();
     217                structTable.enterScope();
     218                enumTable.enterScope();
     219                unionTable.enterScope();
     220                contextTable.enterScope();
    206221    }
    207222
    208223    void Indexer::leaveScope() {
    209         using std::cout;
    210         using std::endl;
    211  
    212         if ( doDebug ) {
    213             cout << "--- Leaving scope containing" << endl;
    214             idTable.dump( cout );
    215             typeTable.dump( cout );
    216             structTable.dump( cout );
    217             enumTable.dump( cout );
    218             unionTable.dump( cout );
    219             contextTable.dump( cout );
    220         }
    221         idTable.leaveScope();
    222         typeTable.leaveScope();
    223         structTable.leaveScope();
    224         enumTable.leaveScope();
    225         unionTable.leaveScope();
    226         contextTable.leaveScope();
     224                using std::cout;
     225                using std::endl;
     226 
     227                if ( doDebug ) {
     228                        cout << "--- Leaving scope containing" << endl;
     229                        idTable.dump( cout );
     230                        typeTable.dump( cout );
     231                        structTable.dump( cout );
     232                        enumTable.dump( cout );
     233                        unionTable.dump( cout );
     234                        contextTable.dump( cout );
     235                }
     236                idTable.leaveScope();
     237                typeTable.leaveScope();
     238                structTable.leaveScope();
     239                enumTable.leaveScope();
     240                unionTable.leaveScope();
     241                contextTable.leaveScope();
    227242    }
    228243
     
    244259        contextTable.dump( os );
    245260#if 0
    246         idTable.dump( os );
    247         typeTable.dump( os );
    248         structTable.dump( os );
    249         enumTable.dump( os );
    250         unionTable.dump( os );
    251         contextTable.dump( os );
     261                idTable.dump( os );
     262                typeTable.dump( os );
     263                structTable.dump( os );
     264                enumTable.dump( os );
     265                unionTable.dump( os );
     266                contextTable.dump( os );
    252267#endif
    253268    }
    254269} // namespace SymTab
     270
     271// Local Variables: //
     272// tab-width: 4 //
     273// mode: c++ //
     274// compile-command: "make install" //
     275// End: //
  • translator/SymTab/Indexer.h

    ra32b204 r0dd3a2f  
    1 #ifndef SYMTAB_INDEXER_H
    2 #define SYMTAB_INDEXER_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Indexer.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:38:55 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:40:17 2015
     13// Update Count     : 2
     14//
     15
     16#ifndef INDEXER_H
     17#define INDEXER_H
    318
    419#include <list>
     
    6176} // namespace SymTab
    6277
    63 #endif // SYMTAB_INDEXER_H
     78#endif // INDEXER_H
     79
     80// Local Variables: //
     81// tab-width: 4 //
     82// mode: c++ //
     83// compile-command: "make install" //
     84// End: //
  • translator/SymTab/Mangler.cc

    ra32b204 r0dd3a2f  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Mangler.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:40:29 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:43:49 2015
     13// Update Count     : 2
     14//
     15
    116#include <cassert>
    217#include <string>
     
    1530
    1631namespace SymTab {
    17     Mangler::Mangler() : nextVarNum( 0 ), isTopLevel( true )
    18     {}
     32    Mangler::Mangler() : nextVarNum( 0 ), isTopLevel( true ) {
     33        }
    1934
    2035//Mangler::Mangler( const Mangler & )
     
    2338//}
    2439    Mangler::Mangler( const Mangler &rhs ) : mangleName() {
    25         varNums = rhs.varNums;
    26         nextVarNum = rhs.nextVarNum;
    27         isTopLevel = rhs.isTopLevel;
     40                varNums = rhs.varNums;
     41                nextVarNum = rhs.nextVarNum;
     42                isTopLevel = rhs.isTopLevel;
    2843    }
    2944
    3045    void Mangler::mangleDecl( DeclarationWithType *declaration ) {
    31         bool wasTopLevel = isTopLevel;
    32         if ( isTopLevel ) {
    33             varNums.clear();
    34             nextVarNum = 0;
    35             isTopLevel = false;
    36         }
    37         mangleName << "__";
    38         CodeGen::OperatorInfo opInfo;
    39         if ( operatorLookup( declaration->get_name(), opInfo ) ) {
    40             mangleName << opInfo.outputName;
    41         } else {
    42             mangleName << declaration->get_name();
    43         }
    44         mangleName << "__";
    45         maybeAccept( declaration->get_type(), *this );
    46         isTopLevel = wasTopLevel;
     46                bool wasTopLevel = isTopLevel;
     47                if ( isTopLevel ) {
     48                        varNums.clear();
     49                        nextVarNum = 0;
     50                        isTopLevel = false;
     51                } // if
     52                mangleName << "__";
     53                CodeGen::OperatorInfo opInfo;
     54                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
     55                        mangleName << opInfo.outputName;
     56                } else {
     57                        mangleName << declaration->get_name();
     58                } // if
     59                mangleName << "__";
     60                maybeAccept( declaration->get_type(), *this );
     61                isTopLevel = wasTopLevel;
    4762    }
    4863
    4964    void Mangler::visit( ObjectDecl *declaration ) {
    50         mangleDecl( declaration );
     65                mangleDecl( declaration );
    5166    }
    5267
    5368    void Mangler::visit( FunctionDecl *declaration ) {
    54         mangleDecl( declaration );
     69                mangleDecl( declaration );
    5570    }
    5671
    5772    void Mangler::visit( VoidType *voidType ) {
    58         printQualifiers( voidType );
    59         mangleName << "v";
     73                printQualifiers( voidType );
     74                mangleName << "v";
    6075    }
    6176
    6277    void Mangler::visit( BasicType *basicType ) {
    63         static const char *btLetter[] = {
    64             "b",        // Bool
    65             "c",        // Char
    66             "Sc",       // SignedChar
    67             "Uc",       // UnsignedChar
    68             "s",        // ShortSignedInt
    69             "Us",       // ShortUnsignedInt
    70             "i",        // SignedInt
    71             "Ui",       // UnsignedInt
    72             "l",        // LongSignedInt
    73             "Ul",       // LongUnsignedInt
    74             "q",        // LongLongSignedInt
    75             "Uq",       // LongLongUnsignedInt
    76             "f",        // Float
    77             "d",        // Double
    78             "r",        // LongDouble
    79             "Xf",       // FloatComplex
    80             "Xd",       // DoubleComplex
    81             "Xr",       // LongDoubleComplex
    82             "If",       // FloatImaginary
    83             "Id",       // DoubleImaginary
    84             "Ir",       // LongDoubleImaginary
    85         };
     78                static const char *btLetter[] = {
     79                        "b",    // Bool
     80                        "c",    // Char
     81                        "Sc",   // SignedChar
     82                        "Uc",   // UnsignedChar
     83                        "s",    // ShortSignedInt
     84                        "Us",   // ShortUnsignedInt
     85                        "i",    // SignedInt
     86                        "Ui",   // UnsignedInt
     87                        "l",    // LongSignedInt
     88                        "Ul",   // LongUnsignedInt
     89                        "q",    // LongLongSignedInt
     90                        "Uq",   // LongLongUnsignedInt
     91                        "f",    // Float
     92                        "d",    // Double
     93                        "r",    // LongDouble
     94                        "Xf",   // FloatComplex
     95                        "Xd",   // DoubleComplex
     96                        "Xr",   // LongDoubleComplex
     97                        "If",   // FloatImaginary
     98                        "Id",   // DoubleImaginary
     99                        "Ir",   // LongDoubleImaginary
     100                };
    86101 
    87         printQualifiers( basicType );
    88         mangleName << btLetter[ basicType->get_kind() ];
     102                printQualifiers( basicType );
     103                mangleName << btLetter[ basicType->get_kind() ];
    89104    }
    90105
    91106    void Mangler::visit( PointerType *pointerType ) {
    92         printQualifiers( pointerType );
    93         mangleName << "P";
    94         maybeAccept( pointerType->get_base(), *this );
     107                printQualifiers( pointerType );
     108                mangleName << "P";
     109                maybeAccept( pointerType->get_base(), *this );
    95110    }
    96111
    97112    void Mangler::visit( ArrayType *arrayType ) {
    98         // TODO: encode dimension
    99         printQualifiers( arrayType );
    100         mangleName << "A0";
    101         maybeAccept( arrayType->get_base(), *this );
     113                // TODO: encode dimension
     114                printQualifiers( arrayType );
     115                mangleName << "A0";
     116                maybeAccept( arrayType->get_base(), *this );
    102117    }
    103118
    104119    namespace {
    105         inline std::list< Type* >
    106         getTypes( const std::list< DeclarationWithType* > decls )
    107         {
    108             std::list< Type* > ret;
    109             std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
    110                             std::mem_fun( &DeclarationWithType::get_type ) );
    111             return ret;
    112         }
     120                inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
     121                        std::list< Type* > ret;
     122                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
     123                                                        std::mem_fun( &DeclarationWithType::get_type ) );
     124                        return ret;
     125                }
    113126    }
    114127
    115128    void Mangler::visit( FunctionType *functionType ) {
    116         printQualifiers( functionType );
    117         mangleName << "F";
    118         std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
    119         acceptAll( returnTypes, *this );
    120         mangleName << "_";
    121         std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
    122         acceptAll( paramTypes, *this );
    123         mangleName << "_";
     129                printQualifiers( functionType );
     130                mangleName << "F";
     131                std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
     132                acceptAll( returnTypes, *this );
     133                mangleName << "_";
     134                std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
     135                acceptAll( paramTypes, *this );
     136                mangleName << "_";
    124137    }
    125138
    126139    void Mangler::mangleRef( ReferenceToType *refType, std::string prefix ) {
    127         printQualifiers( refType );
    128         mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
     140                printQualifiers( refType );
     141                mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
    129142    }
    130143
    131144    void Mangler::visit( StructInstType *aggregateUseType ) {
    132         mangleRef( aggregateUseType, "s" );
     145                mangleRef( aggregateUseType, "s" );
    133146    }
    134147
    135148    void Mangler::visit( UnionInstType *aggregateUseType ) {
    136         mangleRef( aggregateUseType, "u" );
     149                mangleRef( aggregateUseType, "u" );
    137150    }
    138151
    139152    void Mangler::visit( EnumInstType *aggregateUseType ) {
    140         mangleRef( aggregateUseType, "e" );
     153                mangleRef( aggregateUseType, "e" );
    141154    }
    142155
    143156    void Mangler::visit( TypeInstType *typeInst ) {
    144         VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    145         if ( varNum == varNums.end() ) {
    146             mangleRef( typeInst, "t" );
    147         } else {
    148             printQualifiers( typeInst );
    149             std::ostrstream numStream;
    150             numStream << varNum->second.first;
    151             mangleName << (numStream.pcount() + 1);
    152             switch ( (TypeDecl::Kind )varNum->second.second ) {
    153               case TypeDecl::Any:
    154                 mangleName << "t";
    155                 break;
    156               case TypeDecl::Dtype:
    157                 mangleName << "d";
    158                 break;
    159               case TypeDecl::Ftype:
    160                 mangleName << "f";
    161                 break;
    162             }
    163             mangleName << std::string( numStream.str(), numStream.pcount() );
    164         }
     157                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
     158                if ( varNum == varNums.end() ) {
     159                        mangleRef( typeInst, "t" );
     160                } else {
     161                        printQualifiers( typeInst );
     162                        std::ostrstream numStream;
     163                        numStream << varNum->second.first;
     164                        mangleName << (numStream.pcount() + 1);
     165                        switch ( (TypeDecl::Kind )varNum->second.second ) {
     166                          case TypeDecl::Any:
     167                                mangleName << "t";
     168                                break;
     169                          case TypeDecl::Dtype:
     170                                mangleName << "d";
     171                                break;
     172                          case TypeDecl::Ftype:
     173                                mangleName << "f";
     174                                break;
     175                        } // switch
     176                        mangleName << std::string( numStream.str(), numStream.pcount() );
     177                } // if
    165178    }
    166179
    167180    void Mangler::visit( TupleType *tupleType ) {
    168         printQualifiers( tupleType );
    169         mangleName << "T";
    170         acceptAll( tupleType->get_types(), *this );
    171         mangleName << "_";
     181                printQualifiers( tupleType );
     182                mangleName << "T";
     183                acceptAll( tupleType->get_types(), *this );
     184                mangleName << "_";
    172185    }
    173186
    174187    void Mangler::visit( TypeDecl *decl ) {
    175         static const char *typePrefix[] = { "BT", "BD", "BF" };
    176         mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
     188                static const char *typePrefix[] = { "BT", "BD", "BF" };
     189                mangleName << typePrefix[ decl->get_kind() ] << ( decl->get_name().length() + 1 ) << decl->get_name();
    177190    }
    178191
    179192    void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
    180         for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
    181             os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
    182         }
     193                for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     194                        os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
     195                } // for
    183196    }
    184197
    185198    void Mangler::printQualifiers( Type *type ) {
    186         if ( ! type->get_forall().empty() ) {
    187             std::list< std::string > assertionNames;
    188             int tcount = 0, dcount = 0, fcount = 0;
    189             mangleName << "A";
    190             for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
    191                 switch ( (*i)->get_kind() ) {
    192                   case TypeDecl::Any:
    193                     tcount++;
    194                     break;
    195                   case TypeDecl::Dtype:
    196                     dcount++;
    197                     break;
    198                   case TypeDecl::Ftype:
    199                     fcount++;
    200                     break;
    201                 }
    202                 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    203                 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    204                     Mangler sub_mangler;
    205                     sub_mangler.nextVarNum = nextVarNum;
    206                     sub_mangler.isTopLevel = false;
    207                     sub_mangler.varNums = varNums;
    208                     (*assert)->accept( sub_mangler );
    209                     assertionNames.push_back( std::string( sub_mangler.mangleName.str(), sub_mangler.mangleName.pcount() ) );
    210                 }
    211             }
    212             mangleName << tcount << "_" << dcount << "_" << fcount << "_";
    213             std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
    214             mangleName << "_";
    215         }
    216         if ( type->get_isConst() ) {
    217             mangleName << "C";
    218         }
    219         if ( type->get_isVolatile() ) {
    220             mangleName << "V";
    221         }
    222         if ( type->get_isRestrict() ) {
    223             mangleName << "R";
    224         }
    225         if ( type->get_isLvalue() ) {
    226             mangleName << "L";
    227         }
    228         if ( type->get_isAtomic() ) {
    229             mangleName << "A";
    230         }
    231     }
    232 } // SymTab
     199                if ( ! type->get_forall().empty() ) {
     200                        std::list< std::string > assertionNames;
     201                        int tcount = 0, dcount = 0, fcount = 0;
     202                        mangleName << "A";
     203                        for ( std::list< TypeDecl* >::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) {
     204                                switch ( (*i)->get_kind() ) {
     205                                  case TypeDecl::Any:
     206                                        tcount++;
     207                                        break;
     208                                  case TypeDecl::Dtype:
     209                                        dcount++;
     210                                        break;
     211                                  case TypeDecl::Ftype:
     212                                        fcount++;
     213                                        break;
     214                                } // switch
     215                                varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
     216                                for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
     217                                        Mangler sub_mangler;
     218                                        sub_mangler.nextVarNum = nextVarNum;
     219                                        sub_mangler.isTopLevel = false;
     220                                        sub_mangler.varNums = varNums;
     221                                        (*assert)->accept( sub_mangler );
     222                                        assertionNames.push_back( std::string( sub_mangler.mangleName.str(), sub_mangler.mangleName.pcount() ) );
     223                                } // for
     224                        } // for
     225                        mangleName << tcount << "_" << dcount << "_" << fcount << "_";
     226                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
     227                        mangleName << "_";
     228                } // if
     229                if ( type->get_isConst() ) {
     230                        mangleName << "C";
     231                } // if
     232                if ( type->get_isVolatile() ) {
     233                        mangleName << "V";
     234                } // if
     235                if ( type->get_isRestrict() ) {
     236                        mangleName << "R";
     237                } // if
     238                if ( type->get_isLvalue() ) {
     239                        mangleName << "L";
     240                } // if
     241                if ( type->get_isAtomic() ) {
     242                        mangleName << "A";
     243                } // if
     244    }
     245} // namespace SymTab
     246
     247// Local Variables: //
     248// tab-width: 4 //
     249// mode: c++ //
     250// compile-command: "make install" //
     251// End: //
  • translator/SymTab/Mangler.h

    ra32b204 r0dd3a2f  
    1 #ifndef SYMTAB_MANGLER_H
    2 #define SYMTAB_MANGLER_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Mangler.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:44:03 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:45:05 2015
     13// Update Count     : 2
     14//
     15
     16#ifndef MANGLER_H
     17#define MANGLER_H
    318
    419#include <strstream>
     
    924    class Mangler : public Visitor {
    1025      public:
    11         template< typename SynTreeClass >
     26                template< typename SynTreeClass >
    1227            static std::string mangle( SynTreeClass *decl ); // interface to clients
    1328
    1429///   using Visitor::visit;
    15         virtual void visit( ObjectDecl *declaration );
    16         virtual void visit( FunctionDecl *declaration );
    17         virtual void visit( TypeDecl *declaration );
     30                virtual void visit( ObjectDecl *declaration );
     31                virtual void visit( FunctionDecl *declaration );
     32                virtual void visit( TypeDecl *declaration );
    1833
    19         virtual void visit( VoidType *voidType );
    20         virtual void visit( BasicType *basicType );
    21         virtual void visit( PointerType *pointerType );
    22         virtual void visit( ArrayType *arrayType );
    23         virtual void visit( FunctionType *functionType );
    24         virtual void visit( StructInstType *aggregateUseType );
    25         virtual void visit( UnionInstType *aggregateUseType );
    26         virtual void visit( EnumInstType *aggregateUseType );
    27         virtual void visit( TypeInstType *aggregateUseType );
    28         virtual void visit( TupleType *tupleType );
     34                virtual void visit( VoidType *voidType );
     35                virtual void visit( BasicType *basicType );
     36                virtual void visit( PointerType *pointerType );
     37                virtual void visit( ArrayType *arrayType );
     38                virtual void visit( FunctionType *functionType );
     39                virtual void visit( StructInstType *aggregateUseType );
     40                virtual void visit( UnionInstType *aggregateUseType );
     41                virtual void visit( EnumInstType *aggregateUseType );
     42                virtual void visit( TypeInstType *aggregateUseType );
     43                virtual void visit( TupleType *tupleType );
    2944 
    30         std::string get_mangleName() { return std::string( mangleName.str(), mangleName.pcount() ); }
     45                std::string get_mangleName() { return std::string( mangleName.str(), mangleName.pcount() ); }
    3146      private:
    32         std::ostrstream mangleName;
    33         typedef std::map< std::string, std::pair< int, int > > VarMapType;
    34         VarMapType varNums;
    35         int nextVarNum;
    36         bool isTopLevel;
     47                std::ostrstream mangleName;
     48                typedef std::map< std::string, std::pair< int, int > > VarMapType;
     49                VarMapType varNums;
     50                int nextVarNum;
     51                bool isTopLevel;
    3752 
    38         Mangler();
    39         Mangler( const Mangler & );
     53                Mangler();
     54                Mangler( const Mangler & );
    4055 
    41         void mangleDecl( DeclarationWithType *declaration );
    42         void mangleRef( ReferenceToType *refType, std::string prefix );
     56                void mangleDecl( DeclarationWithType *declaration );
     57                void mangleRef( ReferenceToType *refType, std::string prefix );
    4358 
    44         void printQualifiers( Type *type );
     59                void printQualifiers( Type *type );
    4560    }; // Mangler
    4661
    4762    template< typename SynTreeClass >
    4863    std::string Mangler::mangle( SynTreeClass *decl ) {
    49         Mangler mangler;
    50         maybeAccept( decl, mangler );
    51         return mangler.get_mangleName();
     64                Mangler mangler;
     65                maybeAccept( decl, mangler );
     66                return mangler.get_mangleName();
    5267    }
    5368} // SymTab
    5469
    55 #endif // SYMTAB_MANGLER_H
     70#endif // MANGLER_H
     71
     72// Local Variables: //
     73// tab-width: 4 //
     74// mode: c++ //
     75// compile-command: "make install" //
     76// End: //
  • translator/SymTab/StackTable.cc

    ra32b204 r0dd3a2f  
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// StackTable.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:45:15 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:46:59 2015
     13// Update Count     : 2
     14//
     15
    116#include <cassert>
    217
     
    520namespace SymTab {
    621    template< typename Element, typename ConflictFunction >
    7     StackTable< Element, ConflictFunction >::StackTable() : scopeLevel( 0 )
    8     {}
     22    StackTable< Element, ConflictFunction >::StackTable() : scopeLevel( 0 ) {
     23        }
    924
    1025    template< typename Element, typename ConflictFunction >
    1126    void StackTable< Element, ConflictFunction >::enterScope() {
    12         scopeLevel++;
     27                scopeLevel++;
    1328    }
    1429
    1530    template< typename Element, typename ConflictFunction >
    1631    void StackTable< Element, ConflictFunction >::leaveScope() {
    17         for ( typename TableType::iterator it = table.begin(); it != table.end(); ++it ) {
    18             std::stack< Entry >& entry = it->second;
    19             if ( ! entry.empty() && entry.top().second == scopeLevel ) {
    20                 entry.pop();
    21             }
    22         }
    23         scopeLevel--;
    24         assert( scopeLevel >= 0 );
     32                for ( typename TableType::iterator it = table.begin(); it != table.end(); ++it ) {
     33                        std::stack< Entry >& entry = it->second;
     34                        if ( ! entry.empty() && entry.top().second == scopeLevel ) {
     35                                entry.pop();
     36                        } // if
     37                } // for
     38                scopeLevel--;
     39                assert( scopeLevel >= 0 );
    2540    }
    2641
    2742    template< typename Element, typename ConflictFunction >
    2843    void StackTable< Element, ConflictFunction >::add( Element *type ) {
    29         std::stack< Entry >& entry = table[ type->get_name() ];
    30         if ( ! entry.empty() && entry.top().second == scopeLevel ) {
    31             entry.top().first = conflictFunction( entry.top().first, type );
    32         } else {
    33             entry.push( Entry( type, scopeLevel ) );
    34         }
     44                std::stack< Entry >& entry = table[ type->get_name() ];
     45                if ( ! entry.empty() && entry.top().second == scopeLevel ) {
     46                        entry.top().first = conflictFunction( entry.top().first, type );
     47                } else {
     48                        entry.push( Entry( type, scopeLevel ) );
     49                } // if
    3550    }
    3651
    3752    template< typename Element, typename ConflictFunction >
    3853    void StackTable< Element, ConflictFunction >::add( std::string fwdDeclName ) {
    39         add( new Element( fwdDeclName ) );
     54                add( new Element( fwdDeclName ) );
    4055    }
    4156
    4257    template< typename Element, typename ConflictFunction >
    4358    Element *StackTable< Element, ConflictFunction >::lookup( std::string id ) const {
    44         typename TableType::const_iterator it = table.find( id );
    45         if ( it == table.end() ) {
    46             return 0;
    47         } else if ( ! it->second.empty() ) {
    48             return it->second.top().first;
    49         } else {
    50             return 0;
    51         }
     59                typename TableType::const_iterator it = table.find( id );
     60                if ( it == table.end() ) {
     61                        return 0;
     62                } else if ( ! it->second.empty() ) {
     63                        return it->second.top().first;
     64                } else {
     65                        return 0;
     66                } // if
    5267    }
    5368
    5469    template< typename Element, typename ConflictFunction >
    5570    void StackTable< Element, ConflictFunction >::dump( std::ostream &os ) const {
    56         for ( typename TableType::const_iterator it = table.begin(); it != table.end(); ++it ) {
    57             const std::stack< Entry >& entry = it->second;
    58             if ( ! entry.empty() && entry.top().second == scopeLevel ) {
    59                 os << it->first << std::endl;
    60             }
    61         }
     71                for ( typename TableType::const_iterator it = table.begin(); it != table.end(); ++it ) {
     72                        const std::stack< Entry >& entry = it->second;
     73                        if ( ! entry.empty() && entry.top().second == scopeLevel ) {
     74                                os << it->first << std::endl;
     75                        } // if
     76                } // for
    6277    }
    63 } // SymTab
     78} // namespace SymTab
     79
     80// Local Variables: //
     81// tab-width: 4 //
     82// mode: c++ //
     83// compile-command: "make install" //
     84// End: //
  • translator/SymTab/StackTable.h

    ra32b204 r0dd3a2f  
    1 #ifndef SYMTAB_STACKTABLE_H
    2 #define SYMTAB_STACKTABLE_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// StackTable.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:47:10 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:48:15 2015
     13// Update Count     : 3
     14//
     15
     16#ifndef STACKTABLE_H
     17#define STACKTABLE_H
    318
    419#include <map>
     
    1126        class StackTable {
    1227      public:
    13         StackTable();
     28                StackTable();
    1429
    15         void enterScope();
    16         void leaveScope();
    17         void add( Element *type );
    18         void add( std::string fwdDeclName );
    19         Element *lookup( std::string id ) const;
     30                void enterScope();
     31                void leaveScope();
     32                void add( Element *type );
     33                void add( std::string fwdDeclName );
     34                Element *lookup( std::string id ) const;
    2035
    21         void dump( std::ostream &os ) const; // debugging
     36                void dump( std::ostream &os ) const;                    // debugging
    2237      private:
    23         typedef std::pair< Element*, int > Entry;
    24         typedef std::map< std::string, std::stack< Entry > > TableType;
     38                typedef std::pair< Element*, int > Entry;
     39                typedef std::map< std::string, std::stack< Entry > > TableType;
    2540 
    26         ConflictFunction conflictFunction;
    27         TableType table;
    28         int scopeLevel;
     41                ConflictFunction conflictFunction;
     42                TableType table;
     43                int scopeLevel;
    2944    };
    3045} // SymTab
     
    3247#include "StackTable.cc"
    3348
    34 #endif // SYMTAB_STACKTABLE_H
     49#endif // STACKTABLE_H
     50
     51// Local Variables: //
     52// tab-width: 4 //
     53// mode: c++ //
     54// compile-command: "make install" //
     55// End: //
  • translator/SymTab/TypeTable.h

    ra32b204 r0dd3a2f  
    1 #ifndef SYMTAB_TYPETABLE_H
    2 #define SYMTAB_TYPETABLE_H
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// TypeTable.h --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:48:32 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:49:49 2015
     13// Update Count     : 2
     14//
     15
     16#ifndef TYPETABLE_H
     17#define TYPETABLE_H
    318
    419#include <cassert>
     
    1429    class TypeTableConflictFunction : public std::binary_function< NamedTypeDecl *, NamedTypeDecl *, NamedTypeDecl * > {
    1530      public:
    16         NamedTypeDecl *operator()( NamedTypeDecl *existing, NamedTypeDecl *added ) {
    17             if ( existing->get_base() == 0 ) {
    18                 return added;
    19             } else if ( added->get_base() == 0 ) {
    20                 return existing;
    21             } else {
    22                 throw SemanticError( "redeclaration of ", added );
    23             }
    24             assert( false );
    25             return 0;
    26         }
     31                NamedTypeDecl *operator()( NamedTypeDecl *existing, NamedTypeDecl *added ) {
     32                        if ( existing->get_base() == 0 ) {
     33                                return added;
     34                        } else if ( added->get_base() == 0 ) {
     35                                return existing;
     36                        } else {
     37                                throw SemanticError( "redeclaration of ", added );
     38                        } // if
     39                        assert( false );
     40                        return 0;
     41                }
    2742    };
    2843
    2944    typedef StackTable< NamedTypeDecl, TypeTableConflictFunction > TypeTable;
    30 } // SymTab
     45} // namespace SymTab
    3146
    32 #endif // SYMTAB_TYPETABLE_H
     47#endif // TYPETABLE_H
     48
     49// Local Variables: //
     50// tab-width: 4 //
     51// mode: c++ //
     52// compile-command: "make install" //
     53// End: //
  • translator/SymTab/Validate.cc

    ra32b204 r0dd3a2f  
    1 /*
    2   The "validate" phase of translation is used to take a syntax tree and convert it into a standard form that aims to be
    3   as regular in structure as possible.  Some assumptions can be made regarding the state of the tree after this pass is
    4   complete, including:
    5 
    6   - No nested structure or union definitions; any in the input are "hoisted" to the level of the containing struct or
    7     union.
    8 
    9   - All enumeration constants have type EnumInstType.
    10 
    11   - The type "void" never occurs in lists of function parameter or return types; neither do tuple types.  A function
    12     taking no arguments has no argument types, and tuples are flattened.
    13 
    14   - No context instances exist; they are all replaced by the set of declarations signified by the context, instantiated
    15     by the particular set of type arguments.
    16 
    17   - Every declaration is assigned a unique id.
    18 
    19   - No typedef declarations or instances exist; the actual type is substituted for each instance.
    20 
    21   - Each type, struct, and union definition is followed by an appropriate assignment operator.
    22 
    23   - Each use of a struct or union is connected to a complete definition of that struct or union, even if that definition
    24     occurs later in the input.
    25 */
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Validate.cc --
     8//
     9// Author           : Richard C. Bilson
     10// Created On       : Sun May 17 21:50:04 2015
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Sun May 17 21:53:16 2015
     13// Update Count     : 2
     14//
     15
     16// The "validate" phase of translation is used to take a syntax tree and convert it into a standard form that aims to be
     17// as regular in structure as possible.  Some assumptions can be made regarding the state of the tree after this pass is
     18// complete, including:
     19//
     20// - No nested structure or union definitions; any in the input are "hoisted" to the level of the containing struct or
     21//   union.
     22//
     23// - All enumeration constants have type EnumInstType.
     24//
     25// - The type "void" never occurs in lists of function parameter or return types; neither do tuple types.  A function
     26//   taking no arguments has no argument types, and tuples are flattened.
     27//
     28// - No context instances exist; they are all replaced by the set of declarations signified by the context, instantiated
     29//   by the particular set of type arguments.
     30//
     31// - Every declaration is assigned a unique id.
     32//
     33// - No typedef declarations or instances exist; the actual type is substituted for each instance.
     34//
     35// - Each type, struct, and union definition is followed by an appropriate assignment operator.
     36//
     37// - Each use of a struct or union is connected to a complete definition of that struct or union, even if that
     38//   definition occurs later in the input.
    2639
    2740#include <list>
     
    4659    class HoistStruct : public Visitor {
    4760      public:
    48         static void hoistStruct( std::list< Declaration * > &translationUnit );
    49  
    50         std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    51  
    52         virtual void visit( StructDecl *aggregateDecl );
    53         virtual void visit( UnionDecl *aggregateDecl );
    54 
    55         virtual void visit( CompoundStmt *compoundStmt );
    56         virtual void visit( IfStmt *ifStmt );
    57         virtual void visit( WhileStmt *whileStmt );
    58         virtual void visit( ForStmt *forStmt );
    59         virtual void visit( SwitchStmt *switchStmt );
    60         virtual void visit( ChooseStmt *chooseStmt );
    61         virtual void visit( CaseStmt *caseStmt );
    62         virtual void visit( CatchStmt *catchStmt );
     61                static void hoistStruct( std::list< Declaration * > &translationUnit );
     62 
     63                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     64 
     65                virtual void visit( StructDecl *aggregateDecl );
     66                virtual void visit( UnionDecl *aggregateDecl );
     67
     68                virtual void visit( CompoundStmt *compoundStmt );
     69                virtual void visit( IfStmt *ifStmt );
     70                virtual void visit( WhileStmt *whileStmt );
     71                virtual void visit( ForStmt *forStmt );
     72                virtual void visit( SwitchStmt *switchStmt );
     73                virtual void visit( ChooseStmt *chooseStmt );
     74                virtual void visit( CaseStmt *caseStmt );
     75                virtual void visit( CatchStmt *catchStmt );
    6376      private:
    64         HoistStruct();
    65 
    66         template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    67 
    68         std::list< Declaration * > declsToAdd;
    69         bool inStruct;
     77                HoistStruct();
     78
     79                template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
     80
     81                std::list< Declaration * > declsToAdd;
     82                bool inStruct;
    7083    };
    7184
    7285    class Pass1 : public Visitor {
    73         typedef Visitor Parent;
    74         virtual void visit( EnumDecl *aggregateDecl );
    75         virtual void visit( FunctionType *func );
     86                typedef Visitor Parent;
     87                virtual void visit( EnumDecl *aggregateDecl );
     88                virtual void visit( FunctionType *func );
    7689    };
    7790 
    7891    class Pass2 : public Indexer {
    79         typedef Indexer Parent;
     92                typedef Indexer Parent;
    8093      public:
    81         Pass2( bool doDebug, const Indexer *indexer );
     94                Pass2( bool doDebug, const Indexer *indexer );
    8295      private:
    83         virtual void visit( StructInstType *structInst );
    84         virtual void visit( UnionInstType *unionInst );
    85         virtual void visit( ContextInstType *contextInst );
    86         virtual void visit( StructDecl *structDecl );
    87         virtual void visit( UnionDecl *unionDecl );
    88         virtual void visit( TypeInstType *typeInst );
    89 
    90         const Indexer *indexer;
    91  
    92         typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
    93         typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
    94         ForwardStructsType forwardStructs;
    95         ForwardUnionsType forwardUnions;
     96                virtual void visit( StructInstType *structInst );
     97                virtual void visit( UnionInstType *unionInst );
     98                virtual void visit( ContextInstType *contextInst );
     99                virtual void visit( StructDecl *structDecl );
     100                virtual void visit( UnionDecl *unionDecl );
     101                virtual void visit( TypeInstType *typeInst );
     102
     103                const Indexer *indexer;
     104 
     105                typedef std::map< std::string, std::list< StructInstType * > > ForwardStructsType;
     106                typedef std::map< std::string, std::list< UnionInstType * > > ForwardUnionsType;
     107                ForwardStructsType forwardStructs;
     108                ForwardUnionsType forwardUnions;
    96109    };
    97110
    98111    class Pass3 : public Indexer {
    99         typedef Indexer Parent;
     112                typedef Indexer Parent;
    100113      public:
    101         Pass3( const Indexer *indexer );
     114                Pass3( const Indexer *indexer );
    102115      private:
    103         virtual void visit( ObjectDecl *object );
    104         virtual void visit( FunctionDecl *func );
    105 
    106         const Indexer *indexer;
     116                virtual void visit( ObjectDecl *object );
     117                virtual void visit( FunctionDecl *func );
     118
     119                const Indexer *indexer;
    107120    };
    108121
    109122    class AddStructAssignment : public Visitor {
    110123      public:
    111         static void addStructAssignment( std::list< Declaration * > &translationUnit );
    112 
    113         std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    114  
    115         virtual void visit( StructDecl *structDecl );
    116         virtual void visit( UnionDecl *structDecl );
    117         virtual void visit( TypeDecl *typeDecl );
    118         virtual void visit( ContextDecl *ctxDecl );
    119         virtual void visit( FunctionDecl *functionDecl );
    120 
    121         virtual void visit( FunctionType *ftype );
    122         virtual void visit( PointerType *ftype );
    123  
    124         virtual void visit( CompoundStmt *compoundStmt );
    125         virtual void visit( IfStmt *ifStmt );
    126         virtual void visit( WhileStmt *whileStmt );
    127         virtual void visit( ForStmt *forStmt );
    128         virtual void visit( SwitchStmt *switchStmt );
    129         virtual void visit( ChooseStmt *chooseStmt );
    130         virtual void visit( CaseStmt *caseStmt );
    131         virtual void visit( CatchStmt *catchStmt );
    132 
    133         AddStructAssignment() : functionNesting( 0 ) {}
     124                static void addStructAssignment( std::list< Declaration * > &translationUnit );
     125
     126                std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
     127 
     128                virtual void visit( StructDecl *structDecl );
     129                virtual void visit( UnionDecl *structDecl );
     130                virtual void visit( TypeDecl *typeDecl );
     131                virtual void visit( ContextDecl *ctxDecl );
     132                virtual void visit( FunctionDecl *functionDecl );
     133
     134                virtual void visit( FunctionType *ftype );
     135                virtual void visit( PointerType *ftype );
     136 
     137                virtual void visit( CompoundStmt *compoundStmt );
     138                virtual void visit( IfStmt *ifStmt );
     139                virtual void visit( WhileStmt *whileStmt );
     140                virtual void visit( ForStmt *forStmt );
     141                virtual void visit( SwitchStmt *switchStmt );
     142                virtual void visit( ChooseStmt *chooseStmt );
     143                virtual void visit( CaseStmt *caseStmt );
     144                virtual void visit( CatchStmt *catchStmt );
     145
     146                AddStructAssignment() : functionNesting( 0 ) {}
    134147      private:
    135         template< typename StmtClass > void visitStatement( StmtClass *stmt );
    136  
    137         std::list< Declaration * > declsToAdd;
    138         std::set< std::string > structsDone;
    139         unsigned int functionNesting;                   // current level of nested functions
     148                template< typename StmtClass > void visitStatement( StmtClass *stmt );
     149 
     150                std::list< Declaration * > declsToAdd;
     151                std::set< std::string > structsDone;
     152                unsigned int functionNesting;                   // current level of nested functions
    140153    };
    141154
    142155    class EliminateTypedef : public Mutator {
    143156      public:
    144         static void eliminateTypedef( std::list< Declaration * > &translationUnit );
     157                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    145158      private:
    146         virtual Declaration *mutate( TypedefDecl *typeDecl );
    147         virtual TypeDecl *mutate( TypeDecl *typeDecl );
    148         virtual DeclarationWithType *mutate( FunctionDecl *funcDecl );
    149         virtual ObjectDecl *mutate( ObjectDecl *objDecl );
    150         virtual CompoundStmt *mutate( CompoundStmt *compoundStmt );
    151         virtual Type *mutate( TypeInstType *aggregateUseType );
    152         virtual Expression *mutate( CastExpr *castExpr );
    153  
    154         std::map< std::string, TypedefDecl * > typedefNames;
     159                virtual Declaration *mutate( TypedefDecl *typeDecl );
     160                virtual TypeDecl *mutate( TypeDecl *typeDecl );
     161                virtual DeclarationWithType *mutate( FunctionDecl *funcDecl );
     162                virtual ObjectDecl *mutate( ObjectDecl *objDecl );
     163                virtual CompoundStmt *mutate( CompoundStmt *compoundStmt );
     164                virtual Type *mutate( TypeInstType *aggregateUseType );
     165                virtual Expression *mutate( CastExpr *castExpr );
     166 
     167                std::map< std::string, TypedefDecl * > typedefNames;
    155168    };
    156169
    157170    void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    158         Pass1 pass1;
    159         Pass2 pass2( doDebug, 0 );
    160         Pass3 pass3( 0 );
    161         EliminateTypedef::eliminateTypedef( translationUnit );
    162         HoistStruct::hoistStruct( translationUnit );
    163         acceptAll( translationUnit, pass1 );
    164         acceptAll( translationUnit, pass2 );
    165         AddStructAssignment::addStructAssignment( translationUnit );
    166         acceptAll( translationUnit, pass3 );
     171                Pass1 pass1;
     172                Pass2 pass2( doDebug, 0 );
     173                Pass3 pass3( 0 );
     174                EliminateTypedef::eliminateTypedef( translationUnit );
     175                HoistStruct::hoistStruct( translationUnit );
     176                acceptAll( translationUnit, pass1 );
     177                acceptAll( translationUnit, pass2 );
     178                AddStructAssignment::addStructAssignment( translationUnit );
     179                acceptAll( translationUnit, pass3 );
    167180    }
    168181   
    169182    void validateType( Type *type, const Indexer *indexer ) {
    170         Pass1 pass1;
    171         Pass2 pass2( false, indexer );
    172         Pass3 pass3( indexer );
    173         type->accept( pass1 );
    174         type->accept( pass2 );
    175         type->accept( pass3 );
     183                Pass1 pass1;
     184                Pass2 pass2( false, indexer );
     185                Pass3 pass3( indexer );
     186                type->accept( pass1 );
     187                type->accept( pass2 );
     188                type->accept( pass3 );
    176189    }
    177190
    178191    template< typename Visitor >
    179192    void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
    180         std::list< Declaration * >::iterator i = translationUnit.begin();
    181         while ( i != translationUnit.end() ) {
    182             (*i)->accept( visitor );
    183             std::list< Declaration * >::iterator next = i;
    184             next++;
    185             if ( ! visitor.get_declsToAdd().empty() ) {
    186                 translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
    187             } // if
    188             i = next;
    189         } // while
     193                std::list< Declaration * >::iterator i = translationUnit.begin();
     194                while ( i != translationUnit.end() ) {
     195                        (*i)->accept( visitor );
     196                        std::list< Declaration * >::iterator next = i;
     197                        next++;
     198                        if ( ! visitor.get_declsToAdd().empty() ) {
     199                                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     200                        } // if
     201                        i = next;
     202                } // while
    190203    }
    191204
    192205    void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
    193         HoistStruct hoister;
    194         acceptAndAdd( translationUnit, hoister, true );
     206                HoistStruct hoister;
     207                acceptAndAdd( translationUnit, hoister, true );
    195208    }
    196209
     
    199212
    200213    void filter( std::list< Declaration * > &declList, bool (*pred)( Declaration * ), bool doDelete ) {
    201         std::list< Declaration * >::iterator i = declList.begin();
    202         while ( i != declList.end() ) {
    203             std::list< Declaration * >::iterator next = i;
    204             ++next;
    205             if ( pred( *i ) ) {
    206                 if ( doDelete ) {
    207                     delete *i;
    208                 } // if
    209                 declList.erase( i );
    210             } // if
    211             i = next;
    212         } // while
     214                std::list< Declaration * >::iterator i = declList.begin();
     215                while ( i != declList.end() ) {
     216                        std::list< Declaration * >::iterator next = i;
     217                        ++next;
     218                        if ( pred( *i ) ) {
     219                                if ( doDelete ) {
     220                                        delete *i;
     221                                } // if
     222                                declList.erase( i );
     223                        } // if
     224                        i = next;
     225                } // while
    213226    }
    214227
    215228    bool isStructOrUnion( Declaration *decl ) {
    216         return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
     229                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
    217230    }
    218231
    219232    template< typename AggDecl >
    220233    void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
    221         if ( inStruct ) {
    222             // Add elements in stack order corresponding to nesting structure.
    223             declsToAdd.push_front( aggregateDecl );
    224             Visitor::visit( aggregateDecl );
    225         } else {
    226             inStruct = true;
    227             Visitor::visit( aggregateDecl );
    228             inStruct = false;
    229         } // if
    230         // Always remove the hoisted aggregate from the inner structure.
    231         filter( aggregateDecl->get_members(), isStructOrUnion, false );
     234                if ( inStruct ) {
     235                        // Add elements in stack order corresponding to nesting structure.
     236                        declsToAdd.push_front( aggregateDecl );
     237                        Visitor::visit( aggregateDecl );
     238                } else {
     239                        inStruct = true;
     240                        Visitor::visit( aggregateDecl );
     241                        inStruct = false;
     242                } // if
     243                // Always remove the hoisted aggregate from the inner structure.
     244                filter( aggregateDecl->get_members(), isStructOrUnion, false );
    232245    }
    233246
    234247    void HoistStruct::visit( StructDecl *aggregateDecl ) {
    235         handleAggregate( aggregateDecl );
     248                handleAggregate( aggregateDecl );
    236249    }
    237250
    238251    void HoistStruct::visit( UnionDecl *aggregateDecl ) {
    239         handleAggregate( aggregateDecl );
     252                handleAggregate( aggregateDecl );
    240253    }
    241254
    242255    void HoistStruct::visit( CompoundStmt *compoundStmt ) {
    243         addVisit( compoundStmt, *this );
     256                addVisit( compoundStmt, *this );
    244257    }
    245258
    246259    void HoistStruct::visit( IfStmt *ifStmt ) {
    247         addVisit( ifStmt, *this );
     260                addVisit( ifStmt, *this );
    248261    }
    249262
    250263    void HoistStruct::visit( WhileStmt *whileStmt ) {
    251         addVisit( whileStmt, *this );
     264                addVisit( whileStmt, *this );
    252265    }
    253266
    254267    void HoistStruct::visit( ForStmt *forStmt ) {
    255         addVisit( forStmt, *this );
     268                addVisit( forStmt, *this );
    256269    }
    257270
    258271    void HoistStruct::visit( SwitchStmt *switchStmt ) {
    259         addVisit( switchStmt, *this );
     272                addVisit( switchStmt, *this );
    260273    }
    261274
    262275    void HoistStruct::visit( ChooseStmt *switchStmt ) {
    263         addVisit( switchStmt, *this );
     276                addVisit( switchStmt, *this );
    264277    }
    265278
    266279    void HoistStruct::visit( CaseStmt *caseStmt ) {
    267         addVisit( caseStmt, *this );
     280                addVisit( caseStmt, *this );
    268281    }
    269282
    270283    void HoistStruct::visit( CatchStmt *cathStmt ) {
    271         addVisit( cathStmt, *this );
     284                addVisit( cathStmt, *this );
    272285    }
    273286
    274287    void Pass1::visit( EnumDecl *enumDecl ) {
    275         // Set the type of each member of the enumeration to be EnumConstant
    276  
    277         for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
    278             ObjectDecl *obj = dynamic_cast< ObjectDecl * >( *i );
    279             assert( obj );
    280             obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
    281         } // for
    282         Parent::visit( enumDecl );
     288                // Set the type of each member of the enumeration to be EnumConstant
     289 
     290                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     291                        ObjectDecl *obj = dynamic_cast< ObjectDecl * >( *i );
     292                        assert( obj );
     293                        obj->set_type( new EnumInstType( Type::Qualifiers( true, false, false, false, false, false ), enumDecl->get_name() ) );
     294                } // for
     295                Parent::visit( enumDecl );
    283296    }
    284297
    285298    namespace {
    286         template< typename DWTIterator >
    287         void fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) {
    288             // the only case in which "void" is valid is where it is the only one in the list; then
    289             // it should be removed entirely
    290             // other fix ups are handled by the FixFunction class
    291             if ( begin == end ) return;
    292             FixFunction fixer;
    293             DWTIterator i = begin;
    294             *i = (*i )->acceptMutator( fixer );
    295             if ( fixer.get_isVoid() ) {
    296                 DWTIterator j = i;
    297                 ++i;
    298                 func->get_parameters().erase( j );
    299                 if ( i != end ) {
    300                     throw SemanticError( "invalid type void in function type ", func );
    301                 } // if
    302             } else {
    303                 ++i;
    304                 for ( ; i != end; ++i ) {
    305                     FixFunction fixer;
    306                     *i = (*i )->acceptMutator( fixer );
    307                     if ( fixer.get_isVoid() ) {
    308                         throw SemanticError( "invalid type void in function type ", func );
    309                     } // if
     299                template< typename DWTIterator >
     300                void fixFunctionList( DWTIterator begin, DWTIterator end, FunctionType *func ) {
     301                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
     302                        // entirely other fix ups are handled by the FixFunction class
     303                        if ( begin == end ) return;
     304                        FixFunction fixer;
     305                        DWTIterator i = begin;
     306                        *i = (*i )->acceptMutator( fixer );
     307                        if ( fixer.get_isVoid() ) {
     308                                DWTIterator j = i;
     309                                ++i;
     310                                func->get_parameters().erase( j );
     311                                if ( i != end ) {
     312                                        throw SemanticError( "invalid type void in function type ", func );
     313                                } // if
     314                        } else {
     315                                ++i;
     316                                for ( ; i != end; ++i ) {
     317                                        FixFunction fixer;
     318                                        *i = (*i )->acceptMutator( fixer );
     319                                        if ( fixer.get_isVoid() ) {
     320                                                throw SemanticError( "invalid type void in function type ", func );
     321                                        } // if
     322                                } // for
     323                        } // if
     324                }
     325    }
     326
     327    void Pass1::visit( FunctionType *func ) {
     328                // Fix up parameters and return types
     329                fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
     330                fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
     331                Visitor::visit( func );
     332    }
     333
     334    Pass2::Pass2( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {
     335                if ( other_indexer ) {
     336                        indexer = other_indexer;
     337                } else {
     338                        indexer = this;
     339                } // if
     340    }
     341
     342    void Pass2::visit( StructInstType *structInst ) {
     343                Parent::visit( structInst );
     344                StructDecl *st = indexer->lookupStruct( structInst->get_name() );
     345                // it's not a semantic error if the struct is not found, just an implicit forward declaration
     346                if ( st ) {
     347                        assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
     348                        structInst->set_baseStruct( st );
     349                } // if
     350                if ( ! st || st->get_members().empty() ) {
     351                        // use of forward declaration
     352                        forwardStructs[ structInst->get_name() ].push_back( structInst );
     353                } // if
     354    }
     355
     356    void Pass2::visit( UnionInstType *unionInst ) {
     357                Parent::visit( unionInst );
     358                UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
     359                // it's not a semantic error if the union is not found, just an implicit forward declaration
     360                if ( un ) {
     361                        unionInst->set_baseUnion( un );
     362                } // if
     363                if ( ! un || un->get_members().empty() ) {
     364                        // use of forward declaration
     365                        forwardUnions[ unionInst->get_name() ].push_back( unionInst );
     366                } // if
     367    }
     368
     369    void Pass2::visit( ContextInstType *contextInst ) {
     370                Parent::visit( contextInst );
     371                ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
     372                if ( ! ctx ) {
     373                        throw SemanticError( "use of undeclared context " + contextInst->get_name() );
     374                } // if
     375                for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
     376                        for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
     377                                if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {
     378                                        cloneAll( otherCtx->get_members(), contextInst->get_members() );
     379                                } else {
     380                                        contextInst->get_members().push_back( (*assert )->clone() );
     381                                } // if
     382                        } // for
    310383                } // for
    311             } // if
    312         }
    313     }
    314 
    315     void Pass1::visit( FunctionType *func ) {
    316         // Fix up parameters and return types
    317         fixFunctionList( func->get_parameters().begin(), func->get_parameters().end(), func );
    318         fixFunctionList( func->get_returnVals().begin(), func->get_returnVals().end(), func );
    319         Visitor::visit( func );
    320     }
    321 
    322     Pass2::Pass2( bool doDebug, const Indexer *other_indexer ) : Indexer( doDebug ) {
    323         if ( other_indexer ) {
    324             indexer = other_indexer;
    325         } else {
    326             indexer = this;
    327         } // if
    328     }
    329 
    330     void Pass2::visit( StructInstType *structInst ) {
    331         Parent::visit( structInst );
    332         StructDecl *st = indexer->lookupStruct( structInst->get_name() );
    333         // it's not a semantic error if the struct is not found, just an implicit forward declaration
    334         if ( st ) {
    335             assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
    336             structInst->set_baseStruct( st );
    337         } // if
    338         if ( ! st || st->get_members().empty() ) {
    339             // use of forward declaration
    340             forwardStructs[ structInst->get_name() ].push_back( structInst );
    341         } // if
    342     }
    343 
    344     void Pass2::visit( UnionInstType *unionInst ) {
    345         Parent::visit( unionInst );
    346         UnionDecl *un = indexer->lookupUnion( unionInst->get_name() );
    347         // it's not a semantic error if the union is not found, just an implicit forward declaration
    348         if ( un ) {
    349             unionInst->set_baseUnion( un );
    350         } // if
    351         if ( ! un || un->get_members().empty() ) {
    352             // use of forward declaration
    353             forwardUnions[ unionInst->get_name() ].push_back( unionInst );
    354         } // if
    355     }
    356 
    357     void Pass2::visit( ContextInstType *contextInst ) {
    358         Parent::visit( contextInst );
    359         ContextDecl *ctx = indexer->lookupContext( contextInst->get_name() );
    360         if ( ! ctx ) {
    361             throw SemanticError( "use of undeclared context " + contextInst->get_name() );
    362         } // if
    363         for ( std::list< TypeDecl * >::const_iterator i = ctx->get_parameters().begin(); i != ctx->get_parameters().end(); ++i ) {
    364             for ( std::list< DeclarationWithType * >::const_iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    365                 if ( ContextInstType *otherCtx = dynamic_cast< ContextInstType * >(*assert ) ) {
    366                     cloneAll( otherCtx->get_members(), contextInst->get_members() );
     384                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() ) );
     385    }
     386
     387    void Pass2::visit( StructDecl *structDecl ) {
     388                if ( ! structDecl->get_members().empty() ) {
     389                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     390                        if ( fwds != forwardStructs.end() ) {
     391                                for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
     392                                        (*inst )->set_baseStruct( structDecl );
     393                                } // for
     394                                forwardStructs.erase( fwds );
     395                        } // if
     396                } // if
     397                Indexer::visit( structDecl );
     398    }
     399
     400    void Pass2::visit( UnionDecl *unionDecl ) {
     401                if ( ! unionDecl->get_members().empty() ) {
     402                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     403                        if ( fwds != forwardUnions.end() ) {
     404                                for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
     405                                        (*inst )->set_baseUnion( unionDecl );
     406                                } // for
     407                                forwardUnions.erase( fwds );
     408                        } // if
     409                } // if
     410                Indexer::visit( unionDecl );
     411    }
     412
     413    void Pass2::visit( TypeInstType *typeInst ) {
     414                if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
     415                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
     416                                typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
     417                        } // if
     418                } // if
     419    }
     420
     421    Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
     422                if ( other_indexer ) {
     423                        indexer = other_indexer;
    367424                } else {
    368                     contextInst->get_members().push_back( (*assert )->clone() );
    369                 } // if
    370             } // for
    371         } // for
    372         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() ) );
    373     }
    374 
    375     void Pass2::visit( StructDecl *structDecl ) {
    376         if ( ! structDecl->get_members().empty() ) {
    377             ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
    378             if ( fwds != forwardStructs.end() ) {
    379                 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    380                     (*inst )->set_baseStruct( structDecl );
     425                        indexer = this;
     426                } // if
     427    }
     428
     429    void forallFixer( Type *func ) {
     430                // Fix up assertions
     431                for ( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
     432                        std::list< DeclarationWithType * > toBeDone, nextRound;
     433                        toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
     434                        while ( ! toBeDone.empty() ) {
     435                                for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
     436                                        if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {
     437                                                for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
     438                                                        DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
     439                                                        assert( dwt );
     440                                                        nextRound.push_back( dwt->clone() );
     441                                                }
     442                                                delete ctx;
     443                                        } else {
     444                                                FixFunction fixer;
     445                                                *assertion = (*assertion )->acceptMutator( fixer );
     446                                                if ( fixer.get_isVoid() ) {
     447                                                        throw SemanticError( "invalid type void in assertion of function ", func );
     448                                                }
     449                                                (*type )->get_assertions().push_back( *assertion );
     450                                        } // if
     451                                } // for
     452                                toBeDone.clear();
     453                                toBeDone.splice( toBeDone.end(), nextRound );
     454                        } // while
    381455                } // for
    382                 forwardStructs.erase( fwds );
    383             } // if
    384         } // if
    385         Indexer::visit( structDecl );
    386     }
    387 
    388     void Pass2::visit( UnionDecl *unionDecl ) {
    389         if ( ! unionDecl->get_members().empty() ) {
    390             ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
    391             if ( fwds != forwardUnions.end() ) {
    392                 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    393                     (*inst )->set_baseUnion( unionDecl );
    394                 } // for
    395                 forwardUnions.erase( fwds );
    396             } // if
    397         } // if
    398         Indexer::visit( unionDecl );
    399     }
    400 
    401     void Pass2::visit( TypeInstType *typeInst ) {
    402         if ( NamedTypeDecl *namedTypeDecl = lookupType( typeInst->get_name() ) ) {
    403             if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
    404                 typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
    405             } // if
    406         } // if
    407     }
    408 
    409     Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
    410         if ( other_indexer ) {
    411             indexer = other_indexer;
    412         } else {
    413             indexer = this;
    414         } // if
    415     }
    416 
    417     void forallFixer( Type *func ) {
    418         // Fix up assertions
    419         for ( std::list< TypeDecl * >::iterator type = func->get_forall().begin(); type != func->get_forall().end(); ++type ) {
    420             std::list< DeclarationWithType * > toBeDone, nextRound;
    421             toBeDone.splice( toBeDone.end(), (*type )->get_assertions() );
    422             while ( ! toBeDone.empty() ) {
    423                 for ( std::list< DeclarationWithType * >::iterator assertion = toBeDone.begin(); assertion != toBeDone.end(); ++assertion ) {
    424                     if ( ContextInstType *ctx = dynamic_cast< ContextInstType * >( (*assertion )->get_type() ) ) {
    425                         for ( std::list< Declaration * >::const_iterator i = ctx->get_members().begin(); i != ctx->get_members().end(); ++i ) {
    426                             DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *i );
    427                             assert( dwt );
    428                             nextRound.push_back( dwt->clone() );
    429                         }
    430                         delete ctx;
    431                     } else {
    432                         FixFunction fixer;
    433                         *assertion = (*assertion )->acceptMutator( fixer );
    434                         if ( fixer.get_isVoid() ) {
    435                             throw SemanticError( "invalid type void in assertion of function ", func );
    436                         }
    437                         (*type )->get_assertions().push_back( *assertion );
    438                     }
    439                 }
    440                 toBeDone.clear();
    441                 toBeDone.splice( toBeDone.end(), nextRound );
    442             }
    443         }
    444456    }
    445457
    446458    void Pass3::visit( ObjectDecl *object ) {
    447         forallFixer( object->get_type() );
    448         if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
    449             forallFixer( pointer->get_base() );
    450         } // if
    451         Parent::visit( object );
    452         object->fixUniqueId();
     459                forallFixer( object->get_type() );
     460                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     461                        forallFixer( pointer->get_base() );
     462                } // if
     463                Parent::visit( object );
     464                object->fixUniqueId();
    453465    }
    454466
    455467    void Pass3::visit( FunctionDecl *func ) {
    456         forallFixer( func->get_type() );
    457         Parent::visit( func );
    458         func->fixUniqueId();
     468                forallFixer( func->get_type() );
     469                Parent::visit( func );
     470                func->fixUniqueId();
    459471    }
    460472
     
    462474
    463475    void AddStructAssignment::addStructAssignment( std::list< Declaration * > &translationUnit ) {
    464         AddStructAssignment visitor;
    465         acceptAndAdd( translationUnit, visitor, false );
     476                AddStructAssignment visitor;
     477                acceptAndAdd( translationUnit, visitor, false );
    466478    }
    467479
    468480    template< typename OutputIterator >
    469481    void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
    470         ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    471         // unnamed bit fields are not copied as they cannot be accessed
    472         if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    473 
    474         UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    475  
    476         UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    477         derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    478  
    479         // do something special for unnamed members
    480         Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    481         assignExpr->get_args().push_back( dstselect );
    482  
    483         Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    484         assignExpr->get_args().push_back( srcselect );
    485  
    486         *out++ = new ExprStmt( noLabels, assignExpr );
     482                ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
     483                // unnamed bit fields are not copied as they cannot be accessed
     484                if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
     485
     486                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     487 
     488                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     489                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     490 
     491                // do something special for unnamed members
     492                Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
     493                assignExpr->get_args().push_back( dstselect );
     494 
     495                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     496                assignExpr->get_args().push_back( srcselect );
     497 
     498                *out++ = new ExprStmt( noLabels, assignExpr );
    487499    }
    488500
    489501    template< typename OutputIterator >
    490502    void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
    491         static UniqueName indexName( "_index" );
    492  
    493         // for a flexible array member nothing is done -- user must define own assignment
    494         if ( ! array->get_dimension() ) return;
    495  
    496         ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    497         *out++ = new DeclStmt( noLabels, index );
    498  
    499         UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    500         init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    501         init->get_args().push_back( new NameExpr( "0" ) );
    502         Statement *initStmt = new ExprStmt( noLabels, init );
    503  
    504         UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    505         cond->get_args().push_back( new VariableExpr( index ) );
    506         cond->get_args().push_back( array->get_dimension()->clone() );
    507  
    508         UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    509         inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    510  
    511         UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    512  
    513         UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    514         derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    515  
    516         Expression *dstselect = new MemberExpr( member, derefExpr );
    517         UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
    518         dstIndex->get_args().push_back( dstselect );
    519         dstIndex->get_args().push_back( new VariableExpr( index ) );
    520         assignExpr->get_args().push_back( dstIndex );
    521  
    522         Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    523         UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    524         srcIndex->get_args().push_back( srcselect );
    525         srcIndex->get_args().push_back( new VariableExpr( index ) );
    526         assignExpr->get_args().push_back( srcIndex );
    527  
    528         *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
     503                static UniqueName indexName( "_index" );
     504 
     505                // for a flexible array member nothing is done -- user must define own assignment
     506                if ( ! array->get_dimension() ) return;
     507 
     508                ObjectDecl *index = new ObjectDecl( indexName.newName(), Declaration::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
     509                *out++ = new DeclStmt( noLabels, index );
     510 
     511                UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
     512                init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     513                init->get_args().push_back( new NameExpr( "0" ) );
     514                Statement *initStmt = new ExprStmt( noLabels, init );
     515 
     516                UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
     517                cond->get_args().push_back( new VariableExpr( index ) );
     518                cond->get_args().push_back( array->get_dimension()->clone() );
     519 
     520                UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
     521                inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
     522 
     523                UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
     524 
     525                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     526                derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
     527 
     528                Expression *dstselect = new MemberExpr( member, derefExpr );
     529                UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
     530                dstIndex->get_args().push_back( dstselect );
     531                dstIndex->get_args().push_back( new VariableExpr( index ) );
     532                assignExpr->get_args().push_back( dstIndex );
     533 
     534                Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
     535                UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
     536                srcIndex->get_args().push_back( srcselect );
     537                srcIndex->get_args().push_back( new VariableExpr( index ) );
     538                assignExpr->get_args().push_back( srcIndex );
     539 
     540                *out++ = new ForStmt( noLabels, initStmt, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    529541    }
    530542
    531543    Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    532         FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    533  
    534         ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    535         assignType->get_returnVals().push_back( returnVal );
    536  
    537         ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    538         assignType->get_parameters().push_back( dstParam );
    539  
    540         ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    541         assignType->get_parameters().push_back( srcParam );
    542 
    543         // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    544         // because each unit generates copies of the default routines for each aggregate.
    545         FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? Declaration::NoStorageClass : Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
    546         assignDecl->fixUniqueId();
    547  
    548         for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    549             if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    550                 if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    551                     makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    552                 } else {
    553                     makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    554                 } // if
    555             } // if
    556         } // for
    557         assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    558  
    559         return assignDecl;
     544                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     545 
     546                ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     547                assignType->get_returnVals().push_back( returnVal );
     548 
     549                ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
     550                assignType->get_parameters().push_back( dstParam );
     551 
     552                ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
     553                assignType->get_parameters().push_back( srcParam );
     554
     555                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
     556                // because each unit generates copies of the default routines for each aggregate.
     557                FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? Declaration::NoStorageClass : Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
     558                assignDecl->fixUniqueId();
     559 
     560                for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
     561                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
     562                                if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
     563                                        makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
     564                                } else {
     565                                        makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
     566                                } // if
     567                        } // if
     568                } // for
     569                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     570 
     571                return assignDecl;
    560572    }
    561573
    562574    Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
    563         FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    564  
    565         ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    566         assignType->get_returnVals().push_back( returnVal );
    567  
    568         ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
    569         assignType->get_parameters().push_back( dstParam );
    570  
    571         ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
    572         assignType->get_parameters().push_back( srcParam );
    573  
    574         // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    575         // because each unit generates copies of the default routines for each aggregate.
    576         FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? Declaration::NoStorageClass : Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
    577         assignDecl->fixUniqueId();
    578  
    579         UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    580         copy->get_args().push_back( new VariableExpr( dstParam ) );
    581         copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    582         copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
    583 
    584         assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
    585         assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    586  
    587         return assignDecl;
     575                FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
     576 
     577                ObjectDecl *returnVal = new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
     578                assignType->get_returnVals().push_back( returnVal );
     579 
     580                ObjectDecl *dstParam = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), refType->clone() ), 0 );
     581                assignType->get_parameters().push_back( dstParam );
     582 
     583                ObjectDecl *srcParam = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, refType, 0 );
     584                assignType->get_parameters().push_back( srcParam );
     585 
     586                // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
     587                // because each unit generates copies of the default routines for each aggregate.
     588                FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? Declaration::NoStorageClass : Declaration::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true );
     589                assignDecl->fixUniqueId();
     590 
     591                UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
     592                copy->get_args().push_back( new VariableExpr( dstParam ) );
     593                copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
     594                copy->get_args().push_back( new SizeofExpr( refType->clone() ) );
     595
     596                assignDecl->get_statements()->get_kids().push_back( new ExprStmt( noLabels, copy ) );
     597                assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     598 
     599                return assignDecl;
    588600    }
    589601
    590602    void AddStructAssignment::visit( StructDecl *structDecl ) {
    591         if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    592             StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
    593             structInst->set_baseStruct( structDecl );
    594             declsToAdd.push_back( makeStructAssignment( structDecl, structInst, functionNesting ) );
    595             structsDone.insert( structDecl->get_name() );
    596         } // if
     603                if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
     604                        StructInstType *structInst = new StructInstType( Type::Qualifiers(), structDecl->get_name() );
     605                        structInst->set_baseStruct( structDecl );
     606                        declsToAdd.push_back( makeStructAssignment( structDecl, structInst, functionNesting ) );
     607                        structsDone.insert( structDecl->get_name() );
     608                } // if
    597609    }
    598610
    599611    void AddStructAssignment::visit( UnionDecl *unionDecl ) {
    600         if ( ! unionDecl->get_members().empty() ) {
    601             UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
    602             unionInst->set_baseUnion( unionDecl );
    603             declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst, functionNesting ) );
    604         } // if
     612                if ( ! unionDecl->get_members().empty() ) {
     613                        UnionInstType *unionInst = new UnionInstType( Type::Qualifiers(), unionDecl->get_name() );
     614                        unionInst->set_baseUnion( unionDecl );
     615                        declsToAdd.push_back( makeUnionAssignment( unionDecl, unionInst, functionNesting ) );
     616                } // if
    605617    }
    606618
    607619    void AddStructAssignment::visit( TypeDecl *typeDecl ) {
    608         CompoundStmt *stmts = 0;
    609         TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    610         typeInst->set_baseType( typeDecl );
    611         ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
    612         ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
    613         if ( typeDecl->get_base() ) {
    614             stmts = new CompoundStmt( std::list< Label >() );
    615             UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    616             assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    617             assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    618             stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
    619         } // if
    620         FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    621         type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
    622         type->get_parameters().push_back( dst );
    623         type->get_parameters().push_back( src );
    624         FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
    625         declsToAdd.push_back( func );
     620                CompoundStmt *stmts = 0;
     621                TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
     622                typeInst->set_baseType( typeDecl );
     623                ObjectDecl *src = new ObjectDecl( "_src", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
     624                ObjectDecl *dst = new ObjectDecl( "_dst", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
     625                if ( typeDecl->get_base() ) {
     626                        stmts = new CompoundStmt( std::list< Label >() );
     627                        UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
     628                        assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
     629                        assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
     630                        stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
     631                } // if
     632                FunctionType *type = new FunctionType( Type::Qualifiers(), false );
     633                type->get_returnVals().push_back( new ObjectDecl( "", Declaration::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
     634                type->get_parameters().push_back( dst );
     635                type->get_parameters().push_back( src );
     636                FunctionDecl *func = new FunctionDecl( "?=?", Declaration::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false );
     637                declsToAdd.push_back( func );
    626638    }
    627639
    628640    void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
    629         if ( ! declsToAdd.empty() ) {
    630             for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    631                 statements.insert( i, new DeclStmt( noLabels, *decl ) );
    632             } // for
    633             declsToAdd.clear();
    634         } // if
     641                if ( ! declsToAdd.empty() ) {
     642                        for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
     643                                statements.insert( i, new DeclStmt( noLabels, *decl ) );
     644                        } // for
     645                        declsToAdd.clear();
     646                } // if
    635647    }
    636648
    637649    void AddStructAssignment::visit( FunctionType *) {
    638         // ensure that we don't add assignment ops for types defined as part of the function
     650                // ensure that we don't add assignment ops for types defined as part of the function
    639651    }
    640652
    641653    void AddStructAssignment::visit( PointerType *) {
    642         // ensure that we don't add assignment ops for types defined as part of the pointer
     654                // ensure that we don't add assignment ops for types defined as part of the pointer
    643655    }
    644656
    645657    void AddStructAssignment::visit( ContextDecl *) {
    646         // ensure that we don't add assignment ops for types defined as part of the context
     658                // ensure that we don't add assignment ops for types defined as part of the context
    647659    }
    648660
    649661    template< typename StmtClass >
    650662    inline void AddStructAssignment::visitStatement( StmtClass *stmt ) {
    651         std::set< std::string > oldStructs = structsDone;
    652         addVisit( stmt, *this );
    653         structsDone = oldStructs;
     663                std::set< std::string > oldStructs = structsDone;
     664                addVisit( stmt, *this );
     665                structsDone = oldStructs;
    654666    }
    655667
    656668    void AddStructAssignment::visit( FunctionDecl *functionDecl ) {
    657         maybeAccept( functionDecl->get_functionType(), *this );
    658         acceptAll( functionDecl->get_oldDecls(), *this );
    659         functionNesting += 1;
    660         maybeAccept( functionDecl->get_statements(), *this );
    661         functionNesting -= 1;
     669                maybeAccept( functionDecl->get_functionType(), *this );
     670                acceptAll( functionDecl->get_oldDecls(), *this );
     671                functionNesting += 1;
     672                maybeAccept( functionDecl->get_statements(), *this );
     673                functionNesting -= 1;
    662674    }
    663675
    664676    void AddStructAssignment::visit( CompoundStmt *compoundStmt ) {
    665         visitStatement( compoundStmt );
     677                visitStatement( compoundStmt );
    666678    }
    667679
    668680    void AddStructAssignment::visit( IfStmt *ifStmt ) {
    669         visitStatement( ifStmt );
     681                visitStatement( ifStmt );
    670682    }
    671683
    672684    void AddStructAssignment::visit( WhileStmt *whileStmt ) {
    673         visitStatement( whileStmt );
     685                visitStatement( whileStmt );
    674686    }
    675687
    676688    void AddStructAssignment::visit( ForStmt *forStmt ) {
    677         visitStatement( forStmt );
     689                visitStatement( forStmt );
    678690    }
    679691
    680692    void AddStructAssignment::visit( SwitchStmt *switchStmt ) {
    681         visitStatement( switchStmt );
     693                visitStatement( switchStmt );
    682694    }
    683695
    684696    void AddStructAssignment::visit( ChooseStmt *switchStmt ) {
    685         visitStatement( switchStmt );
     697                visitStatement( switchStmt );
    686698    }
    687699
    688700    void AddStructAssignment::visit( CaseStmt *caseStmt ) {
    689         visitStatement( caseStmt );
     701                visitStatement( caseStmt );
    690702    }
    691703
    692704    void AddStructAssignment::visit( CatchStmt *cathStmt ) {
    693         visitStatement( cathStmt );
     705                visitStatement( cathStmt );
    694706    }
    695707
    696708    bool isTypedef( Declaration *decl ) {
    697         return dynamic_cast< TypedefDecl * >( decl );
     709                return dynamic_cast< TypedefDecl * >( decl );
    698710    }
    699711
    700712    void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
    701         EliminateTypedef eliminator;
    702         mutateAll( translationUnit, eliminator );
    703         filter( translationUnit, isTypedef, true );
     713                EliminateTypedef eliminator;
     714                mutateAll( translationUnit, eliminator );
     715                filter( translationUnit, isTypedef, true );
    704716    }
    705717
    706718    Type *EliminateTypedef::mutate( TypeInstType *typeInst ) {
    707         std::map< std::string, TypedefDecl * >::const_iterator def = typedefNames.find( typeInst->get_name() );
    708         if ( def != typedefNames.end() ) {
    709             Type *ret = def->second->get_base()->clone();
    710             ret->get_qualifiers() += typeInst->get_qualifiers();
    711             delete typeInst;
    712             return ret;
    713         } // if
    714         return typeInst;
     719                std::map< std::string, TypedefDecl * >::const_iterator def = typedefNames.find( typeInst->get_name() );
     720                if ( def != typedefNames.end() ) {
     721                        Type *ret = def->second->get_base()->clone();
     722                        ret->get_qualifiers() += typeInst->get_qualifiers();
     723                        delete typeInst;
     724                        return ret;
     725                } // if
     726                return typeInst;
    715727    }
    716728
    717729    Declaration *EliminateTypedef::mutate( TypedefDecl *tyDecl ) {
    718         Declaration *ret = Mutator::mutate( tyDecl );
    719         typedefNames[ tyDecl->get_name() ] = tyDecl;
    720         // When a typedef is a forward declaration:
    721         //    typedef struct screen SCREEN;
    722         // the declaration portion must be retained:
    723         //    struct screen;
    724         // because the expansion of the typedef is:
    725         //    void rtn( SCREEN *p ) => void rtn( struct screen *p )
    726         // hence the type-name "screen" must be defined.
    727         // Note, qualifiers on the typedef are superfluous for the forward declaration.
    728         if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( tyDecl->get_base() ) ) {
    729             return new StructDecl( aggDecl->get_name() );
    730         } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( tyDecl->get_base() ) ) {
    731             return new UnionDecl( aggDecl->get_name() );
    732         } else {
    733             return ret;
    734         } // if
     730                Declaration *ret = Mutator::mutate( tyDecl );
     731                typedefNames[ tyDecl->get_name() ] = tyDecl;
     732                // When a typedef is a forward declaration:
     733                //    typedef struct screen SCREEN;
     734                // the declaration portion must be retained:
     735                //    struct screen;
     736                // because the expansion of the typedef is:
     737                //    void rtn( SCREEN *p ) => void rtn( struct screen *p )
     738                // hence the type-name "screen" must be defined.
     739                // Note, qualifiers on the typedef are superfluous for the forward declaration.
     740                if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( tyDecl->get_base() ) ) {
     741                        return new StructDecl( aggDecl->get_name() );
     742                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( tyDecl->get_base() ) ) {
     743                        return new UnionDecl( aggDecl->get_name() );
     744                } else {
     745                        return ret;
     746                } // if
    735747    }
    736748
    737749    TypeDecl *EliminateTypedef::mutate( TypeDecl *typeDecl ) {
    738         std::map< std::string, TypedefDecl * >::iterator i = typedefNames.find( typeDecl->get_name() );
    739         if ( i != typedefNames.end() ) {
    740             typedefNames.erase( i ) ;
    741         } // if
    742         return typeDecl;
     750                std::map< std::string, TypedefDecl * >::iterator i = typedefNames.find( typeDecl->get_name() );
     751                if ( i != typedefNames.end() ) {
     752                        typedefNames.erase( i ) ;
     753                } // if
     754                return typeDecl;
    743755    }
    744756
    745757    DeclarationWithType *EliminateTypedef::mutate( FunctionDecl *funcDecl ) {
    746         std::map< std::string, TypedefDecl * > oldNames = typedefNames;
    747         DeclarationWithType *ret = Mutator::mutate( funcDecl );
    748         typedefNames = oldNames;
    749         return ret;
     758                std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     759                DeclarationWithType *ret = Mutator::mutate( funcDecl );
     760                typedefNames = oldNames;
     761                return ret;
    750762    }
    751763
    752764    ObjectDecl *EliminateTypedef::mutate( ObjectDecl *objDecl ) {
    753         std::map< std::string, TypedefDecl * > oldNames = typedefNames;
    754         ObjectDecl *ret = Mutator::mutate( objDecl );
    755         typedefNames = oldNames;
    756         return ret;
     765                std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     766                ObjectDecl *ret = Mutator::mutate( objDecl );
     767                typedefNames = oldNames;
     768                return ret;
    757769    }
    758770
    759771    Expression *EliminateTypedef::mutate( CastExpr *castExpr ) {
    760         std::map< std::string, TypedefDecl * > oldNames = typedefNames;
    761         Expression *ret = Mutator::mutate( castExpr );
    762         typedefNames = oldNames;
    763         return ret;
     772                std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     773                Expression *ret = Mutator::mutate( castExpr );
     774                typedefNames = oldNames;
     775                return ret;
    764776    }
    765777
    766778    CompoundStmt *EliminateTypedef::mutate( CompoundStmt *compoundStmt ) {
    767         std::map< std::string, TypedefDecl * > oldNames = typedefNames;
    768         CompoundStmt *ret = Mutator::mutate( compoundStmt );
    769         std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
    770         while ( i != compoundStmt->get_kids().end() ) {
    771             std::list< Statement * >::iterator next = i;
    772             ++next;
    773             if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) {
    774                 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    775                     delete *i;
    776                     compoundStmt->get_kids().erase( i );
    777                 } // if
    778             } // if
    779             i = next;
    780         } // while
    781         typedefNames = oldNames;
    782         return ret;
     779                std::map< std::string, TypedefDecl * > oldNames = typedefNames;
     780                CompoundStmt *ret = Mutator::mutate( compoundStmt );
     781                std::list< Statement * >::iterator i = compoundStmt->get_kids().begin();
     782                while ( i != compoundStmt->get_kids().end() ) {
     783                        std::list< Statement * >::iterator next = i;
     784                        ++next;
     785                        if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( *i ) ) {
     786                                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
     787                                        delete *i;
     788                                        compoundStmt->get_kids().erase( i );
     789                                } // if
     790                        } // if
     791                        i = next;
     792                } // while
     793                typedefNames = oldNames;
     794                return ret;
    783795    }
    784796} // namespace SymTab
     797
     798// Local Variables: //
     799// tab-width: 4 //
     800// mode: c++ //
     801// compile-command: "make install" //
     802// End: //
  • translator/SymTab/Validate.h

    ra32b204 r0dd3a2f  
    1 // This class is intended to perform pre-processing of declarations, validating their
    2 // correctness and computing some auxilliary data that is necessary for the indexer.
     1//
     2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
     3//
     4// The contents of this file are covered under the licence agreement in the
     5// file "LICENCE" distributed with Cforall.
     6//
     7// Validate.h -- This class is intended to perform pre-processing of declarations, validating their correctness and
     8//               computing some auxilliary data that is necessary for the indexer.
     9//
     10// Author           : Richard C. Bilson
     11// Created On       : Sun May 17 21:53:34 2015
     12// Last Modified By : Peter A. Buhr
     13// Last Modified On : Sun May 17 21:55:09 2015
     14// Update Count     : 2
     15//
    316
    4 #ifndef SYMTAB_VALIDATE_H
    5 #define SYMTAB_VALIDATE_H
     17#ifndef VALIDATE_H
     18#define VALIDATE_H
    619
    720#include "SynTree/SynTree.h"
     
    1225    void validate( std::list< Declaration * > &translationUnit, bool doDebug = false );
    1326    void validateType( Type *type, const Indexer *indexer );
    14 } // SymTab
     27} // namespace SymTab
    1528
    16 #endif // SYMTAB_VALIDATE_H
     29#endif // VALIDATE_H
     30
     31// Local Variables: //
     32// tab-width: 4 //
     33// mode: c++ //
     34// compile-command: "make install" //
     35// End: //
Note: See TracChangeset for help on using the changeset viewer.