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