source: src/SymTab/IdTable.cc@ 4389966

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 4389966 was 59cde21, checked in by Rob Schluntz <rschlunt@…>, 10 years ago

rearrange IdTable checks

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