source: translator/SymTab/IdTable.cc @ 9df2dd5

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newstringwith_gc
Last change on this file since 9df2dd5 was 51b7345, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

initial commit

  • Property mode set to 100644
File size: 3.6 KB
Line 
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 */
7
8#include <cassert>
9
10#include "SynTree/Declaration.h"
11#include "ResolvExpr/typeops.h"
12#include "Indexer.h"
13#include "Mangler.h"
14#include "IdTable.h"
15#include "SemanticError.h"
16
17using std::string;
18
19namespace SymTab {
20
21IdTable::IdTable()
22  : scopeLevel( 0 )
23{
24}
25
26void 
27IdTable::enterScope()
28{
29  scopeLevel++;
30}
31
32void 
33IdTable::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}
47
48void 
49IdTable::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  for( InnerTableType::const_iterator i = declTable.begin(); i != declTable.end(); ++i ) {
85    if( !i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
86      throw SemanticError( "invalid overload of C function ", i->second.top().first );
87    }
88  }
89}
90
91void 
92IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const
93{
94  OuterTableType::const_iterator outer = table.find( id );
95  if( outer == table.end() ) return;
96  const InnerTableType &declTable = outer->second;
97  for( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
98    const std::stack< DeclEntry >& entry = it->second;
99    if( !entry.empty() ) {
100      decls.push_back( entry.top().first );
101    }
102  }
103}
104
105void 
106IdTable::dump( std::ostream &os ) const
107{
108  for( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
109    for( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
110      const std::stack< DeclEntry >& entry = inner->second;
111      if( !entry.empty() && entry.top().second == scopeLevel ) {
112        os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
113      }
114    }
115  }
116}
117
118
119} // namespace SymTab
Note: See TracBrowser for help on using the repository browser.