1 // Copyright 2015 The Shaderc Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef LIBSHADERC_UTIL_COUNTING_INCLUDER_H 16 #define LIBSHADERC_UTIL_COUNTING_INCLUDER_H 17 18 #include <atomic> 19 20 #include "glslang/Public/ShaderLang.h" 21 22 namespace shaderc_util { 23 24 // An Includer that counts how many #include directives it saw. 25 class CountingIncluder : public glslang::TShader::Includer { 26 public: 27 // Done as .store(0) instead of in the initializer list for the following 28 // reasons: 29 // Clang > 3.6 will complain about it if it is written as ({0}). 30 // VS2013 fails if it is written as {0}. 31 // G++-4.8 does not correctly support std::atomic_init. 32 CountingIncluder() { 33 num_include_directives_.store(0); 34 } 35 36 enum class IncludeType { 37 System, // Only do < > include search 38 Local, // Only do " " include search 39 }; 40 41 // Resolves an include request for a source by name, type, and name of the 42 // requesting source. For the semantics of the result, see the base class. 43 // Also increments num_include_directives and returns the results of 44 // include_delegate(filename). Subclasses should override include_delegate() 45 // instead of this method. 46 glslang::TShader::Includer::IncludeResult* includeSystem( 47 const char* requested_source, const char* requesting_source, 48 size_t include_depth) final { 49 ++num_include_directives_; 50 return include_delegate(requested_source, requesting_source, 51 IncludeType::System, include_depth); 52 } 53 54 // Like includeSystem, but for "local" include search. 55 glslang::TShader::Includer::IncludeResult* includeLocal( 56 const char* requested_source, const char* requesting_source, 57 size_t include_depth) final { 58 ++num_include_directives_; 59 return include_delegate(requested_source, requesting_source, 60 IncludeType::Local, include_depth); 61 } 62 63 // Releases the given IncludeResult. 64 void releaseInclude(glslang::TShader::Includer::IncludeResult* result) final { 65 release_delegate(result); 66 } 67 68 int num_include_directives() const { return num_include_directives_.load(); } 69 70 private: 71 72 // Invoked by this class to provide results to 73 // glslang::TShader::Includer::include. 74 virtual glslang::TShader::Includer::IncludeResult* include_delegate( 75 const char* requested_source, const char* requesting_source, 76 IncludeType type, size_t include_depth) = 0; 77 78 // Release the given IncludeResult. 79 virtual void release_delegate( 80 glslang::TShader::Includer::IncludeResult* result) = 0; 81 82 // The number of #include directive encountered. 83 std::atomic_int num_include_directives_; 84 }; 85 } 86 87 #endif // LIBSHADERC_UTIL_COUNTING_INCLUDER_H 88