This patch moves `PDiag` into `SemaBase`, making it readily available everywhere across `Sema` without `SemaRef`, like the regular `Diag`.
91 lines
3.2 KiB
C++
91 lines
3.2 KiB
C++
#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<CanonicalDeclPtr<const FunctionDecl>,
|
|
std::vector<PartialDiagnosticAt>> &
|
|
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
|