source: src/SymTab/IdTable.cc @ 620cb95

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsctordeferred_resndemanglerenumforall-pointer-decaygc_noraiijacob/cs343-translationjenkins-sandboxmemorynew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 620cb95 was d3b7937, checked in by Peter A. Buhr <pabuhr@…>, 8 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.