Share built-in symbols common to all stages for desktop (but still per profile per version).
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@22662 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
		
							parent
							
								
									c027579631
								
							
						
					
					
						commit
						99a0576225
					
				| @ -78,35 +78,38 @@ int MapVersionToIndex(int version) | |||||||
| }                 //      V
 | }                 //      V
 | ||||||
| const int VersionCount = 12; | const int VersionCount = 12; | ||||||
| 
 | 
 | ||||||
| //
 | // only one of these needed for non-ES; ES needs 2 for different precision defaults of built-ins
 | ||||||
| // A process-global symbol table per version per profile per language.  This will be sparsely
 | enum EPrecisionClass { | ||||||
|  |     EPcGeneral, | ||||||
|  |     EPcFragment, | ||||||
|  |     EPcCount | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // A process-global symbol table per version per profile for built-ins common 
 | ||||||
|  | // to multiple stages (languages), and a process-global symbol table per version 
 | ||||||
|  | // per profile per stage for built-ins unique to each stage.  They will be sparsely
 | ||||||
| // populated, so they will only only be generated as needed.
 | // populated, so they will only only be generated as needed.
 | ||||||
| // 
 | // 
 | ||||||
| // Each has a different set of built-ins, and we want to preserve that from
 | // Each has a different set of built-ins, and we want to preserve that from
 | ||||||
| // compile to compile.
 | // compile to compile.
 | ||||||
| //
 | //
 | ||||||
|  | TSymbolTable* CommonSymbolTable[VersionCount][EProfileCount][EPcCount] = {}; | ||||||
| TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {}; | TSymbolTable* SharedSymbolTables[VersionCount][EProfileCount][EShLangCount] = {}; | ||||||
| 
 | 
 | ||||||
| TPoolAllocator* PerProcessGPA = 0; | TPoolAllocator* PerProcessGPA = 0; | ||||||
| 
 | 
 | ||||||
| bool InitializeSymbolTable(const TBuiltIns& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink,  | bool InitializeSymbolTable(const TString& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink,  | ||||||
|                            const TBuiltInResource* resources, TSymbolTable* symbolTables) |                            TSymbolTable& symbolTable) | ||||||
| { | { | ||||||
|     TIntermediate intermediate(infoSink, version, profile);	 |     TIntermediate intermediate(infoSink, version, profile);	 | ||||||
|     TSymbolTable* symbolTable; |  | ||||||
| 	 | 	 | ||||||
| 	if (resources) |     TParseContext parseContext(symbolTable, intermediate, true, version, profile, language, infoSink); | ||||||
| 		symbolTable = symbolTables; |  | ||||||
| 	else |  | ||||||
| 		symbolTable = &symbolTables[language]; |  | ||||||
| 
 |  | ||||||
|     TParseContext parseContext(*symbolTable, intermediate, true, version, profile, language, infoSink); |  | ||||||
|     TPpContext ppContext(parseContext); |     TPpContext ppContext(parseContext); | ||||||
|     glslang::TScanContext scanContext(parseContext); |     glslang::TScanContext scanContext(parseContext); | ||||||
|     parseContext.scanContext = &scanContext; |     parseContext.scanContext = &scanContext; | ||||||
|     parseContext.ppContext = &ppContext; |     parseContext.ppContext = &ppContext; | ||||||
|      |      | ||||||
|     assert(symbolTable->isEmpty() || symbolTable->atSharedBuiltInLevel()); |     assert(symbolTable.isEmpty() || symbolTable.atSharedBuiltInLevel()); | ||||||
|         |         | ||||||
|     //
 |     //
 | ||||||
|     // Parse the built-ins.  This should only happen once per
 |     // Parse the built-ins.  This should only happen once per
 | ||||||
| @ -117,55 +120,72 @@ bool InitializeSymbolTable(const TBuiltIns& builtIns, int version, EProfile prof | |||||||
|     // are preserved, and the test for an empty table fails.
 |     // are preserved, and the test for an empty table fails.
 | ||||||
|     //
 |     //
 | ||||||
| 
 | 
 | ||||||
|     symbolTable->push(); |     symbolTable.push(); | ||||||
| 
 | 
 | ||||||
|     const char* builtInShaders[2]; |     const char* builtInShaders[2]; | ||||||
|     int builtInLengths[2]; |     int builtInLengths[2]; | ||||||
|     builtInShaders[0] = builtIns.getCommonString().c_str(); |     builtInShaders[0] = builtIns.c_str(); | ||||||
|     builtInLengths[0] = builtIns.getCommonString().size(); |     builtInLengths[0] = builtIns.size(); | ||||||
|     builtInShaders[1] = builtIns.getStageString(language).c_str(); |  | ||||||
|     builtInLengths[1] = builtIns.getStageString(language).size(); |  | ||||||
| 
 | 
 | ||||||
|     if (! parseContext.parseShaderStrings(ppContext, const_cast<char**>(builtInShaders), builtInLengths, 2) != 0) { |     if (! parseContext.parseShaderStrings(ppContext, const_cast<char**>(builtInShaders), builtInLengths, 1) != 0) { | ||||||
|         infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); |         infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins"); | ||||||
|         printf("Unable to parse built-ins\n"); |         printf("Unable to parse built-ins\n"); | ||||||
| 
 | 
 | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 	if (resources) |  | ||||||
| 		IdentifyBuiltIns(version, profile, parseContext.language, *symbolTable, *resources); |  | ||||||
|     else |  | ||||||
| 		IdentifyBuiltIns(version, profile, parseContext.language, *symbolTable); |  | ||||||
| 
 |  | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool GenerateBuiltInSymbolTable(TInfoSink& infoSink, TSymbolTable* symbolTables, int version, EProfile profile) | //
 | ||||||
|  | // To call for per-stage initialization, with the common table already complete.
 | ||||||
|  | //
 | ||||||
|  | void InitializeSymbolTable(TBuiltIns& builtIns, int version, EProfile profile, EShLanguage language, TInfoSink& infoSink, TSymbolTable* commonTable, TSymbolTable* symbolTables) | ||||||
|  | { | ||||||
|  |     int commonIndex = EPcGeneral; | ||||||
|  |     if (profile == EEsProfile && language == EShLangFragment) | ||||||
|  |         commonIndex = EPcFragment; | ||||||
|  | 
 | ||||||
|  |     symbolTables[language].adoptLevels(commonTable[commonIndex]); | ||||||
|  |     InitializeSymbolTable(builtIns.getStageString(language), version, profile, language, infoSink, symbolTables[language]); | ||||||
|  |     IdentifyBuiltIns(version, profile, language, symbolTables[language]); | ||||||
|  |     if (profile == EEsProfile) | ||||||
|  |         symbolTables[language].setNoBuiltInRedeclarations(); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool GenerateBuiltInSymbolTable(TInfoSink& infoSink, TSymbolTable* commonTable,  TSymbolTable* symbolTables, int version, EProfile profile) | ||||||
| { | { | ||||||
|     TBuiltIns builtIns; |     TBuiltIns builtIns; | ||||||
|      |      | ||||||
| 	builtIns.initialize(version, profile); | 	builtIns.initialize(version, profile); | ||||||
|     InitializeSymbolTable(builtIns, version, profile, EShLangVertex, infoSink, 0, symbolTables); | 
 | ||||||
|  |     // do the common table
 | ||||||
|  |     InitializeSymbolTable(builtIns.getCommonString(), version, profile, EShLangVertex, infoSink, commonTable[EPcGeneral]); | ||||||
|  |     if (profile == EEsProfile) | ||||||
|  |         InitializeSymbolTable(builtIns.getCommonString(), version, profile, EShLangFragment, infoSink, commonTable[EPcFragment]); | ||||||
|  | 
 | ||||||
|  |     // do the per-stage tables
 | ||||||
|  |     InitializeSymbolTable(builtIns, version, profile, EShLangVertex, infoSink, commonTable, symbolTables); | ||||||
|  |     InitializeSymbolTable(builtIns, version, profile, EShLangFragment, infoSink, commonTable, symbolTables); | ||||||
|     if (profile != EEsProfile && version >= 400) { |     if (profile != EEsProfile && version >= 400) { | ||||||
|         InitializeSymbolTable(builtIns, version, profile, EShLangTessControl, infoSink, 0, symbolTables); |         InitializeSymbolTable(builtIns, version, profile, EShLangTessControl, infoSink, commonTable, symbolTables); | ||||||
|         InitializeSymbolTable(builtIns, version, profile, EShLangTessEvaluation, infoSink, 0, symbolTables); |         InitializeSymbolTable(builtIns, version, profile, EShLangTessEvaluation, infoSink, commonTable, symbolTables); | ||||||
|     } |     } | ||||||
|     if (profile != EEsProfile && version >= 150) |     if (profile != EEsProfile && version >= 150) | ||||||
|         InitializeSymbolTable(builtIns, version, profile, EShLangGeometry, infoSink, 0, symbolTables); |         InitializeSymbolTable(builtIns, version, profile, EShLangGeometry, infoSink, commonTable, symbolTables); | ||||||
|     InitializeSymbolTable(builtIns, version, profile, EShLangFragment, infoSink, 0, symbolTables); |  | ||||||
|     if (profile != EEsProfile && version >= 430) |     if (profile != EEsProfile && version >= 430) | ||||||
|         InitializeSymbolTable(builtIns, version, profile, EShLangCompute, infoSink, 0, symbolTables); |         InitializeSymbolTable(builtIns, version, profile, EShLangCompute, infoSink, commonTable, symbolTables); | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable* symbolTables, int version, EProfile profile, EShLanguage language) | bool AddContextSpecificSymbols(const TBuiltInResource* resources, TInfoSink& infoSink, TSymbolTable& symbolTable, int version, EProfile profile, EShLanguage language) | ||||||
| { | { | ||||||
|     TBuiltIns builtIns; |     TBuiltIns builtIns; | ||||||
|      |      | ||||||
| 	builtIns.initialize(*resources, version, profile, language); | 	builtIns.initialize(*resources, version, profile, language); | ||||||
|     InitializeSymbolTable(builtIns, version, profile, language, infoSink, resources, symbolTables); |     InitializeSymbolTable(builtIns.getCommonString(), version, profile, language, infoSink, symbolTable); | ||||||
|  | 	IdentifyBuiltIns(version, profile, language, symbolTable, *resources); | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| @ -189,9 +209,9 @@ void SetupBuiltinSymbolTable(int version, EProfile profile) | |||||||
|     // Make sure only one thread tries to do this at a time
 |     // Make sure only one thread tries to do this at a time
 | ||||||
|     glslang::GetGlobalLock(); |     glslang::GetGlobalLock(); | ||||||
| 
 | 
 | ||||||
|     // See if it's already been done.
 |     // See if it's already been done for this version/profile combination
 | ||||||
|     int versionIndex = MapVersionToIndex(version); |     int versionIndex = MapVersionToIndex(version); | ||||||
|     if (SharedSymbolTables[versionIndex][profile][EShLangVertex]) { |     if (CommonSymbolTable[versionIndex][profile][EPcGeneral]) { | ||||||
|         glslang::ReleaseGlobalLock(); |         glslang::ReleaseGlobalLock(); | ||||||
| 
 | 
 | ||||||
|         return; |         return; | ||||||
| @ -202,25 +222,34 @@ void SetupBuiltinSymbolTable(int version, EProfile profile) | |||||||
|     TPoolAllocator* builtInPoolAllocator = new TPoolAllocator(); |     TPoolAllocator* builtInPoolAllocator = new TPoolAllocator(); | ||||||
|     SetThreadPoolAllocator(*builtInPoolAllocator); |     SetThreadPoolAllocator(*builtInPoolAllocator); | ||||||
| 
 | 
 | ||||||
|     // Generate the symbol table using the new pool
 |     // Generate the local symbol tables using the new pool
 | ||||||
|     TSymbolTable symTables[EShLangCount]; |     TSymbolTable commonTable[2]; | ||||||
|     if (profile == EEsProfile) { |     TSymbolTable stageTables[EShLangCount]; | ||||||
|         for (int stage = 0; stage < EShLangCount; ++stage) |     GenerateBuiltInSymbolTable(infoSink, commonTable, stageTables, version, profile); | ||||||
|             symTables[stage].setNoBuiltInRedeclarations(); |  | ||||||
|     } |  | ||||||
|     GenerateBuiltInSymbolTable(infoSink, symTables, version, profile); |  | ||||||
| 
 | 
 | ||||||
|     // Switch to the process-global pool
 |     // Switch to the process-global pool
 | ||||||
|     SetThreadPoolAllocator(*PerProcessGPA); |     SetThreadPoolAllocator(*PerProcessGPA); | ||||||
| 
 | 
 | ||||||
|     // Copy the symbol table from the new pool to the process-global pool
 |     // Copy the local symbol tables from the new pool to the global tables using the process-global pool
 | ||||||
|  |     for (int precClass = 0; precClass < EPcCount; ++precClass) { | ||||||
|  |         if (! commonTable[precClass].isEmpty()) { | ||||||
|  |             CommonSymbolTable[versionIndex][profile][precClass] = new TSymbolTable; | ||||||
|  |             CommonSymbolTable[versionIndex][profile][precClass]->copyTable(commonTable[precClass]); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|     for (int stage = 0; stage < EShLangCount; ++stage) { |     for (int stage = 0; stage < EShLangCount; ++stage) { | ||||||
|         if (! symTables[stage].isEmpty()) { |         if (! stageTables[stage].isEmpty()) { | ||||||
|             SharedSymbolTables[versionIndex][profile][stage] = new TSymbolTable; |             SharedSymbolTables[versionIndex][profile][stage] = new TSymbolTable; | ||||||
|             SharedSymbolTables[versionIndex][profile][stage]->copyTable(symTables[stage]); |             SharedSymbolTables[versionIndex][profile][stage]->copyTable(stageTables[stage]); | ||||||
|         }     |         }     | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     // Explicitly clean up the local tables before deleting the pool they used and before releasing the lock.
 | ||||||
|  |     for (int precClass = 0; precClass < EPcCount; ++precClass) | ||||||
|  |         commonTable[precClass].~TSymbolTable(); | ||||||
|  |     for (int stage = 0; stage < EShLangCount; ++stage) | ||||||
|  |         stageTables[stage].~TSymbolTable(); | ||||||
|  | 
 | ||||||
|     delete builtInPoolAllocator; |     delete builtInPoolAllocator; | ||||||
|     SetThreadPoolAllocator(savedGPA); |     SetThreadPoolAllocator(savedGPA); | ||||||
| 
 | 
 | ||||||
| @ -429,18 +458,13 @@ int ShCompile( | |||||||
|     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)] |     TSymbolTable* cachedTable = SharedSymbolTables[MapVersionToIndex(version)] | ||||||
|                                                   [profile] |                                                   [profile] | ||||||
|                                                   [compiler->getLanguage()]; |                                                   [compiler->getLanguage()]; | ||||||
|     TSymbolTable* errorTable = 0; |     TSymbolTable symbolTable; | ||||||
|     if (! cachedTable) { |     if (cachedTable) | ||||||
|         errorTable = new TSymbolTable; |         symbolTable.adoptLevels(*cachedTable); | ||||||
|         cachedTable = errorTable; |  | ||||||
|     } |  | ||||||
|     TSymbolTable symbolTable(*cachedTable); |  | ||||||
|     if (errorTable) |  | ||||||
|         delete errorTable; |  | ||||||
|      |      | ||||||
|     // Add built-in symbols that are potentially context dependent;
 |     // Add built-in symbols that are potentially context dependent;
 | ||||||
|     // they get popped again further down.
 |     // they get popped again further down.
 | ||||||
|     AddContextSpecificSymbols(resources, compiler->infoSink, &symbolTable, version, profile, compiler->getLanguage()); |     AddContextSpecificSymbols(resources, compiler->infoSink, symbolTable, version, profile, compiler->getLanguage()); | ||||||
| 
 | 
 | ||||||
|     TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages); |     TParseContext parseContext(symbolTable, intermediate, false, version, profile, compiler->getLanguage(), compiler->infoSink, forwardCompatible, messages); | ||||||
|     glslang::TScanContext scanContext(parseContext); |     glslang::TScanContext scanContext(parseContext); | ||||||
|  | |||||||
| @ -365,21 +365,12 @@ protected: | |||||||
| 
 | 
 | ||||||
| class TSymbolTable { | class TSymbolTable { | ||||||
| public: | public: | ||||||
|     TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), adoptedLevels(1)  // TODO: memory: can we make adoptedLevels be 0 for symbol tables we don't keep?
 |     TSymbolTable() : uniqueId(0), noBuiltInRedeclarations(false), adoptedLevels(0) | ||||||
|     { |     { | ||||||
|         //
 |         //
 | ||||||
|         // This symbol table cannot be used until push() is called.
 |         // This symbol table cannot be used until push() is called.
 | ||||||
|         //
 |         //
 | ||||||
|     } |     } | ||||||
|     explicit TSymbolTable(TSymbolTable& symTable) |  | ||||||
|     { |  | ||||||
|         if (! symTable.isEmpty()) { |  | ||||||
|             table.push_back(symTable.table[0]); |  | ||||||
|             adoptedLevels = 1; |  | ||||||
|             uniqueId = symTable.uniqueId; |  | ||||||
|             noBuiltInRedeclarations = symTable.noBuiltInRedeclarations; |  | ||||||
|         } // else should only be to handle error paths
 |  | ||||||
|     } |  | ||||||
|     ~TSymbolTable() |     ~TSymbolTable() | ||||||
|     { |     { | ||||||
|         // don't deallocate levels passed in from elsewhere
 |         // don't deallocate levels passed in from elsewhere
 | ||||||
| @ -388,18 +379,28 @@ public: | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     //
 |     //
 | ||||||
|     // When the symbol table is initialized with the built-ins, there should
 |     // While level adopting is generic, the methods below enact a the following
 | ||||||
|     // 'push' calls, so that built-in shared across all compiles are at level 0 
 |     // convention for levels:
 | ||||||
|     // built-ins specific to a compile are at level 1 and the shader
 |     //   0: common built-ins shared across all stages, all compiles, only one copy for all symbol tables
 | ||||||
|     // globals are at level 2.
 |     //   1: per-stage built-ins, shared across all compiles, but a different copy per stage
 | ||||||
|     //
 |     //   2: built-ins specific to a compile, like resources that are context-dependent
 | ||||||
|     // TODO: compile-time memory: have an even earlier level for all built-ins
 |     //   3: user-shader globals
 | ||||||
|     //       common to all stages.  Currently, each stage has copy.
 |  | ||||||
|     //
 |     //
 | ||||||
|  |     void adoptLevels(TSymbolTable& symTable) | ||||||
|  |     { | ||||||
|  |         for (unsigned int level = 0; level < symTable.table.size(); ++level) { | ||||||
|  |             table.push_back(symTable.table[level]); | ||||||
|  |             ++adoptedLevels; | ||||||
|  |         } | ||||||
|  |         uniqueId = symTable.uniqueId; | ||||||
|  |         noBuiltInRedeclarations = symTable.noBuiltInRedeclarations; | ||||||
|  |     } | ||||||
|     bool isEmpty() { return table.size() == 0; } |     bool isEmpty() { return table.size() == 0; } | ||||||
|     bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); } |     bool atBuiltInLevel() { return atSharedBuiltInLevel() || atDynamicBuiltInLevel(); } | ||||||
|     bool atSharedBuiltInLevel() { return table.size() == 1; }	 |     bool atSharedBuiltInLevel() { return table.size() <= 2; } | ||||||
|     bool atGlobalLevel() { return table.size() <= 3; } |     bool atDynamicBuiltInLevel() { return table.size() == 3; } | ||||||
|  |     bool atGlobalLevel() { return table.size() <= 4; } | ||||||
|  | 
 | ||||||
|     void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } |     void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } | ||||||
|      |      | ||||||
|     void push() |     void push() | ||||||
| @ -450,8 +451,16 @@ public: | |||||||
|         return symbol; |         return symbol; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     TSymbolTableLevel* getGlobalLevel() { assert(table.size() >= 3); return table[2]; } |     void relateToOperator(const char* name, TOperator op) | ||||||
|     void relateToOperator(const char* name, TOperator op) { table[0]->relateToOperator(name, op); } |     { | ||||||
|  |         for (unsigned int level = 0; level < table.size(); ++level) { | ||||||
|  |             if (atSharedBuiltInLevel()) | ||||||
|  |                 table[level]->relateToOperator(name, op); | ||||||
|  |             else | ||||||
|  |                 break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     int getMaxSymbolId() { return uniqueId; } |     int getMaxSymbolId() { return uniqueId; } | ||||||
|     void dump(TInfoSink &infoSink) const; |     void dump(TInfoSink &infoSink) const; | ||||||
| 	void copyTable(const TSymbolTable& copyOf); | 	void copyTable(const TSymbolTable& copyOf); | ||||||
| @ -459,10 +468,10 @@ public: | |||||||
|     void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } |     void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } | ||||||
| 
 | 
 | ||||||
| protected: | protected: | ||||||
|  |     TSymbolTable(TSymbolTable&); | ||||||
|     TSymbolTable& operator=(TSymbolTableLevel&); |     TSymbolTable& operator=(TSymbolTableLevel&); | ||||||
| 
 | 
 | ||||||
|     int currentLevel() const { return static_cast<int>(table.size()) - 1; } |     int currentLevel() const { return static_cast<int>(table.size()) - 1; } | ||||||
|     bool atDynamicBuiltInLevel() { return table.size() == 2; } |  | ||||||
| 
 | 
 | ||||||
|     std::vector<TSymbolTableLevel*> table; |     std::vector<TSymbolTableLevel*> table; | ||||||
|     int uniqueId;     // for unique identification in code generation
 |     int uniqueId;     // for unique identification in code generation
 | ||||||
|  | |||||||
| @ -1098,7 +1098,7 @@ declaration | |||||||
|     | PRECISION precision_qualifier type_specifier SEMICOLON { |     | PRECISION precision_qualifier type_specifier SEMICOLON { | ||||||
|         parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "precision statement"); |         parseContext.profileRequires($1.loc, ENoProfile, 130, 0, "precision statement"); | ||||||
| 
 | 
 | ||||||
|         // lazy setting of the previous scope's defaults, only takes on first one in a particular scope |         // lazy setting of the previous scope's defaults, has effect only the first time it is called in a particular scope | ||||||
|         parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); |         parseContext.symbolTable.setPreviousDefaultPrecisions(&parseContext.defaultPrecision[0]); | ||||||
| 
 | 
 | ||||||
| 		parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); | 		parseContext.setDefaultPrecision($1.loc, $3, $2.qualifier.precision); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 John Kessenich
						John Kessenich