Commit ee63f5d9 by Olli Etuaho

Move function parsing code to ParseContext

This change is pure refactoring. It will make it easier to fix bugs related to function declarations. BUG=angleproject:911 BUG=angleproject:1067 BUG=angleproject:1068 TEST=angle_unittests Change-Id: I031783dc02612d9cf3ff7a9c8291cf8ab33577aa Reviewed-on: https://chromium-review.googlesource.com/320081 Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com> Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org>
parent e6683860
...@@ -1925,6 +1925,62 @@ void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier) ...@@ -1925,6 +1925,62 @@ void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
} }
} }
TIntermAggregate *TParseContext::addFunctionPrototypeDeclaration(const TFunction &function,
const TSourceLoc &location)
{
TIntermAggregate *prototype = new TIntermAggregate;
prototype->setType(function.getReturnType());
prototype->setName(function.getMangledName());
prototype->setFunctionId(function.getUniqueId());
for (size_t i = 0; i < function.getParamCount(); i++)
{
const TConstParameter &param = function.getParam(i);
if (param.name != 0)
{
TVariable variable(param.name, *param.type);
TIntermSymbol *paramSymbol = intermediate.addSymbol(
variable.getUniqueId(), variable.getName(), variable.getType(), location);
prototype = intermediate.growAggregate(prototype, paramSymbol, location);
}
else
{
TIntermSymbol *paramSymbol = intermediate.addSymbol(0, "", *param.type, location);
prototype = intermediate.growAggregate(prototype, paramSymbol, location);
}
}
prototype->setOp(EOpPrototype);
symbolTable.pop();
return prototype;
}
TIntermAggregate *TParseContext::addFunctionDefinition(const TFunction &function,
TIntermAggregate *functionPrototype,
TIntermAggregate *functionBody,
const TSourceLoc &location)
{
//?? Check that all paths return a value if return type != void ?
// May be best done as post process phase on intermediate code
if (mCurrentFunctionType->getBasicType() != EbtVoid && !mFunctionReturnsValue)
{
error(location, "function does not return a value:", "", function.getName().c_str());
recover();
}
TIntermAggregate *aggregate =
intermediate.growAggregate(functionPrototype, functionBody, location);
intermediate.setAggregateOperator(aggregate, EOpFunction, location);
aggregate->setName(function.getMangledName().c_str());
aggregate->setType(function.getReturnType());
aggregate->setFunctionId(function.getUniqueId());
symbolTable.pop();
return aggregate;
}
void TParseContext::parseFunctionPrototype(const TSourceLoc &location, void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
TFunction *function, TFunction *function,
TIntermAggregate **aggregateOut) TIntermAggregate **aggregateOut)
...@@ -1978,8 +2034,8 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location, ...@@ -1978,8 +2034,8 @@ void TParseContext::parseFunctionPrototype(const TSourceLoc &location,
// //
// Remember the return type for later checking for RETURN statements. // Remember the return type for later checking for RETURN statements.
// //
setCurrentFunctionType(&(prevDec->getReturnType())); mCurrentFunctionType = &(prevDec->getReturnType());
setFunctionReturnsValue(false); mFunctionReturnsValue = false;
// //
// Insert parameters into the symbol table. // Insert parameters into the symbol table.
......
...@@ -102,23 +102,11 @@ class TParseContext : angle::NonCopyable ...@@ -102,23 +102,11 @@ class TParseContext : angle::NonCopyable
mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh; mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
} }
bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
void setFunctionReturnsValue(bool functionReturnsValue)
{
mFunctionReturnsValue = functionReturnsValue;
}
void setLoopNestingLevel(int loopNestintLevel) void setLoopNestingLevel(int loopNestintLevel)
{ {
mLoopNestingLevel = loopNestintLevel; mLoopNestingLevel = loopNestintLevel;
} }
const TType *getCurrentFunctionType() const { return mCurrentFunctionType; }
void setCurrentFunctionType(const TType *currentFunctionType)
{
mCurrentFunctionType = currentFunctionType;
}
void incrLoopNestingLevel() { ++mLoopNestingLevel; } void incrLoopNestingLevel() { ++mLoopNestingLevel; }
void decrLoopNestingLevel() { --mLoopNestingLevel; } void decrLoopNestingLevel() { --mLoopNestingLevel; }
...@@ -244,6 +232,12 @@ class TParseContext : angle::NonCopyable ...@@ -244,6 +232,12 @@ class TParseContext : angle::NonCopyable
TIntermTyped *initializer); TIntermTyped *initializer);
void parseGlobalLayoutQualifier(const TPublicType &typeQualifier); void parseGlobalLayoutQualifier(const TPublicType &typeQualifier);
TIntermAggregate *addFunctionPrototypeDeclaration(const TFunction &function,
const TSourceLoc &location);
TIntermAggregate *addFunctionDefinition(const TFunction &function,
TIntermAggregate *functionPrototype,
TIntermAggregate *functionBody,
const TSourceLoc &location);
void parseFunctionPrototype(const TSourceLoc &location, void parseFunctionPrototype(const TSourceLoc &location,
TFunction *function, TFunction *function,
TIntermAggregate **aggregateOut); TIntermAggregate **aggregateOut);
......
...@@ -178,10 +178,10 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons ...@@ -178,10 +178,10 @@ extern void yyerror(YYLTYPE* yylloc, TParseContext* context, void *scanner, cons
%type <interm.intermNode> translation_unit function_definition %type <interm.intermNode> translation_unit function_definition
%type <interm.intermNode> statement simple_statement %type <interm.intermNode> statement simple_statement
%type <interm.intermAggregate> statement_list compound_statement %type <interm.intermAggregate> statement_list compound_statement compound_statement_no_new_scope
%type <interm.intermNode> declaration_statement selection_statement expression_statement %type <interm.intermNode> declaration_statement selection_statement expression_statement
%type <interm.intermNode> declaration external_declaration %type <interm.intermNode> declaration external_declaration
%type <interm.intermNode> for_init_statement compound_statement_no_new_scope %type <interm.intermNode> for_init_statement
%type <interm.nodePair> selection_rest_statement for_rest_statement %type <interm.nodePair> selection_rest_statement for_rest_statement
%type <interm.intermSwitch> switch_statement %type <interm.intermSwitch> switch_statement
%type <interm.intermCase> case_label %type <interm.intermCase> case_label
...@@ -580,33 +580,8 @@ enter_struct ...@@ -580,33 +580,8 @@ enter_struct
; ;
declaration declaration
: function_prototype SEMICOLON { : function_prototype SEMICOLON {
TFunction &function = *($1.function); $$ = context->addFunctionPrototypeDeclaration(*($1.function), @1);
TIntermAggregate *prototype = new TIntermAggregate;
prototype->setType(function.getReturnType());
prototype->setName(function.getMangledName());
prototype->setFunctionId(function.getUniqueId());
for (size_t i = 0; i < function.getParamCount(); i++)
{
const TConstParameter &param = function.getParam(i);
if (param.name != 0)
{
TVariable variable(param.name, *param.type);
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), @1), @1);
}
else
{
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, @1), @1);
}
}
prototype->setOp(EOpPrototype);
$$ = prototype;
context->symbolTable.pop();
} }
| init_declarator_list SEMICOLON { | init_declarator_list SEMICOLON {
TIntermAggregate *aggNode = $1.intermAggregate; TIntermAggregate *aggNode = $1.intermAggregate;
...@@ -1599,20 +1574,7 @@ function_definition ...@@ -1599,20 +1574,7 @@ function_definition
context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate); context->parseFunctionPrototype(@1, $1.function, &$1.intermAggregate);
} }
compound_statement_no_new_scope { compound_statement_no_new_scope {
//?? Check that all paths return a value if return type != void ? $$ = context->addFunctionDefinition(*($1.function), $1.intermAggregate, $3, @1);
// May be best done as post process phase on intermediate code
if (context->getCurrentFunctionType()->getBasicType() != EbtVoid && !context->getFunctionReturnsValue()) {
context->error(@1, "function does not return a value:", "", $1.function->getName().c_str());
context->recover();
}
$$ = context->intermediate.growAggregate($1.intermAggregate, $3, @$);
context->intermediate.setAggregateOperator($$, EOpFunction, @1);
$$->getAsAggregate()->setName($1.function->getMangledName().c_str());
$$->getAsAggregate()->setType($1.function->getReturnType());
$$->getAsAggregate()->setFunctionId($1.function->getUniqueId());
context->symbolTable.pop();
} }
; ;
......
...@@ -702,26 +702,26 @@ static const yytype_uint16 yyrline[] = ...@@ -702,26 +702,26 @@ static const yytype_uint16 yyrline[] =
440, 443, 446, 449, 455, 456, 459, 465, 466, 473, 440, 443, 446, 449, 455, 456, 459, 465, 466, 473,
474, 481, 482, 489, 490, 496, 497, 503, 504, 510, 474, 481, 482, 489, 490, 496, 497, 503, 504, 510,
511, 517, 518, 526, 527, 528, 529, 533, 534, 535, 511, 517, 518, 526, 527, 528, 529, 533, 534, 535,
539, 543, 547, 551, 558, 561, 567, 575, 583, 611, 539, 543, 547, 551, 558, 561, 567, 575, 583, 586,
617, 628, 632, 636, 640, 647, 653, 656, 663, 671, 592, 603, 607, 611, 615, 622, 628, 631, 638, 646,
692, 719, 729, 757, 762, 772, 777, 787, 790, 793, 667, 694, 704, 732, 737, 747, 752, 762, 765, 768,
796, 802, 809, 812, 816, 820, 825, 830, 837, 841, 771, 777, 784, 787, 791, 795, 800, 805, 812, 816,
845, 849, 854, 859, 863, 870, 880, 886, 889, 895, 820, 824, 829, 834, 838, 845, 855, 861, 864, 870,
901, 908, 917, 927, 935, 938, 945, 949, 953, 958, 876, 883, 892, 902, 910, 913, 920, 924, 928, 933,
966, 969, 973, 977, 986, 995, 1003, 1013, 1025, 1028, 941, 944, 948, 952, 961, 970, 978, 988, 1000, 1003,
1031, 1037, 1044, 1047, 1053, 1056, 1059, 1065, 1068, 1073, 1006, 1012, 1019, 1022, 1028, 1031, 1034, 1040, 1043, 1048,
1088, 1092, 1096, 1100, 1104, 1108, 1113, 1118, 1123, 1128, 1063, 1067, 1071, 1075, 1079, 1083, 1088, 1093, 1098, 1103,
1133, 1138, 1143, 1148, 1153, 1158, 1163, 1168, 1173, 1178, 1108, 1113, 1118, 1123, 1128, 1133, 1138, 1143, 1148, 1153,
1183, 1188, 1193, 1198, 1203, 1208, 1213, 1217, 1221, 1225, 1158, 1163, 1168, 1173, 1178, 1183, 1188, 1192, 1196, 1200,
1229, 1233, 1237, 1241, 1245, 1249, 1253, 1257, 1261, 1265, 1204, 1208, 1212, 1216, 1220, 1224, 1228, 1232, 1236, 1240,
1269, 1273, 1281, 1289, 1293, 1306, 1306, 1309, 1309, 1315, 1244, 1248, 1256, 1264, 1268, 1281, 1281, 1284, 1284, 1290,
1318, 1334, 1337, 1346, 1350, 1356, 1363, 1378, 1382, 1386, 1293, 1309, 1312, 1321, 1325, 1331, 1338, 1353, 1357, 1361,
1387, 1393, 1394, 1395, 1396, 1397, 1398, 1399, 1403, 1404, 1362, 1368, 1369, 1370, 1371, 1372, 1373, 1374, 1378, 1379,
1404, 1404, 1414, 1415, 1419, 1419, 1420, 1420, 1425, 1428, 1379, 1379, 1389, 1390, 1394, 1394, 1395, 1395, 1400, 1403,
1438, 1441, 1447, 1448, 1452, 1460, 1464, 1471, 1471, 1478, 1413, 1416, 1422, 1423, 1427, 1435, 1439, 1446, 1446, 1453,
1481, 1488, 1493, 1508, 1508, 1513, 1513, 1520, 1520, 1528, 1456, 1463, 1468, 1483, 1483, 1488, 1488, 1495, 1495, 1503,
1531, 1537, 1540, 1546, 1550, 1557, 1560, 1563, 1566, 1569, 1506, 1512, 1515, 1521, 1525, 1532, 1535, 1538, 1541, 1544,
1578, 1582, 1589, 1592, 1598, 1598 1553, 1557, 1564, 1567, 1573, 1573
}; };
#endif #endif
...@@ -3048,32 +3048,7 @@ yyreduce: ...@@ -3048,32 +3048,7 @@ yyreduce:
case 88: case 88:
{ {
TFunction &function = *((yyvsp[-1].interm).function); (yyval.interm.intermNode) = context->addFunctionPrototypeDeclaration(*((yyvsp[-1].interm).function), (yylsp[-1]));
TIntermAggregate *prototype = new TIntermAggregate;
prototype->setType(function.getReturnType());
prototype->setName(function.getMangledName());
prototype->setFunctionId(function.getUniqueId());
for (size_t i = 0; i < function.getParamCount(); i++)
{
const TConstParameter &param = function.getParam(i);
if (param.name != 0)
{
TVariable variable(param.name, *param.type);
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(variable.getUniqueId(), variable.getName(), variable.getType(), (yylsp[-1])), (yylsp[-1]));
}
else
{
prototype = context->intermediate.growAggregate(prototype, context->intermediate.addSymbol(0, "", *param.type, (yylsp[-1])), (yylsp[-1]));
}
}
prototype->setOp(EOpPrototype);
(yyval.interm.intermNode) = prototype;
context->symbolTable.pop();
} }
break; break;
...@@ -4488,7 +4463,7 @@ yyreduce: ...@@ -4488,7 +4463,7 @@ yyreduce:
case 232: case 232:
{ (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } { (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break; break;
...@@ -4506,7 +4481,7 @@ yyreduce: ...@@ -4506,7 +4481,7 @@ yyreduce:
case 235: case 235:
{ context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermNode); } { context->symbolTable.pop(); (yyval.interm.intermNode) = (yyvsp[0].interm.intermAggregate); }
break; break;
...@@ -4525,7 +4500,7 @@ yyreduce: ...@@ -4525,7 +4500,7 @@ yyreduce:
case 238: case 238:
{ {
(yyval.interm.intermNode) = 0; (yyval.interm.intermAggregate) = 0;
} }
break; break;
...@@ -4537,7 +4512,7 @@ yyreduce: ...@@ -4537,7 +4512,7 @@ yyreduce:
(yyvsp[-1].interm.intermAggregate)->setOp(EOpSequence); (yyvsp[-1].interm.intermAggregate)->setOp(EOpSequence);
(yyvsp[-1].interm.intermAggregate)->setLine((yyloc)); (yyvsp[-1].interm.intermAggregate)->setLine((yyloc));
} }
(yyval.interm.intermNode) = (yyvsp[-1].interm.intermAggregate); (yyval.interm.intermAggregate) = (yyvsp[-1].interm.intermAggregate);
} }
break; break;
...@@ -4842,20 +4817,7 @@ yyreduce: ...@@ -4842,20 +4817,7 @@ yyreduce:
case 275: case 275:
{ {
//?? Check that all paths return a value if return type != void ? (yyval.interm.intermNode) = context->addFunctionDefinition(*((yyvsp[-2].interm).function), (yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermAggregate), (yylsp[-2]));
// May be best done as post process phase on intermediate code
if (context->getCurrentFunctionType()->getBasicType() != EbtVoid && !context->getFunctionReturnsValue()) {
context->error((yylsp[-2]), "function does not return a value:", "", (yyvsp[-2].interm).function->getName().c_str());
context->recover();
}
(yyval.interm.intermNode) = context->intermediate.growAggregate((yyvsp[-2].interm).intermAggregate, (yyvsp[0].interm.intermNode), (yyloc));
context->intermediate.setAggregateOperator((yyval.interm.intermNode), EOpFunction, (yylsp[-2]));
(yyval.interm.intermNode)->getAsAggregate()->setName((yyvsp[-2].interm).function->getMangledName().c_str());
(yyval.interm.intermNode)->getAsAggregate()->setType((yyvsp[-2].interm).function->getReturnType());
(yyval.interm.intermNode)->getAsAggregate()->setFunctionId((yyvsp[-2].interm).function->getUniqueId());
context->symbolTable.pop();
} }
break; break;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment