1 #include "clang/Sema/SemaBase.h" 2 #include "clang/Sema/Sema.h" 3 4 namespace clang { 5 6 SemaBase::SemaBase(Sema &S) : SemaRef(S) {} 7 8 ASTContext &SemaBase::getASTContext() const { return SemaRef.Context; } 9 DiagnosticsEngine &SemaBase::getDiagnostics() const { return SemaRef.Diags; } 10 const LangOptions &SemaBase::getLangOpts() const { return SemaRef.LangOpts; } 11 12 SemaBase::ImmediateDiagBuilder::~ImmediateDiagBuilder() { 13 // If we aren't active, there is nothing to do. 14 if (!isActive()) 15 return; 16 17 // Otherwise, we need to emit the diagnostic. First clear the diagnostic 18 // 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 will 21 // do its own needless checks to see if the diagnostic needs to be 22 // emitted. However, because we take care to ensure that the builder 23 // objects never escape, a sufficiently smart compiler will be able to 24 // eliminate that code. 25 Clear(); 26 27 // Dispatch to Sema to emit the diagnostic. 28 SemaRef.EmitCurrentDiagnostic(DiagID); 29 } 30 31 const SemaBase::SemaDiagnosticBuilder & 32 operator<<(const SemaBase::SemaDiagnosticBuilder &Diag, 33 const PartialDiagnostic &PD) { 34 if (Diag.ImmediateDiag) 35 PD.Emit(*Diag.ImmediateDiag); 36 else if (Diag.PartialDiagId) 37 Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD; 38 return Diag; 39 } 40 41 void SemaBase::SemaDiagnosticBuilder::AddFixItHint( 42 const FixItHint &Hint) const { 43 if (ImmediateDiag) 44 ImmediateDiag->AddFixItHint(Hint); 45 else if (PartialDiagId) 46 S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint); 47 } 48 49 llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>, 50 std::vector<PartialDiagnosticAt>> & 51 SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const { 52 return S.DeviceDeferredDiags; 53 } 54 55 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID, 56 bool DeferHint) { 57 bool IsError = 58 getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID); 59 bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag && 60 DiagnosticIDs::isDeferrable(DiagID) && 61 (DeferHint || SemaRef.DeferDiags || !IsError); 62 auto SetIsLastErrorImmediate = [&](bool Flag) { 63 if (IsError) 64 SemaRef.IsLastErrorImmediate = Flag; 65 }; 66 if (!ShouldDefer) { 67 SetIsLastErrorImmediate(true); 68 return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc, 69 DiagID, SemaRef.getCurFunctionDecl(), SemaRef); 70 } 71 72 SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice 73 ? SemaRef.CUDADiagIfDeviceCode(Loc, DiagID) 74 : SemaRef.CUDADiagIfHostCode(Loc, DiagID); 75 SetIsLastErrorImmediate(DB.isImmediate()); 76 return DB; 77 } 78 79 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, 80 const PartialDiagnostic &PD, 81 bool DeferHint) { 82 return Diag(Loc, PD.getDiagID(), DeferHint) << PD; 83 } 84 85 } // namespace clang 86