aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaBase.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaBase.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaBase.cpp90
1 files changed, 90 insertions, 0 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaBase.cpp b/contrib/llvm-project/clang/lib/Sema/SemaBase.cpp
new file mode 100644
index 000000000000..a2f12d622e8c
--- /dev/null
+++ b/contrib/llvm-project/clang/lib/Sema/SemaBase.cpp
@@ -0,0 +1,90 @@
+#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