mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +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:
@@ -32,6 +32,7 @@
|
||||
#include "toolchain/check/context.h"
|
||||
#include "toolchain/check/control_flow.h"
|
||||
#include "toolchain/check/convert.h"
|
||||
#include "toolchain/check/core_identifier.h"
|
||||
#include "toolchain/check/cpp/access.h"
|
||||
#include "toolchain/check/cpp/custom_type_mapping.h"
|
||||
#include "toolchain/check/cpp/generate_ast.h"
|
||||
@@ -730,16 +731,17 @@ static auto MakeIntType(Context& context, IntId size_id, bool is_signed)
|
||||
}
|
||||
|
||||
static auto MakeCppCompatType(Context& context, SemIR::LocId loc_id,
|
||||
llvm::StringRef name) -> TypeExpr {
|
||||
return ExprAsType(context, loc_id,
|
||||
LookupNameInCore(context, loc_id, {"CppCompat", name}));
|
||||
CoreIdentifier name) -> TypeExpr {
|
||||
return ExprAsType(
|
||||
context, loc_id,
|
||||
LookupNameInCore(context, loc_id, {CoreIdentifier::CppCompat, name}));
|
||||
}
|
||||
|
||||
// Maps a C++ builtin integer type to a Carbon `Core.CppCompat` type.
|
||||
static auto MapBuiltinCppCompatIntegerType(Context& context,
|
||||
unsigned int cpp_width,
|
||||
unsigned int carbon_width,
|
||||
llvm::StringRef cpp_compat_name)
|
||||
CoreIdentifier cpp_compat_name)
|
||||
-> TypeExpr {
|
||||
if (cpp_width != carbon_width) {
|
||||
return TypeExpr::None;
|
||||
@@ -775,23 +777,27 @@ static auto MapBuiltinIntegerType(Context& context, SemIR::LocId loc_id,
|
||||
MakeCharTypeLiteral(context, Parse::NodeId::None));
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.LongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 32, "Long32");
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 32,
|
||||
CoreIdentifier::Long32);
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.UnsignedLongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 32, "ULong32");
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 32,
|
||||
CoreIdentifier::ULong32);
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type, ast_context.LongLongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 64, "LongLong64");
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 64,
|
||||
CoreIdentifier::LongLong64);
|
||||
}
|
||||
if (clang::ASTContext::hasSameType(qual_type,
|
||||
ast_context.UnsignedLongLongTy)) {
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 64, "ULongLong64");
|
||||
return MapBuiltinCppCompatIntegerType(context, width, 64,
|
||||
CoreIdentifier::ULongLong64);
|
||||
}
|
||||
return TypeExpr::None;
|
||||
}
|
||||
|
||||
static auto MapNullptrType(Context& context, SemIR::LocId loc_id) -> TypeExpr {
|
||||
return MakeCppCompatType(context, loc_id, "NullptrT");
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::NullptrT);
|
||||
}
|
||||
|
||||
// Maps a C++ builtin type to a Carbon type.
|
||||
@@ -820,7 +826,7 @@ static auto MapBuiltinType(Context& context, SemIR::LocId loc_id,
|
||||
}
|
||||
// TODO: Handle floating-point types that map to named aliases.
|
||||
} else if (type.isVoidType()) {
|
||||
return MakeCppCompatType(context, loc_id, "VoidBase");
|
||||
return MakeCppCompatType(context, loc_id, CoreIdentifier::VoidBase);
|
||||
} else if (type.isNullPtrType()) {
|
||||
return MapNullptrType(context, loc_id);
|
||||
}
|
||||
@@ -937,7 +943,7 @@ static auto ClangGetUnqualifiedTypePreserveNonNull(
|
||||
// `inner_type_inst_id`.
|
||||
static auto MakeOptionalType(Context& context, SemIR::LocId loc_id,
|
||||
SemIR::InstId inner_type_inst_id) -> TypeExpr {
|
||||
auto fn_inst_id = LookupNameInCore(context, loc_id, "Optional");
|
||||
auto fn_inst_id = LookupNameInCore(context, loc_id, CoreIdentifier::Optional);
|
||||
auto call_id = PerformCall(context, loc_id, fn_inst_id, {inner_type_inst_id});
|
||||
return ExprAsType(context, loc_id, call_id);
|
||||
}
|
||||
|
||||
+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