SymbolTable.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2012-2013 LunarG, Inc.
  4. // Copyright (C) 2017 ARM Limited.
  5. // Copyright (C) 2015-2018 Google, Inc.
  6. // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
  7. //
  8. // All rights reserved.
  9. //
  10. // Redistribution and use in source and binary forms, with or without
  11. // modification, are permitted provided that the following conditions
  12. // are met:
  13. //
  14. // Redistributions of source code must retain the above copyright
  15. // notice, this list of conditions and the following disclaimer.
  16. //
  17. // Redistributions in binary form must reproduce the above
  18. // copyright notice, this list of conditions and the following
  19. // disclaimer in the documentation and/or other materials provided
  20. // with the distribution.
  21. //
  22. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  23. // contributors may be used to endorse or promote products derived
  24. // from this software without specific prior written permission.
  25. //
  26. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  29. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  30. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  31. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  32. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  34. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  35. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  36. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  37. // POSSIBILITY OF SUCH DAMAGE.
  38. //
  39. //
  40. // Symbol table for parsing. Most functionality and main ideas
  41. // are documented in the header file.
  42. //
  43. #include "SymbolTable.h"
  44. namespace glslang {
  45. //
  46. // TType helper function needs a place to live.
  47. //
  48. //
  49. // Recursively generate mangled names.
  50. //
  51. void TType::buildMangledName(TString& mangledName) const
  52. {
  53. if (isMatrix())
  54. mangledName += 'm';
  55. else if (isVector())
  56. mangledName += 'v';
  57. switch (basicType) {
  58. case EbtFloat: mangledName += 'f'; break;
  59. case EbtInt: mangledName += 'i'; break;
  60. case EbtUint: mangledName += 'u'; break;
  61. case EbtBool: mangledName += 'b'; break;
  62. #ifndef GLSLANG_WEB
  63. case EbtDouble: mangledName += 'd'; break;
  64. case EbtFloat16: mangledName += "f16"; break;
  65. case EbtInt8: mangledName += "i8"; break;
  66. case EbtUint8: mangledName += "u8"; break;
  67. case EbtInt16: mangledName += "i16"; break;
  68. case EbtUint16: mangledName += "u16"; break;
  69. case EbtInt64: mangledName += "i64"; break;
  70. case EbtUint64: mangledName += "u64"; break;
  71. case EbtAtomicUint: mangledName += "au"; break;
  72. case EbtAccStruct: mangledName += "as"; break;
  73. case EbtRayQuery: mangledName += "rq"; break;
  74. #endif
  75. case EbtSampler:
  76. switch (sampler.type) {
  77. #ifndef GLSLANG_WEB
  78. case EbtFloat16: mangledName += "f16"; break;
  79. #endif
  80. case EbtInt: mangledName += "i"; break;
  81. case EbtUint: mangledName += "u"; break;
  82. case EbtInt64: mangledName += "i64"; break;
  83. case EbtUint64: mangledName += "u64"; break;
  84. default: break; // some compilers want this
  85. }
  86. if (sampler.isImageClass())
  87. mangledName += "I"; // a normal image or subpass
  88. else if (sampler.isPureSampler())
  89. mangledName += "p"; // a "pure" sampler
  90. else if (!sampler.isCombined())
  91. mangledName += "t"; // a "pure" texture
  92. else
  93. mangledName += "s"; // traditional combined sampler
  94. if (sampler.isArrayed())
  95. mangledName += "A";
  96. if (sampler.isShadow())
  97. mangledName += "S";
  98. if (sampler.isExternal())
  99. mangledName += "E";
  100. if (sampler.isYuv())
  101. mangledName += "Y";
  102. switch (sampler.dim) {
  103. case Esd2D: mangledName += "2"; break;
  104. case Esd3D: mangledName += "3"; break;
  105. case EsdCube: mangledName += "C"; break;
  106. #ifndef GLSLANG_WEB
  107. case Esd1D: mangledName += "1"; break;
  108. case EsdRect: mangledName += "R2"; break;
  109. case EsdBuffer: mangledName += "B"; break;
  110. case EsdSubpass: mangledName += "P"; break;
  111. #endif
  112. default: break; // some compilers want this
  113. }
  114. #ifdef ENABLE_HLSL
  115. if (sampler.hasReturnStruct()) {
  116. // Name mangle for sampler return struct uses struct table index.
  117. mangledName += "-tx-struct";
  118. char text[16]; // plenty enough space for the small integers.
  119. snprintf(text, sizeof(text), "%u-", sampler.getStructReturnIndex());
  120. mangledName += text;
  121. } else {
  122. switch (sampler.getVectorSize()) {
  123. case 1: mangledName += "1"; break;
  124. case 2: mangledName += "2"; break;
  125. case 3: mangledName += "3"; break;
  126. case 4: break; // default to prior name mangle behavior
  127. }
  128. }
  129. #endif
  130. if (sampler.isMultiSample())
  131. mangledName += "M";
  132. break;
  133. case EbtStruct:
  134. case EbtBlock:
  135. if (basicType == EbtStruct)
  136. mangledName += "struct-";
  137. else
  138. mangledName += "block-";
  139. if (typeName)
  140. mangledName += *typeName;
  141. for (unsigned int i = 0; i < structure->size(); ++i) {
  142. if ((*structure)[i].type->getBasicType() == EbtVoid)
  143. continue;
  144. mangledName += '-';
  145. (*structure)[i].type->buildMangledName(mangledName);
  146. }
  147. default:
  148. break;
  149. }
  150. if (getVectorSize() > 0)
  151. mangledName += static_cast<char>('0' + getVectorSize());
  152. else {
  153. mangledName += static_cast<char>('0' + getMatrixCols());
  154. mangledName += static_cast<char>('0' + getMatrixRows());
  155. }
  156. if (arraySizes) {
  157. const int maxSize = 11;
  158. char buf[maxSize];
  159. for (int i = 0; i < arraySizes->getNumDims(); ++i) {
  160. if (arraySizes->getDimNode(i)) {
  161. if (arraySizes->getDimNode(i)->getAsSymbolNode())
  162. snprintf(buf, maxSize, "s%d", arraySizes->getDimNode(i)->getAsSymbolNode()->getId());
  163. else
  164. snprintf(buf, maxSize, "s%p", arraySizes->getDimNode(i));
  165. } else
  166. snprintf(buf, maxSize, "%d", arraySizes->getDimSize(i));
  167. mangledName += '[';
  168. mangledName += buf;
  169. mangledName += ']';
  170. }
  171. }
  172. }
  173. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  174. //
  175. // Dump functions.
  176. //
  177. void TSymbol::dumpExtensions(TInfoSink& infoSink) const
  178. {
  179. int numExtensions = getNumExtensions();
  180. if (numExtensions) {
  181. infoSink.debug << " <";
  182. for (int i = 0; i < numExtensions; i++)
  183. infoSink.debug << getExtensions()[i] << ",";
  184. infoSink.debug << ">";
  185. }
  186. }
  187. void TVariable::dump(TInfoSink& infoSink, bool complete) const
  188. {
  189. if (complete) {
  190. infoSink.debug << getName().c_str() << ": " << type.getCompleteString();
  191. dumpExtensions(infoSink);
  192. } else {
  193. infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " "
  194. << type.getBasicTypeString();
  195. if (type.isArray())
  196. infoSink.debug << "[0]";
  197. }
  198. infoSink.debug << "\n";
  199. }
  200. void TFunction::dump(TInfoSink& infoSink, bool complete) const
  201. {
  202. if (complete) {
  203. infoSink.debug << getName().c_str() << ": " << returnType.getCompleteString() << " " << getName().c_str()
  204. << "(";
  205. int numParams = getParamCount();
  206. for (int i = 0; i < numParams; i++) {
  207. const TParameter &param = parameters[i];
  208. infoSink.debug << param.type->getCompleteString() << " "
  209. << (param.type->isStruct() ? "of " + param.type->getTypeName() + " " : "")
  210. << (param.name ? *param.name : "") << (i < numParams - 1 ? "," : "");
  211. }
  212. infoSink.debug << ")";
  213. dumpExtensions(infoSink);
  214. } else {
  215. infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " "
  216. << getMangledName().c_str() << "n";
  217. }
  218. infoSink.debug << "\n";
  219. }
  220. void TAnonMember::dump(TInfoSink& TInfoSink, bool) const
  221. {
  222. TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str()
  223. << "\n";
  224. }
  225. void TSymbolTableLevel::dump(TInfoSink& infoSink, bool complete) const
  226. {
  227. tLevel::const_iterator it;
  228. for (it = level.begin(); it != level.end(); ++it)
  229. (*it).second->dump(infoSink, complete);
  230. }
  231. void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const
  232. {
  233. for (int level = currentLevel(); level >= 0; --level) {
  234. infoSink.debug << "LEVEL " << level << "\n";
  235. table[level]->dump(infoSink, complete);
  236. }
  237. }
  238. #endif
  239. //
  240. // Functions have buried pointers to delete.
  241. //
  242. TFunction::~TFunction()
  243. {
  244. for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
  245. delete (*i).type;
  246. }
  247. //
  248. // Symbol table levels are a map of pointers to symbols that have to be deleted.
  249. //
  250. TSymbolTableLevel::~TSymbolTableLevel()
  251. {
  252. for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
  253. delete (*it).second;
  254. delete [] defaultPrecision;
  255. }
  256. //
  257. // Change all function entries in the table with the non-mangled name
  258. // to be related to the provided built-in operation.
  259. //
  260. void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
  261. {
  262. tLevel::const_iterator candidate = level.lower_bound(name);
  263. while (candidate != level.end()) {
  264. const TString& candidateName = (*candidate).first;
  265. TString::size_type parenAt = candidateName.find_first_of('(');
  266. if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) {
  267. TFunction* function = (*candidate).second->getAsFunction();
  268. function->relateToOperator(op);
  269. } else
  270. break;
  271. ++candidate;
  272. }
  273. }
  274. // Make all function overloads of the given name require an extension(s).
  275. // Should only be used for a version/profile that actually needs the extension(s).
  276. void TSymbolTableLevel::setFunctionExtensions(const char* name, int num, const char* const extensions[])
  277. {
  278. tLevel::const_iterator candidate = level.lower_bound(name);
  279. while (candidate != level.end()) {
  280. const TString& candidateName = (*candidate).first;
  281. TString::size_type parenAt = candidateName.find_first_of('(');
  282. if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0) {
  283. TSymbol* symbol = candidate->second;
  284. symbol->setExtensions(num, extensions);
  285. } else
  286. break;
  287. ++candidate;
  288. }
  289. }
  290. //
  291. // Make all symbols in this table level read only.
  292. //
  293. void TSymbolTableLevel::readOnly()
  294. {
  295. for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
  296. (*it).second->makeReadOnly();
  297. }
  298. //
  299. // Copy a symbol, but the copy is writable; call readOnly() afterward if that's not desired.
  300. //
  301. TSymbol::TSymbol(const TSymbol& copyOf)
  302. {
  303. name = NewPoolTString(copyOf.name->c_str());
  304. uniqueId = copyOf.uniqueId;
  305. writable = true;
  306. }
  307. TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
  308. {
  309. type.deepCopy(copyOf.type);
  310. userType = copyOf.userType;
  311. // we don't support specialization-constant subtrees in cloned tables, only extensions
  312. constSubtree = nullptr;
  313. extensions = nullptr;
  314. memberExtensions = nullptr;
  315. if (copyOf.getNumExtensions() > 0)
  316. setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions());
  317. if (copyOf.hasMemberExtensions()) {
  318. for (int m = 0; m < (int)copyOf.type.getStruct()->size(); ++m) {
  319. if (copyOf.getNumMemberExtensions(m) > 0)
  320. setMemberExtensions(m, copyOf.getNumMemberExtensions(m), copyOf.getMemberExtensions(m));
  321. }
  322. }
  323. if (! copyOf.constArray.empty()) {
  324. assert(! copyOf.type.isStruct());
  325. TConstUnionArray newArray(copyOf.constArray, 0, copyOf.constArray.size());
  326. constArray = newArray;
  327. }
  328. }
  329. TVariable* TVariable::clone() const
  330. {
  331. TVariable *variable = new TVariable(*this);
  332. return variable;
  333. }
  334. TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
  335. {
  336. for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
  337. TParameter param;
  338. parameters.push_back(param);
  339. parameters.back().copyParam(copyOf.parameters[i]);
  340. }
  341. extensions = nullptr;
  342. if (copyOf.getNumExtensions() > 0)
  343. setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions());
  344. returnType.deepCopy(copyOf.returnType);
  345. mangledName = copyOf.mangledName;
  346. op = copyOf.op;
  347. defined = copyOf.defined;
  348. prototyped = copyOf.prototyped;
  349. implicitThis = copyOf.implicitThis;
  350. illegalImplicitThis = copyOf.illegalImplicitThis;
  351. defaultParamCount = copyOf.defaultParamCount;
  352. }
  353. TFunction* TFunction::clone() const
  354. {
  355. TFunction *function = new TFunction(*this);
  356. return function;
  357. }
  358. TAnonMember* TAnonMember::clone() const
  359. {
  360. // Anonymous members of a given block should be cloned at a higher level,
  361. // where they can all be assured to still end up pointing to a single
  362. // copy of the original container.
  363. assert(0);
  364. return 0;
  365. }
  366. TSymbolTableLevel* TSymbolTableLevel::clone() const
  367. {
  368. TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
  369. symTableLevel->anonId = anonId;
  370. symTableLevel->thisLevel = thisLevel;
  371. std::vector<bool> containerCopied(anonId, false);
  372. tLevel::const_iterator iter;
  373. for (iter = level.begin(); iter != level.end(); ++iter) {
  374. const TAnonMember* anon = iter->second->getAsAnonMember();
  375. if (anon) {
  376. // Insert all the anonymous members of this same container at once,
  377. // avoid inserting the remaining members in the future, once this has been done,
  378. // allowing them to all be part of the same new container.
  379. if (! containerCopied[anon->getAnonId()]) {
  380. TVariable* container = anon->getAnonContainer().clone();
  381. container->changeName(NewPoolTString(""));
  382. // insert the container and all its members
  383. symTableLevel->insert(*container, false);
  384. containerCopied[anon->getAnonId()] = true;
  385. }
  386. } else
  387. symTableLevel->insert(*iter->second->clone(), false);
  388. }
  389. return symTableLevel;
  390. }
  391. void TSymbolTable::copyTable(const TSymbolTable& copyOf)
  392. {
  393. assert(adoptedLevels == copyOf.adoptedLevels);
  394. uniqueId = copyOf.uniqueId;
  395. noBuiltInRedeclarations = copyOf.noBuiltInRedeclarations;
  396. separateNameSpaces = copyOf.separateNameSpaces;
  397. for (unsigned int i = copyOf.adoptedLevels; i < copyOf.table.size(); ++i)
  398. table.push_back(copyOf.table[i]->clone());
  399. }
  400. } // end namespace glslang