Changeset 36354b1


Ignore:
Timestamp:
May 10, 2019, 12:09:05 PM (2 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr
Children:
9131e54, cdcd53dc
Parents:
292d599 (diff), 14cebb7a (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

Location:
src/AST
Files:
2 added
10 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Bitfield.hpp

    r292d599 r36354b1  
    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

    r292d599 r36354b1  
    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

    r292d599 r36354b1  
    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 Init;
     37class TypeDecl;
    3138
    3239/// Base declaration class
     
    3946        bool extension = false;
    4047
    41         Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 
     48        Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
    4249                Linkage::Spec linkage )
    4350        : ParseNode( loc ), name( name ), storage( storage ), linkage( linkage ) {}
     
    6168        /// This field is generated by SymTab::Validate::Pass2
    6269        std::string mangleName;
    63         /// Stores the scope level at which the variable was declared. 
     70        /// Stores the scope level at which the variable was declared.
    6471        /// Used to access shadowed identifiers.
    6572        int scopeLevel = 0;
    6673
    6774        std::vector<ptr<Attribute>> attributes;
    68         Function::Specs funcSpecs;
     75        Function::Specs funcSpec;
    6976        ptr<Expr> asmName;
    7077        bool isDeleted = false;
    7178
    72         DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 
     79        DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage,
    7380                Linkage::Spec linkage, std::vector<ptr<Attribute>>&& attrs, Function::Specs fs )
    74         : Decl( loc, name, storage, linkage ), mangleName(), attributes( std::move(attrs) ),
    75                 funcSpecs(fs), asmName() {}
     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;
     92private:
     93        virtual DeclWithType* clone() const override = 0;
     94};
     95
     96/// Object declaration `Foo foo = 42;`
     97class ObjectDecl final : public DeclWithType {
     98public:
     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 ); }
     113private:
     114        ObjectDecl* clone() const override { return new ObjectDecl{ *this }; }
     115};
     116
     117/// Aggregate type declaration base class
     118class AggregateDecl : public Decl {
     119public:
     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
     133protected:
     134        /// Produces a name for the kind of aggregate
     135        virtual std::string typeString() const = 0;
     136};
     137
     138/// struct declaration `struct Foo { ... };`
     139class StructDecl final : public AggregateDecl {
     140public:
     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 ); }
     153private:
     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 { ... };`
     160class UnionDecl final : public AggregateDecl {
     161public:
     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 ); }
     167private:
     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 { ... };`
     174class EnumDecl final : public AggregateDecl {
     175public:
     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 ); }
     184private:
     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( ... ) { ... };`
     194class TraitDecl final : public AggregateDecl {
     195public:
     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 ); }
     201private:
     202        TraitDecl* clone() const override { return new TraitDecl{ *this }; }
     203
     204        std::string typeString() const override { return "trait"; }
    76205};
    77206
  • src/AST/Label.hpp

    r292d599 r36354b1  
    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

    r292d599 r36354b1  
    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                }
    40        
     41        }
    4142
    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                         }
     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>";
    5354                }
     55        }
    5456
    55         }
     57}
     58
    5659}
    5760
  • src/AST/LinkageSpec.hpp

    r292d599 r36354b1  
    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
    5658
    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         }
     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
    7475}
    7576
  • src/AST/Node.hpp

    r292d599 r36354b1  
    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

    r292d599 r36354b1  
    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

    r292d599 r36354b1  
    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

    r292d599 r36354b1  
    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:
    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)
    8393
    8494`Expr`
Note: See TracChangeset for help on using the changeset viewer.