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