#include "clang/Sema/SemaBase.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaCUDA.h" namespace clang { SemaBase::SemaBase(Sema &S) : SemaRef(S) {} ASTContext &SemaBase::getASTContext() const { return SemaRef.Context; } DiagnosticsEngine &SemaBase::getDiagnostics() const { return SemaRef.Diags; } const LangOptions &SemaBase::getLangOpts() const { return SemaRef.LangOpts; } SemaBase::ImmediateDiagBuilder::~ImmediateDiagBuilder() { // If we aren't active, there is nothing to do. if (!isActive()) return; // Otherwise, we need to emit the diagnostic. First clear the diagnostic // builder itself so it won't emit the diagnostic in its own destructor. // // This seems wasteful, in that as written the DiagnosticBuilder dtor will // do its own needless checks to see if the diagnostic needs to be // emitted. However, because we take care to ensure that the builder // objects never escape, a sufficiently smart compiler will be able to // eliminate that code. Clear(); // Dispatch to Sema to emit the diagnostic. SemaRef.EmitCurrentDiagnostic(DiagID); } PartialDiagnostic SemaBase::PDiag(unsigned DiagID) { return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator()); } const SemaBase::SemaDiagnosticBuilder & operator<<(const SemaBase::SemaDiagnosticBuilder &Diag, const PartialDiagnostic &PD) { if (Diag.ImmediateDiag) PD.Emit(*Diag.ImmediateDiag); else if (Diag.PartialDiagId) Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD; return Diag; } void SemaBase::SemaDiagnosticBuilder::AddFixItHint( const FixItHint &Hint) const { if (ImmediateDiag) ImmediateDiag->AddFixItHint(Hint); else if (PartialDiagId) S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint); } llvm::DenseMap, std::vector> & SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const { return S.DeviceDeferredDiags; } Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint) { bool IsError = getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID); bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag && DiagnosticIDs::isDeferrable(DiagID) && (DeferHint || SemaRef.DeferDiags || !IsError); auto SetIsLastErrorImmediate = [&](bool Flag) { if (IsError) SemaRef.IsLastErrorImmediate = Flag; }; if (!ShouldDefer) { SetIsLastErrorImmediate(true); return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc, DiagID, SemaRef.getCurFunctionDecl(), SemaRef); } SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice ? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID) : SemaRef.CUDA().DiagIfHostCode(Loc, DiagID); SetIsLastErrorImmediate(DB.isImmediate()); return DB; } Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, const PartialDiagnostic &PD, bool DeferHint) { return Diag(Loc, PD.getDiagID(), DeferHint) << PD; } } // namespace clang