clang 19.0.0git
SemaBase.h
Go to the documentation of this file.
1//===--- SemaBase.h - Common utilities for semantic analysis-----*- 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// This file defines the SemaBase class, which provides utilities for Sema
10// and its parts like SemaOpenACC.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_CLANG_SEMA_SEMABASE_H
15#define LLVM_CLANG_SEMA_SEMABASE_H
16
17#include "clang/AST/Decl.h"
23#include "llvm/ADT/DenseMap.h"
24#include <optional>
25#include <type_traits>
26#include <utility>
27#include <vector>
28
29namespace clang {
30
31class ASTContext;
32class DiagnosticsEngine;
33class LangOptions;
34class Sema;
35
36class SemaBase {
37public:
38 SemaBase(Sema &S);
39
41
44 const LangOptions &getLangOpts() const;
45
46 /// Helper class that creates diagnostics with optional
47 /// template instantiation stacks.
48 ///
49 /// This class provides a wrapper around the basic DiagnosticBuilder
50 /// class that emits diagnostics. ImmediateDiagBuilder is
51 /// responsible for emitting the diagnostic (as DiagnosticBuilder
52 /// does) and, if the diagnostic comes from inside a template
53 /// instantiation, printing the template instantiation stack as
54 /// well.
56 Sema &SemaRef;
57 unsigned DiagID;
58
59 public:
60 ImmediateDiagBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
61 : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
62 ImmediateDiagBuilder(DiagnosticBuilder &&DB, Sema &SemaRef, unsigned DiagID)
63 : DiagnosticBuilder(DB), SemaRef(SemaRef), DiagID(DiagID) {}
64
65 // This is a cunning lie. DiagnosticBuilder actually performs move
66 // construction in its copy constructor (but due to varied uses, it's not
67 // possible to conveniently express this as actual move construction). So
68 // the default copy ctor here is fine, because the base class disables the
69 // source anyway, so the user-defined ~ImmediateDiagBuilder is a safe no-op
70 // in that case anwyay.
72
74
75 /// Teach operator<< to produce an object of the correct type.
76 template <typename T>
77 friend const ImmediateDiagBuilder &
79 const DiagnosticBuilder &BaseDiag = Diag;
80 BaseDiag << Value;
81 return Diag;
82 }
83
84 // It is necessary to limit this to rvalue reference to avoid calling this
85 // function with a bitfield lvalue argument since non-const reference to
86 // bitfield is not allowed.
87 template <typename T,
88 typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
90 const DiagnosticBuilder &BaseDiag = *this;
91 BaseDiag << std::move(V);
92 return *this;
93 }
94 };
95
96 /// A generic diagnostic builder for errors which may or may not be deferred.
97 ///
98 /// In CUDA, there exist constructs (e.g. variable-length arrays, try/catch)
99 /// which are not allowed to appear inside __device__ functions and are
100 /// allowed to appear in __host__ __device__ functions only if the host+device
101 /// function is never codegen'ed.
102 ///
103 /// To handle this, we use the notion of "deferred diagnostics", where we
104 /// attach a diagnostic to a FunctionDecl that's emitted iff it's codegen'ed.
105 ///
106 /// This class lets you emit either a regular diagnostic, a deferred
107 /// diagnostic, or no diagnostic at all, according to an argument you pass to
108 /// its constructor, thus simplifying the process of creating these "maybe
109 /// deferred" diagnostics.
111 public:
112 enum Kind {
113 /// Emit no diagnostics.
115 /// Emit the diagnostic immediately (i.e., behave like Sema::Diag()).
117 /// Emit the diagnostic immediately, and, if it's a warning or error, also
118 /// emit a call stack showing how this function can be reached by an a
119 /// priori known-emitted function.
121 /// Create a deferred diagnostic, which is emitted only if the function
122 /// it's attached to is codegen'ed. Also emit a call stack as with
123 /// K_ImmediateWithCallStack.
125 };
126
128 const FunctionDecl *Fn, Sema &S);
131
132 // The copy and move assignment operator is defined as deleted pending
133 // further motivation.
136
138
139 bool isImmediate() const { return ImmediateDiag.has_value(); }
140
141 /// Convertible to bool: True if we immediately emitted an error, false if
142 /// we didn't emit an error or we created a deferred error.
143 ///
144 /// Example usage:
145 ///
146 /// if (SemaDiagnosticBuilder(...) << foo << bar)
147 /// return ExprError();
148 ///
149 /// But see DiagIfDeviceCode() and DiagIfHostCode() -- you probably
150 /// want to use these instead of creating a SemaDiagnosticBuilder yourself.
151 operator bool() const { return isImmediate(); }
152
153 template <typename T>
156 if (Diag.ImmediateDiag)
157 *Diag.ImmediateDiag << Value;
158 else if (Diag.PartialDiagId)
159 Diag.getDeviceDeferredDiags()[Diag.Fn][*Diag.PartialDiagId].second
160 << Value;
161 return Diag;
162 }
163
164 // It is necessary to limit this to rvalue reference to avoid calling this
165 // function with a bitfield lvalue argument since non-const reference to
166 // bitfield is not allowed.
167 template <typename T,
168 typename = std::enable_if_t<!std::is_lvalue_reference<T>::value>>
170 if (ImmediateDiag)
171 *ImmediateDiag << std::move(V);
172 else if (PartialDiagId)
173 getDeviceDeferredDiags()[Fn][*PartialDiagId].second << std::move(V);
174 return *this;
175 }
176
177 friend const SemaDiagnosticBuilder &
179
180 void AddFixItHint(const FixItHint &Hint) const;
181
183 return ExprError();
184 }
186 return StmtError();
187 }
188 operator ExprResult() const { return ExprError(); }
189 operator StmtResult() const { return StmtError(); }
190 operator TypeResult() const { return TypeError(); }
191 operator DeclResult() const { return DeclResult(true); }
192 operator MemInitResult() const { return MemInitResult(true); }
193
195 llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
196 std::vector<PartialDiagnosticAt>>;
197
198 private:
199 Sema &S;
200 SourceLocation Loc;
201 unsigned DiagID;
202 const FunctionDecl *Fn;
203 bool ShowCallStack;
204
205 // Invariant: At most one of these Optionals has a value.
206 // FIXME: Switch these to a Variant once that exists.
207 std::optional<ImmediateDiagBuilder> ImmediateDiag;
208 std::optional<unsigned> PartialDiagId;
209
210 DeferredDiagnosticsType &getDeviceDeferredDiags() const;
211 };
212
213 /// Emit a diagnostic.
214 SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID,
215 bool DeferHint = false);
216
217 /// Emit a partial diagnostic.
219 bool DeferHint = false);
220};
221
222} // namespace clang
223
224#endif
#define V(N, I)
Definition: ASTContext.h:3284
Defines the Diagnostic-related interfaces.
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
Defines the clang::SourceLocation class and associated facilities.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
A little helper class used to produce diagnostics.
Definition: Diagnostic.h:1271
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:192
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
Definition: Diagnostic.h:71
Represents a function declaration or definition.
Definition: Decl.h:1971
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:461
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: SemaBase.h:55
ImmediateDiagBuilder(DiagnosticBuilder &&DB, Sema &SemaRef, unsigned DiagID)
Definition: SemaBase.h:62
ImmediateDiagBuilder(const ImmediateDiagBuilder &)=default
const ImmediateDiagBuilder & operator<<(T &&V) const
Definition: SemaBase.h:89
friend const ImmediateDiagBuilder & operator<<(const ImmediateDiagBuilder &Diag, const T &Value)
Teach operator<< to produce an object of the correct type.
Definition: SemaBase.h:78
ImmediateDiagBuilder(DiagnosticBuilder &DB, Sema &SemaRef, unsigned DiagID)
Definition: SemaBase.h:60
A generic diagnostic builder for errors which may or may not be deferred.
Definition: SemaBase.h:110
SemaDiagnosticBuilder(const SemaDiagnosticBuilder &)=default
@ K_Deferred
Create a deferred diagnostic, which is emitted only if the function it's attached to is codegen'ed.
Definition: SemaBase.h:124
@ K_ImmediateWithCallStack
Emit the diagnostic immediately, and, if it's a warning or error, also emit a call stack showing how ...
Definition: SemaBase.h:120
@ K_Immediate
Emit the diagnostic immediately (i.e., behave like Sema::Diag()).
Definition: SemaBase.h:116
void AddFixItHint(const FixItHint &Hint) const
Definition: SemaBase.cpp:42
friend const SemaDiagnosticBuilder & operator<<(const SemaDiagnosticBuilder &Diag, const T &Value)
Definition: SemaBase.h:155
SemaDiagnosticBuilder(Kind K, SourceLocation Loc, unsigned DiagID, const FunctionDecl *Fn, Sema &S)
friend StmtResult StmtError(const SemaDiagnosticBuilder &)
Definition: SemaBase.h:185
llvm::DenseMap< CanonicalDeclPtr< const FunctionDecl >, std::vector< PartialDiagnosticAt > > DeferredDiagnosticsType
Definition: SemaBase.h:196
const SemaDiagnosticBuilder & operator<<(T &&V) const
Definition: SemaBase.h:169
SemaDiagnosticBuilder & operator=(const SemaDiagnosticBuilder &)=delete
friend ExprResult ExprError(const SemaDiagnosticBuilder &)
Definition: SemaBase.h:182
SemaDiagnosticBuilder & operator=(SemaDiagnosticBuilder &&)=delete
SemaDiagnosticBuilder(SemaDiagnosticBuilder &&D)
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition: SemaBase.cpp:56
ASTContext & getASTContext() const
Definition: SemaBase.cpp:9
Sema & SemaRef
Definition: SemaBase.h:40
const LangOptions & getLangOpts() const
Definition: SemaBase.cpp:11
DiagnosticsEngine & getDiagnostics() const
Definition: SemaBase.cpp:10
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:457
Encodes a location in the source.
The JSON file list parser is used to communicate input to InstallAPI.
TypeResult TypeError()
Definition: Ownership.h:266
ActionResult< CXXCtorInitializer * > MemInitResult
Definition: Ownership.h:252
ActionResult< Expr * > ExprResult
Definition: Ownership.h:248
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:249
ActionResult< ParsedType > TypeResult
Definition: Ownership.h:250
const FunctionProtoType * T
ActionResult< Decl * > DeclResult
Definition: Ownership.h:254
#define bool
Definition: stdbool.h:20