SymbolTable.h 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. //
  2. // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
  3. // Copyright (C) 2013 LunarG, Inc.
  4. // Copyright (C) 2015-2018 Google, Inc.
  5. //
  6. // All rights reserved.
  7. //
  8. // Redistribution and use in source and binary forms, with or without
  9. // modification, are permitted provided that the following conditions
  10. // are met:
  11. //
  12. // Redistributions of source code must retain the above copyright
  13. // notice, this list of conditions and the following disclaimer.
  14. //
  15. // Redistributions in binary form must reproduce the above
  16. // copyright notice, this list of conditions and the following
  17. // disclaimer in the documentation and/or other materials provided
  18. // with the distribution.
  19. //
  20. // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
  21. // contributors may be used to endorse or promote products derived
  22. // from this software without specific prior written permission.
  23. //
  24. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  27. // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  28. // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  29. // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  30. // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31. // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  32. // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  34. // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  35. // POSSIBILITY OF SUCH DAMAGE.
  36. //
  37. #ifndef _SYMBOL_TABLE_INCLUDED_
  38. #define _SYMBOL_TABLE_INCLUDED_
  39. //
  40. // Symbol table for parsing. Has these design characteristics:
  41. //
  42. // * Same symbol table can be used to compile many shaders, to preserve
  43. // effort of creating and loading with the large numbers of built-in
  44. // symbols.
  45. //
  46. // --> This requires a copy mechanism, so initial pools used to create
  47. // the shared information can be popped. Done through "clone"
  48. // methods.
  49. //
  50. // * Name mangling will be used to give each function a unique name
  51. // so that symbol table lookups are never ambiguous. This allows
  52. // a simpler symbol table structure.
  53. //
  54. // * Pushing and popping of scope, so symbol table will really be a stack
  55. // of symbol tables. Searched from the top, with new inserts going into
  56. // the top.
  57. //
  58. // * Constants: Compile time constant symbols will keep their values
  59. // in the symbol table. The parser can substitute constants at parse
  60. // time, including doing constant folding and constant propagation.
  61. //
  62. // * No temporaries: Temporaries made from operations (+, --, .xy, etc.)
  63. // are tracked in the intermediate representation, not the symbol table.
  64. //
  65. #include "../Include/Common.h"
  66. #include "../Include/intermediate.h"
  67. #include "../Include/InfoSink.h"
  68. namespace glslang {
  69. //
  70. // Symbol base class. (Can build functions or variables out of these...)
  71. //
  72. class TVariable;
  73. class TFunction;
  74. class TAnonMember;
  75. typedef TVector<const char*> TExtensionList;
  76. class TSymbol {
  77. public:
  78. POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
  79. explicit TSymbol(const TString *n) : name(n), extensions(0), writable(true) { }
  80. virtual TSymbol* clone() const = 0;
  81. virtual ~TSymbol() { } // rely on all symbol owned memory coming from the pool
  82. virtual const TString& getName() const { return *name; }
  83. virtual void changeName(const TString* newName) { name = newName; }
  84. virtual void addPrefix(const char* prefix)
  85. {
  86. TString newName(prefix);
  87. newName.append(*name);
  88. changeName(NewPoolTString(newName.c_str()));
  89. }
  90. virtual const TString& getMangledName() const { return getName(); }
  91. virtual TFunction* getAsFunction() { return 0; }
  92. virtual const TFunction* getAsFunction() const { return 0; }
  93. virtual TVariable* getAsVariable() { return 0; }
  94. virtual const TVariable* getAsVariable() const { return 0; }
  95. virtual const TAnonMember* getAsAnonMember() const { return 0; }
  96. virtual const TType& getType() const = 0;
  97. virtual TType& getWritableType() = 0;
  98. virtual void setUniqueId(int id) { uniqueId = id; }
  99. virtual int getUniqueId() const { return uniqueId; }
  100. virtual void setExtensions(int numExts, const char* const exts[])
  101. {
  102. assert(extensions == 0);
  103. assert(numExts > 0);
  104. extensions = NewPoolObject(extensions);
  105. for (int e = 0; e < numExts; ++e)
  106. extensions->push_back(exts[e]);
  107. }
  108. virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); }
  109. virtual const char** getExtensions() const { return extensions->data(); }
  110. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  111. virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0;
  112. void dumpExtensions(TInfoSink& infoSink) const;
  113. #endif
  114. virtual bool isReadOnly() const { return ! writable; }
  115. virtual void makeReadOnly() { writable = false; }
  116. protected:
  117. explicit TSymbol(const TSymbol&);
  118. TSymbol& operator=(const TSymbol&);
  119. const TString *name;
  120. unsigned int uniqueId; // For cross-scope comparing during code generation
  121. // For tracking what extensions must be present
  122. // (don't use if correct version/profile is present).
  123. TExtensionList* extensions; // an array of pointers to existing constant char strings
  124. //
  125. // N.B.: Non-const functions that will be generally used should assert on this,
  126. // to avoid overwriting shared symbol-table information.
  127. //
  128. bool writable;
  129. };
  130. //
  131. // Variable class, meaning a symbol that's not a function.
  132. //
  133. // There could be a separate class hierarchy for Constant variables;
  134. // Only one of int, bool, or float, (or none) is correct for
  135. // any particular use, but it's easy to do this way, and doesn't
  136. // seem worth having separate classes, and "getConst" can't simply return
  137. // different values for different types polymorphically, so this is
  138. // just simple and pragmatic.
  139. //
  140. class TVariable : public TSymbol {
  141. public:
  142. TVariable(const TString *name, const TType& t, bool uT = false )
  143. : TSymbol(name),
  144. userType(uT),
  145. constSubtree(nullptr),
  146. memberExtensions(nullptr),
  147. anonId(-1)
  148. { type.shallowCopy(t); }
  149. virtual TVariable* clone() const;
  150. virtual ~TVariable() { }
  151. virtual TVariable* getAsVariable() { return this; }
  152. virtual const TVariable* getAsVariable() const { return this; }
  153. virtual const TType& getType() const { return type; }
  154. virtual TType& getWritableType() { assert(writable); return type; }
  155. virtual bool isUserType() const { return userType; }
  156. virtual const TConstUnionArray& getConstArray() const { return constArray; }
  157. virtual TConstUnionArray& getWritableConstArray() { assert(writable); return constArray; }
  158. virtual void setConstArray(const TConstUnionArray& array) { constArray = array; }
  159. virtual void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
  160. virtual TIntermTyped* getConstSubtree() const { return constSubtree; }
  161. virtual void setAnonId(int i) { anonId = i; }
  162. virtual int getAnonId() const { return anonId; }
  163. virtual void setMemberExtensions(int member, int numExts, const char* const exts[])
  164. {
  165. assert(type.isStruct());
  166. assert(numExts > 0);
  167. if (memberExtensions == nullptr) {
  168. memberExtensions = NewPoolObject(memberExtensions);
  169. memberExtensions->resize(type.getStruct()->size());
  170. }
  171. for (int e = 0; e < numExts; ++e)
  172. (*memberExtensions)[member].push_back(exts[e]);
  173. }
  174. virtual bool hasMemberExtensions() const { return memberExtensions != nullptr; }
  175. virtual int getNumMemberExtensions(int member) const
  176. {
  177. return memberExtensions == nullptr ? 0 : (int)(*memberExtensions)[member].size();
  178. }
  179. virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); }
  180. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  181. virtual void dump(TInfoSink& infoSink, bool complete = false) const;
  182. #endif
  183. protected:
  184. explicit TVariable(const TVariable&);
  185. TVariable& operator=(const TVariable&);
  186. TType type;
  187. bool userType;
  188. // we are assuming that Pool Allocator will free the memory allocated to unionArray
  189. // when this object is destroyed
  190. TConstUnionArray constArray; // for compile-time constant value
  191. TIntermTyped* constSubtree; // for specialization constant computation
  192. TVector<TExtensionList>* memberExtensions; // per-member extension list, allocated only when needed
  193. int anonId; // the ID used for anonymous blocks: TODO: see if uniqueId could serve a dual purpose
  194. };
  195. //
  196. // The function sub-class of symbols and the parser will need to
  197. // share this definition of a function parameter.
  198. //
  199. struct TParameter {
  200. TString *name;
  201. TType* type;
  202. TIntermTyped* defaultValue;
  203. void copyParam(const TParameter& param)
  204. {
  205. if (param.name)
  206. name = NewPoolTString(param.name->c_str());
  207. else
  208. name = 0;
  209. type = param.type->clone();
  210. defaultValue = param.defaultValue;
  211. }
  212. TBuiltInVariable getDeclaredBuiltIn() const { return type->getQualifier().declaredBuiltIn; }
  213. };
  214. //
  215. // The function sub-class of a symbol.
  216. //
  217. class TFunction : public TSymbol {
  218. public:
  219. explicit TFunction(TOperator o) :
  220. TSymbol(0),
  221. op(o),
  222. defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0) { }
  223. TFunction(const TString *name, const TType& retType, TOperator tOp = EOpNull) :
  224. TSymbol(name),
  225. mangledName(*name + '('),
  226. op(tOp),
  227. defined(false), prototyped(false), implicitThis(false), illegalImplicitThis(false), defaultParamCount(0)
  228. {
  229. returnType.shallowCopy(retType);
  230. declaredBuiltIn = retType.getQualifier().builtIn;
  231. }
  232. virtual TFunction* clone() const override;
  233. virtual ~TFunction();
  234. virtual TFunction* getAsFunction() override { return this; }
  235. virtual const TFunction* getAsFunction() const override { return this; }
  236. // Install 'p' as the (non-'this') last parameter.
  237. // Non-'this' parameters are reflected in both the list of parameters and the
  238. // mangled name.
  239. virtual void addParameter(TParameter& p)
  240. {
  241. assert(writable);
  242. parameters.push_back(p);
  243. p.type->appendMangledName(mangledName);
  244. if (p.defaultValue != nullptr)
  245. defaultParamCount++;
  246. }
  247. // Install 'this' as the first parameter.
  248. // 'this' is reflected in the list of parameters, but not the mangled name.
  249. virtual void addThisParameter(TType& type, const char* name)
  250. {
  251. TParameter p = { NewPoolTString(name), new TType, nullptr };
  252. p.type->shallowCopy(type);
  253. parameters.insert(parameters.begin(), p);
  254. }
  255. virtual void addPrefix(const char* prefix) override
  256. {
  257. TSymbol::addPrefix(prefix);
  258. mangledName.insert(0, prefix);
  259. }
  260. virtual void removePrefix(const TString& prefix)
  261. {
  262. assert(mangledName.compare(0, prefix.size(), prefix) == 0);
  263. mangledName.erase(0, prefix.size());
  264. }
  265. virtual const TString& getMangledName() const override { return mangledName; }
  266. virtual const TType& getType() const override { return returnType; }
  267. virtual TBuiltInVariable getDeclaredBuiltInType() const { return declaredBuiltIn; }
  268. virtual TType& getWritableType() override { return returnType; }
  269. virtual void relateToOperator(TOperator o) { assert(writable); op = o; }
  270. virtual TOperator getBuiltInOp() const { return op; }
  271. virtual void setDefined() { assert(writable); defined = true; }
  272. virtual bool isDefined() const { return defined; }
  273. virtual void setPrototyped() { assert(writable); prototyped = true; }
  274. virtual bool isPrototyped() const { return prototyped; }
  275. virtual void setImplicitThis() { assert(writable); implicitThis = true; }
  276. virtual bool hasImplicitThis() const { return implicitThis; }
  277. virtual void setIllegalImplicitThis() { assert(writable); illegalImplicitThis = true; }
  278. virtual bool hasIllegalImplicitThis() const { return illegalImplicitThis; }
  279. // Return total number of parameters
  280. virtual int getParamCount() const { return static_cast<int>(parameters.size()); }
  281. // Return number of parameters with default values.
  282. virtual int getDefaultParamCount() const { return defaultParamCount; }
  283. // Return number of fixed parameters (without default values)
  284. virtual int getFixedParamCount() const { return getParamCount() - getDefaultParamCount(); }
  285. virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; }
  286. virtual const TParameter& operator[](int i) const { return parameters[i]; }
  287. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  288. virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
  289. #endif
  290. protected:
  291. explicit TFunction(const TFunction&);
  292. TFunction& operator=(const TFunction&);
  293. typedef TVector<TParameter> TParamList;
  294. TParamList parameters;
  295. TType returnType;
  296. TBuiltInVariable declaredBuiltIn;
  297. TString mangledName;
  298. TOperator op;
  299. bool defined;
  300. bool prototyped;
  301. bool implicitThis; // True if this function is allowed to see all members of 'this'
  302. bool illegalImplicitThis; // True if this function is not supposed to have access to dynamic members of 'this',
  303. // even if it finds member variables in the symbol table.
  304. // This is important for a static member function that has member variables in scope,
  305. // but is not allowed to use them, or see hidden symbols instead.
  306. int defaultParamCount;
  307. };
  308. //
  309. // Members of anonymous blocks are a kind of TSymbol. They are not hidden in
  310. // the symbol table behind a container; rather they are visible and point to
  311. // their anonymous container. (The anonymous container is found through the
  312. // member, not the other way around.)
  313. //
  314. class TAnonMember : public TSymbol {
  315. public:
  316. TAnonMember(const TString* n, unsigned int m, TVariable& a, int an) : TSymbol(n), anonContainer(a), memberNumber(m), anonId(an) { }
  317. virtual TAnonMember* clone() const override;
  318. virtual ~TAnonMember() { }
  319. virtual const TAnonMember* getAsAnonMember() const override { return this; }
  320. virtual const TVariable& getAnonContainer() const { return anonContainer; }
  321. virtual unsigned int getMemberNumber() const { return memberNumber; }
  322. virtual const TType& getType() const override
  323. {
  324. const TTypeList& types = *anonContainer.getType().getStruct();
  325. return *types[memberNumber].type;
  326. }
  327. virtual TType& getWritableType() override
  328. {
  329. assert(writable);
  330. const TTypeList& types = *anonContainer.getType().getStruct();
  331. return *types[memberNumber].type;
  332. }
  333. virtual void setExtensions(int numExts, const char* const exts[]) override
  334. {
  335. anonContainer.setMemberExtensions(memberNumber, numExts, exts);
  336. }
  337. virtual int getNumExtensions() const override { return anonContainer.getNumMemberExtensions(memberNumber); }
  338. virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); }
  339. virtual int getAnonId() const { return anonId; }
  340. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  341. virtual void dump(TInfoSink& infoSink, bool complete = false) const override;
  342. #endif
  343. protected:
  344. explicit TAnonMember(const TAnonMember&);
  345. TAnonMember& operator=(const TAnonMember&);
  346. TVariable& anonContainer;
  347. unsigned int memberNumber;
  348. int anonId;
  349. };
  350. class TSymbolTableLevel {
  351. public:
  352. POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
  353. TSymbolTableLevel() : defaultPrecision(0), anonId(0), thisLevel(false) { }
  354. ~TSymbolTableLevel();
  355. bool insert(TSymbol& symbol, bool separateNameSpaces)
  356. {
  357. //
  358. // returning true means symbol was added to the table with no semantic errors
  359. //
  360. const TString& name = symbol.getName();
  361. if (name == "") {
  362. symbol.getAsVariable()->setAnonId(anonId++);
  363. // An empty name means an anonymous container, exposing its members to the external scope.
  364. // Give it a name and insert its members in the symbol table, pointing to the container.
  365. char buf[20];
  366. snprintf(buf, 20, "%s%d", AnonymousPrefix, symbol.getAsVariable()->getAnonId());
  367. symbol.changeName(NewPoolTString(buf));
  368. return insertAnonymousMembers(symbol, 0);
  369. } else {
  370. // Check for redefinition errors:
  371. // - STL itself will tell us if there is a direct name collision, with name mangling, at this level
  372. // - additionally, check for function-redefining-variable name collisions
  373. const TString& insertName = symbol.getMangledName();
  374. if (symbol.getAsFunction()) {
  375. // make sure there isn't a variable of this name
  376. if (! separateNameSpaces && level.find(name) != level.end())
  377. return false;
  378. // insert, and whatever happens is okay
  379. level.insert(tLevelPair(insertName, &symbol));
  380. return true;
  381. } else
  382. return level.insert(tLevelPair(insertName, &symbol)).second;
  383. }
  384. }
  385. // Add more members to an already inserted aggregate object
  386. bool amend(TSymbol& symbol, int firstNewMember)
  387. {
  388. // See insert() for comments on basic explanation of insert.
  389. // This operates similarly, but more simply.
  390. // Only supporting amend of anonymous blocks so far.
  391. if (IsAnonymous(symbol.getName()))
  392. return insertAnonymousMembers(symbol, firstNewMember);
  393. else
  394. return false;
  395. }
  396. bool insertAnonymousMembers(TSymbol& symbol, int firstMember)
  397. {
  398. const TTypeList& types = *symbol.getAsVariable()->getType().getStruct();
  399. for (unsigned int m = firstMember; m < types.size(); ++m) {
  400. TAnonMember* member = new TAnonMember(&types[m].type->getFieldName(), m, *symbol.getAsVariable(), symbol.getAsVariable()->getAnonId());
  401. if (! level.insert(tLevelPair(member->getMangledName(), member)).second)
  402. return false;
  403. }
  404. return true;
  405. }
  406. TSymbol* find(const TString& name) const
  407. {
  408. tLevel::const_iterator it = level.find(name);
  409. if (it == level.end())
  410. return 0;
  411. else
  412. return (*it).second;
  413. }
  414. void findFunctionNameList(const TString& name, TVector<const TFunction*>& list)
  415. {
  416. size_t parenAt = name.find_first_of('(');
  417. TString base(name, 0, parenAt + 1);
  418. tLevel::const_iterator begin = level.lower_bound(base);
  419. base[parenAt] = ')'; // assume ')' is lexically after '('
  420. tLevel::const_iterator end = level.upper_bound(base);
  421. for (tLevel::const_iterator it = begin; it != end; ++it)
  422. list.push_back(it->second->getAsFunction());
  423. }
  424. // See if there is already a function in the table having the given non-function-style name.
  425. bool hasFunctionName(const TString& name) const
  426. {
  427. tLevel::const_iterator candidate = level.lower_bound(name);
  428. if (candidate != level.end()) {
  429. const TString& candidateName = (*candidate).first;
  430. TString::size_type parenAt = candidateName.find_first_of('(');
  431. if (parenAt != candidateName.npos && candidateName.compare(0, parenAt, name) == 0)
  432. return true;
  433. }
  434. return false;
  435. }
  436. // See if there is a variable at this level having the given non-function-style name.
  437. // Return true if name is found, and set variable to true if the name was a variable.
  438. bool findFunctionVariableName(const TString& name, bool& variable) const
  439. {
  440. tLevel::const_iterator candidate = level.lower_bound(name);
  441. if (candidate != level.end()) {
  442. const TString& candidateName = (*candidate).first;
  443. TString::size_type parenAt = candidateName.find_first_of('(');
  444. if (parenAt == candidateName.npos) {
  445. // not a mangled name
  446. if (candidateName == name) {
  447. // found a variable name match
  448. variable = true;
  449. return true;
  450. }
  451. } else {
  452. // a mangled name
  453. if (candidateName.compare(0, parenAt, name) == 0) {
  454. // found a function name match
  455. variable = false;
  456. return true;
  457. }
  458. }
  459. }
  460. return false;
  461. }
  462. // Use this to do a lazy 'push' of precision defaults the first time
  463. // a precision statement is seen in a new scope. Leave it at 0 for
  464. // when no push was needed. Thus, it is not the current defaults,
  465. // it is what to restore the defaults to when popping a level.
  466. void setPreviousDefaultPrecisions(const TPrecisionQualifier *p)
  467. {
  468. // can call multiple times at one scope, will only latch on first call,
  469. // as we're tracking the previous scope's values, not the current values
  470. if (defaultPrecision != 0)
  471. return;
  472. defaultPrecision = new TPrecisionQualifier[EbtNumTypes];
  473. for (int t = 0; t < EbtNumTypes; ++t)
  474. defaultPrecision[t] = p[t];
  475. }
  476. void getPreviousDefaultPrecisions(TPrecisionQualifier *p)
  477. {
  478. // can be called for table level pops that didn't set the
  479. // defaults
  480. if (defaultPrecision == 0 || p == 0)
  481. return;
  482. for (int t = 0; t < EbtNumTypes; ++t)
  483. p[t] = defaultPrecision[t];
  484. }
  485. void relateToOperator(const char* name, TOperator op);
  486. void setFunctionExtensions(const char* name, int num, const char* const extensions[]);
  487. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  488. void dump(TInfoSink& infoSink, bool complete = false) const;
  489. #endif
  490. TSymbolTableLevel* clone() const;
  491. void readOnly();
  492. void setThisLevel() { thisLevel = true; }
  493. bool isThisLevel() const { return thisLevel; }
  494. protected:
  495. explicit TSymbolTableLevel(TSymbolTableLevel&);
  496. TSymbolTableLevel& operator=(TSymbolTableLevel&);
  497. typedef std::map<TString, TSymbol*, std::less<TString>, pool_allocator<std::pair<const TString, TSymbol*> > > tLevel;
  498. typedef const tLevel::value_type tLevelPair;
  499. typedef std::pair<tLevel::iterator, bool> tInsertResult;
  500. tLevel level; // named mappings
  501. TPrecisionQualifier *defaultPrecision;
  502. int anonId;
  503. bool thisLevel; // True if this level of the symbol table is a structure scope containing member function
  504. // that are supposed to see anonymous access to member variables.
  505. };
  506. class TSymbolTable {
  507. public:
  508. TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), separateNameSpaces(false), adoptedLevels(0)
  509. {
  510. //
  511. // This symbol table cannot be used until push() is called.
  512. //
  513. }
  514. ~TSymbolTable()
  515. {
  516. // this can be called explicitly; safest to code it so it can be called multiple times
  517. // don't deallocate levels passed in from elsewhere
  518. while (table.size() > adoptedLevels)
  519. pop(0);
  520. }
  521. void adoptLevels(TSymbolTable& symTable)
  522. {
  523. for (unsigned int level = 0; level < symTable.table.size(); ++level) {
  524. table.push_back(symTable.table[level]);
  525. ++adoptedLevels;
  526. }
  527. uniqueId = symTable.uniqueId;
  528. noBuiltInRedeclarations = symTable.noBuiltInRedeclarations;
  529. separateNameSpaces = symTable.separateNameSpaces;
  530. }
  531. //
  532. // While level adopting is generic, the methods below enact a the following
  533. // convention for levels:
  534. // 0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables
  535. // 1: per-stage built-ins, shared across all compiles, but a different copy per stage
  536. // 2: built-ins specific to a compile, like resources that are context-dependent, or redeclared built-ins
  537. // 3: user-shader globals
  538. //
  539. protected:
  540. static const int globalLevel = 3;
  541. static bool isSharedLevel(int level) { return level <= 1; } // exclude all per-compile levels
  542. static bool isBuiltInLevel(int level) { return level <= 2; } // exclude user globals
  543. static bool isGlobalLevel(int level) { return level <= globalLevel; } // include user globals
  544. public:
  545. bool isEmpty() { return table.size() == 0; }
  546. bool atBuiltInLevel() { return isBuiltInLevel(currentLevel()); }
  547. bool atGlobalLevel() { return isGlobalLevel(currentLevel()); }
  548. static bool isBuiltInSymbol(int uniqueId) {
  549. int level = uniqueId >> LevelFlagBitOffset;
  550. return isBuiltInLevel(level);
  551. }
  552. void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; }
  553. void setSeparateNameSpaces() { separateNameSpaces = true; }
  554. void push()
  555. {
  556. table.push_back(new TSymbolTableLevel);
  557. updateUniqueIdLevelFlag();
  558. }
  559. // Make a new symbol-table level to represent the scope introduced by a structure
  560. // containing member functions, such that the member functions can find anonymous
  561. // references to member variables.
  562. //
  563. // 'thisSymbol' should have a name of "" to trigger anonymous structure-member
  564. // symbol finds.
  565. void pushThis(TSymbol& thisSymbol)
  566. {
  567. assert(thisSymbol.getName().size() == 0);
  568. table.push_back(new TSymbolTableLevel);
  569. updateUniqueIdLevelFlag();
  570. table.back()->setThisLevel();
  571. insert(thisSymbol);
  572. }
  573. void pop(TPrecisionQualifier *p)
  574. {
  575. table[currentLevel()]->getPreviousDefaultPrecisions(p);
  576. delete table.back();
  577. table.pop_back();
  578. updateUniqueIdLevelFlag();
  579. }
  580. //
  581. // Insert a visible symbol into the symbol table so it can
  582. // be found later by name.
  583. //
  584. // Returns false if the was a name collision.
  585. //
  586. bool insert(TSymbol& symbol)
  587. {
  588. symbol.setUniqueId(++uniqueId);
  589. // make sure there isn't a function of this variable name
  590. if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName()))
  591. return false;
  592. // check for not overloading or redefining a built-in function
  593. if (noBuiltInRedeclarations) {
  594. if (atGlobalLevel() && currentLevel() > 0) {
  595. if (table[0]->hasFunctionName(symbol.getName()))
  596. return false;
  597. if (currentLevel() > 1 && table[1]->hasFunctionName(symbol.getName()))
  598. return false;
  599. }
  600. }
  601. return table[currentLevel()]->insert(symbol, separateNameSpaces);
  602. }
  603. // Add more members to an already inserted aggregate object
  604. bool amend(TSymbol& symbol, int firstNewMember)
  605. {
  606. // See insert() for comments on basic explanation of insert.
  607. // This operates similarly, but more simply.
  608. return table[currentLevel()]->amend(symbol, firstNewMember);
  609. }
  610. //
  611. // To allocate an internal temporary, which will need to be uniquely
  612. // identified by the consumer of the AST, but never need to
  613. // found by doing a symbol table search by name, hence allowed an
  614. // arbitrary name in the symbol with no worry of collision.
  615. //
  616. void makeInternalVariable(TSymbol& symbol)
  617. {
  618. symbol.setUniqueId(++uniqueId);
  619. }
  620. //
  621. // Copy a variable or anonymous member's structure from a shared level so that
  622. // it can be added (soon after return) to the symbol table where it can be
  623. // modified without impacting other users of the shared table.
  624. //
  625. TSymbol* copyUpDeferredInsert(TSymbol* shared)
  626. {
  627. if (shared->getAsVariable()) {
  628. TSymbol* copy = shared->clone();
  629. copy->setUniqueId(shared->getUniqueId());
  630. return copy;
  631. } else {
  632. const TAnonMember* anon = shared->getAsAnonMember();
  633. assert(anon);
  634. TVariable* container = anon->getAnonContainer().clone();
  635. container->changeName(NewPoolTString(""));
  636. container->setUniqueId(anon->getAnonContainer().getUniqueId());
  637. return container;
  638. }
  639. }
  640. TSymbol* copyUp(TSymbol* shared)
  641. {
  642. TSymbol* copy = copyUpDeferredInsert(shared);
  643. table[globalLevel]->insert(*copy, separateNameSpaces);
  644. if (shared->getAsVariable())
  645. return copy;
  646. else {
  647. // return the copy of the anonymous member
  648. return table[globalLevel]->find(shared->getName());
  649. }
  650. }
  651. // Normal find of a symbol, that can optionally say whether the symbol was found
  652. // at a built-in level or the current top-scope level.
  653. TSymbol* find(const TString& name, bool* builtIn = 0, bool* currentScope = 0, int* thisDepthP = 0)
  654. {
  655. int level = currentLevel();
  656. TSymbol* symbol;
  657. int thisDepth = 0;
  658. do {
  659. if (table[level]->isThisLevel())
  660. ++thisDepth;
  661. symbol = table[level]->find(name);
  662. --level;
  663. } while (symbol == nullptr && level >= 0);
  664. level++;
  665. if (builtIn)
  666. *builtIn = isBuiltInLevel(level);
  667. if (currentScope)
  668. *currentScope = isGlobalLevel(currentLevel()) || level == currentLevel(); // consider shared levels as "current scope" WRT user globals
  669. if (thisDepthP != nullptr) {
  670. if (! table[level]->isThisLevel())
  671. thisDepth = 0;
  672. *thisDepthP = thisDepth;
  673. }
  674. return symbol;
  675. }
  676. // Find of a symbol that returns how many layers deep of nested
  677. // structures-with-member-functions ('this' scopes) deep the symbol was
  678. // found in.
  679. TSymbol* find(const TString& name, int& thisDepth)
  680. {
  681. int level = currentLevel();
  682. TSymbol* symbol;
  683. thisDepth = 0;
  684. do {
  685. if (table[level]->isThisLevel())
  686. ++thisDepth;
  687. symbol = table[level]->find(name);
  688. --level;
  689. } while (symbol == 0 && level >= 0);
  690. if (! table[level + 1]->isThisLevel())
  691. thisDepth = 0;
  692. return symbol;
  693. }
  694. bool isFunctionNameVariable(const TString& name) const
  695. {
  696. if (separateNameSpaces)
  697. return false;
  698. int level = currentLevel();
  699. do {
  700. bool variable;
  701. bool found = table[level]->findFunctionVariableName(name, variable);
  702. if (found)
  703. return variable;
  704. --level;
  705. } while (level >= 0);
  706. return false;
  707. }
  708. void findFunctionNameList(const TString& name, TVector<const TFunction*>& list, bool& builtIn)
  709. {
  710. // For user levels, return the set found in the first scope with a match
  711. builtIn = false;
  712. int level = currentLevel();
  713. do {
  714. table[level]->findFunctionNameList(name, list);
  715. --level;
  716. } while (list.empty() && level >= globalLevel);
  717. if (! list.empty())
  718. return;
  719. // Gather across all built-in levels; they don't hide each other
  720. builtIn = true;
  721. do {
  722. table[level]->findFunctionNameList(name, list);
  723. --level;
  724. } while (level >= 0);
  725. }
  726. void relateToOperator(const char* name, TOperator op)
  727. {
  728. for (unsigned int level = 0; level < table.size(); ++level)
  729. table[level]->relateToOperator(name, op);
  730. }
  731. void setFunctionExtensions(const char* name, int num, const char* const extensions[])
  732. {
  733. for (unsigned int level = 0; level < table.size(); ++level)
  734. table[level]->setFunctionExtensions(name, num, extensions);
  735. }
  736. void setVariableExtensions(const char* name, int numExts, const char* const extensions[])
  737. {
  738. TSymbol* symbol = find(TString(name));
  739. if (symbol == nullptr)
  740. return;
  741. symbol->setExtensions(numExts, extensions);
  742. }
  743. void setVariableExtensions(const char* blockName, const char* name, int numExts, const char* const extensions[])
  744. {
  745. TSymbol* symbol = find(TString(blockName));
  746. if (symbol == nullptr)
  747. return;
  748. TVariable* variable = symbol->getAsVariable();
  749. assert(variable != nullptr);
  750. const TTypeList& structure = *variable->getAsVariable()->getType().getStruct();
  751. for (int member = 0; member < (int)structure.size(); ++member) {
  752. if (structure[member].type->getFieldName().compare(name) == 0) {
  753. variable->setMemberExtensions(member, numExts, extensions);
  754. return;
  755. }
  756. }
  757. }
  758. int getMaxSymbolId() { return uniqueId; }
  759. #if !defined(GLSLANG_WEB) && !defined(GLSLANG_ANGLE)
  760. void dump(TInfoSink& infoSink, bool complete = false) const;
  761. #endif
  762. void copyTable(const TSymbolTable& copyOf);
  763. void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); }
  764. void readOnly()
  765. {
  766. for (unsigned int level = 0; level < table.size(); ++level)
  767. table[level]->readOnly();
  768. }
  769. // Add current level in the high-bits of unique id
  770. void updateUniqueIdLevelFlag() {
  771. // clamp level to avoid overflow
  772. uint32_t level = currentLevel() > 7 ? 7 : currentLevel();
  773. uniqueId &= ((1 << LevelFlagBitOffset) - 1);
  774. uniqueId |= (level << LevelFlagBitOffset);
  775. }
  776. protected:
  777. TSymbolTable(TSymbolTable&);
  778. TSymbolTable& operator=(TSymbolTableLevel&);
  779. int currentLevel() const { return static_cast<int>(table.size()) - 1; }
  780. static const uint32_t LevelFlagBitOffset = 28;
  781. std::vector<TSymbolTableLevel*> table;
  782. int uniqueId; // for unique identification in code generation
  783. bool noBuiltInRedeclarations;
  784. bool separateNameSpaces;
  785. unsigned int adoptedLevels;
  786. };
  787. } // end namespace glslang
  788. #endif // _SYMBOL_TABLE_INCLUDED_