Changes in / [36354b1:292d599b]


Ignore:
Location:
src/AST
Files:
2 deleted
10 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Bitfield.hpp

    r36354b1 r292d599b  
    1919
    2020/// Make a type a bitfield.
    21 /// Include in type definition to add operators. Used to simulate inheritance because union
     21/// Include in type definition to add operators. Used to simulate inheritance because union 
    2222/// does not allow it. Requires type to have `unsigned val` field
    2323/// @param BFType  Name of containing type
  • src/AST/Decl.cpp

    r36354b1 r292d599b  
    1414//
    1515
    16 #include <cassert>        // for assert, strict_dynamic_cast
    1716#include <unordered_map>
    1817
    1918#include "Decl.hpp"
    2019
    21 #include "Fwd.hpp"        // for UniqueId
    22 #include "Init.hpp"
    23 #include "Node.hpp"       // for readonly
     20#include "Fwd.hpp"   // for UniqueId
     21#include "Node.hpp"  // for readonly
    2422
    2523namespace ast {
    26 
    2724// To canonicalize declarations
    2825static UniqueId lastUniqueId = 0;
     
    4239        return {};
    4340}
    44 
    45 // --- EnumDecl
    46 
    47 bool 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 
    7741}
    7842
  • src/AST/Decl.hpp

    r36354b1 r292d599b  
    1616#pragma once
    1717
    18 #include <string>              // for string, to_string
    19 #include <unordered_map>
     18#include <string>
    2019#include <vector>
    2120
    22 #include "FunctionSpec.hpp"
    2321#include "Fwd.hpp"             // for UniqueId
    2422#include "LinkageSpec.hpp"
     
    2624#include "ParseNode.hpp"
    2725#include "StorageClasses.hpp"
    28 #include "Type.hpp"            // for Type, ptr<Type>
    2926#include "Visitor.hpp"
    30 #include "Parser/ParseNode.h"  // for DeclarationNode::Aggregate
    3127
    3228namespace ast {
    33 
    3429class Attribute;
    3530class Expr;
    36 class Init;
    37 class TypeDecl;
    3831
    3932/// Base declaration class
     
    4639        bool extension = false;
    4740
    48         Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
     41        Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 
    4942                Linkage::Spec linkage )
    5043        : ParseNode( loc ), name( name ), storage( storage ), linkage( linkage ) {}
     
    6861        /// This field is generated by SymTab::Validate::Pass2
    6962        std::string mangleName;
    70         /// Stores the scope level at which the variable was declared.
     63        /// Stores the scope level at which the variable was declared. 
    7164        /// Used to access shadowed identifiers.
    7265        int scopeLevel = 0;
    7366
    7467        std::vector<ptr<Attribute>> attributes;
    75         Function::Specs funcSpec;
     68        Function::Specs funcSpecs;
    7669        ptr<Expr> asmName;
    7770        bool isDeleted = false;
    7871
    79         DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
     72        DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 
    8073                Linkage::Spec linkage, std::vector<ptr<Attribute>>&& attrs, Function::Specs fs )
    81         : Decl( loc, name, storage, linkage ), mangleName(), attributes( std::move(attrs) ),
    82                 funcSpec(fs), asmName() {}
    83 
    84         std::string scopedMangleName() const { return mangleName + "_" + std::to_string(scopeLevel); }
    85 
    86         /// Get type of this declaration. May be generated by subclass
    87         virtual const Type* get_type() const = 0;
    88         /// Set type of this declaration. May be verified by subclass
    89         virtual void set_type(Type*) = 0;
    90 
    91         virtual DeclWithType* accept( Visitor& v ) override = 0;
    92 private:
    93         virtual DeclWithType* clone() const override = 0;
    94 };
    95 
    96 /// Object declaration `Foo foo = 42;`
    97 class ObjectDecl final : public DeclWithType {
    98 public:
    99         ptr<Type> type;
    100         ptr<Init> init;
    101         ptr<Expr> bitfieldWidth;
    102 
    103         ObjectDecl( const CodeLocation& loc, const std::string& name, Type* type, Init* init = nullptr,
    104                 Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, Expr* bitWd = nullptr,
    105                 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {})
    106         : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ),
    107           init( init ), bitfieldWidth( bitWd ) {}
    108 
    109         const Type* get_type() const override { return type; }
    110         void set_type( Type* ty ) override { type = ty; }
    111 
    112         DeclWithType* accept( Visitor& v ) override { return v.visit( this ); }
    113 private:
    114         ObjectDecl* clone() const override { return new ObjectDecl{ *this }; }
    115 };
    116 
    117 /// Aggregate type declaration base class
    118 class AggregateDecl : public Decl {
    119 public:
    120         std::vector<ptr<Decl>> members;
    121         std::vector<ptr<TypeDecl>> parameters;
    122         std::vector<ptr<Attribute>> attributes;
    123         bool body = false;
    124         readonly<AggregateDecl> parent = {};
    125 
    126         AggregateDecl( const CodeLocation& loc, const std::string& name,
    127                 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    128         : Decl( loc, name, Storage::Classes{}, linkage ), members(), parameters(),
    129           attributes( std::move(attrs) ) {}
    130 
    131         AggregateDecl* set_body( bool b ) { body = b; return this; }
    132 
    133 protected:
    134         /// Produces a name for the kind of aggregate
    135         virtual std::string typeString() const = 0;
    136 };
    137 
    138 /// struct declaration `struct Foo { ... };`
    139 class StructDecl final : public AggregateDecl {
    140 public:
    141         DeclarationNode::Aggregate kind;
    142 
    143         StructDecl( const CodeLocation& loc, const std::string& name,
    144                 DeclarationNode::Aggregate kind = DeclarationNode::Struct,
    145                 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    146         : AggregateDecl( loc, name, std::move(attrs), linkage ), kind( kind ) {}
    147 
    148         bool is_coroutine() { return kind == DeclarationNode::Coroutine; }
    149         bool is_monitor() { return kind == DeclarationNode::Monitor; }
    150         bool is_thread() { return kind == DeclarationNode::Thread; }
    151 
    152         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    153 private:
    154         StructDecl* clone() const override { return new StructDecl{ *this }; }
    155 
    156         std::string typeString() const override { return "struct"; }
    157 };
    158 
    159 /// union declaration `union Foo { ... };`
    160 class UnionDecl final : public AggregateDecl {
    161 public:
    162         UnionDecl( const CodeLocation& loc, const std::string& name,
    163                 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    164         : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
    165 
    166         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    167 private:
    168         UnionDecl* clone() const override { return new UnionDecl{ *this }; }
    169 
    170         std::string typeString() const override { return "union"; }
    171 };
    172 
    173 /// enum declaration `enum Foo { ... };`
    174 class EnumDecl final : public AggregateDecl {
    175 public:
    176         EnumDecl( const CodeLocation& loc, const std::string& name,
    177                 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    178         : AggregateDecl( loc, name, std::move(attrs), linkage ), enumValues() {}
    179 
    180         /// gets the integer value for this enumerator, returning true iff value found
    181         bool valueOf( Decl* enumerator, long long& value ) const;
    182 
    183         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    184 private:
    185         EnumDecl* clone() const override { return new EnumDecl{ *this }; }
    186 
    187         std::string typeString() const override { return "enum"; }
    188 
    189         /// Map from names to enumerator values; kept private for lazy initialization
    190         mutable std::unordered_map< std::string, long long > enumValues;
    191 };
    192 
    193 /// trait declaration `trait Foo( ... ) { ... };`
    194 class TraitDecl final : public AggregateDecl {
    195 public:
    196         TraitDecl( const CodeLocation& loc, const std::string& name,
    197                 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall )
    198         : AggregateDecl( loc, name, std::move(attrs), linkage ) {}
    199 
    200         Decl* accept( Visitor& v ) override { return v.visit( this ); }
    201 private:
    202         TraitDecl* clone() const override { return new TraitDecl{ *this }; }
    203 
    204         std::string typeString() const override { return "trait"; }
     74        : Decl( loc, name, storage, linkage ), mangleName(), attributes( std::move(attrs) ),
     75                funcSpecs(fs), asmName() {}
    20576};
    20677
  • src/AST/Label.hpp

    r36354b1 r292d599b  
    3434                std::vector< ptr<Attribute> > attributes;
    3535
    36                 Label( CodeLocation loc, const std::string& name = "",
     36                Label( CodeLocation loc, const std::string& name = "", 
    3737                        const std::vector<ptr<Attribute>>& attrs = std::vector<ptr<Attribute>>{} )
    3838                : location( loc ), name( name ), attributes( attrs ) {}
     
    4747
    4848        inline std::ostream& operator<< ( std::ostream& out, const Label& l ) { return out << l.name; }
    49 
     49       
    5050}
    5151
  • src/AST/LinkageSpec.cpp

    r36354b1 r292d599b  
    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                        }
     39                }
     40       
    2641
    27 namespace Linkage {
     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                }
    2854
    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 );
    40                 }
    4155        }
    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         }
    56 
    57 }
    58 
    5956}
    6057
  • src/AST/LinkageSpec.hpp

    r36354b1 r292d599b  
    2323namespace ast {
    2424
    25 namespace Linkage {
     25        namespace 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
    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;
     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
    4534                };
    4635
    47                 MakeBitfield( Spec )
    48         };
     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                        };
    4946
    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 );
     47                        MakeBitfield( Spec )
     48                };
    5349
    54         /// A human-readable name for this spec
    55         std::string name( Spec spec );
     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 );
    5653
    57         // Pre-defined flag combinations
     54                /// A human-readable name for this spec
     55                std::string name( Spec spec );
    5856
    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 }
    74 
     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        }
    7574}
    7675
  • src/AST/Node.hpp

    r36354b1 r292d599b  
    2727class Node {
    2828public:
    29         // override defaults to ensure assignment doesn't
     29        // override defaults to ensure assignment doesn't 
    3030        // change/share reference counts
    3131        Node() = default;
  • src/AST/ParseNode.hpp

    r36354b1 r292d599b  
    2828
    2929                // Default constructor is deliberately omitted, all ParseNodes must have a location.
    30                 // Escape hatch if needed is to explicitly pass a default-constructed location, but
     30                // Escape hatch if needed is to explicitly pass a default-constructed location, but 
    3131                // this should be used sparingly.
    3232
  • src/AST/StorageClasses.hpp

    r36354b1 r292d599b  
    2020namespace ast {
    2121
    22 namespace Storage {
     22        namespace 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
    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;
     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
    4332                };
    4433
    45                 MakeBitfield( Classes )
    46                 MakeBitfieldPrint( NumClasses )
    47         };
     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                        };
    4844
    49 }
     45                        MakeBitfield( Classes )
     46                        MakeBitfieldPrint( NumClasses )
     47                };
     48
     49        }
    5050}
    5151
  • src/AST/porting.md

    r36354b1 r292d599b  
    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 (including for generated fields)
     57  * No `get_` prefix on getters
    5858* Notable changes:
    5959  * for concision and consistency with subclasses:
    6060    * `Declaration` => `ast::Decl`
    61         * `DeclarationWithType` => `ast::DeclWithType`
     61        * `DeclarationWithType` => `ast::DeclWithType` 
    6262        * `Expression` => `ast::Expr`
    6363        * `Initializer` => `ast::Init`
     
    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()` now returns `const Type*` so can't be inadvertently mutated
    85   * still with `get_` name so it doesn't conflict with subclass field names
    86 
    87 `ObjectDecl`
    88 * changed constructor parameter order for better defaults
    89   * allows `newObject` as just default settings
    90 
    91 `EnumDecl`
    92 * **TODO** rebuild `eval` for new AST (re: `valueOf` implementation)
    9383
    9484`Expr`
Note: See TracChangeset for help on using the changeset viewer.