blob: e01255804c8faddfa9b0f90859fc7af8f5a0506d [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
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
Geoff Lang0a73dd82014-11-19 16:18:08 -05007#ifndef COMPILER_TRANSLATOR_INFOSINK_H_
8#define COMPILER_TRANSLATOR_INFOSINK_H_
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00009
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000010#include <math.h>
Jamie Madilld7f21352013-10-30 17:53:15 -040011#include <stdlib.h>
Geoff Lang17732822013-08-29 13:46:49 -040012#include "compiler/translator/Common.h"
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000013
Jamie Madill45bcc782016-11-07 13:58:48 -050014namespace sh
15{
16
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000017// Returns the fractional part of the given floating-point number.
Jamie Madilld7b1ab52016-12-12 14:42:19 -050018inline float fractionalPart(float f)
19{
20 float intPart = 0.0f;
21 return modff(f, &intPart);
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000022}
23
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024//
25// TPrefixType is used to centralize how info log messages start.
26// See below.
27//
Jamie Madilld7b1ab52016-12-12 14:42:19 -050028enum TPrefixType
29{
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030 EPrefixNone,
31 EPrefixWarning,
32 EPrefixError,
33 EPrefixInternalError,
34 EPrefixUnimplemented,
35 EPrefixNote
36};
37
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000038//
39// Encapsulate info logs for all objects that have them.
40//
41// The methods are a general set of tools for getting a variety of
42// messages and types inserted into the log.
43//
Jamie Madilld7b1ab52016-12-12 14:42:19 -050044class TInfoSinkBase
45{
46 public:
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000047 TInfoSinkBase() {}
48
49 template <typename T>
Jamie Madilld7b1ab52016-12-12 14:42:19 -050050 TInfoSinkBase &operator<<(const T &t)
51 {
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000052 TPersistStringStream stream;
53 stream << t;
54 sink.append(stream.str());
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000055 return *this;
56 }
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000057 // Override << operator for specific types. It is faster to append strings
58 // and characters directly to the sink.
Jamie Madilld7b1ab52016-12-12 14:42:19 -050059 TInfoSinkBase &operator<<(char c)
60 {
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000061 sink.append(1, c);
62 return *this;
63 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -050064 TInfoSinkBase &operator<<(const char *str)
65 {
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000066 sink.append(str);
67 return *this;
68 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -050069 TInfoSinkBase &operator<<(const TPersistString &str)
70 {
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000071 sink.append(str);
72 return *this;
73 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -050074 TInfoSinkBase &operator<<(const TString &str)
75 {
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000076 sink.append(str.c_str());
77 return *this;
78 }
79 // Make sure floats are written with correct precision.
Jamie Madilld7b1ab52016-12-12 14:42:19 -050080 TInfoSinkBase &operator<<(float f)
81 {
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000082 // Make sure that at least one decimal point is written. If a number
83 // does not have a fractional part, the default precision format does
84 // not write the decimal portion which gets interpreted as integer by
85 // the compiler.
86 TPersistStringStream stream;
Jamie Madilld7b1ab52016-12-12 14:42:19 -050087 if (fractionalPart(f) == 0.0f)
88 {
daniel@transgaming.comb0a1dcc2010-06-07 02:06:26 +000089 stream.precision(1);
90 stream << std::showpoint << std::fixed << f;
Jamie Madilld7b1ab52016-12-12 14:42:19 -050091 }
92 else
93 {
daniel@transgaming.comb0a1dcc2010-06-07 02:06:26 +000094 stream.unsetf(std::ios::fixed);
95 stream.unsetf(std::ios::scientific);
96 stream.precision(8);
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000097 stream << f;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000098 }
alokp@chromium.org4e4facd2010-06-02 15:21:22 +000099 sink.append(stream.str());
100 return *this;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101 }
alokp@chromium.org4e4facd2010-06-02 15:21:22 +0000102 // Write boolean values as their names instead of integral value.
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500103 TInfoSinkBase &operator<<(bool b)
104 {
105 const char *str = b ? "true" : "false";
alokp@chromium.org4e4facd2010-06-02 15:21:22 +0000106 sink.append(str);
107 return *this;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108 }
109
alokp@chromium.org4e4facd2010-06-02 15:21:22 +0000110 void erase() { sink.clear(); }
alokp@chromium.org7beea402010-09-15 21:18:34 +0000111 int size() { return static_cast<int>(sink.size()); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500113 const TPersistString &str() const { return sink; }
114 const char *c_str() const { return sink.c_str(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115
Jamie Madill075edd82013-07-08 13:30:19 -0400116 void prefix(TPrefixType p);
117 void location(int file, int line);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500118 void location(const TSourceLoc &loc);
119 void message(TPrefixType p, const TSourceLoc &loc, const char *m);
alokp@chromium.org4e4facd2010-06-02 15:21:22 +0000120
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500121 private:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122 TPersistString sink;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123};
124
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500125class TInfoSink
126{
127 public:
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000128 TInfoSinkBase info;
129 TInfoSinkBase debug;
130 TInfoSinkBase obj;
131};
132
Jamie Madill45bcc782016-11-07 13:58:48 -0500133} // namespace sh
134
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500135#endif // COMPILER_TRANSLATOR_INFOSINK_H_