Commit Graph
60 Commits
Author SHA1 Message Date
Dana Jansens 64139e5d65 Stop using Map for the cache in InstFingerprinter (#6019)
This takes the debug runtime of
`toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon`
from 4.7s down to about 4s (so 15% faster overall).

There's still lots of room to improve this test which seems to be
hitting lots of pathological behaviour, but InstNamer is 30% of the
runtime, with fingerprinting's `InstFingerprinter::GetOrCompute`
consuming 10% of cycles. We reduce its impact by using a vector of
vectors instead of a Map for the cache of fingerprints. After this
change InstNamer drops below 24% of the runtime.

Also move the instruction name when giving it to `AllocateName` since it
receives std::string by value, though this doesn't show up in the
profile for the test.
2025-09-08 16:15:10 +00:00
Boaz Brickner 9f108bad6e Rename cpp_ast to clang_ast_unit (#5926)
Followup of #5924.
2025-08-08 08:11:49 +00:00
Richard SmithandJon Ross-Perkins 7cac77119c Support import Cpp inline "some code";. (#5904)
This adds support for importing C++ code directly from source rather
than via a `#include`.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-08-05 23:03:32 +00:00
Jon Ross-PerkinsandGeoff Romer 7209ad7c9f Generate Destroy impls for classes (#5873)
Although this focused on `Destroy` support, some choices here around
`implicit_type_impls` are because copy/move will likely follow a similar
approach. I'm trying not to predict too much about how we'll structure
those, but I'm putting `Destroy` impl logic in a file that could perhaps
be shared with those. They'd likely be interested in similar things,
e.g. traversing members of types (particularly class, struct literal,
tuple literal).

At present this sets the destroy function as `no_op` which is consistent
with current logic, but has a TODO to correctly define.

Constant importing for functions changes slightly due to some issues I
was having with `GetFunctionType`. zygoloid suggested this approach to
avoid `EvalInst` logic.

Adds a flag for controlling whether to generating these impls. While
this does generation for `class`, as noted above this'll also need to be
done for tuples and struct literals, which would leave the `none.carbon`
min_prelude unable to use any types. Note if destruction *would* occur,
it'll still look up `Core.Destroy` for that and fail, but that's already
true of any test using `none.carbon`. I'm trying to use the flag to see
if we can keep `none.carbon` working mostly-consistently.

I'd tried separating out the flag to #5852, but that got a lot of
pushback over whether the behavior was appropriate. I'm hoping that the
interactions here make it clearer why the particular approach -- the
goal is not to enable advanced testing, or create some new end-user
behavior that we really support, it's just to keep no-prelude tests
functional. The main question raised there was why not just keep
generating `impl T as Core.Destroy` if `fn destroy` is present -- but I
think here it should be apparent that would require additional
complexity, as the generation of `impl T as Core.Destroy` is not
currently conditioned based on the implementation of `fn destroy`. I'd
rather add complexity to this flag only if it's enabling interesting
test functionality.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-08-04 19:39:22 +00:00
Jon Ross-Perkins bd4fbb4393 Expand use of CheckIRId stores (#5820)
This is trying to make it clearer when vectors are being indexed with
`CheckIRId`.

The only one that I still kind of want to change is the
`SmallVector<std::unique_ptr<CompilationUnit>>`, but because it's a
`unique_ptr` that's a little more complex. I may not bother.

Note, some of the changes around nuanced `SmallVector` interactions were
based on trying to copy the way `SmallVector` itself takes arguments,
like with range passing.
2025-07-21 20:02:27 +00:00
Richard SmithandChandler Carruth 553dd6e531 Build the clang::CompilerInvocation in the driver. (#5784)
Add driver flags to specify clang driver arguments.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-07-18 16:30:47 +00:00
Richard SmithandChandler Carruth 3776e464e0 Properly set up C++ include paths and similar environment settings when parsing imported C++. (#5767)
Stop using the clang tooling library to build an ASTUnit; that library
is set up to process clang frontend arguments, assuming that something
has already built frontend arguments from the compiler arguments. It is
also too encapsulated and doesn't let us inspect and modify the compiler
invocation before it's executed.

Instead, build the AST unit directly in two phases:

* FIrst, take a list of clang driver arguments and convert them into a
list of compiler arguments, using `clang::createInvocation`. Internally,
this uses the clang driver to build a frontend invocation, including
building system-specific include paths as needed.
* Then, directly build an ASTUnit from this compiler invocation.

I've factored this so that we can split out the `createInvocation` step,
with the intention that we may want to move it out of check and into the
carbon driver with the rest of the driver-level argument handling, and
we may want to customize some of the clang options before we invoke the
clang frontend with that set of options.

In order to make the invocation reusable, it no longer depends on the
name of the carbon file importing the C++ code. In place of synthesizing
a header file name as `<foo.carbon>.generated.cpp_imports.h`, we now
insert line marker directives into the generated header so that errors
in that header cause Clang to point a diagnostic back at the Carbon
source file itself. This results in a minor improvement in the
diagnostic output: we no longer refer to a nonexistent generated file.
But the snippet still contains text that doesn't match the source code,
so it remains imperfect.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-07-09 03:09:43 +00:00
Jon Ross-Perkins 9855818bb8 Move PrettyStackTraceFunction to common (#5739)
I'm looking at using this as part of file_test to dump streaming,
related to #5733
2025-06-26 18:39:54 +00:00
Geoff Romer effb0c93c2 Remove unused vlog_stream_ member. (#5654)
This resolves an unused-private-member warning with recent versions of
Clang.
2025-06-17 18:18:45 +00:00
Richard Smith 519e633147 Improve backtrace for lowering crashes. (#5651)
Factor out the logic for mapping from a `LocId` into a diagnostic
location from check into sem_ir so it can be reused by lowering. Include
the function and instruction being lowered in the pretty stack trace.
Example stack trace:

```carbon
2.      filename: examples/sieve.carbon
3.      core/prelude/types/int.carbon:213:3: lowering function Core.Op(Core.IntLiteral as Core.ImplicitAs(i32))
            fn Op[addr self: Self*](other: Self) = "int.sadd_assign";
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4.      core/prelude/operators/arithmetic.carbon:22:27: lowering call
            fn Op[addr self: Self*](other: Other);
                                    ^~~~~~~~~~~~
```
2025-06-16 23:21:22 +00:00
Richard SmithandJon Ross-Perkins dc7839e893 Add a new facility GrowingRange for a range that might grow during iteration. (#5641)
Use it to replace most existing modernize-loop-convert lints with
range-based for loops. As requested in review of #5475.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-06-10 23:21:17 +00:00
Richard Smith 2472f44e44 Track pending thunks on the deferred definition worklist. (#5609)
Instead of using somewhat different approaches for defining in-line
methods at the end of the enclosing scope and defining thunks at the end
of the enclosing scope, we now use the same worklist for both.

This fixes a bug where we would crash when defining thunks if there
happens to be nothing else on the deferred definition worklist, leading
to our leaving the enclosing impl scope before we try to define the
pending thunk. That would only happen if the impl contains no in-line
member function bodies, so only if the impl has only a forward
declaration or a builtin declaration for every method. The latter
case happens (a lot) if we start using thunks in the prelude impls.

One complicating factor here is that this means the deferred definition
worklist moves from the layer containing `check/handle*` and
`check/check_unit.cpp` into the layer containing `check/context.cpp`.
Allowing that required moving a couple of other things that it depends
on -- notably `SuspendedFunction` and `HandleSuspendedFunction` --
around.
2025-06-10 22:09:31 +00:00
Jon Ross-Perkins 1e9e148c3b Rename the ImportRefs block to Imports (#5618)
I've been mulling the name of this, changing it and updating comments to
try and better reflect the current semantic. "Imports" reflects how
we're currently printing this in SemIR.
2025-06-05 21:24:58 +00:00
Dana Jansens 02fc484f23 Make pointers in ValueStore stable across insertions (#5576)
This avoids reallocating the backing buffer in ValueStore so that
references into the ValueStore are never invalidated when adding new
values. This works especially well since we never delete values from a
ValueStore.

The strategy used is to allocate chunks of a fixed size, and inserting
into each chunk until it is full before allocating the next. The
ValueStore starts with an initial allocated chunk in all cases, so that
there is only a single indirection for adding and accessing values from
this chunk. After it's full, additional chunks are allocated in a
vector, so two indirections are required to add or access values in
these chunks.

This obviates the need for
https://github.com/carbon-language/carbon-lang/pull/5529 as we no longer
need to worry about holding pointers into a ValueStore.

We introduce a Flatten operation for ranges. It flattens a "range over
ranges over Ts" down to a "range over Ts". This allows us to make an
range over the values in the ValueStore from a range over the chunks in
the ValueStore. See
https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.flatten
for inspiration for this name choice. Flatten is used in one other case
where we were writing two levels of for loops to do the same thing.

The `array_ref()` accessor is changed to `values()` and its now a range
(typed as a `ValueStoreRange`) over all values as references (like
ArrayRef was, but without random access).

As pointers to a ValueStore can no longer be invalidated, we remove the
ASAN poisoning feature and support from ValueStore.

This may cause a regression in our compile benchmark of up to 5%, though
that is close to or within the noise of the benchmark. We can look at
ways to optimize things further in the future. Perhaps by tuning the
chunk size further, or by making later chunks larger than earlier
chunks, or other strategies.
2025-06-02 19:16:31 +00:00
Thomas Köppe f18fc40a32 Add missing standard library header inclusions (#5486)
Discovered by clang-tidy.

See also #5316.
2025-05-28 22:48:20 +00:00
Dana Jansensandjosh11b 950d83451a Add diagnostics for invalid impl declarations (#5420)
Outside of `match_first` this adds diagnostics for invalid non-final and
final `impl` declarations in line with those being proposed in
https://github.com/carbon-language/carbon-lang/pull/5337.

- Two non-final `impl`s with the exact same type structure is invalid.
- A `final impl` that matches the self/constraint of another `impl` as a
query would always be preferred, making the second one invalid.
- Two `final impl`s that overlap (have compatible type structures) in
different files is invalid.
- Two `final impl`s that overlap (have compatible type structures) in
the same file is invalid outside of `match_first`.
- A `final impl` in a different file from its root self type and
interface is invalid.

We add tests for all these scenarios as well as correct scenarios.

The "compatible" test for two type structures was being done
symmetrically, which is incorrect. We want it to test that a query type
structure is the same _or more specific_ in a compatible way with an
impl's type structure. This is corrected in the implementation, and the
diagnostics now have to test both directions to get the desired output,
as expected.

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2025-05-22 18:58:47 +00:00
Boaz Brickner 852d0191a9 Add support for importing C++ inline functions (#5427)
This requires:
* Making `FunctionDecl` mutable since generating code
(`HandleTopLevelDecl()`) requires a mutable declaration and since we
manually add `used` attribute to force code generation.
* Passing the file system to `Lower` since it's needed by Clang code
generation.
* Creating an internal Clang LLVM module and link it against the Carbon
LLVM module.

Demo:

```c++
// hello_world.h

extern int puts;
inline void hello_world() {
  ((int (*)(const char*))&puts)("hello world");
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  Cpp.hello_world();
  return 0;
}
```

```shell
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link main.o --output=demo
$ ./demo
hello world
```

Based on https://github.com/carbon-language/carbon-lang/pull/5406.

Part of #5405.
2025-05-21 07:02:05 +00:00
Dana Jansens b6a55c0818 Diagnose impls that are fully overlapped by a final impl (#5417)
Such impls will never be used, so they should not exist. And test that a
final impl partially overlapping a non-final impl is accepted.

There is a question about a final impl partially overlapping a final
impl that is part of
https://github.com/carbon-language/carbon-lang/pull/5337
2025-05-10 17:36:28 +00:00
Dana Jansens 08065ee764 Do a stable sort when splitting up impls by interface (#5423)
Keep the impls for each interface in the order that they were declared.
This ensures that the resulting diagnostics will be deterministic.
2025-05-05 20:51:27 +00:00
Richard SmithandJon Ross-Perkins c49789d80b Don't use GetCanonicalLocId when determining what instruction an instruction was imported from. (#5418)
The canonical location of the instruction may be an entirely different
instruction, which the instruction in question was not imported from. In
particular, we shouldn't assume that we can use the constant value of an
instruction that the *location* of an imported instruction refers to as
the constant value of the imported instruction.

The only time we should be looking at the `ImportIRInstId` for a `LocId`
is when determining its location in some other file.

Fixes a crash when importing thunks (which can contain instructions
whose location points to an instruction in a differnt IR).

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-05-05 19:58:30 +00:00
Dana JansensandJon Ross-Perkins aa491d8fd8 Implement non-final impl overlap diagnostics (#5412)
When two non-final impls have the same type structure (neither is a
specialization of the other), it is an error unless they are within a
`match_first` block. For now, we don't have `match_first` implemented,
so it's always an error.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-05-05 19:01:41 +00:00
Jon Ross-Perkins 0683742f19 Cache multi-IR info, particularly include_in_dumps (#5408)
Right now we construct `tree_and_subtrees_getters` a couple different
ways, it's just not obvious because one's abstracted in `check`. But
also, when formatting IR, we'll repeatedly do the `IncludeInDumps`
string check, which felt odd to me since it only needs to be calculated
once per IR.

This also shifts `CheckIRId` selection a little earlier, and in doing so
makes `CheckParseTrees` accept a sparse `units` argument. I actually
think this is a positive: it makes `CheckIRId` a little more stable
across possible command lines, when file loading fails (which is the
only time that a file will have a `CompilationUnit` but not a
`Check::Unit`).

Trying to build on the shared issue between these, I'm adding a
`MultiUnitCache` to store the calculated arrays. For the subtree
getters, this is very minor and avoids at most one incremental array
construction (moving logic out of `CompileSubcommand::Run` might be the
bigger benefit). For `include_in_dumps`, when dumping SemIR, this is
changing a calculation run once per entity (in each IR) to be calculated
once per IR (globally), i.e. O(M*N) -> O(N).

Note this seems to be marginal for performance of file_test:

- Before: Stats over 10 runs: max = 5.3s, min = 4.7s, avg = 4.9s, dev =
0.2s
- After: Stats over 10 runs: max = 4.9s, min = 4.7s, avg = 4.8s, dev =
0.1s

I was mainly thinking about this in the context of dumping SemIR ranges.
There, the impact may actually decrease because a range won't do any
cross-IR printing. But, I'm expecting to add another layer for whether
we're printing IR for a file, and that made the `should_format_entity`
callback stick out for me.
2025-05-02 22:53:46 +00:00
Dana JansensandRichard Smith 13da710e94 Poison impl lookup queries with concrete results (#5373)
Once a concrete result has been found, it's not legal to write an `impl`
that would change the concrete result afterward.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-29 21:55:11 +00:00
Dana JansensandJon Ross-Perkins 315e206ff1 Construct LocId from InstId directly (explicitly) instead of doing lookups when possible (#5355)
Remove calls to `InstStore::GetLocId()` to build a LocId from an InstId
now that they can be constructed directly from the InstId. Most uses of
LocId are just plumbing, so this does not affect them. However places
that want to look inside the LocId do not want to work with the InstId
form. In these places, introduce `InstStore::GetResolvedLocId()` which
converts a LocId (or an InstId as an optimization) into a LocId which is
not backed by an InstId. These locations can be printed (they have a
line and column when they are a NodeId), they can have flags added to
them (`ToImplicit`, `ToTokenOnly`), they can be converted to an
underlying ImportIRInstId, or they may be `None`.

`Dump()` is made to print a resolved location instead of printing the
InstId in the location, since (at least in my experience) the resolved
location is what is interesting in debugging, and this saves manual
`MakeInstId` steps in the debugger every time a location is of interest.

The LocId constructor from InstId is made `explicit` to add clarity to
function calls passing an `inst_id` now directly instead of calling
`context.insts().GetLocId(inst_id)`. To avoid needing to construct
`SemIR::LocId(...)` explicitly in all cases though, the diagnostics code
in Check uses `DiagnosticLocId` as its template parameter which accepts
InstId as well and does the construction of LocId from it.

Because LocId now requires an explicit construction from InstId, any
callers to `AddInst()` functions will have to explicitly convert to
LocId if they had an InstId, but not if they pass a NodeId. To make this
difference clear to callers, we `requires` that the input type can be
converted to LocId. This ensures that passing an InstId results in an
error at the callsite where the InstId is passed, instead of generating
a compiler error when trying to construct `LocIdAndInst` inside
`AddInst()`, which is less clear about what went wrong and doesn't seem
entirely intentional.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-04-28 19:06:24 +00:00
Boaz Brickner 609ccefd18 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.
2025-04-25 13:05:45 +00:00
Jon Ross-PerkinsandGeoff Romer 03e693873b Detect control flow in entities nested inside functions (#5336)
Right now, return_scope_stack is being used to determine whether logic
is in a function scope. However, we need to handle nested entities
inside function scopes. For example where this crashes right now:

```
base class C(B:! bool) {}

fn F() {
  class B {
    extend base: C(true or false);
  }
}
```

This is doing a few things to make this kind of code not crash:

- Split `scope_stack().Push` into `PushForDeclName`, `PushForEntity`,
`PushForExpr`, and `PushForFunction` so that better decisions can be
made about behaviors.
- Hide `return_scope_stack` in the API, instead using interfaces to get
at the underlying data.
- Also using `PushForFunction` to update it similar to the other stacks
that `ScopeStack` manages.
- Add `IsInFunctionScope` as the best way to determine presence in
function scope.
- Remove `PeekIsLexicalScope` since destruction really wants function
scope information anyways.
- Clean up `destroy_id_stack` handling to be for function scopes rather
than lexical scopes.
- Return after related `context.TODO`s in a couple more spots, so that
code doesn't proceed to add control flow in spite of the lack of
support.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-04-23 19:03:53 +00:00
josh11bandJosh L ecb99e55e7 definitions_required -> definitions_required_by_decl in toolchain/check/check_unit.cpp (#5329)
Updates message to reflect changes in #5090 .

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2025-04-17 22:48:37 +00:00
Richard Smith 19532967fa Stop pushing a fake generic for the duration of check. (#5326)
This fake generic was used for two reasons:

- The declaration name stack assumes that each declaration name is
processed within a generic scope. This is important if the name might
have generic parameters, which are always parsed even for declarations
that disallow them in check.
- Out-of-line redeclarations of generic entities produce instructions
with symbolic constant values in non-generic scopes.

The former case is addressed by pushing a generic each time we start a
declaration name, even if we will reject generic parameters later. The
latter case is worked around for now by not building a symbolic constant
type or value for instructions that appear outside of any generic, and
will be addressed more completely by #5310 and follow-ups.
2025-04-17 21:58:37 +00:00
Dana Jansens c38e723dd8 Rename singleton InstId constants to TypeInstId (#5323)
These constant instructions are all TypeInstId already in their type,
and this makes their names match.

Change the name of MakeSingletonInstId as well and update its comment.
2025-04-17 18:57:20 +00:00
Thomas Köppe bf32da8dad Add missing standard library header inclusions (#5316)
Discovered by clang-tidy.
2025-04-17 15:37:57 +00:00
Jon Ross-Perkins 4923445e3a Drop Singleton from ErrorInst::SingletonInstId and similar (#5304)
We frequently want to operate on singletons. Per discussion, drop
`Singleton` to make the code shorter.

This started off as wanting to write `inst_id.is_error()`, but the
dependency relationship between ids.h and singleton_insts.h would
require some kind of delayed evaluation to allow the implementation to
remain in headers (which I suspect is helpful to have for inlining). I
could have added something like `IsErrorInst`, forward declared in ids.h
and defined in singleton_insts.h (which would always be included by
typed_insts.h), but the template approach felt like a decent balance
between (a) removing the boilerplate `::SingletonInstId`, (b)
understandability, (c) still visually mirroring if we immediately return
a singleton, and (d) flexibility for more than just `ErrorInst`. But TBH
I'd probably still have written `is_error()` if it didn't require
addressing the cross-header cycle.

Then I tried `SemIR::InstId::Is<SemIR::ErrorInst>`, which generally
worked with types but generated the complaint that it didn't shorten
*all* singleton uses. So pulling back on `::Is`, and instead just
dropping `Singleton`.
2025-04-15 22:40:29 +00:00
Jon Ross-Perkins fe29224016 Refactor LocId to merge in SemIRLoc (#5284)
The main goal of this is to collapse the LocId and SemIRLoc types into a
single type, eliminating the need for APIs to decide which to use. This
originated from discussion about UnwrapSemIRLoc in #5169. Although that
was removed in #5202, it's probably still a good direction for LocId.

This changes the packing of LocId to allow adding InstId, making it
tri-modal: ImportIRInstId, InstId, or NodeId. This has a side-effect of
reducing the available space for ImportIRInstId, although not by much
due to the pre-existing `ImplicitBit` behavior. If needed, we could also
probably play with packing a bit more since `ImplicitBit` really only
applies to `NodeId`, but I was trying to keep the logic a little
simpler. Note `TokenOnlyBit` can still apply to `ImportIRInstId`.

This leaves in place a typedef for SemIRLoc -- I intend to clean that up
separately.

Some Discord discussion is
[here](https://discord.com/channels/655572317891461132/655578254970716160/1353755830058745959).
2025-04-11 13:35:58 +00:00
Alina Sbirlea 077cf56a8a Emit function definitions in check, for all specifics seen. (#5090)
Emitting definitions in check. This resolves the crash in lowering which
necessitated definitions be emitted.
Some of the test changes need further review.
2025-04-02 21:51:25 +00:00
Boaz Brickner 3acca8402f Change NodeIdTraversal.context_ from reference to pointer (#5210)
Per [the style
guide](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/cpp_style_guide.md#syntax-and-formatting):
* If it is captured and must outlive the call expression itself, use a
pointer and document that it must not be null (unless it is also
optional).
* When storing an object's address as a non-owned member, prefer storing
a pointer.
2025-03-28 16:24:17 +00:00
josh11bandJosh L c7a338be59 Replace uses of "defined" with "complete" (#5196)
As of #5087, these terms are no longer synonyms. This change preserves
the original meaning.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2025-03-27 18:14:26 +00:00
Jon Ross-PerkinsandRichard Smith c0ee446cec Refactor InstBlockStore's API, AddDefaultValue -> AddPlaceholder (#5166)
`AddDefaultValue` doesn't quite capture the intended semantics; it
should typically be replaced with an actual value when dealing with
control flows. Trying to indicate the "assign later" with
`AddPlaceholder`, mirroring `AddPlaceholderInst`.

Shifting the `protected` functionality on `BlockValueStore` so that it's
not providing functions just for `InstBlockStore` to use. Also hoping
that seeing the comments next to the function name makes them easier to
understand, whereas `using` buries that a little.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-03-21 23:09:37 +00:00
Jon Ross-Perkins e6872f9499 Change NodeIdOneOf and similar to use "requires" and explicit UnsafeMake (#5084)
This doesn't change functionality, but I was seeing better diagnostics
in VS Code.

This also changes the NodeId constructors for related types (also
NodeCategory and NodeIdForKind) to use UnsafeMake for construction. That
originated from avoiding ambiguity coming from `requires`, but the
constructor mode is also one we should typically avoid (e.g., preferring
`Parse::Tree::As`).
2025-03-12 00:33:54 +00:00
Boaz Brickner 87b9cab7b1 Add support for importing a trivial global C++ function (#5033)
ASTUnit is owned by `CompileSubcommand`, passed through `Unit` to be
populated in `ImportCppFiles()` and used via `SemIR::File`.
When generating the AST, pass `-x c++` args to compile C++ (temporary
until we pass args properly).
`Cpp` namespace is marked as a special namespace and has dedicated logic
in `LookupNameInExactScope()`.
The logic for importing declarations from C++ to Carbon is in
`import_cpp.cpp`, but we're likely to want to refactor this
signfiicantly over time as it grows (perhaps a dedicated directory?).

Part of #4666.
2025-03-03 10:38:19 +00:00
Jon Ross-Perkins 5574ad361d Add more empty stack verification (#5020) 2025-03-01 07:56:04 +00:00
Jon Ross-Perkins e7b68572fa Consolidate post-check logic (#5003)
Right now, some post-run logic is does in `Run()`
(`CheckRequiredDefinitions();` and
`context_.sem_ir().set_has_errors(unit_and_imports_->err_tracker.seen_error());`)
whereas other parts are done by `Finalize`. Noting the goal to move
things off `Context`, this consolidates into a new `FinishRun`. Note
#4962 is adding another bit of post-run that can be consolidated in;
this seems likely to keep growing slowly.

Note this also creates more parity with mutation source, like the
`context_.scope_stack().Pop();` matches the push done by
`CheckUnit::ImportCurrentPackage` and
`context_.inst_block_stack().Pop()` was pushed in `CheckUnit::Run()`.

Also makes `exports()` more consistent with other Context APIs. Makes
`VerifyOnFinish` `const` so that it can't accidentally mutate state, and
is instead only validating that the Context is in its expected
configuration at completion.
2025-02-25 02:07:43 +00:00
Alina Sbirleaandjonmeow 1d48270dc4 Emit diagnostics missing declaration of owned function. (#4962)
Emit diagnostics for a function declared in a non-owning library, that
is not redeclared (or defined) in the owning library.

---------

Co-authored-by: jonmeow <jperkins@google.com>
2025-02-22 01:29:22 +00:00
Jon Ross-Perkins 311b4ff03d Refactor AddInst-family functions to their own file (#4941)
This in particular uses free functions because it's likely to end up
more consistent with types (versus a wrapper object for InstStore).
Note, this is unlikely to have a performance impact, but if it does, we
can look into related approaches (and we've already discussed using
LTO).

Renames `PendingBlock::AddInst` to `PendingBlock::Add` because
`MakeElementAccessInst` expects the matching name to exist.
2025-02-14 19:44:36 +00:00
Jon Ross-Perkins dc8f47e6ad Move type functions off Context (#4951)
This creates a new check/type.h for most logic, and also moves some
functions to TypeStore in sem_ir/type.h. My approach for TypeStore is to
focus on moving the read-only functions there.
2025-02-13 23:02:38 +00:00
Boaz Brickner 3f599c250b Generate Cpp namespace when import Cpp is used (#4873)
Also defined a dedicated `ImportCppDecl` `InstKind`.
Part of #4666
2025-02-12 01:44:37 +00:00
Richard SmithandJon Ross-Perkins 8eb4e24cb6 Implement #4864: Core is a keyword (#4909)
Change representation of package names from `IdentifierId` to
`PackageNameId`, and add a special value `PackageNameId::Core` for the
Core package. Add a `Core` expression to name the Core package, and
support for parsing the `Core` keyword in `package` and `import`
declarations.

For now, I've made no changes to instruction fingerprinting or name
mangling. This means that fingerprints and mangled names will collide
between names in the `Core` package and names in a `r#Core` package. See
#4908.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-02-11 21:33:57 +00:00
Jon Ross-Perkins e79d3be5bd Combine DiagnosticConverter into DiagnosticEmitter (#4878)
At present, we typically define a DiagnosticConverter, then store an
instance of it and a DiagnosticEmitter that wraps it. This is relatively
minor in general, but I've been trying to create more self-contained
DiagnosticEmitter classes (which hold their own DiagnosticConverter,
similar to NullDiagnosticEmitter), and there it just gets in the way.

Since we don't reuse DiagnosticConverter instances, this combines the
definition into DiagnosticEmitter. Mainly this means we don't have a
separate object in play, and less to carry around.

The most impact is probably to SemIRDiagnosticConverter, which was also
the most complex. Now `SemIRLocDiagnosticEmitter`, this gets some
different construction flow. Note in the PR I've split the file rename
to its own commit, to try to help delta views. However, the most
substantial parts of the refactoring are split into #4876, which this
depends upon.
2025-02-06 20:27:57 +00:00
Jon Ross-Perkins 133717cd7e Eliminate NodeLocConverter (#4870)
I'm looking at eliminating `DiagnosticConverter`. This change removes
`NodeLocConverter` (albeit adding `UnitAndImportsDiagnosticConverter`),
and in doing so, refactors lex conversion functions to extract them out
from the `DiagnosticConverter` functions.

I'll be following up with changes that collapse `DiagnosticConverter`
logic into `DiagnosticEmitter` locations. The intent is that we
shouldn't need separate ownership of both types.
2025-01-30 22:30:33 +00:00
Jon Ross-PerkinsandChandler Carruth 7befe2ce9f Switch custom error stream output to diagnostic (#4846)
This switches most error printing to use diagnostics instead of direct
stream writes, even when not a specific file diagnostic. I'm allowing
empty filenames for this use-case.

This allows a little more specific testing to validate coverage of
output using the diagnostic coverage test. I'm adding a few tests to
cover things that weren't previously tested.

Separately, this also forces a little more standardization in format...
considering how changes like #4568 show effort being spent to _mirror_
diagnostic style, my thought is now to just use diagnostic code where
possible.

Note this also allows incrementally better testing of the language
server; I'm changing the crash fix from #4847 in favor of diagnostic
testing.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-01-30 01:58:07 +00:00
Jon Ross-Perkins 9c0faf007e Invalid comment cleanup (#4836)
This is a followup from #4834, I searched for "invalid" uses in our
codebase. This is mostly changing comments, and a couple debug
functions, but shouldn't affect testable behavior.

Note a couple things I'll highlight as not changing (but could) are:
- `ReturnTypeInfo::is_valid`
- `"invalid"` uses in the formatter
- `AddInvalid` for `!has_value` in `inst_fingerprinter` (because the
cases it's called sound invalid-ish)
2025-01-23 02:21:48 +00:00
Jon Ross-Perkins 6b5eb1a101 Id::Invalid -> Id::None (#4834)
High level, replacing `Id::Invalid` with `Id::None` and `Id::is_valid`
with `Id::has_value` for clarity, as discussed
[here](https://discord.com/channels/655572317891461132/655578254970716160/1331664574545395794).
The `IntId` refactoring is needed together with `AnyIdBase` because it's
also used with `ValueStore`.

Note, trying to be careful not to rewrite `EnumBase::InvalidIndex`, or
`is_valid` in general (e.g., `IdKind::is_valid`).

I've tried to sequence commits here:

1. Automatic replacements:

- `((?:Id|Index)(?: |::|\(|Base(?:\(|::)))Invalid((?:Index)?\W)` ->
`$1None$2`
  - `<invalid>` -> `<none>`
  - `InvalidNodeId` -> `NoneNodeId`
  - `/\*invalid\*/` -> `/*none*/`
  - `id((?:_|\(\))(?:\.|->))is_valid` -> `id$1has_value`

2. Manual edits:

  - In `int.h` and `int_test.cpp`
    - `IntT` has `is_value`, which I'm renaming to `is_embedded_value`.
    - Manual edits to comments in this file.
  - `AnyIdBase` and `IdBase`
- Declaration of `is_valid` -> `has_value`, `InvalidIndex` ->
`NoneIndex`.
  - In `ids.h` and `ids.cpp`
    - `is_valid` -> `has_value`
- `// An explicitly invalid ID.` -> `// An ID with no value.`; similar
for index
    - Various math on `InvalidIndex` -> `NoneIndex`
    - Various mentions of "valid" in comments
  - In `value_store.h`, for `IdT::Invalid`, plus one comment
- In `impl.h` and `tokenized_buffer.h`, we had different initialization
of `::None` values (versus `ids.h` syntax) that I fixed manually.
  - Spot checks to compile
- Particularly where `is_valid` replacements didn't catch spots due to
different naming.

3. Autoupdate tests

4. verbose.carbon (NOAUTOUPDATE)

5. Comment spot checks

Note there are probably other mentions of "Invalid" that should be swept
up, but I'd like to argue for merging and separating out remaining
cleanup since this is so sweeping (and likely to hit merge conflicts
from churn). We'll probably have lingering mentions of "invalid" for a
bit regardless, just because there are uses of "invalid" in non-Id APIs.
2025-01-22 23:15:00 +00:00