OptionalDiagnostic.h revision 360784
1//===- OptionalDiagnostic.h - An optional diagnostic ------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// Implements a partial diagnostic which may not be emitted.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_AST_OPTIONALDIAGNOSTIC_H
15#define LLVM_CLANG_AST_OPTIONALDIAGNOSTIC_H
16
17#include "clang/AST/APValue.h"
18#include "clang/Basic/PartialDiagnostic.h"
19#include "llvm/ADT/APFloat.h"
20#include "llvm/ADT/APSInt.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/StringRef.h"
23
24namespace clang {
25
26/// A partial diagnostic which we might know in advance that we are not going
27/// to emit.
28class OptionalDiagnostic {
29  PartialDiagnostic *Diag;
30
31public:
32  explicit OptionalDiagnostic(PartialDiagnostic *Diag = nullptr) : Diag(Diag) {}
33
34  template <typename T> OptionalDiagnostic &operator<<(const T &v) {
35    if (Diag)
36      *Diag << v;
37    return *this;
38  }
39
40  OptionalDiagnostic &operator<<(const llvm::APSInt &I) {
41    if (Diag) {
42      SmallVector<char, 32> Buffer;
43      I.toString(Buffer);
44      *Diag << StringRef(Buffer.data(), Buffer.size());
45    }
46    return *this;
47  }
48
49  OptionalDiagnostic &operator<<(const llvm::APFloat &F) {
50    if (Diag) {
51      // FIXME: Force the precision of the source value down so we don't
52      // print digits which are usually useless (we don't really care here if
53      // we truncate a digit by accident in edge cases).  Ideally,
54      // APFloat::toString would automatically print the shortest
55      // representation which rounds to the correct value, but it's a bit
56      // tricky to implement. Could use std::to_chars.
57      unsigned precision = llvm::APFloat::semanticsPrecision(F.getSemantics());
58      precision = (precision * 59 + 195) / 196;
59      SmallVector<char, 32> Buffer;
60      F.toString(Buffer, precision);
61      *Diag << StringRef(Buffer.data(), Buffer.size());
62    }
63    return *this;
64  }
65
66  OptionalDiagnostic &operator<<(const APFixedPoint &FX) {
67    if (Diag) {
68      SmallVector<char, 32> Buffer;
69      FX.toString(Buffer);
70      *Diag << StringRef(Buffer.data(), Buffer.size());
71    }
72    return *this;
73  }
74};
75
76} // namespace clang
77
78#endif
79