PageRenderTime 62ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/lib_angle/src/compiler/translator/ParseContext.cpp

https://bitbucket.org/xixs/lua
C++ | 2611 lines | 2006 code | 345 blank | 260 comment | 572 complexity | e1b50842d7c273754334821fa9f7ec3a MD5 | raw file
Possible License(s): Zlib, BSD-3-Clause, CC0-1.0, GPL-3.0, GPL-2.0, CPL-1.0, MPL-2.0-no-copyleft-exception, LGPL-2.0, LGPL-2.1, LGPL-3.0, 0BSD, Cube

Large files files are truncated, but you can click here to view the full file

  1. //
  2. // Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
  3. // Use of this source code is governed by a BSD-style license that can be
  4. // found in the LICENSE file.
  5. //
  6. #include "compiler/translator/ParseContext.h"
  7. #include <stdarg.h>
  8. #include <stdio.h>
  9. #include "compiler/translator/glslang.h"
  10. #include "compiler/preprocessor/SourceLocation.h"
  11. ///////////////////////////////////////////////////////////////////////
  12. //
  13. // Sub- vector and matrix fields
  14. //
  15. ////////////////////////////////////////////////////////////////////////
  16. //
  17. // Look at a '.' field selector string and change it into offsets
  18. // for a vector.
  19. //
  20. bool TParseContext::parseVectorFields(const TString& compString, int vecSize, TVectorFields& fields, const TSourceLoc& line)
  21. {
  22. fields.num = (int) compString.size();
  23. if (fields.num > 4) {
  24. error(line, "illegal vector field selection", compString.c_str());
  25. return false;
  26. }
  27. enum {
  28. exyzw,
  29. ergba,
  30. estpq
  31. } fieldSet[4];
  32. for (int i = 0; i < fields.num; ++i) {
  33. switch (compString[i]) {
  34. case 'x':
  35. fields.offsets[i] = 0;
  36. fieldSet[i] = exyzw;
  37. break;
  38. case 'r':
  39. fields.offsets[i] = 0;
  40. fieldSet[i] = ergba;
  41. break;
  42. case 's':
  43. fields.offsets[i] = 0;
  44. fieldSet[i] = estpq;
  45. break;
  46. case 'y':
  47. fields.offsets[i] = 1;
  48. fieldSet[i] = exyzw;
  49. break;
  50. case 'g':
  51. fields.offsets[i] = 1;
  52. fieldSet[i] = ergba;
  53. break;
  54. case 't':
  55. fields.offsets[i] = 1;
  56. fieldSet[i] = estpq;
  57. break;
  58. case 'z':
  59. fields.offsets[i] = 2;
  60. fieldSet[i] = exyzw;
  61. break;
  62. case 'b':
  63. fields.offsets[i] = 2;
  64. fieldSet[i] = ergba;
  65. break;
  66. case 'p':
  67. fields.offsets[i] = 2;
  68. fieldSet[i] = estpq;
  69. break;
  70. case 'w':
  71. fields.offsets[i] = 3;
  72. fieldSet[i] = exyzw;
  73. break;
  74. case 'a':
  75. fields.offsets[i] = 3;
  76. fieldSet[i] = ergba;
  77. break;
  78. case 'q':
  79. fields.offsets[i] = 3;
  80. fieldSet[i] = estpq;
  81. break;
  82. default:
  83. error(line, "illegal vector field selection", compString.c_str());
  84. return false;
  85. }
  86. }
  87. for (int i = 0; i < fields.num; ++i) {
  88. if (fields.offsets[i] >= vecSize) {
  89. error(line, "vector field selection out of range", compString.c_str());
  90. return false;
  91. }
  92. if (i > 0) {
  93. if (fieldSet[i] != fieldSet[i-1]) {
  94. error(line, "illegal - vector component fields not from the same set", compString.c_str());
  95. return false;
  96. }
  97. }
  98. }
  99. return true;
  100. }
  101. //
  102. // Look at a '.' field selector string and change it into offsets
  103. // for a matrix.
  104. //
  105. bool TParseContext::parseMatrixFields(const TString& compString, int matCols, int matRows, TMatrixFields& fields, const TSourceLoc& line)
  106. {
  107. fields.wholeRow = false;
  108. fields.wholeCol = false;
  109. fields.row = -1;
  110. fields.col = -1;
  111. if (compString.size() != 2) {
  112. error(line, "illegal length of matrix field selection", compString.c_str());
  113. return false;
  114. }
  115. if (compString[0] == '_') {
  116. if (compString[1] < '0' || compString[1] > '3') {
  117. error(line, "illegal matrix field selection", compString.c_str());
  118. return false;
  119. }
  120. fields.wholeCol = true;
  121. fields.col = compString[1] - '0';
  122. } else if (compString[1] == '_') {
  123. if (compString[0] < '0' || compString[0] > '3') {
  124. error(line, "illegal matrix field selection", compString.c_str());
  125. return false;
  126. }
  127. fields.wholeRow = true;
  128. fields.row = compString[0] - '0';
  129. } else {
  130. if (compString[0] < '0' || compString[0] > '3' ||
  131. compString[1] < '0' || compString[1] > '3') {
  132. error(line, "illegal matrix field selection", compString.c_str());
  133. return false;
  134. }
  135. fields.row = compString[0] - '0';
  136. fields.col = compString[1] - '0';
  137. }
  138. if (fields.row >= matRows || fields.col >= matCols) {
  139. error(line, "matrix field selection out of range", compString.c_str());
  140. return false;
  141. }
  142. return true;
  143. }
  144. ///////////////////////////////////////////////////////////////////////
  145. //
  146. // Errors
  147. //
  148. ////////////////////////////////////////////////////////////////////////
  149. //
  150. // Track whether errors have occurred.
  151. //
  152. void TParseContext::recover()
  153. {
  154. }
  155. //
  156. // Used by flex/bison to output all syntax and parsing errors.
  157. //
  158. void TParseContext::error(const TSourceLoc& loc,
  159. const char* reason, const char* token,
  160. const char* extraInfo)
  161. {
  162. pp::SourceLocation srcLoc;
  163. srcLoc.file = loc.first_file;
  164. srcLoc.line = loc.first_line;
  165. diagnostics.writeInfo(pp::Diagnostics::PP_ERROR,
  166. srcLoc, reason, token, extraInfo);
  167. }
  168. void TParseContext::warning(const TSourceLoc& loc,
  169. const char* reason, const char* token,
  170. const char* extraInfo) {
  171. pp::SourceLocation srcLoc;
  172. srcLoc.file = loc.first_file;
  173. srcLoc.line = loc.first_line;
  174. diagnostics.writeInfo(pp::Diagnostics::PP_WARNING,
  175. srcLoc, reason, token, extraInfo);
  176. }
  177. void TParseContext::trace(const char* str)
  178. {
  179. diagnostics.writeDebug(str);
  180. }
  181. //
  182. // Same error message for all places assignments don't work.
  183. //
  184. void TParseContext::assignError(const TSourceLoc& line, const char* op, TString left, TString right)
  185. {
  186. std::stringstream extraInfoStream;
  187. extraInfoStream << "cannot convert from '" << right << "' to '" << left << "'";
  188. std::string extraInfo = extraInfoStream.str();
  189. error(line, "", op, extraInfo.c_str());
  190. }
  191. //
  192. // Same error message for all places unary operations don't work.
  193. //
  194. void TParseContext::unaryOpError(const TSourceLoc& line, const char* op, TString operand)
  195. {
  196. std::stringstream extraInfoStream;
  197. extraInfoStream << "no operation '" << op << "' exists that takes an operand of type " << operand
  198. << " (or there is no acceptable conversion)";
  199. std::string extraInfo = extraInfoStream.str();
  200. error(line, " wrong operand type", op, extraInfo.c_str());
  201. }
  202. //
  203. // Same error message for all binary operations don't work.
  204. //
  205. void TParseContext::binaryOpError(const TSourceLoc& line, const char* op, TString left, TString right)
  206. {
  207. std::stringstream extraInfoStream;
  208. extraInfoStream << "no operation '" << op << "' exists that takes a left-hand operand of type '" << left
  209. << "' and a right operand of type '" << right << "' (or there is no acceptable conversion)";
  210. std::string extraInfo = extraInfoStream.str();
  211. error(line, " wrong operand types ", op, extraInfo.c_str());
  212. }
  213. bool TParseContext::precisionErrorCheck(const TSourceLoc& line, TPrecision precision, TBasicType type){
  214. if (!checksPrecisionErrors)
  215. return false;
  216. switch( type ){
  217. case EbtFloat:
  218. if( precision == EbpUndefined ){
  219. error( line, "No precision specified for (float)", "" );
  220. return true;
  221. }
  222. break;
  223. case EbtInt:
  224. if( precision == EbpUndefined ){
  225. error( line, "No precision specified (int)", "" );
  226. return true;
  227. }
  228. break;
  229. default:
  230. return false;
  231. }
  232. return false;
  233. }
  234. //
  235. // Both test and if necessary, spit out an error, to see if the node is really
  236. // an l-value that can be operated on this way.
  237. //
  238. // Returns true if the was an error.
  239. //
  240. bool TParseContext::lValueErrorCheck(const TSourceLoc& line, const char* op, TIntermTyped* node)
  241. {
  242. TIntermSymbol* symNode = node->getAsSymbolNode();
  243. TIntermBinary* binaryNode = node->getAsBinaryNode();
  244. if (binaryNode) {
  245. bool errorReturn;
  246. switch(binaryNode->getOp()) {
  247. case EOpIndexDirect:
  248. case EOpIndexIndirect:
  249. case EOpIndexDirectStruct:
  250. case EOpIndexDirectInterfaceBlock:
  251. return lValueErrorCheck(line, op, binaryNode->getLeft());
  252. case EOpVectorSwizzle:
  253. errorReturn = lValueErrorCheck(line, op, binaryNode->getLeft());
  254. if (!errorReturn) {
  255. int offset[4] = {0,0,0,0};
  256. TIntermTyped* rightNode = binaryNode->getRight();
  257. TIntermAggregate *aggrNode = rightNode->getAsAggregate();
  258. for (TIntermSequence::iterator p = aggrNode->getSequence()->begin();
  259. p != aggrNode->getSequence()->end(); p++) {
  260. int value = (*p)->getAsTyped()->getAsConstantUnion()->getIConst(0);
  261. offset[value]++;
  262. if (offset[value] > 1) {
  263. error(line, " l-value of swizzle cannot have duplicate components", op);
  264. return true;
  265. }
  266. }
  267. }
  268. return errorReturn;
  269. default:
  270. break;
  271. }
  272. error(line, " l-value required", op);
  273. return true;
  274. }
  275. const char* symbol = 0;
  276. if (symNode != 0)
  277. symbol = symNode->getSymbol().c_str();
  278. const char* message = 0;
  279. switch (node->getQualifier()) {
  280. case EvqConst: message = "can't modify a const"; break;
  281. case EvqConstReadOnly: message = "can't modify a const"; break;
  282. case EvqAttribute: message = "can't modify an attribute"; break;
  283. case EvqFragmentIn: message = "can't modify an input"; break;
  284. case EvqVertexIn: message = "can't modify an input"; break;
  285. case EvqUniform: message = "can't modify a uniform"; break;
  286. case EvqVaryingIn: message = "can't modify a varying"; break;
  287. case EvqFragCoord: message = "can't modify gl_FragCoord"; break;
  288. case EvqFrontFacing: message = "can't modify gl_FrontFacing"; break;
  289. case EvqPointCoord: message = "can't modify gl_PointCoord"; break;
  290. default:
  291. //
  292. // Type that can't be written to?
  293. //
  294. if (node->getBasicType() == EbtVoid) {
  295. message = "can't modify void";
  296. }
  297. if (IsSampler(node->getBasicType())) {
  298. message = "can't modify a sampler";
  299. }
  300. }
  301. if (message == 0 && binaryNode == 0 && symNode == 0) {
  302. error(line, " l-value required", op);
  303. return true;
  304. }
  305. //
  306. // Everything else is okay, no error.
  307. //
  308. if (message == 0)
  309. return false;
  310. //
  311. // If we get here, we have an error and a message.
  312. //
  313. if (symNode) {
  314. std::stringstream extraInfoStream;
  315. extraInfoStream << "\"" << symbol << "\" (" << message << ")";
  316. std::string extraInfo = extraInfoStream.str();
  317. error(line, " l-value required", op, extraInfo.c_str());
  318. }
  319. else {
  320. std::stringstream extraInfoStream;
  321. extraInfoStream << "(" << message << ")";
  322. std::string extraInfo = extraInfoStream.str();
  323. error(line, " l-value required", op, extraInfo.c_str());
  324. }
  325. return true;
  326. }
  327. //
  328. // Both test, and if necessary spit out an error, to see if the node is really
  329. // a constant.
  330. //
  331. // Returns true if the was an error.
  332. //
  333. bool TParseContext::constErrorCheck(TIntermTyped* node)
  334. {
  335. if (node->getQualifier() == EvqConst)
  336. return false;
  337. error(node->getLine(), "constant expression required", "");
  338. return true;
  339. }
  340. //
  341. // Both test, and if necessary spit out an error, to see if the node is really
  342. // an integer.
  343. //
  344. // Returns true if the was an error.
  345. //
  346. bool TParseContext::integerErrorCheck(TIntermTyped* node, const char* token)
  347. {
  348. if (node->isScalarInt())
  349. return false;
  350. error(node->getLine(), "integer expression required", token);
  351. return true;
  352. }
  353. //
  354. // Both test, and if necessary spit out an error, to see if we are currently
  355. // globally scoped.
  356. //
  357. // Returns true if the was an error.
  358. //
  359. bool TParseContext::globalErrorCheck(const TSourceLoc& line, bool global, const char* token)
  360. {
  361. if (global)
  362. return false;
  363. error(line, "only allowed at global scope", token);
  364. return true;
  365. }
  366. //
  367. // For now, keep it simple: if it starts "gl_", it's reserved, independent
  368. // of scope. Except, if the symbol table is at the built-in push-level,
  369. // which is when we are parsing built-ins.
  370. // Also checks for "webgl_" and "_webgl_" reserved identifiers if parsing a
  371. // webgl shader.
  372. //
  373. // Returns true if there was an error.
  374. //
  375. bool TParseContext::reservedErrorCheck(const TSourceLoc& line, const TString& identifier)
  376. {
  377. static const char* reservedErrMsg = "reserved built-in name";
  378. if (!symbolTable.atBuiltInLevel()) {
  379. if (identifier.compare(0, 3, "gl_") == 0) {
  380. error(line, reservedErrMsg, "gl_");
  381. return true;
  382. }
  383. if (IsWebGLBasedSpec(shaderSpec)) {
  384. if (identifier.compare(0, 6, "webgl_") == 0) {
  385. error(line, reservedErrMsg, "webgl_");
  386. return true;
  387. }
  388. if (identifier.compare(0, 7, "_webgl_") == 0) {
  389. error(line, reservedErrMsg, "_webgl_");
  390. return true;
  391. }
  392. if (shaderSpec == SH_CSS_SHADERS_SPEC && identifier.compare(0, 4, "css_") == 0) {
  393. error(line, reservedErrMsg, "css_");
  394. return true;
  395. }
  396. }
  397. if (identifier.find("__") != TString::npos) {
  398. error(line, "identifiers containing two consecutive underscores (__) are reserved as possible future keywords", identifier.c_str());
  399. return true;
  400. }
  401. }
  402. return false;
  403. }
  404. //
  405. // Make sure there is enough data provided to the constructor to build
  406. // something of the type of the constructor. Also returns the type of
  407. // the constructor.
  408. //
  409. // Returns true if there was an error in construction.
  410. //
  411. bool TParseContext::constructorErrorCheck(const TSourceLoc& line, TIntermNode* node, TFunction& function, TOperator op, TType* type)
  412. {
  413. *type = function.getReturnType();
  414. bool constructingMatrix = false;
  415. switch(op) {
  416. case EOpConstructMat2:
  417. case EOpConstructMat3:
  418. case EOpConstructMat4:
  419. constructingMatrix = true;
  420. break;
  421. default:
  422. break;
  423. }
  424. //
  425. // Note: It's okay to have too many components available, but not okay to have unused
  426. // arguments. 'full' will go to true when enough args have been seen. If we loop
  427. // again, there is an extra argument, so 'overfull' will become true.
  428. //
  429. size_t size = 0;
  430. bool constType = true;
  431. bool full = false;
  432. bool overFull = false;
  433. bool matrixInMatrix = false;
  434. bool arrayArg = false;
  435. for (size_t i = 0; i < function.getParamCount(); ++i) {
  436. const TParameter& param = function.getParam(i);
  437. size += param.type->getObjectSize();
  438. if (constructingMatrix && param.type->isMatrix())
  439. matrixInMatrix = true;
  440. if (full)
  441. overFull = true;
  442. if (op != EOpConstructStruct && !type->isArray() && size >= type->getObjectSize())
  443. full = true;
  444. if (param.type->getQualifier() != EvqConst)
  445. constType = false;
  446. if (param.type->isArray())
  447. arrayArg = true;
  448. }
  449. if (constType)
  450. type->setQualifier(EvqConst);
  451. if (type->isArray() && static_cast<size_t>(type->getArraySize()) != function.getParamCount()) {
  452. error(line, "array constructor needs one argument per array element", "constructor");
  453. return true;
  454. }
  455. if (arrayArg && op != EOpConstructStruct) {
  456. error(line, "constructing from a non-dereferenced array", "constructor");
  457. return true;
  458. }
  459. if (matrixInMatrix && !type->isArray()) {
  460. if (function.getParamCount() != 1) {
  461. error(line, "constructing matrix from matrix can only take one argument", "constructor");
  462. return true;
  463. }
  464. }
  465. if (overFull) {
  466. error(line, "too many arguments", "constructor");
  467. return true;
  468. }
  469. if (op == EOpConstructStruct && !type->isArray() && type->getStruct()->fields().size() != function.getParamCount()) {
  470. error(line, "Number of constructor parameters does not match the number of structure fields", "constructor");
  471. return true;
  472. }
  473. if (!type->isMatrix() || !matrixInMatrix) {
  474. if ((op != EOpConstructStruct && size != 1 && size < type->getObjectSize()) ||
  475. (op == EOpConstructStruct && size < type->getObjectSize())) {
  476. error(line, "not enough data provided for construction", "constructor");
  477. return true;
  478. }
  479. }
  480. TIntermTyped *typed = node ? node->getAsTyped() : 0;
  481. if (typed == 0) {
  482. error(line, "constructor argument does not have a type", "constructor");
  483. return true;
  484. }
  485. if (op != EOpConstructStruct && IsSampler(typed->getBasicType())) {
  486. error(line, "cannot convert a sampler", "constructor");
  487. return true;
  488. }
  489. if (typed->getBasicType() == EbtVoid) {
  490. error(line, "cannot convert a void", "constructor");
  491. return true;
  492. }
  493. return false;
  494. }
  495. // This function checks to see if a void variable has been declared and raise an error message for such a case
  496. //
  497. // returns true in case of an error
  498. //
  499. bool TParseContext::voidErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& pubType)
  500. {
  501. if (pubType.type == EbtVoid) {
  502. error(line, "illegal use of type 'void'", identifier.c_str());
  503. return true;
  504. }
  505. return false;
  506. }
  507. // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
  508. //
  509. // returns true in case of an error
  510. //
  511. bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TIntermTyped* type)
  512. {
  513. if (type->getBasicType() != EbtBool || type->isArray() || type->isMatrix() || type->isVector()) {
  514. error(line, "boolean expression expected", "");
  515. return true;
  516. }
  517. return false;
  518. }
  519. // This function checks to see if the node (for the expression) contains a scalar boolean expression or not
  520. //
  521. // returns true in case of an error
  522. //
  523. bool TParseContext::boolErrorCheck(const TSourceLoc& line, const TPublicType& pType)
  524. {
  525. if (pType.type != EbtBool || pType.isAggregate()) {
  526. error(line, "boolean expression expected", "");
  527. return true;
  528. }
  529. return false;
  530. }
  531. bool TParseContext::samplerErrorCheck(const TSourceLoc& line, const TPublicType& pType, const char* reason)
  532. {
  533. if (pType.type == EbtStruct) {
  534. if (containsSampler(*pType.userDef)) {
  535. error(line, reason, getBasicString(pType.type), "(structure contains a sampler)");
  536. return true;
  537. }
  538. return false;
  539. } else if (IsSampler(pType.type)) {
  540. error(line, reason, getBasicString(pType.type));
  541. return true;
  542. }
  543. return false;
  544. }
  545. bool TParseContext::structQualifierErrorCheck(const TSourceLoc& line, const TPublicType& pType)
  546. {
  547. switch (pType.qualifier)
  548. {
  549. case EvqVaryingIn:
  550. case EvqVaryingOut:
  551. case EvqAttribute:
  552. case EvqVertexIn:
  553. case EvqFragmentOut:
  554. if (pType.type == EbtStruct)
  555. {
  556. error(line, "cannot be used with a structure", getQualifierString(pType.qualifier));
  557. return true;
  558. }
  559. default: break;
  560. }
  561. if (pType.qualifier != EvqUniform && samplerErrorCheck(line, pType, "samplers must be uniform"))
  562. return true;
  563. return false;
  564. }
  565. bool TParseContext::locationDeclaratorListCheck(const TSourceLoc& line, const TPublicType &pType)
  566. {
  567. if (pType.layoutQualifier.location != -1)
  568. {
  569. error(line, "location must only be specified for a single input or output variable", "location");
  570. return true;
  571. }
  572. return false;
  573. }
  574. bool TParseContext::parameterSamplerErrorCheck(const TSourceLoc& line, TQualifier qualifier, const TType& type)
  575. {
  576. if ((qualifier == EvqOut || qualifier == EvqInOut) &&
  577. type.getBasicType() != EbtStruct && IsSampler(type.getBasicType())) {
  578. error(line, "samplers cannot be output parameters", type.getBasicString());
  579. return true;
  580. }
  581. return false;
  582. }
  583. bool TParseContext::containsSampler(TType& type)
  584. {
  585. if (IsSampler(type.getBasicType()))
  586. return true;
  587. if (type.getBasicType() == EbtStruct || type.isInterfaceBlock()) {
  588. const TFieldList& fields = type.getStruct()->fields();
  589. for (unsigned int i = 0; i < fields.size(); ++i) {
  590. if (containsSampler(*fields[i]->type()))
  591. return true;
  592. }
  593. }
  594. return false;
  595. }
  596. //
  597. // Do size checking for an array type's size.
  598. //
  599. // Returns true if there was an error.
  600. //
  601. bool TParseContext::arraySizeErrorCheck(const TSourceLoc& line, TIntermTyped* expr, int& size)
  602. {
  603. TIntermConstantUnion* constant = expr->getAsConstantUnion();
  604. if (constant == 0 || !constant->isScalarInt())
  605. {
  606. error(line, "array size must be a constant integer expression", "");
  607. return true;
  608. }
  609. unsigned int unsignedSize = 0;
  610. if (constant->getBasicType() == EbtUInt)
  611. {
  612. unsignedSize = constant->getUConst(0);
  613. size = static_cast<int>(unsignedSize);
  614. }
  615. else
  616. {
  617. size = constant->getIConst(0);
  618. if (size < 0)
  619. {
  620. error(line, "array size must be non-negative", "");
  621. size = 1;
  622. return true;
  623. }
  624. unsignedSize = static_cast<unsigned int>(size);
  625. }
  626. if (size == 0)
  627. {
  628. error(line, "array size must be greater than zero", "");
  629. size = 1;
  630. return true;
  631. }
  632. // The size of arrays is restricted here to prevent issues further down the
  633. // compiler/translator/driver stack. Shader Model 5 generation hardware is limited to
  634. // 4096 registers so this should be reasonable even for aggressively optimizable code.
  635. const unsigned int sizeLimit = 65536;
  636. if (unsignedSize > sizeLimit)
  637. {
  638. error(line, "array size too large", "");
  639. size = 1;
  640. return true;
  641. }
  642. return false;
  643. }
  644. //
  645. // See if this qualifier can be an array.
  646. //
  647. // Returns true if there is an error.
  648. //
  649. bool TParseContext::arrayQualifierErrorCheck(const TSourceLoc& line, TPublicType type)
  650. {
  651. if ((type.qualifier == EvqAttribute) || (type.qualifier == EvqVertexIn) || (type.qualifier == EvqConst)) {
  652. error(line, "cannot declare arrays of this qualifier", TType(type).getCompleteString().c_str());
  653. return true;
  654. }
  655. return false;
  656. }
  657. //
  658. // See if this type can be an array.
  659. //
  660. // Returns true if there is an error.
  661. //
  662. bool TParseContext::arrayTypeErrorCheck(const TSourceLoc& line, TPublicType type)
  663. {
  664. //
  665. // Can the type be an array?
  666. //
  667. if (type.array) {
  668. error(line, "cannot declare arrays of arrays", TType(type).getCompleteString().c_str());
  669. return true;
  670. }
  671. return false;
  672. }
  673. //
  674. // Do all the semantic checking for declaring an array, with and
  675. // without a size, and make the right changes to the symbol table.
  676. //
  677. // size == 0 means no specified size.
  678. //
  679. // Returns true if there was an error.
  680. //
  681. bool TParseContext::arrayErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType &type, TVariable*& variable)
  682. {
  683. //
  684. // Don't check for reserved word use until after we know it's not in the symbol table,
  685. // because reserved arrays can be redeclared.
  686. //
  687. bool builtIn = false;
  688. bool sameScope = false;
  689. TSymbol* symbol = symbolTable.find(identifier, 0, &builtIn, &sameScope);
  690. if (symbol == 0 || !sameScope) {
  691. bool needsReservedErrorCheck = true;
  692. // gl_LastFragData may be redeclared with a new precision qualifier
  693. if (identifier.compare(0, 15, "gl_LastFragData") == 0) {
  694. if (type.arraySize == static_cast<const TVariable*>(symbolTable.findBuiltIn("gl_MaxDrawBuffers", shaderVersion))->getConstPointer()->getIConst()) {
  695. if (TSymbol* builtInSymbol = symbolTable.findBuiltIn(identifier, shaderVersion)) {
  696. needsReservedErrorCheck = extensionErrorCheck(line, builtInSymbol->getExtension());
  697. }
  698. } else {
  699. error(line, "redeclaration of array with size != gl_MaxDrawBuffers", identifier.c_str());
  700. return true;
  701. }
  702. }
  703. if (needsReservedErrorCheck)
  704. if (reservedErrorCheck(line, identifier))
  705. return true;
  706. variable = new TVariable(&identifier, TType(type));
  707. if (type.arraySize)
  708. variable->getType().setArraySize(type.arraySize);
  709. if (! symbolTable.declare(variable)) {
  710. delete variable;
  711. error(line, "INTERNAL ERROR inserting new symbol", identifier.c_str());
  712. return true;
  713. }
  714. } else {
  715. if (! symbol->isVariable()) {
  716. error(line, "variable expected", identifier.c_str());
  717. return true;
  718. }
  719. variable = static_cast<TVariable*>(symbol);
  720. if (! variable->getType().isArray()) {
  721. error(line, "redeclaring non-array as array", identifier.c_str());
  722. return true;
  723. }
  724. if (variable->getType().getArraySize() > 0) {
  725. error(line, "redeclaration of array with size", identifier.c_str());
  726. return true;
  727. }
  728. if (! variable->getType().sameElementType(TType(type))) {
  729. error(line, "redeclaration of array with a different type", identifier.c_str());
  730. return true;
  731. }
  732. if (type.arraySize)
  733. variable->getType().setArraySize(type.arraySize);
  734. }
  735. if (voidErrorCheck(line, identifier, type))
  736. return true;
  737. return false;
  738. }
  739. //
  740. // Enforce non-initializer type/qualifier rules.
  741. //
  742. // Returns true if there was an error.
  743. //
  744. bool TParseContext::nonInitConstErrorCheck(const TSourceLoc& line, const TString& identifier, TPublicType& type, bool array)
  745. {
  746. if (type.qualifier == EvqConst)
  747. {
  748. // Make the qualifier make sense.
  749. type.qualifier = EvqTemporary;
  750. if (array)
  751. {
  752. error(line, "arrays may not be declared constant since they cannot be initialized", identifier.c_str());
  753. }
  754. else if (type.isStructureContainingArrays())
  755. {
  756. error(line, "structures containing arrays may not be declared constant since they cannot be initialized", identifier.c_str());
  757. }
  758. else
  759. {
  760. error(line, "variables with qualifier 'const' must be initialized", identifier.c_str());
  761. }
  762. return true;
  763. }
  764. return false;
  765. }
  766. //
  767. // Do semantic checking for a variable declaration that has no initializer,
  768. // and update the symbol table.
  769. //
  770. // Returns true if there was an error.
  771. //
  772. bool TParseContext::nonInitErrorCheck(const TSourceLoc& line, const TString& identifier, const TPublicType& type, TVariable*& variable)
  773. {
  774. if (reservedErrorCheck(line, identifier))
  775. recover();
  776. variable = new TVariable(&identifier, TType(type));
  777. if (! symbolTable.declare(variable)) {
  778. error(line, "redefinition", variable->getName().c_str());
  779. delete variable;
  780. variable = 0;
  781. return true;
  782. }
  783. if (voidErrorCheck(line, identifier, type))
  784. return true;
  785. return false;
  786. }
  787. bool TParseContext::paramErrorCheck(const TSourceLoc& line, TQualifier qualifier, TQualifier paramQualifier, TType* type)
  788. {
  789. if (qualifier != EvqConst && qualifier != EvqTemporary) {
  790. error(line, "qualifier not allowed on function parameter", getQualifierString(qualifier));
  791. return true;
  792. }
  793. if (qualifier == EvqConst && paramQualifier != EvqIn) {
  794. error(line, "qualifier not allowed with ", getQualifierString(qualifier), getQualifierString(paramQualifier));
  795. return true;
  796. }
  797. if (qualifier == EvqConst)
  798. type->setQualifier(EvqConstReadOnly);
  799. else
  800. type->setQualifier(paramQualifier);
  801. return false;
  802. }
  803. bool TParseContext::extensionErrorCheck(const TSourceLoc& line, const TString& extension)
  804. {
  805. const TExtensionBehavior& extBehavior = extensionBehavior();
  806. TExtensionBehavior::const_iterator iter = extBehavior.find(extension.c_str());
  807. if (iter == extBehavior.end()) {
  808. error(line, "extension", extension.c_str(), "is not supported");
  809. return true;
  810. }
  811. // In GLSL ES, an extension's default behavior is "disable".
  812. if (iter->second == EBhDisable || iter->second == EBhUndefined) {
  813. error(line, "extension", extension.c_str(), "is disabled");
  814. return true;
  815. }
  816. if (iter->second == EBhWarn) {
  817. warning(line, "extension", extension.c_str(), "is being used");
  818. return false;
  819. }
  820. return false;
  821. }
  822. bool TParseContext::singleDeclarationErrorCheck(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier)
  823. {
  824. if (structQualifierErrorCheck(identifierLocation, publicType))
  825. return true;
  826. // check for layout qualifier issues
  827. const TLayoutQualifier layoutQualifier = publicType.layoutQualifier;
  828. if (layoutQualifier.matrixPacking != EmpUnspecified)
  829. {
  830. error(identifierLocation, "layout qualifier", getMatrixPackingString(layoutQualifier.matrixPacking), "only valid for interface blocks");
  831. return true;
  832. }
  833. if (layoutQualifier.blockStorage != EbsUnspecified)
  834. {
  835. error(identifierLocation, "layout qualifier", getBlockStorageString(layoutQualifier.blockStorage), "only valid for interface blocks");
  836. return true;
  837. }
  838. if (publicType.qualifier != EvqVertexIn && publicType.qualifier != EvqFragmentOut && layoutLocationErrorCheck(identifierLocation, publicType.layoutQualifier))
  839. {
  840. return true;
  841. }
  842. return false;
  843. }
  844. bool TParseContext::layoutLocationErrorCheck(const TSourceLoc& location, const TLayoutQualifier &layoutQualifier)
  845. {
  846. if (layoutQualifier.location != -1)
  847. {
  848. error(location, "invalid layout qualifier:", "location", "only valid on program inputs and outputs");
  849. return true;
  850. }
  851. return false;
  852. }
  853. bool TParseContext::supportsExtension(const char* extension)
  854. {
  855. const TExtensionBehavior& extbehavior = extensionBehavior();
  856. TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
  857. return (iter != extbehavior.end());
  858. }
  859. bool TParseContext::isExtensionEnabled(const char* extension) const
  860. {
  861. const TExtensionBehavior& extbehavior = extensionBehavior();
  862. TExtensionBehavior::const_iterator iter = extbehavior.find(extension);
  863. if (iter == extbehavior.end())
  864. {
  865. return false;
  866. }
  867. return (iter->second == EBhEnable || iter->second == EBhRequire);
  868. }
  869. void TParseContext::handleExtensionDirective(const TSourceLoc& loc, const char* extName, const char* behavior)
  870. {
  871. pp::SourceLocation srcLoc;
  872. srcLoc.file = loc.first_file;
  873. srcLoc.line = loc.first_line;
  874. directiveHandler.handleExtension(srcLoc, extName, behavior);
  875. }
  876. void TParseContext::handlePragmaDirective(const TSourceLoc& loc, const char* name, const char* value, bool stdgl)
  877. {
  878. pp::SourceLocation srcLoc;
  879. srcLoc.file = loc.first_file;
  880. srcLoc.line = loc.first_line;
  881. directiveHandler.handlePragma(srcLoc, name, value, stdgl);
  882. }
  883. /////////////////////////////////////////////////////////////////////////////////
  884. //
  885. // Non-Errors.
  886. //
  887. /////////////////////////////////////////////////////////////////////////////////
  888. const TVariable *TParseContext::getNamedVariable(const TSourceLoc &location,
  889. const TString *name,
  890. const TSymbol *symbol)
  891. {
  892. const TVariable *variable = NULL;
  893. if (!symbol)
  894. {
  895. error(location, "undeclared identifier", name->c_str());
  896. recover();
  897. }
  898. else if (!symbol->isVariable())
  899. {
  900. error(location, "variable expected", name->c_str());
  901. recover();
  902. }
  903. else
  904. {
  905. variable = static_cast<const TVariable*>(symbol);
  906. if (symbolTable.findBuiltIn(variable->getName(), shaderVersion) &&
  907. !variable->getExtension().empty() &&
  908. extensionErrorCheck(location, variable->getExtension()))
  909. {
  910. recover();
  911. }
  912. }
  913. if (!variable)
  914. {
  915. TType type(EbtFloat, EbpUndefined);
  916. TVariable *fakeVariable = new TVariable(name, type);
  917. symbolTable.declare(fakeVariable);
  918. variable = fakeVariable;
  919. }
  920. return variable;
  921. }
  922. //
  923. // Look up a function name in the symbol table, and make sure it is a function.
  924. //
  925. // Return the function symbol if found, otherwise 0.
  926. //
  927. const TFunction* TParseContext::findFunction(const TSourceLoc& line, TFunction* call, int inputShaderVersion, bool *builtIn)
  928. {
  929. // First find by unmangled name to check whether the function name has been
  930. // hidden by a variable name or struct typename.
  931. // If a function is found, check for one with a matching argument list.
  932. const TSymbol* symbol = symbolTable.find(call->getName(), inputShaderVersion, builtIn);
  933. if (symbol == 0 || symbol->isFunction()) {
  934. symbol = symbolTable.find(call->getMangledName(), inputShaderVersion, builtIn);
  935. }
  936. if (symbol == 0) {
  937. error(line, "no matching overloaded function found", call->getName().c_str());
  938. return 0;
  939. }
  940. if (!symbol->isFunction()) {
  941. error(line, "function name expected", call->getName().c_str());
  942. return 0;
  943. }
  944. return static_cast<const TFunction*>(symbol);
  945. }
  946. //
  947. // Initializers show up in several places in the grammar. Have one set of
  948. // code to handle them here.
  949. //
  950. // Returns true on error, false if no error
  951. //
  952. bool TParseContext::executeInitializer(const TSourceLoc& line, const TString& identifier, TPublicType& pType,
  953. TIntermTyped* initializer, TIntermNode*& intermNode, TVariable* variable)
  954. {
  955. TType type = TType(pType);
  956. if (variable == 0) {
  957. if (reservedErrorCheck(line, identifier))
  958. return true;
  959. if (voidErrorCheck(line, identifier, pType))
  960. return true;
  961. //
  962. // add variable to symbol table
  963. //
  964. variable = new TVariable(&identifier, type);
  965. if (! symbolTable.declare(variable)) {
  966. error(line, "redefinition", variable->getName().c_str());
  967. return true;
  968. // don't delete variable, it's used by error recovery, and the pool
  969. // pop will take care of the memory
  970. }
  971. }
  972. //
  973. // identifier must be of type constant, a global, or a temporary
  974. //
  975. TQualifier qualifier = variable->getType().getQualifier();
  976. if ((qualifier != EvqTemporary) && (qualifier != EvqGlobal) && (qualifier != EvqConst)) {
  977. error(line, " cannot initialize this type of qualifier ", variable->getType().getQualifierString());
  978. return true;
  979. }
  980. //
  981. // test for and propagate constant
  982. //
  983. if (qualifier == EvqConst) {
  984. if (qualifier != initializer->getType().getQualifier()) {
  985. std::stringstream extraInfoStream;
  986. extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
  987. std::string extraInfo = extraInfoStream.str();
  988. error(line, " assigning non-constant to", "=", extraInfo.c_str());
  989. variable->getType().setQualifier(EvqTemporary);
  990. return true;
  991. }
  992. if (type != initializer->getType()) {
  993. error(line, " non-matching types for const initializer ",
  994. variable->getType().getQualifierString());
  995. variable->getType().setQualifier(EvqTemporary);
  996. return true;
  997. }
  998. if (initializer->getAsConstantUnion()) {
  999. variable->shareConstPointer(initializer->getAsConstantUnion()->getUnionArrayPointer());
  1000. } else if (initializer->getAsSymbolNode()) {
  1001. const TSymbol* symbol = symbolTable.find(initializer->getAsSymbolNode()->getSymbol(), 0);
  1002. const TVariable* tVar = static_cast<const TVariable*>(symbol);
  1003. ConstantUnion* constArray = tVar->getConstPointer();
  1004. variable->shareConstPointer(constArray);
  1005. } else {
  1006. std::stringstream extraInfoStream;
  1007. extraInfoStream << "'" << variable->getType().getCompleteString() << "'";
  1008. std::string extraInfo = extraInfoStream.str();
  1009. error(line, " cannot assign to", "=", extraInfo.c_str());
  1010. variable->getType().setQualifier(EvqTemporary);
  1011. return true;
  1012. }
  1013. }
  1014. if (qualifier != EvqConst) {
  1015. TIntermSymbol* intermSymbol = intermediate.addSymbol(variable->getUniqueId(), variable->getName(), variable->getType(), line);
  1016. intermNode = intermediate.addAssign(EOpInitialize, intermSymbol, initializer, line);
  1017. if (intermNode == 0) {
  1018. assignError(line, "=", intermSymbol->getCompleteString(), initializer->getCompleteString());
  1019. return true;
  1020. }
  1021. } else
  1022. intermNode = 0;
  1023. return false;
  1024. }
  1025. bool TParseContext::areAllChildConst(TIntermAggregate* aggrNode)
  1026. {
  1027. ASSERT(aggrNode != NULL);
  1028. if (!aggrNode->isConstructor())
  1029. return false;
  1030. bool allConstant = true;
  1031. // check if all the child nodes are constants so that they can be inserted into
  1032. // the parent node
  1033. TIntermSequence *sequence = aggrNode->getSequence() ;
  1034. for (TIntermSequence::iterator p = sequence->begin(); p != sequence->end(); ++p) {
  1035. if (!(*p)->getAsTyped()->getAsConstantUnion())
  1036. return false;
  1037. }
  1038. return allConstant;
  1039. }
  1040. TPublicType TParseContext::addFullySpecifiedType(TQualifier qualifier, TLayoutQualifier layoutQualifier, const TPublicType& typeSpecifier)
  1041. {
  1042. TPublicType returnType = typeSpecifier;
  1043. returnType.qualifier = qualifier;
  1044. returnType.layoutQualifier = layoutQualifier;
  1045. if (typeSpecifier.array)
  1046. {
  1047. error(typeSpecifier.line, "not supported", "first-class array");
  1048. recover();
  1049. returnType.setArray(false);
  1050. }
  1051. if (shaderVersion < 300)
  1052. {
  1053. if (qualifier == EvqAttribute && (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
  1054. {
  1055. error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
  1056. recover();
  1057. }
  1058. if ((qualifier == EvqVaryingIn || qualifier == EvqVaryingOut) &&
  1059. (typeSpecifier.type == EbtBool || typeSpecifier.type == EbtInt))
  1060. {
  1061. error(typeSpecifier.line, "cannot be bool or int", getQualifierString(qualifier));
  1062. recover();
  1063. }
  1064. }
  1065. else
  1066. {
  1067. switch (qualifier)
  1068. {
  1069. case EvqSmoothIn:
  1070. case EvqSmoothOut:
  1071. case EvqVertexOut:
  1072. case EvqFragmentIn:
  1073. case EvqCentroidOut:
  1074. case EvqCentroidIn:
  1075. if (typeSpecifier.type == EbtBool)
  1076. {
  1077. error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
  1078. recover();
  1079. }
  1080. if (typeSpecifier.type == EbtInt || typeSpecifier.type == EbtUInt)
  1081. {
  1082. error(typeSpecifier.line, "must use 'flat' interpolation here", getQualifierString(qualifier));
  1083. recover();
  1084. }
  1085. break;
  1086. case EvqVertexIn:
  1087. case EvqFragmentOut:
  1088. case EvqFlatIn:
  1089. case EvqFlatOut:
  1090. if (typeSpecifier.type == EbtBool)
  1091. {
  1092. error(typeSpecifier.line, "cannot be bool", getQualifierString(qualifier));
  1093. recover();
  1094. }
  1095. break;
  1096. default: break;
  1097. }
  1098. }
  1099. return returnType;
  1100. }
  1101. TIntermAggregate* TParseContext::parseSingleDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier)
  1102. {
  1103. TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
  1104. TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation);
  1105. if (identifier != "")
  1106. {
  1107. if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
  1108. recover();
  1109. // this error check can mutate the type
  1110. if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
  1111. recover();
  1112. TVariable* variable = 0;
  1113. if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable))
  1114. recover();
  1115. if (variable && symbol)
  1116. {
  1117. symbol->setId(variable->getUniqueId());
  1118. }
  1119. }
  1120. return aggregate;
  1121. }
  1122. TIntermAggregate* TParseContext::parseSingleArrayDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& indexLocation, TIntermTyped *indexExpression)
  1123. {
  1124. if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
  1125. recover();
  1126. // this error check can mutate the type
  1127. if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
  1128. recover();
  1129. if (arrayTypeErrorCheck(indexLocation, publicType) || arrayQualifierErrorCheck(indexLocation, publicType))
  1130. {
  1131. recover();
  1132. }
  1133. TPublicType arrayType = publicType;
  1134. int size;
  1135. if (arraySizeErrorCheck(identifierLocation, indexExpression, size))
  1136. {
  1137. recover();
  1138. }
  1139. else
  1140. {
  1141. arrayType.setArray(true, size);
  1142. }
  1143. TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(arrayType), identifierLocation);
  1144. TIntermAggregate* aggregate = intermediate.makeAggregate(symbol, identifierLocation);
  1145. TVariable* variable = 0;
  1146. if (arrayErrorCheck(identifierLocation, identifier, arrayType, variable))
  1147. recover();
  1148. if (variable && symbol)
  1149. {
  1150. symbol->setId(variable->getUniqueId());
  1151. }
  1152. return aggregate;
  1153. }
  1154. TIntermAggregate* TParseContext::parseSingleInitDeclaration(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer)
  1155. {
  1156. if (singleDeclarationErrorCheck(publicType, identifierLocation, identifier))
  1157. recover();
  1158. TIntermNode* intermNode;
  1159. if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
  1160. {
  1161. //
  1162. // Build intermediate representation
  1163. //
  1164. return intermNode ? intermediate.makeAggregate(intermNode, initLocation) : NULL;
  1165. }
  1166. else
  1167. {
  1168. recover();
  1169. return NULL;
  1170. }
  1171. }
  1172. TIntermAggregate* TParseContext::parseInvariantDeclaration(const TSourceLoc &invariantLoc,
  1173. const TSourceLoc &identifierLoc,
  1174. const TString *identifier,
  1175. const TSymbol *symbol)
  1176. {
  1177. // invariant declaration
  1178. if (globalErrorCheck(invariantLoc, symbolTable.atGlobalLevel(), "invariant varying"))
  1179. {
  1180. recover();
  1181. }
  1182. if (!symbol)
  1183. {
  1184. error(identifierLoc, "undeclared identifier declared as invariant", identifier->c_str());
  1185. recover();
  1186. return NULL;
  1187. }
  1188. else
  1189. {
  1190. const TString kGlFrontFacing("gl_FrontFacing");
  1191. if (*identifier == kGlFrontFacing)
  1192. {
  1193. error(identifierLoc, "identifier should not be declared as invariant", identifier->c_str());
  1194. recover();
  1195. return NULL;
  1196. }
  1197. symbolTable.addInvariantVarying(std::string(identifier->c_str()));
  1198. const TVariable *variable = getNamedVariable(identifierLoc, identifier, symbol);
  1199. ASSERT(variable);
  1200. const TType &type = variable->getType();
  1201. TIntermSymbol *intermSymbol = intermediate.addSymbol(variable->getUniqueId(),
  1202. *identifier, type, identifierLoc);
  1203. TIntermAggregate *aggregate = intermediate.makeAggregate(intermSymbol, identifierLoc);
  1204. aggregate->setOp(EOpInvariantDeclaration);
  1205. return aggregate;
  1206. }
  1207. }
  1208. TIntermAggregate* TParseContext::parseDeclarator(TPublicType &publicType, TIntermAggregate *aggregateDeclaration, TSymbol *identifierSymbol, const TSourceLoc& identifierLocation, const TString &identifier)
  1209. {
  1210. TIntermSymbol* symbol = intermediate.addSymbol(0, identifier, TType(publicType), identifierLocation);
  1211. TIntermAggregate* intermAggregate = intermediate.growAggregate(aggregateDeclaration, symbol, identifierLocation);
  1212. if (structQualifierErrorCheck(identifierLocation, publicType))
  1213. recover();
  1214. if (locationDeclaratorListCheck(identifierLocation, publicType))
  1215. recover();
  1216. if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, false))
  1217. recover();
  1218. TVariable* variable = 0;
  1219. if (nonInitErrorCheck(identifierLocation, identifier, publicType, variable))
  1220. recover();
  1221. if (symbol && variable)
  1222. symbol->setId(variable->getUniqueId());
  1223. return intermAggregate;
  1224. }
  1225. TIntermAggregate* TParseContext::parseArrayDeclarator(TPublicType &publicType, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& arrayLocation, TIntermNode *declaratorList, TIntermTyped *indexExpression)
  1226. {
  1227. if (structQualifierErrorCheck(identifierLocation, publicType))
  1228. recover();
  1229. if (locationDeclaratorListCheck(identifierLocation, publicType))
  1230. recover();
  1231. if (nonInitConstErrorCheck(identifierLocation, identifier, publicType, true))
  1232. recover();
  1233. if (arrayTypeErrorCheck(arrayLocation, publicType) || arrayQualifierErrorCheck(arrayLocation, publicType))
  1234. {
  1235. recover();
  1236. }
  1237. else if (indexExpression)
  1238. {
  1239. int size;
  1240. if (arraySizeErrorCheck(arrayLocation, indexExpression, size))
  1241. recover();
  1242. TPublicType arrayType(publicType);
  1243. arrayType.setArray(true, size);
  1244. TVariable* variable = NULL;
  1245. if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable))
  1246. recover();
  1247. TType type = TType(arrayType);
  1248. type.setArraySize(size);
  1249. return intermediate.growAggregate(declaratorList, intermediate.addSymbol(variable ? variable->getUniqueId() : 0, identifier, type, identifierLocation), identifierLocation);
  1250. }
  1251. else
  1252. {
  1253. TPublicType arrayType(publicType);
  1254. arrayType.setArray(true);
  1255. TVariable* variable = NULL;
  1256. if (arrayErrorCheck(arrayLocation, identifier, arrayType, variable))
  1257. recover();
  1258. }
  1259. return NULL;
  1260. }
  1261. TIntermAggregate* TParseContext::parseInitDeclarator(TPublicType &publicType, TIntermAggregate *declaratorList, const TSourceLoc& identifierLocation, const TString &identifier, const TSourceLoc& initLocation, TIntermTyped *initializer)
  1262. {
  1263. if (structQualifierErrorCheck(identifierLocation, publicType))
  1264. recover();
  1265. if (locationDeclaratorListCheck(identifierLocation, publicType))
  1266. recover();
  1267. TIntermNode* intermNode;
  1268. if (!executeInitializer(identifierLocation, identifier, publicType, initializer, intermNode))
  1269. {
  1270. //
  1271. // build the intermediate representation
  1272. //
  1273. if (intermNode)
  1274. {
  1275. return intermediate.growAggregate(declaratorList, intermNode, initLocation);
  1276. }
  1277. else
  1278. {
  1279. return declaratorList;
  1280. }
  1281. }
  1282. else
  1283. {
  1284. recover();
  1285. return NULL;
  1286. }
  1287. }
  1288. void TParseContext::parseGlobalLayoutQualifier(const TPublicType &typeQualifier)
  1289. {
  1290. if (typeQualifier.qualifier != EvqUniform)
  1291. {
  1292. error(typeQualifier.line, "invalid qualifier:", getQualifierString(typeQualifier.qualifier), "global layout must be uniform");
  1293. recover();
  1294. return;
  1295. }
  1296. const TLayoutQualifier layoutQualifier = typeQualifier.layoutQualifier;
  1297. ASSERT(!layoutQualifier.isEmpty());
  1298. if (shaderVersion < 300)
  1299. {
  1300. error(typeQualifier.line, "layout qualifiers supported in GLSL ES 3.00 only", "layout");
  1301. recover();
  1302. return;
  1303. }
  1304. if (layoutLocationErrorCheck(typeQualifier.line, typeQualifier.layoutQualifier))
  1305. {
  1306. recover();
  1307. return;
  1308. }
  1309. if (layoutQualifier.matrixPacking != EmpUnspecified)
  1310. {
  1311. defaultMatrixPacking = layoutQualifier.matrixPacking;
  1312. }
  1313. if (layoutQualifier.blockStorage != EbsUnspecified)
  1314. {
  1315. defaultBlockStorage = layoutQualifier.blockStorage;
  1316. }
  1317. }
  1318. TFunction *TParseContext::addConstructorFunc(TPublicType publicType)
  1319. {
  1320. TOperator op = EOpNull;
  1321. if (publicType.userDef)
  1322. {
  1323. op = EOpConstructStruct;
  1324. }
  1325. else
  1326. {
  1327. switch (publicType.type)
  1328. {
  1329. case EbtFloat:
  1330. if (publicType.isMatrix())
  1331. {
  1332. // TODO: non-square matrices
  1333. switch(publicType.getCols())
  1334. {
  1335. case 2: op = EOpConstructMat2; break;
  1336. case 3: op = EOpConstructMat3; break;
  1337. case 4: op = EOpConstructMat4; break;
  1338. }
  1339. }
  1340. else
  1341. {
  1342. switch(publicType.getNominalSize())
  1343. {
  1344. case 1: op = EOpConstructFloat; break;
  1345. case 2: op = EOpConstructVec2; break;
  1346. case 3: op = EOpConstructVec3; break;
  1347. case 4: op = EOpConstructVec4; break;
  1348. }
  1349. }
  1350. break;
  1351. case EbtInt:

Large files files are truncated, but you can click here to view the full file