source: src/SymTab/IdTable.cc@ aa99647

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new string with_gc
Last change on this file since aa99647 was 843054c2, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

licencing: seventh groups of files

  • Property mode set to 100644
File size: 5.7 KB
Line 
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//
15
16#include <cassert>
17
18#include "SynTree/Declaration.h"
19#include "ResolvExpr/typeops.h"
20#include "Indexer.h"
21#include "Mangler.h"
22#include "IdTable.h"
23#include "SemanticError.h"
24
25using std::string;
26
27namespace SymTab {
28 IdTable::IdTable() : scopeLevel( 0 ) {
29 }
30
31 void IdTable::enterScope() {
32 scopeLevel++;
33 }
34
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
44
45 scopeLevel--;
46 assert( scopeLevel >= 0 );
47 }
48
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
96 }
97
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 }
109
110 DeclarationWithType * IdTable::lookupId( const std::string &id) const {
111 DeclarationWithType* result = 0;
112 int depth = -1;
113
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 }
126
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 ) {
130#if 0
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
137#endif
138#if 0
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
146#endif
147 } // for
148 } // for
149#if 0
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
158#endif
159 }
160} // namespace SymTab
161
162// Local Variables: //
163// tab-width: 4 //
164// mode: c++ //
165// compile-command: "make install" //
166// End: //
Note: See TracBrowser for help on using the repository browser.