96 lines · cpp
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; }12DeclContext *SemaBase::getCurContext() const { return SemaRef.CurContext; }13 14SemaBase::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 diagnostic20 // 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 will23 // do its own needless checks to see if the diagnostic needs to be24 // emitted. However, because we take care to ensure that the builder25 // objects never escape, a sufficiently smart compiler will be able to26 // eliminate that code.27 Clear();28 29 // Dispatch to Sema to emit the diagnostic.30 SemaRef.EmitDiagnostic(DiagID, *this);31}32 33PartialDiagnostic SemaBase::PDiag(unsigned DiagID) {34 return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator());35}36 37const SemaBase::SemaDiagnosticBuilder &38operator<<(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 47void 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 55llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,56 std::vector<PartialDiagnosticAt>> &57SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const {58 return S.DeviceDeferredDiags;59}60 61Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,62 unsigned DiagID) {63 bool IsError =64 getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID);65 bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag &&66 DiagnosticIDs::isDeferrable(DiagID) &&67 (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().CUDAIsDevice79 ? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID)80 : SemaRef.CUDA().DiagIfHostCode(Loc, DiagID);81 SetIsLastErrorImmediate(DB.isImmediate());82 return DB;83}84 85Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,86 const PartialDiagnostic &PD) {87 return Diag(Loc, PD.getDiagID()) << PD;88}89 90SemaBase::SemaDiagnosticBuilder SemaBase::DiagCompat(SourceLocation Loc,91 unsigned CompatDiagId) {92 return Diag(Loc,93 DiagnosticIDs::getCXXCompatDiagId(getLangOpts(), CompatDiagId));94}95} // namespace clang96