-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Key-type customization in CanonicalValueStore
and ClangDecl
cleanups
#5743
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,17 +20,28 @@ class Decl; | |
namespace Carbon::SemIR { | ||
|
||
// A Clang declaration mapped to a Carbon instruction. | ||
// Using custom hashing since the declaration is keyed by the `decl` member for | ||
// lookup. | ||
// TODO: Avoid custom hashing by either having the data structure support keying | ||
// or create a dedicated mapping. See | ||
// https://discord.com/channels/655572317891461132/768530752592805919/1384999468293947537 | ||
// | ||
// Note that Clang's AST uses address-identity for nodes, which means the | ||
// pointer is the canonical way to represent a specific AST node and is expected | ||
// to be sufficient for comparison, hashing, etc. | ||
// | ||
// This type is specifically designed for use in a `CanonicalValueStore` and | ||
// provide a single canonical access from SemIR to each `clang::Decl*` used. | ||
// This also ensures that a given `clang::Decl*` is associated with exactly one | ||
// instruction, and the `inst_id` here provides access to that instruction from | ||
// either the `ClangDeclId` or the `clang::Decl*`. | ||
struct ClangDecl : public Printable<ClangDecl> { | ||
auto Print(llvm::raw_ostream& out) const -> void; | ||
|
||
friend auto CarbonHashtableEq(const ClangDecl& lhs, const ClangDecl& rhs) | ||
-> bool { | ||
return HashtableEq(lhs.decl, rhs.decl); | ||
// Equality comparison uses the address-identity property of the Clang AST and | ||
// just compares the `decl` pointers. The `inst_id` is always the same due to | ||
// the canonicalization. | ||
auto operator==(const ClangDecl& rhs) const -> bool { | ||
return decl == rhs.decl; | ||
} | ||
// Support direct comparison with the Clang AST node pointer. | ||
auto operator==(const clang::Decl* rhs_decl) const -> bool { | ||
return decl == rhs_decl; | ||
} | ||
|
||
// Hashing for ClangDecl. See common/hashing.h. | ||
|
@@ -45,15 +56,28 @@ struct ClangDecl : public Printable<ClangDecl> { | |
clang::Decl* decl = nullptr; | ||
|
||
// The instruction the Clang declaration is mapped to. | ||
// | ||
// This is stored along side the `decl` pointer to avoid having to lookup both | ||
// the pointer and the instruction ID in two separate areas of storage. | ||
InstId inst_id; | ||
}; | ||
|
||
// The ID of a `ClangDecl`. | ||
// | ||
// These IDs are importantly distinct from the `inst_id` associated with each | ||
// declaration. These form a dense range of IDs that is used to reference the | ||
// AST node pointers without storing those pointers directly into SemIR and | ||
// needing space to hold a full pointer. We can't avoid having these IDs without | ||
// embedding pointers directly into the storage of SemIR as part of an | ||
// instruction. | ||
struct ClangDeclId : public IdBase<ClangDeclId> { | ||
static constexpr llvm::StringLiteral Label = "clang_decl_id"; | ||
|
||
using ValueType = ClangDecl; | ||
|
||
// Use the AST node pointer directly when doing `Lookup` to find an ID. | ||
using KeyType = clang::Decl*; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think @jonmeow raised a concern that we should change the ID as it could be used in multiple value stores, but perhaps just defining the key type is less of an issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy to hear Jon's thoughts here -- the ID type already dictates the value type, and even the reference type, so it seemed reasonable to also dictate the key type... Not sure what the looser coupling would look like? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @bricknerb You were putting value-specific functions here (inside the ID), I think this approach is different. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note in part, I expect |
||
|
||
using IdBase::IdBase; | ||
}; | ||
|
||
|
Uh oh!
There was an error while loading. Please reload this page.