clang_decl.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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_CLANG_DECL_H_
  5. #define CARBON_TOOLCHAIN_SEM_IR_CLANG_DECL_H_
  6. #include <concepts>
  7. #include "clang/AST/Decl.h"
  8. #include "common/hashtable_key_context.h"
  9. #include "common/ostream.h"
  10. #include "toolchain/base/canonical_value_store.h"
  11. #include "toolchain/sem_ir/ids.h"
  12. namespace Carbon::SemIR {
  13. // A key describing a Clang declaration that can be looked up in the value
  14. // store. This is a `clang::Decl*` pointing to a canonical declaration, plus any
  15. // other information that affects the mapping into Carbon. Currently this
  16. // includes the number of imported parameters for a function with default
  17. // arguments.
  18. //
  19. // A canonical declaration pointer is used so that we can perform direct address
  20. // comparisons and hash this structure based on its contents.
  21. struct ClangDeclKey : public Printable<ClangDeclKey> {
  22. // For declaration classes that are unrelated to FunctionDecl, no parameter
  23. // count is expected.
  24. template <typename DeclT>
  25. requires(std::derived_from<DeclT, clang::Decl> &&
  26. !std::derived_from<clang::FunctionDecl, DeclT> &&
  27. !std::derived_from<DeclT, clang::FunctionDecl>)
  28. explicit ClangDeclKey(DeclT* decl) : ClangDeclKey(decl, -1, UncheckedTag()) {}
  29. // For declaration classes that are derived from FunctionDecl, a parameter
  30. // count is required.
  31. static auto ForFunctionDecl(clang::FunctionDecl* decl, int num_params)
  32. -> ClangDeclKey {
  33. return ClangDeclKey(decl, num_params, UncheckedTag());
  34. }
  35. // Factory function for clang declaration that is dynamically known to not be
  36. // a function declaration.
  37. static auto ForNonFunctionDecl(clang::Decl* decl) -> ClangDeclKey {
  38. CARBON_CHECK(!isa<clang::FunctionDecl>(decl));
  39. return ClangDeclKey(decl, -1, UncheckedTag());
  40. }
  41. auto Print(llvm::raw_ostream& out) const -> void;
  42. auto operator==(const ClangDeclKey& rhs) const -> bool {
  43. return decl == rhs.decl && num_params == rhs.num_params;
  44. }
  45. // Hashing for ClangDecl. See common/hashing.h.
  46. friend auto CarbonHashValue(const ClangDeclKey& value, uint64_t seed)
  47. -> HashCode {
  48. // Manual hashing support is required because this type has tail padding in
  49. // 64-bit compilations.
  50. return HashValue(std::pair{value.decl, value.num_params}, seed);
  51. }
  52. // The Clang declaration pointing to the Clang AST.
  53. // TODO: Ensure we can easily serialize/deserialize this. Consider
  54. // `clang::LazyDeclPtr`.
  55. clang::Decl* decl = nullptr;
  56. // The number of parameters to import for a function declaration. Excludes the
  57. // implicit object parameter, if there is one. Always -1 for a non-function
  58. // declaration.
  59. int32_t num_params = -1;
  60. private:
  61. struct UncheckedTag {
  62. explicit UncheckedTag() = default;
  63. };
  64. ClangDeclKey(clang::Decl* decl, int num_params, UncheckedTag /*_*/)
  65. : decl(decl->getCanonicalDecl()), num_params(num_params) {}
  66. };
  67. // A Clang declaration mapped to a Carbon instruction.
  68. //
  69. // Instances of this type are managed by a `ClangDeclStore`, which ensures that
  70. // a single `ClangDecl` exists for each `ClangDeclKey` used.
  71. struct ClangDecl : public Printable<ClangDecl> {
  72. auto Print(llvm::raw_ostream& out) const -> void;
  73. // The key by which this declaration can be looked up.
  74. ClangDeclKey key;
  75. // The instruction the Clang declaration is mapped to.
  76. InstId inst_id;
  77. auto GetAsKey() const -> ClangDeclKey { return key; }
  78. };
  79. // Use the AST node pointer directly when doing `Lookup` to find an ID.
  80. using ClangDeclStore =
  81. CanonicalValueStore<ClangDeclId, ClangDeclKey, Tag<CheckIRId>, ClangDecl>;
  82. } // namespace Carbon::SemIR
  83. #endif // CARBON_TOOLCHAIN_SEM_IR_CLANG_DECL_H_