Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- DiagnosticRenderer.h - Diagnostic Pretty-Printing --------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // This is a utility class that provides support for pretty-printing of
  10. // diagnostics. It is used to implement the different code paths which require
  11. // such functionality in a consistent way.
  12. //
  13. //===----------------------------------------------------------------------===//
  14.  
  15. #ifndef LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
  16. #define LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
  17.  
  18. #include "clang/Basic/Diagnostic.h"
  19. #include "clang/Basic/DiagnosticOptions.h"
  20. #include "clang/Basic/LLVM.h"
  21. #include "clang/Basic/SourceLocation.h"
  22. #include "llvm/ADT/ArrayRef.h"
  23. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  24. #include "llvm/ADT/PointerUnion.h"
  25. #include "llvm/ADT/StringRef.h"
  26.  
  27. namespace clang {
  28.  
  29. class LangOptions;
  30. class SourceManager;
  31.  
  32. using DiagOrStoredDiag =
  33.     llvm::PointerUnion<const Diagnostic *, const StoredDiagnostic *>;
  34.  
  35. /// Class to encapsulate the logic for formatting a diagnostic message.
  36. ///
  37. /// Actual "printing" logic is implemented by subclasses.
  38. ///
  39. /// This class provides an interface for building and emitting
  40. /// diagnostic, including all of the macro backtraces, caret diagnostics, FixIt
  41. /// Hints, and code snippets. In the presence of macros this involves
  42. /// a recursive process, synthesizing notes for each macro expansion.
  43. ///
  44. /// A brief worklist:
  45. /// FIXME: Sink the recursive printing of template instantiations into this
  46. /// class.
  47. class DiagnosticRenderer {
  48. protected:
  49.   const LangOptions &LangOpts;
  50.   IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts;
  51.  
  52.   /// The location of the previous diagnostic if known.
  53.   ///
  54.   /// This will be invalid in cases where there is no (known) previous
  55.   /// diagnostic location, or that location itself is invalid or comes from
  56.   /// a different source manager than SM.
  57.   SourceLocation LastLoc;
  58.  
  59.   /// The location of the last include whose stack was printed if known.
  60.   ///
  61.   /// Same restriction as LastLoc essentially, but tracking include stack
  62.   /// root locations rather than diagnostic locations.
  63.   SourceLocation LastIncludeLoc;
  64.  
  65.   /// The level of the last diagnostic emitted.
  66.   ///
  67.   /// The level of the last diagnostic emitted. Used to detect level changes
  68.   /// which change the amount of information displayed.
  69.   DiagnosticsEngine::Level LastLevel = DiagnosticsEngine::Ignored;
  70.  
  71.   DiagnosticRenderer(const LangOptions &LangOpts,
  72.                      DiagnosticOptions *DiagOpts);
  73.  
  74.   virtual ~DiagnosticRenderer();
  75.  
  76.   virtual void emitDiagnosticMessage(FullSourceLoc Loc, PresumedLoc PLoc,
  77.                                      DiagnosticsEngine::Level Level,
  78.                                      StringRef Message,
  79.                                      ArrayRef<CharSourceRange> Ranges,
  80.                                      DiagOrStoredDiag Info) = 0;
  81.  
  82.   virtual void emitDiagnosticLoc(FullSourceLoc Loc, PresumedLoc PLoc,
  83.                                  DiagnosticsEngine::Level Level,
  84.                                  ArrayRef<CharSourceRange> Ranges) = 0;
  85.  
  86.   virtual void emitCodeContext(FullSourceLoc Loc,
  87.                                DiagnosticsEngine::Level Level,
  88.                                SmallVectorImpl<CharSourceRange> &Ranges,
  89.                                ArrayRef<FixItHint> Hints) = 0;
  90.  
  91.   virtual void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) = 0;
  92.   virtual void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
  93.                                   StringRef ModuleName) = 0;
  94.   virtual void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
  95.                                           StringRef ModuleName) = 0;
  96.  
  97.   virtual void beginDiagnostic(DiagOrStoredDiag D,
  98.                                DiagnosticsEngine::Level Level) {}
  99.   virtual void endDiagnostic(DiagOrStoredDiag D,
  100.                              DiagnosticsEngine::Level Level) {}
  101.  
  102. private:
  103.   void emitBasicNote(StringRef Message);
  104.   void emitIncludeStack(FullSourceLoc Loc, PresumedLoc PLoc,
  105.                         DiagnosticsEngine::Level Level);
  106.   void emitIncludeStackRecursively(FullSourceLoc Loc);
  107.   void emitImportStack(FullSourceLoc Loc);
  108.   void emitImportStackRecursively(FullSourceLoc Loc, StringRef ModuleName);
  109.   void emitModuleBuildStack(const SourceManager &SM);
  110.   void emitCaret(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
  111.                  ArrayRef<CharSourceRange> Ranges, ArrayRef<FixItHint> Hints);
  112.   void emitSingleMacroExpansion(FullSourceLoc Loc,
  113.                                 DiagnosticsEngine::Level Level,
  114.                                 ArrayRef<CharSourceRange> Ranges);
  115.   void emitMacroExpansions(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
  116.                            ArrayRef<CharSourceRange> Ranges,
  117.                            ArrayRef<FixItHint> Hints);
  118.  
  119. public:
  120.   /// Emit a diagnostic.
  121.   ///
  122.   /// This is the primary entry point for emitting diagnostic messages.
  123.   /// It handles formatting and rendering the message as well as any ancillary
  124.   /// information needed based on macros whose expansions impact the
  125.   /// diagnostic.
  126.   ///
  127.   /// \param Loc The location for this caret.
  128.   /// \param Level The level of the diagnostic to be emitted.
  129.   /// \param Message The diagnostic message to emit.
  130.   /// \param Ranges The underlined ranges for this code snippet.
  131.   /// \param FixItHints The FixIt hints active for this diagnostic.
  132.   void emitDiagnostic(FullSourceLoc Loc, DiagnosticsEngine::Level Level,
  133.                       StringRef Message, ArrayRef<CharSourceRange> Ranges,
  134.                       ArrayRef<FixItHint> FixItHints,
  135.                       DiagOrStoredDiag D = (Diagnostic *)nullptr);
  136.  
  137.   void emitStoredDiagnostic(StoredDiagnostic &Diag);
  138. };
  139.  
  140. /// Subclass of DiagnosticRender that turns all subdiagostics into explicit
  141. /// notes.  It is up to subclasses to further define the behavior.
  142. class DiagnosticNoteRenderer : public DiagnosticRenderer {
  143. public:
  144.   DiagnosticNoteRenderer(const LangOptions &LangOpts,
  145.                          DiagnosticOptions *DiagOpts)
  146.       : DiagnosticRenderer(LangOpts, DiagOpts) {}
  147.  
  148.   ~DiagnosticNoteRenderer() override;
  149.  
  150.   void emitIncludeLocation(FullSourceLoc Loc, PresumedLoc PLoc) override;
  151.  
  152.   void emitImportLocation(FullSourceLoc Loc, PresumedLoc PLoc,
  153.                           StringRef ModuleName) override;
  154.  
  155.   void emitBuildingModuleLocation(FullSourceLoc Loc, PresumedLoc PLoc,
  156.                                   StringRef ModuleName) override;
  157.  
  158.   virtual void emitNote(FullSourceLoc Loc, StringRef Message) = 0;
  159. };
  160.  
  161. } // namespace clang
  162.  
  163. #endif // LLVM_CLANG_FRONTEND_DIAGNOSTICRENDERER_H
  164.