xref: /aosp_15_r20/external/angle/src/compiler/translator/InfoSink.h (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 Worker inline 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