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