- Timestamp:
- May 10, 2019, 12:09:05 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:
- 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. - Location:
- src/AST
- Files:
-
- 2 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Bitfield.hpp
r292d599 r36354b1 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
r292d599 r36354b1 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
r292d599 r36354b1 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 Init; 37 class TypeDecl; 31 38 32 39 /// Base declaration class … … 39 46 bool extension = false; 40 47 41 Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 48 Decl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 42 49 Linkage::Spec linkage ) 43 50 : ParseNode( loc ), name( name ), storage( storage ), linkage( linkage ) {} … … 61 68 /// This field is generated by SymTab::Validate::Pass2 62 69 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. 64 71 /// Used to access shadowed identifiers. 65 72 int scopeLevel = 0; 66 73 67 74 std::vector<ptr<Attribute>> attributes; 68 Function::Specs funcSpec s;75 Function::Specs funcSpec; 69 76 ptr<Expr> asmName; 70 77 bool isDeleted = false; 71 78 72 DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 79 DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 73 80 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; 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"; } 76 205 }; 77 206 -
src/AST/Label.hpp
r292d599 r36354b1 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
r292d599 r36354b1 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 } 40 41 } 41 42 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 "cfabuilt-in";50 case BuiltinC: return "cbuilt-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>"; 53 54 } 55 } 54 56 55 } 57 } 58 56 59 } 57 60 -
src/AST/LinkageSpec.hpp
r292d599 r36354b1 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 56 58 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 74 75 } 75 76 -
src/AST/Node.hpp
r292d599 r36354b1 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
r292d599 r36354b1 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
r292d599 r36354b1 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
r292d599 r36354b1 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: 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 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) 83 93 84 94 `Expr`
Note: See TracChangeset
for help on using the changeset viewer.