@@ -752,7 +752,6 @@ struct TConverter final : UastConverter {
752
752
753
753
// Create a new temporary. The type used for it must be supplied.
754
754
Symbol* makeNewTemp (const types::QualifiedType& qt, bool insertDef=true );
755
- Symbol* makeNewTemp (::Qualifier qual, Type* t, bool insertDef=true );
756
755
757
756
// Store 'e' in a temporary if it does not already refer to one. The type
758
757
// for the temporary must be provided and cannot easily be retrieved from
@@ -2809,22 +2808,17 @@ TConverter::defaultValueForType(const types::Type* t,
2809
2808
}
2810
2809
2811
2810
Symbol*
2812
- TConverter::makeNewTemp (::Qualifier qual, Type* t , bool insertDef) {
2811
+ TConverter::makeNewTemp (const types::QualifiedType& qt , bool insertDef) {
2813
2812
auto ret = newTemp ();
2814
2813
ret->addFlag (FLAG_EXPR_TEMP);
2815
- ret->qual = qual ;
2816
- ret->type = t ;
2814
+ ret->qual = convertQualifier (qt. kind ()) ;
2815
+ ret->type = convertType (qt. type ()) ;
2817
2816
2818
2817
if (insertDef) insertStmt (new DefExpr (ret));
2819
2818
2820
2819
return ret;
2821
2820
}
2822
2821
2823
- Symbol*
2824
- TConverter::makeNewTemp (const types::QualifiedType& qt, bool insertDef) {
2825
- return makeNewTemp (convertQualifier (qt.kind ()), convertType (qt.type ()), insertDef);
2826
- }
2827
-
2828
2822
SymExpr*
2829
2823
TConverter::storeInTempIfNeeded (Expr* e, const types::QualifiedType& qt) {
2830
2824
if (SymExpr* se = toSymExpr (e)) {
@@ -2833,16 +2827,12 @@ TConverter::storeInTempIfNeeded(Expr* e, const types::QualifiedType& qt) {
2833
2827
2834
2828
Symbol* t = nullptr ;
2835
2829
2836
- if (qt.isUnknown ()) {
2837
- t = makeNewTemp (e->qualType ().getQual (), e->typeInfo ());
2838
- } else {
2839
- // Prevent default-constructed 'QualifiedType' from slipping in.
2840
- INT_ASSERT (qt.hasTypePtr ());
2841
-
2842
- // otherwise, store the value in a temp
2843
- t = makeNewTemp (qt);
2844
- }
2845
-
2830
+ // Prevent default-constructed 'QualifiedType' from slipping in.
2831
+ // Note: Can't use, e.g., ``e->qualType()`` here because ``qualType`` may
2832
+ // attempt to invoke production's resolution in some cases.
2833
+ INT_ASSERT (qt.hasTypePtr ());
2834
+ // otherwise, store the value in a temp
2835
+ t = makeNewTemp (qt);
2846
2836
insertStmt (new CallExpr (PRIM_MOVE, t, e));
2847
2837
return new SymExpr (t);
2848
2838
}
@@ -4068,8 +4058,9 @@ void TConverter::ActualConverter::convertActual(const FormalActual& fa) {
4068
4058
INT_ASSERT (astActual);
4069
4059
4070
4060
// Convert the actual and leave.
4071
- auto actualExpr = tc_->convertExpr (astActual, rv_);
4072
- std::get<Expr*>(slot) = tc_->storeInTempIfNeeded (actualExpr, {});
4061
+ types::QualifiedType actualType;
4062
+ auto actualExpr = tc_->convertExpr (astActual, rv_, &actualType);
4063
+ std::get<Expr*>(slot) = tc_->storeInTempIfNeeded (actualExpr, actualType);
4073
4064
4074
4065
return ;
4075
4066
}
@@ -5090,50 +5081,41 @@ bool TConverter::enter(const ExternBlock* node, RV& rv) {
5090
5081
5091
5082
void TConverter::exit (const ExternBlock* node, RV& rv) {}
5092
5083
5093
- static SymExpr* makeCaseCond (TConverter& tc, TConverter::RV& rv,
5084
+ static SymExpr* makeCaseCond (TConverter* tc, TConverter::RV& rv,
5094
5085
const uast::When* when,
5095
5086
SymExpr* selectExpr,
5096
5087
const uast::AstNode* cs) {
5097
5088
auto re = rv.byAst (cs);
5098
5089
5099
5090
// Grab the '==' ResolvedFunction
5100
- const AssociatedAction* action = nullptr ;
5101
- for (const auto & a : re.associatedActions ()) {
5102
- if (a.action () == AssociatedAction::COMPARE) {
5103
- action = &a;
5104
- break ;
5105
- } else {
5106
- INT_ASSERT (false );
5107
- }
5108
- }
5091
+ auto action = re.getAction (AssociatedAction::COMPARE);
5092
+ INT_ASSERT (action);
5109
5093
auto cmp = action->fn ();
5110
5094
5111
5095
// TODO: create a wrapper for this kind of thing
5112
5096
const ResolvedFunction* rf = nullptr ;
5113
- if (tc. paramElideCallOrNull (cmp, re.poiScope (), &rf)) {
5097
+ if (tc-> paramElideCallOrNull (cmp, re.poiScope (), &rf)) {
5114
5098
INT_ASSERT (false && " Should not have param elided initializer call!" );
5115
5099
} else if (!rf) {
5116
- return toSymExpr (TC_PLACEHOLDER ((&tc) ));
5100
+ return toSymExpr (TC_PLACEHOLDER (tc ));
5117
5101
}
5118
5102
5119
- auto fn = tc. findOrConvertFunction (rf);
5103
+ auto fn = tc-> findOrConvertFunction (rf);
5120
5104
INT_ASSERT (fn);
5121
5105
5122
- // TODO: is there a better way to represent the return type of '=='? As-is,
5123
- // it's a bit confusing for the case-expression's type in 'rv' to always be
5124
- // a bool.
5125
- Expr* caseExpr = tc.convertExpr (cs, rv);
5126
- caseExpr = tc.storeInTempIfNeeded (caseExpr, {});
5106
+ types::QualifiedType caseType;
5107
+ Expr* caseExpr = tc->convertExpr (cs, rv, &caseType);
5108
+ caseExpr = tc->storeInTempIfNeeded (caseExpr, caseType);
5127
5109
5128
5110
// TODO: handle case where passing to '==' has an associated action
5129
5111
auto call = new CallExpr (fn, selectExpr->copy (), caseExpr);
5130
5112
5131
- auto cond = tc. storeInTempIfNeeded (call, re.type ());
5113
+ auto cond = tc-> storeInTempIfNeeded (call, re.type ());
5132
5114
5133
5115
return cond;
5134
5116
}
5135
5117
5136
- static SymExpr* getWhenCond (TConverter& tc, TConverter::RV& rv,
5118
+ static SymExpr* getWhenCond (TConverter* tc, TConverter::RV& rv,
5137
5119
const uast::When* when,
5138
5120
SymExpr* selectExpr) {
5139
5121
if (when->numCaseExprs () == 1 ) {
@@ -5145,14 +5127,16 @@ static SymExpr* getWhenCond(TConverter& tc, TConverter::RV& rv,
5145
5127
// not match.
5146
5128
5147
5129
VarSymbol* agg = new VarSymbol (" _case_cond_agg" , dtBool);
5148
- tc. insertStmt (new CallExpr (PRIM_MOVE, agg, gFalse ));
5149
- tc. insertStmt (new DefExpr (agg));
5130
+ tc-> insertStmt (new CallExpr (PRIM_MOVE, agg, gFalse ));
5131
+ tc-> insertStmt (new DefExpr (agg));
5150
5132
5151
5133
int count = 0 ;
5152
5134
for (auto cs : when->caseExprs ()) {
5153
- // If it's param-true, 'getWhenCond' would not have been called
5154
- // If it's param-false, there's no need to generate any comparisons
5155
- if (rv.byAst (cs).type ().isParam ()) continue ;
5135
+ if (auto action = rv.byAst (cs).getAction (AssociatedAction::COMPARE)) {
5136
+ // If it's param-true, 'getWhenCond' would not have been called
5137
+ // If it's param-false, there's no need to generate any comparisons
5138
+ if (action->type ().isParam ()) continue ;
5139
+ }
5156
5140
5157
5141
auto cond = makeCaseCond (tc, rv, when, selectExpr, cs);
5158
5142
@@ -5161,16 +5145,16 @@ static SymExpr* getWhenCond(TConverter& tc, TConverter::RV& rv,
5161
5145
5162
5146
auto elseBlock = new BlockStmt ();
5163
5147
auto branch = new CondStmt (cond, thenBlock, elseBlock);
5164
- tc. insertStmt (branch);
5148
+ tc-> insertStmt (branch);
5165
5149
5166
5150
// Push the else branch so that the next case check is inserted there
5167
- tc. pushBlock (elseBlock);
5151
+ tc-> pushBlock (elseBlock);
5168
5152
count += 1 ;
5169
5153
}
5170
5154
5171
5155
// pop the blocks we pushed, to get back to the when-stmt level
5172
5156
for (int i = 0 ; i < count; i++) {
5173
- tc. popBlock ();
5157
+ tc-> popBlock ();
5174
5158
}
5175
5159
5176
5160
return new SymExpr (agg);
@@ -5196,13 +5180,14 @@ bool TConverter::enter(const Select* node, RV& rv) {
5196
5180
bool anyParamTrue = false ;
5197
5181
bool allParamFalse = true ;
5198
5182
for (auto cs : when->caseExprs ()) {
5199
- auto qt = rv.byAst (cs).type ();
5200
- if (!qt .isParamFalse ()) {
5201
- allParamFalse = false ;
5202
- }
5183
+ if ( auto action = rv.byAst (cs).getAction (AssociatedAction::COMPARE)) {
5184
+ if (!action-> type () .isParamFalse ()) {
5185
+ allParamFalse = false ;
5186
+ }
5203
5187
5204
- if (qt.isParamTrue ()) {
5205
- anyParamTrue = true ;
5188
+ if (action->type ().isParamTrue ()) {
5189
+ anyParamTrue = true ;
5190
+ }
5206
5191
}
5207
5192
}
5208
5193
@@ -5214,7 +5199,7 @@ bool TConverter::enter(const Select* node, RV& rv) {
5214
5199
// Nothing else can match after this, so we're done
5215
5200
break ;
5216
5201
} else if (!allParamFalse) {
5217
- auto cond = getWhenCond (* this , rv, when, selectSym);
5202
+ auto cond = getWhenCond (this , rv, when, selectSym);
5218
5203
5219
5204
auto thenBlock = new BlockStmt ();
5220
5205
pushBlock (thenBlock);
0 commit comments