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