1#include "clang/Sema/SemaBase.h"
2#include "clang/Sema/Sema.h"
3#include "clang/Sema/SemaCUDA.h"
4
5namespace clang {
6
7SemaBase::SemaBase(Sema &S) : SemaRef(S) {}
8
9ASTContext &SemaBase::getASTContext() const { return SemaRef.Context; }
10DiagnosticsEngine &SemaBase::getDiagnostics() const { return SemaRef.Diags; }
11const LangOptions &SemaBase::getLangOpts() const { return SemaRef.LangOpts; }
12
13SemaBase::ImmediateDiagBuilder::~ImmediateDiagBuilder() {
14 // If we aren't active, there is nothing to do.
15 if (!isActive())
16 return;
17
18 // Otherwise, we need to emit the diagnostic. First clear the diagnostic
19 // builder itself so it won't emit the diagnostic in its own destructor.
20 //
21 // This seems wasteful, in that as written the DiagnosticBuilder dtor will
22 // do its own needless checks to see if the diagnostic needs to be
23 // emitted. However, because we take care to ensure that the builder
24 // objects never escape, a sufficiently smart compiler will be able to
25 // eliminate that code.
26 Clear();
27
28 // Dispatch to Sema to emit the diagnostic.
29 SemaRef.EmitCurrentDiagnostic(DiagID);
30}
31
32const SemaBase::SemaDiagnosticBuilder &
33operator<<(const SemaBase::SemaDiagnosticBuilder &Diag,
34 const PartialDiagnostic &PD) {
35 if (Diag.ImmediateDiag)
36 PD.Emit(DB: *Diag.ImmediateDiag);
37 else if (Diag.PartialDiagId)
38 Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD;
39 return Diag;
40}
41
42void SemaBase::SemaDiagnosticBuilder::AddFixItHint(
43 const FixItHint &Hint) const {
44 if (ImmediateDiag)
45 ImmediateDiag->AddFixItHint(Hint);
46 else if (PartialDiagId)
47 S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint);
48}
49
50llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
51 std::vector<PartialDiagnosticAt>> &
52SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const {
53 return S.DeviceDeferredDiags;
54}
55
56Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID,
57 bool DeferHint) {
58 bool IsError =
59 getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID);
60 bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag &&
61 DiagnosticIDs::isDeferrable(DiagID) &&
62 (DeferHint || SemaRef.DeferDiags || !IsError);
63 auto SetIsLastErrorImmediate = [&](bool Flag) {
64 if (IsError)
65 SemaRef.IsLastErrorImmediate = Flag;
66 };
67 if (!ShouldDefer) {
68 SetIsLastErrorImmediate(true);
69 return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc,
70 DiagID, SemaRef.getCurFunctionDecl(), SemaRef);
71 }
72
73 SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice
74 ? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID)
75 : SemaRef.CUDA().DiagIfHostCode(Loc, DiagID);
76 SetIsLastErrorImmediate(DB.isImmediate());
77 return DB;
78}
79
80Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,
81 const PartialDiagnostic &PD,
82 bool DeferHint) {
83 return Diag(Loc, DiagID: PD.getDiagID(), DeferHint) << PD;
84}
85
86} // namespace clang
87

source code of clang/lib/Sema/SemaBase.cpp