Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Indexer.h

    r114bde6 red34540  
    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();
     
    4550                        /// non-null if this declaration is deleted
    4651                        BaseSyntaxNode * deleteStmt = nullptr;
    47                         /// scope of identifier
    48                         unsigned long scope = 0;
    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                                 DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt,
    54                                 unsigned long scope )
    55                                 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {}
    56                         IdData( const IdData& o, BaseSyntaxNode * 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;
     
    8280                EnumDecl *globalLookupEnum( const std::string &id ) const;
    8381
     82                void print( std::ostream &os, int indent = 0 ) const;
     83
     84                /// looks up a specific mangled ID at the given scope
     85                IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
     86                const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
     87                /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
     88                bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
     89                /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
     90                bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
     91                // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
     92                NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
     93                StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
     94                EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
     95                UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
     96                TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
     97
     98                typedef std::function<bool(IdData &, const std::string &)> ConflictFunction;
     99
    84100                void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
    85101                void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
     
    96112                void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
    97113
     114                /// adds all of the members of the Aggregate (addWith helper)
     115                void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction );
     116
    98117                /// convenience function for adding a list of Ids to the indexer
    99118                void addIds( const std::list< DeclarationWithType * > & decls );
     
    105124                void addFunctionType( FunctionType * ftype );
    106125
     126                bool doDebug = false; ///< Display debugging trace?
    107127          private:
    108                 /// Wraps a Decl* with a scope
    109                 template<typename Decl>
    110                 struct Scoped {
    111                         Decl* decl;           ///< declaration
    112                         unsigned long scope;  ///< scope of this declaration
     128                struct Impl;
    113129
    114                         Scoped(Decl* d, unsigned long s) : decl(d), scope(s) {}
    115                 };
     130                Impl *tables;         ///< Copy-on-write instance of table data structure
     131                unsigned long scope;  ///< Scope index of this pointer
    116132
    117                 using Ptr = std::shared_ptr<const Indexer>;
     133                /// Takes a new ref to a table (returns null if null)
     134                static Impl *newRef( Impl *toClone );
     135                /// Clears a ref to a table (does nothing if null)
     136                static void deleteRef( Impl *toFree );
    118137
    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> >;
     138                // Removes matching autogenerated constructors and destructors
     139                // so that they will not be selected
     140                // void removeSpecialOverrides( FunctionDecl *decl );
     141                void removeSpecialOverrides( const std::string &id, std::list< IdData > & out ) const;
    126142
    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                         BaseSyntaxNode * deleteStmt;  ///< Statement that deletes this expression
    155 
    156                 private:
    157                         OnConflict() : mode(Error), deleteStmt(nullptr) {}
    158                         OnConflict( BaseSyntaxNode * d ) : mode(Delete), deleteStmt(d) {}
    159                 public:
    160                         OnConflict( const OnConflict& ) = default;
    161 
    162                         static OnConflict error() { return {}; }
    163                         static OnConflict deleteWith( BaseSyntaxNode * d ) { return { d }; }
    164                 };
    165 
    166                 /// true if the existing identifier conflicts with the added identifier
    167                 bool addedIdConflicts(
    168                         const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts,
    169                         BaseSyntaxNode * deleteStmt );
     143                /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
     144                void makeWritable();
    170145
    171146                /// common code for addId, addDeletedId, etc.
    172                 void addId(
    173                         DeclarationWithType * decl, OnConflict handleConflicts,
    174                         Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
    175 
    176                 /// adds all of the members of the Aggregate (addWith helper)
    177                 void addMembers( AggregateDecl * aggr, Expression * expr, OnConflict handleConflicts );
    178 
    179                 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name
    180                 bool hasCompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
    181                 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
    182                 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName ) const;
     147                void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
    183148        };
    184149} // namespace SymTab
Note: See TracChangeset for help on using the changeset viewer.