xref: /freebsd/contrib/llvm-project/clang/lib/Sema/SemaBase.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
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; }
getCurContext() const12 DeclContext *SemaBase::getCurContext() const { return SemaRef.CurContext; }
13 
~ImmediateDiagBuilder()14 SemaBase::ImmediateDiagBuilder::~ImmediateDiagBuilder() {
15   // If we aren't active, there is nothing to do.
16   if (!isActive())
17     return;
18 
19   // Otherwise, we need to emit the diagnostic. First clear the diagnostic
20   // builder itself so it won't emit the diagnostic in its own destructor.
21   //
22   // This seems wasteful, in that as written the DiagnosticBuilder dtor will
23   // do its own needless checks to see if the diagnostic needs to be
24   // emitted. However, because we take care to ensure that the builder
25   // objects never escape, a sufficiently smart compiler will be able to
26   // eliminate that code.
27   Clear();
28 
29   // Dispatch to Sema to emit the diagnostic.
30   SemaRef.EmitDiagnostic(DiagID, *this);
31 }
32 
PDiag(unsigned DiagID)33 PartialDiagnostic SemaBase::PDiag(unsigned DiagID) {
34   return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator());
35 }
36 
37 const SemaBase::SemaDiagnosticBuilder &
operator <<(const SemaBase::SemaDiagnosticBuilder & Diag,const PartialDiagnostic & PD)38 operator<<(const SemaBase::SemaDiagnosticBuilder &Diag,
39            const PartialDiagnostic &PD) {
40   if (Diag.ImmediateDiag)
41     PD.Emit(*Diag.ImmediateDiag);
42   else if (Diag.PartialDiagId)
43     Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD;
44   return Diag;
45 }
46 
AddFixItHint(const FixItHint & Hint) const47 void SemaBase::SemaDiagnosticBuilder::AddFixItHint(
48     const FixItHint &Hint) const {
49   if (ImmediateDiag)
50     ImmediateDiag->AddFixItHint(Hint);
51   else if (PartialDiagId)
52     S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint);
53 }
54 
55 llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,
56                std::vector<PartialDiagnosticAt>> &
getDeviceDeferredDiags() const57 SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const {
58   return S.DeviceDeferredDiags;
59 }
60 
Diag(SourceLocation Loc,unsigned DiagID,bool DeferHint)61 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID,
62                                            bool DeferHint) {
63   bool IsError =
64       getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID);
65   bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag &&
66                      DiagnosticIDs::isDeferrable(DiagID) &&
67                      (DeferHint || SemaRef.DeferDiags || !IsError);
68   auto SetIsLastErrorImmediate = [&](bool Flag) {
69     if (IsError)
70       SemaRef.IsLastErrorImmediate = Flag;
71   };
72   if (!ShouldDefer) {
73     SetIsLastErrorImmediate(true);
74     return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc,
75                                  DiagID, SemaRef.getCurFunctionDecl(), SemaRef);
76   }
77 
78   SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice
79                                  ? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID)
80                                  : SemaRef.CUDA().DiagIfHostCode(Loc, DiagID);
81   SetIsLastErrorImmediate(DB.isImmediate());
82   return DB;
83 }
84 
Diag(SourceLocation Loc,const PartialDiagnostic & PD,bool DeferHint)85 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,
86                                            const PartialDiagnostic &PD,
87                                            bool DeferHint) {
88   return Diag(Loc, PD.getDiagID(), DeferHint) << PD;
89 }
90 
DiagCompat(SourceLocation Loc,unsigned CompatDiagId,bool DeferHint)91 SemaBase::SemaDiagnosticBuilder SemaBase::DiagCompat(SourceLocation Loc,
92                                                      unsigned CompatDiagId,
93                                                      bool DeferHint) {
94   return Diag(Loc,
95               DiagnosticIDs::getCXXCompatDiagId(getLangOpts(), CompatDiagId),
96               DeferHint);
97 }
98 } // namespace clang
99