ParseContextBase.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2016 Google, Inc.
  4. //
  5. // All rights reserved.
  6. //
  7. // Redistribution and use in source and binary forms, with or without
  8. // modification, are permitted provided that the following conditions
  9. // are met:
  10. //
  11. // Redistributions of source code must retain the above copyright
  12. // notice, this list of conditions and the following disclaimer.
  13. //
  14. // Redistributions in binary form must reproduce the above
  15. // copyright notice, this list of conditions and the following
  16. // disclaimer in the documentation and/or other materials provided
  17. // with the distribution.
  18. //
  19. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  20. // contributors may be used to endorse or promote products derived
  21. // from this software without specific prior written permission.
  22. //
  23. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  24. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  25. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  26. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  27. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  28. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  29. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  31. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  33. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. // POSSIBILITY OF SUCH DAMAGE.
  35. //
  36. // Implement the TParseContextBase class.
  37. #include <cstdarg>
  38. #include "ParseHelper.h"
  39. extern int yyparse(glslang::TParseContext*);
  40. namespace glslang {
  41. //
  42. // Used to output syntax, parsing, and semantic errors.
  43. //
  44. void TParseContextBase::outputMessage(const TSourceLoc& loc, const char* szReason,
  45. const char* szToken,
  46. const char* szExtraInfoFormat,
  47. TPrefixType prefix, va_list args)
  48. {
  49. const int maxSize = MaxTokenLength + 200;
  50. char szExtraInfo[maxSize];
  51. safe_vsprintf(szExtraInfo, maxSize, szExtraInfoFormat, args);
  52. infoSink.info.prefix(prefix);
  53. infoSink.info.location(loc);
  54. infoSink.info << "'" << szToken << "' : " << szReason << " " << szExtraInfo << "\n";
  55. if (prefix == EPrefixError) {
  56. ++numErrors;
  57. }
  58. }
  59. #if !defined(GLSLANG_WEB) || defined(GLSLANG_WEB_DEVEL)
  60. void C_DECL TParseContextBase::error(const TSourceLoc& loc, const char* szReason, const char* szToken,
  61. const char* szExtraInfoFormat, ...)
  62. {
  63. if (messages & EShMsgOnlyPreprocessor)
  64. return;
  65. va_list args;
  66. va_start(args, szExtraInfoFormat);
  67. outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
  68. va_end(args);
  69. if ((messages & EShMsgCascadingErrors) == 0)
  70. currentScanner->setEndOfInput();
  71. }
  72. void C_DECL TParseContextBase::warn(const TSourceLoc& loc, const char* szReason, const char* szToken,
  73. const char* szExtraInfoFormat, ...)
  74. {
  75. if (suppressWarnings())
  76. return;
  77. va_list args;
  78. va_start(args, szExtraInfoFormat);
  79. outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
  80. va_end(args);
  81. }
  82. void C_DECL TParseContextBase::ppError(const TSourceLoc& loc, const char* szReason, const char* szToken,
  83. const char* szExtraInfoFormat, ...)
  84. {
  85. va_list args;
  86. va_start(args, szExtraInfoFormat);
  87. outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixError, args);
  88. va_end(args);
  89. if ((messages & EShMsgCascadingErrors) == 0)
  90. currentScanner->setEndOfInput();
  91. }
  92. void C_DECL TParseContextBase::ppWarn(const TSourceLoc& loc, const char* szReason, const char* szToken,
  93. const char* szExtraInfoFormat, ...)
  94. {
  95. va_list args;
  96. va_start(args, szExtraInfoFormat);
  97. outputMessage(loc, szReason, szToken, szExtraInfoFormat, EPrefixWarning, args);
  98. va_end(args);
  99. }
  100. #endif
  101. //
  102. // Both test and if necessary, spit out an error, to see if the node is really
  103. // an l-value that can be operated on this way.
  104. //
  105. // Returns true if there was an error.
  106. //
  107. bool TParseContextBase::lValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
  108. {
  109. TIntermBinary* binaryNode = node->getAsBinaryNode();
  110. const char* symbol = nullptr;
  111. TIntermSymbol* symNode = node->getAsSymbolNode();
  112. if (symNode != nullptr)
  113. symbol = symNode->getName().c_str();
  114. const char* message = nullptr;
  115. switch (node->getQualifier().storage) {
  116. case EvqConst: message = "can't modify a const"; break;
  117. case EvqConstReadOnly: message = "can't modify a const"; break;
  118. case EvqUniform: message = "can't modify a uniform"; break;
  119. #ifndef GLSLANG_WEB
  120. case EvqBuffer:
  121. if (node->getQualifier().isReadOnly())
  122. message = "can't modify a readonly buffer";
  123. if (node->getQualifier().isShaderRecord())
  124. message = "can't modify a shaderrecordnv qualified buffer";
  125. break;
  126. case EvqHitAttr:
  127. if (language != EShLangIntersect)
  128. message = "cannot modify hitAttributeNV in this stage";
  129. break;
  130. #endif
  131. default:
  132. //
  133. // Type that can't be written to?
  134. //
  135. switch (node->getBasicType()) {
  136. case EbtSampler:
  137. message = "can't modify a sampler";
  138. break;
  139. case EbtVoid:
  140. message = "can't modify void";
  141. break;
  142. #ifndef GLSLANG_WEB
  143. case EbtAtomicUint:
  144. message = "can't modify an atomic_uint";
  145. break;
  146. case EbtAccStruct:
  147. message = "can't modify accelerationStructureNV";
  148. break;
  149. case EbtRayQuery:
  150. message = "can't modify rayQueryEXT";
  151. break;
  152. #endif
  153. default:
  154. break;
  155. }
  156. }
  157. if (message == nullptr && binaryNode == nullptr && symNode == nullptr) {
  158. error(loc, " l-value required", op, "", "");
  159. return true;
  160. }
  161. //
  162. // Everything else is okay, no error.
  163. //
  164. if (message == nullptr)
  165. {
  166. if (binaryNode) {
  167. switch (binaryNode->getOp()) {
  168. case EOpIndexDirect:
  169. case EOpIndexIndirect: // fall through
  170. case EOpIndexDirectStruct: // fall through
  171. case EOpVectorSwizzle:
  172. case EOpMatrixSwizzle:
  173. return lValueErrorCheck(loc, op, binaryNode->getLeft());
  174. default:
  175. break;
  176. }
  177. error(loc, " l-value required", op, "", "");
  178. return true;
  179. }
  180. return false;
  181. }
  182. //
  183. // If we get here, we have an error and a message.
  184. //
  185. const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
  186. if (symNode)
  187. error(loc, " l-value required", op, "\"%s\" (%s)", symbol, message);
  188. else
  189. if (binaryNode && binaryNode->getAsOperator()->getOp() == EOpIndexDirectStruct)
  190. if(IsAnonymous(leftMostTypeNode->getAsSymbolNode()->getName()))
  191. error(loc, " l-value required", op, "\"%s\" (%s)", leftMostTypeNode->getAsSymbolNode()->getAccessName().c_str(), message);
  192. else
  193. error(loc, " l-value required", op, "\"%s\" (%s)", leftMostTypeNode->getAsSymbolNode()->getName().c_str(), message);
  194. else
  195. error(loc, " l-value required", op, "(%s)", message);
  196. return true;
  197. }
  198. // Test for and give an error if the node can't be read from.
  199. void TParseContextBase::rValueErrorCheck(const TSourceLoc& loc, const char* op, TIntermTyped* node)
  200. {
  201. TIntermBinary* binaryNode = node->getAsBinaryNode();
  202. const TIntermSymbol* symNode = node->getAsSymbolNode();
  203. if (! node)
  204. return;
  205. if (node->getQualifier().isWriteOnly()) {
  206. const TIntermTyped* leftMostTypeNode = TIntermediate::findLValueBase(node, true);
  207. if (symNode != nullptr)
  208. error(loc, "can't read from writeonly object: ", op, symNode->getName().c_str());
  209. else if (binaryNode &&
  210. (binaryNode->getAsOperator()->getOp() == EOpIndexDirectStruct ||
  211. binaryNode->getAsOperator()->getOp() == EOpIndexDirect))
  212. if(IsAnonymous(leftMostTypeNode->getAsSymbolNode()->getName()))
  213. error(loc, "can't read from writeonly object: ", op, leftMostTypeNode->getAsSymbolNode()->getAccessName().c_str());
  214. else
  215. error(loc, "can't read from writeonly object: ", op, leftMostTypeNode->getAsSymbolNode()->getName().c_str());
  216. else
  217. error(loc, "can't read from writeonly object: ", op, "");
  218. } else {
  219. if (binaryNode) {
  220. switch (binaryNode->getOp()) {
  221. case EOpIndexDirect:
  222. case EOpIndexIndirect:
  223. case EOpIndexDirectStruct:
  224. case EOpVectorSwizzle:
  225. case EOpMatrixSwizzle:
  226. rValueErrorCheck(loc, op, binaryNode->getLeft());
  227. default:
  228. break;
  229. }
  230. }
  231. }
  232. }
  233. // Add 'symbol' to the list of deferred linkage symbols, which
  234. // are later processed in finish(), at which point the symbol
  235. // must still be valid.
  236. // It is okay if the symbol's type will be subsequently edited;
  237. // the modifications will be tracked.
  238. // Order is preserved, to avoid creating novel forward references.
  239. void TParseContextBase::trackLinkage(TSymbol& symbol)
  240. {
  241. if (!parsingBuiltins)
  242. linkageSymbols.push_back(&symbol);
  243. }
  244. // Ensure index is in bounds, correct if necessary.
  245. // Give an error if not.
  246. void TParseContextBase::checkIndex(const TSourceLoc& loc, const TType& type, int& index)
  247. {
  248. const auto sizeIsSpecializationExpression = [&type]() {
  249. return type.containsSpecializationSize() &&
  250. type.getArraySizes()->getOuterNode() != nullptr &&
  251. type.getArraySizes()->getOuterNode()->getAsSymbolNode() == nullptr; };
  252. if (index < 0) {
  253. error(loc, "", "[", "index out of range '%d'", index);
  254. index = 0;
  255. } else if (type.isArray()) {
  256. if (type.isSizedArray() && !sizeIsSpecializationExpression() &&
  257. index >= type.getOuterArraySize()) {
  258. error(loc, "", "[", "array index out of range '%d'", index);
  259. index = type.getOuterArraySize() - 1;
  260. }
  261. } else if (type.isVector()) {
  262. if (index >= type.getVectorSize()) {
  263. error(loc, "", "[", "vector index out of range '%d'", index);
  264. index = type.getVectorSize() - 1;
  265. }
  266. } else if (type.isMatrix()) {
  267. if (index >= type.getMatrixCols()) {
  268. error(loc, "", "[", "matrix index out of range '%d'", index);
  269. index = type.getMatrixCols() - 1;
  270. }
  271. }
  272. }
  273. // Make a shared symbol have a non-shared version that can be edited by the current
  274. // compile, such that editing its type will not change the shared version and will
  275. // effect all nodes already sharing it (non-shallow type),
  276. // or adopting its full type after being edited (shallow type).
  277. void TParseContextBase::makeEditable(TSymbol*& symbol)
  278. {
  279. // copyUp() does a deep copy of the type.
  280. symbol = symbolTable.copyUp(symbol);
  281. // Save it (deferred, so it can be edited first) in the AST for linker use.
  282. if (symbol)
  283. trackLinkage(*symbol);
  284. }
  285. // Return a writable version of the variable 'name'.
  286. //
  287. // Return nullptr if 'name' is not found. This should mean
  288. // something is seriously wrong (e.g., compiler asking self for
  289. // built-in that doesn't exist).
  290. TVariable* TParseContextBase::getEditableVariable(const char* name)
  291. {
  292. bool builtIn;
  293. TSymbol* symbol = symbolTable.find(name, &builtIn);
  294. assert(symbol != nullptr);
  295. if (symbol == nullptr)
  296. return nullptr;
  297. if (builtIn)
  298. makeEditable(symbol);
  299. return symbol->getAsVariable();
  300. }
  301. // Select the best matching function for 'call' from 'candidateList'.
  302. //
  303. // Assumptions
  304. //
  305. // There is no exact match, so a selection algorithm needs to run. That is, the
  306. // language-specific handler should check for exact match first, to
  307. // decide what to do, before calling this selector.
  308. //
  309. // Input
  310. //
  311. // * list of candidate signatures to select from
  312. // * the call
  313. // * a predicate function convertible(from, to) that says whether or not type
  314. // 'from' can implicitly convert to type 'to' (it includes the case of what
  315. // the calling language would consider a matching type with no conversion
  316. // needed)
  317. // * a predicate function better(from1, from2, to1, to2) that says whether or
  318. // not a conversion from <-> to2 is considered better than a conversion
  319. // from <-> to1 (both in and out directions need testing, as declared by the
  320. // formal parameter)
  321. //
  322. // Output
  323. //
  324. // * best matching candidate (or none, if no viable candidates found)
  325. // * whether there was a tie for the best match (ambiguous overload selection,
  326. // caller's choice for how to report)
  327. //
  328. const TFunction* TParseContextBase::selectFunction(
  329. const TVector<const TFunction*> candidateList,
  330. const TFunction& call,
  331. std::function<bool(const TType& from, const TType& to, TOperator op, int arg)> convertible,
  332. std::function<bool(const TType& from, const TType& to1, const TType& to2)> better,
  333. /* output */ bool& tie)
  334. {
  335. //
  336. // Operation
  337. //
  338. // 1. Prune the input list of candidates down to a list of viable candidates,
  339. // where each viable candidate has
  340. //
  341. // * at least as many parameters as there are calling arguments, with any
  342. // remaining parameters being optional or having default values
  343. // * each parameter is true under convertible(A, B), where A is the calling
  344. // type for in and B is the formal type, and in addition, for out B is the
  345. // calling type and A is the formal type
  346. //
  347. // 2. If there are no viable candidates, return with no match.
  348. //
  349. // 3. If there is only one viable candidate, it is the best match.
  350. //
  351. // 4. If there are multiple viable candidates, select the first viable candidate
  352. // as the incumbent. Compare the incumbent to the next viable candidate, and if
  353. // that candidate is better (bullets below), make it the incumbent. Repeat, with
  354. // a linear walk through the viable candidate list. The final incumbent will be
  355. // returned as the best match. A viable candidate is better than the incumbent if
  356. //
  357. // * it has a function argument with a better(...) conversion than the incumbent,
  358. // for all directions needed by in and out
  359. // * the incumbent has no argument with a better(...) conversion then the
  360. // candidate, for either in or out (as needed)
  361. //
  362. // 5. Check for ambiguity by comparing the best match against all other viable
  363. // candidates. If any other viable candidate has a function argument with a
  364. // better(...) conversion than the best candidate (for either in or out
  365. // directions), return that there was a tie for best.
  366. //
  367. tie = false;
  368. // 1. prune to viable...
  369. TVector<const TFunction*> viableCandidates;
  370. for (auto it = candidateList.begin(); it != candidateList.end(); ++it) {
  371. const TFunction& candidate = *(*it);
  372. // to even be a potential match, number of arguments must be >= the number of
  373. // fixed (non-default) parameters, and <= the total (including parameter with defaults).
  374. if (call.getParamCount() < candidate.getFixedParamCount() ||
  375. call.getParamCount() > candidate.getParamCount())
  376. continue;
  377. // see if arguments are convertible
  378. bool viable = true;
  379. // The call can have fewer parameters than the candidate, if some have defaults.
  380. const int paramCount = std::min(call.getParamCount(), candidate.getParamCount());
  381. for (int param = 0; param < paramCount; ++param) {
  382. if (candidate[param].type->getQualifier().isParamInput()) {
  383. if (! convertible(*call[param].type, *candidate[param].type, candidate.getBuiltInOp(), param)) {
  384. viable = false;
  385. break;
  386. }
  387. }
  388. if (candidate[param].type->getQualifier().isParamOutput()) {
  389. if (! convertible(*candidate[param].type, *call[param].type, candidate.getBuiltInOp(), param)) {
  390. viable = false;
  391. break;
  392. }
  393. }
  394. }
  395. if (viable)
  396. viableCandidates.push_back(&candidate);
  397. }
  398. // 2. none viable...
  399. if (viableCandidates.size() == 0)
  400. return nullptr;
  401. // 3. only one viable...
  402. if (viableCandidates.size() == 1)
  403. return viableCandidates.front();
  404. // 4. find best...
  405. const auto betterParam = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
  406. // is call -> can2 better than call -> can1 for any parameter
  407. bool hasBetterParam = false;
  408. for (int param = 0; param < call.getParamCount(); ++param) {
  409. if (better(*call[param].type, *can1[param].type, *can2[param].type)) {
  410. hasBetterParam = true;
  411. break;
  412. }
  413. }
  414. return hasBetterParam;
  415. };
  416. const auto equivalentParams = [&call, &better](const TFunction& can1, const TFunction& can2) -> bool {
  417. // is call -> can2 equivalent to call -> can1 for all the call parameters?
  418. for (int param = 0; param < call.getParamCount(); ++param) {
  419. if (better(*call[param].type, *can1[param].type, *can2[param].type) ||
  420. better(*call[param].type, *can2[param].type, *can1[param].type))
  421. return false;
  422. }
  423. return true;
  424. };
  425. const TFunction* incumbent = viableCandidates.front();
  426. for (auto it = viableCandidates.begin() + 1; it != viableCandidates.end(); ++it) {
  427. const TFunction& candidate = *(*it);
  428. if (betterParam(*incumbent, candidate) && ! betterParam(candidate, *incumbent))
  429. incumbent = &candidate;
  430. }
  431. // 5. ambiguity...
  432. for (auto it = viableCandidates.begin(); it != viableCandidates.end(); ++it) {
  433. if (incumbent == *it)
  434. continue;
  435. const TFunction& candidate = *(*it);
  436. // In the case of default parameters, it may have an identical initial set, which is
  437. // also ambiguous
  438. if (betterParam(*incumbent, candidate) || equivalentParams(*incumbent, candidate))
  439. tie = true;
  440. }
  441. return incumbent;
  442. }
  443. //
  444. // Look at a '.' field selector string and change it into numerical selectors
  445. // for a vector or scalar.
  446. //
  447. // Always return some form of swizzle, so the result is always usable.
  448. //
  449. void TParseContextBase::parseSwizzleSelector(const TSourceLoc& loc, const TString& compString, int vecSize,
  450. TSwizzleSelectors<TVectorSelector>& selector)
  451. {
  452. // Too long?
  453. if (compString.size() > MaxSwizzleSelectors)
  454. error(loc, "vector swizzle too long", compString.c_str(), "");
  455. // Use this to test that all swizzle characters are from the same swizzle-namespace-set
  456. enum {
  457. exyzw,
  458. ergba,
  459. estpq,
  460. } fieldSet[MaxSwizzleSelectors];
  461. // Decode the swizzle string.
  462. int size = std::min(MaxSwizzleSelectors, (int)compString.size());
  463. for (int i = 0; i < size; ++i) {
  464. switch (compString[i]) {
  465. case 'x':
  466. selector.push_back(0);
  467. fieldSet[i] = exyzw;
  468. break;
  469. case 'r':
  470. selector.push_back(0);
  471. fieldSet[i] = ergba;
  472. break;
  473. case 's':
  474. selector.push_back(0);
  475. fieldSet[i] = estpq;
  476. break;
  477. case 'y':
  478. selector.push_back(1);
  479. fieldSet[i] = exyzw;
  480. break;
  481. case 'g':
  482. selector.push_back(1);
  483. fieldSet[i] = ergba;
  484. break;
  485. case 't':
  486. selector.push_back(1);
  487. fieldSet[i] = estpq;
  488. break;
  489. case 'z':
  490. selector.push_back(2);
  491. fieldSet[i] = exyzw;
  492. break;
  493. case 'b':
  494. selector.push_back(2);
  495. fieldSet[i] = ergba;
  496. break;
  497. case 'p':
  498. selector.push_back(2);
  499. fieldSet[i] = estpq;
  500. break;
  501. case 'w':
  502. selector.push_back(3);
  503. fieldSet[i] = exyzw;
  504. break;
  505. case 'a':
  506. selector.push_back(3);
  507. fieldSet[i] = ergba;
  508. break;
  509. case 'q':
  510. selector.push_back(3);
  511. fieldSet[i] = estpq;
  512. break;
  513. default:
  514. error(loc, "unknown swizzle selection", compString.c_str(), "");
  515. break;
  516. }
  517. }
  518. // Additional error checking.
  519. for (int i = 0; i < selector.size(); ++i) {
  520. if (selector[i] >= vecSize) {
  521. error(loc, "vector swizzle selection out of range", compString.c_str(), "");
  522. selector.resize(i);
  523. break;
  524. }
  525. if (i > 0 && fieldSet[i] != fieldSet[i-1]) {
  526. error(loc, "vector swizzle selectors not from the same set", compString.c_str(), "");
  527. selector.resize(i);
  528. break;
  529. }
  530. }
  531. // Ensure it is valid.
  532. if (selector.size() == 0)
  533. selector.push_back(0);
  534. }
  535. #ifdef ENABLE_HLSL
  536. //
  537. // Make the passed-in variable information become a member of the
  538. // global uniform block. If this doesn't exist yet, make it.
  539. //
  540. void TParseContextBase::growGlobalUniformBlock(const TSourceLoc& loc, TType& memberType, const TString& memberName, TTypeList* typeList)
  541. {
  542. // Make the global block, if not yet made.
  543. if (globalUniformBlock == nullptr) {
  544. TQualifier blockQualifier;
  545. blockQualifier.clear();
  546. blockQualifier.storage = EvqUniform;
  547. TType blockType(new TTypeList, *NewPoolTString(getGlobalUniformBlockName()), blockQualifier);
  548. setUniformBlockDefaults(blockType);
  549. globalUniformBlock = new TVariable(NewPoolTString(""), blockType, true);
  550. firstNewMember = 0;
  551. }
  552. // Update with binding and set
  553. globalUniformBlock->getWritableType().getQualifier().layoutBinding = globalUniformBinding;
  554. globalUniformBlock->getWritableType().getQualifier().layoutSet = globalUniformSet;
  555. // Add the requested member as a member to the global block.
  556. TType* type = new TType;
  557. type->shallowCopy(memberType);
  558. type->setFieldName(memberName);
  559. if (typeList)
  560. type->setStruct(typeList);
  561. TTypeLoc typeLoc = {type, loc};
  562. globalUniformBlock->getType().getWritableStruct()->push_back(typeLoc);
  563. // Insert into the symbol table.
  564. if (firstNewMember == 0) {
  565. // This is the first request; we need a normal symbol table insert
  566. if (symbolTable.insert(*globalUniformBlock))
  567. trackLinkage(*globalUniformBlock);
  568. else
  569. error(loc, "failed to insert the global constant buffer", "uniform", "");
  570. } else {
  571. // This is a follow-on request; we need to amend the first insert
  572. symbolTable.amend(*globalUniformBlock, firstNewMember);
  573. }
  574. ++firstNewMember;
  575. }
  576. #endif
  577. void TParseContextBase::finish()
  578. {
  579. if (parsingBuiltins)
  580. return;
  581. // Transfer the linkage symbols to AST nodes, preserving order.
  582. TIntermAggregate* linkage = new TIntermAggregate;
  583. for (auto i = linkageSymbols.begin(); i != linkageSymbols.end(); ++i)
  584. intermediate.addSymbolLinkageNode(linkage, **i);
  585. intermediate.addSymbolLinkageNodes(linkage, getLanguage(), symbolTable);
  586. }
  587. } // end namespace glslang