File indexing completed on 2026-05-10 08:37:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_SEMA_SEMABASE_H
0015 #define LLVM_CLANG_SEMA_SEMABASE_H
0016
0017 #include "clang/AST/Decl.h"
0018 #include "clang/AST/Redeclarable.h"
0019 #include "clang/Basic/Diagnostic.h"
0020 #include "clang/Basic/PartialDiagnostic.h"
0021 #include "clang/Basic/SourceLocation.h"
0022 #include "clang/Sema/Ownership.h"
0023 #include "llvm/ADT/DenseMap.h"
0024 #include <optional>
0025 #include <type_traits>
0026 #include <utility>
0027 #include <vector>
0028
0029 namespace clang {
0030
0031 class ASTContext;
0032 class DiagnosticsEngine;
0033 class LangOptions;
0034 class Sema;
0035
0036 class SemaBase {
0037 public:
0038 SemaBase(Sema &S);
0039
0040 Sema &SemaRef;
0041
0042 ASTContext &getASTContext() const;
0043 DiagnosticsEngine &getDiagnostics() const;
0044 const LangOptions &getLangOpts() const;
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 class ImmediateDiagBuilder : public DiagnosticBuilder {
0056 Sema &SemaRef;
0057 unsigned DiagID;
0058
0059 public:
0060 ImmediateDiagBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
0061 : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
0062 ImmediateDiagBuilder(DiagnosticBuilder &&DB, Sema &SemaRef, unsigned DiagID)
0063 : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
0064
0065
0066
0067
0068
0069
0070
0071 ImmediateDiagBuilder(const ImmediateDiagBuilder &) = default;
0072
0073 ~ImmediateDiagBuilder();
0074
0075
0076 template <typename T>
0077 friend const ImmediateDiagBuilder &
0078 operator<<(const ImmediateDiagBuilder &Diag, const T &Value) {
0079 const DiagnosticBuilder &BaseDiag = Diag;
0080 BaseDiag << Value;
0081 return Diag;
0082 }
0083
0084
0085
0086
0087 template <typename T,
0088 typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
0089 const ImmediateDiagBuilder &operator<<(T &&V) const {
0090 const DiagnosticBuilder &BaseDiag = *this;
0091 BaseDiag << std::move(V);
0092 return *this;
0093 }
0094 };
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 class SemaDiagnosticBuilder {
0111 public:
0112 enum Kind {
0113
0114 K_Nop,
0115
0116 K_Immediate,
0117
0118
0119
0120 K_ImmediateWithCallStack,
0121
0122
0123
0124 K_Deferred
0125 };
0126
0127 SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID,
0128 const FunctionDecl *Fn, Sema &S);
0129 SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D);
0130 SemaDiagnosticBuilder(const SemaDiagnosticBuilder &) = default;
0131
0132
0133
0134 SemaDiagnosticBuilder &operator=(const SemaDiagnosticBuilder &) = delete;
0135 SemaDiagnosticBuilder &operator=(SemaDiagnosticBuilder &&) = delete;
0136
0137 ~SemaDiagnosticBuilder();
0138
0139 bool isImmediate() const { return ImmediateDiag.has_value(); }
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150
0151 operator bool() const { return isImmediate(); }
0152
0153 template <typename T>
0154 friend const SemaDiagnosticBuilder &
0155 operator<<(const SemaDiagnosticBuilder &Diag, const T &Value) {
0156 if (Diag.ImmediateDiag)
0157 *Diag.ImmediateDiag << Value;
0158 else if (Diag.PartialDiagId)
0159 Diag.getDeviceDeferredDiags()[Diag.Fn][*Diag.PartialDiagId].second
0160 << Value;
0161 return Diag;
0162 }
0163
0164
0165
0166
0167 template <typename T,
0168 typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
0169 const SemaDiagnosticBuilder &operator<<(T &&V) const {
0170 if (ImmediateDiag)
0171 *ImmediateDiag << std::move(V);
0172 else if (PartialDiagId)
0173 getDeviceDeferredDiags()[Fn][*PartialDiagId].second << std::move(V);
0174 return *this;
0175 }
0176
0177 friend const SemaDiagnosticBuilder &
0178 operator<<(const SemaDiagnosticBuilder &Diag, const PartialDiagnostic &PD);
0179
0180 void AddFixItHint(const FixItHint &Hint) const;
0181
0182 friend ExprResult ExprError(const SemaDiagnosticBuilder &) {
0183 return ExprError();
0184 }
0185 friend StmtResult StmtError(const SemaDiagnosticBuilder &) {
0186 return StmtError();
0187 }
0188 operator ExprResult() const { return ExprError(); }
0189 operator StmtResult() const { return StmtError(); }
0190 operator TypeResult() const { return TypeError(); }
0191 operator DeclResult() const { return DeclResult(true); }
0192 operator MemInitResult() const { return MemInitResult(true); }
0193
0194 using DeferredDiagnosticsType =
0195 llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
0196 std::vector<PartialDiagnosticAt>>;
0197
0198 private:
0199 Sema &S;
0200 SourceLocation Loc;
0201 unsigned DiagID;
0202 const FunctionDecl *Fn;
0203 bool ShowCallStack;
0204
0205
0206
0207 std::optional<ImmediateDiagBuilder> ImmediateDiag;
0208 std::optional<unsigned> PartialDiagId;
0209
0210 DeferredDiagnosticsType &getDeviceDeferredDiags() const;
0211 };
0212
0213
0214 SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID,
0215 bool DeferHint = false);
0216
0217
0218 SemaDiagnosticBuilder Diag(SourceLocation Loc, const PartialDiagnostic &PD,
0219 bool DeferHint = false);
0220
0221
0222 PartialDiagnostic PDiag(unsigned DiagID = 0);
0223 };
0224
0225 }
0226
0227 #endif