mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Implement 'extern library' support for functions. (#4220)
Support for types (particularly classes) is left as a TODO. There's also an issue I'm observing with a "define in impl" test, but this is probably an issue with resolving the prior declaration which is imported indirectly. The PR was already feeling big, so I'm choosing to cut here. Note, this does not implement the rule "The owning library's API file must import the `extern` declaration, and must also contain a declaration."
This commit is contained in:
@@ -120,13 +120,35 @@ auto RestrictExternModifierOnDecl(Context& context,
|
||||
DeclIntroducerState& introducer,
|
||||
std::optional<SemIR::Inst> parent_scope_inst,
|
||||
bool is_definition) -> void {
|
||||
if (is_definition) {
|
||||
ForbidModifiersOnDecl(context, introducer, KeywordModifierSet::Extern,
|
||||
" that provides a definition");
|
||||
if (!introducer.modifier_set.HasAnyOf(KeywordModifierSet::Extern)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parent_scope_inst && !parent_scope_inst->Is<SemIR::Namespace>()) {
|
||||
ForbidModifiersOnDecl(context, introducer, KeywordModifierSet::Extern,
|
||||
" that is a member");
|
||||
// Treat as unset.
|
||||
introducer.extern_library = SemIR::LibraryNameId::Invalid;
|
||||
return;
|
||||
}
|
||||
|
||||
if (introducer.extern_library == context.sem_ir().library_id()) {
|
||||
// This prints an error for `extern library`, but doesn't drop it because we
|
||||
// assume there is some other, correct value that we just don't know here.
|
||||
CARBON_DIAGNOSTIC(ExternLibraryIsCurrentLibrary, Error,
|
||||
"`extern library` cannot specify the current library.");
|
||||
context.emitter().Emit(introducer.modifier_node_id(ModifierOrder::Extern),
|
||||
ExternLibraryIsCurrentLibrary);
|
||||
introducer.extern_library = SemIR::LibraryNameId::Error;
|
||||
// Right now this can produce both this and the below diagnostic.
|
||||
}
|
||||
|
||||
if (is_definition && introducer.extern_library.is_valid()) {
|
||||
CARBON_DIAGNOSTIC(ExternLibraryOnDefinition, Error,
|
||||
"A library cannot be provided for an `extern` modifier "
|
||||
"on a definition.");
|
||||
context.emitter().Emit(introducer.modifier_node_id(ModifierOrder::Extern),
|
||||
ExternLibraryOnDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user