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