source: src/AST/SymbolTable.hpp @ 561354f

ADT
Last change on this file since 561354f was 561354f, checked in by JiadaL <j82liang@…>, 12 months ago

Save progress

  • Property mode set to 100644
File size: 9.0 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// SymbolTable.hpp --
8//
9// Author           : Aaron B. Moss
10// Created On       : Wed May 29 11:00:00 2019
11// Last Modified By : Aaron B. Moss
12// Last Modified On : Wed May 29 11:00:00 2019
13// Update Count     : 1
14//
15
16#pragma once
17
18#include <memory>                  // for shared_ptr, enable_shared_from_this
19#include <vector>
20
21#include "Fwd.hpp"
22#include "Node.hpp"                // for ptr, readonly
23#include "Common/CodeLocation.h"
24#include "Common/PersistentMap.h"
25
26namespace ResolvExpr {
27        class Cost;
28}
29
30namespace ast {
31
32/// Builds and stores the symbol table, mapping identifiers to declarations.
33class SymbolTable final : public std::enable_shared_from_this<ast::SymbolTable> {
34public:
35        /// special functions stored in dedicated tables, with different lookup keys
36        enum SpecialFunctionKind {CTOR, DTOR, ASSIGN, NUMBER_OF_KINDS};
37        static SpecialFunctionKind getSpecialFunctionKind(const std::string & name);
38
39        /// Stored information about a declaration
40        struct IdData {
41                readonly<DeclWithType> id = nullptr;  ///< Identifier of declaration
42                readonly<Expr> baseExpr = nullptr;    ///< Implied containing aggregate (from WithExpr)
43                readonly<Decl> deleter = nullptr;     ///< Node deleting this declaration (if non-null)
44                unsigned long scope = 0;              ///< Scope of identifier
45
46                IdData() = default;
47                IdData( const DeclWithType * i, const Expr * base, const Decl * del, unsigned long s )
48                : id( i ), baseExpr( base ), deleter( del ), scope( s ) {}
49
50                /// Modify an existing node with a new deleter
51                IdData( const IdData & o, const Decl * del )
52                : id( o.id ), baseExpr( o.baseExpr ), deleter( del ), scope( o.scope ) {}
53
54                /// Constructs an expression referring to this identifier.
55                /// Increments `cost` by cost of reference conversion
56                Expr * combine( const CodeLocation & loc, ResolvExpr::Cost & cost ) const;
57        };
58
59private:
60        /// wraps a reference to D with a scope
61        template<typename D>
62        struct scoped {
63                readonly<D> decl;     ///< wrapped declaration
64                unsigned long scope;  ///< scope of this declaration
65
66                scoped(const D * d, unsigned long s) : decl(d), scope(s) {}
67        };
68
69        using MangleTable = PersistentMap< std::string, IdData >;
70        using IdTable = PersistentMap< std::string, MangleTable::Ptr >;
71        using TypeTable = PersistentMap< std::string, scoped<NamedTypeDecl> >;
72        using StructTable = PersistentMap< std::string, scoped<StructDecl> >;
73        using EnumTable = PersistentMap< std::string, scoped<EnumDecl> >;
74        using AdtTable = PersistentMap< std::string, scoped<AdtDecl> >;
75        using UnionTable = PersistentMap< std::string, scoped<UnionDecl> >;
76        using TraitTable = PersistentMap< std::string, scoped<TraitDecl> >;
77
78        IdTable::Ptr idTable;          ///< identifier namespace
79        TypeTable::Ptr typeTable;      ///< type namespace
80        StructTable::Ptr structTable;  ///< struct namespace
81        EnumTable::Ptr enumTable;      ///< enum namespace
82        UnionTable::Ptr unionTable;    ///< union namespace
83        AdtTable::Ptr adtTable;            ///< adt namespace
84        TraitTable::Ptr traitTable;    ///< trait namespace
85        IdTable::Ptr specialFunctionTable[NUMBER_OF_KINDS];
86
87        // using SpecialFuncTable = PersistentMap< std::string, IdTable::Ptr >; // fname (ctor/dtor/assign) - otypekey
88        // SpecialFuncTable::Ptr specialFuncTable;
89
90        using Ptr = std::shared_ptr<const SymbolTable>;
91
92        Ptr prevScope;                 ///< Indexer for parent scope
93        unsigned long scope;           ///< Scope index of this indexer
94        unsigned long repScope;        ///< Scope index of currently represented scope
95
96public:
97        SymbolTable();
98        ~SymbolTable();
99
100        // when using an indexer manually (e.g., within a mutator traversal), it is necessary to
101        // tell the indexer explicitly when scopes begin and end
102        void enterScope();
103        void leaveScope();
104
105        /// Gets all declarations with the given ID
106        std::vector<IdData> lookupId( const std::string &id ) const;
107        /// Gets special functions associated with a type; if no key is given, returns everything
108        std::vector<IdData> specialLookupId( SpecialFunctionKind kind, const std::string & otypeKey = "" ) const;
109        /// Gets the top-most type declaration with the given ID
110        const NamedTypeDecl * lookupType( const std::string &id ) const;
111        /// Gets the top-most struct declaration with the given ID
112        const StructDecl * lookupStruct( const std::string &id ) const;
113        /// Gets the top-most enum declaration with the given ID
114        const EnumDecl * lookupEnum( const std::string &id ) const;
115        /// Gets the top-most union declaration with the given ID
116        const UnionDecl * lookupUnion( const std::string &id ) const;
117        /// Gets the top-most trait declaration with the given ID
118        const TraitDecl * lookupTrait( const std::string &id ) const;
119
120        /// Gets the type declaration with the given ID at global scope
121        const NamedTypeDecl * globalLookupType( const std::string &id ) const;
122        /// Gets the struct declaration with the given ID at global scope
123        const StructDecl * globalLookupStruct( const std::string &id ) const;
124        /// Gets the union declaration with the given ID at global scope
125        const UnionDecl * globalLookupUnion( const std::string &id ) const;
126        /// Gets the enum declaration with the given ID at global scope
127        const EnumDecl * globalLookupEnum( const std::string &id ) const;
128
129        /// Adds an identifier declaration to the symbol table
130        void addId( const DeclWithType * decl, const Expr * baseExpr = nullptr );
131        /// Adds a deleted identifier declaration to the symbol table
132        void addDeletedId( const DeclWithType * decl, const Decl * deleter );
133
134        /// Adds a type to the symbol table
135        void addType( const NamedTypeDecl * decl );
136        /// Adds a struct declaration to the symbol table by name
137        void addStruct( const std::string & id );
138        /// Adds a struct declaration to the symbol table
139        void addStruct( const StructDecl * decl );
140        /// Adds an enum declaration to the symbol table
141        void addEnum( const EnumDecl * decl );
142        /// Adds an adt declaration to the symbol table
143        void addAdt( const AdtDecl * decl );
144        /// Adds a union declaration to the symbol table by name
145        void addUnion( const std::string & id );
146        /// Adds a union declaration to the symbol table
147        void addUnion( const UnionDecl * decl );
148        /// Adds a trait declaration to the symbol table
149        void addTrait( const TraitDecl * decl );
150
151        /// adds all of the IDs from WithStmt exprs
152        void addWith( const std::vector< ptr<Expr> > & withExprs, const Decl * withStmt );
153
154        /// convenience function for adding a list of Ids to the indexer
155        void addIds( const std::vector< ptr<DeclWithType> > & decls );
156
157        /// convenience function for adding a list of forall parameters to the indexer
158        void addTypes( const std::vector< ptr<TypeDecl> > & tds );
159
160        /// convenience function for adding all of the declarations in a function type to the indexer
161        void addFunction( const FunctionDecl * );
162
163private:
164        /// Ensures that a proper backtracking scope exists before a mutation
165        void lazyInitScope();
166
167        /// Gets the symbol table at a given scope
168        const SymbolTable * atScope( unsigned long i ) const;
169
170        /// Removes matching autogenerated constructors and destructors so that they will not be
171        /// selected. If returns false, passed decl should not be added.
172        bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
173
174        /// Options for handling identifier conflicts
175        struct OnConflict {
176                enum {
177                        Error,  ///< Throw a semantic error
178                        Delete  ///< Delete the earlier version with the delete statement
179                } mode;
180                const Decl * deleter;  ///< Statement that deletes this expression
181
182        private:
183                OnConflict() : mode(Error), deleter(nullptr) {}
184                OnConflict( const Decl * d ) : mode(Delete), deleter(d) {}
185        public:
186                OnConflict( const OnConflict& ) = default;
187
188                static OnConflict error() { return {}; }
189                static OnConflict deleteWith( const Decl * d ) { return { d }; }
190        };
191
192        /// true if the existing identifier conflicts with the added identifier
193        bool addedIdConflicts(
194                const IdData & existing, const DeclWithType * added, OnConflict handleConflicts,
195                const Decl * deleter );
196
197        /// common code for addId, addDeletedId, etc.
198        void addIdCommon(
199                const DeclWithType * decl, OnConflict handleConflicts,
200                const Expr * baseExpr = nullptr, const Decl * deleter = nullptr );
201
202        /// common code for addId when special decls are placed into separate tables
203        void addIdToTable(
204                const DeclWithType * decl, const std::string & lookupKey,
205                IdTable::Ptr & idTable, OnConflict handleConflicts,
206                const Expr * baseExpr = nullptr, const Decl * deleter = nullptr);
207
208        /// adds all of the members of the Aggregate (addWith helper)
209        void addMembers( const AggregateDecl * aggr, const Expr * expr, OnConflict handleConflicts );
210
211        /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
212        bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
213        /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
214        bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
215};
216
217}
218
219// Local Variables: //
220// tab-width: 4 //
221// mode: c++ //
222// compile-command: "make install" //
223// End: //
Note: See TracBrowser for help on using the repository browser.