Changes in / [4ab0669:1531ef5]
- Location:
- src
- Files:
-
- 18 edited
-
AST/Attribute.hpp (modified) (1 diff)
-
AST/Bitfield.hpp (modified) (1 diff)
-
AST/Decl.hpp (modified) (5 diffs)
-
AST/FunctionSpec.hpp (modified) (1 diff)
-
AST/Fwd.hpp (modified) (2 diffs)
-
AST/Init.hpp (modified) (7 diffs)
-
AST/Label.hpp (modified) (1 diff)
-
AST/LinkageSpec.hpp (modified) (1 diff)
-
AST/ParseNode.hpp (modified) (1 diff)
-
AST/Pass.hpp (modified) (6 diffs)
-
AST/Pass.impl.hpp (modified) (10 diffs)
-
AST/Pass.proto.hpp (modified) (1 diff)
-
AST/Stmt.hpp (modified) (1 diff)
-
AST/StorageClasses.hpp (modified) (1 diff)
-
AST/Type.hpp (modified) (1 diff)
-
Common/PassVisitor.impl.h (modified) (2 diffs)
-
Common/PassVisitor.proto.h (modified) (1 diff)
-
SynTree/Declaration.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Attribute.hpp
r4ab0669 r1531ef5 47 47 }; 48 48 49 50 51 //=================================================================================================52 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency53 /// remove only if there is a better solution54 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with55 /// forward declarations56 inline void increment( const class Attribute * node, Node::ref_type ref ) { node->increment( ref ); }57 inline void decrement( const class Attribute * node, Node::ref_type ref ) { node->decrement( ref ); }58 49 } 59 50 -
src/AST/Bitfield.hpp
r4ab0669 r1531ef5 22 22 /// does not allow it. Requires type to have `unsigned val` field 23 23 /// @param BFType Name of containing type 24 template<typename T> 25 struct bitfield : public T { 26 static_assert(sizeof(T) == sizeof(unsigned int), "Type has incorrect size"); 27 using T::val; 28 using val_t = decltype(val); 29 30 constexpr bitfield() : T( 0 ) {} 31 constexpr bitfield( val_t v ) : T( v ) {} 32 33 bool operator[]( val_t i ) const { return val & (1 << i); } 34 bool any() const { return val != 0; } 35 void reset() { val = 0; } 36 int ffs() { return ::ffs( val ) - 1; } 37 38 bitfield operator&=( bitfield other ) { 39 val &= other.val; return *this; 24 #define MakeBitfield( BFType ) \ 25 constexpr BFType() : val( 0 ) {} \ 26 constexpr BFType( unsigned int v ) : val( v ) {} \ 27 bool operator[]( unsigned int i ) const { return val & (1 << i); } \ 28 bool any() const { return val != 0; } \ 29 void reset() { val = 0; } \ 30 int ffs() { return ::ffs( val ) - 1; } \ 31 BFType operator&=( BFType other ) { \ 32 val &= other.val; return *this; \ 33 } \ 34 BFType operator&( BFType other ) const { \ 35 BFType q = other; \ 36 q &= *this; \ 37 return q; \ 38 } \ 39 BFType operator|=( BFType other ) { \ 40 val |= other.val; return *this; \ 41 } \ 42 BFType operator|( BFType other ) const { \ 43 BFType q = other; \ 44 q |= *this; \ 45 return q; \ 46 } \ 47 BFType operator-=( BFType other ) { \ 48 val &= ~other.val; return *this; \ 40 49 } 41 bitfield operator&( bitfield other ) const {42 bitfield q = other;43 q &= *this;44 return q;45 }46 bitfield operator|=( bitfield other ) {47 val |= other.val; return *this;48 }49 bitfield operator|( bitfield other ) const {50 bitfield q = other;51 q |= *this;52 return q;53 }54 bitfield operator-=( bitfield other ) {55 val &= ~other.val; return *this;56 }57 };58 50 59 51 /// Adds default printing operator to a bitfield type. 60 52 /// Include in definition to add print function, requires other bitfield operators. 61 53 /// @param N Number of bits in bitfield 62 #define MakeBitfieldPrint( N ) \ 63 static const char* Names[]; \ 64 \ 65 void print( std::ostream & os ) const { \ 66 if ( (*this).any() ) { \ 67 for ( unsigned int i = 0; i < N; i += 1 ) { \ 68 if ( (*this)[i] ) { \ 69 os << Names[i] << ' '; \ 70 } \ 71 } \ 72 } \ 54 #define MakeBitfieldPrint( N ) \ 55 static const char* Names[]; \ 56 void print( std::ostream & os ) const { \ 57 if ( (*this).any() ) { \ 58 for ( unsigned int i = 0; i < N; i += 1 ) { \ 59 if ( (*this)[i] ) { \ 60 os << Names[i] << ' '; \ 61 } \ 62 } \ 63 } \ 73 64 } 74 65 -
src/AST/Decl.hpp
r4ab0669 r1531ef5 122 122 std::vector<ptr<DeclWithType>> assertions; 123 123 124 NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 124 NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 125 125 Type* b, Linkage::Spec spec = Linkage::Cforall ) 126 126 : Decl( loc, name, storage, spec ), base( b ), parameters(), assertions() {} … … 149 149 Data( TypeDecl* d ) : kind( d->kind ), isComplete( d->sized ) {} 150 150 Data( Kind k, bool c ) : kind( k ), isComplete( c ) {} 151 Data( const Data& d1, const Data& d2 ) 151 Data( const Data& d1, const Data& d2 ) 152 152 : kind( d1.kind ), isComplete( d1.isComplete || d2.isComplete ) {} 153 153 … … 158 158 }; 159 159 160 TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b, 160 TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b, 161 161 Kind k, bool s, Type* i = nullptr ) 162 162 : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == Ttype || s ), init( i ) {} … … 174 174 class TypedefDecl final : public NamedTypeDecl { 175 175 public: 176 TypedefDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 176 TypedefDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 177 177 Type* b, Linkage::Spec spec = Linkage::Cforall ) 178 178 : NamedTypeDecl( loc, name, storage, b, spec ) {} … … 275 275 }; 276 276 277 278 //=================================================================================================279 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency280 /// remove only if there is a better solution281 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with282 /// forward declarations283 inline void increment( const class Decl * node, Node::ref_type ref ) { node->increment(ref); }284 inline void decrement( const class Decl * node, Node::ref_type ref ) { node->decrement(ref); }285 inline void increment( const class DeclWithType * node, Node::ref_type ref ) { node->increment(ref); }286 inline void decrement( const class DeclWithType * node, Node::ref_type ref ) { node->decrement(ref); }287 inline void increment( const class ObjectDecl * node, Node::ref_type ref ) { node->increment(ref); }288 inline void decrement( const class ObjectDecl * node, Node::ref_type ref ) { node->decrement(ref); }289 inline void increment( const class FunctionDecl * node, Node::ref_type ref ) { node->increment(ref); }290 inline void decrement( const class FunctionDecl * node, Node::ref_type ref ) { node->decrement(ref); }291 inline void increment( const class AggregateDecl * node, Node::ref_type ref ) { node->increment(ref); }292 inline void decrement( const class AggregateDecl * node, Node::ref_type ref ) { node->decrement(ref); }293 inline void increment( const class StructDecl * node, Node::ref_type ref ) { node->increment(ref); }294 inline void decrement( const class StructDecl * node, Node::ref_type ref ) { node->decrement(ref); }295 inline void increment( const class UnionDecl * node, Node::ref_type ref ) { node->increment(ref); }296 inline void decrement( const class UnionDecl * node, Node::ref_type ref ) { node->decrement(ref); }297 inline void increment( const class EnumDecl * node, Node::ref_type ref ) { node->increment(ref); }298 inline void decrement( const class EnumDecl * node, Node::ref_type ref ) { node->decrement(ref); }299 inline void increment( const class TraitDecl * node, Node::ref_type ref ) { node->increment(ref); }300 inline void decrement( const class TraitDecl * node, Node::ref_type ref ) { node->decrement(ref); }301 inline void increment( const class NamedTypeDecl * node, Node::ref_type ref ) { node->increment(ref); }302 inline void decrement( const class NamedTypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }303 inline void increment( const class TypeDecl * node, Node::ref_type ref ) { node->increment(ref); }304 inline void decrement( const class TypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }305 inline void increment( const class FtypeDecl * node, Node::ref_type ref ) { node->increment(ref); }306 inline void decrement( const class FtypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }307 inline void increment( const class DtypeDecl * node, Node::ref_type ref ) { node->increment(ref); }308 inline void decrement( const class DtypeDecl * node, Node::ref_type ref ) { node->decrement(ref); }309 inline void increment( const class TypedefDecl * node, Node::ref_type ref ) { node->increment(ref); }310 inline void decrement( const class TypedefDecl * node, Node::ref_type ref ) { node->decrement(ref); }311 inline void increment( const class AsmDecl * node, Node::ref_type ref ) { node->increment(ref); }312 inline void decrement( const class AsmDecl * node, Node::ref_type ref ) { node->decrement(ref); }313 inline void increment( const class StaticAssertDecl * node, Node::ref_type ref ) { node->increment(ref); }314 inline void decrement( const class StaticAssertDecl * node, Node::ref_type ref ) { node->decrement(ref); }315 316 277 } 317 278 -
src/AST/FunctionSpec.hpp
r4ab0669 r1531ef5 31 31 32 32 /// Bitflag type for storage classes 33 struct spec_flags { 34 union { 35 unsigned int val; 36 struct { 37 bool is_inline : 1; 38 bool is_noreturn : 1; 39 bool is_fortran : 1; 40 }; 41 42 // MakeBitfieldPrint( NumSpecs ) 33 union Specs { 34 unsigned int val; 35 struct { 36 bool is_inline : 1; 37 bool is_noreturn : 1; 38 bool is_fortran : 1; 43 39 }; 44 40 45 constexpr spec_flags( unsigned int val ) : val(val) {} 41 MakeBitfield( Specs ) 42 MakeBitfieldPrint( NumSpecs ) 46 43 }; 47 44 48 using Specs = bitfield<spec_flags>;49 45 } 50 46 } -
src/AST/Fwd.hpp
r4ab0669 r1531ef5 16 16 #pragma once 17 17 18 #include "AST/Node.hpp"19 20 18 namespace ast { 21 19 20 class Node; 22 21 class ParseNode; 23 22 … … 138 137 class TypeSubstitution; 139 138 140 //=================================================================================================141 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency142 /// remove only if there is a better solution143 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with144 /// forward declarations145 inline void decrement( const class Node * node, Node::ref_type ref ) { node->decrement(ref); }146 inline void increment( const class Node * node, Node::ref_type ref ) { node->increment(ref); }147 inline void increment( const class ParseNode *, Node::ref_type );148 inline void decrement( const class ParseNode *, Node::ref_type );149 inline void increment( const class Decl *, Node::ref_type );150 inline void decrement( const class Decl *, Node::ref_type );151 inline void increment( const class DeclWithType *, Node::ref_type );152 inline void decrement( const class DeclWithType *, Node::ref_type );153 inline void increment( const class ObjectDecl *, Node::ref_type );154 inline void decrement( const class ObjectDecl *, Node::ref_type );155 inline void increment( const class FunctionDecl *, Node::ref_type );156 inline void decrement( const class FunctionDecl *, Node::ref_type );157 inline void increment( const class AggregateDecl *, Node::ref_type );158 inline void decrement( const class AggregateDecl *, Node::ref_type );159 inline void increment( const class StructDecl *, Node::ref_type );160 inline void decrement( const class StructDecl *, Node::ref_type );161 inline void increment( const class UnionDecl *, Node::ref_type );162 inline void decrement( const class UnionDecl *, Node::ref_type );163 inline void increment( const class EnumDecl *, Node::ref_type );164 inline void decrement( const class EnumDecl *, Node::ref_type );165 inline void increment( const class TraitDecl *, Node::ref_type );166 inline void decrement( const class TraitDecl *, Node::ref_type );167 inline void increment( const class NamedTypeDecl *, Node::ref_type );168 inline void decrement( const class NamedTypeDecl *, Node::ref_type );169 inline void increment( const class TypeDecl *, Node::ref_type );170 inline void decrement( const class TypeDecl *, Node::ref_type );171 inline void increment( const class FtypeDecl *, Node::ref_type );172 inline void decrement( const class FtypeDecl *, Node::ref_type );173 inline void increment( const class DtypeDecl *, Node::ref_type );174 inline void decrement( const class DtypeDecl *, Node::ref_type );175 inline void increment( const class TypedefDecl *, Node::ref_type );176 inline void decrement( const class TypedefDecl *, Node::ref_type );177 inline void increment( const class AsmDecl *, Node::ref_type );178 inline void decrement( const class AsmDecl *, Node::ref_type );179 inline void increment( const class StaticAssertDecl *, Node::ref_type );180 inline void decrement( const class StaticAssertDecl *, Node::ref_type );181 inline void increment( const class Stmt *, Node::ref_type );182 inline void decrement( const class Stmt *, Node::ref_type );183 inline void increment( const class CompoundStmt *, Node::ref_type );184 inline void decrement( const class CompoundStmt *, Node::ref_type );185 inline void increment( const class ExprStmt *, Node::ref_type );186 inline void decrement( const class ExprStmt *, Node::ref_type );187 inline void increment( const class AsmStmt *, Node::ref_type );188 inline void decrement( const class AsmStmt *, Node::ref_type );189 inline void increment( const class DirectiveStmt *, Node::ref_type );190 inline void decrement( const class DirectiveStmt *, Node::ref_type );191 inline void increment( const class IfStmt *, Node::ref_type );192 inline void decrement( const class IfStmt *, Node::ref_type );193 inline void increment( const class WhileStmt *, Node::ref_type );194 inline void decrement( const class WhileStmt *, Node::ref_type );195 inline void increment( const class ForStmt *, Node::ref_type );196 inline void decrement( const class ForStmt *, Node::ref_type );197 inline void increment( const class SwitchStmt *, Node::ref_type );198 inline void decrement( const class SwitchStmt *, Node::ref_type );199 inline void increment( const class CaseStmt *, Node::ref_type );200 inline void decrement( const class CaseStmt *, Node::ref_type );201 inline void increment( const class BranchStmt *, Node::ref_type );202 inline void decrement( const class BranchStmt *, Node::ref_type );203 inline void increment( const class ReturnStmt *, Node::ref_type );204 inline void decrement( const class ReturnStmt *, Node::ref_type );205 inline void increment( const class ThrowStmt *, Node::ref_type );206 inline void decrement( const class ThrowStmt *, Node::ref_type );207 inline void increment( const class TryStmt *, Node::ref_type );208 inline void decrement( const class TryStmt *, Node::ref_type );209 inline void increment( const class CatchStmt *, Node::ref_type );210 inline void decrement( const class CatchStmt *, Node::ref_type );211 inline void increment( const class FinallyStmt *, Node::ref_type );212 inline void decrement( const class FinallyStmt *, Node::ref_type );213 inline void increment( const class WaitForStmt *, Node::ref_type );214 inline void decrement( const class WaitForStmt *, Node::ref_type );215 inline void increment( const class WithStmt *, Node::ref_type );216 inline void decrement( const class WithStmt *, Node::ref_type );217 inline void increment( const class DeclStmt *, Node::ref_type );218 inline void decrement( const class DeclStmt *, Node::ref_type );219 inline void increment( const class NullStmt *, Node::ref_type );220 inline void decrement( const class NullStmt *, Node::ref_type );221 inline void increment( const class ImplicitCtorDtorStmt *, Node::ref_type );222 inline void decrement( const class ImplicitCtorDtorStmt *, Node::ref_type );223 inline void increment( const class Expr *, Node::ref_type );224 inline void decrement( const class Expr *, Node::ref_type );225 inline void increment( const class ApplicationExpr *, Node::ref_type );226 inline void decrement( const class ApplicationExpr *, Node::ref_type );227 inline void increment( const class UntypedExpr *, Node::ref_type );228 inline void decrement( const class UntypedExpr *, Node::ref_type );229 inline void increment( const class NameExpr *, Node::ref_type );230 inline void decrement( const class NameExpr *, Node::ref_type );231 inline void increment( const class AddressExpr *, Node::ref_type );232 inline void decrement( const class AddressExpr *, Node::ref_type );233 inline void increment( const class LabelAddressExpr *, Node::ref_type );234 inline void decrement( const class LabelAddressExpr *, Node::ref_type );235 inline void increment( const class CastExpr *, Node::ref_type );236 inline void decrement( const class CastExpr *, Node::ref_type );237 inline void increment( const class KeywordCastExpr *, Node::ref_type );238 inline void decrement( const class KeywordCastExpr *, Node::ref_type );239 inline void increment( const class VirtualCastExpr *, Node::ref_type );240 inline void decrement( const class VirtualCastExpr *, Node::ref_type );241 inline void increment( const class MemberExpr *, Node::ref_type );242 inline void decrement( const class MemberExpr *, Node::ref_type );243 inline void increment( const class UntypedMemberExpr *, Node::ref_type );244 inline void decrement( const class UntypedMemberExpr *, Node::ref_type );245 inline void increment( const class VariableExpr *, Node::ref_type );246 inline void decrement( const class VariableExpr *, Node::ref_type );247 inline void increment( const class ConstantExpr *, Node::ref_type );248 inline void decrement( const class ConstantExpr *, Node::ref_type );249 inline void increment( const class SizeofExpr *, Node::ref_type );250 inline void decrement( const class SizeofExpr *, Node::ref_type );251 inline void increment( const class AlignofExpr *, Node::ref_type );252 inline void decrement( const class AlignofExpr *, Node::ref_type );253 inline void increment( const class UntypedOffsetofExpr *, Node::ref_type );254 inline void decrement( const class UntypedOffsetofExpr *, Node::ref_type );255 inline void increment( const class OffsetofExpr *, Node::ref_type );256 inline void decrement( const class OffsetofExpr *, Node::ref_type );257 inline void increment( const class OffsetPackExpr *, Node::ref_type );258 inline void decrement( const class OffsetPackExpr *, Node::ref_type );259 inline void increment( const class AttrExpr *, Node::ref_type );260 inline void decrement( const class AttrExpr *, Node::ref_type );261 inline void increment( const class LogicalExpr *, Node::ref_type );262 inline void decrement( const class LogicalExpr *, Node::ref_type );263 inline void increment( const class ConditionalExpr *, Node::ref_type );264 inline void decrement( const class ConditionalExpr *, Node::ref_type );265 inline void increment( const class CommaExpr *, Node::ref_type );266 inline void decrement( const class CommaExpr *, Node::ref_type );267 inline void increment( const class TypeExpr *, Node::ref_type );268 inline void decrement( const class TypeExpr *, Node::ref_type );269 inline void increment( const class AsmExpr *, Node::ref_type );270 inline void decrement( const class AsmExpr *, Node::ref_type );271 inline void increment( const class ImplicitCopyCtorExpr *, Node::ref_type );272 inline void decrement( const class ImplicitCopyCtorExpr *, Node::ref_type );273 inline void increment( const class ConstructorExpr *, Node::ref_type );274 inline void decrement( const class ConstructorExpr *, Node::ref_type );275 inline void increment( const class CompoundLiteralExpr *, Node::ref_type );276 inline void decrement( const class CompoundLiteralExpr *, Node::ref_type );277 inline void increment( const class UntypedValofExpr *, Node::ref_type );278 inline void decrement( const class UntypedValofExpr *, Node::ref_type );279 inline void increment( const class RangeExpr *, Node::ref_type );280 inline void decrement( const class RangeExpr *, Node::ref_type );281 inline void increment( const class UntypedTupleExpr *, Node::ref_type );282 inline void decrement( const class UntypedTupleExpr *, Node::ref_type );283 inline void increment( const class TupleExpr *, Node::ref_type );284 inline void decrement( const class TupleExpr *, Node::ref_type );285 inline void increment( const class TupleIndexExpr *, Node::ref_type );286 inline void decrement( const class TupleIndexExpr *, Node::ref_type );287 inline void increment( const class TupleAssignExpr *, Node::ref_type );288 inline void decrement( const class TupleAssignExpr *, Node::ref_type );289 inline void increment( const class StmtExpr *, Node::ref_type );290 inline void decrement( const class StmtExpr *, Node::ref_type );291 inline void increment( const class UniqueExpr *, Node::ref_type );292 inline void decrement( const class UniqueExpr *, Node::ref_type );293 inline void increment( const class UntypedInitExpr *, Node::ref_type );294 inline void decrement( const class UntypedInitExpr *, Node::ref_type );295 inline void increment( const class InitExpr *, Node::ref_type );296 inline void decrement( const class InitExpr *, Node::ref_type );297 inline void increment( const class DeletedExpr *, Node::ref_type );298 inline void decrement( const class DeletedExpr *, Node::ref_type );299 inline void increment( const class DefaultArgExpr *, Node::ref_type );300 inline void decrement( const class DefaultArgExpr *, Node::ref_type );301 inline void increment( const class GenericExpr *, Node::ref_type );302 inline void decrement( const class GenericExpr *, Node::ref_type );303 inline void increment( const class Type *, Node::ref_type );304 inline void decrement( const class Type *, Node::ref_type );305 inline void increment( const class VoidType *, Node::ref_type );306 inline void decrement( const class VoidType *, Node::ref_type );307 inline void increment( const class BasicType *, Node::ref_type );308 inline void decrement( const class BasicType *, Node::ref_type );309 inline void increment( const class PointerType *, Node::ref_type );310 inline void decrement( const class PointerType *, Node::ref_type );311 inline void increment( const class ArrayType *, Node::ref_type );312 inline void decrement( const class ArrayType *, Node::ref_type );313 inline void increment( const class ReferenceType *, Node::ref_type );314 inline void decrement( const class ReferenceType *, Node::ref_type );315 inline void increment( const class QualifiedType *, Node::ref_type );316 inline void decrement( const class QualifiedType *, Node::ref_type );317 inline void increment( const class FunctionType *, Node::ref_type );318 inline void decrement( const class FunctionType *, Node::ref_type );319 inline void increment( const class ReferenceToType *, Node::ref_type );320 inline void decrement( const class ReferenceToType *, Node::ref_type );321 inline void increment( const class StructInstType *, Node::ref_type );322 inline void decrement( const class StructInstType *, Node::ref_type );323 inline void increment( const class UnionInstType *, Node::ref_type );324 inline void decrement( const class UnionInstType *, Node::ref_type );325 inline void increment( const class EnumInstType *, Node::ref_type );326 inline void decrement( const class EnumInstType *, Node::ref_type );327 inline void increment( const class TraitInstType *, Node::ref_type );328 inline void decrement( const class TraitInstType *, Node::ref_type );329 inline void increment( const class TypeInstType *, Node::ref_type );330 inline void decrement( const class TypeInstType *, Node::ref_type );331 inline void increment( const class TupleType *, Node::ref_type );332 inline void decrement( const class TupleType *, Node::ref_type );333 inline void increment( const class TypeofType *, Node::ref_type );334 inline void decrement( const class TypeofType *, Node::ref_type );335 inline void increment( const class AttrType *, Node::ref_type );336 inline void decrement( const class AttrType *, Node::ref_type );337 inline void increment( const class VarArgsType *, Node::ref_type );338 inline void decrement( const class VarArgsType *, Node::ref_type );339 inline void increment( const class ZeroType *, Node::ref_type );340 inline void decrement( const class ZeroType *, Node::ref_type );341 inline void increment( const class OneType *, Node::ref_type );342 inline void decrement( const class OneType *, Node::ref_type );343 inline void increment( const class GlobalScopeType *, Node::ref_type );344 inline void decrement( const class GlobalScopeType *, Node::ref_type );345 inline void increment( const class Designation *, Node::ref_type );346 inline void decrement( const class Designation *, Node::ref_type );347 inline void increment( const class Init *, Node::ref_type );348 inline void decrement( const class Init *, Node::ref_type );349 inline void increment( const class SingleInit *, Node::ref_type );350 inline void decrement( const class SingleInit *, Node::ref_type );351 inline void increment( const class ListInit *, Node::ref_type );352 inline void decrement( const class ListInit *, Node::ref_type );353 inline void increment( const class ConstructorInit *, Node::ref_type );354 inline void decrement( const class ConstructorInit *, Node::ref_type );355 inline void increment( const class Constant *, Node::ref_type );356 inline void decrement( const class Constant *, Node::ref_type );357 inline void increment( const class Label *, Node::ref_type );358 inline void decrement( const class Label *, Node::ref_type );359 inline void increment( const class Attribute *, Node::ref_type );360 inline void decrement( const class Attribute *, Node::ref_type );361 inline void increment( const class TypeSubstitution *, Node::ref_type );362 inline void decrement( const class TypeSubstitution *, Node::ref_type );363 364 139 typedef unsigned int UniqueId; 365 140 -
src/AST/Init.hpp
r4ab0669 r1531ef5 28 28 class Stmt; 29 29 30 /// List of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an 30 /// List of designator (NameExpr, VariableExpr, and ConstantExpr) expressions that specify an 31 31 /// object being initialized 32 32 class Designation final : public ParseNode { … … 34 34 std::vector<ptr<Expr>> designators; 35 35 36 Designation( const CodeLocation& loc, std::vector<ptr<Expr>>&& ds = {} ) 36 Designation( const CodeLocation& loc, std::vector<ptr<Expr>>&& ds = {} ) 37 37 : ParseNode( loc ), designators( std::move(ds) ) {} 38 38 … … 60 60 ptr<Expr> value; 61 61 62 SingleInit( const CodeLocation& loc, Expr* val, bool mc = false ) 62 SingleInit( const CodeLocation& loc, Expr* val, bool mc = false ) 63 63 : Init( loc, mc ), value( val ) {} 64 64 … … 77 77 std::vector<ptr<Designation>> designations; 78 78 79 ListInit( const CodeLocation& loc, std::vector<ptr<Init>>&& is, 79 ListInit( const CodeLocation& loc, std::vector<ptr<Init>>&& is, 80 80 std::vector<ptr<Designation>>&& ds = {}, bool mc = false ); 81 81 82 82 using iterator = std::vector<ptr<Init>>::iterator; 83 83 using const_iterator = std::vector<ptr<Init>>::const_iterator; … … 93 93 94 94 /// Either a constructor expression or a C-style initializer. 95 /// Should not be necessary to create manually; instead set `maybeConstructed` true on `SingleInit` 95 /// Should not be necessary to create manually; instead set `maybeConstructed` true on `SingleInit` 96 96 /// or `ListInit` if the object should be constructed. 97 97 class ConstructorInit final : public Init { … … 99 99 ptr<Stmt> ctor; 100 100 ptr<Stmt> dtor; 101 /// C-style initializer made up of SingleInit/ListInit nodes to use as a fallback if an 101 /// C-style initializer made up of SingleInit/ListInit nodes to use as a fallback if an 102 102 /// appropriate constructor definition is not found by the resolver. 103 103 ptr<Init> init; … … 111 111 }; 112 112 113 114 //=================================================================================================115 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency116 /// remove only if there is a better solution117 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with118 /// forward declarations119 inline void increment( const class Init * node, Node::ref_type ref ) { node->increment( ref ); }120 inline void decrement( const class Init * node, Node::ref_type ref ) { node->decrement( ref ); }121 inline void increment( const class SingleInit * node, Node::ref_type ref ) { node->increment( ref ); }122 inline void decrement( const class SingleInit * node, Node::ref_type ref ) { node->decrement( ref ); }123 inline void increment( const class ListInit * node, Node::ref_type ref ) { node->increment( ref ); }124 inline void decrement( const class ListInit * node, Node::ref_type ref ) { node->decrement( ref ); }125 inline void increment( const class ConstructorInit * node, Node::ref_type ref ) { node->increment( ref ); }126 inline void decrement( const class ConstructorInit * node, Node::ref_type ref ) { node->decrement( ref ); }127 113 } 128 114 -
src/AST/Label.hpp
r4ab0669 r1531ef5 25 25 namespace ast { 26 26 27 class Attribute;27 class Attribute; 28 28 29 /// Named labels for statements30 class Label {31 public:32 CodeLocation location;33 std::string name;34 std::vector< ptr<Attribute> > attributes;29 /// Named labels for statements 30 class Label { 31 public: 32 CodeLocation location; 33 std::string name; 34 std::vector< ptr<Attribute> > attributes; 35 35 36 Label( CodeLocation loc, const std::string& name = "",37 const std::vector<ptr<Attribute>>& attrs = std::vector<ptr<Attribute>>{} )38 : location( loc ), name( name ), attributes( attrs ) {}36 Label( CodeLocation loc, const std::string& name = "", 37 const std::vector<ptr<Attribute>>& attrs = std::vector<ptr<Attribute>>{} ) 38 : location( loc ), name( name ), attributes( attrs ) {} 39 39 40 operator std::string () const { return name; }41 bool empty() { return name.empty(); }42 };40 operator std::string () const { return name; } 41 bool empty() { return name.empty(); } 42 }; 43 43 44 inline bool operator== ( const Label& l1, const Label& l2 ) { return l1.name == l2.name; }45 inline bool operator!= ( const Label& l1, const Label& l2 ) { return !(l1 == l2); }46 inline bool operator< ( const Label& l1, const Label& l2 ) { return l1.name < l2.name; }44 inline bool operator== ( const Label& l1, const Label& l2 ) { return l1.name == l2.name; } 45 inline bool operator!= ( const Label& l1, const Label& l2 ) { return !(l1 == l2); } 46 inline bool operator< ( const Label& l1, const Label& l2 ) { return l1.name < l2.name; } 47 47 48 inline std::ostream& operator<< ( std::ostream& out, const Label& l ) { return out << l.name; } 49 50 51 //================================================================================================= 52 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency 53 /// remove only if there is a better solution 54 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with 55 /// forward declarations 56 inline void increment( const class Label * node, Node::ref_type ref ) { node->increment( ref ); } 57 inline void decrement( const class Label * node, Node::ref_type ref ) { node->decrement( ref ); } 48 inline std::ostream& operator<< ( std::ostream& out, const Label& l ) { return out << l.name; } 58 49 59 50 } -
src/AST/LinkageSpec.hpp
r4ab0669 r1531ef5 35 35 36 36 /// Bitflag type for storage classes 37 struct spec_flags { 38 union { 39 unsigned int val; 40 struct { 41 bool is_mangled : 1; 42 bool is_generatable : 1; 43 bool is_overrideable : 1; 44 bool is_builtin : 1; 45 bool is_gcc_builtin : 1; 46 }; 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; 47 45 }; 48 46 49 constexpr spec_flags( unsigned int val ) : val(val) {}47 MakeBitfield( Spec ) 50 48 }; 51 52 using Spec = bitfield<spec_flags>;53 49 54 50 /// If `cmd` = "C" returns `spec` with `is_mangled = false`. -
src/AST/ParseNode.hpp
r4ab0669 r1531ef5 22 22 namespace ast { 23 23 24 /// AST node with an included source location25 class ParseNode : public Node {26 public:27 CodeLocation location;24 /// AST node with an included source location 25 class ParseNode : public Node { 26 public: 27 CodeLocation location; 28 28 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, but31 // this should be used sparingly.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 31 // this should be used sparingly. 32 32 33 ParseNode( const CodeLocation& loc ) : Node(), location(loc) {}33 ParseNode( const CodeLocation& loc ) : Node(), location(loc) {} 34 34 35 ParseNode( const ParseNode& o ) = default;36 };35 ParseNode( const ParseNode& o ) = default; 36 }; 37 37 38 39 //=================================================================================================40 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency41 /// remove only if there is a better solution42 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with43 /// forward declarations44 inline void increment( const class ParseNode * node, Node::ref_type ref ) { node->increment( ref ); }45 inline void decrement( const class ParseNode * node, Node::ref_type ref ) { node->decrement( ref ); }46 38 } 47 39 -
src/AST/Pass.hpp
r4ab0669 r1531ef5 1 //2 // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo3 //4 // The contents of this file are covered under the licence agreement in the5 // file "LICENCE" distributed with Cforall.6 //7 // Pass.hpp --8 //9 // Author : Thierry Delisle10 // Created On : Thu May 09 15::37::05 201911 // Last Modified By :12 // Last Modified On :13 // Update Count :14 //15 16 1 #pragma once 17 // IWYU pragma: private, include " AST/Pass.hpp"2 // IWYU pragma: private, include "Common/PassVisitor.h" 18 3 19 4 #include <functional> … … 21 6 #include <stack> 22 7 23 #include "AST/Fwd.hpp" 24 #include "AST/Node.hpp" 25 #include "AST/Decl.hpp" 26 #include "AST/Visitor.hpp" 27 28 #include "SymTab/Indexer.h" 8 #include "Fwd.hpp" 9 #include "Node.hpp" 29 10 30 11 // Private prelude header, needed for some of the magic tricks this class pulls off 31 #include " AST/Pass.proto.hpp"12 #include "Pass.proto.hpp" 32 13 33 14 namespace ast { … … 39 20 // 40 21 // Several additional features are available through inheritance 41 // | WithTypeSubstitution - provides polymorphic const TypeSubstitution * env for the 42 // current expression 22 // | WithTypeSubstitution - provides polymorphic TypeSubstitution * env for the current expression 43 23 // | WithStmtsToAdd - provides the ability to insert statements before or after the current 44 24 // statement by adding new statements into stmtsToAddBefore or 45 25 // stmtsToAddAfter respectively. 46 // | WithDeclsToAdd - provides the ability to insert declarations before or after the current47 // declarations by adding new DeclStmt into declsToAddBefore or48 // declsToAddAfter respectively.49 26 // | WithShortCircuiting - provides the ability to skip visiting child nodes; set visit_children 50 27 // to false in pre{visit,visit} to skip visiting children … … 53 30 // automatically be restored to its previous value after the corresponding 54 31 // postvisit/postmutate teminates. 55 // | WithVisitorRef - provides an pointer to the templated visitor wrapper56 // | WithIndexer - provides indexer functionality (i.e. up-to-date symbol table)57 32 //------------------------------------------------------------------------------------------------- 58 33 template< typename pass_t > 59 34 class Pass final : public ast::Visitor { 60 35 public: 61 /// Forward any arguments to the pass constructor62 /// Propagate 'this' if necessary63 36 template< typename... Args > 64 37 Pass( Args &&... args) 65 : pass( std::forward<Args>( args )... )38 : m_pass( std::forward<Args>( args )... ) 66 39 { 67 40 // After the pass is constructed, check if it wants the have a pointer to the wrapping visitor 68 41 typedef Pass<pass_t> this_t; 69 this_t * const * visitor = __pass::visitor( pass, 0);42 this_t * const * visitor = __pass::visitor(m_pass, 0); 70 43 if(visitor) { 71 44 *const_cast<this_t **>( visitor ) = this; … … 75 48 virtual ~Pass() = default; 76 49 77 /// Storage for the actual pass 78 pass_t pass; 79 80 /// Visit function declarations 50 pass_t m_pass; 51 81 52 virtual DeclWithType * visit( const ObjectDecl * ) override final; 82 53 virtual DeclWithType * visit( const FunctionDecl * ) override final; … … 174 145 virtual TypeSubstitution * visit( const TypeSubstitution * ) override final; 175 146 176 friend void acceptAll( std::list< ptr<Decl> > & decls, Pass<pass_t>& visitor ); 177 private: 178 179 bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(pass, 0); return ptr ? *ptr : true; } 180 181 private: 182 /// Logic to call the accept and mutate the parent if needed, delegates call to accept 147 private: 148 149 bool __visit_children() { __pass::bool_ref * ptr = __pass::visit_children(m_pass, 0); return ptr ? *ptr : true; } 150 151 private: 183 152 template<typename parent_t, typename child_t> 184 153 void maybe_accept(parent_t * & , typename parent_t::child_t *); 185 154 186 Stmt * call_accept( const Stmt* );187 Expr * call_accept( const Expr* );155 ast::Statement * call_accept( const ast::Statement * ); 156 ast::Expression * call_accept( const ast::Expression * ); 188 157 189 158 template< template <class> class container_t > 190 container_t< ptr<Stmt> > call_accept( const container_t< ptr<Stmt> > & );159 container_t< ast::ptr<ast::Statement> > call_accept( const container_t< ast::ptr<ast::Statement> > & ); 191 160 192 161 template< template <class> class container_t, typename node_t > 193 container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container ); 194 195 private: 196 /// Internal RAII guard for indexer features 197 struct guard_indexer { 198 guard_indexer( Pass<pass_t> & pass ): pass( pass ) { __pass::indexer::enter(pass, 0); } 199 ~guard_indexer() { __pass::indexer::leave(pass, 0); } 162 container_t< ast::ptr<node_t> > call_accept( const container_t< ast::ptr<node_t> > & container ); 163 164 private: 165 struct indexer_guard { 200 166 Pass<pass_t> & pass; 167 168 indexer_guard( Pass<pass_t> & pass ) : pass( pass ) { __pass::indexer::enter(pass, 0); } 169 ~indexer_guard() { __pass::indexer::leave(pass, 0); } 201 170 }; 202 171 203 /// Internal RAII guard for scope features204 struct guard_scope { 205 guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass, 0); } 206 ~guard_scope() { __pass::scope::leave(pass, 0); }172 indexer_guard make_indexer_guard() { return { *this }; } 173 174 private: 175 struct scope_guard { 207 176 Pass<pass_t> & pass; 177 178 scope_guard( Pass<pass_t> & pass ) : pass( pass ) { __pass::scope::enter(pass, 0); } 179 ~scope_guard() { __pass::scope::leave(pass, 0); } 208 180 }; 209 }; 210 211 template<typename pass_t> 212 void acceptAll( std::list< ptr<Decl> >, Pass<pass_t>& visitor ); 213 214 //------------------------------------------------------------------------------------------------- 181 182 scope_guard make_scope_guard() { return { *this }; } 183 }; 184 185 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 186 // Guard value : RAII type to restore a value when the Pass finishes visiting this node 187 template<typename pass_t, typename T> 188 void GuardValue( pass_t * pass, T& val ) { 189 pass->at_cleanup( [ val ]( void * newVal ) { 190 * static_cast< T * >( newVal ) = val; 191 }, static_cast< void * >( & val ) ); 192 } 193 194 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 215 195 // PASS ACCESSORIES 216 //------------------------------------------------------------------------------------------------- 196 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 197 198 // Keep track of the type substitution 199 struct WithConstTypeSubstitution { 200 const ast::TypeSubstitution * env = nullptr; 201 }; 217 202 218 203 template<typename T> 219 204 using std_list = std::list<T>; 220 205 221 /// Keep track of the polymorphic const TypeSubstitution * env for the current expression 222 struct WithConstTypeSubstitution { 223 const TypeSubstitution * env = nullptr; 224 }; 225 226 /// Used if visitor requires added statements before or after the current node. 227 /// The Pass template handles what *before* and *after* means automatically 206 // Used if visitor requires added statements before or after the current node. 207 // The Pass template handles what *before* and *after* means automatically 228 208 template< template<class> class container_t = std_list > 229 209 struct WithStmtsToAdd { 230 container_t< ptr<Stmt> > stmtsToAddBefore;231 container_t< ptr<Stmt> > stmtsToAddAfter;232 }; 233 234 // /Used if visitor requires added declarations before or after the current node.235 // /The Pass template handles what *before* and *after* means automatically210 container_t< ast::ptr< ast::Statement > > stmtsToAddBefore; 211 container_t< ast::ptr< ast::Statement > > stmtsToAddAfter; 212 }; 213 214 // Used if visitor requires added declarations before or after the current node. 215 // The Pass template handles what *before* and *after* means automatically 236 216 template< template<class> class container_t = std_list > 237 217 struct WithDeclsToAdd { 238 container_t< ptr<Decl> > declsToAddBefore; 239 container_t< ptr<Decl> > declsToAddAfter; 240 }; 241 242 /// Use if visitation should stop at certain levels 243 /// set visit_children false of all child nodes should be ignored 218 ~WithDeclsToAdd() { 219 assert( declsToAddBefore.empty() ); 220 } 221 222 container_t< ast::ptr< ast::Declaration > > declsToAddBefore; 223 container_t< ast::ptr< ast::Declaration > > declsToAddAfter; 224 }; 225 226 // Use if visitation should stop at certain levels 227 // set visit_children false of all child nodes should be ignored 244 228 struct WithShortCircuiting { 245 229 __pass::bool_ref visit_children; 246 230 }; 247 231 248 /// Used to restore values/functions/etc. when the Pass finishes visiting this node 249 class WithGuards { 250 __pass::at_cleanup_t at_cleanup; 251 252 public: 253 /// When this node is finished being visited, restore the value of a variable 254 template< typename T > 255 void GuardValue( T& val ) { 256 at_cleanup( [ val ]( void * newVal ) { 257 * static_cast< T * >( newVal ) = val; 258 }, static_cast< void * >( & val ) ); 259 } 260 261 /// On the object, all beginScope now and endScope when the current node is finished being visited 262 template< typename T > 263 void GuardScope( T& val ) { 264 val.beginScope(); 265 at_cleanup( []( void * val ) { 266 static_cast< T * >( val )->endScope(); 267 }, static_cast< void * >( & val ) ); 268 } 269 270 /// When this node is finished being visited, call a function 271 template< typename Func > 272 void GuardAction( Func func ) { 273 at_cleanup( [func](void *) { func(); }, nullptr ); 274 } 275 }; 276 277 /// Used to get a pointer to the pass with its wrapped type 278 template<typename pass_t> 279 struct WithVisitorRef { 280 Pass<pass_t> * const visitor = nullptr; 281 }; 282 283 /// Use when the templated visitor should update the indexer 232 // class WithGuards { 233 // protected: 234 // WithGuards() = default; 235 // ~WithGuards() = default; 236 237 // public: 238 // at_cleanup_t at_cleanup; 239 240 // template< typename T > 241 // void GuardValue( T& val ) { 242 // at_cleanup( [ val ]( void * newVal ) { 243 // * static_cast< T * >( newVal ) = val; 244 // }, static_cast< void * >( & val ) ); 245 // } 246 247 // template< typename T > 248 // void GuardScope( T& val ) { 249 // val.beginScope(); 250 // at_cleanup( []( void * val ) { 251 // static_cast< T * >( val )->endScope(); 252 // }, static_cast< void * >( & val ) ); 253 // } 254 255 // template< typename Func > 256 // void GuardAction( Func func ) { 257 // at_cleanup( [func](__attribute__((unused)) void *) { func(); }, nullptr ); 258 // } 259 // }; 260 261 // template<typename pass_type> 262 // class WithVisitorRef { 263 // protected: 264 // WithVisitorRef() {} 265 // ~WithVisitorRef() {} 266 267 // public: 268 // PassVisitor<pass_type> * const visitor = nullptr; 269 // }; 270 284 271 struct WithIndexer { 285 272 SymTab::Indexer indexer; -
src/AST/Pass.impl.hpp
r4ab0669 r1531ef5 1 //2 // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo3 //4 // The contents of this file are covered under the licence agreement in the5 // file "LICENCE" distributed with Cforall.6 //7 // Pass.impl.hpp --8 //9 // Author : Thierry Delisle10 // Created On : Thu May 09 15::37::05 201911 // Last Modified By :12 // Last Modified On :13 // Update Count :14 //15 16 1 #pragma once 17 // IWYU pragma: private, include " AST/Pass.hpp"2 // IWYU pragma: private, include "Pass.hpp" 18 3 19 4 #define VISIT_START( node ) \ 20 using namespace ast; \21 5 /* back-up the visit children */ \ 22 __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children( pass, 0) ); \6 __attribute__((unused)) ast::__pass::visit_children_guard guard1( ast::__pass::visit_children(m_pass, 0) ); \ 23 7 /* setup the scope for passes that want to run code at exit */ \ 24 __attribute__((unused)) ast::__pass::guard_value guard2( ast::__pass::at_cleanup ( pass, 0) ); \8 __attribute__((unused)) ast::__pass::guard_value guard2( ast::__pass::at_cleanup (m_pass, 0) ); \ 25 9 /* call the implementation of the previsit of this pass */ \ 26 __pass::previsit( pass, node, 0 );10 __pass::previsit( m_pass, node, 0 ); 27 11 28 12 #define VISIT( code ) \ … … 114 98 115 99 template< typename pass_t > 116 ast::Expr * Pass< pass_t >::call_accept( const ast::Expr* expr ) {100 ast::Expression * Pass< pass_t >::call_accept( const ast::Expression * expr ) { 117 101 __pedantic_pass_assert( __visit_children() ); 118 102 __pedantic_pass_assert( expr ); 119 103 120 const ast::TypeSubstitution ** env_ptr = __pass::env( pass, 0);104 const ast::TypeSubstitution ** env_ptr = __pass::env( m_pass, 0); 121 105 if ( env_ptr && expr->env ) { 122 106 *env_ptr = expr->env; … … 127 111 128 112 template< typename pass_t > 129 Stmt * Pass< pass_t >::call_accept( const Stmt * stmt ) {113 ast::Statement * Pass< pass_t >::call_accept( const ast::Statement * stmt ) { 130 114 __pedantic_pass_assert( __visit_children() ); 131 115 __pedantic_pass_assert( stmt ); 116 117 // add a few useful symbols to the scope 118 using __pass::empty; 119 using decls_t = typename std::remove_pointer< decltype(__decls_before()) >::type; 120 using stmts_t = typename std::remove_pointer< decltype(__stmts_before()) >::type; 121 122 // get the stmts/decls that will need to be spliced in 123 auto stmts_before = __pass::stmtsToAddBefore( m_pass, 0); 124 auto stmts_after = __pass::stmtsToAddAfter ( m_pass, 0); 125 auto decls_before = __pass::declsToAddBefore( m_pass, 0); 126 auto decls_after = __pass::declsToAddAfter ( m_pass, 0); 127 128 // These may be modified by subnode but most be restored once we exit this statemnet. 129 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::env( m_pass, 0); ); 130 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before ); 131 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after ); 132 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before ); 133 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after ); 134 135 // Now is the time to actually visit the node 136 ast::Statement * nstmt = stmt->accept( *this ); 137 138 // If the pass doesn't want to add anything then we are done 139 if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) { 140 return nstmt; 141 } 142 143 // Make sure that it is either adding statements or declartions but not both 144 // this is because otherwise the order would be awkward to predict 145 assert(( empty( stmts_before ) && empty( stmts_after )) 146 || ( empty( decls_before ) && empty( decls_after )) ); 147 148 // Create a new Compound Statement to hold the new decls/stmts 149 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location ); 150 151 // Take all the declarations that go before 152 __pass::take_all( std::back_inserter( compound->kids ), decls_before ); 153 __pass::take_all( std::back_inserter( compound->kids ), stmts_before ); 154 155 // Insert the original declaration 156 compound->kids.push_back( nstmt ); 157 158 // Insert all the declarations that go before 159 __pass::take_all( std::back_inserter( compound->kids ), decls_after ); 160 __pass::take_all( std::back_inserter( compound->kids ), stmts_after ); 161 162 return compound; 163 } 164 165 template< typename pass_t > 166 template< template <class> class container_t > 167 container_t< ast::ptr<ast::Statement> > Pass< pass_t >::call_accept( const container_t< ast::ptr<ast::Statement> > & statements ) { 168 __pedantic_pass_assert( __visit_children() ); 169 if( statements.empty() ) return {}; 170 171 // We are going to aggregate errors for all these statements 172 SemanticErrorException errors; 132 173 133 174 // add a few useful symbols to the scope … … 141 182 142 183 // These may be modified by subnode but most be restored once we exit this statemnet. 143 ValueGuardPtr< const ast::TypeSubstitution * > __old_env ( __pass::env( pass, 0); );144 184 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before ); 145 185 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after ); … … 147 187 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after ); 148 188 149 // Now is the time to actually visit the node150 ast::Statement * nstmt = stmt->accept( *this );151 152 // If the pass doesn't want to add anything then we are done153 if( empty(stmts_before) && empty(stmts_after) && empty(decls_before) && empty(decls_after) ) {154 return nstmt;155 }156 157 // Make sure that it is either adding statements or declartions but not both158 // this is because otherwise the order would be awkward to predict159 assert(( empty( stmts_before ) && empty( stmts_after ))160 || ( empty( decls_before ) && empty( decls_after )) );161 162 // Create a new Compound Statement to hold the new decls/stmts163 ast::CompoundStmt * compound = new ast::CompoundStmt( parent->*child.location );164 165 // Take all the declarations that go before166 __pass::take_all( std::back_inserter( compound->kids ), decls_before );167 __pass::take_all( std::back_inserter( compound->kids ), stmts_before );168 169 // Insert the original declaration170 compound->kids.push_back( nstmt );171 172 // Insert all the declarations that go before173 __pass::take_all( std::back_inserter( compound->kids ), decls_after );174 __pass::take_all( std::back_inserter( compound->kids ), stmts_after );175 176 return compound;177 }178 179 template< typename pass_t >180 template< template <class> class container_t >181 container_t< ptr<Stmt> > Pass< pass_t >::call_accept( const container_t< ptr<Stmt> > & statements ) {182 __pedantic_pass_assert( __visit_children() );183 if( statements.empty() ) return {};184 185 // We are going to aggregate errors for all these statements186 SemanticErrorException errors;187 188 // add a few useful symbols to the scope189 using __pass::empty;190 191 // get the stmts/decls that will need to be spliced in192 auto stmts_before = __pass::stmtsToAddBefore( pass, 0);193 auto stmts_after = __pass::stmtsToAddAfter ( pass, 0);194 auto decls_before = __pass::declsToAddBefore( pass, 0);195 auto decls_after = __pass::declsToAddAfter ( pass, 0);196 197 // These may be modified by subnode but most be restored once we exit this statemnet.198 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_before) > __old_decls_before( stmts_before );199 ValueGuardPtr< typename std::remove_pointer< decltype(stmts_after ) > __old_decls_after ( stmts_after );200 ValueGuardPtr< typename std::remove_pointer< decltype(decls_before) > __old_stmts_before( decls_before );201 ValueGuardPtr< typename std::remove_pointer< decltype(decls_after ) > __old_stmts_after ( decls_after );202 203 189 // update pass statitistics 204 190 pass_visitor_stats.depth++; … … 207 193 208 194 bool mutated = false; 209 container_t< ptr<Stmt>> new_kids;210 for( const Stmt * stmt : statements ) {195 container_t<ast::ptr< ast::Statement >> new_kids; 196 for( const ast::Statement * stmt : statements ) { 211 197 try { 212 198 __pedantic_pass_assert( stmt ); … … 283 269 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 284 270 285 template< typename pass_t >286 inline void ast::acceptAll( std::list< ast::ptr<ast::Decl> > & decls, ast::Pass< pass_t > & visitor ) {287 // We are going to aggregate errors for all these statements288 SemanticErrorException errors;289 290 // add a few useful symbols to the scope291 using __pass::empty;292 293 // get the stmts/decls that will need to be spliced in294 auto decls_before = __pass::declsToAddBefore( pass, 0);295 auto decls_after = __pass::declsToAddAfter ( pass, 0);296 297 // update pass statitistics298 pass_visitor_stats.depth++;299 pass_visitor_stats.max->push(pass_visitor_stats.depth);300 pass_visitor_stats.avg->push(pass_visitor_stats.depth);301 302 for ( std::list< ast::ptr<ast::Decl> >::iterator i = decls.begin(); ; ++i ) {303 // splice in new declarations after previous decl304 if ( !empty( decls_after ) ) { decls.splice( i, *decls_after ); }305 306 if ( i == decls.end() ) break;307 308 try {309 // run visitor on declaration310 ast::ptr<ast::Decl> & node = *i;311 assert( node );312 node = node->accept( visitor );313 }314 catch( SemanticErrorException &e ) {315 errors.append( e );316 }317 318 // splice in new declarations before current decl319 if ( !empty( decls_before ) ) { decls.splice( i, *decls_before ); }320 }321 pass_visitor_stats.depth--;322 if ( !errors.isEmpty() ) { throw errors; }323 }324 325 271 // A NOTE ON THE ORDER OF TRAVERSAL 326 272 // … … 343 289 // ObjectDecl 344 290 template< typename pass_t > 345 ast::Decl WithType * ast::Pass< pass_t >::visit( constast::ObjectDecl * node ) {291 ast::DeclarationWithType * Pass< pass_t >::mutate( ast::ObjectDecl * node ) { 346 292 VISIT_START( node ); 347 293 348 294 VISIT( 349 295 { 350 indexer_guard guard { *this };351 maybe_accept( node, ObjectDecl::type );352 } 353 maybe_accept( node, ObjectDecl::init );354 maybe_accept( node, ObjectDecl::bitfieldWidth );355 maybe_accept( node, ObjectDecl::attributes );296 auto guard = make_indexer_guard(); 297 maybe_accept( node, ast::ObjectDecl::type ); 298 } 299 maybe_accept( node, ast::ObjectDecl::init ); 300 maybe_accept( node, ast::ObjectDecl::bitfieldWidth ); 301 maybe_accept( node, ast::ObjectDecl::attributes ); 356 302 ) 357 303 358 __pass::indexer::AddId( pass, 0, node );359 360 VISIT_END( Decl WithType, node );304 __pass::indexer::AddId( m_pass, 0, node ); 305 306 VISIT_END( DeclarationWithType, node ); 361 307 } 362 308 … … 364 310 // Attribute 365 311 template< typename pass_type > 366 ast::Attribute * ast::Pass< pass_type >::visit( const ast::Attribute *node ) {312 ast::Attribute * ast::Pass< pass_type >::visit( ast::ptr<ast::Attribute> & node ) { 367 313 VISIT_START(node); 368 314 … … 377 323 // TypeSubstitution 378 324 template< typename pass_type > 379 TypeSubstitution * PassVisitor< pass_type >::mutate( constTypeSubstitution * node ) {325 TypeSubstitution * PassVisitor< pass_type >::mutate( TypeSubstitution * node ) { 380 326 MUTATE_START( node ); 381 327 -
src/AST/Pass.proto.hpp
r4ab0669 r1531ef5 1 //2 // Cforall Version 1.0.0 Copyright (C) 2019 University of Waterloo3 //4 // The contents of this file are covered under the licence agreement in the5 // file "LICENCE" distributed with Cforall.6 //7 // Pass.impl.hpp --8 //9 // Author : Thierry Delisle10 // Created On : Thu May 09 15::37::05 201911 // Last Modified By :12 // Last Modified On :13 // Update Count :14 //15 16 1 #pragma once 17 2 // IWYU pragma: private, include "Pass.hpp" 18 3 19 4 namespace ast { 20 template<typename pass_type> 21 class Pass; 22 23 namespace __pass { 24 typedef std::function<void( void * )> cleanup_func_t; 25 typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t; 26 27 28 // boolean reference that may be null 29 // either refers to a boolean value or is null and returns true 30 class bool_ref { 31 public: 32 bool_ref() = default; 33 ~bool_ref() = default; 34 35 operator bool() { return m_ref ? *m_ref : true; } 36 bool operator=( bool val ) { assert(m_ref); return *m_ref = val; } 37 38 private: 39 40 friend class visit_children_guard; 41 42 bool * set( bool * val ) { 43 bool * prev = m_ref; 44 m_ref = val; 45 return prev; 5 template<typename pass_type> 6 class Pass; 7 8 namespace __pass { 9 typedef std::function<void( void * )> cleanup_func_t; 10 typedef std::function<void( cleanup_func_t, void * )> at_cleanup_t; 11 12 13 // boolean reference that may be null 14 // either refers to a boolean value or is null and returns true 15 class bool_ref { 16 public: 17 bool_ref() = default; 18 ~bool_ref() = default; 19 20 operator bool() { return m_ref ? *m_ref : true; } 21 bool operator=( bool val ) { assert(m_ref); return *m_ref = val; } 22 23 private: 24 25 friend class visit_children_guard; 26 27 bool * set( bool * val ) { 28 bool * prev = m_ref; 29 m_ref = val; 30 return prev; 31 } 32 33 bool * m_ref = nullptr; 34 }; 35 36 // Implementation of the guard value 37 // Created inside the visit scope 38 class guard_value { 39 public: 40 guard_value( at_cleanup_t * at_cleanup ) { 41 if( at_cleanup ) { 42 *at_cleanup = [this]( cleanup_func_t && func, void* val ) { 43 push( std::move( func ), val ); 44 }; 45 } 46 } 47 48 ~guard_value() { 49 while( !cleanups.empty() ) { 50 auto& cleanup = cleanups.top(); 51 cleanup.func( cleanup.val ); 52 cleanups.pop(); 53 } 54 } 55 56 void push( cleanup_func_t && func, void* val ) { 57 cleanups.emplace( std::move(func), val ); 58 } 59 60 private: 61 struct cleanup_t { 62 cleanup_func_t func; 63 void * val; 64 65 cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {} 66 }; 67 68 std::stack< cleanup_t > cleanups; 69 }; 70 71 // Guard structure implementation for whether or not children should be visited 72 class visit_children_guard { 73 public: 74 75 visit_children_guard( bool_ref * ref ) 76 : m_val ( true ) 77 , m_prev( ref ? ref->set( &m_val ) : nullptr ) 78 , m_ref ( ref ) 79 {} 80 81 ~visit_children_guard() { 82 if( m_ref ) { 83 m_ref->set( m_prev ); 84 } 85 } 86 87 operator bool() { return m_val; } 88 89 private: 90 bool m_val; 91 bool * m_prev; 92 bool_ref * m_ref; 93 }; 94 95 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 96 // Deep magic (a.k.a template meta programming) to make the templated visitor work 97 // Basically the goal is to make 2 previsit 98 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 99 // 'pass.previsit( node )' that compiles will be used for that node for that type 100 // This requires that this option only compile for passes that actually define an appropriate visit. 101 // SFINAE will make sure the compilation errors in this function don't halt the build. 102 // See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE 103 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing. 104 // This is needed only to eliminate the need for passes to specify any kind of handlers. 105 // The second implementation only works because it has a lower priority. This is due to the bogus last parameter. 106 // The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0 107 // the first implementation takes priority in regards to overloading. 108 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 109 // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call 110 template<typename pass_t, typename node_t> 111 static inline auto previsit( pass_t & pass, const node_t * & node, int ) -> decltype( pass.previsit( node ), void() ) { 112 node = pass.previsit( node ); 113 assert(node); 46 114 } 47 115 48 bool * m_ref = nullptr; 49 }; 50 51 // Implementation of the guard value 52 // Created inside the visit scope 53 class guard_value { 54 public: 55 /// Push onto the cleanup 56 guard_value( at_cleanup_t * at_cleanup ) { 57 if( at_cleanup ) { 58 *at_cleanup = [this]( cleanup_func_t && func, void* val ) { 59 push( std::move( func ), val ); 60 }; 61 } 116 template<typename pass_t, typename node_t> 117 static inline auto previsit( pass_t &, const node_t *, long ) {} 118 119 // PostVisit : never mutates the passed pointer but may return a different node 120 template<typename pass_t, typename node_t> 121 static inline auto postvisit( pass_t & pass, const node_t * node, int ) -> decltype( pass.postvisit( node ), (const node_t *)nullptr ) { 122 return pass.postvisit( node ); 62 123 } 63 124 64 ~guard_value() { 65 while( !cleanups.empty() ) { 66 auto& cleanup = cleanups.top(); 67 cleanup.func( cleanup.val ); 68 cleanups.pop(); 69 } 70 } 71 72 void push( cleanup_func_t && func, void* val ) { 73 cleanups.emplace( std::move(func), val ); 74 } 75 76 private: 77 struct cleanup_t { 78 cleanup_func_t func; 79 void * val; 80 81 cleanup_t( cleanup_func_t&& func, void * val ) : func(func), val(val) {} 82 }; 83 84 std::stack< cleanup_t > cleanups; 85 }; 86 87 // Guard structure implementation for whether or not children should be visited 88 class visit_children_guard { 89 public: 90 91 visit_children_guard( bool_ref * ref ) 92 : m_val ( true ) 93 , m_prev( ref ? ref->set( &m_val ) : nullptr ) 94 , m_ref ( ref ) 95 {} 96 97 ~visit_children_guard() { 98 if( m_ref ) { 99 m_ref->set( m_prev ); 100 } 101 } 102 103 operator bool() { return m_val; } 104 105 private: 106 bool m_val; 107 bool * m_prev; 108 bool_ref * m_ref; 109 }; 110 111 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 112 // Deep magic (a.k.a template meta programming) to make the templated visitor work 113 // Basically the goal is to make 2 previsit 114 // 1 - Use when a pass implements a valid previsit. This uses overloading which means the any overload of 115 // 'pass.previsit( node )' that compiles will be used for that node for that type 116 // This requires that this option only compile for passes that actually define an appropriate visit. 117 // SFINAE will make sure the compilation errors in this function don't halt the build. 118 // See http://en.cppreference.com/w/cpp/language/sfinae for details on SFINAE 119 // 2 - Since the first implementation might not be specilizable, the second implementation exists and does nothing. 120 // This is needed only to eliminate the need for passes to specify any kind of handlers. 121 // The second implementation only works because it has a lower priority. This is due to the bogus last parameter. 122 // The second implementation takes a long while the first takes an int. Since the caller always passes an literal 0 123 // the first implementation takes priority in regards to overloading. 124 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 125 // PreVisit : may mutate the pointer passed in if the node is mutated in the previsit call 126 template<typename pass_t, typename node_t> 127 static inline auto previsit( pass_t & pass, const node_t * & node, int ) -> decltype( pass.previsit( node ), void() ) { 128 node = pass.previsit( node ); 129 assert(node); 130 } 131 132 template<typename pass_t, typename node_t> 133 static inline auto previsit( pass_t &, const node_t *, long ) {} 134 135 // PostVisit : never mutates the passed pointer but may return a different node 136 template<typename pass_t, typename node_t> 137 static inline auto postvisit( pass_t & pass, const node_t * node, int ) -> decltype( pass.postvisit( node ), (const node_t *)nullptr ) { 138 return pass.postvisit( node ); 139 } 140 141 template<typename pass_t, typename node_t> 142 static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; } 143 144 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 145 // Deep magic (a.k.a template meta programming) continued 146 // To make the templated visitor be more expressive, we allow 'accessories' : classes/structs the implementation can inherit 147 // from in order to get extra functionallity for example 148 // class ErrorChecker : WithShortCircuiting { ... }; 149 // Pass<ErrorChecker> checker; 150 // this would define a pass that uses the templated visitor with the additionnal feature that it has short circuiting 151 // Note that in all cases the accessories are not required but guarantee the requirements of the feature is matched 152 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 153 // For several accessories, the feature is enabled by detecting that a specific field is present 154 // Use a macro the encapsulate the logic of detecting a particular field 155 // The type is not strictly enforced but does match the accessory 156 #define FIELD_PTR( name, default_type ) \ 157 template< typename pass_t > \ 158 static inline auto name( pass_t & pass, int ) -> decltype( &pass.name ) { return &pass.name; } \ 159 \ 160 template< typename pass_t > \ 161 static inline default_type * name( pass_t &, long ) { return nullptr; } 162 163 // List of fields and their expected types 164 FIELD_PTR( env, const ast::TypeSubstitution ) 165 FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > ) 166 FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > ) 167 FIELD_PTR( declsToAddBefore, std::list< ast::ptr< ast::Decl > > ) 168 FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > ) 169 FIELD_PTR( visit_children, __pass::bool_ref ) 170 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 171 FIELD_PTR( visitor, ast::Pass<pass_t> * const ) 172 173 // Remove the macro to make sure we don't clash 174 #undef FIELD_PTR 175 176 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 177 // All passes which have such functions are assumed desire this behaviour 178 // detect it using the same strategy 179 namespace scope { 180 template<typename pass_t> 181 static inline auto enter( pass_t & pass, int ) -> decltype( pass.beginScope(), void() ) { 182 pass.beginScope(); 183 } 184 185 template<typename pass_t> 186 static inline void enter( pass_t &, long ) {} 187 188 template<typename pass_t> 189 static inline auto leave( pass_t & pass, int ) -> decltype( pass.endScope(), void() ) { 190 pass.endScope(); 191 } 192 193 template<typename pass_t> 194 static inline void leave( pass_t &, long ) {} 195 }; 196 197 // Finally certain pass desire an up to date indexer automatically 198 // detect the presence of a member name indexer and call all the members appropriately 199 namespace indexer { 200 // Some simple scoping rules 201 template<typename pass_t> 202 static inline auto enter( pass_t & pass, int ) -> decltype( pass.indexer.enterScope(), void() ) { 203 pass.indexer.enterScope(); 204 } 205 206 template<typename pass_t> 207 static inline auto enter( pass_t &, long ) {} 208 209 template<typename pass_t> 210 static inline auto leave( pass_t & pass, int ) -> decltype( pass.indexer.leaveScope(), void() ) { 211 pass.indexer.leaveScope(); 212 } 213 214 template<typename pass_t> 215 static inline auto leave( pass_t &, long ) {} 216 217 // The indexer has 2 kind of functions mostly, 1 argument and 2 arguments 218 // Create macro to condense these common patterns 219 #define INDEXER_FUNC1( func, type ) \ 220 template<typename pass_t> \ 221 static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) {\ 222 pass.indexer.func( arg ); \ 223 } \ 125 template<typename pass_t, typename node_t> 126 static inline const node_t * postvisit( pass_t &, const node_t * node, long ) { return node; } 127 128 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 129 // Deep magic (a.k.a template meta programming) continued 130 // To make the templated visitor be more expressive, we allow 'accessories' : classes/structs the implementation can inherit 131 // from in order to get extra functionallity for example 132 // class ErrorChecker : WithShortCircuiting { ... }; 133 // Pass<ErrorChecker> checker; 134 // this would define a pass that uses the templated visitor with the additionnal feature that it has short circuiting 135 // Note that in all cases the accessories are not required but guarantee the requirements of the feature is matched 136 //------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 137 // For several accessories, the feature is enabled by detecting that a specific field is present 138 // Use a macro the encapsulate the logic of detecting a particular field 139 // The type is not strictly enforced but does match the accessory 140 #define FIELD_PTR( name, default_type ) \ 141 template< typename pass_t > \ 142 static inline auto name( pass_t & pass, int ) -> decltype( &pass.name ) { return &pass.name; } \ 224 143 \ 225 template<typename pass_t> \ 226 static inline void func( pass_t &, long, type ) {} 227 228 #define INDEXER_FUNC2( func, type1, type2 ) \ 229 template<typename pass_t> \ 230 static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.indexer.func( arg1, arg2 ), void () ) {\ 231 pass.indexer.func( arg1, arg2 ); \ 232 } \ 144 template< typename pass_t > \ 145 static inline default_type * name( pass_t &, long ) { return nullptr; } 146 147 // List of fields and their expected types 148 FIELD_PTR( env, const ast::TypeSubstitution ) 149 FIELD_PTR( stmtsToAddBefore, std::list< ast::ptr< ast::Stmt > > ) 150 FIELD_PTR( stmtsToAddAfter , std::list< ast::ptr< ast::Stmt > > ) 151 FIELD_PTR( declsToAddBefore, std::list< ast::ptr< ast::Decl > > ) 152 FIELD_PTR( declsToAddAfter , std::list< ast::ptr< ast::Decl > > ) 153 FIELD_PTR( visit_children, __pass::bool_ref ) 154 FIELD_PTR( at_cleanup, __pass::at_cleanup_t ) 155 FIELD_PTR( visitor, ast::Pass<pass_t> * const ) 156 157 // Remove the macro to make sure we don't clash 158 #undef FIELD_PTR 159 160 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 161 // All passes which have such functions are assumed desire this behaviour 162 // detect it using the same strategy 163 namespace scope { 164 template<typename pass_t> 165 static inline auto enter( pass_t & pass, int ) -> decltype( pass.beginScope(), void() ) { 166 pass.beginScope(); 167 } 168 169 template<typename pass_t> 170 static inline void enter( pass_t &, long ) {} 171 172 template<typename pass_t> 173 static inline auto leave( pass_t & pass, int ) -> decltype( pass.endScope(), void() ) { 174 pass.endScope(); 175 } 176 177 template<typename pass_t> 178 static inline void leave( pass_t &, long ) {} 179 }; 180 181 // Finally certain pass desire an up to date indexer automatically 182 // detect the presence of a member name indexer and call all the members appropriately 183 namespace indexer { 184 // Some simple scoping rules 185 template<typename pass_t> 186 static inline auto enter( pass_t & pass, int ) -> decltype( pass.indexer.enterScope(), void() ) { 187 pass.indexer.enterScope(); 188 } 189 190 template<typename pass_t> 191 static inline auto enter( pass_t &, long ) {} 192 193 template<typename pass_t> 194 static inline auto leave( pass_t & pass, int ) -> decltype( pass.indexer.leaveScope(), void() ) { 195 pass.indexer.leaveScope(); 196 } 197 198 template<typename pass_t> 199 static inline auto leave( pass_t &, long ) {} 200 201 // The indexer has 2 kind of functions mostly, 1 argument and 2 arguments 202 // Create macro to condense these common patterns 203 #define INDEXER_FUNC1( func, type ) \ 204 template<typename pass_t> \ 205 static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) {\ 206 pass.indexer.func( arg ); \ 207 } \ 233 208 \ 234 template<typename pass_t> \ 235 static inline void func( pass_t &, long, type1, type2 ) {} 236 237 INDEXER_FUNC1( addId , DeclWithType * ); 238 INDEXER_FUNC1( addType , NamedTypeDecl * ); 239 INDEXER_FUNC1( addStruct , StructDecl * ); 240 INDEXER_FUNC1( addEnum , EnumDecl * ); 241 INDEXER_FUNC1( addUnion , UnionDecl * ); 242 INDEXER_FUNC1( addTrait , TraitDecl * ); 243 INDEXER_FUNC2( addWith , std::list< Expression * > &, Node * ); 244 245 // A few extra functions have more complicated behaviour, they are hand written 246 // template<typename pass_t> 247 // static inline auto addStructFwd( pass_t & pass, int, ast::StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 248 // ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 249 // fwd->parameters = decl->parameters; 250 // pass.indexer.addStruct( fwd ); 251 // } 252 253 // template<typename pass_t> 254 // static inline void addStructFwd( pass_t &, long, ast::StructDecl * ) {} 255 256 // template<typename pass_t> 257 // static inline auto addUnionFwd( pass_t & pass, int, ast::UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 258 // UnionDecl * fwd = new UnionDecl( decl->name ); 259 // fwd->parameters = decl->parameters; 260 // pass.indexer.addUnion( fwd ); 261 // } 262 263 // template<typename pass_t> 264 // static inline void addUnionFwd( pass_t &, long, ast::UnionDecl * ) {} 265 266 // template<typename pass_t> 267 // static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) { 268 // if ( ! pass.indexer.lookupStruct( str ) ) { 269 // pass.indexer.addStruct( str ); 270 // } 271 // } 272 273 // template<typename pass_t> 274 // static inline void addStruct( pass_t &, long, const std::string & ) {} 275 276 // template<typename pass_t> 277 // static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) { 278 // if ( ! pass.indexer.lookupUnion( str ) ) { 279 // pass.indexer.addUnion( str ); 280 // } 281 // } 282 283 // template<typename pass_t> 284 // static inline void addUnion( pass_t &, long, const std::string & ) {} 285 286 #undef INDEXER_FUNC1 287 #undef INDEXER_FUNC2 209 template<typename pass_t> \ 210 static inline void func( pass_t &, long, type ) {} 211 212 #define INDEXER_FUNC2( func, type1, type2 ) \ 213 template<typename pass_t> \ 214 static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.indexer.func( arg1, arg2 ), void () ) {\ 215 pass.indexer.func( arg1, arg2 ); \ 216 } \ 217 \ 218 template<typename pass_t> \ 219 static inline void func( pass_t &, long, type1, type2 ) {} 220 221 INDEXER_FUNC1( addId , DeclarationWithType * ); 222 INDEXER_FUNC1( addType , NamedTypeDecl * ); 223 INDEXER_FUNC1( addStruct , StructDecl * ); 224 INDEXER_FUNC1( addEnum , EnumDecl * ); 225 INDEXER_FUNC1( addUnion , UnionDecl * ); 226 INDEXER_FUNC1( addTrait , TraitDecl * ); 227 INDEXER_FUNC2( addWith , std::list< Expression * > &, BaseSyntaxNode * ); 228 229 // A few extra functions have more complicated behaviour, they are hand written 230 template<typename pass_t> 231 static inline auto addStructFwd( pass_t & pass, int, ast::StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 232 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 233 fwd->parameters = decl->parameters; 234 pass.indexer.addStruct( fwd ); 235 } 236 237 template<typename pass_t> 238 static inline void addStructFwd( pass_t &, long, ast::StructDecl * ) {} 239 240 template<typename pass_t> 241 static inline auto addUnionFwd( pass_t & pass, int, ast::UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 242 UnionDecl * fwd = new UnionDecl( decl->name ); 243 fwd->parameters = decl->parameters; 244 pass.indexer.addUnion( fwd ); 245 } 246 247 template<typename pass_t> 248 static inline void addUnionFwd( pass_t &, long, ast::UnionDecl * ) {} 249 250 template<typename pass_t> 251 static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) { 252 if ( ! pass.indexer.lookupStruct( str ) ) { 253 pass.indexer.addStruct( str ); 254 } 255 } 256 257 template<typename pass_t> 258 static inline void addStruct( pass_t &, long, const std::string & ) {} 259 260 template<typename pass_t> 261 static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) { 262 if ( ! pass.indexer.lookupUnion( str ) ) { 263 pass.indexer.addUnion( str ); 264 } 265 } 266 267 template<typename pass_t> 268 static inline void addUnion( pass_t &, long, const std::string & ) {} 269 270 #undef INDEXER_FUNC1 271 #undef INDEXER_FUNC2 272 }; 288 273 }; 289 274 }; 290 }; -
src/AST/Stmt.hpp
r4ab0669 r1531ef5 89 89 90 90 91 //=================================================================================================92 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency93 /// remove only if there is a better solution94 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with95 /// forward declarations96 inline void increment( const class Stmt * node, Node::ref_type ref ) { node->increment( ref ); }97 inline void decrement( const class Stmt * node, Node::ref_type ref ) { node->decrement( ref ); }98 inline void increment( const class CompoundStmt * node, Node::ref_type ref ) { node->increment( ref ); }99 inline void decrement( const class CompoundStmt * node, Node::ref_type ref ) { node->decrement( ref ); }100 inline void increment( const class ExprStmt * node, Node::ref_type ref ) { node->increment( ref ); }101 inline void decrement( const class ExprStmt * node, Node::ref_type ref ) { node->decrement( ref ); }102 inline void increment( const class AsmStmt * node, Node::ref_type ref ) { node->increment( ref ); }103 inline void decrement( const class AsmStmt * node, Node::ref_type ref ) { node->decrement( ref ); }104 inline void increment( const class DirectiveStmt * node, Node::ref_type ref ) { node->increment( ref ); }105 inline void decrement( const class DirectiveStmt * node, Node::ref_type ref ) { node->decrement( ref ); }106 inline void increment( const class IfStmt * node, Node::ref_type ref ) { node->increment( ref ); }107 inline void decrement( const class IfStmt * node, Node::ref_type ref ) { node->decrement( ref ); }108 inline void increment( const class WhileStmt * node, Node::ref_type ref ) { node->increment( ref ); }109 inline void decrement( const class WhileStmt * node, Node::ref_type ref ) { node->decrement( ref ); }110 inline void increment( const class ForStmt * node, Node::ref_type ref ) { node->increment( ref ); }111 inline void decrement( const class ForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }112 inline void increment( const class SwitchStmt * node, Node::ref_type ref ) { node->increment( ref ); }113 inline void decrement( const class SwitchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }114 inline void increment( const class CaseStmt * node, Node::ref_type ref ) { node->increment( ref ); }115 inline void decrement( const class CaseStmt * node, Node::ref_type ref ) { node->decrement( ref ); }116 inline void increment( const class BranchStmt * node, Node::ref_type ref ) { node->increment( ref ); }117 inline void decrement( const class BranchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }118 inline void increment( const class ReturnStmt * node, Node::ref_type ref ) { node->increment( ref ); }119 inline void decrement( const class ReturnStmt * node, Node::ref_type ref ) { node->decrement( ref ); }120 inline void increment( const class ThrowStmt * node, Node::ref_type ref ) { node->increment( ref ); }121 inline void decrement( const class ThrowStmt * node, Node::ref_type ref ) { node->decrement( ref ); }122 inline void increment( const class TryStmt * node, Node::ref_type ref ) { node->increment( ref ); }123 inline void decrement( const class TryStmt * node, Node::ref_type ref ) { node->decrement( ref ); }124 inline void increment( const class CatchStmt * node, Node::ref_type ref ) { node->increment( ref ); }125 inline void decrement( const class CatchStmt * node, Node::ref_type ref ) { node->decrement( ref ); }126 inline void increment( const class FinallyStmt * node, Node::ref_type ref ) { node->increment( ref ); }127 inline void decrement( const class FinallyStmt * node, Node::ref_type ref ) { node->decrement( ref ); }128 inline void increment( const class WaitForStmt * node, Node::ref_type ref ) { node->increment( ref ); }129 inline void decrement( const class WaitForStmt * node, Node::ref_type ref ) { node->decrement( ref ); }130 inline void increment( const class WithStmt * node, Node::ref_type ref ) { node->increment( ref ); }131 inline void decrement( const class WithStmt * node, Node::ref_type ref ) { node->decrement( ref ); }132 inline void increment( const class DeclStmt * node, Node::ref_type ref ) { node->increment( ref ); }133 inline void decrement( const class DeclStmt * node, Node::ref_type ref ) { node->decrement( ref ); }134 inline void increment( const class NullStmt * node, Node::ref_type ref ) { node->increment( ref ); }135 inline void decrement( const class NullStmt * node, Node::ref_type ref ) { node->decrement( ref ); }136 inline void increment( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->increment( ref ); }137 inline void decrement( const class ImplicitCtorDtorStmt * node, Node::ref_type ref ) { node->decrement( ref ); }138 139 91 } 140 92 -
src/AST/StorageClasses.hpp
r4ab0669 r1531ef5 33 33 34 34 /// Bitflag type for storage classes 35 struct class_flags { 36 union { 37 unsigned int val; 38 struct { 39 bool is_extern : 1; 40 bool is_static : 1; 41 bool is_auto : 1; 42 bool is_register : 1; 43 bool is_threadlocal : 1; 44 }; 45 46 // MakeBitfieldPrint( NumClasses ) 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; 47 43 }; 48 44 49 constexpr class_flags( unsigned int val ) : val(val) {} 45 MakeBitfield( Classes ) 46 MakeBitfieldPrint( NumClasses ) 50 47 }; 51 48 52 using Classes = bitfield<class_flags>;53 49 } 54 50 } -
src/AST/Type.hpp
r4ab0669 r1531ef5 24 24 }; 25 25 26 27 28 //=================================================================================================29 /// This disgusting and giant piece of boiler-plate is here to solve a cyclic dependency30 /// remove only if there is a better solution31 /// The problem is that ast::ptr< ... > uses increment/decrement which won't work well with32 /// forward declarations33 inline void increment( const class Type * node, Node::ref_type ref ) { node->increment( ref ); }34 inline void decrement( const class Type * node, Node::ref_type ref ) { node->decrement( ref ); }35 inline void increment( const class VoidType * node, Node::ref_type ref ) { node->increment( ref ); }36 inline void decrement( const class VoidType * node, Node::ref_type ref ) { node->decrement( ref ); }37 inline void increment( const class BasicType * node, Node::ref_type ref ) { node->increment( ref ); }38 inline void decrement( const class BasicType * node, Node::ref_type ref ) { node->decrement( ref ); }39 inline void increment( const class PointerType * node, Node::ref_type ref ) { node->increment( ref ); }40 inline void decrement( const class PointerType * node, Node::ref_type ref ) { node->decrement( ref ); }41 inline void increment( const class ArrayType * node, Node::ref_type ref ) { node->increment( ref ); }42 inline void decrement( const class ArrayType * node, Node::ref_type ref ) { node->decrement( ref ); }43 inline void increment( const class ReferenceType * node, Node::ref_type ref ) { node->increment( ref ); }44 inline void decrement( const class ReferenceType * node, Node::ref_type ref ) { node->decrement( ref ); }45 inline void increment( const class QualifiedType * node, Node::ref_type ref ) { node->increment( ref ); }46 inline void decrement( const class QualifiedType * node, Node::ref_type ref ) { node->decrement( ref ); }47 inline void increment( const class FunctionType * node, Node::ref_type ref ) { node->increment( ref ); }48 inline void decrement( const class FunctionType * node, Node::ref_type ref ) { node->decrement( ref ); }49 inline void increment( const class ReferenceToType * node, Node::ref_type ref ) { node->increment( ref ); }50 inline void decrement( const class ReferenceToType * node, Node::ref_type ref ) { node->decrement( ref ); }51 inline void increment( const class StructInstType * node, Node::ref_type ref ) { node->increment( ref ); }52 inline void decrement( const class StructInstType * node, Node::ref_type ref ) { node->decrement( ref ); }53 inline void increment( const class UnionInstType * node, Node::ref_type ref ) { node->increment( ref ); }54 inline void decrement( const class UnionInstType * node, Node::ref_type ref ) { node->decrement( ref ); }55 inline void increment( const class EnumInstType * node, Node::ref_type ref ) { node->increment( ref ); }56 inline void decrement( const class EnumInstType * node, Node::ref_type ref ) { node->decrement( ref ); }57 inline void increment( const class TraitInstType * node, Node::ref_type ref ) { node->increment( ref ); }58 inline void decrement( const class TraitInstType * node, Node::ref_type ref ) { node->decrement( ref ); }59 inline void increment( const class TypeInstType * node, Node::ref_type ref ) { node->increment( ref ); }60 inline void decrement( const class TypeInstType * node, Node::ref_type ref ) { node->decrement( ref ); }61 inline void increment( const class TupleType * node, Node::ref_type ref ) { node->increment( ref ); }62 inline void decrement( const class TupleType * node, Node::ref_type ref ) { node->decrement( ref ); }63 inline void increment( const class TypeofType * node, Node::ref_type ref ) { node->increment( ref ); }64 inline void decrement( const class TypeofType * node, Node::ref_type ref ) { node->decrement( ref ); }65 inline void increment( const class AttrType * node, Node::ref_type ref ) { node->increment( ref ); }66 inline void decrement( const class AttrType * node, Node::ref_type ref ) { node->decrement( ref ); }67 inline void increment( const class VarArgsType * node, Node::ref_type ref ) { node->increment( ref ); }68 inline void decrement( const class VarArgsType * node, Node::ref_type ref ) { node->decrement( ref ); }69 inline void increment( const class ZeroType * node, Node::ref_type ref ) { node->increment( ref ); }70 inline void decrement( const class ZeroType * node, Node::ref_type ref ) { node->decrement( ref ); }71 inline void increment( const class OneType * node, Node::ref_type ref ) { node->increment( ref ); }72 inline void decrement( const class OneType * node, Node::ref_type ref ) { node->decrement( ref ); }73 inline void increment( const class GlobalScopeType * node, Node::ref_type ref ) { node->increment( ref ); }74 inline void decrement( const class GlobalScopeType * node, Node::ref_type ref ) { node->decrement( ref ); }75 76 26 } 77 27 -
src/Common/PassVisitor.impl.h
r4ab0669 r1531ef5 168 168 template< typename Container, typename pass_type > 169 169 inline void maybeMutate_impl( Container & container, PassVisitor< pass_type > & mutator ) { 170 171 170 if ( ! mutator.get_visit_children() ) return; 172 171 SemanticErrorException errors; … … 218 217 try { 219 218 func( *i ); 220 assert( *i );221 219 assert(( empty( beforeStmts ) && empty( afterStmts )) 222 220 || ( empty( beforeDecls ) && empty( afterDecls )) ); -
src/Common/PassVisitor.proto.h
r4ab0669 r1531ef5 222 222 INDEXER_FUNC2( addWith , std::list< Expression * > &, BaseSyntaxNode * ); 223 223 224 #undef INDEXER_FUNC1225 #undef INDEXER_FUNC2226 224 227 225 template<typename pass_type> -
src/SynTree/Declaration.h
r4ab0669 r1531ef5 71 71 static Declaration *declFromId( UniqueId id ); 72 72 73 private: 74 Type::StorageClasses storageClasses; 73 75 UniqueId uniqueId; 74 Type::StorageClasses storageClasses;75 private:76 76 }; 77 77 … … 213 213 TypeDecl::Kind kind; 214 214 bool isComplete; 215 215 216 216 Data() : kind( (TypeDecl::Kind)-1 ), isComplete( false ) {} 217 217 Data( TypeDecl * typeDecl ) : Data( typeDecl->get_kind(), typeDecl->isComplete() ) {} 218 218 Data( Kind kind, bool isComplete ) : kind( kind ), isComplete( isComplete ) {} 219 Data( const Data& d1, const Data& d2 ) 219 Data( const Data& d1, const Data& d2 ) 220 220 : kind( d1.kind ), isComplete ( d1.isComplete || d2.isComplete ) {} 221 221
Note:
See TracChangeset
for help on using the changeset viewer.