Changeset 13edbac


Ignore:
Timestamp:
Oct 28, 2022, 5:12:26 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master
Children:
be5f0a5
Parents:
2856982c (diff), fa2e183 (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

Files:
1 added
26 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Convert.cpp

    r2856982c r13edbac  
    234234                }
    235235                return declWithTypePostamble( decl, node );
     236        }
     237
     238        // InlineValueDecl vanish after EnumAndPointerDecay pass so no necessary to implement NewToOld
     239        const ast::DeclWithType * visit( const ast::InlineValueDecl * node ) override final {   
     240                assert( false );
     241                (void) node;
     242                return nullptr;
    236243        }
    237244
     
    18631870        }
    18641871
     1872        virtual void visit( const InlineValueDecl * old ) override final {
     1873                if ( inCache( old ) ) {
     1874                        return;
     1875                }
     1876                auto&& type = GET_ACCEPT_1(type, Type);
     1877                auto&& attr = GET_ACCEPT_V(attributes, Attribute);
     1878 
     1879                auto decl = new ast::InlineValueDecl(
     1880                        old->location,
     1881                        old->name,
     1882                        type,
     1883                        { old->get_storageClasses().val },
     1884                        { old->linkage.val },
     1885                        std::move(attr),
     1886                        { old->get_funcSpec().val }
     1887                );
     1888                cache.emplace(old, decl);
     1889                assert(cache.find( old ) != cache.end());
     1890                decl->scopeLevel = old->scopeLevel;
     1891                decl->mangleName = old->mangleName;
     1892                decl->isDeleted  = old->isDeleted;
     1893                decl->asmName    = GET_ACCEPT_1(asmName, Expr);
     1894                decl->uniqueId   = old->uniqueId;
     1895                decl->extension  = old->extension;
     1896
     1897                this->node = decl;
     1898        }
     1899
    18651900        virtual void visit( const CompoundStmt * old ) override final {
    18661901                if ( inCache( old ) ) return;
  • src/AST/Decl.hpp

    r2856982c r13edbac  
    414414};
    415415
     416class InlineValueDecl final : public DeclWithType {
     417public:
     418        ptr<Type> type;
     419
     420        InlineValueDecl( const CodeLocation & loc, const std::string & name, const Type * type,
     421                Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::Cforall,
     422                std::vector< ptr<Attribute> > && attrs = {}, Function::Specs fs = {} )
     423        : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ) {}
     424
     425        const Type * get_type() const override { return type; }
     426        void set_type( const Type * ty ) override { type = ty; }
     427
     428        const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); }
     429private:
     430        InlineValueDecl * clone() const override { return new InlineValueDecl{ *this }; }
     431        MUTATE_FRIEND
     432};
    416433}
    417434
  • src/AST/Fwd.hpp

    r2856982c r13edbac  
    3737class DirectiveDecl;
    3838class StaticAssertDecl;
     39class InlineValueDecl;
    3940
    4041class Stmt;
  • src/AST/Pass.hpp

    r2856982c r13edbac  
    141141        const ast::DirectiveDecl *    visit( const ast::DirectiveDecl        * ) override final;
    142142        const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) override final;
     143        const ast::DeclWithType *     visit( const ast::InlineValueDecl      * ) override final;
    143144        const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) override final;
    144145        const ast::Stmt *             visit( const ast::ExprStmt             * ) override final;
  • src/AST/Pass.impl.hpp

    r2856982c r13edbac  
    803803
    804804//--------------------------------------------------------------------------
     805// DeclWithType
     806template< typename core_t >
     807const ast::DeclWithType * ast::Pass< core_t >::visit( const ast::InlineValueDecl * node ) {
     808        VISIT_START( node );
     809
     810        if ( __visit_children() ) {
     811                {
     812                        guard_symtab guard { *this };
     813                        maybe_accept( node, &InlineValueDecl::type );
     814                }
     815        }
     816
     817        VISIT_END( DeclWithType, node );
     818}
     819
     820//--------------------------------------------------------------------------
    805821// CompoundStmt
    806822template< typename core_t >
  • src/AST/Print.cpp

    r2856982c r13edbac  
    398398        virtual const ast::Decl * visit( const ast::StructDecl * node ) override final {
    399399                print(node);
     400                return node;
     401        }
     402
     403        virtual const ast::DeclWithType * visit( const ast::InlineValueDecl * node ) override final {
     404                os << "inline ";
     405                if ( ! node->name.empty() ) os << node->name;
     406
    400407                return node;
    401408        }
  • src/AST/Visitor.hpp

    r2856982c r13edbac  
    3333    virtual const ast::DirectiveDecl *    visit( const ast::DirectiveDecl        * ) = 0;
    3434    virtual const ast::StaticAssertDecl * visit( const ast::StaticAssertDecl     * ) = 0;
     35    virtual const ast::DeclWithType *     visit( const ast::InlineValueDecl      * ) = 0;
    3536    virtual const ast::CompoundStmt *     visit( const ast::CompoundStmt         * ) = 0;
    3637    virtual const ast::Stmt *             visit( const ast::ExprStmt             * ) = 0;
  • src/Common/CodeLocationTools.cpp

    r2856982c r13edbac  
    111111    macro(DirectiveDecl, DirectiveDecl) \
    112112    macro(StaticAssertDecl, StaticAssertDecl) \
     113    macro(InlineValueDecl, DeclWithType) \
    113114    macro(CompoundStmt, CompoundStmt) \
    114115    macro(ExprStmt, Stmt) \
  • src/Common/PassVisitor.h

    r2856982c r13edbac  
    8181        virtual void visit( StaticAssertDecl * assertDecl ) override final;
    8282        virtual void visit( const StaticAssertDecl * assertDecl ) override final;
     83        virtual void visit( InlineValueDecl * valueDecl ) override final;
     84        virtual void visit( const InlineValueDecl * valueDecl ) override final;
    8385
    8486        virtual void visit( CompoundStmt * compoundStmt ) override final;
     
    273275        virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) override final;
    274276        virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) override final;
     277        virtual DeclarationWithType * mutate( InlineValueDecl * valueDecl ) override final;
    275278
    276279        virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) override final;
  • src/Common/PassVisitor.impl.h

    r2856982c r13edbac  
    10471047
    10481048//--------------------------------------------------------------------------
     1049// InlineValueDecl
     1050template< typename pass_type >
     1051void PassVisitor< pass_type >::visit( InlineValueDecl * node ) {
     1052        VISIT_START( node );
     1053
     1054        maybeAccept_impl( node->type, *this );
     1055
     1056        VISIT_END( node );
     1057}
     1058
     1059template< typename pass_type >
     1060void PassVisitor< pass_type >::visit( const InlineValueDecl * node ) {
     1061        VISIT_START( node );
     1062
     1063        maybeAccept_impl( node->type, *this );
     1064
     1065        VISIT_END( node );
     1066}
     1067
     1068template< typename pass_type >
     1069DeclarationWithType * PassVisitor< pass_type >::mutate( InlineValueDecl * node ) {
     1070        MUTATE_START( node );
     1071
     1072        maybeMutate_impl( node->type, *this );
     1073
     1074        MUTATE_END( DeclarationWithType, node );
     1075}
     1076
     1077//--------------------------------------------------------------------------
    10491078// CompoundStmt
    10501079template< typename pass_type >
  • src/Parser/DeclarationNode.cc

    r2856982c r13edbac  
    2727#include "SynTree/LinkageSpec.h"   // for Spec, linkageName, Cforall
    2828#include "SynTree/Attribute.h"     // for Attribute
    29 #include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, Declaration
     29#include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, InlineValueDecl, Declaration
    3030#include "SynTree/Expression.h"    // for Expression, ConstantExpr
    3131#include "SynTree/Statement.h"     // for AsmStmt
     
    11651165                SemanticError( this, "invalid function specifier for " );
    11661166        } // if
     1167        if ( enumInLine ) {
     1168                return new InlineValueDecl( *name, storageClasses, linkage, nullptr );
     1169        } // if
    11671170        assertf( name, "ObjectDecl must a have name\n" );
    11681171        return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild< Expression >( bitfieldWidth ), nullptr, maybeBuild< Initializer >( initializer ) ))->set_asmName( asmName )->set_extension( extension );
  • src/Parser/ExpressionNode.cc

    r2856982c r13edbac  
    519519                }
    520520        }
    521         auto ret =  new QualifiedNameExpr( newDecl, name->name );
    522         if ( auto e = dynamic_cast<EnumDecl*>(newDecl) ) {
    523                 auto enumInst = new EnumInstType( Type::Qualifiers(), e );
    524                 auto obj = new ObjectDecl( name->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, enumInst, nullptr );
    525         }
    526         return ret;
     521        return new QualifiedNameExpr( newDecl, name->name );
    527522}
    528523
  • src/Parser/TypeData.cc

    r2856982c r13edbac  
    925925        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
    926926                if ( cur->enumInLine ) {
    927                         // Tell the compiler this is a inline value placeholder
    928                         ObjectDecl * member = dynamic_cast< ObjectDecl* >(* members);
    929                         member->enumInLine = true;
    930                 }
    931                 if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
     927                        // Do Nothing
     928                } else if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) {
    932929                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
    933930                } else if ( cur->has_enumeratorValue() ) {
  • src/ResolvExpr/CommonType.cc

    r2856982c r13edbac  
    991991                                add_qualifiers( result, type2->qualifiers );
    992992                        } else {
    993                                 // xxx - does unifying a ref with typed enumInst makes sense?
    994993                                if (!dynamic_cast<const ast::EnumInstType *>(type2))
    995994                                        result = commonType( type2, ref, tenv, need, have, open, widen, symtab );
     
    10101009
    10111010                void postvisit( const ast::EnumInstType * enumInst ) {
    1012                         // reuse BasicType/EnumInstType common type by swapping
    1013                         // xxx - is this already handled by unify?
    10141011                        if (!dynamic_cast<const ast::EnumInstType *>(type2))
    10151012                                result = commonType( type2, enumInst, tenv, need, have, open, widen, symtab);
  • src/ResolvExpr/ConversionCost.cc

    r2856982c r13edbac  
    720720                costCalc( baseType, dst, srcIsLvalue, symtab, env );
    721721        } else {
    722                 (void)enumInstType;
    723722                static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };
    724723                cost = costCalc( integer, dst, srcIsLvalue, symtab, env );
  • src/SynTree/Declaration.h

    r2856982c r13edbac  
    449449};
    450450
     451
     452class InlineValueDecl : public DeclarationWithType {
     453        typedef DeclarationWithType Parent;
     454  public:
     455        Type * type;
     456
     457        InlineValueDecl( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, Type * type,
     458                                const std::list< Attribute * > attributes = std::list< Attribute * >(), Type::FuncSpecifiers fs = Type::FuncSpecifiers() );
     459        InlineValueDecl( const InlineValueDecl & other );
     460        virtual ~InlineValueDecl();
     461
     462        virtual Type * get_type() const override { return type; }
     463        virtual void set_type(Type * newType) override { type = newType; }
     464
     465        static InlineValueDecl * newInlineValueDecl( const std::string & name, Type * type );
     466
     467        virtual InlineValueDecl * clone() const override { return new InlineValueDecl( *this ); }
     468        virtual void accept( Visitor & v ) override { v.visit( this ); }
     469        virtual void accept( Visitor & v ) const override { v.visit( this ); }
     470        virtual DeclarationWithType * acceptMutator( Mutator & m )  override { return m.mutate( this ); }
     471        virtual void print( std::ostream & os, Indenter indent = {} ) const override;
     472        virtual void printShort( std::ostream & os, Indenter indent = {} ) const override;
     473
     474};
     475
    451476std::ostream & operator<<( std::ostream & os, const TypeDecl::Data & data );
    452477
  • src/SynTree/Mutator.h

    r2856982c r13edbac  
    3636        virtual DirectiveDecl * mutate( DirectiveDecl * directiveDecl ) = 0;
    3737        virtual StaticAssertDecl * mutate( StaticAssertDecl * assertDecl ) = 0;
     38        virtual DeclarationWithType * mutate( InlineValueDecl * inlineValueDecl ) = 0;
    3839
    3940        virtual CompoundStmt * mutate( CompoundStmt * compoundStmt ) = 0;
  • src/SynTree/SynTree.h

    r2856982c r13edbac  
    3838class DirectiveDecl;
    3939class StaticAssertDecl;
     40class InlineValueDecl;
    4041
    4142class Statement;
  • src/SynTree/Visitor.h

    r2856982c r13edbac  
    4949        virtual void visit( StaticAssertDecl * node ) { visit( const_cast<const StaticAssertDecl *>(node) ); }
    5050        virtual void visit( const StaticAssertDecl * assertDecl ) = 0;
     51        virtual void visit( InlineValueDecl * node ) { visit( const_cast<const InlineValueDecl *>(node) ); }
     52        virtual void visit( const InlineValueDecl * valueDecl ) = 0;
    5153
    5254        virtual void visit( CompoundStmt * node ) { visit( const_cast<const CompoundStmt *>(node) ); }
  • src/SynTree/module.mk

    r2856982c r13edbac  
    4242      SynTree/Initializer.cc \
    4343      SynTree/Initializer.h \
     44      SynTree/InlineValueDecl.cc \
    4445      SynTree/Label.h \
    4546      SynTree/LinkageSpec.cc \
  • src/Validate/EnumAndPointerDecay.cpp

    r2856982c r13edbac  
    2121#include "AST/Type.hpp"
    2222#include "SymTab/FixFunction.h"
     23#include "Validate/NoIdSymbolTable.hpp"
    2324
    2425namespace Validate {
     
    2627namespace {
    2728
    28 struct EnumAndPointerDecayCore final : public ast::WithCodeLocation {
     29struct EnumAndPointerDecayCore final : public WithNoIdSymbolTable, public ast::WithCodeLocation {
    2930        ast::EnumDecl const * previsit( ast::EnumDecl const * decl );
    3031        ast::FunctionDecl const * previsit( ast::FunctionDecl const * decl );
     
    3940        // Set the type of each member of the enumeration to be EnumContant.
    4041        auto mut = ast::mutate( decl );
    41         for ( ast::ptr<ast::Decl> & member : mut->members ) {
    42                 ast::ObjectDecl const * object = member.strict_as<ast::ObjectDecl>();
    43                 member = ast::mutate_field( object, &ast::ObjectDecl::type,
    44                         new ast::EnumInstType( decl, ast::CV::Const ) );
     42        std::vector<ast::ptr<ast::Decl>> buffer;
     43        for ( auto it = decl->members.begin(); it != decl->members.end(); ++it ) {
     44                if ( ast::ObjectDecl const * object = (*it).as<ast::ObjectDecl>() ) {
     45                        buffer.push_back( ast::mutate_field( object, &ast::ObjectDecl::type, new ast::EnumInstType( decl, ast::CV::Const ) ) );
     46                } else if ( ast::InlineValueDecl const * value = (*it).as<ast::InlineValueDecl>() ) {
     47                        if ( auto targetEnum = symtab.lookupEnum( value->name ) ) {
     48                                for ( auto singleMember : targetEnum->members ) {
     49                                        auto copyingMember = singleMember.as<ast::ObjectDecl>();
     50                                        buffer.push_back( new ast::ObjectDecl(
     51                                                value->location, // use the "inline" location
     52                                                copyingMember->name,
     53                                                new ast::EnumInstType( decl, ast::CV::Const ),
     54                                                // Construct a new EnumInstType as the type
     55                                                copyingMember->init,
     56                                                copyingMember->storage,
     57                                                copyingMember->linkage,
     58                                                copyingMember->bitfieldWidth,
     59                                                {},
     60                                                copyingMember->funcSpec
     61                                        ) );
     62                                }
     63                        }
     64                }
    4565        }
     66        mut->members = buffer;
    4667        return mut;
    4768}
  • src/Validate/LinkReferenceToTypes.cpp

    r2856982c r13edbac  
    185185                                decl = mut;
    186186                        }
     187                        // visit the base
    187188                } else if ( auto ptr = decl->base.as<ast::PointerType>() ) {
    188189                        if ( auto base = ptr->base.as<ast::TypeInstType>() ) {
     
    203204
    204205        // The following section
    205         auto mut = ast::mutate( decl );
    206         std::vector<ast::ptr<ast::Decl>> buffer;
    207         for ( auto it = decl->members.begin(); it != decl->members.end(); ++it) {
    208                 auto member = (*it).as<ast::ObjectDecl>();
    209                 if ( member->enumInLine ) {
    210                         auto targetEnum = symtab.lookupEnum( member->name );
    211                         if ( targetEnum ) {                     
    212                                 for ( auto singleMamber : targetEnum->members ) {
    213                                         auto tm = singleMamber.as<ast::ObjectDecl>();
    214                                         auto t = new ast::ObjectDecl(
    215                                                 member->location, // use the "inline" location
    216                                                 tm->name,
    217                                                 new ast::EnumInstType( decl, ast::CV::Const ),
    218                                                 // Construct a new EnumInstType as the type
    219                                                 tm->init,
    220                                                 tm->storage,
    221                                                 tm->linkage,
    222                                                 tm->bitfieldWidth,
    223                                                 {}, // enum member doesn't have attribute
    224                                                 tm->funcSpec
    225                                         );
    226                                         t->importValue = true;
    227                                         buffer.push_back(t);
    228                                 }
    229                         }
    230                 } else {
    231                         auto search_it = std::find_if( buffer.begin(), buffer.end(), [member](ast::ptr<ast::Decl> cur) {
    232                                 auto curAsObjDecl = cur.as<ast::ObjectDecl>();
    233                                 return (curAsObjDecl->importValue) && (curAsObjDecl->name == member->name);
    234                         });
    235                         if ( search_it != buffer.end() ) {
    236                                 buffer.erase( search_it ); // Found an import enum value that has the same name
    237                                 // override the imported value
    238                         }
    239                         buffer.push_back( *it );
    240                 }
    241         }
    242         mut->members = buffer;
    243         decl = mut;
    244206
    245207        ForwardEnumsType::iterator fwds = forwardEnums.find( decl->name );
  • tests/enum_tests/.expect/enumInlineValue.txt

    r2856982c r13edbac  
    11enumB.A is 5
    2 enumB.B is 10
     2enumB.B is 6
    33enumB.D is 11
    44enumB.E is 12
  • tests/enum_tests/.expect/qualifiedEnum.cfa

    r2856982c r13edbac  
    1 l :0
     1l :1
  • tests/enum_tests/enumInlineValue.cfa

    r2856982c r13edbac  
    66enum enumB {
    77    inline enumA,
    8     E, B=10
     8    E
    99};
    1010
  • tests/enum_tests/qualifiedEnum.cfa

    r2856982c r13edbac  
    88
    99int main() {
    10     enum Level l = Level.LOW;
     10    enum Level l = Level.MEDIUM;
    1111    sout | "l :" | l;
    1212    return 0;
Note: See TracChangeset for help on using the changeset viewer.