Commit Graph
159 Commits
Author SHA1 Message Date
David Blaikie 9e68ee0806 Support indirect C++ dependency by sharing domains more broadly (#7763)
Fixes #7731, at least under `--share-cpp-ast` which is expected to be
the future direction.

When --share-cpp-ast is enabled and any compilation unit has C++
imports, include all compilation units in the shared CppDomain inputs
and assign the domain to every unit. In ImportCpp, when a unit has no
direct C++ imports but is covered by a shared CppDomain, initialize
its C++ AST context and import namespace. This ensures units without
direct C++ imports have access to the C++ AST and code generator when
instantiating generics or referencing declarations from units that do.

Assisted-by: Antigravity with Gemini
2026-09-15 20:45:18 +00:00
Richard Smith a1e843718e Create modules for header imports. (#7613)
Make multiple imports of the same header only parse it once per C++
domain. Reuse of the same header in `--share-cpp-ast` mode now reuses
the representation.

Importing a Carbon file with C++ dependencies now makes those transitive
C++ dependencies in the same C++ domain visible too.

Assisted-by: Gemini via Antigravity
2026-08-06 13:32:37 +00:00
Richard Smith dea290db81 Only lower files we are going to emit. (#7611)
Move `--output-last-file-only` and output filename synthesis logic out
of the general-purpose compile driver and into the `carbon compile`
subcommand, which is the only thing that should be using them. Track on
CompilationUnit whether it is being lowered, or whether it exists only
to be imported into other units.

`carbon compile` now never lowers inputs that it discovered for itself,
only inputs that were specified on the command line. In particular, it
doesn't lower (and throw away the result of lowering) the prelude any
more. This makes the toolchain tests about 10% faster in my crude
measurements.

Also, we now do not create a clang `CodeGenerator` for input files that
we are not lowering, similarly saving compilation time for units that
exist only to be imported, not lowered.

One minor change: we use the same mechanism to determine whether an
input is being lowered and to determine what the output filename is.
This means that `--phase=lower` and `--phase=optimize`, which lower but
don't produce an output file, still need an output filename to be
specified now in some cases. Given those are just debugging tools, I
think that's fine.

Assisted-by: Gemini via Antigravity
2026-08-05 12:52:24 +00:00
Richard Smith 34a2e270f4 Fix C++ code generation in --share-cpp-ast mode (#7605)
Instead of creating a CodeGenerator per CppDomain, and then crashing in
lowering when we try to consume the same llvm Module multiple times,
create a CodeGenerator for each CppFile within the domain.

For now, we mulitplex all of Clang's ASTConsumer output to all code
generators, which means that any strong external definitions within a
Carbon file (for example, in an inline `Cpp` fragment) will be emitted
to all output files in the same `CppDomain`, resulting in link errors
due to symbol redefinitions. This will be addressed later. But this
should be sufficient for Carbon compilations in which such symbols are
not defined.

We also don't yet attempt to classify which compilations will need C++
code generation, and instead create a clang `CodeGenerator` for every
Carbon file that has C++ imports. For `carbom compile`, only one Carbon
file will need code generation, and yet we still build multiple
`CodeGenerator` objects in general. Fixing this requires more plumbing
from the driver, and this will also be handled in a follow-up.

Assisted-by: Gemini via Antigravity
2026-08-04 17:59:06 +00:00
Richard SmithandChristopher Di Bella 9bcee64b32 Add some encapsulation to CppDomain (#7579)
Start tracking the domain within `CppContext`s instead of having them
duplicate its fields. This allows us to remove the shared ownership of
the clang parser.

---------

Co-authored-by: Christopher Di Bella <cjdb.ns@gmail.com>
2026-07-31 18:08:13 +00:00
Richard Smith 7d89ac98c7 Add a flag to build a single ASTContext shared across all compilations (#7567)
Instead of building one Clang `ASTContext` per compilation, the
`--share-cpp-ast` flag causes us to build a single `ASTContext` and
share it across all contexts. One new abstraction is added: `CppDomain`
represents the Carbon-side view of a Clang AST that might be shared
across multiple `SemIR::File`s. This object owns the Clang instance and
the AST.

For now, we have no isolation between the C++ state exposed to different
Carbon compilations, and we have no multiplexing of generated LLVM IR
from C++ into different Carbon compilations, so the mode is not usable
yet. The plan is to keep it behind a flag until it's ready.

Assisted-by: Gemini via Antigravity
2026-07-28 00:19:40 +00:00
Lucile Rose Nihlen 625f2ca629 precompile and cache Carbon prelude (#7432)
Refactors the link driver to automatically compile and cache the carbon
prelude for use in linking.

Implements a `carbon_library` rule for compiling the Core library
dependencies in the examples.
2026-07-16 18:02:14 +00:00
Richard Smith be70c092fa Add a text mode for fingerprinting. (#7231)
The intent is to add visibility into how the fingerprint is computed, so
that fingerprinting issues and mangling collisions can be more readily
understood and fixed.

Assisted-by: Gemini via Antigravity
2026-05-19 23:16:51 +00:00
Jon Ross-Perkins 45ca3d28f5 Drop "diagnostic" from some filenames in the "diagnostics" folder (#6686)
Mainly because "sorting_diagnostic_consumer" is legacy, since
`SortingDiagnosticConsumer` became `SortingConsumer`. Also better
reflecting contents of these files.

Where I'm not renaming, I'm less positive about dropping "diagnostics"
from "file_diagnostics" and "null_diagnostics" (which contain both a
consumer and emitter, and "null.h" seems like poor naming), so not doing
that here. Also "diagnostic.h" contains `struct Diagnostic`, so is a
decent fit.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-04 17:24:55 +00:00
David Blaikie f1f6005d4a Perform Clang IRGen during check (#6569)
Background:
https://docs.google.com/document/d/1wi85FRiWh4X9A-gCYMVGKR40-q5fM6-3JaSpePk-XCY/edit?usp=sharing
And specifically this work is essentially an alternative to #5543

Clang's code generation is implemented through an ASTListener
(clang::CodeGenerator) that is attached throughout Clang's
parsing/sema/code
generation phases and acts on Clang AST incrementally throughout that
process.

Prior to this patch, Carbon has only created the CodeGenerator during
Carbon's
`lower` phase, missing out on key callbacks that would be made by Clang
during
`check`. Some of these issues were addressed by #6237 and #6483 - but
there were
still remaining cases where the delayed processing lead to missing
functionality.

With #6483 much of the Clang code that made multithreaded complexity of
#5543 is
no longer present, and we have access to the point of ASTListener
registration
so we can register the CodeGenerator there and consume its resulting
llvm::Module during lower.

Examples of some of the bugs this addresses are seen in the linked doc,
and
checked in as tests in this change in
`clang_code_generator_callbacks.carbon`

An indicental bug that's also fixed, and caused all the other test case
churn,
is that the `CodeGenerator` created during `lower` wasn't getting passed
the
Clang `CodeGenOpts` and was creating its own default - so, most notably,
optimization flags were not respected. This meant that the LLVM IR from
Clang
was always -O0 style IR (optnone, no inlinehint, no TBAA, etc). With
this
change, now the Clang IRGen gets the real `CodeGenOpts` and respects
optimization/other flags specified there.

This is only meant to be a rough proof of concept - I'm totally open to
reworking this in any way (even quite substantially) if folks have ideas
about
how this should be implemented most generally/elegantly/etc.
2026-01-14 00:54:37 +00:00
Geoff Romer 2380be2ae1 Add flag to dump the raw SemIR in the event of a crash. (#6558) 2026-01-06 21:56:08 +00:00
Richard SmithandJon Ross-Perkins d208e950c7 Encapsulate clang::ASTUnit in SemIR::CppFile. (#6459)
This intends to avoid proliferation of dependencies on the exact API of
`clang::ASTUnit`, and would enable us to more easily switch to a
different approach that gives us more control over the construction of
the Clang AST.

Also remove some unnecessary tracking of the `CppFile` and instead
always retrieve it from the `SemIR::File`.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-12-04 21:05:40 +00:00
Boaz Brickner b54f2dd592 Support import Cpp; to import Cpp namespace for using C++ builtins (#6320)
This allows writing
```
import Cpp;
```

Instead of writing
```
import Cpp inline "";
```

Part of #6330.
2025-11-06 08:45:28 +00:00
Jon Ross-PerkinsandDana Jansens 8166f9a7cf Formalize Cpp as a PackageNameId (#6306)
This turns `Cpp` into a keyword, and makes it map to `NameId::Cpp` and
`PackageNameId::Cpp`.

Per discussion with zygoloid, the keyword versus identifier question is
deliberately kept open by #4846. This PR switches to a keyword because
mapping to a specific `PackageNameId` works best with a special `NameId`
not backed by an `IdentifierId`. We could in theory make it work using
`IdentifierId` or a runtime-tracked `PackageNameId` for `Cpp` (e.g.
stored on `SemIR::File`), but this approach is consistent with `Core`
and so seemed like a good starting point.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-11-05 17:21:41 +00:00
Boaz Brickner d3762f9723 Remove unused ImportCppId and list of Cpp imports in File (#6290)
See discussion:
https://discord.com/channels/655572317891461132/655578254970716160/1432518191350808659

Part of #5245.
2025-10-30 18:03:34 +00:00
Jon Ross-Perkins 49ba8cf3e1 Switch class to use a blanket impl for Destroy (#6125)
Right now, the class destroy impl is incorrectly generated (first
discussed [in
Discord](https://discord.com/channels/655572317891461132/941071822756143115/1418614787449032826)).
If we want it to be correct, deferred definition logic would need to be
added, and the declaration would need to be moved inside the `class`
scope (along with whatever generic logic that needs).

This instead switches to a blanket impl, to avoid creating latent bugs
with generating the `impl` and function body in the wrong scope. This
approach uses the same blanket impl as aggregate destruction that was
added by #6098.

The intent here is to allow progress on other parts of `Destroy`. For
example, under this model the implementation of the function body could
be done as part of lowering the specific.
2025-09-29 16:05:06 +00:00
Boaz Brickner f29515fe4e Move C++ interop related check code files to a cpp dir (#6065)
Context:
https://github.com/carbon-language/carbon-lang/pull/5891#pullrequestreview-3178216893
2025-09-17 09:31:36 +00:00
Boaz Brickner dfe9ffd369 Rename check/import_cpp.* to check/cpp_import.* to group C++ interop logic in check (#6074)
See #6065 for context.
2025-09-16 17:22:03 +00:00
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
Jon Ross-Perkins 8d08e774fc Add a feature to explicitly include a file's SemIR (#5961)
Trying to figure out an easy way to debug semir in the prelude, #5703
removed an option to set `--exclude-dump-file-prefix` to empty. But,
this is probably an improvement over that flow... With this change, it's
possible to add `//@dump-sem-ir-file` to a specific prelude file, and
its full IR will be printed. Additionally, it becomes an option with the
default `--dump-sem-ir-ranges=only` to add `//@dump-sem-ir-file` and get
the full file's IR.
2025-08-15 18:53:43 +00:00
Boaz Brickner 9f108bad6e Rename cpp_ast to clang_ast_unit (#5926)
Followup of #5924.
2025-08-08 08:11:49 +00:00
Boaz Brickner 52ed26235d Add a flag to dump the C++ AST (#5918)
Use it to dump the AST that includes a generated C++ thunk.
Based on #5917.

Also added printing of the full actual text when check fails to make
debugging easier.
Changed line replacement to allow removing complete lines.

Part of #5514.
2025-08-07 17:09:30 +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 57ef976802 Move dumping into the phase factory functions (#5747)
By moving dumping, we can have dumping occur before verification that
might CHECK-fail (e.g. parse tree and llvm IR verification).

I'm dropping vlogging of raw semir. It was only done when dumping, so
`-v` would print zero copies and `-v --dump-raw-sem-ir` would print two
copies. The lack of complaints about this suggests it's not needed.

I'm making a small change to drop newlines between textual and raw
semir. This is an edge case so I don't expect people to really notice in
general, but it seemed unusually aware of what's on a stream, and it
made it harder to do the dump_stream/raw_dump_stream approach, which I
felt would be decent in general, since check is the only phase that can
emit two different things (which I could also just drop -- we don't
really use raw semir anymore, it doesn't seem like a big need to be able
to print it with textual semir, but I'm assuming to just maintain
existing behavior).

In parse, we were previously dumping the tree on verification errors.
I'm removing that because now `--dump-parse-tree` should work fine,
where previously it wouldn't.
2025-07-01 15:51:41 +00:00
Jon Ross-Perkins 2de746e83c Switch compile functions to use options structs (#5742)
I've been mulling this mainly for the parameter complexity of
check/lower, but doing lex/parse for symmetry.

I'm motivated by the plan to move dumping for all of them into the
respective functions, because of discussion about llvm-verifier. That
basically would add another bool parameter (or more) to each of these.
My instinct is we're going to probably accrue a little more over time,
so I'm suggesting this as maybe adding the boundary a little simpler
and/or easier to read.

Note it may make sense to refactor a little further, e.g. maybe
Lower::Context could receive the full set of options and pick out what
it wants, but I figured creating the struct itself would be a decent
start.

I'm trying to put things into options when we can produce a reasonable
default if the user doesn't assign a value. I'm using an explicit
constructor so that values can be added without affecting every caller.

A different factoring would be to pass in everything through the param
struct, but that just felt weird when I was trying it out.

Removing `inst_namer` and `module_name` from `LowerToLLVM` params --
both of these can be inferred from `sem_ir`, and I'm not seeing a
particular reason to maintain them at the call site.
2025-06-27 22:08: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
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
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 0a3efb76ed Use DiagnosticEmitter for phase-specific types (#5188)
Given the namespacing of `Diagnostics` in #5173, now we can use
`DiagnosticEmitter` for phase-specific emitters. This is consistent with
how we do `Context`, and also check had started this with
`DiagnosticBuilder` in anticipation of the namespacing.

Also renames `Emitter::DiagnosticBuilder` to `Emitter::Builder` for
consistency with other `Diagnostics` entities.

In check, I'm still splitting `DiagnosticEmitterBase` and
`DiagnosticEmitter` just to keep the emitter definition separate from
the context.

Also cleans up some incorrect check diagnostic emitter dependencies in
lower.
2025-03-27 00:41:30 +00:00
Jon Ross-Perkins acbe6530c3 Move diagnostics into a namespace (#5173)
What this really does is avoids shadowing names, so that we can
comfortable have things like `Check::DiagnosticEmitter` or
`Check::DiagnosticLoc` without shadowing being a concern.

Note, down this path I'm also thinking about:

- Renaming misc DiagnosticConsumer/DiagnosticEmitter classes, possibly
just to DiagnosticConsumer/DiagnosticEmitter (so
`Check::DiagnosticEmitter` instead of `SemIRLocDiagnosticEmitter`).
- Dropping `Diagnostic` from `Emitter::DiagnosticBuilder`.
- But not for `Check::DiagnosticBuilder`, because `Check::Builder` would
be ambiguous.
- Renaming diagnostics/diagnostic_* to drop "diagnostic".

[Discussion about SemIRLoc ->
DiagnosticLoc](https://discord.com/channels/655572317891461132/655578254970716160/1353771570463768698)
reminded me of this (in particular the older [Check::DiagnosticBuilder
discussion](https://discord.com/channels/655572317891461132/655578254970716160/1344363562608627763)),
but I'd only do that rename if there's matching consensus about a path
forward where we keep SemIRLoc, and in a way that it's only ever used
for diagnostics (the divergence from which is at the root of current
LocId discussion).

I'm trying to keep that separate from a namespace addition for clarity.
2025-03-26 19:12:10 +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 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
Boaz Brickner 5b70a3ea91 Generate AST when importing a cpp file (#4790)
Ignore the AST and support a single Cpp import, for now.
Report cpp compilation errors and warnings.
Part of #4666
2025-01-14 20:45:50 +00:00
Jon Ross-Perkins 87b3671330 Refactor single-unit checking out of check.cpp (#4649)
This is primarily moving code around, to try to create a logical split
of the code in check.cpp, makingthe API boundaries clearer.

There's one small, deliberate logic change around false returns from
`HandleParseNode`, where before there was a `CARBON_CHECK` instantiated
by the `#define` (per `NodeKind`), and now it's outside the `#define`
(done mainly because the message didn't keep up with the `Handle##Name`
-> `HandleParseNode` rename).
2024-12-10 21:00:51 +00:00
Boaz Bricknerandjonmeow daba2c72cf [NFC] Convert NameScope from struct to class (#4623)
This is a preparation change for adding name poisoning support
(https://github.com/carbon-language/carbon-lang/issues/4622), which is
expected to require more elaborate logic around NameScope since a name
can be not defined yet, defined, or poisoned.

The API separates looking up a name from getting the full entry since we
have cases where the entries are invalidated between the time we're
looking for the name and when we access (and sometimes modify) the
entry.

This change has the following benefits:
* `names` and `name_map` are internal to `NameScope` and are guaranteed
to match.
* `extended_scopes` and `import_ir_scopes` can not be manipulated (only
new scopes can be added).
* `inst_id`, `name_id` and `parent_scope_id` are constants.
* `has_error` can only be mutated from false to true.

---------

Co-authored-by: jonmeow <jperkins@google.com>
2024-12-06 21:50:50 +00:00
Jon Ross-Perkins e7a86b03c6 Remove offsets from InstId formatting, trying to name more (#4645)
The offsets were originally added to deal with churn from builtins in
the raw semir. In textual semir, we mostly see instruction IDs for
imports, and builtins have also settled down more.

On imports, where possible, use the `EntityNameId` for an import instead
of printing an instruction. Next, show the source location if we have a
node. Only show the instruction if there's no location.

This also exposes `Parse::Tree` and `TokenizedBuffer`, so that we can
pass a `SemIR::File` without the component parts. In particular this
allows us to get the `TokenizedBuffer` for import IRs without
substantial structural modifications. We may want to make these optional
for serialized `SemIR` later, but the nodes/tokens contain source
location, which we'd need for debug information -- so it's not clear how
much we can really make them optional without substantial information
loss.

Reduce arguments to just `File` in a few spots, as a result of the
accompanying `TokenizedBuffer` and `Parse::Tree`. Also updates style to
pass around `const File*` where the reference is maintained, instead of
`const File&`.

I was considering keeping a direct reference to the tree and tokens on
`Context`, but initially my thought was it wouldn't make much
difference. I can re-add those if desired, just as direct caching of the
`File` fields.
2024-12-06 21:17:24 +00:00
Jon Ross-Perkins 1cba3328f7 Finish removing BuiltinInstKind (#4637) 2024-12-05 22:07:51 +00:00
Jon Ross-Perkins efab39cbd9 Remove InstId::Builtin members (#4632)
- `InstId::Builtin<Inst>` -> `<Inst>::SingletonInstId`
- `InstId::PackageNamespace` -> `Namespace::PackageInstId`
2024-12-05 18:13:46 +00:00
Jon Ross-Perkins 48a84ca55d Restrict the Cpp package name (#4618)
We're looking at using this for imports, and it gets awkward if we allow
users to declare entries.
2024-12-03 20:47:19 +00:00
Jon Ross-Perkins 17272cf93c Change how CheckParseTrees receives NodeLocConverters (#4563)
This is really a set of closely related changes:

1) We really shouldn't be creating a Check::Unit for _Lower_. This fixes
that by storing the diagnostic converter for reuse.
2) Rather than passing in node converters to Check as their own array,
pass diagnostic converters as part of Check::Unit.
3) To support creating the converters early, pass SemIR::File
pre-constructed.
4) Since SemIR::File construction was used to track "checked", add
`is_checked` for that.
5) Clarifies a subtle edge case around `input_filename_` use with `-`.

Note the key consequence of this change, where I actually started, is
that `Check` only has one array of `Check::Unit` instead of receiving
`NodeLocConverter` as a separate array.
2024-11-22 16:51:10 +00:00
Jon Ross-Perkins 16bf3f710e Split deferred node traversal out from check.cpp (#4559)
I'm looking at adding more significant logic to checking, particularly
for interop. But check.cpp is getting large, and I think just adding
more logic will make it harder to reason about, so I'm looking at
splitting it up. This moves out NodeIdTraversal and
DeferredDefinitionWorklist because they're already independent from the
other code, and are reasonably sized to have their own files.
2024-11-20 20:58:58 +00:00
Jon Ross-Perkins 4eb955bf42 Drop std:: on size_t in various spots. (#4546)
We predominantly omit the `std::` in these cases already. This is for
style: "Prefer to omit the std:: prefix for these types, as the extra 5
characters do not merit the added clutter."
(https://google.github.io/styleguide/cppguide.html#Integer_Types)
2024-11-18 22:28:57 +00:00
Jon Ross-Perkins 1d8c7ffe89 Add support for scoped timings. (#4533)
I think there are a few related ways to do this. I considered
llvm::make_scope_exit, but the return type is difficult to work with. I
particularly was thinking I could encapsulate the duration logic this
way.
2024-11-15 16:57:33 +00:00