blob: b16cae482153a99fbe135c6a57f6b20b2a949ef5 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
|
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file contains the declaration of TrapReasonBuilder and related classes.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_CODEGEN_TRAP_REASON_BUILDER_H
#define LLVM_CLANG_CODEGEN_TRAP_REASON_BUILDER_H
#include "clang/Basic/Diagnostic.h"
namespace clang {
namespace CodeGen {
/// Helper class for \class TrapReasonBuilder. \class TrapReason stores the
/// "trap reason" built by \class TrapReasonBuilder. This consists of
/// a trap message and trap category.
///
/// It is intended that this object be allocated on the stack.
class TrapReason {
public:
TrapReason() = default;
/// \return The trap message. Note the lifetime of the underlying storage for
/// the returned StringRef lives in this class which means the returned
/// StringRef should not be used after this class is destroyed.
StringRef getMessage() const { return Message; }
/// \return the trap category (e.g. "Undefined Behavior Sanitizer")
StringRef getCategory() const { return Category; }
bool isEmpty() const {
// Note both Message and Category are checked because it is legitimate for
// the Message to be empty but for the Category to be non-empty when the
// trap category is known but the specific reason is not available during
// codegen.
return Message.size() == 0 && Category.size() == 0;
}
private:
llvm::SmallString<64> Message;
// The Category doesn't need its own storage because the StringRef points
// to a global constant string.
StringRef Category;
// Only this class can set the private fields.
friend class TrapReasonBuilder;
};
/// Class to make it convenient to initialize TrapReason objects which can be
/// used to attach the "trap reason" to trap instructions.
///
/// Although this class inherits from \class DiagnosticBuilder it has slightly
/// different semantics.
///
/// * This class should only be used with trap diagnostics (declared in
/// `DiagnosticTrapKinds.td`).
/// * The `TrapReasonBuilder` does not emit diagnostics to the normal
/// diagnostics consumers on destruction like normal Diagnostic builders.
/// Instead on destruction it assigns to the TrapReason object passed into
/// the constructor.
///
/// Given that this class inherits from `DiagnosticBuilder` it inherits all of
/// its abilities to format diagnostic messages and consume various types in
/// class (e.g. Type, Exprs, etc.). This makes it particularly suited to
/// printing types and expressions from the AST while codegen-ing runtime
/// checks.
///
///
/// Example use via the `CodeGenModule::BuildTrapReason` helper.
///
/// \code
/// {
/// TrapReason TR;
/// CGM.BuildTrapReason(diag::trap_diagnostic, TR) << 0 << SomeExpr;
/// consume(&TR);
/// }
/// \endcode
///
///
class TrapReasonBuilder : public DiagnosticBuilder {
public:
TrapReasonBuilder(DiagnosticsEngine *DiagObj, unsigned DiagID,
TrapReason &TR);
~TrapReasonBuilder();
// Prevent accidentally copying or assigning
TrapReasonBuilder &operator=(const TrapReasonBuilder &) = delete;
TrapReasonBuilder &operator=(const TrapReasonBuilder &&) = delete;
TrapReasonBuilder(const TrapReasonBuilder &) = delete;
TrapReasonBuilder(const TrapReasonBuilder &&) = delete;
private:
/// \return Format the trap message into `Storage`.
void getMessage(SmallVectorImpl<char> &Storage);
/// \return Return the trap category. These are the `CategoryName` property
/// of `trap` diagnostics declared in `DiagnosticTrapKinds.td`.
StringRef getCategory();
private:
TrapReason &TR;
};
} // namespace CodeGen
} // namespace clang
#endif
|