Ignore:
Timestamp:
Oct 29, 2019, 4:01:24 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
773db65, 9421f3d8
Parents:
7951100 (diff), 8364209 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.h

    r7951100 rb067d9b  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:38:55 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Aug 17 16:09:12 2017
    13 // Update Count     : 8
     11// Last Modified By : Aaron B. Moss
     12// Last Modified On : Fri Mar  8 13:55:00 2019
     13// Update Count     : 9
    1414//
    1515
    1616#pragma once
    1717
    18 #include <iosfwd>             // for ostream
    19 #include <list>               // for list
    20 #include <string>             // for string
    21 #include <functional>         // for function
     18#include <functional>              // for function
     19#include <list>                    // for list
     20#include <memory>                  // for shared_ptr, enable_shared_from_this
     21#include <string>                  // for string
    2222
    23 #include "SynTree/Visitor.h"  // for Visitor
    24 #include "SynTree/SynTree.h"  // for AST nodes
     23#include "Common/PersistentMap.h"  // for PersistentMap
     24#include "SynTree/SynTree.h"       // for AST nodes
    2525
    2626namespace ResolvExpr {
    27 class Cost;
     27        class Cost;
    2828}
    2929
    3030namespace SymTab {
    31         class Indexer {
    32           public:
     31        class Indexer : public std::enable_shared_from_this<SymTab::Indexer> {
     32        public:
    3333                explicit Indexer();
     34                virtual ~Indexer();
    3435
    35                 Indexer( const Indexer &that );
    36                 Indexer( Indexer &&that );
    37                 virtual ~Indexer();
    38                 Indexer& operator= ( const Indexer &that );
    39                 Indexer& operator= ( Indexer &&that );
    40 
    41                 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to tell the indexer
    42                 // explicitly when scopes begin and end
     36                // when using an indexer manually (e.g., within a mutator traversal), it is necessary to
     37                // tell the indexer explicitly when scopes begin and end
    4338                void enterScope();
    4439                void leaveScope();
    4540
    4641                struct IdData {
    47                         DeclarationWithType * id = nullptr;
    48                         Expression * baseExpr = nullptr; // WithExpr
     42                        const DeclarationWithType * id = nullptr;
     43                        const Expression * baseExpr = nullptr; // WithExpr
    4944
    5045                        /// non-null if this declaration is deleted
    51                         BaseSyntaxNode * deleteStmt = nullptr;
     46                        const Declaration * deleteStmt = nullptr;
     47                        /// scope of identifier
     48                        unsigned long scope = 0;
    5249
    5350                        // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
    5451                        IdData() = default;
    55                         IdData( DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ) {}
     52                        IdData(
     53                                const DeclarationWithType * id, const Expression * baseExpr, const Declaration * deleteStmt,
     54                                unsigned long scope )
     55                                : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
     56                        IdData( const IdData& o, const Declaration * deleteStmt )
     57                                : id( o.id ), baseExpr( o.baseExpr ), deleteStmt( deleteStmt ), scope( o.scope ) {}
    5658
    5759                        Expression * combine( ResolvExpr::Cost & cost ) const;
     
    5961
    6062                /// Gets all declarations with the given ID
    61                 void lookupId( const std::string &id, std::list< IdData > &out ) const;
     63                void lookupId( const std::string & id, std::list< IdData > &out ) const;
    6264                /// Gets the top-most type declaration with the given ID
    63                 NamedTypeDecl *lookupType( const std::string &id ) const;
     65                const NamedTypeDecl * lookupType( const std::string & id ) const;
    6466                /// Gets the top-most struct declaration with the given ID
    65                 StructDecl *lookupStruct( const std::string &id ) const;
     67                const StructDecl * lookupStruct( const std::string & id ) const;
    6668                /// Gets the top-most enum declaration with the given ID
    67                 EnumDecl *lookupEnum( const std::string &id ) const;
     69                const EnumDecl * lookupEnum( const std::string & id ) const;
    6870                /// Gets the top-most union declaration with the given ID
    69                 UnionDecl *lookupUnion( const std::string &id ) const;
     71                const UnionDecl * lookupUnion( const std::string & id ) const;
    7072                /// Gets the top-most trait declaration with the given ID
    71                 TraitDecl *lookupTrait( const std::string &id ) const;
     73                const TraitDecl * lookupTrait( const std::string & id ) const;
    7274
    73                 void print( std::ostream &os, int indent = 0 ) const;
     75                /// Gets the type declaration with the given ID at global scope
     76                const NamedTypeDecl * globalLookupType( const std::string & id ) const;
     77                /// Gets the struct declaration with the given ID at global scope
     78                const StructDecl * globalLookupStruct( const std::string & id ) const;
     79                /// Gets the union declaration with the given ID at global scope
     80                const UnionDecl * globalLookupUnion( const std::string & id ) const;
     81                /// Gets the enum declaration with the given ID at global scope
     82                const EnumDecl * globalLookupEnum( const std::string & id ) const;
    7483
    75                 /// looks up a specific mangled ID at the given scope
    76                 IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
    77                 const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    78                 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
    79                 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    80                 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
    81                 bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    82                 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
    83                 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
    84                 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
    85                 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
    86                 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
    87                 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
     84                void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr );
     85                void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt );
    8886
    89                 typedef std::function<bool(IdData &, const std::string &)> ConflictFunction;
    90 
    91                 void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
    92                 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
    93 
    94                 void addType( NamedTypeDecl *decl );
    95                 void addStruct( const std::string &id );
    96                 void addStruct( StructDecl *decl );
    97                 void addEnum( EnumDecl *decl );
    98                 void addUnion( const std::string &id );
    99                 void addUnion( UnionDecl *decl );
    100                 void addTrait( TraitDecl *decl );
     87                void addType( const NamedTypeDecl * decl );
     88                void addStruct( const std::string & id );
     89                void addStruct( const StructDecl * decl );
     90                void addEnum( const EnumDecl * decl );
     91                void addUnion( const std::string & id );
     92                void addUnion( const UnionDecl * decl );
     93                void addTrait( const TraitDecl * decl );
    10194
    10295                /// adds all of the IDs from WithStmt exprs
    103                 void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
    104 
    105                 /// adds all of the members of the Aggregate (addWith helper)
    106                 void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction );
     96                void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt );
    10797
    10898                /// convenience function for adding a list of Ids to the indexer
     
    113103
    114104                /// convenience function for adding all of the declarations in a function type to the indexer
    115                 void addFunctionType( FunctionType * ftype );
     105                void addFunctionType( const FunctionType * ftype );
    116106
    117                 bool doDebug = false; ///< Display debugging trace?
    118107          private:
    119                 struct Impl;
     108                /// Wraps a Decl * with a scope
     109                template<typename Decl>
     110                struct Scoped {
     111                        const Decl * decl;           ///< declaration
     112                        unsigned long scope;  ///< scope of this declaration
    120113
    121                 Impl *tables;         ///< Copy-on-write instance of table data structure
    122                 unsigned long scope;  ///< Scope index of this pointer
     114                        Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {}
     115                };
    123116
    124                 /// Takes a new ref to a table (returns null if null)
    125                 static Impl *newRef( Impl *toClone );
    126                 /// Clears a ref to a table (does nothing if null)
    127                 static void deleteRef( Impl *toFree );
     117                using Ptr = std::shared_ptr<const Indexer>;
    128118
    129                 // Removes matching autogenerated constructors and destructors
    130                 // so that they will not be selected
    131                 // void removeSpecialOverrides( FunctionDecl *decl );
    132                 void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
     119                using MangleTable = PersistentMap< std::string, IdData >;
     120                using IdTable = PersistentMap< std::string, MangleTable::Ptr >;
     121                using TypeTable = PersistentMap< std::string, Scoped<NamedTypeDecl> >;
     122                using StructTable = PersistentMap< std::string, Scoped<StructDecl> >;
     123                using EnumTable = PersistentMap< std::string, Scoped<EnumDecl> >;
     124                using UnionTable = PersistentMap< std::string, Scoped<UnionDecl> >;
     125                using TraitTable = PersistentMap< std::string, Scoped<TraitDecl> >;
    133126
    134                 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
    135                 void makeWritable();
     127                IdTable::Ptr idTable;          ///< identifier namespace
     128                TypeTable::Ptr typeTable;      ///< type namespace
     129                StructTable::Ptr structTable;  ///< struct namespace
     130                EnumTable::Ptr enumTable;      ///< enum namespace
     131                UnionTable::Ptr unionTable;    ///< union namespace
     132                TraitTable::Ptr traitTable;    ///< trait namespace
     133
     134                Ptr prevScope;                 ///< reference to indexer for parent scope
     135                unsigned long scope;           ///< Scope index of this indexer
     136                unsigned long repScope;        ///< Scope index of currently represented scope
     137
     138                /// Ensures that a proper backtracking scope exists before a mutation
     139                void lazyInitScope();
     140
     141                /// Gets the indexer at the given scope
     142                const Indexer * atScope( unsigned long scope ) const;
     143
     144                /// Removes matching autogenerated constructors and destructors so that they will not be
     145                /// selected. If returns false, passed decl should not be added.
     146                bool removeSpecialOverrides( IdData & decl, MangleTable::Ptr & mangleTable );
     147
     148                /// Options for handling identifier conflicts
     149                struct OnConflict {
     150                        enum {
     151                                Error,  ///< Throw a semantic error
     152                                Delete  ///< Delete the earlier version with the delete statement
     153                        } mode;
     154                        const Declaration * deleteStmt;  ///< Statement that deletes this expression
     155
     156                private:
     157                        OnConflict() : mode(Error), deleteStmt(nullptr) {}
     158                        OnConflict( const Declaration * d ) : mode(Delete), deleteStmt(d) {}
     159                public:
     160                        OnConflict( const OnConflict& ) = default;
     161
     162                        static OnConflict error() { return {}; }
     163                        static OnConflict deleteWith( const Declaration * d ) { return { d }; }
     164                };
     165
     166                /// true if the existing identifier conflicts with the added identifier
     167                bool addedIdConflicts(
     168                        const IdData & existing, const DeclarationWithType * added, OnConflict handleConflicts,
     169                        const Declaration * deleteStmt );
    136170
    137171                /// common code for addId, addDeletedId, etc.
    138                 void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
     172                void addId(const DeclarationWithType * decl, OnConflict handleConflicts,
     173                        const Expression * baseExpr = nullptr, const Declaration * deleteStmt = nullptr );
     174
     175                /// adds all of the members of the Aggregate (addWith helper)
     176                void addMembers( const AggregateDecl * aggr, const Expression * expr, OnConflict handleConflicts );
     177
     178                /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
     179                bool hasCompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
     180                /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
     181                bool hasIncompatibleCDecl( const std::string & id, const std::string & mangleName ) const;
    139182        };
    140183} // namespace SymTab
Note: See TracChangeset for help on using the changeset viewer.