mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-02 14:26:02 +01:00
Add well-known identifier caching (#6486)
I'm doing this because I figured it'd be an incremental improvement for all the operator lookups that we do. Even to the extent that we've discussed witness caching, I think it'll still apply. It does add one more step to adding new interfaces (before, you'd just write the string, now you add it to the def file and reference it). I'll claim it makes GetClangOperatorKind a lot friendlier to read/edit, nevermind removing the string comparisons. :)
This commit is contained in:
+145
-138
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "clang/Sema/Overload.h"
|
||||
#include "clang/Sema/Sema.h"
|
||||
#include "toolchain/check/core_identifier.h"
|
||||
#include "toolchain/check/cpp/import.h"
|
||||
#include "toolchain/check/cpp/location.h"
|
||||
#include "toolchain/check/cpp/overload_resolution.h"
|
||||
@@ -20,147 +21,153 @@ namespace Carbon::Check {
|
||||
|
||||
// Maps Carbon operator interface and operator names to Clang operator kinds.
|
||||
static auto GetClangOperatorKind(Context& context, SemIR::LocId loc_id,
|
||||
llvm::StringLiteral interface_name,
|
||||
llvm::StringLiteral op_name)
|
||||
CoreIdentifier interface_name,
|
||||
CoreIdentifier op_name)
|
||||
-> std::optional<clang::OverloadedOperatorKind> {
|
||||
// Unary operators.
|
||||
if (interface_name == "Destroy" || interface_name == "As" ||
|
||||
interface_name == "ImplicitAs" || interface_name == "Copy") {
|
||||
// TODO: Support destructors and conversions.
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// Increment and Decrement.
|
||||
if (interface_name == "Inc") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_PlusPlus;
|
||||
}
|
||||
if (interface_name == "Dec") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_MinusMinus;
|
||||
}
|
||||
|
||||
// Arithmetic.
|
||||
if (interface_name == "Negate") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Minus;
|
||||
}
|
||||
|
||||
// Binary operators.
|
||||
|
||||
// Arithmetic Operators.
|
||||
if (interface_name == "AddWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Plus;
|
||||
}
|
||||
if (interface_name == "SubWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Minus;
|
||||
}
|
||||
if (interface_name == "MulWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Star;
|
||||
}
|
||||
if (interface_name == "DivWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Slash;
|
||||
}
|
||||
if (interface_name == "ModWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Percent;
|
||||
}
|
||||
|
||||
// Bitwise Operators.
|
||||
if (interface_name == "BitAndWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Amp;
|
||||
}
|
||||
if (interface_name == "BitOrWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Pipe;
|
||||
}
|
||||
if (interface_name == "BitXorWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_Caret;
|
||||
}
|
||||
if (interface_name == "LeftShiftWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_LessLess;
|
||||
}
|
||||
if (interface_name == "RightShiftWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_GreaterGreater;
|
||||
}
|
||||
|
||||
// Compound Assignment Arithmetic Operators.
|
||||
if (interface_name == "AddAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_PlusEqual;
|
||||
}
|
||||
if (interface_name == "SubAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_MinusEqual;
|
||||
}
|
||||
if (interface_name == "MulAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_StarEqual;
|
||||
}
|
||||
if (interface_name == "DivAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_SlashEqual;
|
||||
}
|
||||
if (interface_name == "ModAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_PercentEqual;
|
||||
}
|
||||
|
||||
// Compound Assignment Bitwise Operators.
|
||||
if (interface_name == "BitAndAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_AmpEqual;
|
||||
}
|
||||
if (interface_name == "BitOrAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_PipeEqual;
|
||||
}
|
||||
if (interface_name == "BitXorAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_CaretEqual;
|
||||
}
|
||||
if (interface_name == "LeftShiftAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_LessLessEqual;
|
||||
}
|
||||
if (interface_name == "RightShiftAssignWith") {
|
||||
CARBON_CHECK(op_name == "Op");
|
||||
return clang::OO_GreaterGreaterEqual;
|
||||
}
|
||||
|
||||
// Relational Operators.
|
||||
if (interface_name == "EqWith") {
|
||||
if (op_name == "Equal") {
|
||||
return clang::OO_EqualEqual;
|
||||
switch (interface_name) {
|
||||
// Unary operators.
|
||||
case CoreIdentifier::Destroy:
|
||||
case CoreIdentifier::As:
|
||||
case CoreIdentifier::ImplicitAs:
|
||||
case CoreIdentifier::Copy: {
|
||||
// TODO: Support destructors and conversions.
|
||||
return std::nullopt;
|
||||
}
|
||||
CARBON_CHECK(op_name == "NotEqual");
|
||||
return clang::OO_ExclaimEqual;
|
||||
}
|
||||
if (interface_name == "OrderedWith") {
|
||||
if (op_name == "Less") {
|
||||
return clang::OO_Less;
|
||||
}
|
||||
if (op_name == "Greater") {
|
||||
return clang::OO_Greater;
|
||||
}
|
||||
if (op_name == "LessOrEquivalent") {
|
||||
return clang::OO_LessEqual;
|
||||
}
|
||||
CARBON_CHECK(op_name == "GreaterOrEquivalent");
|
||||
return clang::OO_GreaterEqual;
|
||||
}
|
||||
|
||||
context.TODO(loc_id, llvm::formatv("Unsupported operator interface `{0}`",
|
||||
interface_name));
|
||||
return std::nullopt;
|
||||
// Increment and decrement.
|
||||
case CoreIdentifier::Inc: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_PlusPlus;
|
||||
}
|
||||
case CoreIdentifier::Dec: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_MinusMinus;
|
||||
}
|
||||
|
||||
// Arithmetic.
|
||||
case CoreIdentifier::Negate: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Minus;
|
||||
}
|
||||
|
||||
// Binary operators.
|
||||
|
||||
// Arithmetic operators.
|
||||
case CoreIdentifier::AddWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Plus;
|
||||
}
|
||||
case CoreIdentifier::SubWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Minus;
|
||||
}
|
||||
case CoreIdentifier::MulWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Star;
|
||||
}
|
||||
case CoreIdentifier::DivWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Slash;
|
||||
}
|
||||
case CoreIdentifier::ModWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Percent;
|
||||
}
|
||||
|
||||
// Bitwise operators.
|
||||
case CoreIdentifier::BitAndWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Amp;
|
||||
}
|
||||
case CoreIdentifier::BitOrWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Pipe;
|
||||
}
|
||||
case CoreIdentifier::BitXorWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_Caret;
|
||||
}
|
||||
case CoreIdentifier::LeftShiftWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_LessLess;
|
||||
}
|
||||
case CoreIdentifier::RightShiftWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_GreaterGreater;
|
||||
}
|
||||
|
||||
// Compound assignment arithmetic operators.
|
||||
case CoreIdentifier::AddAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_PlusEqual;
|
||||
}
|
||||
case CoreIdentifier::SubAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_MinusEqual;
|
||||
}
|
||||
case CoreIdentifier::MulAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_StarEqual;
|
||||
}
|
||||
case CoreIdentifier::DivAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_SlashEqual;
|
||||
}
|
||||
case CoreIdentifier::ModAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_PercentEqual;
|
||||
}
|
||||
|
||||
// Compound assignment bitwise operators.
|
||||
case CoreIdentifier::BitAndAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_AmpEqual;
|
||||
}
|
||||
case CoreIdentifier::BitOrAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_PipeEqual;
|
||||
}
|
||||
case CoreIdentifier::BitXorAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_CaretEqual;
|
||||
}
|
||||
case CoreIdentifier::LeftShiftAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_LessLessEqual;
|
||||
}
|
||||
case CoreIdentifier::RightShiftAssignWith: {
|
||||
CARBON_CHECK(op_name == CoreIdentifier::Op);
|
||||
return clang::OO_GreaterGreaterEqual;
|
||||
}
|
||||
|
||||
// Relational operators.
|
||||
case CoreIdentifier::EqWith: {
|
||||
if (op_name == CoreIdentifier::Equal) {
|
||||
return clang::OO_EqualEqual;
|
||||
}
|
||||
CARBON_CHECK(op_name == CoreIdentifier::NotEqual);
|
||||
return clang::OO_ExclaimEqual;
|
||||
}
|
||||
case CoreIdentifier::OrderedWith: {
|
||||
switch (op_name) {
|
||||
case CoreIdentifier::Less:
|
||||
return clang::OO_Less;
|
||||
case CoreIdentifier::Greater:
|
||||
return clang::OO_Greater;
|
||||
case CoreIdentifier::LessOrEquivalent:
|
||||
return clang::OO_LessEqual;
|
||||
case CoreIdentifier::GreaterOrEquivalent:
|
||||
return clang::OO_GreaterEqual;
|
||||
default:
|
||||
CARBON_FATAL("Unexpected OrderedWith op `{0}`", op_name);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
context.TODO(loc_id, llvm::formatv("Unsupported operator interface `{0}`",
|
||||
interface_name));
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
auto LookupCppOperator(Context& context, SemIR::LocId loc_id, Operator op,
|
||||
|
||||
Reference in New Issue
Block a user