diff --git a/StandAlone/StandAlone.cpp b/StandAlone/StandAlone.cpp index bb37a840eb..b7c4387718 100644 --- a/StandAlone/StandAlone.cpp +++ b/StandAlone/StandAlone.cpp @@ -162,6 +162,7 @@ const char* shaderStageName = nullptr; const char* variableName = nullptr; bool HlslEnable16BitTypes = false; bool HlslDX9compatible = false; +bool DumpBuiltinSymbols = false; std::vector IncludeDirectoryList; // Source environment @@ -494,6 +495,8 @@ void ProcessArguments(std::vector>& workItem Error("--client expects vulkan100 or opengl100"); } bumpArg(); + } else if (lowerword == "dump-builtin-symbols") { + DumpBuiltinSymbols = true; } else if (lowerword == "entry-point") { entryPointName = argv[1]; if (argc <= 1) @@ -833,6 +836,8 @@ void SetMessageOptions(EShMessages& messages) messages = (EShMessages)(messages | EShMsgHlslLegalization); if (HlslDX9compatible) messages = (EShMessages)(messages | EShMsgHlslDX9Compatible); + if (DumpBuiltinSymbols) + messages = (EShMessages)(messages | EShMsgBuiltinSymbolTable); } // @@ -1520,6 +1525,7 @@ void usage() " --auto-map-locations | --aml automatically locate input/output lacking\n" " 'location' (fragile, not cross stage)\n" " --client {vulkan|opengl} see -V and -G\n" + " --dump-builtin-symbols prints builtin symbol table prior each compile\n" " -dumpfullversion | -dumpversion print bare major.minor.patchlevel\n" " --flatten-uniform-arrays | --fua flatten uniform texture/sampler arrays to\n" " scalars\n" diff --git a/glslang/Include/Types.h b/glslang/Include/Types.h index d0d9b604a3..90341dcb27 100644 --- a/glslang/Include/Types.h +++ b/glslang/Include/Types.h @@ -2018,7 +2018,7 @@ class TType { } // Add struct/block members - if (isStruct()) { + if (isStruct() && structure) { appendStr("{"); for (size_t i = 0; i < structure->size(); ++i) { if (! (*structure)[i].type->hiddenMember()) { diff --git a/glslang/MachineIndependent/ShaderLang.cpp b/glslang/MachineIndependent/ShaderLang.cpp index adfe5344a1..6f9db0195c 100755 --- a/glslang/MachineIndependent/ShaderLang.cpp +++ b/glslang/MachineIndependent/ShaderLang.cpp @@ -377,6 +377,8 @@ bool InitializeSymbolTables(TInfoSink& infoSink, TSymbolTable** commonTable, TS infoSink, commonTable, symbolTables); #endif + + return true; } @@ -474,6 +476,16 @@ void SetupBuiltinSymbolTable(int version, EProfile profile, const SpvVersion& sp glslang::ReleaseGlobalLock(); } +// Function to Print all builtins +void DumpBuiltinSymbolTable(TInfoSink& infoSink, const TSymbolTable& symbolTable) +{ + infoSink.debug << "BuiltinSymbolTable {\n"; + + symbolTable.dump(infoSink, true); + + infoSink.debug << "}\n"; +} + // Return true if the shader was correctly specified for version/profile/stage. bool DeduceVersionProfile(TInfoSink& infoSink, EShLanguage stage, bool versionNotFirst, int defaultVersion, EShSource source, int& version, EProfile& profile, const SpvVersion& spvVersion) @@ -905,6 +917,9 @@ bool ProcessDeferred( return false; } + if (messages & EShMsgBuiltinSymbolTable) + DumpBuiltinSymbolTable(compiler->infoSink, *symbolTable); + // // Now we can process the full shader under proper symbols and rules. // diff --git a/glslang/MachineIndependent/SymbolTable.cpp b/glslang/MachineIndependent/SymbolTable.cpp index d8d68468be..c0a02e68a7 100755 --- a/glslang/MachineIndependent/SymbolTable.cpp +++ b/glslang/MachineIndependent/SymbolTable.cpp @@ -176,37 +176,77 @@ void TType::buildMangledName(TString& mangledName) const // 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 ¶m = 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 complete) 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); } } diff --git a/glslang/MachineIndependent/SymbolTable.h b/glslang/MachineIndependent/SymbolTable.h index f9c1903475..f3873cff02 100755 --- a/glslang/MachineIndependent/SymbolTable.h +++ b/glslang/MachineIndependent/SymbolTable.h @@ -116,7 +116,8 @@ class TSymbol { } virtual int getNumExtensions() const { return extensions == nullptr ? 0 : (int)extensions->size(); } virtual const char** getExtensions() const { return extensions->data(); } - virtual void dump(TInfoSink &infoSink) const = 0; + virtual void dump(TInfoSink& infoSink, bool complete = false) const = 0; + void dumpExtensions(TInfoSink& infoSink) const; virtual bool isReadOnly() const { return ! writable; } virtual void makeReadOnly() { writable = false; } @@ -192,7 +193,7 @@ class TVariable : public TSymbol { } virtual const char** getMemberExtensions(int member) const { return (*memberExtensions)[member].data(); } - virtual void dump(TInfoSink &infoSink) const; + virtual void dump(TInfoSink& infoSink, bool complete = false) const; protected: explicit TVariable(const TVariable&); @@ -313,7 +314,7 @@ class TFunction : public TSymbol { virtual TParameter& operator[](int i) { assert(writable); return parameters[i]; } virtual const TParameter& operator[](int i) const { return parameters[i]; } - virtual void dump(TInfoSink &infoSink) const override; + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; protected: explicit TFunction(const TFunction&); @@ -373,7 +374,7 @@ class TAnonMember : public TSymbol { virtual const char** getExtensions() const override { return anonContainer.getMemberExtensions(memberNumber); } virtual int getAnonId() const { return anonId; } - virtual void dump(TInfoSink &infoSink) const override; + virtual void dump(TInfoSink& infoSink, bool complete = false) const override; protected: explicit TAnonMember(const TAnonMember&); @@ -541,7 +542,7 @@ class TSymbolTableLevel { void relateToOperator(const char* name, TOperator op); void setFunctionExtensions(const char* name, int num, const char* const extensions[]); - void dump(TInfoSink &infoSink) const; + void dump(TInfoSink& infoSink, bool complete = false) const; TSymbolTableLevel* clone() const; void readOnly(); @@ -842,7 +843,7 @@ class TSymbolTable { } int getMaxSymbolId() { return uniqueId; } - void dump(TInfoSink &infoSink) const; + void dump(TInfoSink& infoSink, bool complete = false) const; void copyTable(const TSymbolTable& copyOf); void setPreviousDefaultPrecisions(TPrecisionQualifier *p) { table[currentLevel()]->setPreviousDefaultPrecisions(p); } diff --git a/glslang/Public/ShaderLang.h b/glslang/Public/ShaderLang.h index 0c2556976d..d6b0bc9d55 100755 --- a/glslang/Public/ShaderLang.h +++ b/glslang/Public/ShaderLang.h @@ -234,6 +234,7 @@ enum EShMessages { EShMsgHlslEnable16BitTypes = (1 << 11), // enable use of 16-bit types in SPIR-V for HLSL EShMsgHlslLegalization = (1 << 12), // enable HLSL Legalization messages EShMsgHlslDX9Compatible = (1 << 13), // enable HLSL DX9 compatible mode (right now only for samplers) + EShMsgBuiltinSymbolTable = (1 << 14), // print the builtin symbol table }; //