source: src/SymTab/IdTable.cc@ ae7f1e0

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 with_gc
Last change on this file since ae7f1e0 was d3b7937, checked in by Peter A. Buhr <pabuhr@…>, 10 years ago

building runtime library (first attempt)

  • Property mode set to 100644
File size: 7.2 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 : Fri Jan 8 22:59:23 2016
13// Update Count : 74
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 "Common/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 // xxx - should be while?
40 if ( ! entry.empty() && entry.top().second == scopeLevel ) {
41 entry.pop();
42 } // if
43 } // for
44 } // for
45
46 scopeLevel--;
47 assert( scopeLevel >= 0 );
48 }
49
50 void IdTable::addDecl( DeclarationWithType *decl ) {
51 const string &name = decl->get_name();
52 string manglename;
53 if ( decl->get_linkage() == LinkageSpec::C ) {
54 manglename = name;
55 } else if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
56 // mangle the name without including the appropriate suffix, so overridable routines are placed into the
57 // same "bucket" as their user defined versions.
58 manglename = Mangler::mangle( decl, false );
59 } else {
60 manglename = Mangler::mangle( decl );
61 } // if
62
63 InnerTableType &declTable = table[ name ];
64 InnerTableType::iterator it = declTable.find( manglename );
65
66 if ( it == declTable.end() ) {
67 // first time this name mangling has been defined
68 declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
69 } else {
70 std::stack< DeclEntry >& entry = it->second;
71 if ( ! entry.empty() && entry.top().second == scopeLevel ) {
72 // if we're giving the same name mangling to things of different types then there is something wrong
73 Declaration *old = entry.top().first;
74 assert( (dynamic_cast<ObjectDecl*>( decl ) && dynamic_cast<ObjectDecl*>( old ) )
75 || (dynamic_cast<FunctionDecl*>( decl ) && dynamic_cast<FunctionDecl*>( old ) ) );
76
77 if ( LinkageSpec::isOverridable( old->get_linkage() ) ) {
78 // new definition shadows the autogenerated one, even at the same scope
79 declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
80 } else if ( decl->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( decl->get_type(), entry.top().first->get_type(), Indexer() ) ) {
81 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
82 // we should ignore outermost pointer qualifiers, except _Atomic?
83 FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( decl );
84 FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( old );
85 if ( newentry && oldentry ) {
86 if ( newentry->get_statements() && oldentry->get_statements() ) {
87 throw SemanticError( "duplicate function definition for 1 ", decl );
88 } // if
89 } else {
90 // two objects with the same mangled name defined in the same scope.
91 // both objects must be marked extern or both must be intrinsic for this to be okay
92 // xxx - perhaps it's actually if either is intrinsic then this is okay?
93 // might also need to be same storage class?
94 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( decl );
95 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( old );
96 if (newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) {
97 throw SemanticError( "duplicate definition for 3 ", decl );
98 } // if
99 } // if
100 } else {
101 throw SemanticError( "duplicate definition for ", decl );
102 } // if
103 } else {
104 // new scope level - shadow existing definition
105 declTable[ manglename ].push( DeclEntry( decl, scopeLevel ) );
106 } // if
107 } // if
108 // this ensures that no two declarations with the same unmangled name both have C linkage
109 for ( InnerTableType::iterator i = declTable.begin(); i != declTable.end(); ++i ) {
110 if ( ! i->second.empty() && i->second.top().first->get_linkage() == LinkageSpec::C && declTable.size() > 1 ) {
111 InnerTableType::iterator j = i;
112 for ( j++; j != declTable.end(); ++j ) {
113 if ( ! j->second.empty() && j->second.top().first->get_linkage() == LinkageSpec::C ) {
114 throw SemanticError( "invalid overload of C function " );
115 } // if
116 } // for
117 } // if
118 } // for
119 }
120
121 void IdTable::lookupId( const std::string &id, std::list< DeclarationWithType* >& decls ) const {
122 OuterTableType::const_iterator outer = table.find( id );
123 if ( outer == table.end() ) return;
124 const InnerTableType &declTable = outer->second;
125 for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
126 const std::stack< DeclEntry >& entry = it->second;
127 if ( ! entry.empty() ) {
128 decls.push_back( entry.top().first );
129 } // if
130 } // for
131 }
132
133 DeclarationWithType * IdTable::lookupId( const std::string &id) const {
134 DeclarationWithType* result = 0;
135 int depth = -1;
136
137 OuterTableType::const_iterator outer = table.find( id );
138 if ( outer == table.end() ) return 0;
139 const InnerTableType &declTable = outer->second;
140 for ( InnerTableType::const_iterator it = declTable.begin(); it != declTable.end(); ++it ) {
141 const std::stack< DeclEntry >& entry = it->second;
142 if ( ! entry.empty() && entry.top().second > depth ) {
143 result = entry.top().first;
144 depth = entry.top().second;
145 } // if
146 } // for
147 return result;
148 }
149
150 void IdTable::dump( std::ostream &os ) const {
151 for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
152 for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
153#if 0
154 const std::stack< DeclEntry >& entry = inner->second;
155 if ( ! entry.empty() ) { // && entry.top().second == scopeLevel ) {
156 os << outer->first << " (" << inner->first << ") (" << entry.top().second << ")" << std::endl;
157 } else {
158 os << outer->first << " (" << inner->first << ") ( entry-empty)" << std::endl;
159 } // if
160#endif
161#if 0
162 std::stack<DeclEntry> stack = inner->second;
163 os << "dumping a stack" << std::endl;
164 while ( ! stack.empty()) {
165 DeclEntry d = stack.top();
166 os << outer->first << " (" << inner->first << ") (" << d.second << ") " << std::endl;
167 stack.pop();
168 } // while
169#endif
170 } // for
171 } // for
172#if 0
173 for ( OuterTableType::const_iterator outer = table.begin(); outer != table.end(); ++outer ) {
174 for ( InnerTableType::const_iterator inner = outer->second.begin(); inner != outer->second.end(); ++inner ) {
175 const std::stack< DeclEntry >& entry = inner->second;
176 if ( ! entry.empty() && entry.top().second == scopeLevel ) {
177 os << outer->first << " (" << inner->first << ") (" << scopeLevel << ")" << std::endl;
178 } // if
179 } // for
180 } // for
181#endif
182 }
183} // namespace SymTab
184
185// Local Variables: //
186// tab-width: 4 //
187// mode: c++ //
188// compile-command: "make install" //
189// End: //
Note: See TracBrowser for help on using the repository browser.