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