diagnostic_loc_converter.h 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. // Part of the Carbon Language project, under the Apache License v2.0 with LLVM
  2. // Exceptions. See /LICENSE for license information.
  3. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. #ifndef CARBON_TOOLCHAIN_SEM_IR_DIAGNOSTIC_LOC_CONVERTER_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_DIAGNOSTIC_LOC_CONVERTER_H_
  6. #include "llvm/ADT/ArrayRef.h"
  7. #include "llvm/ADT/SmallVector.h"
  8. #include "toolchain/diagnostics/emitter.h"
  9. #include "toolchain/parse/tree_and_subtrees.h"
  10. #include "toolchain/sem_ir/absolute_node_id.h"
  11. #include "toolchain/sem_ir/file.h"
  12. #include "toolchain/sem_ir/ids.h"
  13. namespace Carbon::SemIR {
  14. // Converter from compact location information into a diagnostic location
  15. // describing a filename, line location, and potentially a sequence of imports.
  16. // Such diagnostics locations are used to render user-facing diagnostics and
  17. // also locations for stack trace in crash diagnostics.
  18. class DiagnosticLocConverter {
  19. public:
  20. // Information about an import within which the location was found.
  21. struct ImportLoc {
  22. enum Kind {
  23. // A regular Carbon `import`.
  24. Import,
  25. // A C++ `#include`.
  26. CppInclude,
  27. // A C++ module import.
  28. CppModuleImport,
  29. // A C++ macro expansion.
  30. CppMacroExpansion,
  31. };
  32. // The location of the import.
  33. Diagnostics::Loc loc;
  34. // The kind of import.
  35. Kind kind;
  36. // The name of the imported module for CppInclude, or the complete macro
  37. // expansion diagnostic message for CppMacroExpansion.
  38. // TODO: In the latter case, provide just the macro name.
  39. // TODO: Include the name of the imported library in this information for
  40. // Import so it can be mentioned in the diagnostic.
  41. llvm::StringRef imported_name;
  42. };
  43. // Information about a location that has been converted from a LocId to a
  44. // diagnostic location.
  45. struct LocAndImports {
  46. llvm::SmallVector<ImportLoc> imports;
  47. Diagnostics::ConvertedLoc loc;
  48. };
  49. // `tree_and_subtrees_getters` and `sem_ir` must not be null.
  50. explicit DiagnosticLocConverter(
  51. const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters,
  52. const File* sem_ir)
  53. : tree_and_subtrees_getters_(tree_and_subtrees_getters),
  54. sem_ir_(sem_ir) {}
  55. // Converts the given location into a sequence of import locations and a final
  56. // diagnostic location.
  57. auto ConvertWithImports(LocId loc_id, bool token_only) const -> LocAndImports;
  58. // Converts the given location into a diagnostic location.
  59. auto Convert(LocId loc_id, bool token_only) const
  60. -> Diagnostics::ConvertedLoc;
  61. private:
  62. // Converts an `absolute_node_id` in either a Carbon file or C++ import to a
  63. // diagnostic location.
  64. auto ConvertImpl(AbsoluteNodeId absolute_node_id, bool token_only) const
  65. -> Diagnostics::ConvertedLoc;
  66. // Converts a `node_id` corresponding to a specific check IR to a diagnostic
  67. // location.
  68. auto ConvertImpl(CheckIRId check_ir_id, Parse::NodeId node_id,
  69. bool token_only) const -> Diagnostics::ConvertedLoc;
  70. // Converts a location pointing into C++ code to a diagnostic location.
  71. auto ConvertImpl(ClangSourceLocId clang_source_loc_id) const
  72. -> Diagnostics::ConvertedLoc;
  73. // Converters for each SemIR.
  74. const Parse::GetTreeAndSubtreesStore* tree_and_subtrees_getters_;
  75. // The current SemIR being processed.
  76. const File* sem_ir_;
  77. };
  78. } // namespace Carbon::SemIR
  79. #endif // CARBON_TOOLCHAIN_SEM_IR_DIAGNOSTIC_LOC_CONVERTER_H_