1 #include "clang/Sema/SemaBase.h"
2 #include "clang/Sema/Sema.h"
3 #include "clang/Sema/SemaCUDA.h"
4
5 namespace clang {
6
SemaBase(Sema & S)7 SemaBase::SemaBase(Sema &S) : SemaRef(S) {}
8
getASTContext() const9 ASTContext &SemaBase::getASTContext() const { return SemaRef.Context; }
getDiagnostics() const10 DiagnosticsEngine &SemaBase::getDiagnostics() const { return SemaRef.Diags; }
getLangOpts() const11 const LangOptions &SemaBase::getLangOpts() const { return SemaRef.LangOpts; }
12
~ImmediateDiagBuilder()13 SemaBase::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
PDiag(unsigned DiagID)32 PartialDiagnostic SemaBase::PDiag(unsigned DiagID) {
33 return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator());
34 }
35
36 const SemaBase::SemaDiagnosticBuilder &
operator <<(const SemaBase::SemaDiagnosticBuilder & Diag,const PartialDiagnostic & PD)37 operator<<(const SemaBase::SemaDiagnosticBuilder &Diag,
38 const PartialDiagnostic &PD) {
39 if (Diag.ImmediateDiag)
40 PD.Emit(*Diag.ImmediateDiag);
41 else if (Diag.PartialDiagId)
42 Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD;
43 return Diag;
44 }
45
AddFixItHint(const FixItHint & Hint) const46 void SemaBase::SemaDiagnosticBuilder::AddFixItHint(
47 const FixItHint &Hint) const {
48 if (ImmediateDiag)
49 ImmediateDiag->AddFixItHint(Hint);
50 else if (PartialDiagId)
51 S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint);
52 }
53
54 llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
55 std::vector<PartialDiagnosticAt>> &
getDeviceDeferredDiags() const56 SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const {
57 return S.DeviceDeferredDiags;
58 }
59
Diag(SourceLocation Loc,unsigned DiagID,bool DeferHint)60 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID,
61 bool DeferHint) {
62 bool IsError =
63 getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID);
64 bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag &&
65 DiagnosticIDs::isDeferrable(DiagID) &&
66 (DeferHint || SemaRef.DeferDiags || !IsError);
67 auto SetIsLastErrorImmediate = [&](bool Flag) {
68 if (IsError)
69 SemaRef.IsLastErrorImmediate = Flag;
70 };
71 if (!ShouldDefer) {
72 SetIsLastErrorImmediate(true);
73 return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc,
74 DiagID, SemaRef.getCurFunctionDecl(), SemaRef);
75 }
76
77 SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice
78 ? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID)
79 : SemaRef.CUDA().DiagIfHostCode(Loc, DiagID);
80 SetIsLastErrorImmediate(DB.isImmediate());
81 return DB;
82 }
83
Diag(SourceLocation Loc,const PartialDiagnostic & PD,bool DeferHint)84 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,
85 const PartialDiagnostic &PD,
86 bool DeferHint) {
87 return Diag(Loc, PD.getDiagID(), DeferHint) << PD;
88 }
89
90 } // namespace clang
91