Introduce a Clang diagnostic instruction and use it to point to C++ source locations on Clang errors and warnings (#5262)

Introduce `ImportIRId::Cpp` and refer to clang source location in its
`ImportIRInst`.

Part of #5245.
This commit is contained in:
Boaz Brickner
2025-04-25 13:05:45 +00:00
committed by GitHub
parent 1e2d4c3405
commit 609ccefd18
29 changed files with 487 additions and 267 deletions
+17 -13
View File
@@ -34,7 +34,11 @@ static auto GetImportedIRCount(UnitAndImports* unit_and_imports) -> int {
count += package_imports.imports.size();
}
if (!unit_and_imports->api_for_impl) {
// Leave an empty slot for ImportIRId::ApiForImpl.
// Leave an empty slot for `ImportIRId::ApiForImpl`.
++count;
}
if (!unit_and_imports->cpp_import_names.empty()) {
// Leave an empty slot for `ImportIRId::Cpp`.
++count;
}
return count;
@@ -101,20 +105,20 @@ auto CheckUnit::InitPackageScopeAndImports() -> void {
.import_id = SemIR::InstId::None});
CARBON_CHECK(package_inst_id == SemIR::Namespace::PackageInstId);
// If there is an implicit `api` import, set it first so that it uses the
// ImportIRId::ApiForImpl when processed for imports.
// Call `SetSpecialImportIRs()` to set `ImportIRId::ApiForImpl` and
// `ImportIRId::Cpp` first, as required.
if (unit_and_imports_->api_for_impl) {
const auto& names = context_.parse_tree().packaging_decl()->names;
auto import_decl_id = AddInst<SemIR::ImportDecl>(
context_, names.node_id,
{.package_id = SemIR::NameId::ForPackageName(names.package_id)});
SetApiImportIR(context_,
{.decl_id = import_decl_id,
.is_export = false,
.sem_ir = unit_and_imports_->api_for_impl->unit->sem_ir});
SetSpecialImportIRs(
context_, {.decl_id = import_decl_id,
.is_export = false,
.sem_ir = unit_and_imports_->api_for_impl->unit->sem_ir});
} else {
SetApiImportIR(context_,
{.decl_id = SemIR::InstId::None, .sem_ir = nullptr});
SetSpecialImportIRs(context_,
{.decl_id = SemIR::InstId::None, .sem_ir = nullptr});
}
// Add import instructions for everything directly imported. Implicit imports
@@ -327,9 +331,9 @@ auto CheckUnit::ImportOtherPackages(SemIR::TypeId namespace_type_id) -> void {
if (local_imports) {
CARBON_CHECK(package_id == api_imports_entry.first);
} else {
auto import_ir_inst_id = context_.import_ir_insts().Add(
{.ir_id = SemIR::ImportIRId::ApiForImpl,
.inst_id = api_imports->import_decl_id});
auto import_ir_inst_id =
context_.import_ir_insts().Add(SemIR::ImportIRInst(
SemIR::ImportIRId::ApiForImpl, api_imports->import_decl_id));
import_decl_id =
AddInst(context_, MakeImportedLocIdAndInst<SemIR::ImportDecl>(
context_, import_ir_inst_id,
@@ -411,7 +415,7 @@ auto CheckUnit::CheckRequiredDeclarations() -> void {
auto import_ir_id = context_.sem_ir()
.import_ir_insts()
.Get(function_loc_id.import_ir_inst_id())
.ir_id;
.ir_id();
auto& import_ir = context_.import_irs().Get(import_ir_id);
if (import_ir.sem_ir->package_id().has_value() !=
context_.sem_ir().package_id().has_value()) {
+36
View File
@@ -5,6 +5,7 @@
#include "toolchain/check/diagnostic_emitter.h"
#include <algorithm>
#include <optional>
#include <string>
#include "common/raw_string_ostream.h"
@@ -16,6 +17,14 @@ namespace Carbon::Check {
auto DiagnosticEmitter::ConvertLoc(SemIR::LocId loc_id,
ContextFnT context_fn) const
-> Diagnostics::ConvertedLoc {
// TODO: Instead of special casing Clang location here, support it within
// `GetAbsoluteNodeId()`. See discussion in
// https://github.com/carbon-language/carbon-lang/pull/5262/files#r2040308805.
auto converted_clang_loc = TryConvertClangDiagnosticLoc(loc_id);
if (converted_clang_loc) {
return *converted_clang_loc;
}
auto converted = ConvertLocImpl(loc_id, context_fn);
// Use the token when possible, but -1 is the default value.
@@ -60,6 +69,33 @@ auto DiagnosticEmitter::ConvertLocImpl(SemIR::LocId loc_id,
return ConvertLocInFile(final_node_id, token_only, context_fn);
}
auto DiagnosticEmitter::TryConvertClangDiagnosticLoc(SemIR::LocId loc_id) const
-> std::optional<Diagnostics::ConvertedLoc> {
if (loc_id.kind() != SemIR::LocId::Kind::ImportIRInstId) {
return std::nullopt;
}
SemIR::ImportIRInst import_ir_inst =
sem_ir_->import_ir_insts().Get(loc_id.import_ir_inst_id());
if (import_ir_inst.ir_id() != SemIR::ImportIRId::Cpp) {
return std::nullopt;
}
clang::SourceLocation clang_loc =
sem_ir_->clang_source_locs().Get(import_ir_inst.clang_source_loc_id());
CARBON_CHECK(sem_ir_->cpp_ast());
clang::PresumedLoc presumed_loc =
sem_ir_->cpp_ast()->getSourceManager().getPresumedLoc(clang_loc);
return Diagnostics::ConvertedLoc{
.loc = {.filename = presumed_loc.getFilename(),
.line_number = static_cast<int32_t>(presumed_loc.getLine())},
// TODO: Set `last_byte_offset` based on the `import Cpp` location.
.last_byte_offset = 0};
}
auto DiagnosticEmitter::ConvertLocInFile(SemIR::AbsoluteNodeId absolute_node_id,
bool token_only,
ContextFnT /*context_fn*/) const
+4
View File
@@ -51,6 +51,10 @@ class DiagnosticEmitter : public DiagnosticEmitterBase {
auto ConvertLocImpl(SemIR::LocId loc_id, ContextFnT context_fn) const
-> Diagnostics::ConvertedLoc;
// Returns `ConvertedLoc` if `loc` points to a `ClangDiagnostic` instruction.
auto TryConvertClangDiagnosticLoc(SemIR::LocId loc_id) const
-> std::optional<Diagnostics::ConvertedLoc>;
// Converts a node_id corresponding to a specific sem_ir to a diagnostic
// location.
auto ConvertLocInFile(SemIR::AbsoluteNodeId absolute_node_id, bool token_only,
+1 -1
View File
@@ -120,7 +120,7 @@ LLVM_DUMP_METHOD static auto Dump(const Context& context, SemIR::LocId loc_id)
auto import_ir_id = context.sem_ir()
.import_ir_insts()
.Get(loc_id.import_ir_inst_id())
.ir_id;
.ir_id();
const auto* import_file =
context.sem_ir().import_irs().Get(import_ir_id).sem_ir;
out << "LocId(import from \"" << FormatEscaped(import_file->filename())
+4 -4
View File
@@ -132,8 +132,8 @@ static auto MergeOrAddName(Context& context, Parse::AnyClassDeclId node_id,
// Verify the decl so that things like aliases are name conflicts.
const auto* import_ir =
context.import_irs().Get(import_ir_inst.ir_id).sem_ir;
if (!import_ir->insts().Is<SemIR::ClassDecl>(import_ir_inst.inst_id)) {
context.import_irs().Get(import_ir_inst.ir_id()).sem_ir;
if (!import_ir->insts().Is<SemIR::ClassDecl>(import_ir_inst.inst_id())) {
break;
}
@@ -142,12 +142,12 @@ static auto MergeOrAddName(Context& context, Parse::AnyClassDeclId node_id,
context.constant_values().GetConstantInstId(prev_id));
if (auto class_type = decl_value.TryAs<SemIR::ClassType>()) {
prev_class_id = class_type->class_id;
prev_import_ir_id = import_ir_inst.ir_id;
prev_import_ir_id = import_ir_inst.ir_id();
} else if (auto generic_class_type =
context.types().TryGetAs<SemIR::GenericClassType>(
decl_value.type_id())) {
prev_class_id = generic_class_type->class_id;
prev_import_ir_id = import_ir_inst.ir_id;
prev_import_ir_id = import_ir_inst.ir_id();
}
break;
}
+4 -3
View File
@@ -221,8 +221,9 @@ static auto TryMergeRedecl(Context& context, Parse::AnyFunctionDeclId node_id,
// Verify the decl so that things like aliases are name conflicts.
const auto* import_ir =
context.import_irs().Get(import_ir_inst.ir_id).sem_ir;
if (!import_ir->insts().Is<SemIR::FunctionDecl>(import_ir_inst.inst_id)) {
context.import_irs().Get(import_ir_inst.ir_id()).sem_ir;
if (!import_ir->insts().Is<SemIR::FunctionDecl>(
import_ir_inst.inst_id())) {
break;
}
@@ -233,7 +234,7 @@ static auto TryMergeRedecl(Context& context, Parse::AnyFunctionDeclId node_id,
struct_value->type_id)) {
prev_function_id = function_type->function_id;
prev_type_id = struct_value->type_id;
prev_import_ir_id = import_ir_inst.ir_id;
prev_import_ir_id = import_ir_inst.ir_id();
}
}
break;
+1 -1
View File
@@ -42,7 +42,7 @@ static auto FindAssociatedImportIRs(Context& context,
if (!decl_id.has_value()) {
return;
}
if (auto ir_id = GetCanonicalImportIRInst(context, decl_id).ir_id;
if (auto ir_id = GetCanonicalImportIRInst(context, decl_id).ir_id();
ir_id.has_value()) {
result.push_back(ir_id);
}
+5 -5
View File
@@ -226,7 +226,7 @@ static auto CopySingleNameScopeFromImportIR(
auto entity_name_id = context.entity_names().Add(
{.name_id = name_id, .parent_scope_id = parent_scope_id});
auto import_ir_inst_id = context.import_ir_insts().Add(
{.ir_id = ir_id, .inst_id = import_inst_id});
SemIR::ImportIRInst(ir_id, import_inst_id));
auto inst_id = AddInstInNoBlock(
context, MakeImportedLocIdAndInst<SemIR::ImportRefLoaded>(
context, import_ir_inst_id,
@@ -354,7 +354,7 @@ static auto AddImportRefOrMerge(Context& context, SemIR::ImportIRId ir_id,
auto entity_name_id = context.entity_names().Add(
{.name_id = name_id, .parent_scope_id = parent_scope_id});
auto import_ref = AddImportRef(
context, {.ir_id = ir_id, .inst_id = import_inst_id}, entity_name_id);
context, SemIR::ImportIRInst(ir_id, import_inst_id), entity_name_id);
entry.result = SemIR::ScopeLookupResult::MakeFound(
import_ref, SemIR::AccessKind::Public);
@@ -444,8 +444,8 @@ static auto ImportScopeFromApiFile(Context& context,
} else {
// Add an ImportRef for other instructions.
AddScopedImportRef(context, impl_scope_id, impl_scope, impl_name_id,
{.ir_id = SemIR::ImportIRId::ApiForImpl,
.inst_id = api_entry.result.target_inst_id()},
SemIR::ImportIRInst(SemIR::ImportIRId::ApiForImpl,
api_entry.result.target_inst_id()),
api_entry.result.access_kind());
}
}
@@ -668,7 +668,7 @@ auto ImportNameFromOtherPackage(
} else {
result_id = AddScopedImportRef(
context, scope_id, context.name_scopes().Get(scope_id), name_id,
{.ir_id = import_ir_id, .inst_id = import_scope_inst_id},
SemIR::ImportIRInst(import_ir_id, import_scope_inst_id),
SemIR::AccessKind::Public);
LoadImportRef(context, result_id);
}
+79 -36
View File
@@ -52,6 +52,17 @@ static auto GenerateCppIncludesHeaderCode(
namespace {
// Adds the given source location and an `ImportIRInst` referring to it in
// `ImportIRId::Cpp`.
static auto AddImportIRInst(Context& context,
clang::SourceLocation clang_source_loc)
-> SemIR::ImportIRInstId {
SemIR::ClangSourceLocId clang_source_loc_id =
context.sem_ir().clang_source_locs().Add(clang_source_loc);
return context.import_ir_insts().Add(
SemIR::ImportIRInst(clang_source_loc_id));
}
// Used to convert Clang diagnostics to Carbon diagnostics.
class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
public:
@@ -66,6 +77,9 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
const clang::Diagnostic& info) -> void override {
DiagnosticConsumer::HandleDiagnostic(diag_level, info);
SemIR::ImportIRInstId clang_import_ir_inst_id =
AddImportIRInst(*context_, info.getLocation());
llvm::SmallString<256> message;
info.FormatDiagnostic(message);
@@ -84,40 +98,48 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
std::string diagnostics_str = diagnostics_stream.TakeStr();
switch (diag_level) {
case clang::DiagnosticsEngine::Ignored:
case clang::DiagnosticsEngine::Note:
case clang::DiagnosticsEngine::Remark: {
context_->TODO(
loc_id_,
llvm::formatv(
"Unsupported: C++ diagnostic level for diagnostic\n{0}",
diagnostics_str));
return;
}
case clang::DiagnosticsEngine::Warning:
case clang::DiagnosticsEngine::Error:
case clang::DiagnosticsEngine::Fatal: {
// TODO: Adjust diagnostics to drop the Carbon file here, and then
// remove the "C++:\n" prefix.
CARBON_DIAGNOSTIC(CppInteropParseWarning, Warning, "C++:\n{0}",
std::string);
CARBON_DIAGNOSTIC(CppInteropParseError, Error, "C++:\n{0}",
std::string);
// TODO: This should be part of the location, instead of added as a note
// here.
CARBON_DIAGNOSTIC(InCppImport, Note, "in `Cpp` import");
diagnostic_infos_.push_back({.level = diag_level,
.import_ir_inst_id = clang_import_ir_inst_id,
.message = diagnostics_str});
}
// TODO: Use a more specific location.
context_->emitter()
.Build(SemIR::LocId::None,
diag_level == clang::DiagnosticsEngine::Warning
? CppInteropParseWarning
: CppInteropParseError,
diagnostics_str)
.Note(loc_id_, InCppImport)
.Emit();
return;
// Outputs Carbon diagnostics based on the collected Clang diagnostics. Must
// be called after the AST is set in the context.
auto EmitDiagnostics() -> void {
for (const ClangDiagnosticInfo& info : diagnostic_infos_) {
switch (info.level) {
case clang::DiagnosticsEngine::Ignored:
case clang::DiagnosticsEngine::Note:
case clang::DiagnosticsEngine::Remark: {
context_->TODO(
SemIR::LocId(info.import_ir_inst_id),
llvm::formatv(
"Unsupported: C++ diagnostic level for diagnostic\n{0}",
info.message));
break;
}
case clang::DiagnosticsEngine::Warning:
case clang::DiagnosticsEngine::Error:
case clang::DiagnosticsEngine::Fatal: {
// TODO: Adjust diagnostics to drop the Carbon file here, and then
// remove the "C++:\n" prefix.
CARBON_DIAGNOSTIC(CppInteropParseWarning, Warning, "C++:\n{0}",
std::string);
CARBON_DIAGNOSTIC(CppInteropParseError, Error, "C++:\n{0}",
std::string);
// TODO: This should be part of the location, instead of added as a
// note here.
CARBON_DIAGNOSTIC(InCppImport, Note, "in `Cpp` import");
context_->emitter()
.Build(SemIR::LocId(info.import_ir_inst_id),
info.level == clang::DiagnosticsEngine::Warning
? CppInteropParseWarning
: CppInteropParseError,
info.message)
.Note(loc_id_, InCppImport)
.Emit();
break;
}
}
}
}
@@ -128,13 +150,32 @@ class CarbonClangDiagnosticConsumer : public clang::DiagnosticConsumer {
// The location that triggered calling Clang.
SemIR::LocId loc_id_;
// Information on a Clang diagnostic that can be converted to a Carbon
// diagnostic.
struct ClangDiagnosticInfo {
// The Clang diagnostic level.
clang::DiagnosticsEngine::Level level;
// The ID of the ImportIR instruction referring to the Clang source
// location.
SemIR::ImportIRInstId import_ir_inst_id;
// The Clang diagnostic textual message.
std::string message;
};
// Collects the information for all Clang diagnostics to be converted to
// Carbon diagnostics after the context has been initialized with the Clang
// AST.
llvm::SmallVector<ClangDiagnosticInfo> diagnostic_infos_;
};
} // namespace
// Returns an AST for the C++ imports and a bool that represents whether
// compilation errors where encountered or the generated AST is null due to an
// error.
// error. Sets the AST in the context's `sem_ir`.
// TODO: Consider to always have a (non-null) AST.
static auto GenerateAst(Context& context, llvm::StringRef importing_file_path,
llvm::ArrayRef<Parse::Tree::PackagingNames> imports,
@@ -157,6 +198,10 @@ static auto GenerateAst(Context& context, llvm::StringRef importing_file_path,
// Remove link to the diagnostics consumer before its deletion.
ast->getDiagnostics().setClient(nullptr);
// In order to emit diagnostics, we need the AST.
context.sem_ir().set_cpp_ast(ast.get());
diagnostics_consumer.EmitDiagnostics();
return {std::move(ast), !ast || diagnostics_consumer.getNumErrors() > 0};
}
@@ -212,8 +257,6 @@ auto ImportCppFiles(Context& context, llvm::StringRef importing_file_path,
name_scope.set_cpp_decl_context(
generated_ast->getASTContext().getTranslationUnitDecl());
context.sem_ir().set_cpp_ast(generated_ast.get());
if (ast_has_error) {
name_scope.set_has_error();
}
+44 -31
View File
@@ -37,7 +37,10 @@ static auto InternalAddImportIR(Context& context, SemIR::ImportIR import_ir)
return context.import_irs().Add(import_ir);
}
auto SetApiImportIR(Context& context, SemIR::ImportIR import_ir) -> void {
// Adds a special-cased IR and verifies it received the correct ID.
static auto SetSpecialImportIR(Context& context, SemIR::ImportIR import_ir,
SemIR::ImportIRId expected_import_ir_id)
-> void {
auto ir_id = SemIR::ImportIRId::None;
if (import_ir.sem_ir != nullptr) {
ir_id = AddImportIR(context, import_ir);
@@ -45,8 +48,16 @@ auto SetApiImportIR(Context& context, SemIR::ImportIR import_ir) -> void {
// We don't have a check_ir_id, so add without touching check_ir_map.
ir_id = InternalAddImportIR(context, import_ir);
}
CARBON_CHECK(ir_id == SemIR::ImportIRId::ApiForImpl,
"ApiForImpl must be the first IR");
CARBON_CHECK(ir_id == expected_import_ir_id,
"Actual ImportIRId ($0) != Expected ImportIRId ({1})", ir_id,
expected_import_ir_id);
}
auto SetSpecialImportIRs(Context& context, SemIR::ImportIR import_ir) -> void {
SetSpecialImportIR(context, import_ir, SemIR::ImportIRId::ApiForImpl);
SetSpecialImportIR(context,
{.decl_id = SemIR::InstId::None, .is_export = false},
SemIR::ImportIRId::Cpp);
}
auto AddImportIR(Context& context, SemIR::ImportIR import_ir)
@@ -95,8 +106,8 @@ static auto AddLoadedImportRef(Context& context, SemIR::TypeId type_id,
context.import_ref_ids().push_back(inst_id);
context.constant_values().Set(inst_id, const_id);
context.import_ir_constant_values()[import_ir_inst.ir_id.index].Set(
import_ir_inst.inst_id, const_id);
context.import_ir_constant_values()[import_ir_inst.ir_id().index].Set(
import_ir_inst.inst_id(), const_id);
return inst_id;
}
@@ -111,8 +122,8 @@ static auto GetCanonicalImportIRInst(Context& context,
if (loc_id.kind() == SemIR::LocId::Kind::ImportIRInstId) {
auto import_ir_inst =
cursor_ir->import_ir_insts().Get(loc_id.import_ir_inst_id());
cursor_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id).sem_ir;
cursor_inst_id = import_ir_inst.inst_id;
cursor_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
cursor_inst_id = import_ir_inst.inst_id();
continue;
}
@@ -135,7 +146,7 @@ static auto GetCanonicalImportIRInst(Context& context,
.is_export = false,
.sem_ir = cursor_ir});
}
return {.ir_id = ir_id, .inst_id = cursor_inst_id};
return SemIR::ImportIRInst(ir_id, cursor_inst_id);
}
auto GetCanonicalImportIRInst(Context& context, SemIR::InstId inst_id)
@@ -155,7 +166,7 @@ auto VerifySameCanonicalImportIRInst(Context& context, SemIR::NameId name_id,
return;
}
auto conflict_id =
AddImportRef(context, {.ir_id = new_ir_id, .inst_id = new_inst_id});
AddImportRef(context, SemIR::ImportIRInst(new_ir_id, new_inst_id));
// TODO: Pass the imported name location instead of the conflict id.
DiagnoseDuplicateName(context, name_id, conflict_id, prev_id);
}
@@ -609,7 +620,7 @@ class ImportRefResolver : public ImportContext {
const auto* prev_ir = cursor_ir;
auto prev_inst_id = cursor_inst_id;
cursor_ir = cursor_ir->import_irs().Get(ir_inst.ir_id).sem_ir;
cursor_ir = cursor_ir->import_irs().Get(ir_inst.ir_id()).sem_ir;
cursor_ir_id =
local_context().check_ir_map()[cursor_ir->check_ir_id().index];
if (!cursor_ir_id.has_value()) {
@@ -619,7 +630,7 @@ class ImportRefResolver : public ImportContext {
.is_export = false,
.sem_ir = cursor_ir});
}
cursor_inst_id = ir_inst.inst_id;
cursor_inst_id = ir_inst.inst_id();
CARBON_CHECK(cursor_ir != prev_ir || cursor_inst_id != prev_inst_id,
"{0}", cursor_ir->insts().Get(cursor_inst_id));
@@ -634,7 +645,7 @@ class ImportRefResolver : public ImportContext {
return result;
} else {
result.indirect_insts.push_back(
{.ir_id = cursor_ir_id, .inst_id = cursor_inst_id});
SemIR::ImportIRInst(cursor_ir_id, cursor_inst_id));
}
}
}
@@ -646,8 +657,8 @@ class ImportRefResolver : public ImportContext {
local_constant_values_for_import_insts().Set(inst_id, const_id);
for (auto indirect_inst : indirect_insts) {
local_context()
.import_ir_constant_values()[indirect_inst.ir_id.index]
.Set(indirect_inst.inst_id, const_id);
.import_ir_constant_values()[indirect_inst.ir_id().index]
.Set(indirect_inst.inst_id(), const_id);
}
}
@@ -663,7 +674,7 @@ static auto AddImportRef(ImportContext& context, SemIR::InstId inst_id,
SemIR::EntityNameId entity_name_id =
SemIR::EntityNameId::None) -> SemIR::InstId {
return AddImportRef(context.local_context(),
{.ir_id = context.import_ir_id(), .inst_id = inst_id},
SemIR::ImportIRInst(context.import_ir_id(), inst_id),
entity_name_id);
}
@@ -672,13 +683,13 @@ static auto AddLoadedImportRef(ImportContext& context, SemIR::TypeId type_id,
SemIR::ConstantId const_id) -> SemIR::InstId {
return AddLoadedImportRef(
context.local_context(), type_id,
{.ir_id = context.import_ir_id(), .inst_id = inst_id}, const_id);
SemIR::ImportIRInst(context.import_ir_id(), inst_id), const_id);
}
static auto AddImportIRInst(ImportContext& context, SemIR::InstId inst_id)
-> SemIR::ImportIRInstId {
return context.local_import_ir_insts().Add(
{.ir_id = context.import_ir_id(), .inst_id = inst_id});
SemIR::ImportIRInst(context.import_ir_id(), inst_id));
}
// Computes, sets, and returns the constant value for an instruction.
@@ -3267,10 +3278,11 @@ static auto GetInstForLoad(Context& context,
// The first ImportIRInst is added directly because the IR doesn't need to be
// localized.
import_ir_insts.push_back(import_ir_inst);
const auto* cursor_ir = context.import_irs().Get(import_ir_inst.ir_id).sem_ir;
const auto* cursor_ir =
context.import_irs().Get(import_ir_inst.ir_id()).sem_ir;
while (true) {
auto cursor_inst = cursor_ir->insts().Get(import_ir_inst.inst_id);
auto cursor_inst = cursor_ir->insts().Get(import_ir_inst.inst_id());
auto import_ref = cursor_inst.TryAs<SemIR::ImportRefUnloaded>();
if (!import_ref) {
@@ -3280,12 +3292,12 @@ static auto GetInstForLoad(Context& context,
import_ir_inst =
cursor_ir->import_ir_insts().Get(import_ref->import_ir_inst_id);
cursor_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id).sem_ir;
import_ir_insts.push_back(
{.ir_id = AddImportIR(context, {.decl_id = SemIR::InstId::None,
.is_export = false,
.sem_ir = cursor_ir}),
.inst_id = import_ir_inst.inst_id});
cursor_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
import_ir_insts.push_back(SemIR::ImportIRInst(
AddImportIR(context, {.decl_id = SemIR::InstId::None,
.is_export = false,
.sem_ir = cursor_ir}),
import_ir_inst.inst_id()));
}
}
@@ -3302,9 +3314,9 @@ auto LoadImportRef(Context& context, SemIR::InstId inst_id) -> void {
// The last indirect instruction is the one to resolve. Pop it here because
// Resolve will assign the constant.
auto load_ir_inst = indirect_insts.pop_back_val();
ImportRefResolver resolver(&context, load_ir_inst.ir_id);
ImportRefResolver resolver(&context, load_ir_inst.ir_id());
auto type_id = resolver.ResolveType(load_type_id);
auto constant_id = resolver.Resolve(load_ir_inst.inst_id);
auto constant_id = resolver.Resolve(load_ir_inst.inst_id());
// Replace the ImportRefUnloaded instruction with ImportRefLoaded. This
// doesn't use ReplacePlaceholderImportedInst because it would trigger
@@ -3318,8 +3330,8 @@ auto LoadImportRef(Context& context, SemIR::InstId inst_id) -> void {
// Store the constant for both the ImportRefLoaded and indirect instructions.
context.constant_values().Set(inst_id, constant_id);
for (const auto& import_ir_inst : indirect_insts) {
context.import_ir_constant_values()[import_ir_inst.ir_id.index].Set(
import_ir_inst.inst_id, constant_id);
context.import_ir_constant_values()[import_ir_inst.ir_id().index].Set(
import_ir_inst.inst_id(), constant_id);
}
}
@@ -3370,8 +3382,9 @@ auto CheckCompatibleImportedNodeKind(Context& context,
SemIR::ImportIRInstId imported_loc_id,
SemIR::InstKind kind) -> void {
auto& import_ir_inst = context.import_ir_insts().Get(imported_loc_id);
const auto* import_ir = context.import_irs().Get(import_ir_inst.ir_id).sem_ir;
auto imported_kind = import_ir->insts().Get(import_ir_inst.inst_id).kind();
const auto* import_ir =
context.import_irs().Get(import_ir_inst.ir_id()).sem_ir;
auto imported_kind = import_ir->insts().Get(import_ir_inst.inst_id()).kind();
CARBON_CHECK(
HasCompatibleImportedNodeKind(imported_kind, kind),
"Node of kind {0} created with location of imported node of kind {1}",
+4 -3
View File
@@ -11,9 +11,10 @@
namespace Carbon::Check {
// Sets the IR for ImportIRId::ApiForImpl. Should be called before AddImportIR
// in order to ensure the correct ID is assigned.
auto SetApiImportIR(Context& context, SemIR::ImportIR import_ir) -> void;
// Sets the IRs for `ImportIRId::ApiForImpl` from `import_ir`, and
// `ImportIRId::Cpp` from defaults. Should be called before `AddImportIR` in
// order to ensure the correct IDs are assigned.
auto SetSpecialImportIRs(Context& context, SemIR::ImportIR import_ir) -> void;
// Adds an ImportIR, returning the ID. May use an existing ID if already added.
auto AddImportIR(Context& context, SemIR::ImportIR import_ir)
+1
View File
@@ -15,6 +15,7 @@
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {}}
@@ -22,18 +22,18 @@ import Cpp;
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp_library_empty.carbon:[[@LINE+4]]:1: error: `Cpp` import missing library [CppInteropMissingLibrary]
// CHECK:STDERR: fail_import_cpp_library_empty.carbon:[[@LINE+9]]:1: error: `Cpp` import missing library [CppInteropMissingLibrary]
// CHECK:STDERR: import Cpp library "";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
import Cpp library "";
// --- fail_import_cpp_library_file_with_quotes.carbon
// CHECK:STDERR: fail_import_cpp_library_file_with_quotes.carbon: error: C++:
// CHECK:STDERR: fail_import_cpp_library_file_with_quotes.carbon.generated.cpp_imports.h:1: error: C++:
// CHECK:STDERR: fail_import_cpp_library_file_with_quotes.carbon.generated.cpp_imports.h:1:10: fatal error: '\"foo.h\"' file not found
// CHECK:STDERR: 1 | #include "\"foo.h\""
// CHECK:STDERR: | ^~~~~~~~~~~
// CHECK:STDERR: [CppInteropParseError]
import Cpp library "";
// --- fail_import_cpp_library_file_with_quotes.carbon
library "[[@TEST_NAME]]";
@@ -10,15 +10,15 @@
// --- one_error.h
// CHECK:STDERR: ./one_error.h:[[@LINE+6]]: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_one_error.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error.h:[[@LINE+4]]:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
#error "error1"
// --- fail_import_cpp_file_with_one_error.carbon
// CHECK:STDERR: fail_import_cpp_file_with_one_error.carbon: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_one_error.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
library "[[@TEST_NAME]]";
@@ -30,16 +30,16 @@ import Cpp library "one_error.h";
// --- multiple_errors.h
// CHECK:STDERR: ./multiple_errors.h:[[@LINE+6]]: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors.h:[[@LINE+4]]:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
#error "error1"
#error "error2"
// --- fail_import_cpp_file_with_multiple_errors.carbon
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors.carbon: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
library "[[@TEST_NAME]]";
@@ -47,10 +47,10 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR: import Cpp library "multiple_errors.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors.carbon: error: C++:
// CHECK:STDERR: ./multiple_errors.h:9: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors.h:3:2: error: "error2"
// CHECK:STDERR: 3 | #error "error2"
// CHECK:STDERR: ./multiple_errors.h:9:2: error: "error2"
// CHECK:STDERR: 9 | #error "error2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
@@ -61,15 +61,15 @@ import Cpp library "multiple_errors.h";
// --- one_warning.h
// CHECK:STDERR: ./one_warning.h:[[@LINE+6]]: warning: C++:
// CHECK:STDERR: In file included from import_cpp_file_with_one_warning.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_warning.h:[[@LINE+4]]:2: warning: "warning1"
// CHECK:STDERR: 8 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
#warning "warning1"
// --- import_cpp_file_with_one_warning.carbon
// CHECK:STDERR: import_cpp_file_with_one_warning.carbon: warning: C++:
// CHECK:STDERR: In file included from import_cpp_file_with_one_warning.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1"
// CHECK:STDERR: 2 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
library "[[@TEST_NAME]]";
@@ -81,17 +81,17 @@ import Cpp library "one_warning.h";
// --- multiple_warnings.h
// CHECK:STDERR: ./multiple_warnings.h:[[@LINE+6]]: warning: C++:
// CHECK:STDERR: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_warnings.h:[[@LINE+4]]:2: warning: "warning1"
// CHECK:STDERR: 8 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
#warning "warning1"
#warning "warning2"
#warning "warning3"
// --- import_cpp_file_with_multiple_warnings.carbon
// CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon: warning: C++:
// CHECK:STDERR: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_warnings.h:2:2: warning: "warning1"
// CHECK:STDERR: 2 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
library "[[@TEST_NAME]]";
@@ -99,20 +99,20 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR: import Cpp library "multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_warnings.h:9: warning: C++:
// CHECK:STDERR: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_warnings.h:3:2: warning: "warning2"
// CHECK:STDERR: 3 | #warning "warning2"
// CHECK:STDERR: ./multiple_warnings.h:9:2: warning: "warning2"
// CHECK:STDERR: 9 | #warning "warning2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon:[[@LINE+14]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_warnings.h:10: warning: C++:
// CHECK:STDERR: In file included from import_cpp_file_with_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_warnings.h:4:2: warning: "warning3"
// CHECK:STDERR: 4 | #warning "warning3"
// CHECK:STDERR: ./multiple_warnings.h:10:2: warning: "warning3"
// CHECK:STDERR: 10 | #warning "warning3"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: import_cpp_file_with_multiple_warnings.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
@@ -123,16 +123,16 @@ import Cpp library "multiple_warnings.h";
// --- one_error_and_one_warning.h
// CHECK:STDERR: ./one_error_and_one_warning.h:[[@LINE+6]]: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error_and_one_warning.h:[[@LINE+4]]:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
#error "error1"
#warning "warning1"
// --- fail_import_cpp_file_with_one_error_and_one_warning.carbon
// CHECK:STDERR: fail_import_cpp_file_with_one_error_and_one_warning.carbon: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error_and_one_warning.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
library "[[@TEST_NAME]]";
@@ -140,10 +140,10 @@ library "[[@TEST_NAME]]";
// CHECK:STDERR: import Cpp library "one_error_and_one_warning.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_file_with_one_error_and_one_warning.carbon: warning: C++:
// CHECK:STDERR: ./one_error_and_one_warning.h:9: warning: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_one_error_and_one_warning.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error_and_one_warning.h:3:2: warning: "warning1"
// CHECK:STDERR: 3 | #warning "warning1"
// CHECK:STDERR: ./one_error_and_one_warning.h:9:2: warning: "warning1"
// CHECK:STDERR: 9 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_cpp_file_with_one_error_and_one_warning.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
@@ -154,6 +154,12 @@ import Cpp library "one_error_and_one_warning.h";
// --- multiple_errors_and_multiple_warnings.h
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:[[@LINE+6]]: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:[[@LINE+4]]:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
#error "error1"
#error "error2"
#warning "warning1"
@@ -161,227 +167,242 @@ import Cpp library "one_error_and_one_warning.h";
#warning "warning3"
// --- fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+44]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+50]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon: error: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:9: error: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3:2: error: "error2"
// CHECK:STDERR: 3 | #error "error2"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:9:2: error: "error2"
// CHECK:STDERR: 9 | #error "error2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+34]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+40]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:10: warning: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4:2: warning: "warning1"
// CHECK:STDERR: 4 | #warning "warning1"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:10:2: warning: "warning1"
// CHECK:STDERR: 10 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+24]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+30]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:11: warning: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5:2: warning: "warning2"
// CHECK:STDERR: 5 | #warning "warning2"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:11:2: warning: "warning2"
// CHECK:STDERR: 11 | #warning "warning2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+14]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+20]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:12: warning: C++:
// CHECK:STDERR: In file included from fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6:2: warning: "warning3"
// CHECK:STDERR: 6 | #warning "warning3"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:12:2: warning: "warning3"
// CHECK:STDERR: 12 | #warning "warning3"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_cpp_file_with_multiple_errors_and_multiple_warnings.carbon:[[@LINE+10]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: ./one_warning.h:8: warning: C++:
// CHECK:STDERR: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_warning.h:8:2: warning: "warning1"
// CHECK:STDERR: 8 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
import Cpp library "multiple_errors_and_multiple_warnings.h";
// --- import_multiple_cpp_files_with_warnings.carbon
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon: warning: C++:
// CHECK:STDERR: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1"
// CHECK:STDERR: 2 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
library "[[@TEST_NAME]]";
import Cpp library "one_warning.h";
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+34]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+40]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_warnings.h:8: warning: C++:
// CHECK:STDERR: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_warnings.h:2:2: warning: "warning1"
// CHECK:STDERR: 2 | #warning "warning1"
// CHECK:STDERR: ./multiple_warnings.h:8:2: warning: "warning1"
// CHECK:STDERR: 8 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+24]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+30]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_warnings.h:9: warning: C++:
// CHECK:STDERR: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_warnings.h:3:2: warning: "warning2"
// CHECK:STDERR: 3 | #warning "warning2"
// CHECK:STDERR: ./multiple_warnings.h:9:2: warning: "warning2"
// CHECK:STDERR: 9 | #warning "warning2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+14]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+20]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon: warning: C++:
// CHECK:STDERR: ./multiple_warnings.h:10: warning: C++:
// CHECK:STDERR: In file included from import_multiple_cpp_files_with_warnings.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_warnings.h:4:2: warning: "warning3"
// CHECK:STDERR: 4 | #warning "warning3"
// CHECK:STDERR: ./multiple_warnings.h:10:2: warning: "warning3"
// CHECK:STDERR: 10 | #warning "warning3"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import_multiple_cpp_files_with_warnings.carbon:[[@LINE+10]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: ./one_error_and_one_warning.h:8: error: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error_and_one_warning.h:8:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
import Cpp library "multiple_warnings.h";
// --- fail_import_multiple_cpp_files_with_warnings_and_errors.carbon
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: error: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error_and_one_warning.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
library "[[@TEST_NAME]]";
import Cpp library "one_error_and_one_warning.h";
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+64]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+66]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: warning: C++:
// CHECK:STDERR: ./one_error_and_one_warning.h:9: warning: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_error_and_one_warning.h:3:2: warning: "warning1"
// CHECK:STDERR: 3 | #warning "warning1"
// CHECK:STDERR: ./one_error_and_one_warning.h:9:2: warning: "warning1"
// CHECK:STDERR: 9 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+54]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+56]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: error: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:8: error: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:8:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+44]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+46]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: error: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:9: error: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:3:2: error: "error2"
// CHECK:STDERR: 3 | #error "error2"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:9:2: error: "error2"
// CHECK:STDERR: 9 | #error "error2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+34]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+36]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: warning: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:10: warning: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:4:2: warning: "warning1"
// CHECK:STDERR: 4 | #warning "warning1"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:10:2: warning: "warning1"
// CHECK:STDERR: 10 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+24]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+26]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: warning: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:11: warning: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:5:2: warning: "warning2"
// CHECK:STDERR: 5 | #warning "warning2"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:11:2: warning: "warning2"
// CHECK:STDERR: 11 | #warning "warning2"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+14]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+16]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon: warning: C++:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:12: warning: C++:
// CHECK:STDERR: In file included from fail_import_multiple_cpp_files_with_warnings_and_errors.carbon.generated.cpp_imports.h:2:
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:6:2: warning: "warning3"
// CHECK:STDERR: 6 | #warning "warning3"
// CHECK:STDERR: ./multiple_errors_and_multiple_warnings.h:12:2: warning: "warning3"
// CHECK:STDERR: 12 | #warning "warning3"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_multiple_cpp_files_with_warnings_and_errors.carbon:[[@LINE+6]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "multiple_errors_and_multiple_warnings.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: ./one_error.h:8: error: C++:
// CHECK:STDERR: In file included from fail_import_indirect_error.carbon.generated.cpp_imports.h:1:
import Cpp library "multiple_errors_and_multiple_warnings.h";
// --- indirect_error.h
// CHECK:STDERR: In file included from ./indirect_error.h:[[@LINE+5]]:
// CHECK:STDERR: ./one_error.h:8:2: error: "error1"
// CHECK:STDERR: 8 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
#include "one_error.h"
// --- fail_import_indirect_error.carbon
// CHECK:STDERR: fail_import_indirect_error.carbon: error: C++:
// CHECK:STDERR: In file included from fail_import_indirect_error.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: In file included from ./indirect_error.h:2:
// CHECK:STDERR: ./one_error.h:2:2: error: "error1"
// CHECK:STDERR: 2 | #error "error1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseError]
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_import_indirect_error.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: fail_import_indirect_error.carbon:[[@LINE+6]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "indirect_error.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: ./one_warning.h:8: warning: C++:
// CHECK:STDERR: In file included from import_indirect_warning.carbon.generated.cpp_imports.h:1:
import Cpp library "indirect_error.h";
// --- indirect_warning.h
// CHECK:STDERR: In file included from ./indirect_warning.h:[[@LINE+5]]:
// CHECK:STDERR: ./one_warning.h:8:2: warning: "warning1"
// CHECK:STDERR: 8 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
#include "one_warning.h"
// --- import_indirect_warning.carbon
// CHECK:STDERR: import_indirect_warning.carbon: warning: C++:
// CHECK:STDERR: In file included from import_indirect_warning.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: In file included from ./indirect_warning.h:2:
// CHECK:STDERR: ./one_warning.h:2:2: warning: "warning1"
// CHECK:STDERR: 2 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
library "[[@TEST_NAME]]";
// CHECK:STDERR: import_indirect_warning.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import_indirect_warning.carbon:[[@LINE+10]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "indirect_warning.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: ./one_warning.h:8: warning: C++:
// CHECK:STDERR: In file included from fail_import_cpp_library_lexer_error.carbon.generated.cpp_imports.h:1:
// CHECK:STDERR: ./one_warning.h:8:2: warning: "warning1"
// CHECK:STDERR: 8 | #warning "warning1"
// CHECK:STDERR: | ^
// CHECK:STDERR: [CppInteropParseWarning]
import Cpp library "indirect_warning.h";
// --- fail_import_cpp_library_lexer_error.carbon
library "[[@TEST_NAME]]"; // Trailing comment
// TODO: Move this warning to be after the lexer trailing comment error.
// CHECK:STDERR: fail_import_cpp_library_lexer_error.carbon:[[@LINE+8]]:1: note: in `Cpp` import [InCppImport]
// CHECK:STDERR: import Cpp library "one_warning.h";
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// CHECK:STDERR:
// CHECK:STDERR: fail_import_cpp_library_lexer_error.carbon:[[@LINE-7]]:44: error: trailing comments are not permitted [TrailingComment]
// CHECK:STDERR: library "import_cpp_library_lexer_error"; // Trailing comment
// CHECK:STDERR: ^
// CHECK:STDERR:
import Cpp library "one_warning.h";
// CHECK:STDOUT: --- fail_import_cpp_file_with_one_error.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
@@ -560,3 +581,20 @@ import Cpp library "indirect_warning.h";
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: --- fail_import_cpp_library_lexer_error.carbon
// CHECK:STDOUT:
// CHECK:STDOUT: imports {
// CHECK:STDOUT: %Cpp: <namespace> = namespace file.%Cpp.import_cpp, [concrete] {
// CHECK:STDOUT: import Cpp//...
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
// CHECK:STDOUT: file {
// CHECK:STDOUT: package: <namespace> = namespace [concrete] {
// CHECK:STDOUT: .Cpp = imports.%Cpp
// CHECK:STDOUT: }
// CHECK:STDOUT: %Cpp.import_cpp = import_cpp {
// CHECK:STDOUT: import Cpp "one_warning.h"
// CHECK:STDOUT: }
// CHECK:STDOUT: }
// CHECK:STDOUT:
@@ -7,14 +7,14 @@
// TIP: bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/check/testdata/interop/cpp/no_prelude/file_not_found.carbon
// TIP: To dump output, run:
// TIP: bazel run //toolchain/testing:file_test -- --dump_output --file_tests=toolchain/check/testdata/interop/cpp/no_prelude/file_not_found.carbon
// --- fail_cpp_file_not_found.carbon
// CHECK:STDERR: fail_cpp_file_not_found.carbon: error: C++:
// CHECK:STDERR: fail_cpp_file_not_found.carbon.generated.cpp_imports.h:1: error: C++:
// CHECK:STDERR: fail_cpp_file_not_found.carbon.generated.cpp_imports.h:1:10: fatal error: 'not_found.h' file not found
// CHECK:STDERR: 1 | #include "not_found.h"
// CHECK:STDERR: | ^~~~~~~~~~~~~
// CHECK:STDERR: [CppInteropParseError]
// --- fail_cpp_file_not_found.carbon
library "[[@TEST_NAME]]";
// CHECK:STDERR: fail_cpp_file_not_found.carbon:[[@LINE+4]]:1: note: in `Cpp` import [InCppImport]
+2 -2
View File
@@ -573,13 +573,13 @@ auto CompilationUnit::PostCheck() -> void {
auto import_ir_inst =
file->import_ir_insts().Get(loc_id.import_ir_inst_id());
const auto* import_file =
file->import_irs().Get(import_ir_inst.ir_id).sem_ir;
file->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
CARBON_CHECK(import_file);
if (!IncludeInDumps(import_file->filename())) {
return false;
}
file = import_file;
entity_inst_id = import_ir_inst.inst_id;
entity_inst_id = import_ir_inst.inst_id();
}
};
@@ -31,6 +31,7 @@ fn B() {
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst15}}
@@ -105,10 +106,11 @@ fn B() {
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst15, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir2: {decl_id: inst15, is_export: false}
// CHECK:STDOUT: import_ir_insts:
// CHECK:STDOUT: import_ir_inst0: {ir_id: ir1, inst_id: inst15}
// CHECK:STDOUT: import_ir_inst1: {ir_id: ir1, inst_id: inst15}
// CHECK:STDOUT: import_ir_inst0: {ir_id: ir2, inst_id: inst15}
// CHECK:STDOUT: import_ir_inst1: {ir_id: ir2, inst_id: inst15}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst16, name0: inst17}}
// CHECK:STDOUT: name_scope1: {inst: inst16, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst22}}
+5 -3
View File
@@ -31,6 +31,7 @@ fn B() {
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst15}}
@@ -85,10 +86,11 @@ fn B() {
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst15, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir2: {decl_id: inst15, is_export: false}
// CHECK:STDOUT: import_ir_insts:
// CHECK:STDOUT: import_ir_inst0: {ir_id: ir1, inst_id: inst15}
// CHECK:STDOUT: import_ir_inst1: {ir_id: ir1, inst_id: inst15}
// CHECK:STDOUT: import_ir_inst0: {ir_id: ir2, inst_id: inst15}
// CHECK:STDOUT: import_ir_inst1: {ir_id: ir2, inst_id: inst15}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name1: inst16, name0: inst17}}
// CHECK:STDOUT: name_scope1: {inst: inst16, parent_scope: name_scope0, has_error: false, extended_scopes: [], names: {name1: inst22}}
@@ -21,6 +21,7 @@ fn Foo(n: ()) -> ((), ()) {
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst34}}
+1
View File
@@ -21,6 +21,7 @@ fn Foo[T:! type](n: T) -> (T, ()) {
// CHECK:STDOUT: sem_ir:
// CHECK:STDOUT: import_irs:
// CHECK:STDOUT: ir0: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: ir1: {decl_id: inst<none>, is_export: false}
// CHECK:STDOUT: import_ir_insts: {}
// CHECK:STDOUT: name_scopes:
// CHECK:STDOUT: name_scope0: {inst: inst14, parent_scope: name_scope<none>, has_error: false, extended_scopes: [], names: {name0: inst36}}
+6 -5
View File
@@ -15,7 +15,8 @@ static auto FollowImportRef(
const File*& cursor_ir, InstId& cursor_inst_id,
ImportIRInstId import_ir_inst_id) -> void {
auto import_ir_inst = cursor_ir->import_ir_insts().Get(import_ir_inst_id);
const auto& import_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id);
CARBON_CHECK(import_ir_inst.ir_id() != ImportIRId::Cpp);
const auto& import_ir = cursor_ir->import_irs().Get(import_ir_inst.ir_id());
CARBON_CHECK(import_ir.decl_id.has_value(),
"If we get `None` locations here, we may need to more "
"thoroughly track ImportDecls.");
@@ -31,9 +32,9 @@ static auto FollowImportRef(
auto implicit_import_ir_inst =
cursor_ir->import_ir_insts().Get(import_loc_id.import_ir_inst_id());
const auto& implicit_ir =
cursor_ir->import_irs().Get(implicit_import_ir_inst.ir_id);
auto implicit_loc_id =
implicit_ir.sem_ir->insts().GetLocId(implicit_import_ir_inst.inst_id);
cursor_ir->import_irs().Get(implicit_import_ir_inst.ir_id());
auto implicit_loc_id = implicit_ir.sem_ir->insts().GetLocId(
implicit_import_ir_inst.inst_id());
CARBON_CHECK(implicit_loc_id.kind() == SemIR::LocId::Kind::NodeId,
"Should only be one layer of implicit imports");
absolute_node_ids.push_back(
@@ -54,7 +55,7 @@ static auto FollowImportRef(
}
cursor_ir = import_ir.sem_ir;
cursor_inst_id = import_ir_inst.inst_id;
cursor_inst_id = import_ir_inst.inst_id();
}
// Returns true if this is the final parse node location. If the location is is
+2 -2
View File
@@ -50,8 +50,8 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory {
case ImportRefLoaded::Kind: {
auto import_ir_inst = ir->import_ir_insts().Get(
untyped_inst.As<SemIR::AnyImportRef>().import_ir_inst_id);
ir = ir->import_irs().Get(import_ir_inst.ir_id).sem_ir;
inst_id = import_ir_inst.inst_id;
ir = ir->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
inst_id = import_ir_inst.inst_id();
continue;
}
+11
View File
@@ -198,6 +198,7 @@ class File : public Printable<File> {
return import_cpps_;
}
auto cpp_ast() -> clang::ASTUnit* { return cpp_ast_; }
auto cpp_ast() const -> const clang::ASTUnit* { return cpp_ast_; }
// TODO: When the AST can be created before creating `File`, initialize the
// pointer in the constructor and remove this function. This is part of
// https://github.com/carbon-language/carbon-lang/issues/4666
@@ -231,6 +232,13 @@ class File : public Printable<File> {
return expr_regions_;
}
auto clang_source_locs() -> ValueStore<ClangSourceLocId>& {
return clang_source_locs_;
}
auto clang_source_locs() const -> const ValueStore<ClangSourceLocId>& {
return clang_source_locs_;
}
auto top_inst_block_id() const -> InstBlockId { return top_inst_block_id_; }
auto set_top_inst_block_id(InstBlockId block_id) -> void {
top_inst_block_id_ = block_id;
@@ -354,6 +362,9 @@ class File : public Printable<File> {
// Single-entry/single-exit regions that are referenced as units, e.g. because
// they represent expressions.
ValueStore<ExprRegionId> expr_regions_;
// C++ source locations for C++ interop.
ValueStore<ClangSourceLocId> clang_source_locs_;
};
} // namespace Carbon::SemIR
+7 -6
View File
@@ -566,7 +566,7 @@ class FormatterImpl {
auto loc_id = sem_ir_->insts().GetLocId(first_owning_decl_id);
if (loc_id.kind() == SemIR::LocId::Kind::ImportIRInstId) {
auto import_ir_id =
sem_ir_->import_ir_insts().Get(loc_id.import_ir_inst_id()).ir_id;
sem_ir_->import_ir_insts().Get(loc_id.import_ir_inst_id()).ir_id();
const auto* import_file =
sem_ir_->import_irs().Get(import_ir_id).sem_ir;
pending_imported_from_ = import_file->filename();
@@ -1149,7 +1149,7 @@ class FormatterImpl {
llvm::StringLiteral loaded_label) -> void {
out_ << " ";
auto import_ir_inst = sem_ir_->import_ir_insts().Get(import_ir_inst_id);
FormatArg(import_ir_inst.ir_id);
FormatArg(import_ir_inst.ir_id());
out_ << ", ";
if (entity_name_id.has_value()) {
// Prefer to show the entity name when possible.
@@ -1157,17 +1157,18 @@ class FormatterImpl {
} else {
// Show a name based on the location when possible, or the numeric
// instruction as a last resort.
const auto& import_ir = sem_ir_->import_irs().Get(import_ir_inst.ir_id);
auto loc_id = import_ir.sem_ir->insts().GetLocId(import_ir_inst.inst_id);
const auto& import_ir = sem_ir_->import_irs().Get(import_ir_inst.ir_id());
auto loc_id =
import_ir.sem_ir->insts().GetLocId(import_ir_inst.inst_id());
switch (loc_id.kind()) {
case SemIR::LocId::Kind::None: {
out_ << import_ir_inst.inst_id << " [no loc]";
out_ << import_ir_inst.inst_id() << " [no loc]";
break;
}
case SemIR::LocId::Kind::ImportIRInstId: {
// TODO: Probably don't want to format each indirection, but maybe
// reuse GetCanonicalImportIRInst?
out_ << import_ir_inst.inst_id << " [indirect]";
out_ << import_ir_inst.inst_id() << " [indirect]";
break;
}
case SemIR::LocId::Kind::NodeId: {
+22 -1
View File
@@ -14,10 +14,19 @@
#include "toolchain/diagnostics/diagnostic_emitter.h"
#include "toolchain/parse/node_ids.h"
// NOLINTNEXTLINE(readability-identifier-naming)
namespace clang {
// Forward declare indexed types, for integration with ValueStore.
class SourceLocation;
} // namespace clang
namespace Carbon::SemIR {
// Forward declare indexed types, for integration with ValueStore.
class File;
class ImportIRInst;
class Inst;
class NameScope;
struct AssociatedConstant;
@@ -32,7 +41,6 @@ struct Specific;
struct SpecificInterface;
struct ImportCpp;
struct ImportIR;
struct ImportIRInst;
struct Impl;
struct Interface;
struct StructTypeField;
@@ -409,10 +417,15 @@ struct ImportIRId : public IdBase<ImportIRId> {
// instructions.
static const ImportIRId ApiForImpl;
// The `Cpp` import. A null entry is added if there is none, in which case
// this ID should not show up in instructions.
static const ImportIRId Cpp;
using IdBase::IdBase;
};
constexpr ImportIRId ImportIRId::ApiForImpl = ImportIRId(0);
constexpr ImportIRId ImportIRId::Cpp = ImportIRId(ApiForImpl.index + 1);
// A boolean value.
struct BoolValue : public IdBase<BoolValue> {
@@ -757,6 +770,14 @@ struct TypeId : public IdBase<TypeId> {
auto Print(llvm::raw_ostream& out) const -> void;
};
// The ID of a Clang Source Location.
struct ClangSourceLocId : public IdBase<ClangSourceLocId> {
static constexpr llvm::StringLiteral Label = "clang_source_loc";
using ValueType = clang::SourceLocation;
using IdBase::IdBase;
};
// An index for element access, for structs, tuples, and classes.
struct ElementIndex : public IndexBase<ElementIndex> {
static constexpr llvm::StringLiteral Label = "element";
+44 -6
View File
@@ -29,19 +29,57 @@ struct ImportIR : public Printable<ImportIR> {
static_assert(sizeof(ImportIR) == 8 + sizeof(uintptr_t), "Unexpected size");
// A reference to an instruction in an imported IR. Used for diagnostics with
// LocId.
struct ImportIRInst : public Printable<ImportIRInst> {
// LocId. For a `Cpp` import, points to a Clang source location.
class ImportIRInst : public Printable<ImportIRInst> {
public:
// Constructor for a non-`Cpp` import.
explicit ImportIRInst(ImportIRId ir_id, InstId inst_id)
: ir_id_(ir_id), inst_id_(inst_id) {
CARBON_CHECK(ir_id != ImportIRId::Cpp);
}
// Constructor for a `Cpp` import.
explicit ImportIRInst(ClangSourceLocId clang_source_loc_id)
: ir_id_(SemIR::ImportIRId::Cpp),
clang_source_loc_id_(clang_source_loc_id) {}
auto Print(llvm::raw_ostream& out) const -> void {
out << "{ir_id: " << ir_id << ", inst_id: " << inst_id << "}";
out << "{ir_id: " << ir_id() << ", ";
if (ir_id() == ImportIRId::Cpp) {
out << "clang_source_loc_id: " << clang_source_loc_id();
} else {
out << "inst_id: " << inst_id();
}
out << "}";
}
friend auto operator==(const ImportIRInst& lhs, const ImportIRInst& rhs)
-> bool {
return lhs.ir_id == rhs.ir_id && lhs.inst_id == rhs.inst_id;
return lhs.ir_id() == rhs.ir_id() &&
(lhs.ir_id() == ImportIRId::Cpp
? lhs.clang_source_loc_id() == rhs.clang_source_loc_id()
: lhs.inst_id() == rhs.inst_id());
}
ImportIRId ir_id;
InstId inst_id;
auto ir_id() const -> ImportIRId { return ir_id_; }
auto inst_id() const -> InstId {
CARBON_CHECK(ir_id() != ImportIRId::Cpp);
return inst_id_;
}
auto clang_source_loc_id() const -> ClangSourceLocId {
CARBON_CHECK(ir_id() == ImportIRId::Cpp);
return clang_source_loc_id_;
}
private:
ImportIRId ir_id_;
union {
// Set iff `ir_id != ImportIRId::Cpp`.
InstId inst_id_;
// Set iff `ir_id == ImportIRId::Cpp`.
ClangSourceLocId clang_source_loc_id_;
};
};
} // namespace Carbon::SemIR
+2 -1
View File
@@ -293,7 +293,8 @@ struct Worklist {
auto Add(ImportIRInstId ir_inst_id) -> void {
auto ir_inst = sem_ir->import_ir_insts().Get(ir_inst_id);
AddInFile(sem_ir->import_irs().Get(ir_inst.ir_id).sem_ir, ir_inst.inst_id);
AddInFile(sem_ir->import_irs().Get(ir_inst.ir_id()).sem_ir,
ir_inst.inst_id());
}
template <typename T>
+1 -1
View File
@@ -737,7 +737,7 @@ auto InstNamer::CollectNamesInBlock(ScopeId top_scope_id,
auto import_ir_inst =
sem_ir_->import_ir_insts().Get(inst.import_ir_inst_id);
const auto& import_ir =
*sem_ir_->import_irs().Get(import_ir_inst.ir_id).sem_ir;
*sem_ir_->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
auto package_id = import_ir.package_id();
if (auto ident_id = package_id.AsIdentifierId(); ident_id.has_value()) {
out << import_ir.identifiers().Get(ident_id);
+1 -1
View File
@@ -56,7 +56,7 @@ TEST(SemIRTest, Yaml) {
auto type_builtin = Pair(type_id, Yaml::Mapping(_));
auto file = Yaml::Mapping(ElementsAre(
Pair("import_irs", Yaml::Mapping(SizeIs(1))),
Pair("import_irs", Yaml::Mapping(SizeIs(2))),
Pair("import_ir_insts", Yaml::Mapping(SizeIs(0))),
Pair("name_scopes", Yaml::Mapping(SizeIs(1))),
Pair("entity_names", Yaml::Mapping(SizeIs(1))),