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