Changeset a300e4a


Ignore:
Timestamp:
May 9, 2019, 5:17:51 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
3e46cc8
Parents:
2bb4a01
Message:

Add some decls to the new AST

Location:
src/AST
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Decl.cpp

    r2bb4a01 ra300e4a  
    1414//
    1515
     16#include <cassert>        // for assert, strict_dynamic_cast
    1617#include <unordered_map>
    1718
    1819#include "Decl.hpp"
    1920
    20 #include "Fwd.hpp"   // for UniqueId
    21 #include "Node.hpp"  // for readonly
     21#include "Fwd.hpp"        // for UniqueId
     22#include "Init.hpp"
     23#include "Node.hpp"       // for readonly
    2224
    2325namespace ast {
     26
    2427// To canonicalize declarations
    2528static UniqueId lastUniqueId = 0;
     
    3942        return {};
    4043}
     44
     45// --- EnumDecl
     46
     47bool EnumDecl::valueOf( Decl* enumerator, long long& value ) const {
     48        if ( enumValues.empty() ) {
     49                long long crntVal = 0;
     50                for ( const Decl* member : members ) {
     51                        const ObjectDecl* field = strict_dynamic_cast< const ObjectDecl* >( member );
     52                        if ( field->init ) {
     53                                const SingleInit* init = strict_dynamic_cast< const SingleInit* >( field->init );
     54                                auto result = eval( init->value );
     55                                if ( ! result.second ) {
     56                                        SemanticError( init->location, toString( "Non-constexpr in initialization of "
     57                                                "enumerator: ", field ) );
     58                                }
     59                                crntVal = result.first;
     60                        }
     61                        if ( enumValues.count( field->name ) != 0 ) {
     62                                SemanticError( location, toString( "Enum ", name, " has multiple members with the "     "name ", field->name ) );
     63                        }
     64                        enumValues[ field->name ] = crntVal;
     65                        ++crntVal;
     66                }
     67        }
     68
     69        auto it = enumValues.find( enumerator->name );
     70        if ( it != enumValues.end() ) {
     71                value = it->second;
     72                return true;
     73        }
     74        return false;
     75}
     76
    4177}
    4278
  • src/AST/Decl.hpp

    r2bb4a01 ra300e4a  
    1616#pragma once
    1717
    18 #include <string>
     18#include <string>              // for string, to_string
     19#include <unordered_map>
    1920#include <vector>
    2021
     22#include "FunctionSpec.hpp"
    2123#include "Fwd.hpp"             // for UniqueId
    2224#include "LinkageSpec.hpp"
     
    2426#include "ParseNode.hpp"
    2527#include "StorageClasses.hpp"
     28#include "Type.hpp"            // for Type, ptr<Type>
    2629#include "Visitor.hpp"
     30#include "Parser/ParseNode.h"  // for DeclarationNode::Aggregate
    2731
    2832namespace ast {
     33
    2934class Attribute;
    3035class Expr;
     36class TypeDecl;
    3137
    3238/// Base declaration class
     
    6672
    6773        std::vector<ptr<Attribute>> attributes;
    68         Function::Specs funcSpecs;
     74        Function::Specs funcSpec;
    6975        ptr<Expr> asmName;
    7076        bool isDeleted = false;
     
    7379                Linkage::Spec linkage, std::vector<ptr<Attribute>>&& attrs, Function::Specs fs )
    7480        : Decl( loc, name, storage, linkage ), mangleName(), attributes( std::move(attrs) ),
    75                 funcSpecs(fs), asmName() {}
     81                funcSpec(fs), asmName() {}
     82       
     83        std::string scopedMangleName() const { return mangleName + "_" + std::to_string(scopeLevel); }
     84
     85        /// Get type of this declaration. May be generated by subclass
     86        virtual const Type* type() const = 0;
     87        /// Set type of this declaration. May be verified by subclass
     88        virtual void set_type(Type*) = 0;
     89
     90        virtual DeclWithType* accept( Visitor& v ) override = 0;
     91private:
     92        virtual DeclWithType* clone() const override = 0;
     93};
     94
     95/// Aggregate type declaration base class
     96class AggregateDecl : public Decl {
     97public:
     98        std::vector<ptr<Decl>> members;
     99        std::vector<ptr<TypeDecl>> parameters;
     100        std::vector<ptr<Attribute>> attributes;
     101        bool body = false;
     102        readonly<AggregateDecl> parent = {};
     103
     104        AggregateDecl( const CodeLocation& loc, const std::string& name,
     105                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
     106        : Decl( loc, name, Storage::Classes{}, linkage ), members(), parameters(),
     107          attributes( std::move(attrs) ) {}
     108       
     109        AggregateDecl* set_body( bool b ) { body = b; return this; }
     110
     111protected:
     112        /// Produces a name for the kind of aggregate
     113        virtual std::string typeString() const = 0;
     114};
     115
     116/// struct declaration `struct Foo { ... };`
     117class StructDecl final : public AggregateDecl {
     118public:
     119        DeclarationNode::Aggregate kind;
     120
     121        StructDecl( const CodeLocation& loc, const std::string& name,
     122                DeclarationNode::Aggregate kind = DeclarationNode::Struct,
     123                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
     124        : AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {}
     125
     126        bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
     127        bool is_monitor() { return kind == DeclarationNode::Monitor; }
     128        bool is_thread() { return kind == DeclarationNode::Thread; }
     129
     130        Decl* accept( Visitor& v ) override { return v.visit( this ); }
     131private:
     132        StructDecl* clone() const override { return new StructDecl{ *this }; }
     133
     134        std::string typeString() const override { return "struct"; }
     135};
     136
     137/// union declaration `union Foo { ... };`
     138class UnionDecl final : public AggregateDecl {
     139public:
     140        UnionDecl( const CodeLocation& loc, const std::string& name,
     141                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
     142        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
     143
     144        Decl* accept( Visitor& v ) override { return v.visit( this ); }
     145private:
     146        UnionDecl* clone() const override { return new UnionDecl{ *this }; }
     147
     148        std::string typeString() const override { return "union"; }
     149};
     150
     151/// enum declaration `enum Foo { ... };`
     152class EnumDecl final : public AggregateDecl {
     153public:
     154        EnumDecl( const CodeLocation& loc, const std::string& name,
     155                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
     156        : AggregateDecl( loc, name, std::move(attrs), linkage ), enumValues() {}
     157
     158        /// gets the integer value for this enumerator, returning true iff value found
     159        bool valueOf( Decl* enumerator, long long& value ) const;
     160
     161        Decl* accept( Visitor& v ) override { return v.visit( this ); }
     162private:
     163        EnumDecl* clone() const override { return new EnumDecl{ *this }; }
     164
     165        std::string typeString() const override { return "enum"; }
     166
     167        /// Map from names to enumerator values; kept private for lazy initialization
     168        mutable std::unordered_map< std::string, long long > enumValues;
     169};
     170
     171/// trait declaration `trait Foo( ... ) { ... };`
     172class TraitDecl final : public AggregateDecl {
     173public:
     174        TraitDecl( const CodeLocation& loc, const std::string& name,
     175                std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
     176        : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
     177
     178        Decl* accept( Visitor& v ) override { return v.visit( this ); }
     179private:
     180        TraitDecl* clone() const override { return new TraitDecl{ *this }; }
     181
     182        std::string typeString() const override { return "trait"; }
    76183};
    77184
  • src/AST/LinkageSpec.cpp

    r2bb4a01 ra300e4a  
    2424
    2525namespace ast {
    26         namespace Linkage {
    27                 Spec update( CodeLocation loc, Spec spec, const std::string * cmd ) {
    28                         assert( cmd );
    29                         std::unique_ptr<const std::string> guard( cmd ); // allocated by lexer
    30                         if ( *cmd == "\"Cforall\"" ) {
    31                                 spec.is_mangled = true;
    32                                 return spec;
    33                         } else if ( *cmd == "\"C\"" ) {
    34                                 spec.is_mangled = false;
    35                                 return spec;
    36                         } else {
    37                                 SemanticError( loc, "Invalid linkage specifier " + *cmd );
    38                         }
     26
     27namespace Linkage {
     28
     29        Spec update( CodeLocation loc, Spec spec, const std::string * cmd ) {
     30                assert( cmd );
     31                std::unique_ptr<const std::string> guard( cmd ); // allocated by lexer
     32                if ( *cmd == "\"Cforall\"" ) {
     33                        spec.is_mangled = true;
     34                        return spec;
     35                } else if ( *cmd == "\"C\"" ) {
     36                        spec.is_mangled = false;
     37                        return spec;
     38                } else {
     39                        SemanticError( loc, "Invalid linkage specifier " + *cmd );
    3940                }
     41        }
     42
     43
     44        std::string name( Spec spec ) {
     45                switch ( spec ) {
     46                case Intrinsic:  return "intrinsic";
     47                case C:          return "C";
     48                case Cforall:    return "Cforall";
     49                case AutoGen:    return "autogenerated cfa";
     50                case Compiler:   return "compiler built-in";
     51                case BuiltinCFA: return "cfa built-in";
     52                case BuiltinC:   return "c built-in";
     53                default:         return "<unnamed linkage spec>";
     54                }
     55        }
    4056       
     57}
    4158
    42                 std::string name( Spec spec ) {
    43                         switch ( spec ) {
    44                         case Intrinsic:  return "intrinsic";
    45                         case C:          return "C";
    46                         case Cforall:    return "Cforall";
    47                         case AutoGen:    return "autogenerated cfa";
    48                         case Compiler:   return "compiler built-in";
    49                         case BuiltinCFA: return "cfa built-in";
    50                         case BuiltinC:   return "c built-in";
    51                         default:         return "<unnamed linkage spec>";
    52                         }
    53                 }
    54 
    55         }
    5659}
    5760
  • src/AST/LinkageSpec.hpp

    r2bb4a01 ra300e4a  
    2323namespace ast {
    2424
    25         namespace Linkage {
     25namespace Linkage {
    2626
    27                 /// Bitflags for linkage specifiers
    28                 enum {
    29                         Mangle       = 1 << 0,
    30                         Generate     = 1 << 1,
    31                         Overrideable = 1 << 2,
    32                         Builtin      = 1 << 3,
    33                         GccBuiltin   = 1 << 4
     27        /// Bitflags for linkage specifiers
     28        enum {
     29                Mangle       = 1 << 0,
     30                Generate     = 1 << 1,
     31                Overrideable = 1 << 2,
     32                Builtin      = 1 << 3,
     33                GccBuiltin   = 1 << 4
     34        };
     35
     36        /// Bitflag type for storage classes
     37        union Spec {
     38                unsigned int val;
     39                struct {
     40                        bool is_mangled      : 1;
     41                        bool is_generatable  : 1;
     42                        bool is_overrideable : 1;
     43                        bool is_builtin      : 1;
     44                        bool is_gcc_builtin  : 1;
    3445                };
    3546
    36                 /// Bitflag type for storage classes
    37                 union Spec {
    38                         unsigned int val;
    39                         struct {
    40                                 bool is_mangled      : 1;
    41                                 bool is_generatable  : 1;
    42                                 bool is_overrideable : 1;
    43                                 bool is_builtin      : 1;
    44                                 bool is_gcc_builtin  : 1;
    45                         };
     47                MakeBitfield( Spec )
     48        };
    4649
    47                         MakeBitfield( Spec )
    48                 };
     50        /// If `cmd` = "C" returns `spec` with `is_mangled = false`.
     51        /// If `cmd` = "Cforall" returns `spec` with `is_mangled = true`.
     52        Spec update( CodeLocation loc, Spec spec, const std::string * cmd );
    4953
    50                 /// If `cmd` = "C" returns `spec` with `is_mangled = false`.
    51                 /// If `cmd` = "Cforall" returns `spec` with `is_mangled = true`.
    52                 Spec update( CodeLocation loc, Spec spec, const std::string * cmd );
     54        /// A human-readable name for this spec
     55        std::string name( Spec spec );
    5356
    54                 /// A human-readable name for this spec
    55                 std::string name( Spec spec );
     57        // Pre-defined flag combinations
     58       
     59        /// C built-in defined in prelude
     60        constexpr Spec Intrinsic  = { Mangle | Generate | Overrideable | Builtin };
     61        /// Ordinary Cforall
     62        constexpr Spec Cforall    = { Mangle | Generate };
     63        /// C code: not overloadable, not mangled
     64        constexpr Spec C          = { Generate };
     65        /// Built by translator (e.g. struct assignment)
     66        constexpr Spec AutoGen    = { Mangle | Generate | Overrideable };
     67        /// GCC internal
     68        constexpr Spec Compiler   = { Mangle | Builtin | GccBuiltin };
     69        /// Mangled builtins
     70        constexpr Spec BuiltinCFA = { Mangle | Generate | Builtin };
     71        /// Non-mangled builtins
     72        constexpr Spec BuiltinC   = { Generate | Builtin };
     73}
    5674
    57                 // Pre-defined flag combinations
    58                
    59                 /// C built-in defined in prelude
    60                 constexpr Spec Intrinsic  = { Mangle | Generate | Overrideable | Builtin };
    61                 /// Ordinary Cforall
    62                 constexpr Spec Cforall    = { Mangle | Generate };
    63                 /// C code: not overloadable, not mangled
    64                 constexpr Spec C          = { Generate };
    65                 /// Built by translator (e.g. struct assignment)
    66                 constexpr Spec AutoGen    = { Mangle | Generate | Overrideable };
    67                 /// GCC internal
    68                 constexpr Spec Compiler   = { Mangle | Builtin | GccBuiltin };
    69                 /// Mangled builtins
    70                 constexpr Spec BuiltinCFA = { Mangle | Generate | Builtin };
    71                 /// Non-mangled builtins
    72                 constexpr Spec BuiltinC   = { Generate | Builtin };
    73         }
    7475}
    7576
  • src/AST/StorageClasses.hpp

    r2bb4a01 ra300e4a  
    2020namespace ast {
    2121
    22         namespace Storage {
     22namespace Storage {
    2323
    24                 /// Bitflags for storage classes
    25                 enum {
    26                         Extern      = 1 << 0,
    27                         Static      = 1 << 1,
    28                         Auto        = 1 << 2,
    29                         Register    = 1 << 3,
    30                         ThreadLocal = 1 << 4,
    31                         NumClasses       = 5
     24        /// Bitflags for storage classes
     25        enum {
     26                Extern      = 1 << 0,
     27                Static      = 1 << 1,
     28                Auto        = 1 << 2,
     29                Register    = 1 << 3,
     30                ThreadLocal = 1 << 4,
     31                NumClasses       = 5
     32        };
     33
     34        /// Bitflag type for storage classes
     35        union Classes {
     36                unsigned int val;
     37                struct {
     38                        bool is_extern      : 1;
     39                        bool is_static      : 1;
     40                        bool is_auto        : 1;
     41                        bool is_register    : 1;
     42                        bool is_threadlocal : 1;
    3243                };
    3344
    34                 /// Bitflag type for storage classes
    35                 union Classes {
    36                         unsigned int val;
    37                         struct {
    38                                 bool is_extern      : 1;
    39                                 bool is_static      : 1;
    40                                 bool is_auto        : 1;
    41                                 bool is_register    : 1;
    42                                 bool is_threadlocal : 1;
    43                         };
     45                MakeBitfield( Classes )
     46                MakeBitfieldPrint( NumClasses )
     47        };
    4448
    45                         MakeBitfield( Classes )
    46                         MakeBitfieldPrint( NumClasses )
    47                 };
    48 
    49         }
     49}
    5050}
    5151
  • src/AST/porting.md

    r2bb4a01 ra300e4a  
    5555* Preserve names from previous AST whenever reasonable, and get team consensus on any changes.
    5656* Strong justification required for private fields
    57   * No `get_` prefix on getters
     57  * No `get_` prefix on getters (including for generated fields)
    5858* Notable changes:
    5959  * for concision and consistency with subclasses:
     
    8181`DeclWithType`
    8282* When `SymTab::Validate::Pass2` is rewritten, update comment on `mangleName` with new name of pass
     83* `get_scopedMangleName()` => `scopedMangleName()`
     84* `get_type()` => `type()`
     85  * now returns `const Type*` so can't be inadvertently mutated
     86
     87`EnumDecl`
     88* **TODO** rebuild `eval` for new AST (re: `valueOf` implementation)
    8389
    8490`Expr`
Note: See TracChangeset for help on using the changeset viewer.