GL_EXT_ray_query updates
[platform/upstream/glslang.git] / glslang / MachineIndependent / SymbolTable.cpp
index d34f4d2..5dc8353 100644 (file)
@@ -1,12 +1,15 @@
 //
-//Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
-//Copyright (C) 2012-2013 LunarG, Inc.
+// Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
+// Copyright (C) 2012-2013 LunarG, Inc.
+// Copyright (C) 2017 ARM Limited.
+// Copyright (C) 2015-2018 Google, Inc.
+// Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
 //
-//All rights reserved.
+// All rights reserved.
 //
-//Redistribution and use in source and binary forms, with or without
-//modification, are permitted provided that the following conditions
-//are met:
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
 //
 //    Redistributions of source code must retain the above copyright
 //    notice, this list of conditions and the following disclaimer.
 //    contributors may be used to endorse or promote products derived
 //    from this software without specific prior written permission.
 //
-//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-//POSSIBILITY OF SUCH DAMAGE.
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+// COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
 //
 
 //
@@ -50,7 +53,7 @@ namespace glslang {
 //
 // Recursively generate mangled names.
 //
-void TType::buildMangledName(TString& mangledName)
+void TType::buildMangledName(TString& mangledName) const
 {
     if (isMatrix())
         mangledName += 'm';
@@ -59,51 +62,87 @@ void TType::buildMangledName(TString& mangledName)
 
     switch (basicType) {
     case EbtFloat:              mangledName += 'f';      break;
-    case EbtDouble:             mangledName += 'd';      break;
-#ifdef AMD_EXTENSIONS
-    case EbtFloat16:            mangledName += "f16";    break;
-#endif
     case EbtInt:                mangledName += 'i';      break;
     case EbtUint:               mangledName += 'u';      break;
+    case EbtBool:               mangledName += 'b';      break;
+#ifndef GLSLANG_WEB
+    case EbtDouble:             mangledName += 'd';      break;
+    case EbtFloat16:            mangledName += "f16";    break;
+    case EbtInt8:               mangledName += "i8";     break;
+    case EbtUint8:              mangledName += "u8";     break;
+    case EbtInt16:              mangledName += "i16";    break;
+    case EbtUint16:             mangledName += "u16";    break;
     case EbtInt64:              mangledName += "i64";    break;
     case EbtUint64:             mangledName += "u64";    break;
-    case EbtBool:               mangledName += 'b';      break;
     case EbtAtomicUint:         mangledName += "au";     break;
+    case EbtAccStruct:          mangledName += "as";     break;
+    case EbtRayQuery:           mangledName += "rq";     break;
+#endif
     case EbtSampler:
         switch (sampler.type) {
+#ifndef GLSLANG_WEB
+        case EbtFloat16: mangledName += "f16"; break;
+#endif
         case EbtInt:   mangledName += "i"; break;
         case EbtUint:  mangledName += "u"; break;
         default: break; // some compilers want this
         }
-        if (sampler.image)
-            mangledName += "I";  // a normal image
-        else if (sampler.sampler)
+        if (sampler.isImageClass())
+            mangledName += "I";  // a normal image or subpass
+        else if (sampler.isPureSampler())
             mangledName += "p";  // a "pure" sampler
-        else if (!sampler.combined)
+        else if (!sampler.isCombined())
             mangledName += "t";  // a "pure" texture
         else
             mangledName += "s";  // traditional combined sampler
-        if (sampler.arrayed)
+        if (sampler.isArrayed())
             mangledName += "A";
-        if (sampler.shadow)
+        if (sampler.isShadow())
             mangledName += "S";
-        if (sampler.external)
+        if (sampler.isExternal())
             mangledName += "E";
+        if (sampler.isYuv())
+            mangledName += "Y";
         switch (sampler.dim) {
-        case Esd1D:       mangledName += "1";  break;
         case Esd2D:       mangledName += "2";  break;
         case Esd3D:       mangledName += "3";  break;
         case EsdCube:     mangledName += "C";  break;
+#ifndef GLSLANG_WEB
+        case Esd1D:       mangledName += "1";  break;
         case EsdRect:     mangledName += "R2"; break;
         case EsdBuffer:   mangledName += "B";  break;
         case EsdSubpass:  mangledName += "P";  break;
+#endif
         default: break; // some compilers want this
         }
-        if (sampler.ms)
+
+#ifdef ENABLE_HLSL
+        if (sampler.hasReturnStruct()) {
+            // Name mangle for sampler return struct uses struct table index.
+            mangledName += "-tx-struct";
+
+            char text[16]; // plenty enough space for the small integers.
+            snprintf(text, sizeof(text), "%d-", sampler.getStructReturnIndex());
+            mangledName += text;
+        } else {
+            switch (sampler.getVectorSize()) {
+            case 1: mangledName += "1"; break;
+            case 2: mangledName += "2"; break;
+            case 3: mangledName += "3"; break;
+            case 4: break; // default to prior name mangle behavior
+            }
+        }
+#endif
+
+        if (sampler.isMultiSample())
             mangledName += "M";
         break;
     case EbtStruct:
-        mangledName += "struct-";
+    case EbtBlock:
+        if (basicType == EbtStruct)
+            mangledName += "struct-";
+        else
+            mangledName += "block-";
         if (typeName)
             mangledName += *typeName;
         for (unsigned int i = 0; i < structure->size(); ++i) {
@@ -139,44 +178,88 @@ void TType::buildMangledName(TString& mangledName)
     }
 }
 
+#ifndef GLSLANG_WEB
+
 //
 // Dump functions.
 //
 
-void TVariable::dump(TInfoSink& infoSink) const
+void TSymbol::dumpExtensions(TInfoSink& infoSink) const
 {
-    infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " " << type.getBasicTypeString();
-    if (type.isArray()) {
-        infoSink.debug << "[0]";
+    int numExtensions = getNumExtensions();
+    if (numExtensions) {
+        infoSink.debug << " <";
+
+        for (int i = 0; i < numExtensions; i++)
+            infoSink.debug << getExtensions()[i] << ",";
+
+        infoSink.debug << ">";
+    }
+}
+
+void TVariable::dump(TInfoSink& infoSink, bool complete) const
+{
+    if (complete) {
+        infoSink.debug << getName().c_str() << ": " << type.getCompleteString();
+        dumpExtensions(infoSink);
+    } else {
+        infoSink.debug << getName().c_str() << ": " << type.getStorageQualifierString() << " "
+                       << type.getBasicTypeString();
+
+        if (type.isArray())
+            infoSink.debug << "[0]";
     }
+
     infoSink.debug << "\n";
 }
 
-void TFunction::dump(TInfoSink& infoSink) const
+void TFunction::dump(TInfoSink& infoSink, bool complete) const
 {
-    infoSink.debug << getName().c_str() << ": " <<  returnType.getBasicTypeString() << " " << getMangledName().c_str() << "\n";
+    if (complete) {
+        infoSink.debug << getName().c_str() << ": " << returnType.getCompleteString() << " " << getName().c_str()
+                       << "(";
+
+        int numParams = getParamCount();
+        for (int i = 0; i < numParams; i++) {
+            const TParameter &param = parameters[i];
+            infoSink.debug << param.type->getCompleteString() << " "
+                           << (param.type->isStruct() ? "of " + param.type->getTypeName() + " " : "")
+                           << (param.name ? *param.name : "") << (i < numParams - 1 ? "," : "");
+        }
+
+        infoSink.debug << ")";
+        dumpExtensions(infoSink);
+    } else {
+        infoSink.debug << getName().c_str() << ": " << returnType.getBasicTypeString() << " "
+                       << getMangledName().c_str() << "n";
+    }
+
+    infoSink.debug << "\n";
 }
 
-void TAnonMember::dump(TInfoSink& TInfoSink) const
+void TAnonMember::dump(TInfoSink& TInfoSink, bool) const
 {
-    TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str() << "\n";
+    TInfoSink.debug << "anonymous member " << getMemberNumber() << " of " << getAnonContainer().getName().c_str()
+                    << "\n";
 }
 
-void TSymbolTableLevel::dump(TInfoSink &infoSink) const
+void TSymbolTableLevel::dump(TInfoSink& infoSink, bool complete) const
 {
     tLevel::const_iterator it;
     for (it = level.begin(); it != level.end(); ++it)
-        (*it).second->dump(infoSink);
+        (*it).second->dump(infoSink, complete);
 }
 
-void TSymbolTable::dump(TInfoSink &infoSink) const
+void TSymbolTable::dump(TInfoSink& infoSink, bool complete) const
 {
     for (int level = currentLevel(); level >= 0; --level) {
         infoSink.debug << "LEVEL " << level << "\n";
-        table[level]->dump(infoSink);
+        table[level]->dump(infoSink, complete);
     }
 }
 
+#endif
+
 //
 // Functions have buried pointers to delete.
 //
@@ -256,19 +339,25 @@ TVariable::TVariable(const TVariable& copyOf) : TSymbol(copyOf)
 {
     type.deepCopy(copyOf.type);
     userType = copyOf.userType;
-    numExtensions = 0;
-    extensions = 0;
-    if (copyOf.numExtensions != 0)
-        setExtensions(copyOf.numExtensions, copyOf.extensions);
+
+    // we don't support specialization-constant subtrees in cloned tables, only extensions
+    constSubtree = nullptr;
+    extensions = nullptr;
+    memberExtensions = nullptr;
+    if (copyOf.getNumExtensions() > 0)
+        setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions());
+    if (copyOf.hasMemberExtensions()) {
+        for (int m = 0; m < (int)copyOf.type.getStruct()->size(); ++m) {
+            if (copyOf.getNumMemberExtensions(m) > 0)
+                setMemberExtensions(m, copyOf.getNumMemberExtensions(m), copyOf.getMemberExtensions(m));
+        }
+    }
 
     if (! copyOf.constArray.empty()) {
         assert(! copyOf.type.isStruct());
         TConstUnionArray newArray(copyOf.constArray, 0, copyOf.constArray.size());
         constArray = newArray;
     }
-
-    // don't support specialization-constant subtrees in cloned tables
-    constSubtree = nullptr;
 }
 
 TVariable* TVariable::clone() const
@@ -286,15 +375,16 @@ TFunction::TFunction(const TFunction& copyOf) : TSymbol(copyOf)
         parameters.back().copyParam(copyOf.parameters[i]);
     }
 
-    numExtensions = 0;
-    extensions = 0;
-    if (copyOf.extensions != 0)
-        setExtensions(copyOf.numExtensions, copyOf.extensions);
+    extensions = nullptr;
+    if (copyOf.getNumExtensions() > 0)
+        setExtensions(copyOf.getNumExtensions(), copyOf.getExtensions());
     returnType.deepCopy(copyOf.returnType);
     mangledName = copyOf.mangledName;
     op = copyOf.op;
     defined = copyOf.defined;
     prototyped = copyOf.prototyped;
+    implicitThis = copyOf.implicitThis;
+    illegalImplicitThis = copyOf.illegalImplicitThis;
     defaultParamCount = copyOf.defaultParamCount;
 }
 
@@ -319,18 +409,19 @@ TSymbolTableLevel* TSymbolTableLevel::clone() const
 {
     TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
     symTableLevel->anonId = anonId;
+    symTableLevel->thisLevel = thisLevel;
     std::vector<bool> containerCopied(anonId, false);
     tLevel::const_iterator iter;
     for (iter = level.begin(); iter != level.end(); ++iter) {
         const TAnonMember* anon = iter->second->getAsAnonMember();
         if (anon) {
             // Insert all the anonymous members of this same container at once,
-            // avoid inserting the other members in the future, once this has been done,
+            // avoid inserting the remaining members in the future, once this has been done,
             // allowing them to all be part of the same new container.
             if (! containerCopied[anon->getAnonId()]) {
                 TVariable* container = anon->getAnonContainer().clone();
                 container->changeName(NewPoolTString(""));
-                // insert the whole container
+                // insert the container and all its members
                 symTableLevel->insert(*container, false);
                 containerCopied[anon->getAnonId()] = true;
             }