1// 2// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5// 6 7#include "compiler/translator/RegenerateStructNames.h" 8#include "compiler/translator/compilerdebug.h" 9 10void RegenerateStructNames::visitSymbol(TIntermSymbol *symbol) 11{ 12 ASSERT(symbol); 13 TType *type = symbol->getTypePointer(); 14 ASSERT(type); 15 TStructure *userType = type->getStruct(); 16 if (!userType) 17 return; 18 19 if (mSymbolTable.findBuiltIn(userType->name(), mShaderVersion)) 20 { 21 // Built-in struct, do not touch it. 22 return; 23 } 24 25 int uniqueId = userType->uniqueId(); 26 27 ASSERT(mScopeDepth > 0); 28 if (mScopeDepth == 1) 29 { 30 // If a struct is defined at global scope, we don't map its name. 31 // This is because at global level, the struct might be used to 32 // declare a uniform, so the same name needs to stay the same for 33 // vertex/fragment shaders. However, our mapping uses internal ID, 34 // which will be different for the same struct in vertex/fragment 35 // shaders. 36 // This is OK because names for any structs defined in other scopes 37 // will begin with "_webgl", which is reserved. So there will be 38 // no conflicts among unmapped struct names from global scope and 39 // mapped struct names from other scopes. 40 // However, we need to keep track of these global structs, so if a 41 // variable is used in a local scope, we don't try to modify the 42 // struct name through that variable. 43 mDeclaredGlobalStructs.insert(uniqueId); 44 return; 45 } 46 if (mDeclaredGlobalStructs.count(uniqueId) > 0) 47 return; 48 // Map {name} to _webgl_struct_{uniqueId}_{name}. 49 const char kPrefix[] = "_webgl_struct_"; 50 if (userType->name().find(kPrefix) == 0) 51 { 52 // The name has already been regenerated. 53 return; 54 } 55 std::string id = Str(uniqueId); 56 TString tmp = kPrefix + TString(id.c_str()); 57 tmp += "_" + userType->name(); 58 userType->setName(tmp); 59} 60 61bool RegenerateStructNames::visitAggregate(Visit, TIntermAggregate *aggregate) 62{ 63 ASSERT(aggregate); 64 switch (aggregate->getOp()) 65 { 66 case EOpSequence: 67 ++mScopeDepth; 68 { 69 TIntermSequence &sequence = *(aggregate->getSequence()); 70 for (size_t ii = 0; ii < sequence.size(); ++ii) 71 { 72 TIntermNode *node = sequence[ii]; 73 ASSERT(node != NULL); 74 node->traverse(this); 75 } 76 } 77 --mScopeDepth; 78 return false; 79 default: 80 return true; 81 } 82} 83