Changes in / [36354b1:292d599b]
- Location:
- src/AST
- Files:
-
- 2 deleted
- 10 edited
-
Bitfield.hpp (modified) (1 diff)
-
Decl.cpp (modified) (2 diffs)
-
Decl.hpp (modified) (4 diffs)
-
FunctionSpec.hpp (deleted)
-
Init.hpp (deleted)
-
Label.hpp (modified) (2 diffs)
-
LinkageSpec.cpp (modified) (1 diff)
-
LinkageSpec.hpp (modified) (1 diff)
-
Node.hpp (modified) (1 diff)
-
ParseNode.hpp (modified) (1 diff)
-
StorageClasses.hpp (modified) (1 diff)
-
porting.md (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Bitfield.hpp
r36354b1 r292d599b 19 19 20 20 /// 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 22 22 /// does not allow it. Requires type to have `unsigned val` field 23 23 /// @param BFType Name of containing type -
src/AST/Decl.cpp
r36354b1 r292d599b 14 14 // 15 15 16 #include <cassert> // for assert, strict_dynamic_cast17 16 #include <unordered_map> 18 17 19 18 #include "Decl.hpp" 20 19 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 24 22 25 23 namespace ast { 26 27 24 // To canonicalize declarations 28 25 static UniqueId lastUniqueId = 0; … … 42 39 return {}; 43 40 } 44 45 // --- EnumDecl46 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 77 41 } 78 42 -
src/AST/Decl.hpp
r36354b1 r292d599b 16 16 #pragma once 17 17 18 #include <string> // for string, to_string 19 #include <unordered_map> 18 #include <string> 20 19 #include <vector> 21 20 22 #include "FunctionSpec.hpp"23 21 #include "Fwd.hpp" // for UniqueId 24 22 #include "LinkageSpec.hpp" … … 26 24 #include "ParseNode.hpp" 27 25 #include "StorageClasses.hpp" 28 #include "Type.hpp" // for Type, ptr<Type>29 26 #include "Visitor.hpp" 30 #include "Parser/ParseNode.h" // for DeclarationNode::Aggregate31 27 32 28 namespace ast { 33 34 29 class Attribute; 35 30 class Expr; 36 class Init;37 class TypeDecl;38 31 39 32 /// Base declaration class … … 46 39 bool extension = false; 47 40 48 Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 41 Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 49 42 Linkage::Spec linkage ) 50 43 : ParseNode( loc ), name( name ), storage( storage ), linkage( linkage ) {} … … 68 61 /// This field is generated by SymTab::Validate::Pass2 69 62 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. 71 64 /// Used to access shadowed identifiers. 72 65 int scopeLevel = 0; 73 66 74 67 std::vector<ptr<Attribute>> attributes; 75 Function::Specs funcSpec ;68 Function::Specs funcSpecs; 76 69 ptr<Expr> asmName; 77 70 bool isDeleted = false; 78 71 79 DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 72 DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 80 73 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() {} 205 76 }; 206 77 -
src/AST/Label.hpp
r36354b1 r292d599b 34 34 std::vector< ptr<Attribute> > attributes; 35 35 36 Label( CodeLocation loc, const std::string& name = "", 36 Label( CodeLocation loc, const std::string& name = "", 37 37 const std::vector<ptr<Attribute>>& attrs = std::vector<ptr<Attribute>>{} ) 38 38 : location( loc ), name( name ), attributes( attrs ) {} … … 47 47 48 48 inline std::ostream& operator<< ( std::ostream& out, const Label& l ) { return out << l.name; } 49 49 50 50 } 51 51 -
src/AST/LinkageSpec.cpp
r36354b1 r292d599b 24 24 25 25 namespace 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 26 41 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 } 28 54 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 lexer32 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 }41 55 } 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 59 56 } 60 57 -
src/AST/LinkageSpec.hpp
r36354b1 r292d599b 23 23 namespace ast { 24 24 25 namespace Linkage {25 namespace Linkage { 26 26 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 45 34 }; 46 35 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 }; 49 46 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 }; 53 49 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 ); 56 53 57 // Pre-defined flag combinations 54 /// A human-readable name for this spec 55 std::string name( Spec spec ); 58 56 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 } 75 74 } 76 75 -
src/AST/Node.hpp
r36354b1 r292d599b 27 27 class Node { 28 28 public: 29 // override defaults to ensure assignment doesn't 29 // override defaults to ensure assignment doesn't 30 30 // change/share reference counts 31 31 Node() = default; -
src/AST/ParseNode.hpp
r36354b1 r292d599b 28 28 29 29 // 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 31 31 // this should be used sparingly. 32 32 -
src/AST/StorageClasses.hpp
r36354b1 r292d599b 20 20 namespace ast { 21 21 22 namespace Storage {22 namespace Storage { 23 23 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 43 32 }; 44 33 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 }; 48 44 49 } 45 MakeBitfield( Classes ) 46 MakeBitfieldPrint( NumClasses ) 47 }; 48 49 } 50 50 } 51 51 -
src/AST/porting.md
r36354b1 r292d599b 55 55 * Preserve names from previous AST whenever reasonable, and get team consensus on any changes. 56 56 * Strong justification required for private fields 57 * No `get_` prefix on getters (including for generated fields)57 * No `get_` prefix on getters 58 58 * Notable changes: 59 59 * for concision and consistency with subclasses: 60 60 * `Declaration` => `ast::Decl` 61 * `DeclarationWithType` => `ast::DeclWithType` 61 * `DeclarationWithType` => `ast::DeclWithType` 62 62 * `Expression` => `ast::Expr` 63 63 * `Initializer` => `ast::Init` … … 81 81 `DeclWithType` 82 82 * 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 mutated85 * still with `get_` name so it doesn't conflict with subclass field names86 87 `ObjectDecl`88 * changed constructor parameter order for better defaults89 * allows `newObject` as just default settings90 91 `EnumDecl`92 * **TODO** rebuild `eval` for new AST (re: `valueOf` implementation)93 83 94 84 `Expr`
Note:
See TracChangeset
for help on using the changeset viewer.