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