Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.h

    re67991f ra181494  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:38:55 2015
    11 // Last Modified By : Aaron B. Moss
    12 // Last Modified On : Fri Mar  8 13:55:00 2019
    13 // Update Count     : 9
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Aug 17 16:09:12 2017
     13// Update Count     : 8
    1414//
    1515
    1616#pragma once
    1717
    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
     18#include <iosfwd>             // for ostream
     19#include <list>               // for list
     20#include <string>             // for string
     21#include <functional>         // for function
    2222
    23 #include "Common/PersistentMap.h"  // for PersistentMap
    24 #include "SynTree/SynTree.h"       // for AST nodes
     23#include "SynTree/Visitor.h"  // for Visitor
     24#include "SynTree/SynTree.h"  // for AST nodes
    2525
    2626namespace ResolvExpr {
    27         class Cost;
     27class Cost;
    2828}
    2929
    3030namespace SymTab {
    31         class Indexer : public std::enable_shared_from_this<SymTab::Indexer> {
    32         public:
     31        class Indexer {
     32          public:
    3333                explicit Indexer();
     34
     35                Indexer( const Indexer &that );
     36                Indexer( Indexer &&that );
    3437                virtual ~Indexer();
     38                Indexer& operator= ( const Indexer &that );
     39                Indexer& operator= ( Indexer &&that );
    3540
    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
     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
    3843                void enterScope();
    3944                void leaveScope();
    4045
    4146                struct IdData {
    42                         const DeclarationWithType * id = nullptr;
    43                         const Expression * baseExpr = nullptr; // WithExpr
     47                        DeclarationWithType * id = nullptr;
     48                        Expression * baseExpr = nullptr; // WithExpr
    4449
    4550                        /// non-null if this declaration is deleted
    46                         const Declaration * deleteStmt = nullptr;
    47                         /// scope of identifier
    48                         unsigned long scope = 0;
     51                        BaseSyntaxNode * deleteStmt = nullptr;
    4952
    5053                        // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
    5154                        IdData() = default;
    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 ) {}
     55                        IdData( DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ) {}
    5856
    5957                        Expression * combine( ResolvExpr::Cost & cost ) const;
     
    6159
    6260                /// Gets all declarations with the given ID
    63                 void lookupId( const std::string & id, std::list< IdData > &out ) const;
     61                void lookupId( const std::string &id, std::list< IdData > &out ) const;
    6462                /// Gets the top-most type declaration with the given ID
    65                 const NamedTypeDecl * lookupType( const std::string & id ) const;
     63                NamedTypeDecl *lookupType( const std::string &id ) const;
    6664                /// Gets the top-most struct declaration with the given ID
    67                 const StructDecl * lookupStruct( const std::string & id ) const;
     65                StructDecl *lookupStruct( const std::string &id ) const;
    6866                /// Gets the top-most enum declaration with the given ID
    69                 const EnumDecl * lookupEnum( const std::string & id ) const;
     67                EnumDecl *lookupEnum( const std::string &id ) const;
    7068                /// Gets the top-most union declaration with the given ID
    71                 const UnionDecl * lookupUnion( const std::string & id ) const;
     69                UnionDecl *lookupUnion( const std::string &id ) const;
    7270                /// Gets the top-most trait declaration with the given ID
    73                 const TraitDecl * lookupTrait( const std::string & id ) const;
     71                TraitDecl *lookupTrait( const std::string &id ) const;
    7472
    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;
     73                void print( std::ostream &os, int indent = 0 ) const;
    8374
    84                 void addId( const DeclarationWithType * decl, const Expression * baseExpr = nullptr );
    85                 void addDeletedId( const DeclarationWithType * decl, const Declaration * deleteStmt );
     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;
    8688
    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 );
     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 );
    94101
    95102                /// adds all of the IDs from WithStmt exprs
    96                 void addWith( const std::list< Expression * > & withExprs, const Declaration * withStmt );
     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 );
    97107
    98108                /// convenience function for adding a list of Ids to the indexer
     
    103113
    104114                /// convenience function for adding all of the declarations in a function type to the indexer
    105                 void addFunctionType( const FunctionType * ftype );
     115                void addFunctionType( FunctionType * ftype );
    106116
     117                bool doDebug = false; ///< Display debugging trace?
    107118          private:
    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
     119                struct Impl;
    113120
    114                         Scoped(const Decl * d, unsigned long s) : decl(d), scope(s) {}
    115                 };
     121                Impl *tables;         ///< Copy-on-write instance of table data structure
     122                unsigned long scope;  ///< Scope index of this pointer
    116123
    117                 using Ptr = std::shared_ptr<const Indexer>;
     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 );
    118128
    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> >;
     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;
    126133
    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 );
     134                /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
     135                void makeWritable();
    170136
    171137                /// common code for addId, addDeletedId, etc.
    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;
     138                void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
    182139        };
    183140} // namespace SymTab
Note: See TracChangeset for help on using the changeset viewer.