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 PartialDiagnostic SemaBase::PDiag(unsigned DiagID) { 33 return PartialDiagnostic(DiagID, SemaRef.Context.getDiagAllocator()); 34 } 35 36 const SemaBase::SemaDiagnosticBuilder & 37 operator<<(const SemaBase::SemaDiagnosticBuilder &Diag, 38 const PartialDiagnostic &PD) { 39 if (Diag.ImmediateDiag) 40 PD.Emit(*Diag.ImmediateDiag); 41 else if (Diag.PartialDiagId) 42 Diag.S.DeviceDeferredDiags[Diag.Fn][*Diag.PartialDiagId].second = PD; 43 return Diag; 44 } 45 46 void SemaBase::SemaDiagnosticBuilder::AddFixItHint( 47 const FixItHint &Hint) const { 48 if (ImmediateDiag) 49 ImmediateDiag->AddFixItHint(Hint); 50 else if (PartialDiagId) 51 S.DeviceDeferredDiags[Fn][*PartialDiagId].second.AddFixItHint(Hint); 52 } 53 54 llvm::DenseMap<CanonicalDeclPtr<const FunctionDecl>, 55 std::vector<PartialDiagnosticAt>> & 56 SemaBase::SemaDiagnosticBuilder::getDeviceDeferredDiags() const { 57 return S.DeviceDeferredDiags; 58 } 59 60 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, unsigned DiagID, 61 bool DeferHint) { 62 bool IsError = 63 getDiagnostics().getDiagnosticIDs()->isDefaultMappingAsError(DiagID); 64 bool ShouldDefer = getLangOpts().CUDA && getLangOpts().GPUDeferDiag && 65 DiagnosticIDs::isDeferrable(DiagID) && 66 (DeferHint || SemaRef.DeferDiags || !IsError); 67 auto SetIsLastErrorImmediate = [&](bool Flag) { 68 if (IsError) 69 SemaRef.IsLastErrorImmediate = Flag; 70 }; 71 if (!ShouldDefer) { 72 SetIsLastErrorImmediate(true); 73 return SemaDiagnosticBuilder(SemaDiagnosticBuilder::K_Immediate, Loc, 74 DiagID, SemaRef.getCurFunctionDecl(), SemaRef); 75 } 76 77 SemaDiagnosticBuilder DB = getLangOpts().CUDAIsDevice 78 ? SemaRef.CUDA().DiagIfDeviceCode(Loc, DiagID) 79 : SemaRef.CUDA().DiagIfHostCode(Loc, DiagID); 80 SetIsLastErrorImmediate(DB.isImmediate()); 81 return DB; 82 } 83 84 Sema::SemaDiagnosticBuilder SemaBase::Diag(SourceLocation Loc, 85 const PartialDiagnostic &PD, 86 bool DeferHint) { 87 return Diag(Loc, PD.getDiagID(), DeferHint) << PD; 88 } 89 90 } // namespace clang 91