mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
Fundamentally, this uses forward declarations of Clang types to reduce the overall compile time cost of Clang headers across the codebase. Tracing and profiling showed ~2s of every check TU's ~8-12s compile time going just to parsing Clang frontend and AST headers pulled in via a few sem_ir and check headers that only use the Clang types by pointer or reference: - sem_ir/cpp_file.h (reached via sem_ir/file.h by ~150 TUs) included clang/Frontend/CompilerInstance.h, clang/CodeGen/ModuleBuilder.h, clang/AST/Mangle.h, and llvm/IR/Module.h. CppFile's accessors move out of line to a new cpp_file.cpp and the header now forward-declares the Clang types. - check/cpp/context.h (reached via check/context.h by ~100 TUs) included clang/Frontend/FrontendAction.h and clang/Parse/Parser.h, pulling in clang's Sema.h and ASTUnit.h. - sem_ir/clang_decl.h included clang/AST/Decl.h; the three small functions that need complete Clang types move out of line. - sem_ir/cpp_overload_set.h included clang/Sema/Overload.h solely for the three-field OverloadCandidateSet::OperatorRewriteInfo, which is now mirrored as CppOverloadSet::OperatorRewriteInfo, and clang/AST/Decl.h solely for a pointer. - sem_ir/name_scope.h's clang/AST/DeclBase.h include was vestigial. TUs (and more narrowly included headers) that genuinely use the Clang definitions now include the Clang headers directly. Representative compile times (fastbuild, aarch64), combined with the preceding instantiation-cost changes, relative to trunk: - check/eval.cpp: 11.85s -> 6.94s (-41%) - check/handle_operator.cpp: 7.71s -> 3.30s (-57%) - language_server.cpp: 6.68s -> 3.16s (-53%) - lower/handle.cpp: 6.75s -> 3.66s (-46%) - sem_ir/file.cpp: 8.60s -> 6.11s (-29%) - driver.cpp: 6.68s -> 4.78s (-28%) Measured full-rebuild impact (316 first-party TUs, fastbuild): -689.5s CPU, -29.9% relative to trunk. Assisted-by: Claude
62 lines
2.3 KiB
C++
62 lines
2.3 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/check/cpp/access.h"
|
|
|
|
#include "clang/AST/Decl.h"
|
|
|
|
namespace Carbon::Check {
|
|
|
|
static auto CalculateEffectiveAccess(clang::DeclAccessPair access_pair)
|
|
-> clang::AccessSpecifier {
|
|
// Note that we use `.getAccess()` here, not `->getAccess()`, which is
|
|
// equivalent to `.getDecl()->getAccess()`, because we want to consider the
|
|
// lookup access and not the lexical access.
|
|
switch (access_pair.getAccess()) {
|
|
// Lookup access takes precedence.
|
|
case clang::AS_public:
|
|
case clang::AS_protected:
|
|
case clang::AS_private:
|
|
return access_pair.getAccess();
|
|
case clang::AS_none:
|
|
// No access specified meaning depends on the declaration. For non class
|
|
// members, it means there's no access associated with this function so we
|
|
// treat it as public. For class members it means we lost access along the
|
|
// inheritance path, and the difference between `none` and `private` only
|
|
// matters when the access check is performed within a friend or member of
|
|
// the naming class. Because the naming class is a C++ class, and we don't
|
|
// yet have a mechanism for a C++ class to befriend a Carbon class, we can
|
|
// safely map `none` to `private` for now.
|
|
return access_pair->isCXXClassMember() ? clang::AS_private
|
|
: clang::AS_public;
|
|
}
|
|
}
|
|
|
|
auto MapCppAccess(clang::DeclAccessPair access_pair) -> SemIR::AccessKind {
|
|
switch (CalculateEffectiveAccess(access_pair)) {
|
|
case clang::AS_public:
|
|
return SemIR::AccessKind::Public;
|
|
case clang::AS_protected:
|
|
return SemIR::AccessKind::Protected;
|
|
case clang::AS_private:
|
|
return SemIR::AccessKind::Private;
|
|
case clang::AS_none:
|
|
CARBON_FATAL("Couldn't convert access");
|
|
}
|
|
}
|
|
|
|
auto MapToCppAccess(SemIR::AccessKind access) -> clang::AccessSpecifier {
|
|
switch (access) {
|
|
case SemIR::AccessKind::Public:
|
|
return clang::AS_public;
|
|
case SemIR::AccessKind::Protected:
|
|
return clang::AS_protected;
|
|
case SemIR::AccessKind::Private:
|
|
case SemIR::AccessKind::Hidden:
|
|
return clang::AS_private;
|
|
}
|
|
}
|
|
|
|
} // namespace Carbon::Check
|