- Timestamp:
- Oct 19, 2022, 4:43:26 PM (3 years ago)
- Branches:
- ADT, ast-experimental, master
- Children:
- 1a45263
- Parents:
- 9cd5bd2 (diff), 135143ba (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
- Files:
-
- 1 added
- 48 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r9cd5bd2 rdf6cc9d 310 310 node->name, 311 311 get<Attribute>().acceptL( node->attributes ), 312 false, // Temporary312 node->isTyped, 313 313 LinkageSpec::Spec( node->linkage.val ), 314 314 get<Type>().accept1(node->base) 315 315 ); 316 return aggregatePostamble( decl, node ); // Node info, including members, processed in aggregatePostamble316 return aggregatePostamble( decl, node ); 317 317 } 318 318 … … 737 737 node->name 738 738 ); 739 temp->var = get<DeclarationWithType>().accept1(node->var);740 739 auto expr = visitBaseExpr( node, 741 740 temp … … 1615 1614 { old->get_funcSpec().val } 1616 1615 ); 1616 decl->enumInLine = old->enumInLine; 1617 1617 cache.emplace(old, decl); 1618 1618 assert(cache.find( old ) != cache.end()); … … 2281 2281 } 2282 2282 2283 /// xxx - type_decl should be DeclWithType in the final design2284 /// type_decl is set to EnumDecl as a temporary fix2285 2283 virtual void visit( const QualifiedNameExpr * old ) override final { 2286 2284 this->node = visitBaseExpr( old, … … 2288 2286 old->location, 2289 2287 GET_ACCEPT_1(type_decl, Decl), 2290 GET_ACCEPT_1(var, DeclWithType),2291 2288 old->name 2292 2289 ) -
src/AST/Decl.cpp
r9cd5bd2 rdf6cc9d 58 58 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage, 59 59 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 60 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 61 type_params(std::move(forall)), stmts( stmts ) { 60 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), 61 type_params(std::move(forall)), assertions(), 62 params(std::move(params)), returns(std::move(returns)), stmts( stmts ) { 62 63 FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs)); 63 64 for (auto & param : this->params) { … … 82 83 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs) 83 84 : DeclWithType( location, name, storage, linkage, std::move(attrs), fs ), 85 type_params( std::move( forall) ), assertions( std::move( assertions ) ), 84 86 params( std::move(params) ), returns( std::move(returns) ), 85 type_params( std::move( forall) ), assertions( std::move( assertions ) ),86 87 type( nullptr ), stmts( stmts ) { 87 88 FunctionType * type = new FunctionType( (isVarArgs) ? VariableArgs : FixedArgs ); … … 162 163 163 164 auto it = enumValues.find( enumerator->name ); 164 165 165 166 if ( it != enumValues.end() ) { 166 167 167 168 // Handle typed enum by casting the value in (C++) compiler 168 169 // if ( base ) { // A typed enum … … 179 180 // case BasicType::Kind::LongUnsignedInt: value = (long unsigned int) it->second; break; 180 181 // case BasicType::Kind::LongLongSignedInt: value = (long long signed int) it->second; break; 181 // case BasicType::Kind::LongLongUnsignedInt: value = (long long unsigned int) it->second; break; 182 // case BasicType::Kind::LongLongUnsignedInt: value = (long long unsigned int) it->second; break; 182 183 // // TODO: value should be able to handle long long unsigned int 183 184 -
src/AST/Decl.hpp
r9cd5bd2 rdf6cc9d 105 105 ptr<Init> init; 106 106 ptr<Expr> bitfieldWidth; 107 bool enumInLine = false; // enum inline is not a real object declaration. 108 // It is a place holder for a set of enum value (ObjectDecl) 109 bool importValue = false; // if the value copied from somewhere else 107 110 108 111 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, … … 125 128 class FunctionDecl : public DeclWithType { 126 129 public: 130 std::vector<ptr<TypeDecl>> type_params; 131 std::vector<ptr<DeclWithType>> assertions; 127 132 std::vector<ptr<DeclWithType>> params; 128 133 std::vector<ptr<DeclWithType>> returns; 129 std::vector<ptr<TypeDecl>> type_params;130 std::vector<ptr<DeclWithType>> assertions;131 134 // declared type, derived from parameter declarations 132 135 ptr<FunctionType> type; … … 312 315 class EnumDecl final : public AggregateDecl { 313 316 public: 314 bool isTyped; 315 ptr<Type> base; 317 bool isTyped; // isTyped indicated if the enum has a declaration like: 318 // enum (type_optional) Name {...} 319 ptr<Type> base; // if isTyped == true && base.get() == nullptr, it is a "void" type enum 316 320 317 321 EnumDecl( const CodeLocation& loc, const std::string& name, bool isTyped = false, -
src/AST/Expr.cpp
r9cd5bd2 rdf6cc9d 22 22 #include "Copy.hpp" // for shallowCopy 23 23 #include "GenericSubstitution.hpp" 24 #include "Inspect.hpp" 24 25 #include "LinkageSpec.hpp" 25 26 #include "Stmt.hpp" … … 29 30 #include "Common/SemanticError.h" 30 31 #include "GenPoly/Lvalue.h" // for referencesPermissable 31 #include "InitTweak/InitTweak.h" // for getFunction, getPointerBase32 32 #include "ResolvExpr/typeops.h" // for extractResultType 33 33 #include "Tuples/Tuples.h" // for makeTupleType … … 58 58 59 59 bool ApplicationExpr::get_lvalue() const { 60 if ( const DeclWithType * func = InitTweak::getFunction( this ) ) {60 if ( const DeclWithType * func = getFunction( this ) ) { 61 61 return func->linkage == Linkage::Intrinsic && lvalueFunctionNames.count( func->name ); 62 62 } … … 67 67 68 68 bool UntypedExpr::get_lvalue() const { 69 std::string fname = InitTweak::getFunctionName( this );69 std::string fname = getFunctionName( this ); 70 70 return lvalueFunctionNames.count( fname ); 71 71 } … … 76 76 UntypedExpr * ret = createCall( loc, "*?", { arg } ); 77 77 if ( const Type * ty = arg->result ) { 78 const Type * base = InitTweak::getPointerBase( ty );78 const Type * base = getPointerBase( ty ); 79 79 assertf( base, "expected pointer type in dereference (type was %s)", toString( ty ).c_str() ); 80 80 … … 335 335 // first argument 336 336 assert( callExpr ); 337 const Expr * arg = InitTweak::getCallArg( callExpr, 0 );337 const Expr * arg = getCallArg( callExpr, 0 ); 338 338 assert( arg ); 339 339 result = arg->result; -
src/AST/Expr.hpp
r9cd5bd2 rdf6cc9d 257 257 public: 258 258 ptr<Decl> type_decl; 259 ptr<DeclWithType> var;260 259 std::string name; 261 260 262 QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const DeclWithType * r, conststd::string & n )263 : Expr( loc ), type_decl( d ), var(r),name( n ) {}261 QualifiedNameExpr( const CodeLocation & loc, const Decl * d, const std::string & n ) 262 : Expr( loc ), type_decl( d ), name( n ) {} 264 263 265 264 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Inspect.cpp
r9cd5bd2 rdf6cc9d 10 10 // Created On : Fri Jun 24 13:16:31 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 27 15:35:00 202213 // Update Count : 112 // Last Modified On : Mon Oct 3 11:04:00 2022 13 // Update Count : 3 14 14 // 15 15 16 #include "AST/Decl.hpp" 17 #include "AST/Type.hpp" 16 #include "Inspect.hpp" 18 17 19 18 #include <iostream> 20 #include <AST/Print.hpp> 19 #include <iterator> 20 21 #include "AST/Decl.hpp" 22 #include "AST/Expr.hpp" 23 #include "AST/Print.hpp" 24 #include "AST/Stmt.hpp" 25 #include "AST/Type.hpp" 26 #include "CodeGen/OperatorTable.h" 21 27 22 28 namespace ast { 29 30 const Type * getPointerBase( const Type * type ) { 31 if ( const auto * p = dynamic_cast< const PointerType * >( type ) ) { 32 return p->base; 33 } else if ( auto a = dynamic_cast< const ArrayType * >( type ) ) { 34 return a->base; 35 } else if ( auto r = dynamic_cast< const ReferenceType * >( type ) ) { 36 return r->base; 37 } else { 38 return nullptr; 39 } 40 } 41 42 template<typename CallExpr, typename Ret> 43 static Ret throughDeref( const CallExpr * expr, Ret(*func)( const Expr * ) ) { 44 // In `(*f)(x)` the function we want is `f`. 45 std::string name = getFunctionName( expr ); 46 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() ); 47 assertf( !expr->args.empty(), "Cannot pass through dereference with no arguments." ); 48 return func( expr->args.front() ); 49 } 50 51 static const DeclWithType * getCalledFunction( const Expr * expr ) { 52 assert( expr ); 53 if ( const auto * varExpr = dynamic_cast< const VariableExpr * >( expr ) ) { 54 return varExpr->var; 55 } else if ( auto memberExpr = dynamic_cast< const MemberExpr * >( expr ) ) { 56 return memberExpr->member; 57 } else if ( auto castExpr = dynamic_cast< const CastExpr * >( expr ) ) { 58 return getCalledFunction( castExpr->arg ); 59 } else if ( auto untypedExpr = dynamic_cast< const UntypedExpr * >( expr ) ) { 60 return throughDeref( untypedExpr, getCalledFunction ); 61 } else if ( auto appExpr = dynamic_cast< const ApplicationExpr * > ( expr ) ) { 62 return throughDeref( appExpr, getCalledFunction ); 63 } else if ( auto addrExpr = dynamic_cast< const AddressExpr * >( expr ) ) { 64 return getCalledFunction( addrExpr->arg ); 65 } else if ( auto commaExpr = dynamic_cast< const CommaExpr * >( expr ) ) { 66 return getCalledFunction( commaExpr->arg2 ); 67 } else { 68 return nullptr; 69 } 70 } 71 72 const DeclWithType * getFunction( const Expr * expr ) { 73 if ( auto app = dynamic_cast< const ApplicationExpr * >( expr ) ) { 74 return getCalledFunction( app->func ); 75 } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( expr ) ) { 76 return getCalledFunction( untyped->func ); 77 } else { 78 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() ); 79 } 80 } 81 82 // There is a lot of overlap with getCalledFunction. Ideally it would use 83 // it as a helper function and return the name of the DeclWithType. But the 84 // NameExpr and UntypedMemberExpr only work on this version. 85 static std::string funcName( const Expr * func ) { 86 assert( func ); 87 if ( const auto * nameExpr = dynamic_cast< const NameExpr * >( func ) ) { 88 return nameExpr->name; 89 } else if ( auto varExpr = dynamic_cast< const VariableExpr * >( func ) ) { 90 return varExpr->var->name; 91 } else if ( auto castExpr = dynamic_cast< const CastExpr * >( func ) ) { 92 return funcName( castExpr->arg ); 93 } else if ( auto memberExpr = dynamic_cast< const MemberExpr * >( func ) ) { 94 return memberExpr->member->name; 95 } else if ( auto memberExpr = dynamic_cast< const UntypedMemberExpr * >( func ) ) { 96 return funcName( memberExpr->member ); 97 } else if ( auto untypedExpr = dynamic_cast< const UntypedExpr * >( func ) ) { 98 return throughDeref( untypedExpr, funcName ); 99 } else if ( auto appExpr = dynamic_cast< const ApplicationExpr * >( func ) ) { 100 return throughDeref( appExpr, funcName ); 101 } else if ( auto ctorExpr = dynamic_cast< const ConstructorExpr * >( func ) ) { 102 return funcName( getCallArg( ctorExpr->callExpr, 0 ) ); 103 } else { 104 assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() ); 105 } 106 } 107 108 std::string getFunctionName( const Expr * expr ) { 109 // There's some unforunate overlap here with getFunction. See above. 110 if ( auto app = dynamic_cast< const ApplicationExpr * >( expr ) ) { 111 return funcName( app->func ); 112 } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( expr ) ) { 113 return funcName( untyped->func ); 114 } else { 115 assertf( false, "getFunctionName received unknown expression: %s", toString( expr ).c_str() ); 116 } 117 } 118 119 template<typename CallExpr> 120 static const Expr * callArg( const CallExpr * call, unsigned int pos ) { 121 assertf( pos < call->args.size(), 122 "callArg for argument that doesn't exist: (%u); %s.", 123 pos, toString( call ).c_str() ); 124 auto it = call->args.begin(); 125 std::advance( it, pos ); 126 return *it; 127 } 128 129 const Expr * getCallArg( const Expr * call, unsigned int pos ) { 130 if ( auto app = dynamic_cast< const ApplicationExpr * >( call ) ) { 131 return callArg( app, pos ); 132 } else if ( auto untyped = dynamic_cast< const UntypedExpr * >( call ) ) { 133 return callArg( untyped, pos ); 134 } else if ( auto tupleAssn = dynamic_cast< const TupleAssignExpr * >( call ) ) { 135 const std::list<ptr<Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids; 136 assertf( !stmts.empty(), "TupleAssignExpr missing statements." ); 137 auto stmt = stmts.back().strict_as< ExprStmt >(); 138 auto tuple = stmt->expr.strict_as< TupleExpr >(); 139 assertf( !tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr." ); 140 return getCallArg( tuple->exprs.front(), pos ); 141 } else if ( auto ctor = dynamic_cast< const ImplicitCopyCtorExpr * >( call ) ) { 142 return getCallArg( ctor->callExpr, pos ); 143 } else { 144 assertf( false, "Unexpected expression type passed to getCallArg: %s", toString( call ).c_str() ); 145 } 146 } 23 147 24 148 bool structHasFlexibleArray( const ast::StructDecl * decl ) { … … 33 157 } 34 158 159 const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr ) { 160 auto appExpr = dynamic_cast< const ApplicationExpr * >( expr ); 161 if ( !appExpr ) return nullptr; 162 163 const DeclWithType * func = getCalledFunction( appExpr->func ); 164 assertf( func, "getCalledFunction returned nullptr: %s", 165 toString( appExpr->func ).c_str() ); 166 167 return func->linkage == Linkage::Intrinsic ? appExpr : nullptr; 168 } 169 35 170 } // namespace ast -
src/AST/Inspect.hpp
r9cd5bd2 rdf6cc9d 10 10 // Created On : Fri Jun 24 13:16:31 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 27 15:35:00 202213 // Update Count : 112 // Last Modified On : Thr Sep 22 13:44:00 2022 13 // Update Count : 2 14 14 // 15 15 … … 18 18 namespace ast { 19 19 20 // Does the structure end in a flexable array declaration? 21 bool structHasFlexibleArray( const ast::StructDecl * ); 20 /// Returns the base type of an pointer/array/reference type, 21 /// if the argument is not one of those types, return null. 22 const Type * getPointerBase( const Type * ); 23 24 /// Get the declaration of the function called (ApplicationExpr or UntypedExpr). 25 const DeclWithType * getFunction( const Expr * expr ); 26 27 /// Get the name of the function being called. 28 std::string getFunctionName( const Expr * expr ); 29 30 /// Returns the argument to a call expression in position N, indexed from 0. 31 const Expr * getCallArg( const Expr * call, unsigned pos ); 32 33 /// Does the structure end in a flexable array declaration? 34 bool structHasFlexibleArray( const StructDecl * ); 35 36 /// If the expression is an application whose target function is an 37 /// intrinsic, then returns a pointer to that application. 38 const ApplicationExpr * isIntrinsicCallExpr( const Expr * expr ); 22 39 23 40 } -
src/AST/Pass.hpp
r9cd5bd2 rdf6cc9d 167 167 const ast::Expr * visit( const ast::UntypedExpr * ) override final; 168 168 const ast::Expr * visit( const ast::NameExpr * ) override final; 169 const ast::Expr * 169 const ast::Expr * visit( const ast::QualifiedNameExpr * ) override final; 170 170 const ast::Expr * visit( const ast::AddressExpr * ) override final; 171 171 const ast::Expr * visit( const ast::LabelAddressExpr * ) override final; … … 395 395 at_cleanup( [func](void *) { func(); }, nullptr ); 396 396 } 397 398 /// When this node is finished being visited, call a member of an object.399 template<typename T>400 void GuardMethod( T * obj, void (T::*method)() ) {401 at_cleanup( [ method ]( void * object ) {402 static_cast< T * >( object )->method();403 }, static_cast< void * >( obj ) );404 }405 397 }; 406 398 -
src/AST/Pass.impl.hpp
r9cd5bd2 rdf6cc9d 1205 1205 if ( __visit_children() ) { 1206 1206 guard_symtab guard { *this }; 1207 maybe_accept( node, &QualifiedNameExpr::var );1208 1207 maybe_accept( node, &QualifiedNameExpr::type_decl ); 1209 1208 } -
src/AST/SymbolTable.cpp
r9cd5bd2 rdf6cc9d 20 20 #include "Decl.hpp" 21 21 #include "Expr.hpp" 22 #include "Inspect.hpp" 22 23 #include "Type.hpp" 23 24 #include "CodeGen/OperatorTable.h" // for isCtorDtorAssign … … 315 316 316 317 void SymbolTable::addStruct( const std::string &id ) { 317 addStruct( new StructDecl( CodeLocation {}, id ) );318 addStruct( new StructDecl( CodeLocation(), id ) ); 318 319 } 319 320 … … 357 358 358 359 void SymbolTable::addUnion( const std::string &id ) { 359 addUnion( new UnionDecl( CodeLocation {}, id ) );360 addUnion( new UnionDecl( CodeLocation(), id ) ); 360 361 } 361 362 … … 466 467 assert( ! params.empty() ); 467 468 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 468 const Type * base = InitTweak::getPointerBase( params.front() );469 const Type * base = ast::getPointerBase( params.front() ); 469 470 assert( base ); 470 471 if (stripParams) { -
src/AST/Type.cpp
r9cd5bd2 rdf6cc9d 22 22 #include "Decl.hpp" 23 23 #include "Init.hpp" 24 #include "Inspect.hpp" 24 25 #include "Common/utility.h" // for copy, move 25 #include "InitTweak/InitTweak.h" // for getPointerBase26 26 #include "Tuples/Tuples.h" // for isTtype 27 27 … … 36 36 const Type * t; 37 37 const Type * a; 38 for ( t = this; (a = InitTweak::getPointerBase( t )); t = a );38 for ( t = this; (a = ast::getPointerBase( t )); t = a ); 39 39 return t; 40 40 } … … 176 176 for ( const Type * ty : types ) { 177 177 members.emplace_back( new ObjectDecl{ 178 CodeLocation {}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ),178 CodeLocation(), "", ty, new ListInit( CodeLocation(), {}, {}, NoConstruct ), 179 179 Storage::Classes{}, Linkage::Cforall } ); 180 180 } -
src/CodeGen/CodeGenerator.cc
r9cd5bd2 rdf6cc9d 912 912 } 913 913 output << ")"; 914 }915 916 // QualifiedNameExpr should not reach to CodeGen.917 // FixQualifiedName Convert QualifiedNameExpr to VariableExpr918 void CodeGenerator::postvisit( QualifiedNameExpr * expr ) {919 output << "/* label */" << mangleName(expr->var);920 914 } 921 915 -
src/CodeGen/CodeGenerator.h
r9cd5bd2 rdf6cc9d 103 103 void postvisit( DefaultArgExpr * ); 104 104 void postvisit( GenericExpr * ); 105 void postvisit( QualifiedNameExpr *);106 105 107 106 //*** Statements -
src/CodeGen/GenType.cc
r9cd5bd2 rdf6cc9d 169 169 170 170 void GenType::postvisit( ReferenceType * refType ) { 171 assert( refType->base != 0);171 assert( 0 != refType->base ); 172 172 assertf( ! options.genC, "Reference types should not reach code generation." ); 173 173 handleQualifiers( refType ); -
src/Common/Eval.cc
r9cd5bd2 rdf6cc9d 16 16 #include <utility> // for pair 17 17 18 #include "AST/Inspect.hpp" 18 19 #include "Common/PassVisitor.h" 19 20 #include "CodeGen/OperatorTable.h" // access: OperatorInfo … … 177 178 178 179 void postvisit( const ast::ApplicationExpr * expr ) { 179 const ast::DeclWithType * function = InitTweak::getFunction(expr);180 const ast::DeclWithType * function = ast::getFunction(expr); 180 181 if ( ! function || function->linkage != ast::Linkage::Intrinsic ) { valid = false; return; } 181 182 const std::string & fname = function->name; -
src/Common/PassVisitor.impl.h
r9cd5bd2 rdf6cc9d 1934 1934 indexerScopedAccept( node->result, *this ); 1935 1935 maybeAccept_impl( node->type_decl, *this ); 1936 maybeAccept_impl( node->var, *this );1937 1936 1938 1937 VISIT_END( node ); … … 1945 1944 indexerScopedAccept( node->result, *this ); 1946 1945 maybeAccept_impl( node->type_decl, *this ); 1947 maybeAccept_impl( node->var, *this );1948 1946 1949 1947 VISIT_END( node ); … … 1957 1955 indexerScopedMutate( node->result, *this ); 1958 1956 maybeMutate_impl( node->type_decl, *this ); 1959 maybeAccept_impl( node->var, *this );1960 1957 1961 1958 MUTATE_END( Expression, node ); -
src/Concurrency/KeywordsNew.cpp
r9cd5bd2 rdf6cc9d 21 21 #include "AST/Decl.hpp" 22 22 #include "AST/Expr.hpp" 23 #include "AST/Inspect.hpp" 23 24 #include "AST/Pass.hpp" 24 25 #include "AST/Stmt.hpp" … … 1528 1529 const ast::ptr<ast::DeclWithType> & param = decl->params.front(); 1529 1530 auto type = dynamic_cast<const ast::StructInstType *>( 1530 InitTweak::getPointerBase( param->get_type() ) );1531 ast::getPointerBase( param->get_type() ) ); 1531 1532 if ( nullptr == type ) return decl; 1532 1533 if ( !type->base->is_thread() ) return decl; -
src/GenPoly/Box.cc
r9cd5bd2 rdf6cc9d 66 66 }; 67 67 68 /// Adds layout-generation functions to polymorphic types 68 /// Adds layout-generation functions to polymorphic types. 69 69 class LayoutFunctionBuilder final : public WithDeclsToAdd, public WithVisitorRef<LayoutFunctionBuilder>, public WithShortCircuiting { 70 unsigned int functionNesting = 0; // current level of nested functions 70 // Current level of nested functions: 71 unsigned int functionNesting = 0; 71 72 public: 72 73 void previsit( FunctionDecl *functionDecl ); … … 75 76 }; 76 77 77 /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call 78 /// Replaces polymorphic return types with out-parameters, 79 /// replaces calls to polymorphic functions with adapter calls, 80 /// and adds appropriate type variables to the function call. 78 81 class Pass1 final : public BoxPass, public WithConstTypeSubstitution, public WithStmtsToAdd, public WithGuards, public WithVisitorRef<Pass1>, public WithShortCircuiting { 79 82 public: … … 146 149 }; 147 150 148 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions.151 /// * Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions. 149 152 /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference 150 153 /// * Calculates polymorphic offsetof expressions from offset array … … 199 202 }; 200 203 201 /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, sizeof expressions of polymorphic types with the proper variable, and strips fields from generic struct declarations. 204 /// Replaces initialization of polymorphic values with alloca, 205 /// declaration of dtype/ftype with appropriate void expression, 206 /// sizeof expressions of polymorphic types with the proper variable, 207 /// and strips fields from generic struct declarations. 202 208 struct Pass3 final : public BoxPass, public WithGuards { 203 209 template< typename DeclClass > -
src/GenPoly/GenPoly.cc
r9cd5bd2 rdf6cc9d 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Sep 14 9:24:00 202213 // Update Count : 1 512 // Last Modified On : Fri Oct 7 15:25:00 2022 13 // Update Count : 16 14 14 // 15 15 … … 64 64 } 65 65 66 __attribute__((unused))67 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {68 for (auto ¶m : params) {69 auto paramType = param.strict_as<ast::TypeExpr>();70 if (isPolyType(paramType->type, tyVars, env)) return true;71 }72 return false;73 }74 75 66 /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present 76 67 bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) { … … 83 74 } 84 75 85 bool hasDynParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) { 86 for ( ast::ptr<ast::Expr> const & param : params ) { 87 auto paramType = param.as<ast::TypeExpr>(); 88 assertf( paramType, "Aggregate parameters should be type expressions." ); 89 if ( isDynType( paramType->type, tyVars, typeSubs ) ) { 76 bool hasDynParams( 77 const std::vector<ast::ptr<ast::Expr>> & params, 78 const TypeVarMap & typeVars, 79 const ast::TypeSubstitution * subst ) { 80 for ( ast::ptr<ast::Expr> const & paramExpr : params ) { 81 auto param = paramExpr.as<ast::TypeExpr>(); 82 assertf( param, "Aggregate parameters should be type expressions." ); 83 if ( isDynType( param->type.get(), typeVars, subst ) ) { 90 84 return true; 91 85 } … … 195 189 } 196 190 191 const ast::Type * isPolyType( const ast::Type * type, 192 const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) { 193 type = replaceTypeInst( type, subst ); 194 195 if ( auto inst = dynamic_cast< const ast::TypeInstType * >( type ) ) { 196 if ( typeVars.find( inst->typeString() ) != typeVars.end() ) return type; 197 } else if ( auto array = dynamic_cast< const ast::ArrayType * >( type ) ) { 198 return isPolyType( array->base, subst ); 199 } else if ( auto sue = dynamic_cast< const ast::StructInstType * >( type ) ) { 200 if ( hasPolyParams( sue->params, subst ) ) return type; 201 } else if ( auto sue = dynamic_cast< const ast::UnionInstType * >( type ) ) { 202 if ( hasPolyParams( sue->params, subst ) ) return type; 203 } 204 return nullptr; 205 } 206 197 207 ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 198 208 type = replaceTypeInst( type, env ); … … 211 221 } 212 222 213 const ast::BaseInstType *isDynType( const ast::Type *type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs ) { 214 type = replaceTypeInst( type, typeSubs ); 215 216 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) { 217 auto var = tyVars.find( inst->name ); 218 if ( var != tyVars.end() && var->second.isComplete ) { 219 return inst; 220 } 221 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) { 222 if ( hasDynParams( inst->params, tyVars, typeSubs ) ) { 223 return inst; 224 } 225 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) { 226 if ( hasDynParams( inst->params, tyVars, typeSubs ) ) { 227 return inst; 228 } 229 } 230 return nullptr; 231 } 223 const ast::BaseInstType * isDynType( 224 const ast::Type * type, const TypeVarMap & typeVars, 225 const ast::TypeSubstitution * subst ) { 226 type = replaceTypeInst( type, subst ); 227 228 if ( auto inst = dynamic_cast<ast::TypeInstType const *>( type ) ) { 229 auto var = typeVars.find( inst->name ); 230 if ( var != typeVars.end() && var->second.isComplete ) { 231 232 } 233 } else if ( auto inst = dynamic_cast<ast::StructInstType const *>( type ) ) { 234 if ( hasDynParams( inst->params, typeVars, subst ) ) { 235 return inst; 236 } 237 } else if ( auto inst = dynamic_cast<ast::UnionInstType const *>( type ) ) { 238 if ( hasDynParams( inst->params, typeVars, subst ) ) { 239 return inst; 240 } 241 } 242 return nullptr; 243 } 232 244 233 245 ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &forallTypes ) { … … 236 248 return (ReferenceToType*)isDynType( function->get_returnVals().front()->get_type(), forallTypes ); 237 249 } 250 251 const ast::BaseInstType *isDynRet( 252 const ast::FunctionType * type, const TypeVarMap & typeVars ) { 253 if ( type->returns.empty() ) return nullptr; 254 255 return isDynType( type->returns.front(), typeVars ); 256 } 238 257 239 258 ReferenceToType *isDynRet( FunctionType *function ) { … … 260 279 } 261 280 281 bool needsAdapter( 282 ast::FunctionType const * adaptee, const TypeVarMap & typeVars ) { 283 if ( isDynRet( adaptee, typeVars ) ) return true; 284 285 for ( auto param : adaptee->params ) { 286 if ( isDynType( param, typeVars ) ) { 287 return true; 288 } 289 } 290 return false; 291 } 292 262 293 Type *isPolyPtr( Type *type, const TypeSubstitution *env ) { 263 294 type = replaceTypeInst( type, env ); … … 311 342 return isPolyType( type, tyVars, env ); 312 343 } 344 345 ast::Type const * hasPolyBase( 346 ast::Type const * type, const TypeVarMap & typeVars, 347 int * levels, const ast::TypeSubstitution * subst ) { 348 int level_count = 0; 349 350 while ( true ) { 351 type = replaceTypeInst( type, subst ); 352 353 if ( auto ptr = dynamic_cast<ast::PointerType const *>( type ) ) { 354 type = ptr->base; 355 ++level_count; 356 } else { 357 break; 358 } 359 } 360 361 if ( nullptr != levels ) { *levels = level_count; } 362 return isPolyType( type, typeVars, subst ); 363 } 313 364 314 365 bool includesPolyType( Type *type, const TypeSubstitution *env ) { … … 685 736 } 686 737 687 namespace {688 // temporary hack to avoid re-implementing anything related to TyVarMap689 // does this work? these two structs have identical definitions.690 inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {691 return *reinterpret_cast<const TypeDecl::Data *>(&data);692 }693 }694 695 738 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) { 696 739 // is parameter is not polymorphic, don't need to box … … 703 746 } 704 747 705 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) { 706 // is parameter is not polymorphic, don't need to box 707 if ( ! isPolyType( param, exprTyVars ) ) return false; 708 ast::ptr<ast::Type> newType = arg; 709 if ( env ) env->apply( newType ); 710 // if the argument's type is polymorphic, we don't need to box again! 711 return ! isPolyType( newType ); 712 } 748 bool needsBoxing( const ast::Type * param, const ast::Type * arg, 749 const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ) { 750 // Don't need to box if the parameter is not polymorphic. 751 if ( !isPolyType( param, typeVars ) ) return false; 752 753 ast::ptr<ast::Type> newType = arg; 754 if ( subst ) { 755 int count = subst->apply( newType ); 756 (void)count; 757 } 758 // Only need to box if the argument is not also polymorphic. 759 return !isPolyType( newType ); 760 } 713 761 714 762 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) { … … 720 768 } 721 769 722 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) { 723 const ast::FunctionType * function = getFunctionType(appExpr->func->result); 724 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() ); 725 TyVarMap exprTyVars(TypeDecl::Data{}); 726 makeTyVarMap(function, exprTyVars); 727 return needsBoxing(param, arg, exprTyVars, env); 728 729 } 770 bool needsBoxing( 771 const ast::Type * param, const ast::Type * arg, 772 const ast::ApplicationExpr * expr, 773 const ast::TypeSubstitution * subst ) { 774 const ast::FunctionType * function = getFunctionType( expr->func->result ); 775 assertf( function, "ApplicationExpr has non-function type: %s", toString( expr->func->result ).c_str() ); 776 TypeVarMap exprTyVars = { ast::TypeDecl::Data() }; 777 makeTypeVarMap( function, exprTyVars ); 778 return needsBoxing( param, arg, exprTyVars, subst ); 779 } 730 780 731 781 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { … … 733 783 } 734 784 735 void addToTyVarMap( const ast::TypeInstType * tyVar, TyVarMap & tyVarMap) {736 tyVarMap.insert(tyVar->typeString(), convData(ast::TypeDecl::Data{tyVar->base}));737 785 void addToTypeVarMap( const ast::TypeInstType * type, TypeVarMap & typeVars ) { 786 typeVars.insert( type->typeString(), ast::TypeDecl::Data( type->base ) ); 787 } 738 788 739 789 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ) { … … 747 797 } 748 798 749 void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {750 if (auto ptype = dynamic_cast<const ast::FunctionType *>(type)) {751 for (auto & tyVar : ptype->forall) {752 assert (tyVar);753 addToTyVarMap(tyVar, tyVarMap);754 755 756 if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {757 makeTyVarMap(pointer->base, tyVarMap);758 759 799 void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ) { 800 if ( auto func = dynamic_cast<ast::FunctionType const *>( type ) ) { 801 for ( auto & typeVar : func->forall ) { 802 assert( typeVar ); 803 addToTypeVarMap( typeVar, typeVars ); 804 } 805 } 806 if ( auto pointer = dynamic_cast<ast::PointerType const *>( type ) ) { 807 makeTypeVarMap( pointer->base, typeVars ); 808 } 809 } 760 810 761 811 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { … … 766 816 } 767 817 818 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ) { 819 for ( auto const & pair : typeVars ) { 820 os << pair.first << " (" << pair.second << ") "; 821 } // for 822 os << std::endl; 823 } 824 768 825 } // namespace GenPoly 769 826 -
src/GenPoly/GenPoly.h
r9cd5bd2 rdf6cc9d 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:03:00 202213 // Update Count : 812 // Last Modified On : Fri Oct 7 15:06:00 2022 13 // Update Count : 9 14 14 // 15 15 … … 20 20 21 21 #include "ErasableScopedMap.h" // for ErasableScopedMap 22 #include "AST/Fwd.hpp" 22 #include "AST/Decl.hpp" // for TypeDecl::Data 23 #include "AST/Fwd.hpp" // for ApplicationExpr, BaseInstType, Func... 23 24 #include "SymTab/Mangler.h" // for Mangler 24 25 #include "SynTree/Declaration.h" // for TypeDecl::Data, AggregateDecl, Type... … … 29 30 // TODO Via some tricks this works for ast::TypeDecl::Data as well. 30 31 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 32 using TypeVarMap = ErasableScopedMap< std::string, ast::TypeDecl::Data >; 31 33 32 34 /// Replaces a TypeInstType by its referrent in the environment, if applicable … … 39 41 /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 40 42 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 41 const ast::Type * isPolyType( const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env = nullptr);43 const ast::Type * isPolyType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = nullptr ); 42 44 43 45 /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided 44 46 ReferenceToType *isDynType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 45 const ast::BaseInstType *isDynType( const ast::Type * type, const TyVarMap &tyVars, const ast::TypeSubstitution *typeSubs= 0 );47 const ast::BaseInstType *isDynType( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst = 0 ); 46 48 47 49 /// true iff function has dynamic-layout return type under the given type variable map 48 50 ReferenceToType *isDynRet( FunctionType *function, const TyVarMap &tyVars ); 51 const ast::BaseInstType *isDynRet( const ast::FunctionType * type, const TypeVarMap & typeVars ); 49 52 50 53 /// true iff function has dynamic-layout return type under the type variable map generated from its forall-parameters … … 53 56 /// A function needs an adapter if it returns a dynamic-layout value or if any of its parameters have dynamic-layout type 54 57 bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVarr ); 58 bool needsAdapter( ast::FunctionType const * adaptee, const TypeVarMap & typeVars ); 55 59 56 60 /// returns polymorphic type if is pointer to polymorphic type, NULL otherwise; will look up substitution in env if provided … … 59 63 /// returns polymorphic type if is pointer to polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 60 64 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 65 const ast::Type * isPolyPtr( const ast::Type * type, const TypeVarMap & typeVars, const ast::TypeSubstitution * env = 0 ); 61 66 62 67 /// if the base type (after dereferencing N >= 0 pointers) is a polymorphic type, returns the base type, NULL otherwise; … … 67 72 /// N will be stored in levels, if provided, will look up substitution in env if provided 68 73 Type *hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels = 0, const TypeSubstitution *env = 0 ); 74 const ast::Type * hasPolyBase( const ast::Type * type, const TypeVarMap & typeVars, int * levels = 0, const ast::TypeSubstitution * env = 0 ); 69 75 70 76 /// true iff this type or some base of this type after dereferencing pointers is either polymorphic or a generic type with at least one … … 90 96 /// true if arg requires boxing given exprTyVars 91 97 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ); 92 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const Ty VarMap &exprTyVars, const ast::TypeSubstitution * env);98 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TypeVarMap & typeVars, const ast::TypeSubstitution * subst ); 93 99 94 100 /// true if arg requires boxing in the call to appExpr 95 101 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ); 96 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env);102 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * expr, const ast::TypeSubstitution * subst ); 97 103 98 104 /// Adds the type variable `tyVar` to `tyVarMap` 99 105 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ); 106 void addToTypeVarMap( const ast::TypeDecl * type, TypeVarMap & typeVars ); 100 107 101 108 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` 102 109 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 103 void makeTy VarMap(const ast::Type * type, TyVarMap & tyVarMap);110 void makeTypeVarMap( const ast::Type * type, TypeVarMap & typeVars ); 104 111 105 112 /// Prints type variable map 106 113 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 114 void printTypeVarMap( std::ostream &os, const TypeVarMap & typeVars ); 107 115 108 116 /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType(). -
src/GenPoly/InstantiateGenericNew.cpp
r9cd5bd2 rdf6cc9d 23 23 #include "AST/Copy.hpp" // for deepCopy 24 24 #include "AST/Create.hpp" // for asForward 25 #include "AST/Inspect.hpp" // for getFunction 25 26 #include "AST/Pass.hpp" // for Pass, WithGuard, WithShortCi... 26 27 #include "AST/TranslationUnit.hpp" // for TranslationUnit … … 30 31 #include "GenPoly/GenPoly.h" // for isPolyType, typesPolyCompatible 31 32 #include "GenPoly/ScrubTyVars.h" // for scrubAll 32 #include "InitTweak/InitTweak.h" // for getFunction33 33 #include "ResolvExpr/typeops.h" // for typesCompatible 34 34 … … 294 294 ast::ApplicationExpr const * expr ) { 295 295 GuardValue( isLValueArg ) = false; 296 ast::Decl const * function = InitTweak::getFunction( expr );296 ast::Decl const * function = ast::getFunction( expr ); 297 297 if ( ast::Linkage::Intrinsic != function->linkage 298 298 || !CodeGen::isAssignment( function->name ) ) { -
src/GenPoly/Lvalue.h
r9cd5bd2 rdf6cc9d 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:21:59 201713 // Update Count : 211 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Sep 15 14:13:00 2022 13 // Update Count : 3 14 14 // 15 15 … … 20 20 class Declaration; 21 21 class Expression; 22 namespace ast { 23 class Expr; 24 class TranslationUnit; 25 } 22 26 23 27 namespace GenPoly { 24 28 /// replaces return type of `lvalue T` with `T*`, along with appropriate address-of and dereference operators 25 29 void convertLvalue( std::list< Declaration* >& translationUnit ); 30 void convertLvalue( ast::TranslationUnit & translationUnit ); 26 31 27 32 /// true after reference types have been eliminated from the source code. After this point, reference types should not be added to the AST. … … 30 35 /// applies transformations that allow GCC to accept more complicated lvalue expressions, e.g. &(a, b) 31 36 Expression * generalizedLvalue( Expression * expr ); 37 ast::Expr const * generalizedLvalue( ast::Expr const * expr ); 32 38 } // namespace GenPoly 33 39 -
src/GenPoly/ScrubTyVars.cc
r9cd5bd2 rdf6cc9d 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 16:10:00 202213 // Update Count : 412 // Last Modified On : Fri Oct 7 15:42:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 128 128 public ast::WithVisitorRef<ScrubTypeVars> { 129 129 130 ScrubTypeVars( ScrubMode m, Ty VarMap const * tv ) :130 ScrubTypeVars( ScrubMode m, TypeVarMap const * tv ) : 131 131 mode ( m ), typeVars( tv ) {} 132 132 … … 148 148 ScrubMode const mode; 149 149 /// Type varriables to scrub. 150 Ty VarMap const * const typeVars;150 TypeVarMap const * const typeVars; 151 151 /// Value cached by primeBaseScrub. 152 152 ast::Type const * dynType = nullptr; … … 255 255 const ast::Node * scrubTypeVarsBase( 256 256 const ast::Node * target, 257 ScrubMode mode, const Ty VarMap * typeVars ) {257 ScrubMode mode, const TypeVarMap * typeVars ) { 258 258 if ( ScrubMode::All == mode ) { 259 259 assert( nullptr == typeVars ); … … 266 266 267 267 } // namespace 268 269 template<> 270 ast::Node const * scrubTypeVars<ast::Node>( 271 const ast::Node * target, const TypeVarMap & typeVars ) { 272 return scrubTypeVarsBase( target, ScrubMode::FromMap, &typeVars ); 273 } 274 275 template<> 276 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 277 ast::Node const * target, const TypeVarMap & typeVars ) { 278 return scrubTypeVarsBase( target, ScrubMode::DynamicFromMap, &typeVars ); 279 } 268 280 269 281 template<> -
src/GenPoly/ScrubTyVars.h
r9cd5bd2 rdf6cc9d 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Aug 19 14:14:00 202213 // Update Count : 312 // Last Modified On : Fri Oct 7 15:51:00 2022 13 // Update Count : 4 14 14 // 15 15 … … 109 109 } 110 110 111 /// For all polymorphic types with type variables in `typeVars`, 112 /// replaces generic types, dtypes, and ftypes with the appropriate void type, 113 /// and sizeof/alignof expressions with the proper variable. 114 template<typename node_t> 115 node_t const * scrubTypeVars( 116 node_t const * target, const TypeVarMap & typeVars ) { 117 return strict_dynamic_cast<node_t const *>( 118 scrubTypeVars<ast::Node>( target, typeVars ) ); 119 } 120 121 /// For all dynamic-layout types with type variables in `typeVars`, 122 /// replaces generic types, dtypes, and ftypes with the appropriate void type, 123 /// and sizeof/alignof expressions with the proper variable. 124 template<typename node_t> 125 ast::Node const * scrubTypeVarsDynamic( 126 node_t const * target, const TypeVarMap & typeVars ) { 127 return strict_dynamic_cast<node_t const *>( 128 scrubTypeVarsDynamic<ast::Node>( target, typeVars ) ); 129 } 130 111 131 /// For all polymorphic types, replaces generic types, with the appropriate 112 132 /// void type, and sizeof/alignof expressions with the proper variable. 113 133 template<typename node_t> 114 134 node_t const * scrubAllTypeVars( node_t const * target ) { 115 return strict_dynamic_cast<node_t const *>( scrubAllTypeVars<ast::Node>( target ) ); 135 return strict_dynamic_cast<node_t const *>( 136 scrubAllTypeVars<ast::Node>( target ) ); 116 137 } 138 139 // We specialize for Node as a base case. 140 template<> 141 ast::Node const * scrubTypeVars<ast::Node>( 142 const ast::Node * target, const TypeVarMap & typeVars ); 143 144 template<> 145 ast::Node const * scrubTypeVarsDynamic<ast::Node>( 146 ast::Node const * target, const TypeVarMap & typeVars ); 117 147 118 148 template<> -
src/GenPoly/SpecializeNew.cpp
r9cd5bd2 rdf6cc9d 16 16 #include "Specialize.h" 17 17 18 #include "AST/Pass.hpp" 18 #include "AST/Inspect.hpp" // for isIntrinsicCallExpr 19 #include "AST/Pass.hpp" // for Pass 19 20 #include "AST/TypeEnvironment.hpp" // for OpenVarSet, AssertionSet 20 21 #include "Common/UniqueName.h" // for UniqueName 21 22 #include "GenPoly/GenPoly.h" // for getFunctionType 22 #include "InitTweak/InitTweak.h" // for isIntrinsicCallExpr23 23 #include "ResolvExpr/FindOpenVars.h" // for findOpenVars 24 24 #include "ResolvExpr/TypeEnvironment.h" // for FirstOpen, FirstClosed 25 26 #include "AST/Print.hpp"27 25 28 26 namespace GenPoly { … … 425 423 const ast::Expr * SpecializeCore::postvisit( 426 424 const ast::ApplicationExpr * expr ) { 427 if ( InitTweak::isIntrinsicCallExpr( expr ) ) {425 if ( ast::isIntrinsicCallExpr( expr ) ) { 428 426 return expr; 429 427 } -
src/GenPoly/module.mk
r9cd5bd2 rdf6cc9d 30 30 GenPoly/InstantiateGeneric.cc \ 31 31 GenPoly/InstantiateGeneric.h \ 32 GenPoly/LvalueNew.cpp \ 32 33 GenPoly/Lvalue.cc \ 33 34 GenPoly/ScopedSet.h \ -
src/InitTweak/FixInitNew.cpp
r9cd5bd2 rdf6cc9d 14 14 #include <utility> // for pair 15 15 16 #include "AST/Inspect.hpp" // for getFunction, getPointerBase, g... 16 17 #include "CodeGen/GenType.h" // for genPrettyType 17 18 #include "CodeGen/OperatorTable.h" … … 24 25 #include "GenInit.h" // for genCtorDtor 25 26 #include "GenPoly/GenPoly.h" // for getFunctionType 26 #include "InitTweak.h" // for getFunctionName, getCallArg27 27 #include "ResolvExpr/Resolver.h" // for findVoidExpression 28 28 #include "ResolvExpr/typeops.h" // for typesCompatible -
src/InitTweak/InitTweak.cc
r9cd5bd2 rdf6cc9d 10 10 // Created On : Fri May 13 11:26:36 2016 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Dec 6 13:21:00 202113 // Update Count : 2 012 // Last Modified On : Wed Sep 22 9:50:00 2022 13 // Update Count : 21 14 14 // 15 15 … … 23 23 #include "AST/Expr.hpp" 24 24 #include "AST/Init.hpp" 25 #include "AST/Inspect.hpp" 25 26 #include "AST/Node.hpp" 26 27 #include "AST/Pass.hpp" … … 654 655 namespace { 655 656 DeclarationWithType * getCalledFunction( Expression * expr ); 656 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr );657 657 658 658 template<typename CallExpr> … … 664 664 return getCalledFunction( expr->get_args().front() ); 665 665 } 666 667 template<typename CallExpr>668 const ast::DeclWithType * handleDerefCalledFunction( const CallExpr * expr ) {669 // (*f)(x) => should get "f"670 std::string name = getFunctionName( expr );671 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );672 assertf( ! expr->args.empty(), "Cannot get called function from dereference with no arguments" );673 return getCalledFunction( expr->args.front() );674 }675 676 666 677 667 DeclarationWithType * getCalledFunction( Expression * expr ) { … … 695 685 } 696 686 697 const ast::DeclWithType * getCalledFunction( const ast::Expr * expr ) {698 assert( expr );699 if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( expr ) ) {700 return varExpr->var;701 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( expr ) ) {702 return memberExpr->member;703 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( expr ) ) {704 return getCalledFunction( castExpr->arg );705 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( expr ) ) {706 return handleDerefCalledFunction( untypedExpr );707 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * > ( expr ) ) {708 return handleDerefCalledFunction( appExpr );709 } else if ( const ast::AddressExpr * addrExpr = dynamic_cast< const ast::AddressExpr * >( expr ) ) {710 return getCalledFunction( addrExpr->arg );711 } else if ( const ast::CommaExpr * commaExpr = dynamic_cast< const ast::CommaExpr * >( expr ) ) {712 return getCalledFunction( commaExpr->arg2 );713 }714 return nullptr;715 }716 717 687 DeclarationWithType * getFunctionCore( const Expression * expr ) { 718 688 if ( const auto * appExpr = dynamic_cast< const ApplicationExpr * >( expr ) ) { … … 731 701 const DeclarationWithType * getFunction( const Expression * expr ) { 732 702 return getFunctionCore( expr ); 733 }734 735 const ast::DeclWithType * getFunction( const ast::Expr * expr ) {736 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {737 return getCalledFunction( appExpr->func );738 } else if ( const ast::UntypedExpr * untyped = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {739 return getCalledFunction( untyped->func );740 }741 assertf( false, "getFunction received unknown expression: %s", toString( expr ).c_str() );742 703 } 743 704 … … 752 713 } 753 714 754 const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr ) {755 auto appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr );756 if ( ! appExpr ) return nullptr;757 758 const ast::DeclWithType * func = getCalledFunction( appExpr->func );759 assertf( func,760 "getCalledFunction returned nullptr: %s", toString( appExpr->func ).c_str() );761 762 // check for Intrinsic only -- don't want to remove all overridable ctor/dtor because763 // autogenerated ctor/dtor will call all member dtors, and some members may have a764 // user-defined dtor765 return func->linkage == ast::Linkage::Intrinsic ? appExpr : nullptr;766 }767 768 715 namespace { 769 716 template <typename Predicate> … … 817 764 if ( pos == 0 ) return arg; 818 765 pos--; 819 }820 assert( false );821 }822 823 template<typename CallExpr>824 const ast::Expr * callArg( const CallExpr * call, unsigned int pos ) {825 if( pos >= call->args.size() ) {826 assertf( false, "getCallArg for argument that doesn't exist: (%u); %s.",827 pos, toString( call ).c_str() );828 }829 for ( const ast::Expr * arg : call->args ) {830 if ( pos == 0 ) return arg;831 --pos;832 766 } 833 767 assert( false ); … … 854 788 } 855 789 856 const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos ) {857 if ( auto app = dynamic_cast< const ast::ApplicationExpr * >( call ) ) {858 return callArg( app, pos );859 } else if ( auto untyped = dynamic_cast< const ast::UntypedExpr * >( call ) ) {860 return callArg( untyped, pos );861 } else if ( auto tupleAssn = dynamic_cast< const ast::TupleAssignExpr * >( call ) ) {862 const std::list<ast::ptr<ast::Stmt>>& stmts = tupleAssn->stmtExpr->stmts->kids;863 assertf( ! stmts.empty(), "TupleAssignExpr missing statements." );864 auto stmt = strict_dynamic_cast< const ast::ExprStmt * >( stmts.back().get() );865 auto tuple = strict_dynamic_cast< const ast::TupleExpr * >( stmt->expr.get() );866 assertf( ! tuple->exprs.empty(), "TupleAssignExpr has empty tuple expr.");867 return getCallArg( tuple->exprs.front(), pos );868 } else if ( auto ctor = dynamic_cast< const ast::ImplicitCopyCtorExpr * >( call ) ) {869 return getCallArg( ctor->callExpr, pos );870 } else {871 assertf( false, "Unexpected expression type passed to getCallArg: %s",872 toString( call ).c_str() );873 }874 }875 876 790 namespace { 877 791 std::string funcName( Expression * func ); 878 std::string funcName( const ast::Expr * func );879 792 880 793 template<typename CallExpr> … … 885 798 assertf( ! expr->get_args().empty(), "Cannot get function name from dereference with no arguments" ); 886 799 return funcName( expr->get_args().front() ); 887 }888 889 template<typename CallExpr>890 std::string handleDerefName( const CallExpr * expr ) {891 // (*f)(x) => should get name "f"892 std::string name = getFunctionName( expr );893 assertf( name == "*?", "Unexpected untyped expression: %s", name.c_str() );894 assertf( ! expr->args.empty(), "Cannot get function name from dereference with no arguments" );895 return funcName( expr->args.front() );896 800 } 897 801 … … 917 821 } 918 822 } 919 920 std::string funcName( const ast::Expr * func ) {921 if ( const ast::NameExpr * nameExpr = dynamic_cast< const ast::NameExpr * >( func ) ) {922 return nameExpr->name;923 } else if ( const ast::VariableExpr * varExpr = dynamic_cast< const ast::VariableExpr * >( func ) ) {924 return varExpr->var->name;925 } else if ( const ast::CastExpr * castExpr = dynamic_cast< const ast::CastExpr * >( func ) ) {926 return funcName( castExpr->arg );927 } else if ( const ast::MemberExpr * memberExpr = dynamic_cast< const ast::MemberExpr * >( func ) ) {928 return memberExpr->member->name;929 } else if ( const ast::UntypedMemberExpr * memberExpr = dynamic_cast< const ast::UntypedMemberExpr * > ( func ) ) {930 return funcName( memberExpr->member );931 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * >( func ) ) {932 return handleDerefName( untypedExpr );933 } else if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( func ) ) {934 return handleDerefName( appExpr );935 } else if ( const ast::ConstructorExpr * ctorExpr = dynamic_cast< const ast::ConstructorExpr * >( func ) ) {936 return funcName( getCallArg( ctorExpr->callExpr, 0 ) );937 } else {938 assertf( false, "Unexpected expression type being called as a function in call expression: %s", toString( func ).c_str() );939 }940 }941 823 } 942 824 … … 955 837 } 956 838 957 std::string getFunctionName( const ast::Expr * expr ) {958 // there's some unforunate overlap here with getCalledFunction. Ideally this would be able to use getCalledFunction and959 // return the name of the DeclarationWithType, but this needs to work for NameExpr and UntypedMemberExpr, where getCalledFunction960 // can't possibly do anything reasonable.961 if ( const ast::ApplicationExpr * appExpr = dynamic_cast< const ast::ApplicationExpr * >( expr ) ) {962 return funcName( appExpr->func );963 } else if ( const ast::UntypedExpr * untypedExpr = dynamic_cast< const ast::UntypedExpr * > ( expr ) ) {964 return funcName( untypedExpr->func );965 } else {966 std::cerr << expr << std::endl;967 assertf( false, "Unexpected expression type passed to getFunctionName" );968 }969 }970 971 839 Type * getPointerBase( Type * type ) { 972 840 if ( PointerType * ptrType = dynamic_cast< PointerType * >( type ) ) { … … 980 848 } 981 849 } 982 const ast::Type* getPointerBase( const ast::Type* t ) {983 if ( const auto * p = dynamic_cast< const ast::PointerType * >( t ) ) {984 return p->base;985 } else if ( const auto * a = dynamic_cast< const ast::ArrayType * >( t ) ) {986 return a->base;987 } else if ( const auto * r = dynamic_cast< const ast::ReferenceType * >( t ) ) {988 return r->base;989 } else return nullptr;990 }991 850 992 851 Type * isPointerType( Type * type ) { … … 1022 881 static ast::ptr<ast::FunctionDecl> assign = nullptr; 1023 882 if (!assign) { 1024 auto td = new ast::TypeDecl( {}, "T", {}, nullptr, ast::TypeDecl::Dtype, true);1025 assign = new ast::FunctionDecl( {}, "?=?", {},1026 { new ast::ObjectDecl( {}, "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),1027 new ast::ObjectDecl( {}, "_src", new ast::TypeInstType("T", td))},1028 { new ast::ObjectDecl( {}, "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic);883 auto td = new ast::TypeDecl(CodeLocation(), "T", {}, nullptr, ast::TypeDecl::Dtype, true); 884 assign = new ast::FunctionDecl(CodeLocation(), "?=?", {}, 885 { new ast::ObjectDecl(CodeLocation(), "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))), 886 new ast::ObjectDecl(CodeLocation(), "_src", new ast::TypeInstType("T", td))}, 887 { new ast::ObjectDecl(CodeLocation(), "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic); 1029 888 } 1030 889 if (dst->result.as<ast::ReferenceType>()) { … … 1203 1062 if ( ftype->params.size() != 2 ) return false; 1204 1063 1205 const ast::Type * t1 = getPointerBase( ftype->params.front() );1064 const ast::Type * t1 = ast::getPointerBase( ftype->params.front() ); 1206 1065 if ( ! t1 ) return false; 1207 1066 const ast::Type * t2 = ftype->params.back(); 1208 1067 1209 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable {});1068 return ResolvExpr::typesCompatibleIgnoreQualifiers( t1, t2, ast::SymbolTable() ); 1210 1069 } 1070 1211 1071 1212 1072 const FunctionDecl * isAssignment( const Declaration * decl ) { -
src/InitTweak/InitTweak.h
r9cd5bd2 rdf6cc9d 10 10 // Created On : Fri May 13 11:26:36 2016 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Dec 6 13:20:00 202113 // Update Count : 812 // Last Modified On : Wed Sep 22 9:21:00 2022 13 // Update Count : 9 14 14 // 15 15 … … 74 74 DeclarationWithType * getFunction( Expression * expr ); 75 75 const DeclarationWithType * getFunction( const Expression * expr ); 76 const ast::DeclWithType * getFunction( const ast::Expr * expr );77 76 78 77 /// Non-Null if expr is a call expression whose target function is intrinsic 79 78 ApplicationExpr * isIntrinsicCallExpr( Expression * expr ); 80 const ast::ApplicationExpr * isIntrinsicCallExpr( const ast::Expr * expr);81 79 82 80 /// True if stmt is a call statement where the function called is intrinsic and takes one parameter. … … 98 96 /// returns the name of the function being called 99 97 std::string getFunctionName( Expression * expr ); 100 std::string getFunctionName( const ast::Expr * expr );101 98 102 99 /// returns the argument to a call expression in position N indexed from 0 103 100 Expression *& getCallArg( Expression * callExpr, unsigned int pos ); 104 const ast::Expr * getCallArg( const ast::Expr * call, unsigned pos );105 101 106 102 /// returns the base type of a PointerType or ArrayType, else returns NULL 107 103 Type * getPointerBase( Type * ); 108 const ast::Type* getPointerBase( const ast::Type* );109 104 110 105 /// returns the argument if it is a PointerType or ArrayType, else returns NULL -
src/Parser/DeclarationNode.cc
r9cd5bd2 rdf6cc9d 297 297 } // if 298 298 } // DeclarationNode::newEnumValueGeneric 299 300 DeclarationNode * DeclarationNode::newEnumInLine( const string name ) { 301 DeclarationNode * newnode = newName( new std::string(name) ); 302 newnode->enumInLine = true; 303 return newnode; 304 } 299 305 300 306 DeclarationNode * DeclarationNode::newFromTypedef( const string * name ) { -
src/Parser/ExpressionNode.cc
r9cd5bd2 rdf6cc9d 523 523 auto enumInst = new EnumInstType( Type::Qualifiers(), e ); 524 524 auto obj = new ObjectDecl( name->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, enumInst, nullptr ); 525 ret->set_var( obj );526 525 } 527 526 return ret; -
src/Parser/ParseNode.h
r9cd5bd2 rdf6cc9d 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Feb 2 09:15:49202213 // Update Count : 9 0512 // Last Modified On : Tue Oct 18 14:15:37 2022 13 // Update Count : 936 14 14 // 15 15 … … 240 240 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); 241 241 static DeclarationNode * newEnumValueGeneric( const std::string * name, InitializerNode * init ); 242 static DeclarationNode * newEnumInLine( const std::string name ); 242 243 static DeclarationNode * newName( const std::string * ); 243 244 static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params ); … … 339 340 340 341 bool inLine = false; 342 bool enumInLine = false; 341 343 Type::FuncSpecifiers funcSpecs; 342 344 Type::StorageClasses storageClasses; … … 463 465 errors.append( e ); 464 466 } // try 465 cur = dynamic_cast< NodeType * >( cur->get_next() ); 467 const ParseNode * temp = (cur->get_next()); 468 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr 469 if ( ! cur && temp ) { // non-homogeneous nodes ? 470 SemanticError( cur->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 471 } // if 466 472 } // while 467 473 if ( ! errors.isEmpty() ) { -
src/Parser/TypeData.cc
r9cd5bd2 rdf6cc9d 924 924 list< Declaration * >::iterator members = ret->get_members().begin(); 925 925 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 926 if ( cur->enumInLine ) { 927 // Tell the compiler this is a inline value placeholder 928 ObjectDecl * member = dynamic_cast< ObjectDecl* >(* members); 929 member->enumInLine = true; 930 } 926 931 if ( ret->isTyped && !ret->base && cur->has_enumeratorValue() ) { 927 932 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); -
src/Parser/lex.ll
r9cd5bd2 rdf6cc9d 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : T ue Sep 20 21:18:55202213 * Update Count : 76 212 * Last Modified On : Thu Oct 13 20:46:04 2022 13 * Update Count : 764 14 14 */ 15 15 … … 331 331 __uint128_t { KEYWORD_RETURN(UINT128); } // GCC 332 332 unsigned { KEYWORD_RETURN(UNSIGNED); } 333 __builtin_va_list { KEYWORD_RETURN(VALIST); } // GCC 333 __builtin_va_arg { KEYWORD_RETURN(VA_ARG); } // GCC 334 __builtin_va_list { KEYWORD_RETURN(VA_LIST); } // GCC 334 335 virtual { KEYWORD_RETURN(VIRTUAL); } // CFA 335 336 void { KEYWORD_RETURN(VOID); } -
src/Parser/parser.yy
r9cd5bd2 rdf6cc9d 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 27 13:21:28202213 // Update Count : 5 66112 // Last Modified On : Fri Oct 14 14:04:43 2022 13 // Update Count : 5751 14 14 // 15 15 … … 103 103 // distribute declaration_specifier across all declared variables, e.g., static, const, but not __attribute__. 104 104 assert( declList ); 105 //printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout );105 // printf( "distAttr1 typeSpec %p\n", typeSpec ); typeSpec->print( std::cout ); 106 106 DeclarationNode * cur = declList, * cl = (new DeclarationNode)->addType( typeSpec ); 107 //printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout );108 //cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name;107 // printf( "distAttr2 cl %p\n", cl ); cl->type->print( std::cout ); 108 // cl->type->aggregate.name = cl->type->aggInst.aggregate->aggregate.name; 109 109 110 110 for ( cur = dynamic_cast<DeclarationNode *>( cur->get_next() ); cur != nullptr; cur = dynamic_cast<DeclarationNode *>( cur->get_next() ) ) { … … 112 112 } // for 113 113 declList->addType( cl ); 114 //printf( "distAttr3 declList %p\n", declList ); declList->print( std::cout, 0 );114 // printf( "distAttr3 declList %p\n", declList ); declList->print( std::cout, 0 ); 115 115 return declList; 116 116 } // distAttr … … 248 248 } // forCtrl 249 249 250 static void IdentifierBeforeIdentifier( string & identifier1, string & identifier2, const char * kind ) { 251 SemanticError( yylloc, ::toString( "Adjacent identifiers \"", identifier1, "\" and \"", identifier2, "\" are not meaningful in a", kind, ".\n" 252 "Possible cause is misspelled type name or missing generic parameter." ) ); 253 } // IdentifierBeforeIdentifier 254 255 static void IdentifierBeforeType( string & identifier, const char * kind ) { 256 SemanticError( yylloc, ::toString( "Identifier \"", identifier, "\" cannot appear before a ", kind, ".\n" 257 "Possible cause is misspelled storage/CV qualifier, misspelled typename, or missing generic parameter." ) ); 258 } // IdentifierBeforeType 259 250 260 bool forall = false; // aggregate have one or more forall qualifiers ? 251 261 … … 295 305 %token TYPEDEF 296 306 %token EXTERN STATIC AUTO REGISTER 297 %token THREADLOCALGCC THREADLOCALC11 307 %token THREADLOCALGCC THREADLOCALC11 // GCC, C11 298 308 %token INLINE FORTRAN // C99, extension ISO/IEC 9899:1999 Section J.5.9(1) 299 309 %token NORETURN // C11 … … 308 318 %token DECIMAL32 DECIMAL64 DECIMAL128 // GCC 309 319 %token ZERO_T ONE_T // CFA 310 %token SIZEOF TYPEOF VA LIST AUTO_TYPE// GCC320 %token SIZEOF TYPEOF VA_LIST VA_ARG AUTO_TYPE // GCC 311 321 %token OFFSETOF BASETYPEOF TYPEID // CFA 312 322 %token ENUM STRUCT UNION … … 399 409 // declarations 400 410 %type<decl> abstract_declarator abstract_ptr abstract_array abstract_function array_dimension multi_array_dimension 401 %type<decl> abstract_parameter_declarator abstract_parameter_ptr abstract_parameter_array abstract_parameter_function array_parameter_dimension array_parameter_1st_dimension411 %type<decl> abstract_parameter_declarator_opt abstract_parameter_declarator abstract_parameter_ptr abstract_parameter_array abstract_parameter_function array_parameter_dimension array_parameter_1st_dimension 402 412 %type<decl> abstract_parameter_declaration 403 413 … … 651 661 // { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; } 652 662 | IDENTIFIER IDENTIFIER // syntax error 653 { 654 SemanticError( yylloc, ::toString( "Adjacent identifiers are not meaningful in an expression. " 655 "Possible problem is identifier \"", *$1.str, 656 "\" is a misspelled typename or an incorrectly specified type name, " 657 "e.g., missing generic parameter or missing struct/union/enum before typename." ) ); 658 $$ = nullptr; 659 } 660 | IDENTIFIER direct_type // syntax error 661 { 662 SemanticError( yylloc, ::toString( "Identifier \"", *$1.str, "\" cannot appear before a type. " 663 "Possible problem is misspelled storage or CV qualifier." ) ); 664 $$ = nullptr; 665 } 663 { IdentifierBeforeIdentifier( *$1.str, *$2.str, "n expression" ); $$ = nullptr; } 664 | IDENTIFIER type_qualifier // syntax error 665 { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; } 666 | IDENTIFIER storage_class // syntax error 667 { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; } 668 | IDENTIFIER basic_type_name // syntax error 669 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 670 | IDENTIFIER TYPEDEFname // syntax error 671 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 672 | IDENTIFIER TYPEGENname // syntax error 673 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 666 674 ; 667 675 … … 690 698 primary_expression 691 699 | postfix_expression '[' assignment_expression ',' tuple_expression_list ']' 692 693 694 700 // Historic, transitional: Disallow commas in subscripts. 701 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 702 // Current: Commas in subscripts make tuples. 695 703 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); } 696 704 | postfix_expression '[' assignment_expression ']' … … 712 720 | postfix_expression '(' argument_expression_list_opt ')' 713 721 { $$ = new ExpressionNode( build_func( $1, $3 ) ); } 722 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 723 // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; } 724 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ), 725 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 714 726 | postfix_expression '`' identifier // CFA, postfix call 715 727 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); } … … 2148 2160 | LONG 2149 2161 { $$ = DeclarationNode::newLength( DeclarationNode::Long ); } 2150 | VA LIST // GCC, __builtin_va_list2162 | VA_LIST // GCC, __builtin_va_list 2151 2163 { $$ = DeclarationNode::newBuiltinType( DeclarationNode::Valist ); } 2152 2164 | AUTO_TYPE … … 2593 2605 { $$ = DeclarationNode::newEnumValueGeneric( $1, $2 ); } 2594 2606 | INLINE type_name 2595 { $$ = DeclarationNode::newEnum ValueGeneric( new string("inline"), nullptr); }2607 { $$ = DeclarationNode::newEnumInLine( *$2->type->symbolic.name ); } 2596 2608 | enumerator_list ',' identifier_or_type_name enumerator_value_opt 2597 2609 { $$ = $1->appendList( DeclarationNode::newEnumValueGeneric( $3, $4 ) ); } … … 2993 3005 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); } 2994 3006 | declaration 3007 | IDENTIFIER IDENTIFIER 3008 { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; } 3009 | IDENTIFIER type_qualifier // syntax error 3010 { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; } 3011 | IDENTIFIER storage_class // syntax error 3012 { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; } 3013 | IDENTIFIER basic_type_name // syntax error 3014 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 3015 | IDENTIFIER TYPEDEFname // syntax error 3016 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 3017 | IDENTIFIER TYPEGENname // syntax error 3018 { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; } 2995 3019 | external_function_definition 2996 3020 | EXTENSION external_definition // GCC, multiple __extension__ allowed, meaning unknown … … 3023 3047 $$ = $6; 3024 3048 } 3049 // global distribution 3025 3050 | type_qualifier_list 3026 3051 { … … 3047 3072 | declaration_qualifier_list type_qualifier_list 3048 3073 { 3049 if ( ($1->type && $1->type->qualifiers.val) || $2->type->qualifiers.val) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); }3050 if ( ($1->type && $1->type->forall) || $2->type->forall) forall = true; // remember generic type3074 if ( ($1->type && $1->type->qualifiers.val) || ($2->type && $2->type->qualifiers.val) ) { SemanticError( yylloc, "CV qualifiers cannot be distributed; only storage-class and forall qualifiers." ); } 3075 if ( ($1->type && $1->type->forall) || ($2->type && $2->type->forall) ) forall = true; // remember generic type 3051 3076 } 3052 3077 '{' up external_definition_list_opt down '}' // CFA, namespace … … 3655 3680 // functions. 3656 3681 3682 abstract_parameter_declarator_opt: 3683 // empty 3684 { $$ = nullptr; } 3685 | abstract_parameter_declarator 3686 ; 3687 3657 3688 abstract_parameter_declarator: 3658 3689 abstract_parameter_ptr -
src/ResolvExpr/CandidateFinder.cpp
r9cd5bd2 rdf6cc9d 862 862 } 863 863 } 864 }865 866 void postvisit( const ast::QualifiedNameExpr * qualifiedNameExpr ) {867 auto mangleName = Mangle::mangle(qualifiedNameExpr->var);868 addCandidate( qualifiedNameExpr, tenv );869 864 } 870 865 -
src/ResolvExpr/Unify.cc
r9cd5bd2 rdf6cc9d 1036 1036 /// Creates a tuple type based on a list of Type 1037 1037 1038 1039 1038 static bool unifyList( 1040 1039 const std::vector< ast::ptr< ast::Type > > & list1, … … 1174 1173 return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab ); 1175 1174 } else { 1176 ast::Pass<Unify_new> comparator{ type2, env, need, have, open, widen, symtab }; 1177 type1->accept( comparator ); 1178 return comparator.core.result; 1175 return ast::Pass<Unify_new>::read( 1176 type1, type2, env, need, have, open, widen, symtab ); 1179 1177 } 1180 1178 } -
src/SymTab/Mangler.cc
r9cd5bd2 rdf6cc9d 65 65 void postvisit( const QualifiedType * qualType ); 66 66 67 void postvisit( const QualifiedNameExpr * qualNameExpr );68 69 67 std::string get_mangleName() { return mangleName; } 70 68 private: … … 307 305 mangleName += Encoding::qualifiedTypeEnd; 308 306 } 309 }310 311 void Mangler_old::postvisit( const QualifiedNameExpr * qual ) {312 maybeAccept( qual->var, *visitor );313 307 } 314 308 … … 423 417 void postvisit( const ast::OneType * oneType ); 424 418 void postvisit( const ast::QualifiedType * qualType ); 425 void postvisit( const ast::QualifiedNameExpr * qualNameExpr );426 419 427 420 std::string get_mangleName() { return mangleName; } … … 652 645 mangleName += Encoding::qualifiedTypeEnd; 653 646 } 654 }655 void Mangler_new::postvisit( const ast::QualifiedNameExpr * qual ) {656 maybeAccept( qual->var.get(), *visitor );657 647 } 658 648 -
src/SymTab/Validate.cc
r9cd5bd2 rdf6cc9d 858 858 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 859 859 } else if ( EnumInstType * enumInst = dynamic_cast< EnumInstType * >( designatorType ) ) { 860 // declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage, enumDecl->baseEnum->base ) );861 860 if ( enumInst->baseEnum ) { 862 861 const EnumDecl * enumDecl = enumInst->baseEnum; -
src/SymTab/ValidateType.cc
r9cd5bd2 rdf6cc9d 81 81 void previsit( QualifiedType * qualType ); 82 82 void postvisit( QualifiedType * qualType ); 83 84 83 void postvisit( QualifiedNameExpr * qualExpr ); 85 84 86 85 void postvisit( EnumDecl * enumDecl ); 87 86 void postvisit( StructDecl * structDecl ); -
src/SynTree/AddressExpr.cc
r9cd5bd2 rdf6cc9d 50 50 set_result( addrType( refType->base ) ); 51 51 } else { 52 if(!arg->result->location.isSet()) arg->result->location = arg->location; 52 53 SemanticError( arg->result, "Attempt to take address of non-lvalue expression: " ); 53 54 } // if -
src/SynTree/Declaration.h
r9cd5bd2 rdf6cc9d 121 121 Initializer * init; 122 122 Expression * bitfieldWidth; 123 bool enumInLine = false; 123 124 124 125 ObjectDecl( const std::string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage, Expression * bitfieldWidth, Type * type, Initializer * init, -
src/SynTree/Expression.h
r9cd5bd2 rdf6cc9d 168 168 Declaration * type_decl; 169 169 std::string name; 170 DeclarationWithType * var;171 170 172 171 QualifiedNameExpr( Declaration * decl, std::string name): Expression(), type_decl(decl), name(name) {} 173 QualifiedNameExpr( const QualifiedNameExpr & other): Expression(other), type_decl(other.type_decl), name(other.name), var(other.var) {} 174 DeclarationWithType * get_var() const { return var; } 175 void set_var( DeclarationWithType * newValue ) { var = newValue; } 172 QualifiedNameExpr( const QualifiedNameExpr & other): Expression(other), type_decl(other.type_decl), name(other.name) {} 176 173 177 174 virtual ~QualifiedNameExpr() { 178 delete var;179 175 delete type_decl; 180 176 } -
src/Tuples/TupleExpansionNew.cpp
r9cd5bd2 rdf6cc9d 10 10 // Created On : Mon Aug 23 15:36:09 2021 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Sep 20 16:17:00 202213 // Update Count : 412 // Last Modified On : Mon Sep 26 10:25:00 2022 13 // Update Count : 5 14 14 // 15 15 … … 30 30 struct UniqueExprExpander final : public ast::WithDeclsToAdd<> { 31 31 const ast::Expr * postvisit( const ast::UniqueExpr * unqExpr ); 32 std::map< int, ast::ptr<ast::Expr> > decls; // not vector, because order added may not be increasing order 32 // Not a vector, because they may not be adding in increasing order. 33 std::map< int, ast::ptr<ast::Expr> > decls; 34 }; 35 36 /// Replaces Tuple Assign & Index Expressions, and Tuple Types. 37 struct TupleMainExpander final : 38 public ast::WithCodeLocation, 39 public ast::WithDeclsToAdd<>, 40 public ast::WithGuards, 41 public ast::WithVisitorRef<TupleMainExpander> { 42 ast::Expr const * postvisit( ast::TupleAssignExpr const * expr ); 43 44 void previsit( ast::CompoundStmt const * ); 45 ast::Expr const * postvisit( ast::Expr const * expr ); 46 ast::Type const * postvisit( ast::TupleType const * type ); 47 48 ast::Expr const * postvisit( ast::TupleIndexExpr const * expr ); 49 private: 50 ScopedMap< int, ast::StructDecl const * > typeMap; 51 }; 52 53 struct TupleExprExpander final { 54 ast::Expr const * postvisit( ast::TupleExpr const * expr ); 33 55 }; 34 56 … … 100 122 } 101 123 102 /// Replaces Tuple Assign & Index Expressions, and Tuple Types. 103 struct TupleMainExpander final : 104 public ast::WithCodeLocation, 105 public ast::WithDeclsToAdd<>, 106 public ast::WithGuards, 107 public ast::WithVisitorRef<TupleMainExpander> { 108 ast::Expr const * postvisit( ast::TupleAssignExpr const * expr ) { 109 // Just move the env on the new top level expression. 110 return ast::mutate_field( expr->stmtExpr.get(), 111 &ast::TupleAssignExpr::env, expr->env.get() ); 112 } 113 114 void previsit( ast::CompoundStmt const * ) { 115 GuardScope( typeMap ); 116 } 117 118 ast::Expr const * postvisit( ast::Expr const * expr ) { 119 if ( nullptr == expr->env ) { 120 return expr; 121 } 122 // TypeSubstitutions are never visited in the new Pass template, 123 // so it is done manually here, where all types have to be replaced. 124 return ast::mutate_field( expr, &ast::Expr::env, 125 expr->env->accept( *visitor ) ); 126 } 127 128 ast::Type const * postvisit( ast::TupleType const * type ) { 129 assert( location ); 130 unsigned tupleSize = type->size(); 131 if ( !typeMap.count( tupleSize ) ) { 132 ast::StructDecl * decl = new ast::StructDecl( *location, 133 toString( "_tuple", tupleSize, "_" ) 124 // Handles expansion of tuple assignment. 125 ast::Expr const * TupleMainExpander::postvisit( 126 ast::TupleAssignExpr const * expr ) { 127 // Just move the env on the new top level expression. 128 return ast::mutate_field( expr->stmtExpr.get(), 129 &ast::TupleAssignExpr::env, expr->env.get() ); 130 } 131 132 // Context information for tuple type expansion. 133 void TupleMainExpander::previsit( ast::CompoundStmt const * ) { 134 GuardScope( typeMap ); 135 } 136 137 // Make sure types in a TypeSubstitution are expanded. 138 ast::Expr const * TupleMainExpander::postvisit( ast::Expr const * expr ) { 139 if ( nullptr == expr->env ) { 140 return expr; 141 } 142 return ast::mutate_field( expr, &ast::Expr::env, 143 expr->env->accept( *visitor ) ); 144 } 145 146 // Create a generic tuple structure of a given size. 147 ast::StructDecl * createTupleStruct( 148 unsigned int tupleSize, CodeLocation const & location ) { 149 ast::StructDecl * decl = new ast::StructDecl( location, 150 toString( "_tuple", tupleSize, "_" ) 151 ); 152 decl->body = true; 153 154 for ( size_t i = 0 ; i < tupleSize ; ++i ) { 155 ast::TypeDecl * typeParam = new ast::TypeDecl( location, 156 toString( "tuple_param_", tupleSize, "_", i ), 157 ast::Storage::Classes(), 158 nullptr, 159 ast::TypeDecl::Dtype, 160 true 134 161 ); 135 decl->body = true; 136 137 for ( size_t i = 0 ; i < tupleSize ; ++i ) { 138 ast::TypeDecl * typeParam = new ast::TypeDecl( *location, 139 toString( "tuple_param_", tupleSize, "_", i ), 140 ast::Storage::Classes(), 141 nullptr, 142 ast::TypeDecl::Dtype, 143 true 144 ); 145 ast::ObjectDecl * member = new ast::ObjectDecl( *location, 146 toString( "field_", i ), 147 new ast::TypeInstType( typeParam ) 148 ); 149 decl->params.push_back( typeParam ); 150 decl->members.push_back( member ); 151 } 152 153 // Empty structures are not standard C. Add a dummy field to 154 // empty tuples to silence warnings when a compound literal 155 // `_tuple0_` is created. 156 if ( tupleSize == 0 ) { 157 decl->members.push_back( 158 new ast::ObjectDecl( *location, 159 "dummy", 160 new ast::BasicType( ast::BasicType::SignedInt ), 161 nullptr, 162 ast::Storage::Classes(), 163 // Does this have to be a C linkage? 164 ast::Linkage::C 165 ) 166 ); 167 } 168 typeMap[tupleSize] = decl; 169 declsToAddBefore.push_back( decl ); 170 } 171 172 ast::StructDecl const * decl = typeMap[ tupleSize ]; 173 ast::StructInstType * newType = 174 new ast::StructInstType( decl, type->qualifiers ); 175 for ( auto pair : group_iterate( type->types, decl->params ) ) { 176 ast::Type const * t = std::get<0>( pair ); 177 newType->params.push_back( 178 new ast::TypeExpr( *location, ast::deepCopy( t ) ) ); 179 } 180 return newType; 181 } 182 183 ast::Expr const * postvisit( ast::TupleIndexExpr const * expr ) { 184 CodeLocation const & location = expr->location; 185 ast::Expr const * tuple = expr->tuple.get(); 186 assert( tuple ); 187 unsigned int index = expr->index; 188 ast::TypeSubstitution const * env = expr->env.get(); 189 190 if ( auto tupleExpr = dynamic_cast<ast::TupleExpr const *>( tuple ) ) { 191 // Optimization: If it is a definitely pure tuple expr, 192 // then it can reduce to the only relevant component. 193 if ( !maybeImpureIgnoreUnique( tupleExpr ) ) { 194 assert( index < tupleExpr->exprs.size() ); 195 ast::ptr<ast::Expr> const & expr = 196 *std::next( tupleExpr->exprs.begin(), index ); 197 ast::Expr * ret = ast::mutate( expr.get() ); 198 ret->env = env; 199 return ret; 200 } 201 } 202 203 auto type = tuple->result.strict_as<ast::StructInstType>(); 204 ast::StructDecl const * structDecl = type->base; 205 assert( index < structDecl->members.size() ); 206 ast::ptr<ast::Decl> const & member = 207 *std::next( structDecl->members.begin(), index ); 208 ast::MemberExpr * memberExpr = new ast::MemberExpr( location, 209 member.strict_as<ast::DeclWithType>(), tuple ); 210 memberExpr->env = env; 211 return memberExpr; 212 } 213 private: 214 ScopedMap< int, ast::StructDecl const * > typeMap; 215 }; 162 ast::ObjectDecl * member = new ast::ObjectDecl( location, 163 toString( "field_", i ), 164 new ast::TypeInstType( typeParam ) 165 ); 166 decl->params.push_back( typeParam ); 167 decl->members.push_back( member ); 168 } 169 170 // Empty structures are not standard C. Add a dummy field to 171 // empty tuples to silence warnings when a compound literal 172 // `_tuple0_` is created. 173 if ( tupleSize == 0 ) { 174 decl->members.push_back( 175 new ast::ObjectDecl( location, 176 "dummy", 177 new ast::BasicType( ast::BasicType::SignedInt ), 178 nullptr, 179 ast::Storage::Classes(), 180 // Does this have to be a C linkage? 181 ast::Linkage::C 182 ) 183 ); 184 } 185 return decl; 186 } 187 188 ast::Type const * TupleMainExpander::postvisit( ast::TupleType const * type ) { 189 assert( location ); 190 unsigned tupleSize = type->size(); 191 if ( !typeMap.count( tupleSize ) ) { 192 ast::StructDecl * decl = createTupleStruct( tupleSize, *location ); 193 typeMap[tupleSize] = decl; 194 declsToAddBefore.push_back( decl ); 195 } 196 197 ast::StructDecl const * decl = typeMap[ tupleSize ]; 198 ast::StructInstType * newType = 199 new ast::StructInstType( decl, type->qualifiers ); 200 for ( auto pair : group_iterate( type->types, decl->params ) ) { 201 ast::Type const * t = std::get<0>( pair ); 202 newType->params.push_back( 203 new ast::TypeExpr( *location, ast::deepCopy( t ) ) ); 204 } 205 return newType; 206 } 207 208 // Expand a tuple index into a field access in the underlying structure. 209 ast::Expr const * TupleMainExpander::postvisit( 210 ast::TupleIndexExpr const * expr ) { 211 CodeLocation const & location = expr->location; 212 ast::Expr const * tuple = expr->tuple.get(); 213 assert( tuple ); 214 unsigned int index = expr->index; 215 ast::TypeSubstitution const * env = expr->env.get(); 216 217 if ( auto tupleExpr = dynamic_cast<ast::TupleExpr const *>( tuple ) ) { 218 // Optimization: If it is a definitely pure tuple expr, 219 // then it can reduce to the only relevant component. 220 if ( !maybeImpureIgnoreUnique( tupleExpr ) ) { 221 assert( index < tupleExpr->exprs.size() ); 222 ast::ptr<ast::Expr> const & expr = 223 *std::next( tupleExpr->exprs.begin(), index ); 224 ast::Expr * ret = ast::mutate( expr.get() ); 225 ret->env = env; 226 return ret; 227 } 228 } 229 230 auto type = tuple->result.strict_as<ast::StructInstType>(); 231 ast::StructDecl const * structDecl = type->base; 232 assert( index < structDecl->members.size() ); 233 ast::ptr<ast::Decl> const & member = 234 *std::next( structDecl->members.begin(), index ); 235 ast::MemberExpr * memberExpr = new ast::MemberExpr( location, 236 member.strict_as<ast::DeclWithType>(), tuple ); 237 memberExpr->env = env; 238 return memberExpr; 239 } 216 240 217 241 ast::Expr const * replaceTupleExpr( … … 249 273 } 250 274 251 struct TupleExprExpander final { 252 ast::Expr const * postvisit( ast::TupleExpr const * expr ) { 253 return replaceTupleExpr( expr->location, 254 expr->result, expr->exprs, expr->env ); 255 } 256 }; 275 ast::Expr const * TupleExprExpander::postvisit( ast::TupleExpr const * expr ) { 276 return replaceTupleExpr( expr->location, 277 expr->result, expr->exprs, expr->env ); 278 } 257 279 258 280 } // namespace -
src/Tuples/Tuples.cc
r9cd5bd2 rdf6cc9d 17 17 18 18 #include "AST/Pass.hpp" 19 #include "AST/Inspect.hpp" 19 20 #include "AST/LinkageSpec.hpp" 20 21 #include "Common/PassVisitor.h" … … 80 81 81 82 void previsit( ast::ApplicationExpr const * appExpr ) { 82 if ( ast::DeclWithType const * function = InitTweak::getFunction( appExpr ) ) {83 if ( ast::DeclWithType const * function = ast::getFunction( appExpr ) ) { 83 84 if ( function->linkage == ast::Linkage::Intrinsic 84 85 && ( function->name == "*?" || function->name == "?[?]" ) ) { -
src/Validate/FixQualifiedTypes.cpp
r9cd5bd2 rdf6cc9d 102 102 } 103 103 104 105 auto var = new ast::ObjectDecl( t->var->location, t->name, 106 new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall ); 107 var->scopeLevel = 1; // 1 for now; should copy the scopeLevel of the enumValue 104 auto var = new ast::ObjectDecl( t->location, t->name, 105 new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall ); 108 106 var->mangleName = Mangle::mangle( var ); 109 107 return new ast::VariableExpr( t->location, var ); 110 // return ret;111 108 } 112 109 -
src/Validate/LinkReferenceToTypes.cpp
r9cd5bd2 rdf6cc9d 44 44 void postvisit( ast::UnionDecl const * decl ); 45 45 ast::TraitDecl const * postvisit( ast::TraitDecl const * decl ); 46 ast::QualifiedNameExpr const * previsit( ast::QualifiedNameExpr const * decl);47 46 48 47 private: … … 203 202 } 204 203 204 // The following section 205 auto mut = ast::mutate( decl ); 206 std::vector<ast::ptr<ast::Decl>> buffer; 207 for ( auto it = decl->members.begin(); it != decl->members.end(); ++it) { 208 auto member = (*it).as<ast::ObjectDecl>(); 209 if ( member->enumInLine ) { 210 auto targetEnum = symtab.lookupEnum( member->name ); 211 if ( targetEnum ) { 212 for ( auto singleMamber : targetEnum->members ) { 213 auto tm = singleMamber.as<ast::ObjectDecl>(); 214 auto t = new ast::ObjectDecl( 215 member->location, // use the "inline" location 216 tm->name, 217 new ast::EnumInstType( decl, ast::CV::Const ), 218 // Construct a new EnumInstType as the type 219 tm->init, 220 tm->storage, 221 tm->linkage, 222 tm->bitfieldWidth, 223 {}, // enum member doesn't have attribute 224 tm->funcSpec 225 ); 226 t->importValue = true; 227 buffer.push_back(t); 228 } 229 } 230 } else { 231 auto search_it = std::find_if( buffer.begin(), buffer.end(), [member](ast::ptr<ast::Decl> cur) { 232 auto curAsObjDecl = cur.as<ast::ObjectDecl>(); 233 return (curAsObjDecl->importValue) && (curAsObjDecl->name == member->name); 234 }); 235 if ( search_it != buffer.end() ) { 236 buffer.erase( search_it ); // Found an import enum value that has the same name 237 // override the imported value 238 } 239 buffer.push_back( *it ); 240 } 241 } 242 mut->members = buffer; 243 decl = mut; 244 205 245 ForwardEnumsType::iterator fwds = forwardEnums.find( decl->name ); 206 246 if ( fwds != forwardEnums.end() ) { … … 284 324 } 285 325 286 ast::QualifiedNameExpr const * LinkTypesCore::previsit( ast::QualifiedNameExpr const * decl ) {287 // Try to lookup type288 if ( auto objDecl = decl->type_decl.as<ast::ObjectDecl>() ) {289 if ( auto inst = objDecl->type.as<ast::TypeInstType>()) {290 if ( auto enumDecl = symtab.lookupEnum ( inst->name ) ) {291 auto mut = ast::mutate( decl );292 mut->type_decl = enumDecl;293 auto enumInst = new ast::EnumInstType( enumDecl );294 enumInst->name = decl->name;295 // Adding result; addCandidate() use result296 mut->result = enumInst;297 decl = mut;298 }299 }300 } else if ( auto enumDecl = decl->type_decl.as<ast::EnumDecl>() ) {301 auto mut = ast::mutate( decl );302 auto enumInst = new ast::EnumInstType( enumDecl );303 enumInst->name = decl->name;304 // Adding result; addCandidate() use result305 mut->result = enumInst;306 decl = mut;307 }308 // ast::EnumDecl const * decl = symtab.lookupEnum( type->name );309 // // It's not a semantic error if the enum is not found, just an implicit forward declaration.310 // if ( decl ) {311 // // Just linking in the node.312 // auto mut = ast::mutate( type );313 // mut->base = const_cast<ast::EnumDecl *>( decl );314 // type = mut;315 // }316 return decl;317 }318 319 326 } // namespace 320 327 -
src/main.cc
r9cd5bd2 rdf6cc9d 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thu Sep 15 13:58:00 202213 // Update Count : 67 812 // Last Modified On : Wed Oct 5 12:06:00 2022 13 // Update Count : 679 14 14 // 15 15 … … 444 444 445 445 PASS( "Instantiate Generics", GenPoly::instantiateGeneric( transUnit ) ); 446 if ( genericsp ) { 447 dump( std::move( transUnit ) ); 448 return EXIT_SUCCESS; 449 } // if 450 451 PASS( "Convert L-Value", GenPoly::convertLvalue( transUnit ) ); 446 452 447 453 translationUnit = convert( std::move( transUnit ) ); 448 449 if ( genericsp ) {450 dump( translationUnit );451 return EXIT_SUCCESS;452 } // if453 454 PASS( "Convert L-Value", GenPoly::convertLvalue( translationUnit ) );455 454 456 455 if ( bboxp ) {
Note:
See TracChangeset
for help on using the changeset viewer.