Path: blob/main/contrib/llvm-project/clang/lib/Sema/SemaBase.cpp
35233 views
#include "clang/Sema/SemaBase.h"1#include "clang/Sema/Sema.h"2#include "clang/Sema/SemaCUDA.h"34namespace clang {56SemaBase::SemaBase(Sema &S) : SemaRef(S) {}78ASTContext &SemaBase::getASTContext() const { return SemaRef.Context; }9DiagnosticsEngine &SemaBase::getDiagnostics() const { return SemaRef.Diags; }10const LangOptions &SemaBase::getLangOpts() const { return SemaRef.LangOpts; }1112SemaBase::ImmediateDiagBuilder::~ImmediateDiagBuilder() {13// If we aren't active, there is nothing to do.14if (!isActive())15return;1617// Otherwise, we need to emit the diagnostic. First clear the diagnostic18// builder itself so it won't emit the diagnostic in its own destructor.19//20// This seems wasteful, in that as written the DiagnosticBuilder dtor will21// do its own needless checks to see if the diagnostic needs to be22// emitted. However, because we take care to ensure that the builder23// objects never escape, a sufficiently smart compiler will be able to24// eliminate that code.25Clear();2627// Dispatch to Sema to emit the diagnostic.28SemaRef.EmitCurrentDiagnostic(DiagID);29}3031PartialDiagnostic SemaBase::PDiag(unsigned DiagID) {32return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator());33}3435const SemaBase::SemaDiagnosticBuilder &36operator<<(const SemaBase::SemaDiagnosticBuilder &Diag,37const PartialDiagnostic &PD) {38if (Diag.ImmediateDiag)39PD.Emit(*Diag.ImmediateDiag);40else if (Diag.PartialDiagId)41Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD;42return Diag;43}4445void SemaBase::SemaDiagnosticBuilder::AddFixItHint(46const FixItHint &Hint) const {47if (ImmediateDiag)48ImmediateDiag->AddFixItHint(Hint);49else if (PartialDiagId)50S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint);51}5253llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>,54std::vector<PartialDiagnosticAt>> &55SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const {56return S.DeviceDeferredDiags;57}5859Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID,60bool DeferHint) {61bool IsError =62getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID);63bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag &&64DiagnosticIDs::isDeferrable(DiagID) &&65(DeferHint || SemaRef.DeferDiags || !IsError);66auto SetIsLastErrorImmediate = [&](bool Flag) {67if (IsError)68SemaRef.IsLastErrorImmediate = Flag;69};70if (!ShouldDefer) {71SetIsLastErrorImmediate(true);72return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc,73DiagID, SemaRef.getCurFunctionDecl(), SemaRef);74}7576SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice77? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID)78: SemaRef.CUDA().DiagIfHostCode(Loc, DiagID);79SetIsLastErrorImmediate(DB.isImmediate());80return DB;81}8283Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc,84const PartialDiagnostic &PD,85bool DeferHint) {86return Diag(Loc, PD.getDiagID(), DeferHint) << PD;87}8889} // namespace clang909192