2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 // Copyright (C) 2012-2016 LunarG, Inc.
4 // Copyright (C) 2015-2016 Google, Inc.
5 // Copyright (C) 2017 ARM Limited.
7 // All rights reserved.
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
13 // Redistributions of source code must retain the above copyright
14 // notice, this list of conditions and the following disclaimer.
16 // Redistributions in binary form must reproduce the above
17 // copyright notice, this list of conditions and the following
18 // disclaimer in the documentation and/or other materials provided
19 // with the distribution.
21 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
22 // contributors may be used to endorse or promote products derived
23 // from this software without specific prior written permission.
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 // POSSIBILITY OF SUCH DAMAGE.
39 #ifndef _TYPES_INCLUDED
40 #define _TYPES_INCLUDED
42 #include "../Include/Common.h"
43 #include "../Include/BaseTypes.h"
44 #include "../Public/ShaderLang.h"
51 const int GlslangMaxTypeLength = 200; // TODO: need to print block/struct one member per line, so this can stay bounded
53 const char* const AnonymousPrefix = "anon@"; // for something like a block whose members can be directly accessed
54 inline bool IsAnonymous(const TString& name)
56 return name.compare(0, 5, AnonymousPrefix) == 0;
60 // Details within a sampler type
70 EsdSubpass, // goes only with non-sampled image (image is true)
74 struct TSampler { // misnomer now; includes images, textures without sampler, and textures with sampler
75 TBasicType type : 8; // type returned by sampler
80 bool image : 1; // image, combined should be false
81 bool combined : 1; // true means texture is combined with a sampler, false means texture with no sampler
82 bool sampler : 1; // true means a pure sampler, other fields should be clear()
83 bool external : 1; // GL_OES_EGL_image_external
84 unsigned int vectorSize : 3; // vector return type size.
86 // Some languages support structures as sample results. Storing the whole structure in the
87 // TSampler is too large, so there is an index to a separate table.
88 static const unsigned structReturnIndexBits = 4; // number of index bits to use.
89 static const unsigned structReturnSlots = (1<<structReturnIndexBits)-1; // number of valid values
90 static const unsigned noReturnStruct = structReturnSlots; // value if no return struct type.
92 // Index into a language specific table of texture return structures.
93 unsigned int structReturnIndex : structReturnIndexBits;
95 // Encapsulate getting members' vector sizes packed into the vectorSize bitfield.
96 unsigned int getVectorSize() const { return vectorSize; }
98 bool isImage() const { return image && dim != EsdSubpass; }
99 bool isSubpass() const { return dim == EsdSubpass; }
100 bool isCombined() const { return combined; }
101 bool isPureSampler() const { return sampler; }
102 bool isTexture() const { return !sampler && !image; }
103 bool isShadow() const { return shadow; }
104 bool isArrayed() const { return arrayed; }
105 bool isMultiSample() const { return ms; }
106 bool hasReturnStruct() const { return structReturnIndex != noReturnStruct; }
119 structReturnIndex = noReturnStruct;
121 // by default, returns a single vec4;
125 // make a combined sampler and texture
126 void set(TBasicType t, TSamplerDim d, bool a = false, bool s = false, bool m = false)
138 void setImage(TBasicType t, TSamplerDim d, bool a = false, bool s = false, bool m = false)
149 // make a texture with no sampler
150 void setTexture(TBasicType t, TSamplerDim d, bool a = false, bool s = false, bool m = false)
160 // make a subpass input attachment
161 void setSubpass(TBasicType t, bool m = false)
170 // make a pure sampler, no texture, no image, nothing combined, the 'sampler' keyword
171 void setPureSampler(bool s)
178 bool operator==(const TSampler& right) const
180 return type == right.type &&
182 arrayed == right.arrayed &&
183 shadow == right.shadow &&
185 image == right.image &&
186 combined == right.combined &&
187 sampler == right.sampler &&
188 external == right.external &&
189 vectorSize == right.vectorSize &&
190 structReturnIndex == right.structReturnIndex;
193 bool operator!=(const TSampler& right) const
195 return ! operator==(right);
198 TString getString() const
208 case EbtFloat: break;
209 #ifdef AMD_EXTENSIONS
210 case EbtFloat16: s.append("f16"); break;
212 case EbtInt8: s.append("i8"); break;
213 case EbtUint16: s.append("u8"); break;
214 case EbtInt16: s.append("i16"); break;
215 case EbtUint8: s.append("u16"); break;
216 case EbtInt: s.append("i"); break;
217 case EbtUint: s.append("u"); break;
218 case EbtInt64: s.append("i64"); break;
219 case EbtUint64: s.append("u64"); break;
220 default: break; // some compilers want this
223 if (dim == EsdSubpass)
227 } else if (combined) {
233 s.append("ExternalOES");
237 case Esd1D: s.append("1D"); break;
238 case Esd2D: s.append("2D"); break;
239 case Esd3D: s.append("3D"); break;
240 case EsdCube: s.append("Cube"); break;
241 case EsdRect: s.append("2DRect"); break;
242 case EsdBuffer: s.append("Buffer"); break;
243 case EsdSubpass: s.append("Input"); break;
244 default: break; // some compilers want this
258 // Need to have association of line numbers to types in a list for building structs.
265 typedef TVector<TTypeLoc> TTypeList;
267 typedef TVector<TString*> TIdentifierList;
270 // Following are a series of helper enums for managing layouts and qualifiers,
271 // used for TPublicType, TType, others.
274 enum TLayoutPacking {
276 ElpShared, // default, but different than saying nothing
280 ElpCount // If expanding, see bitfield width below
286 ElmColumnMajor, // default, but different than saying nothing
287 ElmCount // If expanding, see bitfield width below
290 // Union of geometry shader and tessellation shader geometry types.
291 // They don't go into TType, but rather have current state per shader or
292 // active parser type (TPublicType).
293 enum TLayoutGeometry {
300 ElgTrianglesAdjacency,
306 enum TVertexSpacing {
319 // Note: order matters, as type of format is done by comparison.
330 ElfEsFloatGuard, // to help with comparisons
348 ElfFloatGuard, // to help with comparisons
356 ElfEsIntGuard, // to help with comparisons
364 ElfIntGuard, // to help with comparisons
372 ElfEsUintGuard, // to help with comparisons
394 enum TBlendEquationShift {
396 // These are used as bit-shift amounts. A mask of such shifts will have type 'int',
397 // and in that space, 0 means no bits set, or none. In this enum, 0 means (1 << 0), a bit is set.
420 static const int layoutNotSet = -1;
426 noContraction = false;
428 declaredBuiltIn = EbvNone;
431 // drop qualifiers that don't belong in a temporary variable
434 semanticName = nullptr;
435 storage = EvqTemporary;
439 specConstant = false;
444 void clearInterstage()
446 clearInterpolation();
451 void clearInterpolation()
457 #ifdef AMD_EXTENSIONS
458 explicitInterp = false;
471 // Drop just the storage qualification, which perhaps should
472 // never be done, as it is fundamentally inconsistent, but need to
473 // explore what downstream consumers need.
474 // E.g., in a dereference, it is an inconsistency between:
475 // A) partially dereferenced resource is still in the storage class it started in
476 // B) partially dereferenced resource is a new temporary object
477 // If A, then nothing should change, if B, then everything should change, but this is half way.
478 void makePartialTemporary()
480 storage = EvqTemporary;
481 specConstant = false;
485 const char* semanticName;
486 TStorageQualifier storage : 6;
487 TBuiltInVariable builtIn : 8;
488 TBuiltInVariable declaredBuiltIn : 8;
489 TPrecisionQualifier precision : 3;
490 bool invariant : 1; // require canonical treatment for cross-shader invariance
491 bool noContraction: 1; // prevent contraction and reassociation, e.g., for 'precise' keyword, and expressions it affects
496 #ifdef AMD_EXTENSIONS
497 bool explicitInterp : 1;
506 bool specConstant : 1; // having a constant_id is not sufficient: expressions have no id, but are still specConstant
509 bool isMemory() const
511 return coherent || volatil || restrict || readonly || writeonly;
513 bool isInterpolation() const
515 #ifdef AMD_EXTENSIONS
516 return flat || smooth || nopersp || explicitInterp;
518 return flat || smooth || nopersp;
521 #ifdef AMD_EXTENSIONS
522 bool isExplicitInterpolation() const
524 return explicitInterp;
527 bool isAuxiliary() const
529 return centroid || patch || sample;
532 bool isPipeInput() const
547 bool isPipeOutput() const
562 bool isParamInput() const
567 case EvqConstReadOnly:
574 bool isParamOutput() const
585 bool isUniformOrBuffer() const
619 // non-built-in symbols that might link between compilation units
620 bool isLinkable() const
635 // True if this type of IO is supposed to be arrayed with extra level for per-vertex data
636 bool isArrayedIo(EShLanguage language) const
639 case EShLangGeometry:
640 return isPipeInput();
641 case EShLangTessControl:
642 return ! patch && (isPipeInput() || isPipeOutput());
643 case EShLangTessEvaluation:
644 return ! patch && isPipeInput();
650 // Implementing an embedded layout-qualifier class here, since C++ can't have a real class bitfield
651 void clearLayout() // all layout
653 clearUniformLayout();
655 layoutPushConstant = false;
657 layoutPassthrough = false;
658 layoutViewportRelative = false;
659 // -2048 as the default value indicating layoutSecondaryViewportRelative is not set
660 layoutSecondaryViewportRelativeOffset = -2048;
663 clearInterstageLayout();
665 layoutSpecConstantId = layoutSpecConstantIdEnd;
667 layoutFormat = ElfNone;
669 void clearInterstageLayout()
671 layoutLocation = layoutLocationEnd;
672 layoutComponent = layoutComponentEnd;
673 layoutIndex = layoutIndexEnd;
677 void clearStreamLayout()
679 layoutStream = layoutStreamEnd;
681 void clearXfbLayout()
683 layoutXfbBuffer = layoutXfbBufferEnd;
684 layoutXfbStride = layoutXfbStrideEnd;
685 layoutXfbOffset = layoutXfbOffsetEnd;
688 bool hasNonXfbLayout() const
690 return hasUniformLayout() ||
696 bool hasLayout() const
698 return hasNonXfbLayout() ||
701 TLayoutMatrix layoutMatrix : 3;
702 TLayoutPacking layoutPacking : 4;
706 unsigned int layoutLocation :12;
707 static const unsigned int layoutLocationEnd = 0xFFF;
709 unsigned int layoutComponent : 3;
710 static const unsigned int layoutComponentEnd = 4;
712 unsigned int layoutSet : 7;
713 static const unsigned int layoutSetEnd = 0x3F;
715 unsigned int layoutBinding : 16;
716 static const unsigned int layoutBindingEnd = 0xFFFF;
718 unsigned int layoutIndex : 8;
719 static const unsigned int layoutIndexEnd = 0xFF;
721 unsigned int layoutStream : 8;
722 static const unsigned int layoutStreamEnd = 0xFF;
724 unsigned int layoutXfbBuffer : 4;
725 static const unsigned int layoutXfbBufferEnd = 0xF;
727 unsigned int layoutXfbStride : 10;
728 static const unsigned int layoutXfbStrideEnd = 0x3FF;
730 unsigned int layoutXfbOffset : 10;
731 static const unsigned int layoutXfbOffsetEnd = 0x3FF;
733 unsigned int layoutAttachment : 8; // for input_attachment_index
734 static const unsigned int layoutAttachmentEnd = 0XFF;
736 unsigned int layoutSpecConstantId : 11;
737 static const unsigned int layoutSpecConstantIdEnd = 0x7FF;
739 TLayoutFormat layoutFormat : 8;
741 bool layoutPushConstant;
744 bool layoutPassthrough;
745 bool layoutViewportRelative;
746 int layoutSecondaryViewportRelativeOffset;
749 bool hasUniformLayout() const
751 return hasMatrix() ||
758 void clearUniformLayout() // only uniform specific
760 layoutMatrix = ElmNone;
761 layoutPacking = ElpNone;
762 layoutOffset = layoutNotSet;
763 layoutAlign = layoutNotSet;
765 layoutSet = layoutSetEnd;
766 layoutBinding = layoutBindingEnd;
767 layoutAttachment = layoutAttachmentEnd;
770 bool hasMatrix() const
772 return layoutMatrix != ElmNone;
774 bool hasPacking() const
776 return layoutPacking != ElpNone;
778 bool hasOffset() const
780 return layoutOffset != layoutNotSet;
782 bool hasAlign() const
784 return layoutAlign != layoutNotSet;
786 bool hasAnyLocation() const
788 return hasLocation() ||
792 bool hasLocation() const
794 return layoutLocation != layoutLocationEnd;
796 bool hasComponent() const
798 return layoutComponent != layoutComponentEnd;
800 bool hasIndex() const
802 return layoutIndex != layoutIndexEnd;
806 return layoutSet != layoutSetEnd;
808 bool hasBinding() const
810 return layoutBinding != layoutBindingEnd;
812 bool hasStream() const
814 return layoutStream != layoutStreamEnd;
816 bool hasFormat() const
818 return layoutFormat != ElfNone;
822 return hasXfbBuffer() ||
826 bool hasXfbBuffer() const
828 return layoutXfbBuffer != layoutXfbBufferEnd;
830 bool hasXfbStride() const
832 return layoutXfbStride != layoutXfbStrideEnd;
834 bool hasXfbOffset() const
836 return layoutXfbOffset != layoutXfbOffsetEnd;
838 bool hasAttachment() const
840 return layoutAttachment != layoutAttachmentEnd;
842 bool hasSpecConstantId() const
844 // Not the same thing as being a specialization constant, this
845 // is just whether or not it was declared with an ID.
846 return layoutSpecConstantId != layoutSpecConstantIdEnd;
848 bool isSpecConstant() const
850 // True if type is a specialization constant, whether or not it
851 // had a specialization-constant ID, and false if it is not a
852 // true front-end constant.
855 bool isNonUniform() const
859 bool isFrontEndConstant() const
861 // True if the front-end knows the final constant value.
862 // This allows front-end constant folding.
863 return storage == EvqConst && ! specConstant;
865 bool isConstant() const
867 // True if is either kind of constant; specialization or regular.
868 return isFrontEndConstant() || isSpecConstant();
870 void makeSpecConstant()
875 static const char* getLayoutPackingString(TLayoutPacking packing)
878 case ElpPacked: return "packed";
879 case ElpShared: return "shared";
880 case ElpStd140: return "std140";
881 case ElpStd430: return "std430";
882 default: return "none";
885 static const char* getLayoutMatrixString(TLayoutMatrix m)
888 case ElmColumnMajor: return "column_major";
889 case ElmRowMajor: return "row_major";
890 default: return "none";
893 static const char* getLayoutFormatString(TLayoutFormat f)
896 case ElfRgba32f: return "rgba32f";
897 case ElfRgba16f: return "rgba16f";
898 case ElfRg32f: return "rg32f";
899 case ElfRg16f: return "rg16f";
900 case ElfR11fG11fB10f: return "r11f_g11f_b10f";
901 case ElfR32f: return "r32f";
902 case ElfR16f: return "r16f";
903 case ElfRgba16: return "rgba16";
904 case ElfRgb10A2: return "rgb10_a2";
905 case ElfRgba8: return "rgba8";
906 case ElfRg16: return "rg16";
907 case ElfRg8: return "rg8";
908 case ElfR16: return "r16";
909 case ElfR8: return "r8";
910 case ElfRgba16Snorm: return "rgba16_snorm";
911 case ElfRgba8Snorm: return "rgba8_snorm";
912 case ElfRg16Snorm: return "rg16_snorm";
913 case ElfRg8Snorm: return "rg8_snorm";
914 case ElfR16Snorm: return "r16_snorm";
915 case ElfR8Snorm: return "r8_snorm";
917 case ElfRgba32i: return "rgba32i";
918 case ElfRgba16i: return "rgba16i";
919 case ElfRgba8i: return "rgba8i";
920 case ElfRg32i: return "rg32i";
921 case ElfRg16i: return "rg16i";
922 case ElfRg8i: return "rg8i";
923 case ElfR32i: return "r32i";
924 case ElfR16i: return "r16i";
925 case ElfR8i: return "r8i";
927 case ElfRgba32ui: return "rgba32ui";
928 case ElfRgba16ui: return "rgba16ui";
929 case ElfRgba8ui: return "rgba8ui";
930 case ElfRg32ui: return "rg32ui";
931 case ElfRg16ui: return "rg16ui";
932 case ElfRgb10a2ui: return "rgb10_a2ui";
933 case ElfRg8ui: return "rg8ui";
934 case ElfR32ui: return "r32ui";
935 case ElfR16ui: return "r16ui";
936 case ElfR8ui: return "r8ui";
937 default: return "none";
940 static const char* getLayoutDepthString(TLayoutDepth d)
943 case EldAny: return "depth_any";
944 case EldGreater: return "depth_greater";
945 case EldLess: return "depth_less";
946 case EldUnchanged: return "depth_unchanged";
947 default: return "none";
950 static const char* getBlendEquationString(TBlendEquationShift e)
953 case EBlendMultiply: return "blend_support_multiply";
954 case EBlendScreen: return "blend_support_screen";
955 case EBlendOverlay: return "blend_support_overlay";
956 case EBlendDarken: return "blend_support_darken";
957 case EBlendLighten: return "blend_support_lighten";
958 case EBlendColordodge: return "blend_support_colordodge";
959 case EBlendColorburn: return "blend_support_colorburn";
960 case EBlendHardlight: return "blend_support_hardlight";
961 case EBlendSoftlight: return "blend_support_softlight";
962 case EBlendDifference: return "blend_support_difference";
963 case EBlendExclusion: return "blend_support_exclusion";
964 case EBlendHslHue: return "blend_support_hsl_hue";
965 case EBlendHslSaturation: return "blend_support_hsl_saturation";
966 case EBlendHslColor: return "blend_support_hsl_color";
967 case EBlendHslLuminosity: return "blend_support_hsl_luminosity";
968 case EBlendAllEquations: return "blend_support_all_equations";
969 default: return "unknown";
972 static const char* getGeometryString(TLayoutGeometry geometry)
975 case ElgPoints: return "points";
976 case ElgLines: return "lines";
977 case ElgLinesAdjacency: return "lines_adjacency";
978 case ElgLineStrip: return "line_strip";
979 case ElgTriangles: return "triangles";
980 case ElgTrianglesAdjacency: return "triangles_adjacency";
981 case ElgTriangleStrip: return "triangle_strip";
982 case ElgQuads: return "quads";
983 case ElgIsolines: return "isolines";
984 default: return "none";
987 static const char* getVertexSpacingString(TVertexSpacing spacing)
990 case EvsEqual: return "equal_spacing";
991 case EvsFractionalEven: return "fractional_even_spacing";
992 case EvsFractionalOdd: return "fractional_odd_spacing";
993 default: return "none";
996 static const char* getVertexOrderString(TVertexOrder order)
999 case EvoCw: return "cw";
1000 case EvoCcw: return "ccw";
1001 default: return "none";
1004 static int mapGeometryToSize(TLayoutGeometry geometry)
1007 case ElgPoints: return 1;
1008 case ElgLines: return 2;
1009 case ElgLinesAdjacency: return 4;
1010 case ElgTriangles: return 3;
1011 case ElgTrianglesAdjacency: return 6;
1017 // Qualifiers that don't need to be keep per object. They have shader scope, not object scope.
1018 // So, they will not be part of TType, TQualifier, etc.
1019 struct TShaderQualifiers {
1020 TLayoutGeometry geometry; // geometry/tessellation shader in/out primitives
1021 bool pixelCenterInteger; // fragment shader
1022 bool originUpperLeft; // fragment shader
1024 int vertices; // both for tessellation "vertices" and geometry "max_vertices"
1025 TVertexSpacing spacing;
1028 int localSize[3]; // compute shader
1029 int localSizeSpecId[3]; // compute shader specialization id for gl_WorkGroupSize
1030 bool earlyFragmentTests; // fragment input
1031 bool postDepthCoverage; // fragment input
1032 TLayoutDepth layoutDepth;
1033 bool blendEquation; // true if any blend equation was specified
1034 int numViews; // multiview extenstions
1036 #ifdef NV_EXTENSIONS
1037 bool layoutOverrideCoverage; // true if layout override_coverage set
1043 originUpperLeft = false;
1044 pixelCenterInteger = false;
1045 invocations = TQualifier::layoutNotSet;
1046 vertices = TQualifier::layoutNotSet;
1053 localSizeSpecId[0] = TQualifier::layoutNotSet;
1054 localSizeSpecId[1] = TQualifier::layoutNotSet;
1055 localSizeSpecId[2] = TQualifier::layoutNotSet;
1056 earlyFragmentTests = false;
1057 postDepthCoverage = false;
1058 layoutDepth = EldNone;
1059 blendEquation = false;
1060 numViews = TQualifier::layoutNotSet;
1061 #ifdef NV_EXTENSIONS
1062 layoutOverrideCoverage = false;
1066 // Merge in characteristics from the 'src' qualifier. They can override when
1067 // set, but never erase when not set.
1068 void merge(const TShaderQualifiers& src)
1070 if (src.geometry != ElgNone)
1071 geometry = src.geometry;
1072 if (src.pixelCenterInteger)
1073 pixelCenterInteger = src.pixelCenterInteger;
1074 if (src.originUpperLeft)
1075 originUpperLeft = src.originUpperLeft;
1076 if (src.invocations != TQualifier::layoutNotSet)
1077 invocations = src.invocations;
1078 if (src.vertices != TQualifier::layoutNotSet)
1079 vertices = src.vertices;
1080 if (src.spacing != EvsNone)
1081 spacing = src.spacing;
1082 if (src.order != EvoNone)
1086 for (int i = 0; i < 3; ++i) {
1087 if (src.localSize[i] > 1)
1088 localSize[i] = src.localSize[i];
1090 for (int i = 0; i < 3; ++i) {
1091 if (src.localSizeSpecId[i] != TQualifier::layoutNotSet)
1092 localSizeSpecId[i] = src.localSizeSpecId[i];
1094 if (src.earlyFragmentTests)
1095 earlyFragmentTests = true;
1096 if (src.postDepthCoverage)
1097 postDepthCoverage = true;
1098 if (src.layoutDepth)
1099 layoutDepth = src.layoutDepth;
1100 if (src.blendEquation)
1101 blendEquation = src.blendEquation;
1102 if (src.numViews != TQualifier::layoutNotSet)
1103 numViews = src.numViews;
1104 #ifdef NV_EXTENSIONS
1105 if (src.layoutOverrideCoverage)
1106 layoutOverrideCoverage = src.layoutOverrideCoverage;
1112 // TPublicType is just temporarily used while parsing and not quite the same
1113 // information kept per node in TType. Due to the bison stack, it can't have
1114 // types that it thinks have non-trivial constructors. It should
1115 // just be used while recognizing the grammar, not anything else.
1116 // Once enough is known about the situation, the proper information
1117 // moved into a TType, or the parse context, etc.
1121 TBasicType basicType;
1123 TQualifier qualifier;
1124 TShaderQualifiers shaderQualifiers;
1128 TArraySizes* arraySizes;
1129 const TType* userDef;
1132 void initType(const TSourceLoc& l)
1134 basicType = EbtVoid;
1138 arraySizes = nullptr;
1143 void initQualifiers(bool global = false)
1147 qualifier.storage = EvqGlobal;
1150 void init(const TSourceLoc& l, bool global = false)
1154 initQualifiers(global);
1155 shaderQualifiers.init();
1158 void setVector(int s)
1165 void setMatrix(int c, int r)
1172 bool isScalar() const
1174 return matrixCols == 0 && vectorSize == 1 && arraySizes == nullptr && userDef == nullptr;
1177 // "Image" is a superset of "Subpass"
1178 bool isImage() const { return basicType == EbtSampler && sampler.isImage(); }
1179 bool isSubpass() const { return basicType == EbtSampler && sampler.isSubpass(); }
1183 // Base class for things that have a type.
1187 POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
1189 // for "empty" type (no args) or simple scalar/vector/matrix
1190 explicit TType(TBasicType t = EbtVoid, TStorageQualifier q = EvqTemporary, int vs = 1, int mc = 0, int mr = 0,
1191 bool isVector = false) :
1192 basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1),
1193 arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
1197 qualifier.storage = q;
1198 assert(!(isMatrix() && vectorSize != 0)); // prevent vectorSize != 0 on matrices
1200 // for explicit precision qualifier
1201 TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0,
1202 bool isVector = false) :
1203 basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1),
1204 arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr)
1208 qualifier.storage = q;
1209 qualifier.precision = p;
1210 assert(p >= EpqNone && p <= EpqHigh);
1211 assert(!(isMatrix() && vectorSize != 0)); // prevent vectorSize != 0 on matrices
1213 // for turning a TPublicType into a TType, using a shallow copy
1214 explicit TType(const TPublicType& p) :
1215 basicType(p.basicType),
1216 vectorSize(p.vectorSize), matrixCols(p.matrixCols), matrixRows(p.matrixRows), vector1(false),
1217 arraySizes(p.arraySizes), structure(nullptr), fieldName(nullptr), typeName(nullptr)
1219 if (basicType == EbtSampler)
1220 sampler = p.sampler;
1223 qualifier = p.qualifier;
1225 structure = p.userDef->getWritableStruct(); // public type is short-lived; there are no sharing issues
1226 typeName = NewPoolTString(p.userDef->getTypeName().c_str());
1229 // for construction of sampler types
1230 TType(const TSampler& sampler, TStorageQualifier q = EvqUniform, TArraySizes* as = nullptr) :
1231 basicType(EbtSampler), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
1232 arraySizes(as), structure(nullptr), fieldName(nullptr), typeName(nullptr),
1236 qualifier.storage = q;
1238 // to efficiently make a dereferenced type
1239 // without ever duplicating the outer structure that will be thrown away
1240 // and using only shallow copy
1241 TType(const TType& type, int derefIndex, bool rowMajor = false)
1243 if (type.isArray()) {
1245 if (type.getArraySizes()->getNumDims() == 1) {
1246 arraySizes = nullptr;
1248 // want our own copy of the array, so we can edit it
1249 arraySizes = new TArraySizes;
1250 arraySizes->copyDereferenced(*type.arraySizes);
1252 } else if (type.basicType == EbtStruct || type.basicType == EbtBlock) {
1253 // do a structure dereference
1254 const TTypeList& memberList = *type.getStruct();
1255 shallowCopy(*memberList[derefIndex].type);
1258 // do a vector/matrix dereference
1260 if (matrixCols > 0) {
1261 // dereference from matrix to vector
1263 vectorSize = matrixCols;
1265 vectorSize = matrixRows;
1268 if (vectorSize == 1)
1270 } else if (isVector()) {
1271 // dereference from vector to scalar
1277 // for making structures, ...
1278 TType(TTypeList* userDef, const TString& n) :
1279 basicType(EbtStruct), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
1280 arraySizes(nullptr), structure(userDef), fieldName(nullptr)
1284 typeName = NewPoolTString(n.c_str());
1286 // For interface blocks
1287 TType(TTypeList* userDef, const TString& n, const TQualifier& q) :
1288 basicType(EbtBlock), vectorSize(1), matrixCols(0), matrixRows(0), vector1(false),
1289 qualifier(q), arraySizes(nullptr), structure(userDef), fieldName(nullptr)
1292 typeName = NewPoolTString(n.c_str());
1296 // Not for use across pool pops; it will cause multiple instances of TType to point to the same information.
1297 // This only works if that information (like a structure's list of types) does not change and
1298 // the instances are sharing the same pool.
1299 void shallowCopy(const TType& copyOf)
1301 basicType = copyOf.basicType;
1302 sampler = copyOf.sampler;
1303 qualifier = copyOf.qualifier;
1304 vectorSize = copyOf.vectorSize;
1305 matrixCols = copyOf.matrixCols;
1306 matrixRows = copyOf.matrixRows;
1307 vector1 = copyOf.vector1;
1308 arraySizes = copyOf.arraySizes; // copying the pointer only, not the contents
1309 structure = copyOf.structure;
1310 fieldName = copyOf.fieldName;
1311 typeName = copyOf.typeName;
1314 // Make complete copy of the whole type graph rooted at 'copyOf'.
1315 void deepCopy(const TType& copyOf)
1317 TMap<TTypeList*,TTypeList*> copied; // to enable copying a type graph as a graph, not a tree
1318 deepCopy(copyOf, copied);
1321 // Recursively make temporary
1322 void makeTemporary()
1324 getQualifier().makeTemporary();
1327 for (unsigned int i = 0; i < structure->size(); ++i)
1328 (*structure)[i].type->makeTemporary();
1331 TType* clone() const
1333 TType *newType = new TType();
1334 newType->deepCopy(*this);
1339 void makeVector() { vector1 = true; }
1341 virtual void hideMember() { basicType = EbtVoid; vectorSize = 1; }
1342 virtual bool hiddenMember() const { return basicType == EbtVoid; }
1344 virtual void setFieldName(const TString& n) { fieldName = NewPoolTString(n.c_str()); }
1345 virtual const TString& getTypeName() const
1351 virtual const TString& getFieldName() const
1357 virtual TBasicType getBasicType() const { return basicType; }
1358 virtual const TSampler& getSampler() const { return sampler; }
1359 virtual TSampler& getSampler() { return sampler; }
1361 virtual TQualifier& getQualifier() { return qualifier; }
1362 virtual const TQualifier& getQualifier() const { return qualifier; }
1364 virtual int getVectorSize() const { return vectorSize; } // returns 1 for either scalar or vector of size 1, valid for both
1365 virtual int getMatrixCols() const { return matrixCols; }
1366 virtual int getMatrixRows() const { return matrixRows; }
1367 virtual int getOuterArraySize() const { return arraySizes->getOuterSize(); }
1368 virtual TIntermTyped* getOuterArrayNode() const { return arraySizes->getOuterNode(); }
1369 virtual int getCumulativeArraySize() const { return arraySizes->getCumulativeSize(); }
1370 virtual bool isArrayOfArrays() const { return arraySizes != nullptr && arraySizes->getNumDims() > 1; }
1371 virtual int getImplicitArraySize() const { return arraySizes->getImplicitSize(); }
1372 virtual const TArraySizes* getArraySizes() const { return arraySizes; }
1373 virtual TArraySizes* getArraySizes() { return arraySizes; }
1375 virtual bool isScalar() const { return ! isVector() && ! isMatrix() && ! isStruct() && ! isArray(); }
1376 virtual bool isScalarOrVec1() const { return isScalar() || vector1; }
1377 virtual bool isVector() const { return vectorSize > 1 || vector1; }
1378 virtual bool isMatrix() const { return matrixCols ? true : false; }
1379 virtual bool isArray() const { return arraySizes != nullptr; }
1380 virtual bool isSizedArray() const { return isArray() && arraySizes->isSized(); }
1381 virtual bool isUnsizedArray() const { return isArray() && !arraySizes->isSized(); }
1382 virtual bool isArrayVariablyIndexed() const { assert(isArray()); return arraySizes->isVariablyIndexed(); }
1383 virtual void setArrayVariablyIndexed() { assert(isArray()); arraySizes->setVariablyIndexed(); }
1384 virtual void updateImplicitArraySize(int size) { assert(isArray()); arraySizes->updateImplicitSize(size); }
1385 virtual bool isStruct() const { return structure != nullptr; }
1386 virtual bool isFloatingDomain() const { return basicType == EbtFloat || basicType == EbtDouble || basicType == EbtFloat16; }
1387 virtual bool isIntegerDomain() const
1389 switch (basicType) {
1405 virtual bool isOpaque() const { return basicType == EbtSampler || basicType == EbtAtomicUint; }
1406 virtual bool isBuiltIn() const { return getQualifier().builtIn != EbvNone; }
1408 // "Image" is a superset of "Subpass"
1409 virtual bool isImage() const { return basicType == EbtSampler && getSampler().isImage(); }
1410 virtual bool isSubpass() const { return basicType == EbtSampler && getSampler().isSubpass(); }
1411 virtual bool isTexture() const { return basicType == EbtSampler && getSampler().isTexture(); }
1413 // return true if this type contains any subtype which satisfies the given predicate.
1414 template <typename P>
1415 bool contains(P predicate) const
1417 if (predicate(this))
1420 const auto hasa = [predicate](const TTypeLoc& tl) { return tl.type->contains(predicate); };
1422 return structure && std::any_of(structure->begin(), structure->end(), hasa);
1425 // Recursively checks if the type contains the given basic type
1426 virtual bool containsBasicType(TBasicType checkType) const
1428 return contains([checkType](const TType* t) { return t->basicType == checkType; } );
1431 // Recursively check the structure for any arrays, needed for some error checks
1432 virtual bool containsArray() const
1434 return contains([](const TType* t) { return t->isArray(); } );
1437 // Check the structure for any structures, needed for some error checks
1438 virtual bool containsStructure() const
1440 return contains([this](const TType* t) { return t != this && t->isStruct(); } );
1443 // Recursively check the structure for any unsized arrays, needed for triggering a copyUp().
1444 virtual bool containsUnsizedArray() const
1446 return contains([](const TType* t) { return t->isUnsizedArray(); } );
1449 virtual bool containsOpaque() const
1451 return contains([](const TType* t) { return t->isOpaque(); } );
1454 // Recursively checks if the type contains a built-in variable
1455 virtual bool containsBuiltIn() const
1457 return contains([](const TType* t) { return t->isBuiltIn(); } );
1460 virtual bool containsNonOpaque() const
1462 const auto nonOpaque = [](const TType* t) {
1463 switch (t->basicType) {
1483 return contains(nonOpaque);
1486 virtual bool containsSpecializationSize() const
1488 return contains([](const TType* t) { return t->isArray() && t->arraySizes->isOuterSpecialization(); } );
1491 virtual bool contains16BitInt() const
1493 return containsBasicType(EbtInt16) || containsBasicType(EbtUint16);
1496 virtual bool contains8BitInt() const
1498 return containsBasicType(EbtInt8) || containsBasicType(EbtUint8);
1501 // Array editing methods. Array descriptors can be shared across
1502 // type instances. This allows all uses of the same array
1503 // to be updated at once. E.g., all nodes can be explicitly sized
1504 // by tracking and correcting one implicit size. Or, all nodes
1505 // can get the explicit size on a redeclaration that gives size.
1507 // N.B.: Don't share with the shared symbol tables (symbols are
1508 // marked as isReadOnly(). Such symbols with arrays that will be
1509 // edited need to copyUp() on first use, so that
1510 // A) the edits don't effect the shared symbol table, and
1511 // B) the edits are shared across all users.
1512 void updateArraySizes(const TType& type)
1514 // For when we may already be sharing existing array descriptors,
1515 // keeping the pointers the same, just updating the contents.
1516 assert(arraySizes != nullptr);
1517 assert(type.arraySizes != nullptr);
1518 *arraySizes = *type.arraySizes;
1520 void copyArraySizes(const TArraySizes& s)
1522 // For setting a fresh new set of array sizes, not yet worrying about sharing.
1523 arraySizes = new TArraySizes;
1526 void transferArraySizes(TArraySizes* s)
1528 // For setting an already allocated set of sizes that this type can use
1532 void clearArraySizes()
1534 arraySizes = nullptr;
1537 // Add inner array sizes, to any existing sizes, via copy; the
1538 // sizes passed in can still be reused for other purposes.
1539 void copyArrayInnerSizes(const TArraySizes* s)
1542 if (arraySizes == nullptr)
1545 arraySizes->addInnerSizes(*s);
1548 void changeOuterArraySize(int s) { arraySizes->changeOuterSize(s); }
1550 // Recursively make the implicit array size the explicit array size.
1551 // Expicit arrays are compile-time or link-time sized, never run-time sized.
1552 // Sometimes, policy calls for an array to be run-time sized even if it was
1553 // never variably indexed: Don't turn a 'skipNonvariablyIndexed' array into
1554 // an explicit array.
1555 void adoptImplicitArraySizes(bool skipNonvariablyIndexed)
1557 if (isUnsizedArray() && !(skipNonvariablyIndexed || isArrayVariablyIndexed()))
1558 changeOuterArraySize(getImplicitArraySize());
1559 if (isStruct() && structure->size() > 0) {
1560 int lastMember = (int)structure->size() - 1;
1561 for (int i = 0; i < lastMember; ++i)
1562 (*structure)[i].type->adoptImplicitArraySizes(false);
1563 // implement the "last member of an SSBO" policy
1564 (*structure)[lastMember].type->adoptImplicitArraySizes(getQualifier().storage == EvqBuffer);
1568 const char* getBasicString() const
1570 return TType::getBasicString(basicType);
1573 static const char* getBasicString(TBasicType t)
1576 case EbtVoid: return "void";
1577 case EbtFloat: return "float";
1578 case EbtDouble: return "double";
1579 case EbtFloat16: return "float16_t";
1580 case EbtInt8: return "int8_t";
1581 case EbtUint8: return "uint8_t";
1582 case EbtInt16: return "int16_t";
1583 case EbtUint16: return "uint16_t";
1584 case EbtInt: return "int";
1585 case EbtUint: return "uint";
1586 case EbtInt64: return "int64_t";
1587 case EbtUint64: return "uint64_t";
1588 case EbtBool: return "bool";
1589 case EbtAtomicUint: return "atomic_uint";
1590 case EbtSampler: return "sampler/image";
1591 case EbtStruct: return "structure";
1592 case EbtBlock: return "block";
1593 default: return "unknown type";
1597 TString getCompleteString() const
1601 const auto appendStr = [&](const char* s) { typeString.append(s); };
1602 const auto appendUint = [&](unsigned int u) { typeString.append(std::to_string(u).c_str()); };
1603 const auto appendInt = [&](int i) { typeString.append(std::to_string(i).c_str()); };
1605 if (qualifier.hasLayout()) {
1606 // To reduce noise, skip this if the only layout is an xfb_buffer
1607 // with no triggering xfb_offset.
1608 TQualifier noXfbBuffer = qualifier;
1609 noXfbBuffer.layoutXfbBuffer = TQualifier::layoutXfbBufferEnd;
1610 if (noXfbBuffer.hasLayout()) {
1611 appendStr("layout(");
1612 if (qualifier.hasAnyLocation()) {
1613 appendStr(" location=");
1614 appendUint(qualifier.layoutLocation);
1615 if (qualifier.hasComponent()) {
1616 appendStr(" component=");
1617 appendUint(qualifier.layoutComponent);
1619 if (qualifier.hasIndex()) {
1620 appendStr(" index=");
1621 appendUint(qualifier.layoutIndex);
1624 if (qualifier.hasSet()) {
1626 appendUint(qualifier.layoutSet);
1628 if (qualifier.hasBinding()) {
1629 appendStr(" binding=");
1630 appendUint(qualifier.layoutBinding);
1632 if (qualifier.hasStream()) {
1633 appendStr(" stream=");
1634 appendUint(qualifier.layoutStream);
1636 if (qualifier.hasMatrix()) {
1638 appendStr(TQualifier::getLayoutMatrixString(qualifier.layoutMatrix));
1640 if (qualifier.hasPacking()) {
1642 appendStr(TQualifier::getLayoutPackingString(qualifier.layoutPacking));
1644 if (qualifier.hasOffset()) {
1645 appendStr(" offset=");
1646 appendInt(qualifier.layoutOffset);
1648 if (qualifier.hasAlign()) {
1649 appendStr(" align=");
1650 appendInt(qualifier.layoutAlign);
1652 if (qualifier.hasFormat()) {
1654 appendStr(TQualifier::getLayoutFormatString(qualifier.layoutFormat));
1656 if (qualifier.hasXfbBuffer() && qualifier.hasXfbOffset()) {
1657 appendStr(" xfb_buffer=");
1658 appendUint(qualifier.layoutXfbBuffer);
1660 if (qualifier.hasXfbOffset()) {
1661 appendStr(" xfb_offset=");
1662 appendUint(qualifier.layoutXfbOffset);
1664 if (qualifier.hasXfbStride()) {
1665 appendStr(" xfb_stride=");
1666 appendUint(qualifier.layoutXfbStride);
1668 if (qualifier.hasAttachment()) {
1669 appendStr(" input_attachment_index=");
1670 appendUint(qualifier.layoutAttachment);
1672 if (qualifier.hasSpecConstantId()) {
1673 appendStr(" constant_id=");
1674 appendUint(qualifier.layoutSpecConstantId);
1676 if (qualifier.layoutPushConstant)
1677 appendStr(" push_constant");
1679 #ifdef NV_EXTENSIONS
1680 if (qualifier.layoutPassthrough)
1681 appendStr(" passthrough");
1682 if (qualifier.layoutViewportRelative)
1683 appendStr(" layoutViewportRelative");
1684 if (qualifier.layoutSecondaryViewportRelativeOffset != -2048) {
1685 appendStr(" layoutSecondaryViewportRelativeOffset=");
1686 appendInt(qualifier.layoutSecondaryViewportRelativeOffset);
1694 if (qualifier.invariant)
1695 appendStr(" invariant");
1696 if (qualifier.noContraction)
1697 appendStr(" noContraction");
1698 if (qualifier.centroid)
1699 appendStr(" centroid");
1700 if (qualifier.smooth)
1701 appendStr(" smooth");
1704 if (qualifier.nopersp)
1705 appendStr(" noperspective");
1706 #ifdef AMD_EXTENSIONS
1707 if (qualifier.explicitInterp)
1708 appendStr(" __explicitInterpAMD");
1710 if (qualifier.patch)
1711 appendStr(" patch");
1712 if (qualifier.sample)
1713 appendStr(" sample");
1714 if (qualifier.coherent)
1715 appendStr(" coherent");
1716 if (qualifier.volatil)
1717 appendStr(" volatile");
1718 if (qualifier.restrict)
1719 appendStr(" restrict");
1720 if (qualifier.readonly)
1721 appendStr(" readonly");
1722 if (qualifier.writeonly)
1723 appendStr(" writeonly");
1724 if (qualifier.specConstant)
1725 appendStr(" specialization-constant");
1726 if (qualifier.nonUniform)
1727 appendStr(" nonuniform");
1729 appendStr(getStorageQualifierString());
1731 for(int i = 0; i < (int)arraySizes->getNumDims(); ++i) {
1732 int size = arraySizes->getDimSize(i);
1733 if (size == UnsizedArraySize && i == 0 && arraySizes->isVariablyIndexed())
1734 appendStr(" runtime-sized array of");
1736 if (size == UnsizedArraySize) {
1737 appendStr(" unsized");
1740 appendInt(arraySizes->getImplicitSize());
1744 appendInt(arraySizes->getDimSize(i));
1746 appendStr("-element array of");
1750 if (qualifier.precision != EpqNone) {
1752 appendStr(getPrecisionQualifierString());
1756 appendInt(matrixCols);
1758 appendInt(matrixRows);
1759 appendStr(" matrix of");
1760 } else if (isVector()) {
1762 appendInt(vectorSize);
1763 appendStr("-component vector of");
1767 typeString.append(getBasicTypeString());
1769 if (qualifier.builtIn != EbvNone) {
1771 appendStr(getBuiltInVariableString());
1774 // Add struct/block members
1777 for (size_t i = 0; i < structure->size(); ++i) {
1778 if (! (*structure)[i].type->hiddenMember()) {
1779 typeString.append((*structure)[i].type->getCompleteString());
1780 typeString.append(" ");
1781 typeString.append((*structure)[i].type->getFieldName());
1782 if (i < structure->size() - 1)
1792 TString getBasicTypeString() const
1794 if (basicType == EbtSampler)
1795 return sampler.getString();
1797 return getBasicString();
1800 const char* getStorageQualifierString() const { return GetStorageQualifierString(qualifier.storage); }
1801 const char* getBuiltInVariableString() const { return GetBuiltInVariableString(qualifier.builtIn); }
1802 const char* getPrecisionQualifierString() const { return GetPrecisionQualifierString(qualifier.precision); }
1803 const TTypeList* getStruct() const { return structure; }
1804 void setStruct(TTypeList* s) { structure = s; }
1805 TTypeList* getWritableStruct() const { return structure; } // This should only be used when known to not be sharing with other threads
1807 int computeNumComponents() const
1811 if (getBasicType() == EbtStruct || getBasicType() == EbtBlock) {
1812 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
1813 components += ((*tl).type)->computeNumComponents();
1814 } else if (matrixCols)
1815 components = matrixCols * matrixRows;
1817 components = vectorSize;
1819 if (arraySizes != nullptr) {
1820 components *= arraySizes->getCumulativeSize();
1826 // append this type's mangled name to the passed in 'name'
1827 void appendMangledName(TString& name) const
1829 buildMangledName(name);
1833 // Do two structure types match? They could be declared independently,
1834 // in different places, but still might satisfy the definition of matching.
1837 // "Structures must have the same name, sequence of type names, and
1838 // type definitions, and member names to be considered the same type.
1839 // This rule applies recursively for nested or embedded types."
1841 bool sameStructType(const TType& right) const
1843 // Most commonly, they are both nullptr, or the same pointer to the same actual structure
1844 if (structure == right.structure)
1847 // Both being nullptr was caught above, now they both have to be structures of the same number of elements
1848 if (structure == nullptr || right.structure == nullptr ||
1849 structure->size() != right.structure->size())
1852 // Structure names have to match
1853 if (*typeName != *right.typeName)
1856 // Compare the names and types of all the members, which have to match
1857 for (unsigned int i = 0; i < structure->size(); ++i) {
1858 if ((*structure)[i].type->getFieldName() != (*right.structure)[i].type->getFieldName())
1861 if (*(*structure)[i].type != *(*right.structure)[i].type)
1868 // See if two types match, in all aspects except arrayness
1869 bool sameElementType(const TType& right) const
1871 return basicType == right.basicType && sameElementShape(right);
1874 // See if two type's arrayness match
1875 bool sameArrayness(const TType& right) const
1877 return ((arraySizes == nullptr && right.arraySizes == nullptr) ||
1878 (arraySizes != nullptr && right.arraySizes != nullptr && *arraySizes == *right.arraySizes));
1881 // See if two type's arrayness match in everything except their outer dimension
1882 bool sameInnerArrayness(const TType& right) const
1884 assert(arraySizes != nullptr && right.arraySizes != nullptr);
1885 return arraySizes->sameInnerArrayness(*right.arraySizes);
1888 // See if two type's elements match in all ways except basic type
1889 bool sameElementShape(const TType& right) const
1891 return sampler == right.sampler &&
1892 vectorSize == right.vectorSize &&
1893 matrixCols == right.matrixCols &&
1894 matrixRows == right.matrixRows &&
1895 vector1 == right.vector1 &&
1896 sameStructType(right);
1899 // See if two types match in all ways (just the actual type, not qualification)
1900 bool operator==(const TType& right) const
1902 return sameElementType(right) && sameArrayness(right);
1905 bool operator!=(const TType& right) const
1907 return ! operator==(right);
1911 // Require consumer to pick between deep copy and shallow copy.
1912 TType(const TType& type);
1913 TType& operator=(const TType& type);
1915 // Recursively copy a type graph, while preserving the graph-like
1916 // quality. That is, don't make more than one copy of a structure that
1917 // gets reused multiple times in the type graph.
1918 void deepCopy(const TType& copyOf, TMap<TTypeList*,TTypeList*>& copiedMap)
1920 shallowCopy(copyOf);
1922 if (copyOf.arraySizes) {
1923 arraySizes = new TArraySizes;
1924 *arraySizes = *copyOf.arraySizes;
1927 if (copyOf.structure) {
1928 auto prevCopy = copiedMap.find(copyOf.structure);
1929 if (prevCopy != copiedMap.end())
1930 structure = prevCopy->second;
1932 structure = new TTypeList;
1933 copiedMap[copyOf.structure] = structure;
1934 for (unsigned int i = 0; i < copyOf.structure->size(); ++i) {
1936 typeLoc.loc = (*copyOf.structure)[i].loc;
1937 typeLoc.type = new TType();
1938 typeLoc.type->deepCopy(*(*copyOf.structure)[i].type, copiedMap);
1939 structure->push_back(typeLoc);
1944 if (copyOf.fieldName)
1945 fieldName = NewPoolTString(copyOf.fieldName->c_str());
1946 if (copyOf.typeName)
1947 typeName = NewPoolTString(copyOf.typeName->c_str());
1951 void buildMangledName(TString&) const;
1953 TBasicType basicType : 8;
1954 int vectorSize : 4; // 1 means either scalar or 1-component vector; see vector1 to disambiguate.
1957 bool vector1 : 1; // Backward-compatible tracking of a 1-component vector distinguished from a scalar.
1958 // GLSL 4.5 never has a 1-component vector; so this will always be false until such
1959 // functionality is added.
1960 // HLSL does have a 1-component vectors, so this will be true to disambiguate
1962 TQualifier qualifier;
1964 TArraySizes* arraySizes; // nullptr unless an array; can be shared across types
1965 TTypeList* structure; // nullptr unless this is a struct; can be shared across types
1966 TString *fieldName; // for structure field names
1967 TString *typeName; // for structure type name
1971 } // end namespace glslang
1973 #endif // _TYPES_INCLUDED_