Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/SymbolTable.cpp

    r4b8b2a4 r251ce80  
    1818#include <cassert>
    1919
     20#include "Copy.hpp"
    2021#include "Decl.hpp"
    2122#include "Expr.hpp"
    2223#include "Inspect.hpp"
    2324#include "Type.hpp"
    24 #include "CodeGen/OperatorTable.h"  // for isCtorDtorAssign
     25#include "CodeGen/OperatorTable.h"         // for isCtorDtorAssign
    2526#include "Common/SemanticError.h"
    2627#include "Common/Stats/Counter.h"
     
    2829#include "InitTweak/InitTweak.h"
    2930#include "ResolvExpr/Cost.h"
    30 #include "ResolvExpr/typeops.h"
     31#include "ResolvExpr/CandidateFinder.hpp"  // for referenceToRvalueConversion
     32#include "ResolvExpr/Unify.h"
    3133#include "SymTab/Mangler.h"
    3234
     
    6971        if ( baseExpr ) {
    7072                if (baseExpr->env) {
    71                         Expr * base = shallowCopy(baseExpr);
     73                        Expr * base = deepCopy(baseExpr);
    7274                        const TypeSubstitution * subs = baseExpr->env;
    7375                        base->env = nullptr;
     
    259261void SymbolTable::addId( const DeclWithType * decl, const Expr * baseExpr ) {
    260262        // default handling of conflicts is to raise an error
    261         addId( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
     263        addIdCommon( decl, OnConflict::error(), baseExpr, decl->isDeleted ? decl : nullptr );
    262264}
    263265
    264266void SymbolTable::addDeletedId( const DeclWithType * decl, const Decl * deleter ) {
    265267        // default handling of conflicts is to raise an error
    266         addId( decl, OnConflict::error(), nullptr, deleter );
     268        addIdCommon( decl, OnConflict::error(), nullptr, deleter );
    267269}
    268270
     
    276278                } else {
    277279                        // typedef redeclarations are errors only if types are different
    278                         if ( ! ResolvExpr::typesCompatible( existing->base, added->base, SymbolTable{} ) ) {
     280                        if ( ! ResolvExpr::typesCompatible( existing->base, added->base ) ) {
    279281                                SemanticError( added->location, "redeclaration of " + added->name );
    280282                        }
     
    641643        } else if ( existing.id->linkage.is_mangled
    642644                        || ResolvExpr::typesCompatible(
    643                                 added->get_type(), existing.id->get_type(), SymbolTable{} ) ) {
     645                                added->get_type(), existing.id->get_type() ) ) {
    644646
    645647                // it is a conflict if one declaration is deleted and the other is not
     
    676678}
    677679
    678 void SymbolTable::addId(
    679                 const DeclWithType * decl, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    680                 const Decl * deleter ) {
     680void SymbolTable::addIdCommon(
     681                const DeclWithType * decl, SymbolTable::OnConflict handleConflicts,
     682                const Expr * baseExpr, const Decl * deleter ) {
    681683        SpecialFunctionKind kind = getSpecialFunctionKind(decl->name);
    682684        if (kind == NUMBER_OF_KINDS) { // not a special decl
    683                 addId(decl, decl->name, idTable, handleConflicts, baseExpr, deleter);
     685                addIdToTable(decl, decl->name, idTable, handleConflicts, baseExpr, deleter);
    684686        }
    685687        else {
     
    694696                        assertf(false, "special decl with non-function type");
    695697                }
    696                 addId(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter);
    697         }
    698 }
    699 
    700 void SymbolTable::addId(
    701                 const DeclWithType * decl, const std::string & lookupKey, IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts, const Expr * baseExpr,
    702                 const Decl * deleter ) {
     698                addIdToTable(decl, key, specialFunctionTable[kind], handleConflicts, baseExpr, deleter);
     699        }
     700}
     701
     702void SymbolTable::addIdToTable(
     703                const DeclWithType * decl, const std::string & lookupKey,
     704                IdTable::Ptr & table, SymbolTable::OnConflict handleConflicts,
     705                const Expr * baseExpr, const Decl * deleter ) {
    703706        ++*stats().add_calls;
    704707        const std::string &name = decl->name;
     
    777780void SymbolTable::addMembers(
    778781                const AggregateDecl * aggr, const Expr * expr, SymbolTable::OnConflict handleConflicts ) {
    779         for ( const Decl * decl : aggr->members ) {
    780                 if ( auto dwt = dynamic_cast< const DeclWithType * >( decl ) ) {
    781                         addId( dwt, handleConflicts, expr );
    782                         if ( dwt->name == "" ) {
    783                                 const Type * t = dwt->get_type()->stripReferences();
    784                                 if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) {
    785                                         if ( ! dynamic_cast<const StructInstType *>(rty)
    786                                                 && ! dynamic_cast<const UnionInstType *>(rty) ) continue;
    787                                         ResolvExpr::Cost cost = ResolvExpr::Cost::zero;
    788                                         ast::ptr<ast::TypeSubstitution> tmp = expr->env;
    789                                         expr = mutate_field(expr, &Expr::env, nullptr);
    790                                         const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost );
    791                                         base = mutate_field(base, &Expr::env, tmp);
    792 
    793                                         addMembers(
    794                                                 rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts );
    795                                 }
    796                         }
     782        for ( const ptr<Decl> & decl : aggr->members ) {
     783                auto dwt = decl.as<DeclWithType>();
     784                if ( nullptr == dwt ) continue;
     785                addIdCommon( dwt, handleConflicts, expr );
     786                // Inline through unnamed struct/union members.
     787                if ( "" != dwt->name ) continue;
     788                const Type * t = dwt->get_type()->stripReferences();
     789                if ( auto rty = dynamic_cast<const BaseInstType *>( t ) ) {
     790                        if ( ! dynamic_cast<const StructInstType *>(rty)
     791                                && ! dynamic_cast<const UnionInstType *>(rty) ) continue;
     792                        ResolvExpr::Cost cost = ResolvExpr::Cost::zero;
     793                        ast::ptr<ast::TypeSubstitution> tmp = expr->env;
     794                        expr = mutate_field(expr, &Expr::env, nullptr);
     795                        const Expr * base = ResolvExpr::referenceToRvalueConversion( expr, cost );
     796                        base = mutate_field(base, &Expr::env, tmp);
     797
     798                        addMembers(
     799                                rty->aggr(), new MemberExpr{ base->location, dwt, base }, handleConflicts );
    797800                }
    798801        }
Note: See TracChangeset for help on using the changeset viewer.