Changeset a300e4a
- Timestamp:
- May 9, 2019, 5:17:51 PM (5 years ago)
- 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
- Location:
- src/AST
- Files:
-
- 2 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Decl.cpp
r2bb4a01 ra300e4a 14 14 // 15 15 16 #include <cassert> // for assert, strict_dynamic_cast 16 17 #include <unordered_map> 17 18 18 19 #include "Decl.hpp" 19 20 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 22 24 23 25 namespace ast { 26 24 27 // To canonicalize declarations 25 28 static UniqueId lastUniqueId = 0; … … 39 42 return {}; 40 43 } 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 41 77 } 42 78 -
src/AST/Decl.hpp
r2bb4a01 ra300e4a 16 16 #pragma once 17 17 18 #include <string> 18 #include <string> // for string, to_string 19 #include <unordered_map> 19 20 #include <vector> 20 21 22 #include "FunctionSpec.hpp" 21 23 #include "Fwd.hpp" // for UniqueId 22 24 #include "LinkageSpec.hpp" … … 24 26 #include "ParseNode.hpp" 25 27 #include "StorageClasses.hpp" 28 #include "Type.hpp" // for Type, ptr<Type> 26 29 #include "Visitor.hpp" 30 #include "Parser/ParseNode.h" // for DeclarationNode::Aggregate 27 31 28 32 namespace ast { 33 29 34 class Attribute; 30 35 class Expr; 36 class TypeDecl; 31 37 32 38 /// Base declaration class … … 66 72 67 73 std::vector<ptr<Attribute>> attributes; 68 Function::Specs funcSpec s;74 Function::Specs funcSpec; 69 75 ptr<Expr> asmName; 70 76 bool isDeleted = false; … … 73 79 Linkage::Spec linkage, std::vector<ptr<Attribute>>&& attrs, Function::Specs fs ) 74 80 : 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; 91 private: 92 virtual DeclWithType* clone() const override = 0; 93 }; 94 95 /// Aggregate type declaration base class 96 class AggregateDecl : public Decl { 97 public: 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 111 protected: 112 /// Produces a name for the kind of aggregate 113 virtual std::string typeString() const = 0; 114 }; 115 116 /// struct declaration `struct Foo { ... };` 117 class StructDecl final : public AggregateDecl { 118 public: 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 ); } 131 private: 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 { ... };` 138 class UnionDecl final : public AggregateDecl { 139 public: 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 ); } 145 private: 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 { ... };` 152 class EnumDecl final : public AggregateDecl { 153 public: 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 ); } 162 private: 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( ... ) { ... };` 172 class TraitDecl final : public AggregateDecl { 173 public: 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 ); } 179 private: 180 TraitDecl* clone() const override { return new TraitDecl{ *this }; } 181 182 std::string typeString() const override { return "trait"; } 76 183 }; 77 184 -
src/AST/LinkageSpec.cpp
r2bb4a01 ra300e4a 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 } 26 27 namespace 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 ); 39 40 } 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 } 40 56 57 } 41 58 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 }56 59 } 57 60 -
src/AST/LinkageSpec.hpp
r2bb4a01 ra300e4a 23 23 namespace ast { 24 24 25 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 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; 34 45 }; 35 46 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 }; 46 49 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 ); 49 53 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 ); 53 56 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 } 56 74 57 // Pre-defined flag combinations58 59 /// C built-in defined in prelude60 constexpr Spec Intrinsic = { Mangle | Generate | Overrideable | Builtin };61 /// Ordinary Cforall62 constexpr Spec Cforall = { Mangle | Generate };63 /// C code: not overloadable, not mangled64 constexpr Spec C = { Generate };65 /// Built by translator (e.g. struct assignment)66 constexpr Spec AutoGen = { Mangle | Generate | Overrideable };67 /// GCC internal68 constexpr Spec Compiler = { Mangle | Builtin | GccBuiltin };69 /// Mangled builtins70 constexpr Spec BuiltinCFA = { Mangle | Generate | Builtin };71 /// Non-mangled builtins72 constexpr Spec BuiltinC = { Generate | Builtin };73 }74 75 } 75 76 -
src/AST/StorageClasses.hpp
r2bb4a01 ra300e4a 20 20 namespace ast { 21 21 22 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 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; 32 43 }; 33 44 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 }; 44 48 45 MakeBitfield( Classes ) 46 MakeBitfieldPrint( NumClasses ) 47 }; 48 49 } 49 } 50 50 } 51 51 -
src/AST/porting.md
r2bb4a01 ra300e4a 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 57 * No `get_` prefix on getters (including for generated fields) 58 58 * Notable changes: 59 59 * for concision and consistency with subclasses: … … 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()` => `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) 83 89 84 90 `Expr`
Note: See TracChangeset
for help on using the changeset viewer.