clang_decl.h 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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 "common/hashtable_key_context.h"
  7. #include "common/ostream.h"
  8. #include "toolchain/base/canonical_value_store.h"
  9. #include "toolchain/sem_ir/ids.h"
  10. // NOLINTNEXTLINE(readability-identifier-naming)
  11. namespace clang {
  12. // Forward declare indexed types, for integration with ValueStore.
  13. class Decl;
  14. } // namespace clang
  15. namespace Carbon::SemIR {
  16. // A Clang declaration mapped to a Carbon instruction.
  17. //
  18. // Note that Clang's AST uses address-identity for nodes, which means the
  19. // pointer is the canonical way to represent a specific AST node and is expected
  20. // to be sufficient for comparison, hashing, etc.
  21. //
  22. // This type is specifically designed for use in a `CanonicalValueStore` and
  23. // provide a single canonical access from SemIR to each `clang::Decl*` used.
  24. // This also ensures that a given `clang::Decl*` is associated with exactly one
  25. // instruction, and the `inst_id` here provides access to that instruction from
  26. // either the `ClangDeclId` or the `clang::Decl*`.
  27. struct ClangDecl : public Printable<ClangDecl> {
  28. auto Print(llvm::raw_ostream& out) const -> void;
  29. // Equality comparison uses the address-identity property of the Clang AST and
  30. // just compares the `decl` pointers. The `inst_id` is always the same due to
  31. // the canonicalization.
  32. auto operator==(const ClangDecl& rhs) const -> bool {
  33. return decl == rhs.decl;
  34. }
  35. // Support direct comparison with the Clang AST node pointer.
  36. auto operator==(const clang::Decl* rhs_decl) const -> bool {
  37. return decl == rhs_decl;
  38. }
  39. // Hashing for ClangDecl. See common/hashing.h.
  40. friend auto CarbonHashValue(const ClangDecl& value, uint64_t seed)
  41. -> HashCode {
  42. return HashValue(value.decl, seed);
  43. }
  44. // The Clang declaration pointing to the Clang AST.
  45. // TODO: Ensure we can easily serialize/deserialize this. Consider
  46. // `clang::LazyDeclPtr`.
  47. clang::Decl* decl = nullptr;
  48. // The instruction the Clang declaration is mapped to.
  49. //
  50. // This is stored along side the `decl` pointer to avoid having to lookup both
  51. // the pointer and the instruction ID in two separate areas of storage.
  52. InstId inst_id;
  53. };
  54. // The ID of a `ClangDecl`.
  55. //
  56. // These IDs are importantly distinct from the `inst_id` associated with each
  57. // declaration. These form a dense range of IDs that is used to reference the
  58. // AST node pointers without storing those pointers directly into SemIR and
  59. // needing space to hold a full pointer. We can't avoid having these IDs without
  60. // embedding pointers directly into the storage of SemIR as part of an
  61. // instruction.
  62. struct ClangDeclId : public IdBase<ClangDeclId> {
  63. static constexpr llvm::StringLiteral Label = "clang_decl_id";
  64. using IdBase::IdBase;
  65. };
  66. // Use the AST node pointer directly when doing `Lookup` to find an ID.
  67. using ClangDeclStore =
  68. CanonicalValueStore<ClangDeclId, clang::Decl*, ClangDecl>;
  69. } // namespace Carbon::SemIR
  70. #endif // CARBON_TOOLCHAIN_SEM_IR_CLANG_DECL_H_