1 // 2 // Copyright 2002 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 #ifndef COMPILER_TRANSLATOR_INFOSINK_H_ 8 #define COMPILER_TRANSLATOR_INFOSINK_H_ 9 10 #include <cmath> 11 #include <stdlib.h> 12 #include "GLSLANG/ShaderLang.h" 13 #include "compiler/translator/Common.h" 14 #include "compiler/translator/Severity.h" 15 16 namespace sh 17 { 18 19 class ImmutableString; 20 class TType; 21 22 // Returns the fractional part of the given floating-point number. fractionalPart(float f)23inline float fractionalPart(float f) 24 { 25 float intPart = 0.0f; 26 return modff(f, &intPart); 27 } 28 29 class ImmutableString; 30 31 // 32 // Encapsulate info logs for all objects that have them. 33 // 34 // The methods are a general set of tools for getting a variety of 35 // messages and types inserted into the log. 36 // 37 class TInfoSinkBase 38 { 39 public: TInfoSinkBase()40 TInfoSinkBase() {} 41 42 template <typename T> 43 TInfoSinkBase &operator<<(const T &t) 44 { 45 TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>(); 46 stream << t; 47 sink.append(stream.str()); 48 return *this; 49 } 50 // Override << operator for specific types. It is faster to append strings 51 // and characters directly to the sink. 52 TInfoSinkBase &operator<<(char c) 53 { 54 sink.append(1, c); 55 return *this; 56 } 57 TInfoSinkBase &operator<<(const char *str) 58 { 59 sink.append(str); 60 return *this; 61 } 62 TInfoSinkBase &operator<<(const TPersistString &str) 63 { 64 sink.append(str); 65 return *this; 66 } 67 TInfoSinkBase &operator<<(const TString &str) 68 { 69 sink.append(str.c_str()); 70 return *this; 71 } 72 TInfoSinkBase &operator<<(const ImmutableString &str); 73 74 TInfoSinkBase &operator<<(const TType &type); 75 76 // Make sure floats are written with correct precision. 77 TInfoSinkBase &operator<<(float f) 78 { 79 // Make sure that at least one decimal point is written. If a number 80 // does not have a fractional part, the default precision format does 81 // not write the decimal portion which gets interpreted as integer by 82 // the compiler. 83 TPersistStringStream stream = sh::InitializeStream<TPersistStringStream>(); 84 if (fractionalPart(f) == 0.0f) 85 { 86 stream.precision(1); 87 stream << std::showpoint << std::fixed << f; 88 } 89 else 90 { 91 stream.unsetf(std::ios::fixed); 92 stream.unsetf(std::ios::scientific); 93 stream.precision(8); 94 stream << f; 95 } 96 sink.append(stream.str()); 97 return *this; 98 } 99 // Write boolean values as their names instead of integral value. 100 TInfoSinkBase &operator<<(bool b) 101 { 102 const char *str = b ? "true" : "false"; 103 sink.append(str); 104 return *this; 105 } 106 erase()107 void erase() 108 { 109 sink.clear(); 110 binarySink.clear(); 111 } size()112 int size() { return static_cast<int>(isBinary() ? binarySink.size() : sink.size()); } 113 str()114 const TPersistString &str() const 115 { 116 ASSERT(!isBinary()); 117 return sink; 118 } c_str()119 const char *c_str() const 120 { 121 ASSERT(!isBinary()); 122 return sink.c_str(); 123 } 124 125 void prefix(Severity severity); 126 void location(int file, int line); 127 isBinary()128 bool isBinary() const { return !binarySink.empty(); } setBinary(BinaryBlob && binary)129 void setBinary(BinaryBlob &&binary) { binarySink = std::move(binary); } getBinary()130 const BinaryBlob &getBinary() const 131 { 132 ASSERT(isBinary()); 133 return binarySink; 134 } 135 136 private: 137 // The data in the info sink is either in human readable form (|sink|) or binary (|binarySink|). 138 TPersistString sink; 139 BinaryBlob binarySink; 140 }; 141 142 class TInfoSink 143 { 144 public: 145 TInfoSinkBase info; 146 TInfoSinkBase debug; 147 TInfoSinkBase obj; 148 }; 149 150 } // namespace sh 151 152 #endif // COMPILER_TRANSLATOR_INFOSINK_H_ 153