314 changes: 314 additions & 0 deletions bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper.s

Large diffs are not rendered by default.

315 changes: 315 additions & 0 deletions bolt/test/X86/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper1.s

Large diffs are not rendered by default.

505 changes: 505 additions & 0 deletions bolt/test/X86/Inputs/dwarf5-df-debug-names-ftu-ltu-mix-main.s

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions bolt/test/X86/dwarf5-df-main-debug-names-ftu-ltu-mix.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
; RUN: rm -rf %t
; RUN: mkdir %t
; RUN: cd %t
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-df-debug-names-ftu-ltu-mix-main.s \
; RUN: -split-dwarf-file=main.dwo -o main.o
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper.s -o helper.o
; RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %p/Inputs/dwarf5-debug-names-ftu-ltu-mix-helper1.s -o helper1.o
; RUN: %clang %cflags -gdwarf-5 -gsplit-dwarf=split main.o helper.o helper1.o -o main.exe -fno-pic -no-pie
; RUN: llvm-bolt main.exe -o main.exe.bolt --update-debug-sections --create-debug-names-section=true
; RUN: llvm-dwarfdump --debug-names main.exe.bolt | FileCheck -check-prefix=BOLT %s

;; Tests BOLT correctly sets foreign TU Index when there are local TUs.

; BOLT: Compilation Unit offsets [
; BOLT-NEXT: CU[0]: {{.+}}
; BOLT-NEXT: CU[1]: {{.+}}
; BOLT-NEXT: CU[2]: {{.+}}
; BOLT-NEXT: ]
; BOLT-NEXT: Local Type Unit offsets [
; BOLT-NEXT: LocalTU[0]: {{.+}}
; BOLT-NEXT: LocalTU[1]: {{.+}}
; BOLT-NEXT: ]
; BOLT-NEXT: Foreign Type Unit signatures [
; BOLT-NEXT: ForeignTU[0]: 0x889c84450dac881f
; BOLT-NEXT: ]
; BOLT: Name 3 {
; BOLT-NEXT: Hash: 0x6A05C500
; BOLT-NEXT: String: {{.+}} "globalMono1"
; BOLT-NEXT: Entry @ {{.+}} {
; BOLT-NEXT: Abbrev: 0x5
; BOLT-NEXT: Tag: DW_TAG_variable
; BOLT-NEXT: DW_IDX_compile_unit: 0x02
; BOLT-NEXT: DW_IDX_die_offset: 0x0000001e
; BOLT-NEXT: }
; BOLT-NEXT: }
; BOLT: Name 6 {
; BOLT-NEXT: Hash: 0xF283AF92
; BOLT-NEXT: String: {{.+}} "ASplit"
; BOLT-NEXT: Entry @ {{.+}} {
; BOLT-NEXT: Abbrev: 0x7
; BOLT-NEXT: Tag: DW_TAG_structure_type
; BOLT-NEXT: DW_IDX_type_unit: 0x02
; BOLT-NEXT: DW_IDX_compile_unit: 0x00
; BOLT-NEXT: DW_IDX_die_offset: 0x00000021
; BOLT-NEXT: }
; BOLT-NEXT: }
; BOLT: Name 7 {
; BOLT-NEXT: Hash: 0xF17F51F
; BOLT-NEXT: String: {{.+}} "AMono"
; BOLT-NEXT: Entry @ {{.+}} {
; BOLT-NEXT: Abbrev: 0x4
; BOLT-NEXT: Tag: DW_TAG_structure_type
; BOLT-NEXT: DW_IDX_type_unit: 0x00
; BOLT-NEXT: DW_IDX_die_offset: 0x00000023
; BOLT-NEXT: }
; BOLT-NEXT: }
41 changes: 41 additions & 0 deletions bolt/test/X86/linux-pci-fixup.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# REQUIRES: system-linux

# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %s -o %t.o
# RUN: %clang %cflags -nostdlib %t.o -o %t.exe \
# RUN: -Wl,--image-base=0xffffffff80000000,--no-dynamic-linker,--no-eh-frame-hdr,--no-pie
# RUN: llvm-bolt %t.exe --print-normalized -o %t.out |& FileCheck %s

## Check that BOLT correctly parses the Linux kernel .pci_fixup section and
## verify that PCI fixup hook in the middle of a function is detected.

# CHECK: BOLT-INFO: Linux kernel binary detected
# CHECK: BOLT-WARNING: PCI fixup detected in the middle of function _start
# CHECK: BOLT-INFO: parsed 2 PCI fixup entries

.text
.globl _start
.type _start, %function
_start:
nop
.L0:
ret
.size _start, .-_start

## PCI fixup table.
.section .pci_fixup,"a",@progbits

.short 0x8086 # vendor
.short 0xbeef # device
.long 0xffffffff # class
.long 0x0 # class shift
.long _start - . # fixup

.short 0x8086 # vendor
.short 0xbad # device
.long 0xffffffff # class
.long 0x0 # class shift
.long .L0 - . # fixup

## Fake Linux Kernel sections.
.section __ksymtab,"a",@progbits
.section __ksymtab_gpl,"a",@progbits
33 changes: 23 additions & 10 deletions clang-tools-extra/clang-tidy/bugprone/UnusedReturnValueCheck.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Basic/OperatorKinds.h"

using namespace clang::ast_matchers;
using namespace clang::ast_matchers::internal;
Expand All @@ -28,6 +30,11 @@ AST_MATCHER_P(FunctionDecl, isInstantiatedFrom, Matcher<FunctionDecl>,
return InnerMatcher.matches(InstantiatedFrom ? *InstantiatedFrom : Node,
Finder, Builder);
}

AST_MATCHER_P(CXXMethodDecl, isOperatorOverloading,
llvm::SmallVector<OverloadedOperatorKind>, Kinds) {
return llvm::is_contained(Kinds, Node.getOverloadedOperator());
}
} // namespace

UnusedReturnValueCheck::UnusedReturnValueCheck(llvm::StringRef Name,
Expand Down Expand Up @@ -157,16 +164,22 @@ void UnusedReturnValueCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}

void UnusedReturnValueCheck::registerMatchers(MatchFinder *Finder) {
auto MatchedDirectCallExpr =
expr(callExpr(callee(functionDecl(
// Don't match void overloads of checked functions.
unless(returns(voidType())),
anyOf(isInstantiatedFrom(matchers::matchesAnyListedName(
CheckedFunctions)),
returns(hasCanonicalType(hasDeclaration(
namedDecl(matchers::matchesAnyListedName(
CheckedReturnTypes)))))))))
.bind("match"));
auto MatchedDirectCallExpr = expr(
callExpr(
callee(functionDecl(
// Don't match void overloads of checked functions.
unless(returns(voidType())),
// Don't match copy or move assignment operator.
unless(cxxMethodDecl(isOperatorOverloading(
{OO_Equal, OO_PlusEqual, OO_MinusEqual, OO_StarEqual,
OO_SlashEqual, OO_PercentEqual, OO_CaretEqual, OO_AmpEqual,
OO_PipeEqual, OO_LessLessEqual, OO_GreaterGreaterEqual}))),
anyOf(
isInstantiatedFrom(
matchers::matchesAnyListedName(CheckedFunctions)),
returns(hasCanonicalType(hasDeclaration(namedDecl(
matchers::matchesAnyListedName(CheckedReturnTypes)))))))))
.bind("match"));

auto CheckCastToVoid =
AllowCastToVoid ? castExpr(unless(hasCastKind(CK_ToVoid))) : castExpr();
Expand Down
10 changes: 5 additions & 5 deletions clang-tools-extra/clangd/ClangdServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,7 @@ void ClangdServer::formatFile(PathRef File, std::optional<Range> Rng,
auto Action = [File = File.str(), Code = std::move(*Code),
Ranges = std::vector<tooling::Range>{RequestedRange},
CB = std::move(CB), this]() mutable {
format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS);
format::FormatStyle Style = getFormatStyleForFile(File, Code, TFS, true);
tooling::Replacements IncludeReplaces =
format::sortIncludes(Style, Code, Ranges, File);
auto Changed = tooling::applyAllReplacements(Code, IncludeReplaces);
Expand Down Expand Up @@ -551,7 +551,7 @@ void ClangdServer::formatOnType(PathRef File, Position Pos,
auto Action = [File = File.str(), Code = std::move(*Code),
TriggerText = TriggerText.str(), CursorPos = *CursorPos,
CB = std::move(CB), this]() mutable {
auto Style = getFormatStyleForFile(File, Code, TFS);
auto Style = getFormatStyleForFile(File, Code, TFS, false);
std::vector<TextEdit> Result;
for (const tooling::Replacement &R :
formatIncremental(Code, CursorPos, TriggerText, Style))
Expand Down Expand Up @@ -605,7 +605,7 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,

if (Opts.WantFormat) {
auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
*InpAST->Inputs.TFS);
*InpAST->Inputs.TFS, false);
llvm::Error Err = llvm::Error::success();
for (auto &E : R->GlobalChanges)
Err =
Expand Down Expand Up @@ -762,7 +762,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID,
for (auto &It : (*Effect)->ApplyEdits) {
Edit &E = It.second;
format::FormatStyle Style =
getFormatStyleForFile(File, E.InitialCode, TFS);
getFormatStyleForFile(File, E.InitialCode, TFS, false);
if (llvm::Error Err = reformatEdit(E, Style))
elog("Failed to format {0}: {1}", It.first(), std::move(Err));
}
Expand Down Expand Up @@ -825,7 +825,7 @@ void ClangdServer::findHover(PathRef File, Position Pos,
if (!InpAST)
return CB(InpAST.takeError());
format::FormatStyle Style = getFormatStyleForFile(
File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS);
File, InpAST->Inputs.Contents, *InpAST->Inputs.TFS, false);
CB(clangd::getHover(InpAST->AST, Pos, std::move(Style), Index));
};

Expand Down
4 changes: 2 additions & 2 deletions clang-tools-extra/clangd/CodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,7 +1628,7 @@ class CodeCompleteFlow {
IsUsingDeclaration = Recorder->CCContext.isUsingDeclaration();
auto Style = getFormatStyleForFile(SemaCCInput.FileName,
SemaCCInput.ParseInput.Contents,
*SemaCCInput.ParseInput.TFS);
*SemaCCInput.ParseInput.TFS, false);
const auto NextToken = findTokenAfterCompletionPoint(
Recorder->CCSema->getPreprocessor().getCodeCompletionLoc(),
Recorder->CCSema->getSourceManager(), Recorder->CCSema->LangOpts);
Expand Down Expand Up @@ -1719,7 +1719,7 @@ class CodeCompleteFlow {
ProxSources[FileName].Cost = 0;
FileProximity.emplace(ProxSources);

auto Style = getFormatStyleForFile(FileName, Content, TFS);
auto Style = getFormatStyleForFile(FileName, Content, TFS, false);
// This will only insert verbatim headers.
Inserter.emplace(FileName, Content, Style,
/*BuildDir=*/"", /*HeaderSearchInfo=*/nullptr);
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/IncludeCleaner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ std::vector<Diag> generateMissingIncludeDiagnostics(
const SourceManager &SM = AST.getSourceManager();
const FileEntry *MainFile = SM.getFileEntryForID(SM.getMainFileID());

auto FileStyle = getFormatStyleForFile(AST.tuPath(), Code, TFS);
auto FileStyle = getFormatStyleForFile(AST.tuPath(), Code, TFS, false);

tooling::HeaderIncludes HeaderIncludes(AST.tuPath(), Code,
FileStyle.IncludeStyle);
Expand Down
3 changes: 1 addition & 2 deletions clang-tools-extra/clangd/JSONTransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ class JSONTransport : public Transport {
return error(std::make_error_code(std::errc::operation_canceled),
"Got signal, shutting down");
if (ferror(In))
return llvm::errorCodeToError(
std::error_code(errno, std::system_category()));
return llvm::errorCodeToError(llvm::errnoAsErrorCode());
if (readRawMessage(JSON)) {
ThreadCrashReporter ScopedReporter([&JSON]() {
auto &OS = llvm::errs();
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/ParsedAST.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,7 @@ ParsedAST::build(llvm::StringRef Filename, const ParseInputs &Inputs,
// (e.g. incomplete type) and attach include insertion fixes to diagnostics.
if (Inputs.Index && !BuildDir.getError()) {
auto Style =
getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS);
getFormatStyleForFile(Filename, Inputs.Contents, *Inputs.TFS, false);
auto Inserter = std::make_shared<IncludeInserter>(
Filename, Inputs.Contents, Style, BuildDir.get(),
&Clang->getPreprocessor().getHeaderSearchInfo());
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1412,7 +1412,7 @@ bool fromJSON(const llvm::json::Value &Params, ReferenceParams &R,
}

llvm::json::Value toJSON(SymbolTag Tag) {
return llvm::json::Value{static_cast<int>(Tag)};
return llvm::json::Value(static_cast<int>(Tag));
}

llvm::json::Value toJSON(const CallHierarchyItem &I) {
Expand Down
16 changes: 15 additions & 1 deletion clang-tools-extra/clangd/SourceCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -582,7 +582,21 @@ std::optional<FileDigest> digestFile(const SourceManager &SM, FileID FID) {

format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
llvm::StringRef Content,
const ThreadsafeFS &TFS) {
const ThreadsafeFS &TFS,
bool FormatFile) {
// Unless we're formatting a substantial amount of code (the entire file
// or an arbitrarily large range), skip libFormat's heuristic check for
// .h files that tries to determine whether the file contains objective-c
// code. (This is accomplished by passing empty code contents to getStyle().
// The heuristic is the only thing that looks at the contents.)
// This is a workaround for PR60151, a known issue in libFormat where this
// heuristic can OOM on large files. If we *are* formatting the entire file,
// there's no point in doing this because the actual format::reformat() call
// will run into the same OOM; we'd just be risking inconsistencies between
// clangd and clang-format on smaller .h files where they disagree on what
// language is detected.
if (!FormatFile)
Content = {};
auto Style = format::getStyle(format::DefaultFormatStyle, File,
format::DefaultFallbackStyle, Content,
TFS.view(/*CWD=*/std::nullopt).get());
Expand Down
6 changes: 5 additions & 1 deletion clang-tools-extra/clangd/SourceCode.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,13 @@ std::optional<std::string> getCanonicalPath(const FileEntryRef F,
/// FIXME: should we be caching the .clang-format file search?
/// This uses format::DefaultFormatStyle and format::DefaultFallbackStyle,
/// though the latter may have been overridden in main()!
/// \p FormatFile indicates whether the returned FormatStyle is used
/// to format the entire main file (or a range selected by the user
/// which can be arbitrarily long).
format::FormatStyle getFormatStyleForFile(llvm::StringRef File,
llvm::StringRef Content,
const ThreadsafeFS &TFS);
const ThreadsafeFS &TFS,
bool FormatFile);

/// Cleanup and format the given replacements.
llvm::Expected<tooling::Replacements>
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/tool/Check.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class Checker {

// FIXME: Check that resource-dir/built-in-headers exist?

Style = getFormatStyleForFile(File, Inputs.Contents, TFS);
Style = getFormatStyleForFile(File, Inputs.Contents, TFS, false);

return true;
}
Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/unittests/DiagnosticsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ TEST(DiagnosticTest, RespectsDiagnosticConfig) {
Diag(Main.range("ret"),
"void function 'x' should not return a value")));
Config Cfg;
Cfg.Diagnostics.Suppress.insert("return-type");
Cfg.Diagnostics.Suppress.insert("return-mismatch");
WithContextValue WithCfg(Config::Key, std::move(Cfg));
EXPECT_THAT(TU.build().getDiagnostics(),
ElementsAre(Diag(Main.range(),
Expand Down
28 changes: 28 additions & 0 deletions clang-tools-extra/clangd/unittests/SelectionTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "SourceCode.h"
#include "TestTU.h"
#include "support/TestTracer.h"
#include "clang/AST/ASTConcept.h"
#include "clang/AST/Decl.h"
#include "llvm/Support/Casting.h"
#include "gmock/gmock.h"
Expand Down Expand Up @@ -893,6 +894,33 @@ TEST(SelectionTest, DeclContextLambda) {
EXPECT_TRUE(ST.commonAncestor()->getDeclContext().isFunctionOrMethod());
}

TEST(SelectionTest, UsingConcepts) {
llvm::Annotations Test(R"cpp(
namespace ns {
template <typename T>
concept Foo = true;
}
using ns::Foo;
template <Fo^o... T, Fo^o auto U>
auto Func(Fo^o auto V) -> Fo^o decltype(auto) {
Fo^o auto W = V;
return W;
}
)cpp");
auto TU = TestTU::withCode(Test.code());
TU.ExtraArgs.emplace_back("-std=c++2c");
auto AST = TU.build();
for (auto Point : Test.points()) {
auto ST = SelectionTree::createRight(AST.getASTContext(), AST.getTokens(),
Point, Point);
auto *C = ST.commonAncestor()->ASTNode.get<ConceptReference>();
EXPECT_TRUE(C && C->getFoundDecl() &&
C->getFoundDecl()->getKind() == Decl::UsingShadow);
}
}

} // namespace
} // namespace clangd
} // namespace clang
38 changes: 38 additions & 0 deletions clang-tools-extra/clangd/unittests/SourceCodeTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,44 @@ TEST(ApplyEditsTest, EndLineOutOfRange) {
FailedWithMessage("Line value is out of range (100)"));
}

TEST(FormatStyleForFile, LanguageGuessingHeuristic) {
StringRef ObjCContent = "@interface Foo\n@end\n";
StringRef CppContent = "class Foo {};\n";
using LK = format::FormatStyle::LanguageKind;
struct TestCase {
llvm::StringRef Filename;
llvm::StringRef Contents;
bool FormatFile;
LK ExpectedLanguage;
} TestCases[] = {
// If the file extension identifies the file as ObjC, the guessed
// language should be ObjC regardless of content or FormatFile flag.
{"foo.mm", ObjCContent, true, LK::LK_ObjC},
{"foo.mm", ObjCContent, false, LK::LK_ObjC},
{"foo.mm", CppContent, true, LK::LK_ObjC},
{"foo.mm", CppContent, false, LK::LK_ObjC},

// If the file extension is ambiguous like .h, FormatFile=true should
// result in using libFormat's heuristic to guess the language based
// on the file contents.
{"foo.h", ObjCContent, true, LK::LK_ObjC},
{"foo.h", CppContent, true, LK::LK_Cpp},

// With FomatFile=false, the language guessing heuristic should be
// bypassed
{"foo.h", ObjCContent, false, LK::LK_Cpp},
{"foo.h", CppContent, false, LK::LK_Cpp},
};

MockFS FS;
for (const auto &[Filename, Contents, FormatFile, ExpectedLanguage] :
TestCases) {
EXPECT_EQ(
getFormatStyleForFile(Filename, Contents, FS, FormatFile).Language,
ExpectedLanguage);
}
}

} // namespace
} // namespace clangd
} // namespace clang
4 changes: 2 additions & 2 deletions clang-tools-extra/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ Changes in existing checks

- Improved :doc:`bugprone-unused-return-value
<clang-tidy/checks/bugprone/unused-return-value>` check by updating the
parameter `CheckedFunctions` to support regexp and avoiding false postive for
parameter `CheckedFunctions` to support regexp, avoiding false positive for
function with the same prefix as the default argument, e.g. ``std::unique_ptr``
and ``std::unique``.
and ``std::unique``, avoiding false positive for assignment operator overloading.

- Improved :doc:`bugprone-use-after-move
<clang-tidy/checks/bugprone/use-after-move>` check to also handle
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ bugprone-unused-return-value

Warns on unused function return values. The checked functions can be configured.

Operator overloading with assignment semantics are ignored.

Options
-------

Expand Down
4 changes: 1 addition & 3 deletions clang-tools-extra/include-cleaner/unittests/WalkASTTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -548,9 +548,7 @@ TEST(WalkAST, Concepts) {
testWalk(Concept, "template<typename T> requires ^Foo<T> void func() {}");
testWalk(Concept, "template<typename T> void func() requires ^Foo<T> {}");
testWalk(Concept, "void func(^Foo auto x) {}");
// FIXME: Foo should be explicitly referenced.
testWalk("template<typename T> concept Foo = true;",
"void func() { ^Foo auto x = 1; }");
testWalk(Concept, "void func() { ^Foo auto x = 1; }");
}

TEST(WalkAST, FriendDecl) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// RUN: %check_clang_tidy %s bugprone-unused-return-value %t \
// RUN: -config='{CheckOptions: \
// RUN: {bugprone-unused-return-value.CheckedFunctions: "::*"}}' \
// RUN: --

struct S {
S(){};
S(S const &);
S(S &&);
S &operator=(S const &);
S &operator=(S &&);
S &operator+=(S);
};

S returnValue();
S const &returnRef();

void bar() {
returnValue();
// CHECK-MESSAGES: [[@LINE-1]]:3: warning: the value returned by this function should not be disregarded; neglecting it may lead to errors

S a{};
a = returnValue();
a.operator=(returnValue());

a = returnRef();
a.operator=(returnRef());

a += returnRef();
}
2 changes: 2 additions & 0 deletions clang/cmake/caches/Fuchsia.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ set(_FUCHSIA_BOOTSTRAP_PASSTHROUGH
LLDB_EMBED_PYTHON_HOME
LLDB_PYTHON_HOME
LLDB_PYTHON_RELATIVE_PATH
LLDB_TEST_USE_VENDOR_PACKAGES
LLDB_TEST_USER_ARGS
Python3_EXECUTABLE
Python3_LIBRARIES
Python3_INCLUDE_DIRS
Expand Down
22 changes: 22 additions & 0 deletions clang/docs/DataFlowSanitizer.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,28 @@ labels of just ``v1`` and ``v2``.
or, and can be accessed using
``dfsan_label dfsan_get_labels_in_signal_conditional();``.

* ``-dfsan-reaches-function-callbacks`` -- An experimental feature that inserts
callbacks for data entering a function.

In addition to this compilation flag, a callback handler must be registered
using ``dfsan_set_reaches_function_callback(my_callback);``, where my_callback is
a function with a signature matching
``void my_callback(dfsan_label label, dfsan_origin origin, const char *file, unsigned int line, const char *function);``
This signature is the same when origin tracking is disabled - in this case
the dfsan_origin passed in it will always be 0.

The callback will be called when a tained value reach stack/registers
in the context of a function. Tainted values can reach a function:
* via the arguments of the function
* via the return value of a call that occurs in the function
* via the loaded value of a load that occurs in the function

The callback will be skipped for conditional expressions inside signal
handlers, as this is prone to deadlock. Tainted values reaching functions
inside signal handlers will instead be aggregated via bitwise or, and can
be accessed using
``dfsan_label dfsan_get_labels_in_signal_reaches_function()``.

* ``-dfsan-track-origins`` -- Controls how to track origins. When its value is
0, the runtime does not track origins. When its value is 1, the runtime tracks
origins at memory store operations. When its value is 2, the runtime tracks
Expand Down
15 changes: 15 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3443,6 +3443,21 @@ Query for this feature with ``__has_builtin(__builtin_debugtrap)``.

Query for this feature with ``__has_builtin(__builtin_trap)``.

``__builtin_arm_trap``
------------------

``__builtin_arm_trap`` is an AArch64 extension to ``__builtin_trap`` which also accepts a compile-time constant value, encoded directly into the trap instruction for later inspection.

**Syntax**:

.. code-block:: c++

__builtin_arm_trap(const unsigned short payload)

**Description**

``__builtin_arm_trap`` is lowered to the ``llvm.aarch64.break`` builtin, and then to ``brk #payload``.

``__builtin_nondeterministic_value``
------------------------------------

Expand Down
48 changes: 47 additions & 1 deletion clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ C++23 Feature Support

- Implemented `P2718R0: Lifetime extension in range-based for loops <https://wg21.link/P2718R0>`_. Also
materialize temporary object which is a prvalue in discarded-value expression.
- Implemented `P1774R8: Portable assumptions <https://wg21.link/P1774R8>`_.

- Implemented `P2448R2: Relaxing some constexpr restrictions <https://wg21.link/P2448R2>`_.

Expand Down Expand Up @@ -182,6 +183,9 @@ Deprecated Compiler Flags

Modified Compiler Flags
-----------------------
- Added a new diagnostic flag ``-Wreturn-mismatch`` which is grouped under
``-Wreturn-type``, and moved some of the diagnostics previously controlled by
``-Wreturn-type`` under this new flag. Fixes #GH72116.

Removed Compiler Flags
-------------------------
Expand All @@ -190,6 +194,12 @@ Removed Compiler Flags

Attribute Changes in Clang
--------------------------
- Introduced a new function attribute ``__attribute__((amdgpu_max_num_work_groups(x, y, z)))`` or
``[[clang::amdgpu_max_num_work_groups(x, y, z)]]`` for the AMDGPU target. This attribute can be
attached to HIP or OpenCL kernel function definitions to provide an optimization hint. The parameters
``x``, ``y``, and ``z`` specify the maximum number of workgroups for the respective dimensions,
and each must be a positive integer when provided. The parameter ``x`` is required, while ``y`` and
``z`` are optional with default value of 1.

Improvements to Clang's diagnostics
-----------------------------------
Expand Down Expand Up @@ -227,6 +237,10 @@ Improvements to Clang's diagnostics
- Clang now diagnoses lambda function expressions being implicitly cast to boolean values, under ``-Wpointer-bool-conversion``.
Fixes #GH82512.

- Clang now provides improved warnings for the ``cleanup`` attribute to detect misuse scenarios,
such as attempting to call ``free`` on an unallocated object. Fixes
`#79443 <https://github.com/llvm/llvm-project/issues/79443>`_.

Improvements to Clang's time-trace
----------------------------------

Expand All @@ -250,6 +264,9 @@ Bug Fixes in This Version
for logical operators in C23.
Fixes (#GH64356).

- ``__is_trivially_relocatable`` no longer returns ``false`` for volatile-qualified types.
Fixes (#GH77091).

- Clang no longer produces a false-positive `-Wunused-variable` warning
for variables created through copy initialization having side-effects in C++17 and later.
Fixes (#GH64356) (#GH79518).
Expand All @@ -258,6 +275,16 @@ Bug Fixes in This Version
operator.
Fixes (#GH83267).

- Clang now correctly generates overloads for bit-precise integer types for
builtin operators in C++. Fixes #GH82998.

- When performing mixed arithmetic between ``_Complex`` floating-point types and integers,
Clang now correctly promotes the integer to its corresponding real floating-point
type only rather than to the complex type (e.g. ``_Complex float / int`` is now evaluated
as ``_Complex float / float`` rather than ``_Complex float / _Complex float``), as mandated
by the C standard. This significantly improves codegen of `*` and `/` especially.
Fixes (`#31205 <https://github.com/llvm/llvm-project/issues/31205>`_).

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down Expand Up @@ -344,9 +371,17 @@ Bug Fixes to C++ Support
when one of the function had more specialized templates.
Fixes (`#82509 <https://github.com/llvm/llvm-project/issues/82509>`_)
and (`#74494 <https://github.com/llvm/llvm-project/issues/74494>`_)
- Allow access to a public template alias declaration that refers to friend's
private nested type. (#GH25708).
- Fixed a crash in constant evaluation when trying to access a
captured ``this`` pointer in a lambda with an explicit object parameter.
Fixes (#GH80997)
- Fix an issue where missing set friend declaration in template class instantiation.
Fixes (#GH84368).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Clang now properly preserves ``FoundDecls`` within a ``ConceptReference``. (#GH82628)

Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -408,7 +443,7 @@ RISC-V Support
CUDA/HIP Language Changes
^^^^^^^^^^^^^^^^^^^^^^^^^

- PTX is no longer included by default when compiling for CUDA. Using
- PTX is no longer included by default when compiling for CUDA. Using
``--cuda-include-ptx=all`` will return the old behavior.

CUDA Support
Expand Down Expand Up @@ -440,6 +475,8 @@ AST Matchers

- ``isInStdNamespace`` now supports Decl declared with ``extern "C++"``.
- Add ``isExplicitObjectMemberFunction``.
- Fixed ``forEachArgumentWithParam`` and ``forEachArgumentWithParamType`` to
not skip the explicit object parameter for operator calls.

clang-format
------------
Expand All @@ -455,6 +492,10 @@ libclang
Static Analyzer
---------------

- Fixed crashing on loops if the loop variable was declared in switch blocks
but not under any case blocks if ``unroll-loops=true`` analyzer config is
set. (#GH68819)

New features
^^^^^^^^^^^^

Expand Down Expand Up @@ -490,6 +531,11 @@ Python Binding Changes

- Exposed `CXRewriter` API as `class Rewriter`.

OpenMP Support
--------------

- Added support for the `[[omp::assume]]` attribute.

Additional Information
======================

Expand Down
61 changes: 61 additions & 0 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4227,7 +4227,68 @@ Clang expects the GCC executable "gcc.exe" compiled for

AIX
^^^
TOC Data Transformation
"""""""""""""""""""""""
TOC data transformation is off by default (``-mno-tocdata``).
When ``-mtocdata`` is specified, the TOC data transformation will be applied to
all suitable variables with static storage duration, including static data
members of classes and block-scope static variables (if not marked as exceptions,
see further below).

Suitable variables must:

- have complete types
- be independently generated (i.e., not placed in a pool)
- be at most as large as a pointer
- not be aligned more strictly than a pointer
- not be structs containing flexible array members
- not have internal linkage
- not have aliases
- not have section attributes
- not be thread local storage

The TOC data transformation results in the variable, not its address,
being placed in the TOC. This eliminates the need to load the address of the
variable from the TOC.

Note:
If the TOC data transformation is applied to a variable whose definition
is imported, the linker will generate fixup code for reading or writing to the
variable.

When multiple toc-data options are used, the last option used has the affect.
For example: -mno-tocdata=g5,g1 -mtocdata=g1,g2 -mno-tocdata=g2 -mtocdata=g3,g4
results in -mtocdata=g1,g3,g4

Names of variables not having external linkage will be ignored.

**Options:**

.. option:: -mno-tocdata

This is the default behaviour. Only variables explicitly specified with
``-mtocdata=`` will have the TOC data transformation applied.

.. option:: -mtocdata

Apply the TOC data transformation to all suitable variables with static
storage duration (including static data members of classes and block-scope
static variables) that are not explicitly specified with ``-mno-tocdata=``.

.. option:: -mno-tocdata=

Can be used in conjunction with ``-mtocdata`` to mark the comma-separated
list of external linkage variables, specified using their mangled names, as
exceptions to ``-mtocdata``.

.. option:: -mtocdata=

Apply the TOC data transformation to the comma-separated list of external
linkage variables, specified using their mangled names, if they are suitable.
Emit diagnostics for all unsuitable variables specified.

Default Visibility Export Mapping
"""""""""""""""""""""""""""""""""
The ``-mdefault-visibility-export-mapping=`` option can be used to control
mapping of default visibility to an explicit shared object export
(i.e. XCOFF exported visibility). Three values are provided for the option:
Expand Down
10 changes: 10 additions & 0 deletions clang/include/clang/AST/DeclBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,16 @@ class alignas(8) Decl {
/// fragment. See [module.global.frag]p3,4 for details.
bool isDiscardedInGlobalModuleFragment() const { return false; }

/// Check if we should skip checking ODRHash for declaration \param D.
///
/// The existing ODRHash mechanism seems to be not stable enough and
/// the false positive ODR violation reports are annoying and we rarely see
/// true ODR violation reports. Also we learned that MSVC disabled ODR checks
/// for declarations in GMF. So we try to disable ODR checks in the GMF to
/// get better user experiences before we make the ODR violation checks stable
/// enough.
bool shouldSkipCheckingODR() const;

/// Return true if this declaration has an attribute which acts as
/// definition of the entity, such as 'alias' or 'ifunc'.
bool hasDefiningAttr() const;
Expand Down
21 changes: 21 additions & 0 deletions clang/include/clang/AST/ExprCXX.h
Original file line number Diff line number Diff line change
Expand Up @@ -5038,6 +5038,9 @@ class CoroutineSuspendExpr : public Expr {
OpaqueValueExpr *OpaqueValue = nullptr;

public:
// These types correspond to the three C++ 'await_suspend' return variants
enum class SuspendReturnType { SuspendVoid, SuspendBool, SuspendHandle };

CoroutineSuspendExpr(StmtClass SC, SourceLocation KeywordLoc, Expr *Operand,
Expr *Common, Expr *Ready, Expr *Suspend, Expr *Resume,
OpaqueValueExpr *OpaqueValue)
Expand Down Expand Up @@ -5097,6 +5100,24 @@ class CoroutineSuspendExpr : public Expr {
return static_cast<Expr *>(SubExprs[SubExpr::Operand]);
}

SuspendReturnType getSuspendReturnType() const {
auto *SuspendExpr = getSuspendExpr();
assert(SuspendExpr);

auto SuspendType = SuspendExpr->getType();

if (SuspendType->isVoidType())
return SuspendReturnType::SuspendVoid;
if (SuspendType->isBooleanType())
return SuspendReturnType::SuspendBool;

// Void pointer is the type of handle.address(), which is returned
// from the await suspend wrapper so that the temporary coroutine handle
// value won't go to the frame by mistake
assert(SuspendType->isVoidPointerType());
return SuspendReturnType::SuspendHandle;
}

SourceLocation getKeywordLoc() const { return KeywordLoc; }

SourceLocation getBeginLoc() const LLVM_READONLY { return KeywordLoc; }
Expand Down
59 changes: 31 additions & 28 deletions clang/include/clang/ASTMatchers/ASTMatchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -5032,6 +5032,25 @@ AST_POLYMORPHIC_MATCHER_P2(hasParameter,
&& InnerMatcher.matches(*Node.parameters()[N], Finder, Builder));
}

/// Matches if the given method declaration declares a member function with an
/// explicit object parameter.
///
/// Given
/// \code
/// struct A {
/// int operator-(this A, int);
/// void fun(this A &&self);
/// static int operator()(int);
/// int operator+(int);
/// };
/// \endcode
///
/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
/// methods but not the last two.
AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) {
return Node.isExplicitObjectMemberFunction();
}

/// Matches all arguments and their respective ParmVarDecl.
///
/// Given
Expand Down Expand Up @@ -5060,10 +5079,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParam,
// argument of the method which should not be matched against a parameter, so
// we skip over it here.
BoundNodesTreeBuilder Matches;
unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
.matches(Node, Finder, &Matches)
? 1
: 0;
unsigned ArgIndex =
cxxOperatorCallExpr(
callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction()))))
.matches(Node, Finder, &Matches)
? 1
: 0;
int ParamIndex = 0;
bool Matched = false;
for (; ArgIndex < Node.getNumArgs(); ++ArgIndex) {
Expand Down Expand Up @@ -5121,11 +5142,12 @@ AST_POLYMORPHIC_MATCHER_P2(forEachArgumentWithParamType,
// argument of the method which should not be matched against a parameter, so
// we skip over it here.
BoundNodesTreeBuilder Matches;
unsigned ArgIndex = cxxOperatorCallExpr(callee(cxxMethodDecl()))
.matches(Node, Finder, &Matches)
? 1
: 0;

unsigned ArgIndex =
cxxOperatorCallExpr(
callee(cxxMethodDecl(unless(isExplicitObjectMemberFunction()))))
.matches(Node, Finder, &Matches)
? 1
: 0;
const FunctionProtoType *FProto = nullptr;

if (const auto *Call = dyn_cast<CallExpr>(&Node)) {
Expand Down Expand Up @@ -6366,25 +6388,6 @@ AST_MATCHER(CXXMethodDecl, isConst) {
return Node.isConst();
}

/// Matches if the given method declaration declares a member function with an
/// explicit object parameter.
///
/// Given
/// \code
/// struct A {
/// int operator-(this A, int);
/// void fun(this A &&self);
/// static int operator()(int);
/// int operator+(int);
/// };
/// \endcode
///
/// cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
/// methods but not the last two.
AST_MATCHER(CXXMethodDecl, isExplicitObjectMemberFunction) {
return Node.isExplicitObjectMemberFunction();
}

/// Matches if the given method declaration declares a copy assignment
/// operator.
///
Expand Down
22 changes: 18 additions & 4 deletions clang/include/clang/Basic/Attr.td
Original file line number Diff line number Diff line change
Expand Up @@ -1580,6 +1580,13 @@ def Unlikely : StmtAttr {
}
def : MutualExclusions<[Likely, Unlikely]>;

def CXXAssume : StmtAttr {
let Spellings = [CXX11<"", "assume", 202207>];
let Subjects = SubjectList<[NullStmt], ErrorDiag, "empty statements">;
let Args = [ExprArgument<"Assumption">];
let Documentation = [CXXAssumeDocs];
}

def NoMerge : DeclOrStmtAttr {
let Spellings = [Clang<"nomerge">];
let Documentation = [NoMergeDocs];
Expand Down Expand Up @@ -2047,6 +2054,13 @@ def AMDGPUNumVGPR : InheritableAttr {
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}

def AMDGPUMaxNumWorkGroups : InheritableAttr {
let Spellings = [Clang<"amdgpu_max_num_work_groups", 0>];
let Args = [ExprArgument<"MaxNumWorkGroupsX">, ExprArgument<"MaxNumWorkGroupsY", 1>, ExprArgument<"MaxNumWorkGroupsZ", 1>];
let Documentation = [AMDGPUMaxNumWorkGroupsDocs];
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
}

def AMDGPUKernelCall : DeclOrTypeAttr {
let Spellings = [Clang<"amdgpu_kernel">];
let Documentation = [Undocumented];
Expand Down Expand Up @@ -2920,7 +2934,7 @@ def Suppress : DeclOrStmtAttr {
def SysVABI : DeclOrTypeAttr {
let Spellings = [GCC<"sysv_abi">];
// let Subjects = [Function, ObjCMethod];
let Documentation = [Undocumented];
let Documentation = [SysVABIDocs];
}

def ThisCall : DeclOrTypeAttr {
Expand Down Expand Up @@ -4151,11 +4165,11 @@ def OMPDeclareVariant : InheritableAttr {
}];
}

def Assumption : InheritableAttr {
let Spellings = [Clang<"assume">];
def OMPAssume : InheritableAttr {
let Spellings = [Clang<"assume">, CXX11<"omp", "assume">];
let Subjects = SubjectList<[Function, ObjCMethod]>;
let InheritEvenIfAlreadyPresent = 1;
let Documentation = [AssumptionDocs];
let Documentation = [OMPAssumeDocs];
let Args = [StringArgument<"Assumption">];
}

Expand Down
57 changes: 56 additions & 1 deletion clang/include/clang/Basic/AttrDocs.td
Original file line number Diff line number Diff line change
Expand Up @@ -1996,6 +1996,34 @@ Here is an example:
}];
}

def CXXAssumeDocs : Documentation {
let Category = DocCatStmt;
let Heading = "assume";
let Content = [{
The ``assume`` attribute is used to indicate to the optimizer that a
certain condition is assumed to be true at a certain point in the
program. If this condition is violated at runtime, the behavior is
undefined. ``assume`` can only be applied to a null statement.

Different optimisers are likely to react differently to the presence of
this attribute; in some cases, adding ``assume`` may affect performance
negatively. It should be used with parsimony and care.

Note that `clang::assume` is a different attribute. Always write ``assume``
without a namespace if you intend to use the standard C++ attribute.

Example:

.. code-block:: c++

int f(int x, int y) {
[[assume(x == 27)]];
[[assume(x == y)]];
return y + 1; // May be optimised to `return 28`.
}
}];
}

def LikelihoodDocs : Documentation {
let Category = DocCatStmt;
let Heading = "likely and unlikely";
Expand Down Expand Up @@ -2713,6 +2741,33 @@ An error will be given if:
}];
}

def AMDGPUMaxNumWorkGroupsDocs : Documentation {
let Category = DocCatAMDGPUAttributes;
let Content = [{
This attribute specifies the max number of work groups when the kernel
is dispatched.

Clang supports the
``__attribute__((amdgpu_max_num_work_groups(<x>, <y>, <z>)))`` or
``[[clang::amdgpu_max_num_work_groups(<x>, <y>, <z>)]]`` attribute for the
AMDGPU target. This attribute may be attached to HIP or OpenCL kernel function
definitions and is an optimization hint.

The ``<x>`` parameter specifies the maximum number of work groups in the x dimension.
Similarly ``<y>`` and ``<z>`` are for the y and z dimensions respectively.
Each of the three values must be greater than 0 when provided. The ``<x>`` parameter
is required, while ``<y>`` and ``<z>`` are optional with default value of 1.

If specified, the AMDGPU target backend might be able to produce better machine
code.

An error will be given if:
- Specified values violate subtarget specifications;
- Specified values are not compatible with values provided through other
attributes.
}];
}

def DocCatCallingConvs : DocumentationCategory<"Calling Conventions"> {
let Content = [{
Clang supports several different calling conventions, depending on the target
Expand Down Expand Up @@ -4629,7 +4684,7 @@ For more information see
}];
}

def AssumptionDocs : Documentation {
def OMPAssumeDocs : Documentation {
let Category = DocCatFunction;
let Heading = "assume";
let Content = [{
Expand Down
102 changes: 102 additions & 0 deletions clang/include/clang/Basic/Builtins.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
//===--- Builtins.def - Builtin function info database ----------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// This is only documentation for the database layout. This will be removed once
// all builtin databases are converted to tablegen files

// The second value provided to the macro specifies the type of the function
// (result value, then each argument) as follows:
// v -> void
// b -> boolean
// c -> char
// s -> short
// i -> int
// h -> half (__fp16, OpenCL)
// x -> half (_Float16)
// y -> half (__bf16)
// f -> float
// d -> double
// z -> size_t
// w -> wchar_t
// F -> constant CFString
// G -> id
// H -> SEL
// M -> struct objc_super
// a -> __builtin_va_list
// A -> "reference" to __builtin_va_list
// V -> Vector, followed by the number of elements and the base type.
// q -> Scalable vector, followed by the number of elements and the base type.
// Q -> target builtin type, followed by a character to distinguish the builtin type
// Qa -> AArch64 svcount_t builtin type.
// E -> ext_vector, followed by the number of elements and the base type.
// X -> _Complex, followed by the base type.
// Y -> ptrdiff_t
// P -> FILE
// J -> jmp_buf
// SJ -> sigjmp_buf
// K -> ucontext_t
// p -> pid_t
// . -> "...". This may only occur at the end of the function list.
//
// Types may be prefixed with the following modifiers:
// L -> long (e.g. Li for 'long int', Ld for 'long double')
// LL -> long long (e.g. LLi for 'long long int', LLd for __float128)
// LLL -> __int128_t (e.g. LLLi)
// Z -> int32_t (require a native 32-bit integer type on the target)
// W -> int64_t (require a native 64-bit integer type on the target)
// N -> 'int' size if target is LP64, 'L' otherwise.
// O -> long for OpenCL targets, long long otherwise.
// S -> signed
// U -> unsigned
// I -> Required to constant fold to an integer constant expression.
//
// Types may be postfixed with the following modifiers:
// * -> pointer (optionally followed by an address space number, if no address
// space is specified than any address space will be accepted)
// & -> reference (optionally followed by an address space number)
// C -> const
// D -> volatile
// R -> restrict

// The third value provided to the macro specifies information about attributes
// of the function. These must be kept in sync with the predicates in the
// Builtin::Context class. Currently we have:
// n -> nothrow
// r -> noreturn
// U -> pure
// c -> const
// t -> signature is meaningless, use custom typechecking
// T -> type is not important to semantic analysis and codegen; recognize as
// builtin even if type doesn't match signature, and don't warn if we
// can't be sure the type is right
// F -> this is a libc/libm function with a '__builtin_' prefix added.
// f -> this is a libc/libm function without a '__builtin_' prefix, or with
// 'z', a C++ standard library function in namespace std::. This builtin
// is disableable by '-fno-builtin-foo' / '-fno-builtin-std-foo'.
// h -> this function requires a specific header or an explicit declaration.
// i -> this is a runtime library implemented function without the
// '__builtin_' prefix. It will be implemented in compiler-rt or libgcc.
// p:N: -> this is a printf-like function whose Nth argument is the format
// string.
// P:N: -> similar to the p:N: attribute, but the function is like vprintf
// in that it accepts its arguments as a va_list rather than
// through an ellipsis
// s:N: -> this is a scanf-like function whose Nth argument is the format
// string.
// S:N: -> similar to the s:N: attribute, but the function is like vscanf
// in that it accepts its arguments as a va_list rather than
// through an ellipsis
// e -> const, but only when -fno-math-errno and FP exceptions are ignored
// g -> const when FP exceptions are ignored
// j -> returns_twice (like setjmp)
// u -> arguments are not evaluated for their side-effects
// V:N: -> requires vectors of at least N bits to be legal
// C<N,M_0,...,M_k> -> callback behavior: argument N is called with argument
// M_0, ..., M_k as payload
// z -> this is a function in (possibly-versioned) namespace std
// E -> this function can be constant evaluated by Clang frontend
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/BuiltinsAArch64.def
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ BUILTIN(__builtin_arm_wfi, "v", "")
BUILTIN(__builtin_arm_sev, "v", "")
BUILTIN(__builtin_arm_sevl, "v", "")

// Like __builtin_trap but provide an 16-bit immediate reason code (which goes into `brk #N`).
BUILTIN(__builtin_arm_trap, "vUIs", "nr")

// CRC32
TARGET_BUILTIN(__builtin_arm_crc32b, "UiUiUc", "nc", "crc")
TARGET_BUILTIN(__builtin_arm_crc32cb, "UiUiUc", "nc", "crc")
Expand Down
8 changes: 4 additions & 4 deletions clang/include/clang/Basic/BuiltinsX86.def
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,8 @@ TARGET_BUILTIN(__builtin_ia32_minps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_maxps, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_minss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_maxss, "V4fV4fV4f", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "sse")
TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "sse")

TARGET_BUILTIN(__builtin_ia32_cmpeqpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpltpd, "V2dV2dV2d", "ncV:128:", "sse2")
Expand All @@ -243,6 +245,8 @@ TARGET_BUILTIN(__builtin_ia32_cmpneqsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpnltsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpnlesd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpordsd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_minpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_maxpd, "V2dV2dV2d", "ncV:128:", "sse2")
TARGET_BUILTIN(__builtin_ia32_minsd, "V2dV2dV2d", "ncV:128:", "sse2")
Expand Down Expand Up @@ -462,12 +466,8 @@ TARGET_BUILTIN(__builtin_ia32_blendvps256, "V8fV8fV8fV8f", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_shufpd256, "V4dV4dV4dIi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_shufps256, "V8fV8fV8fIi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_dpps256, "V8fV8fV8fIc", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_cmppd, "V2dV2dV2dIc", "ncV:128:", "avx")
TARGET_BUILTIN(__builtin_ia32_cmppd256, "V4dV4dV4dIc", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_cmpps, "V4fV4fV4fIc", "ncV:128:", "avx")
TARGET_BUILTIN(__builtin_ia32_cmpps256, "V8fV8fV8fIc", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_cmpsd, "V2dV2dV2dIc", "ncV:128:", "avx")
TARGET_BUILTIN(__builtin_ia32_cmpss, "V4fV4fV4fIc", "ncV:128:", "avx")
TARGET_BUILTIN(__builtin_ia32_vextractf128_pd256, "V2dV4dIi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_vextractf128_ps256, "V4fV8fIi", "ncV:256:", "avx")
TARGET_BUILTIN(__builtin_ia32_vextractf128_si256, "V4iV8iIi", "ncV:256:", "avx")
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block
///< basic block sections.
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none

CODEGENOPT(ClearASTBeforeBackend , 1, 0) ///< Free the AST before running backend code generation. Only works with -disable-free.
Expand Down
6 changes: 6 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ class CodeGenOptions : public CodeGenOptionsBase {
/// List of pass builder callbacks.
std::vector<std::function<void(llvm::PassBuilder &)>> PassBuilderCallbacks;

/// List of global variables explicitly specified by the user as toc-data.
std::vector<std::string> TocDataVarsUserSpecified;

/// List of global variables that over-ride the toc-data default.
std::vector<std::string> NoTocDataVars;

/// Path to allowlist file specifying which objects
/// (files, functions) should exclusively be instrumented
/// by sanitizer coverage pass.
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticASTKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ def note_constexpr_unsupported_flexible_array : Note<
"flexible array initialization is not yet supported">;
def note_constexpr_non_const_vectorelements : Note<
"cannot determine number of elements for sizeless vectors in a constant expression">;
def note_constexpr_assumption_failed : Note<
"assumption evaluated to false">;
def err_experimental_clang_interp_failed : Error<
"the experimental clang interpreter failed to evaluate an expression">;

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticDriverKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,9 @@ def warn_drv_unsupported_gpopt : Warning<
"ignoring '-mgpopt' option as it cannot be used with %select{|the implicit"
" usage of }0-mabicalls">,
InGroup<UnsupportedGPOpt>;
def warn_drv_unsupported_tocdata: Warning<
"ignoring '-mtocdata' as it is only supported for -mcmodel=small">,
InGroup<OptionIgnored>;
def warn_drv_unsupported_sdata : Warning<
"ignoring '-msmall-data-limit=' with -mcmodel=large for -fpic or RV64">,
InGroup<OptionIgnored>;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/DiagnosticFrontendKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def err_fe_backend_error_attr :
def warn_fe_backend_warning_attr :
Warning<"call to '%0' declared with 'warning' attribute: %1">, BackendInfo,
InGroup<BackendWarningAttributes>;
def warn_toc_unsupported_type : Warning<"-mtocdata option is ignored "
"for %0 because %1">, InGroup<BackendWarningAttributes>;

def err_fe_invalid_code_complete_file : Error<
"cannot locate code-completion file %0">, DefaultFatal;
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -617,7 +617,9 @@ def GNURedeclaredEnum : DiagGroup<"gnu-redeclared-enum">;
def RedundantMove : DiagGroup<"redundant-move">;
def Register : DiagGroup<"register", [DeprecatedRegister]>;
def ReturnTypeCLinkage : DiagGroup<"return-type-c-linkage">;
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage]>;
def ReturnMismatch : DiagGroup<"return-mismatch">;
def ReturnType : DiagGroup<"return-type", [ReturnTypeCLinkage, ReturnMismatch]>;

def BindToTemporaryCopy : DiagGroup<"bind-to-temporary-copy",
[CXX98CompatBindToTemporaryCopy]>;
def SelfAssignmentField : DiagGroup<"self-assign-field">;
Expand Down Expand Up @@ -1133,9 +1135,11 @@ def NonGCC : DiagGroup<"non-gcc",
def CXX14Attrs : DiagGroup<"c++14-attribute-extensions">;
def CXX17Attrs : DiagGroup<"c++17-attribute-extensions">;
def CXX20Attrs : DiagGroup<"c++20-attribute-extensions">;
def CXX23Attrs : DiagGroup<"c++23-attribute-extensions">;
def FutureAttrs : DiagGroup<"future-attribute-extensions", [CXX14Attrs,
CXX17Attrs,
CXX20Attrs]>;
CXX20Attrs,
CXX23Attrs]>;

def CXX23AttrsOnLambda : DiagGroup<"c++23-lambda-attributes">;

Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/DiagnosticParseKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,9 @@ def err_ms_property_expected_comma_or_rparen : Error<
def err_ms_property_initializer : Error<
"property declaration cannot have a default member initializer">;

def err_assume_attr_expects_cond_expr : Error<
"use of this expression in an %0 attribute requires parentheses">;

def warn_cxx20_compat_explicit_bool : Warning<
"this expression will be parsed as explicit(bool) in C++20">,
InGroup<CXX20Compat>, DefaultIgnore;
Expand Down
17 changes: 10 additions & 7 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -855,10 +855,10 @@ def note_strncat_wrong_size : Note<
def warn_assume_side_effects : Warning<
"the argument to %0 has side effects that will be discarded">,
InGroup<DiagGroup<"assume">>;
def warn_assume_attribute_string_unknown : Warning<
def warn_omp_assume_attribute_string_unknown : Warning<
"unknown assumption string '%0'; attribute is potentially ignored">,
InGroup<UnknownAssumption>;
def warn_assume_attribute_string_unknown_suggested : Warning<
def warn_omp_assume_attribute_string_unknown_suggested : Warning<
"unknown assumption string '%0' may be misspelled; attribute is potentially "
"ignored, did you mean '%1'?">,
InGroup<MisspelledAssumption>;
Expand Down Expand Up @@ -9115,6 +9115,8 @@ def ext_cxx17_attr : Extension<
"use of the %0 attribute is a C++17 extension">, InGroup<CXX17Attrs>;
def ext_cxx20_attr : Extension<
"use of the %0 attribute is a C++20 extension">, InGroup<CXX20Attrs>;
def ext_cxx23_attr : Extension<
"use of the %0 attribute is a C++23 extension">, InGroup<CXX23Attrs>;

def warn_unused_comparison : Warning<
"%select{equality|inequality|relational|three-way}0 comparison result unused">,
Expand Down Expand Up @@ -10169,6 +10171,9 @@ def err_fallthrough_attr_outside_switch : Error<
def err_fallthrough_attr_invalid_placement : Error<
"fallthrough annotation does not directly precede switch label">;

def err_assume_attr_args : Error<
"attribute '%0' requires a single expression argument">;

def warn_unreachable_default : Warning<
"default label in switch which covers all enumeration values">,
InGroup<CoveredSwitchDefault>, DefaultIgnore;
Expand Down Expand Up @@ -10243,14 +10248,14 @@ def warn_second_parameter_to_va_arg_never_compatible : Warning<

def warn_return_missing_expr : Warning<
"non-void %select{function|method}1 %0 should return a value">, DefaultError,
InGroup<ReturnType>;
InGroup<ReturnMismatch>;
def ext_return_missing_expr : ExtWarn<
"non-void %select{function|method}1 %0 should return a value">, DefaultError,
InGroup<ReturnType>;
InGroup<ReturnMismatch>;
def ext_return_has_expr : ExtWarn<
"%select{void function|void method|constructor|destructor}1 %0 "
"should not return a value">,
DefaultError, InGroup<ReturnType>;
DefaultError, InGroup<ReturnMismatch>;
def ext_return_has_void_expr : Extension<
"void %select{function|method|block}1 %0 should not return void expression">;
def err_return_init_list : Error<
Expand Down Expand Up @@ -11511,8 +11516,6 @@ def err_module_not_defined : Error<
def err_module_redeclaration : Error<
"translation unit contains multiple module declarations">;
def note_prev_module_declaration : Note<"previous module declaration is here">;
def err_module_declaration_missing : Error<
"missing 'export module' declaration in module interface unit">;
def err_module_declaration_missing_after_global_module_introducer : Error<
"missing 'module' declaration at end of global module fragment "
"introduced here">;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/LangOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,8 @@ LANGOPT(RegCall4, 1, 0, "Set __regcall4 as a default calling convention to respe

LANGOPT(MatrixTypes, 1, 0, "Enable or disable the builtin matrix type")

LANGOPT(CXXAssumptions, 1, 1, "Enable or disable codegen and compile-time checks for C++23's [[assume]] attribute")

ENUM_LANGOPT(StrictFlexArraysLevel, StrictFlexArraysLevelKind, 2,
StrictFlexArraysLevelKind::Default,
"Rely on strict definition of flexible arrays")
Expand Down
9 changes: 2 additions & 7 deletions clang/include/clang/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,11 +560,6 @@ class LangOptions : public LangOptionsBase {
return getCompilingModule() != CMK_None;
}

/// Are we compiling a standard c++ module interface?
bool isCompilingModuleInterface() const {
return getCompilingModule() == CMK_ModuleInterface;
}

/// Are we compiling a module implementation?
bool isCompilingModuleImplementation() const {
return !isCompilingModule() && !ModuleName.empty();
Expand Down Expand Up @@ -993,8 +988,8 @@ enum TranslationUnitKind {
/// not complete.
TU_Prefix,

/// The translation unit is a module.
TU_Module,
/// The translation unit is a clang module.
TU_ClangModule,

/// The translation unit is a is a complete translation unit that we might
/// incrementally extend later.
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/LangStandard.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ struct LangStandard {
bool isOpenCL() const { return Flags & OpenCL; }

static Kind getLangKind(StringRef Name);
static Kind getHLSLLangKind(StringRef Name);
static const LangStandard &getLangStandardForKind(Kind K);
static const LangStandard *getLangStandardForName(StringRef Name);
};
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/Driver/OffloadBundler.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#ifndef LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H
#define LLVM_CLANG_DRIVER_OFFLOADBUNDLER_H

#include "llvm/Support/Compression.h"
#include "llvm/Support/Error.h"
#include "llvm/TargetParser/Triple.h"
#include <llvm/Support/MemoryBuffer.h>
Expand All @@ -36,6 +37,8 @@ class OffloadBundlerConfig {
bool HipOpenmpCompatible = false;
bool Compress = false;
bool Verbose = false;
llvm::compression::Format CompressionFormat;
int CompressionLevel;

unsigned BundleAlignment = 1;
unsigned HostInputIndex = ~0u;
Expand Down Expand Up @@ -116,7 +119,8 @@ class CompressedOffloadBundle {

public:
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
compress(const llvm::MemoryBuffer &Input, bool Verbose = false);
compress(llvm::compression::Params P, const llvm::MemoryBuffer &Input,
bool Verbose = false);
static llvm::Expected<std::unique_ptr<llvm::MemoryBuffer>>
decompress(const llvm::MemoryBuffer &Input, bool Verbose = false);
};
Expand Down
36 changes: 36 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,10 @@ def fno_gpu_sanitize : Flag<["-"], "fno-gpu-sanitize">, Group<f_Group>;
def offload_compress : Flag<["--"], "offload-compress">,
HelpText<"Compress offload device binaries (HIP only)">;
def no_offload_compress : Flag<["--"], "no-offload-compress">;

def offload_compression_level_EQ : Joined<["--"], "offload-compression-level=">,
Flags<[HelpHidden]>,
HelpText<"Compression level for offload device binaries (HIP only)">;
}

// CUDA options
Expand Down Expand Up @@ -3605,6 +3609,27 @@ def fpass_plugin_EQ : Joined<["-"], "fpass-plugin=">,
MetaVarName<"<dsopath>">,
HelpText<"Load pass plugin from a dynamic shared object file (only with new pass manager).">,
MarshallingInfoStringVector<CodeGenOpts<"PassPlugins">>;
defm tocdata : BoolOption<"m","tocdata",
CodeGenOpts<"AllTocData">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"All suitable variables will have the TOC data transformation applied">,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
"This is the default. TOC data transformation is not applied to any"
"variables. Only variables specified explicitly in -mtocdata= will"
"have the TOC data transformation.">,
BothFlags<[TargetSpecific], [ClangOption, CLOption]>>, Group<m_Group>;
def mtocdata_EQ : CommaJoined<["-"], "mtocdata=">,
Visibility<[ClangOption, CC1Option]>,
Flags<[TargetSpecific]>, Group<m_Group>,
HelpText<"Specifies a list of variables to which the TOC data transformation"
"will be applied.">,
MarshallingInfoStringVector<CodeGenOpts<"TocDataVarsUserSpecified">>;
def mno_tocdata_EQ : CommaJoined<["-"], "mno-tocdata=">,
Visibility<[ClangOption, CC1Option]>,
Flags<[TargetSpecific]>, Group<m_Group>,
HelpText<"Specifies a list of variables to be exempt from the TOC data"
"transformation.">,
MarshallingInfoStringVector<CodeGenOpts<"NoTocDataVars">>;
defm preserve_as_comments : BoolFOption<"preserve-as-comments",
CodeGenOpts<"PreserveAsmComments">, DefaultTrue,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
Expand Down Expand Up @@ -3789,6 +3814,12 @@ def foptimization_record_passes_EQ : Joined<["-"], "foptimization-record-passes=
HelpText<"Only include passes which match a specified regular expression in the generated optimization record (by default, include all passes)">,
MetaVarName<"<regex>">;

defm assumptions : BoolFOption<"assumptions",
LangOpts<"CXXAssumptions">, DefaultTrue,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
"Disable codegen and compile-time checks for C++23's [[assume]] attribute">,
PosFlag<SetTrue>>;

def fvectorize : Flag<["-"], "fvectorize">, Group<f_Group>,
HelpText<"Enable the loop vectorization passes">;
def fno_vectorize : Flag<["-"], "fno-vectorize">, Group<f_Group>;
Expand Down Expand Up @@ -8547,6 +8578,11 @@ def dxc_entrypoint : Option<["--", "/", "-"], "E", KIND_JOINED_OR_SEPARATE>,
Group<dxc_Group>,
Visibility<[DXCOption]>,
HelpText<"Entry point name">;
def dxc_hlsl_version : Option<["/", "-"], "HV", KIND_JOINED_OR_SEPARATE>,
Group<dxc_Group>,
Visibility<[DXCOption]>,
HelpText<"HLSL Version">,
Values<"2016, 2017, 2018, 2021, 202x">;
def dxc_validator_path_EQ : Joined<["--"], "dxv-path=">, Group<dxc_Group>,
HelpText<"DXIL validator installation path">;
def dxc_disable_validation : DXCFlag<"Vd">,
Expand Down
8 changes: 6 additions & 2 deletions clang/include/clang/Frontend/FrontendActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class GenerateModuleAction : public ASTFrontendAction {
StringRef InFile) override;

TranslationUnitKind getTranslationUnitKind() override {
return TU_Module;
return TU_ClangModule;
}

bool hasASTFileSupport() const override { return false; }
Expand All @@ -138,7 +138,9 @@ class GenerateInterfaceStubsAction : public ASTFrontendAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;

TranslationUnitKind getTranslationUnitKind() override { return TU_Module; }
TranslationUnitKind getTranslationUnitKind() override {
return TU_ClangModule;
}
bool hasASTFileSupport() const override { return false; }
};

Expand All @@ -159,6 +161,8 @@ class GenerateModuleInterfaceAction : public GenerateModuleAction {
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
StringRef InFile) override;

TranslationUnitKind getTranslationUnitKind() override { return TU_Complete; }

std::unique_ptr<raw_pwrite_stream>
CreateOutputFile(CompilerInstance &CI, StringRef InFile) override;
};
Expand Down
6 changes: 3 additions & 3 deletions clang/include/clang/InstallAPI/Context.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/FileManager.h"
#include "clang/InstallAPI/HeaderFile.h"
#include "clang/InstallAPI/MachO.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/TextAPI/InterfaceFile.h"

namespace clang {
namespace installapi {
Expand All @@ -25,7 +25,7 @@ class FrontendRecordsSlice;
struct InstallAPIContext {

/// Library attributes that are typically passed as linker inputs.
llvm::MachO::RecordsSlice::BinaryAttrs BA;
BinaryAttrs BA;

/// All headers that represent a library.
HeaderSeq InputHeaders;
Expand All @@ -49,7 +49,7 @@ struct InstallAPIContext {
llvm::StringRef OutputLoc{};

/// What encoding to write output as.
llvm::MachO::FileType FT = llvm::MachO::FileType::TBD_V5;
FileType FT = FileType::TBD_V5;

/// Populate entries of headers that should be included for TextAPI
/// generation.
Expand Down
94 changes: 0 additions & 94 deletions clang/include/clang/InstallAPI/Frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,100 +25,6 @@
namespace clang {
namespace installapi {

using SymbolFlags = llvm::MachO::SymbolFlags;
using RecordLinkage = llvm::MachO::RecordLinkage;
using GlobalRecord = llvm::MachO::GlobalRecord;
using ObjCContainerRecord = llvm::MachO::ObjCContainerRecord;
using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord;
using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord;
using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord;

// Represents a collection of frontend records for a library that are tied to a
// darwin target triple.
class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
public:
FrontendRecordsSlice(const llvm::Triple &T)
: llvm::MachO::RecordsSlice({T}) {}

/// Add non-ObjC global record with attributes from AST.
///
/// \param Name The name of symbol.
/// \param Linkage The linkage of symbol.
/// \param GV The kind of global.
/// \param Avail The availability information tied to the active target
/// triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \param Flags The flags that describe attributes of the symbol.
/// \param Inlined Whether declaration is inlined, only applicable to
/// functions.
/// \return The non-owning pointer to added record in slice.
GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
GlobalRecord::Kind GV,
const clang::AvailabilityInfo Avail, const Decl *D,
const HeaderType Access,
SymbolFlags Flags = SymbolFlags::None,
bool Inlined = false);

/// Add ObjC Class record with attributes from AST.
///
/// \param Name The name of class, not symbol.
/// \param Linkage The linkage of symbol.
/// \param Avail The availability information tied to the active target
/// triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \param IsEHType Whether declaration has an exception attribute.
/// \return The non-owning pointer to added record in slice.
ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
const clang::AvailabilityInfo Avail,
const Decl *D, HeaderType Access,
bool IsEHType);

/// Add ObjC Category record with attributes from AST.
///
/// \param ClassToExtend The name of class that is extended by category, not
/// symbol.
/// \param CategoryName The name of category, not symbol.
/// \param Avail The availability information tied
/// to the active target triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \return The non-owning pointer to added record in slice.
ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
StringRef CategoryName,
const clang::AvailabilityInfo Avail,
const Decl *D, HeaderType Access);

/// Add ObjC IVar record with attributes from AST.
///
/// \param Container The owning pointer for instance variable.
/// \param Name The name of ivar, not symbol.
/// \param Linkage The linkage of symbol.
/// \param Avail The availability information tied to the active target
/// triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \param AC The access control tied to the ivar declaration.
/// \return The non-owning pointer to added record in slice.
ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container,
StringRef IvarName, RecordLinkage Linkage,
const clang::AvailabilityInfo Avail,
const Decl *D, HeaderType Access,
const clang::ObjCIvarDecl::AccessControl AC);

private:
/// Frontend information captured about records.
struct FrontendAttrs {
const AvailabilityInfo Avail;
const Decl *D;
const HeaderType Access;
};

/// Mapping of records stored in slice to their frontend attributes.
llvm::DenseMap<llvm::MachO::Record *, FrontendAttrs> FrontendRecords;
};

/// Create a buffer that contains all headers to scan
/// for global symbols with.
std::unique_ptr<llvm::MemoryBuffer> createInputBuffer(InstallAPIContext &Ctx);
Expand Down
109 changes: 109 additions & 0 deletions clang/include/clang/InstallAPI/FrontendRecords.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
//===- InstallAPI/FrontendRecords.h ------------------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_INSTALLAPI_FRONTENDRECORDS_H
#define LLVM_CLANG_INSTALLAPI_FRONTENDRECORDS_H

#include "clang/AST/Availability.h"
#include "clang/AST/DeclObjC.h"
#include "clang/InstallAPI/HeaderFile.h"
#include "clang/InstallAPI/MachO.h"

namespace clang {
namespace installapi {

/// Frontend information captured about records.
struct FrontendAttrs {
const AvailabilityInfo Avail;
const Decl *D;
const HeaderType Access;
};

// Represents a collection of frontend records for a library that are tied to a
// darwin target triple.
class FrontendRecordsSlice : public llvm::MachO::RecordsSlice {
public:
FrontendRecordsSlice(const llvm::Triple &T)
: llvm::MachO::RecordsSlice({T}) {}

/// Add non-ObjC global record with attributes from AST.
///
/// \param Name The name of symbol.
/// \param Linkage The linkage of symbol.
/// \param GV The kind of global.
/// \param Avail The availability information tied to the active target
/// triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \param Flags The flags that describe attributes of the symbol.
/// \param Inlined Whether declaration is inlined, only applicable to
/// functions.
/// \return The non-owning pointer to added record in slice.
GlobalRecord *addGlobal(StringRef Name, RecordLinkage Linkage,
GlobalRecord::Kind GV,
const clang::AvailabilityInfo Avail, const Decl *D,
const HeaderType Access,
SymbolFlags Flags = SymbolFlags::None,
bool Inlined = false);

/// Add ObjC Class record with attributes from AST.
///
/// \param Name The name of class, not symbol.
/// \param Linkage The linkage of symbol.
/// \param Avail The availability information tied to the active target
/// triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \param IsEHType Whether declaration has an exception attribute.
/// \return The non-owning pointer to added record in slice.
ObjCInterfaceRecord *addObjCInterface(StringRef Name, RecordLinkage Linkage,
const clang::AvailabilityInfo Avail,
const Decl *D, HeaderType Access,
bool IsEHType);

/// Add ObjC Category record with attributes from AST.
///
/// \param ClassToExtend The name of class that is extended by category, not
/// symbol.
/// \param CategoryName The name of category, not symbol.
/// \param Avail The availability information tied
/// to the active target triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \return The non-owning pointer to added record in slice.
ObjCCategoryRecord *addObjCCategory(StringRef ClassToExtend,
StringRef CategoryName,
const clang::AvailabilityInfo Avail,
const Decl *D, HeaderType Access);

/// Add ObjC IVar record with attributes from AST.
///
/// \param Container The owning pointer for instance variable.
/// \param Name The name of ivar, not symbol.
/// \param Linkage The linkage of symbol.
/// \param Avail The availability information tied to the active target
/// triple.
/// \param D The pointer to the declaration from traversing AST.
/// \param Access The intended access level of symbol.
/// \param AC The access control tied to the ivar declaration.
/// \return The non-owning pointer to added record in slice.
ObjCIVarRecord *addObjCIVar(ObjCContainerRecord *Container,
StringRef IvarName, RecordLinkage Linkage,
const clang::AvailabilityInfo Avail,
const Decl *D, HeaderType Access,
const clang::ObjCIvarDecl::AccessControl AC);

private:
/// Mapping of records stored in slice to their frontend attributes.
llvm::DenseMap<Record *, FrontendAttrs> FrontendRecords;
};

} // namespace installapi
} // namespace clang

#endif // LLVM_CLANG_INSTALLAPI_FRONTENDRECORDS_H
40 changes: 40 additions & 0 deletions clang/include/clang/InstallAPI/MachO.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//===- InstallAPI/MachO.h ---------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Imports and forward declarations for llvm::MachO types.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_INSTALLAPI_MACHO_H
#define LLVM_CLANG_INSTALLAPI_MACHO_H

#include "llvm/TextAPI/Architecture.h"
#include "llvm/TextAPI/InterfaceFile.h"
#include "llvm/TextAPI/PackedVersion.h"
#include "llvm/TextAPI/Platform.h"
#include "llvm/TextAPI/RecordVisitor.h"
#include "llvm/TextAPI/Target.h"
#include "llvm/TextAPI/TextAPIWriter.h"
#include "llvm/TextAPI/Utils.h"

using SymbolFlags = llvm::MachO::SymbolFlags;
using RecordLinkage = llvm::MachO::RecordLinkage;
using Record = llvm::MachO::Record;
using GlobalRecord = llvm::MachO::GlobalRecord;
using ObjCContainerRecord = llvm::MachO::ObjCContainerRecord;
using ObjCInterfaceRecord = llvm::MachO::ObjCInterfaceRecord;
using ObjCCategoryRecord = llvm::MachO::ObjCCategoryRecord;
using ObjCIVarRecord = llvm::MachO::ObjCIVarRecord;
using Records = llvm::MachO::Records;
using BinaryAttrs = llvm::MachO::RecordsSlice::BinaryAttrs;
using SymbolSet = llvm::MachO::SymbolSet;
using FileType = llvm::MachO::FileType;
using PackedVersion = llvm::MachO::PackedVersion;
using Target = llvm::MachO::Target;

#endif // LLVM_CLANG_INSTALLAPI_MACHO_H
14 changes: 14 additions & 0 deletions clang/include/clang/InstallAPI/Visitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "llvm/ADT/Twine.h"

namespace clang {
struct AvailabilityInfo;
namespace installapi {

/// ASTVisitor for collecting declarations that represent global symbols.
Expand All @@ -33,6 +34,7 @@ class InstallAPIVisitor final : public ASTConsumer,
MC(ItaniumMangleContext::create(ASTCtx, ASTCtx.getDiagnostics())),
Layout(ASTCtx.getTargetInfo().getDataLayoutString()) {}
void HandleTranslationUnit(ASTContext &ASTCtx) override;
bool shouldVisitTemplateInstantiations() const { return true; }

/// Collect global variables.
bool VisitVarDecl(const VarDecl *D);
Expand All @@ -51,16 +53,28 @@ class InstallAPIVisitor final : public ASTConsumer,
/// is therefore itself not collected.
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *D);

/// Collect global c++ declarations.
bool VisitCXXRecordDecl(const CXXRecordDecl *D);

private:
std::string getMangledName(const NamedDecl *D) const;
std::string getBackendMangledName(llvm::Twine Name) const;
std::string getMangledCXXVTableName(const CXXRecordDecl *D) const;
std::string getMangledCXXThunk(const GlobalDecl &D,
const ThunkInfo &Thunk) const;
std::string getMangledCXXRTTI(const CXXRecordDecl *D) const;
std::string getMangledCXXRTTIName(const CXXRecordDecl *D) const;
std::string getMangledCtorDtor(const CXXMethodDecl *D, int Type) const;

std::optional<HeaderType> getAccessForDecl(const NamedDecl *D) const;
void recordObjCInstanceVariables(
const ASTContext &ASTCtx, llvm::MachO::ObjCContainerRecord *Record,
StringRef SuperClass,
const llvm::iterator_range<
DeclContext::specific_decl_iterator<ObjCIvarDecl>>
Ivars);
void emitVTableSymbols(const CXXRecordDecl *D, const AvailabilityInfo &Avail,
const HeaderType Access, bool EmittedVTable = false);

InstallAPIContext &Ctx;
SourceManager &SrcMgr;
Expand Down
45 changes: 39 additions & 6 deletions clang/include/clang/Interpreter/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "clang/AST/GlobalDecl.h"
#include "clang/Interpreter/PartialTranslationUnit.h"
#include "clang/Interpreter/Value.h"
#include "clang/Sema/Ownership.h"

#include "llvm/ADT/DenseMap.h"
#include "llvm/ExecutionEngine/JITSymbol.h"
Expand Down Expand Up @@ -75,27 +76,60 @@ class IncrementalCompilerBuilder {
llvm::StringRef CudaSDKPath;
};

/// Generate glue code between the Interpreter's built-in runtime and user code.
class RuntimeInterfaceBuilder {
public:
virtual ~RuntimeInterfaceBuilder() = default;

using TransformExprFunction = ExprResult(RuntimeInterfaceBuilder *Builder,
Expr *, ArrayRef<Expr *>);
virtual TransformExprFunction *getPrintValueTransformer() = 0;
};

/// Provides top-level interfaces for incremental compilation and execution.
class Interpreter {
std::unique_ptr<llvm::orc::ThreadSafeContext> TSCtx;
std::unique_ptr<IncrementalParser> IncrParser;
std::unique_ptr<IncrementalExecutor> IncrExecutor;
std::unique_ptr<RuntimeInterfaceBuilder> RuntimeIB;

// An optional parser for CUDA offloading
std::unique_ptr<IncrementalParser> DeviceParser;

Interpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &Err);

llvm::Error CreateExecutor();
unsigned InitPTUSize = 0;

// This member holds the last result of the value printing. It's a class
// member because we might want to access it after more inputs. If no value
// printing happens, it's in an invalid state.
Value LastValue;

// Add a call to an Expr to report its result. We query the function from
// RuntimeInterfaceBuilder once and store it as a function pointer to avoid
// frequent virtual function calls.
RuntimeInterfaceBuilder::TransformExprFunction *AddPrintValueCall = nullptr;

protected:
// Derived classes can make use an extended interface of the Interpreter.
// That's useful for testing and out-of-tree clients.
Interpreter(std::unique_ptr<CompilerInstance> CI, llvm::Error &Err);

// Create the internal IncrementalExecutor, or re-create it after calling
// ResetExecutor().
llvm::Error CreateExecutor();

// Delete the internal IncrementalExecutor. This causes a hard shutdown of the
// JIT engine. In particular, it doesn't run cleanup or destructors.
void ResetExecutor();

// Lazily construct the RuntimeInterfaceBuilder. The provided instance will be
// used for the entire lifetime of the interpreter. The default implementation
// targets the in-process __clang_Interpreter runtime. Override this to use a
// custom runtime.
virtual std::unique_ptr<RuntimeInterfaceBuilder> FindRuntimeInterface();

public:
~Interpreter();
virtual ~Interpreter();

static llvm::Expected<std::unique_ptr<Interpreter>>
create(std::unique_ptr<CompilerInstance> CI);
static llvm::Expected<std::unique_ptr<Interpreter>>
Expand Down Expand Up @@ -142,8 +176,7 @@ class Interpreter {

private:
size_t getEffectivePTUSize() const;

bool FindRuntimeInterface();
void markUserCodeStart();

llvm::DenseMap<CXXRecordDecl *, llvm::orc::ExecutorAddr> Dtors;

Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,7 @@ class Parser : public CodeCompletionHandler {
ExprResult ParseConstraintLogicalOrExpression(bool IsTrailingRequiresClause);
// Expr that doesn't include commas.
ExprResult ParseAssignmentExpression(TypeCastState isTypeCast = NotTypeCast);
ExprResult ParseConditionalExpression();

ExprResult ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
unsigned &NumLineToksConsumed,
Expand Down Expand Up @@ -2955,6 +2956,12 @@ class Parser : public CodeCompletionHandler {
SourceLocation ScopeLoc,
CachedTokens &OpenMPTokens);

/// Parse a C++23 assume() attribute. Returns true on error.
bool ParseCXXAssumeAttributeArg(ParsedAttributes &Attrs,
IdentifierInfo *AttrName,
SourceLocation AttrNameLoc,
SourceLocation *EndLoc);

IdentifierInfo *TryParseCXX11AttributeIdentifier(
SourceLocation &Loc,
Sema::AttributeCompletion Completion = Sema::AttributeCompletion::None,
Expand Down
45 changes: 27 additions & 18 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -2152,14 +2152,15 @@ class Sema final {

bool IsLayoutCompatible(QualType T1, QualType T2) const;

bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
const FunctionProtoType *Proto);

private:
void CheckArrayAccess(const Expr *BaseExpr, const Expr *IndexExpr,
const ArraySubscriptExpr *ASE = nullptr,
bool AllowOnePastEnd = true, bool IndexNegated = false);
void CheckArrayAccess(const Expr *E);

bool CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall,
const FunctionProtoType *Proto);
bool CheckObjCMethodCall(ObjCMethodDecl *Method, SourceLocation loc,
ArrayRef<const Expr *> Args);
bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
Expand Down Expand Up @@ -3911,6 +3912,16 @@ class Sema final {
void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *Min, Expr *Max);

/// Create an AMDGPUMaxNumWorkGroupsAttr attribute.
AMDGPUMaxNumWorkGroupsAttr *
CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr,
Expr *YExpr, Expr *ZExpr);

/// addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups
/// attribute to a particular declaration.
void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI,
Expr *XExpr, Expr *YExpr, Expr *ZExpr);

DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI);
DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI);
MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D,
Expand Down Expand Up @@ -6752,18 +6763,10 @@ class Sema final {
SourceLocation RParenLoc);

//// ActOnCXXThis - Parse 'this' pointer.
///
/// \param ThisRefersToClosureObject Whether to skip the 'this' check for a
/// lambda because 'this' refers to the closure object.
ExprResult ActOnCXXThis(SourceLocation loc,
bool ThisRefersToClosureObject = false);
ExprResult ActOnCXXThis(SourceLocation loc);

/// Build a CXXThisExpr and mark it referenced in the current context.
///
/// \param ThisRefersToClosureObject Whether to skip the 'this' check for a
/// lambda because 'this' refers to the closure object.
Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit,
bool ThisRefersToClosureObject = false);
Expr *BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit);
void MarkThisReferenced(CXXThisExpr *This);

/// Try to retrieve the type of the 'this' pointer.
Expand Down Expand Up @@ -8062,13 +8065,13 @@ class Sema final {

/// The parser has processed a module import translated from a
/// #include or similar preprocessing directive.
void ActOnModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
void ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod);
void BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod);

/// The parsed has entered a submodule.
void ActOnModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
void ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod);
/// The parser has left a submodule.
void ActOnModuleEnd(SourceLocation DirectiveLoc, Module *Mod);
void ActOnAnnotModuleEnd(SourceLocation DirectiveLoc, Module *Mod);

/// Create an implicit import of the given module at the given
/// source location, for error recovery, if possible.
Expand Down Expand Up @@ -9011,6 +9014,12 @@ class Sema final {
void ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributes &InAttrs,
SmallVectorImpl<const Attr *> &OutAttrs);

ExprResult ActOnCXXAssumeAttr(Stmt *St, const ParsedAttr &A,
SourceRange Range);
ExprResult BuildCXXAssumeExpr(Expr *Assumption,
const IdentifierInfo *AttrName,
SourceRange Range);

///@}

//
Expand Down Expand Up @@ -9206,7 +9215,7 @@ class Sema final {

bool AttachTypeConstraint(NestedNameSpecifierLoc NS,
DeclarationNameInfo NameInfo,
ConceptDecl *NamedConcept,
ConceptDecl *NamedConcept, NamedDecl *FoundDecl,
const TemplateArgumentListInfo *TemplateArgs,
TemplateTypeParmDecl *ConstrainedParameter,
SourceLocation EllipsisLoc);
Expand Down Expand Up @@ -14716,10 +14725,10 @@ class Sema final {
SmallVector<OMPDeclareVariantScope, 4> OMPDeclareVariantScopes;

/// The current `omp begin/end assumes` scopes.
SmallVector<AssumptionAttr *, 4> OMPAssumeScoped;
SmallVector<OMPAssumeAttr *, 4> OMPAssumeScoped;

/// All `omp assumes` we encountered so far.
SmallVector<AssumptionAttr *, 4> OMPAssumeGlobal;
SmallVector<OMPAssumeAttr *, 4> OMPAssumeGlobal;

/// OMPD_loop is mapped to OMPD_for, OMPD_distribute or OMPD_simd depending
/// on the parameter of the bind clause. In the methods for the
Expand Down
7 changes: 0 additions & 7 deletions clang/include/clang/Serialization/ASTReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -2456,13 +2456,6 @@ class BitsUnpacker {
uint32_t Value;
uint32_t CurrentBitsIndex = ~0;
};

inline bool shouldSkipCheckingODR(const Decl *D) {
return D->getOwningModule() &&
D->getASTContext().getLangOpts().SkipODRCheckInGMF &&
D->getOwningModule()->isExplicitGlobalModule();
}

} // namespace clang

#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H
8 changes: 6 additions & 2 deletions clang/include/clang/Serialization/ASTWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,8 @@ class PCHGenerator : public SemaConsumer {
return SemaPtr->getDiagnostics();
}

virtual Module *getEmittingModule(ASTContext &Ctx);

public:
PCHGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile, StringRef isysroot,
Expand All @@ -887,10 +889,12 @@ class PCHGenerator : public SemaConsumer {
};

class ReducedBMIGenerator : public PCHGenerator {
protected:
virtual Module *getEmittingModule(ASTContext &Ctx) override;

public:
ReducedBMIGenerator(const Preprocessor &PP, InMemoryModuleCache &ModuleCache,
StringRef OutputFile, std::shared_ptr<PCHBuffer> Buffer,
bool IncludeTimestamps);
StringRef OutputFile);

void HandleTranslationUnit(ASTContext &Ctx) override;
};
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/StaticAnalyzer/Core/CheckerManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class ExplodedNodeSet;
class ExprEngine;
struct EvalCallOptions;
class MemRegion;
struct NodeBuilderContext;
class NodeBuilderContext;
class ObjCMethodCall;
class RegionAndSymbolInvalidationTraits;
class SVal;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class CoreEngine {
friend class ExprEngine;
friend class IndirectGotoNodeBuilder;
friend class NodeBuilder;
friend struct NodeBuilderContext;
friend class NodeBuilderContext;
friend class SwitchNodeBuilder;

public:
Expand Down Expand Up @@ -193,12 +193,12 @@ class CoreEngine {
DataTag::Factory &getDataTags() { return DataTags; }
};

// TODO: Turn into a class.
struct NodeBuilderContext {
class NodeBuilderContext {
const CoreEngine &Eng;
const CFGBlock *Block;
const LocationContext *LC;

public:
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B,
const LocationContext *L)
: Eng(E), Block(B), LC(L) {
Expand All @@ -208,9 +208,15 @@ struct NodeBuilderContext {
NodeBuilderContext(const CoreEngine &E, const CFGBlock *B, ExplodedNode *N)
: NodeBuilderContext(E, B, N->getLocationContext()) {}

/// Return the CoreEngine associated with this builder.
const CoreEngine &getEngine() const { return Eng; }

/// Return the CFGBlock associated with this builder.
const CFGBlock *getBlock() const { return Block; }

/// Return the location context associated with this builder.
const LocationContext *getLocationContext() const { return LC; }

/// Returns the number of times the current basic block has been
/// visited on the exploded graph path.
unsigned blockCount() const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ExplodedNodeSet;
class ExplodedNode;
class IndirectGotoNodeBuilder;
class MemRegion;
struct NodeBuilderContext;
class NodeBuilderContext;
class NodeBuilderWithSinks;
class ProgramState;
class ProgramStateManager;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/APINotes/APINotesManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ APINotesManager::getCurrentModuleAPINotes(Module *M, bool LookInModule,
llvm::SmallVector<FileEntryRef, 2> APINotes;

// First, look relative to the module itself.
if (LookInModule) {
if (LookInModule && M->Directory) {
// Local function to try loading an API notes file in the given directory.
auto tryAPINotes = [&](DirectoryEntryRef Dir, bool WantPublic) {
if (auto File = findAPINotesFile(Dir, ModuleName, WantPublic)) {
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2577,11 +2577,14 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, Notes,
IsConstantInitialization);

// In C++/C23, this isn't a constant initializer if we produced notes. In that
// case, we can't keep the result, because it may only be correct under the
// assumption that the initializer is a constant context.
// In C++, or in C23 if we're initialising a 'constexpr' variable, this isn't
// a constant initializer if we produced notes. In that case, we can't keep
// the result, because it may only be correct under the assumption that the
// initializer is a constant context.
if (IsConstantInitialization &&
(Ctx.getLangOpts().CPlusPlus || Ctx.getLangOpts().C23) && !Notes.empty())
(Ctx.getLangOpts().CPlusPlus ||
(isConstexpr() && Ctx.getLangOpts().C23)) &&
!Notes.empty())
Result = false;

// Ensure the computed APValue is cleaned up later if evaluation succeeded,
Expand Down Expand Up @@ -4496,7 +4499,7 @@ unsigned FunctionDecl::getODRHash() {
}

class ODRHash Hash;
Hash.AddFunctionDecl(this);
Hash.AddFunctionDecl(this, /*SkipBody=*/shouldSkipCheckingODR());
setHasODRHash(true);
ODRHash = Hash.CalculateHash();
return ODRHash;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,11 @@ bool Decl::isInAnotherModuleUnit() const {
return M != getASTContext().getCurrentNamedModule();
}

bool Decl::shouldSkipCheckingODR() const {
return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() &&
getOwningModule()->isExplicitGlobalModule();
}

static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
static Decl::Kind getKind(const DeclContext *DC) { return DC->getDeclKind(); }

Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/DeclPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,11 @@ void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
return;
}
bool eolnOut = false;
if (OID->hasAttrs()) {
prettyPrintAttributes(OID);
Out << "\n";
}

Out << "@interface " << I;

if (auto TypeParams = OID->getTypeParamListAsWritten()) {
Expand Down
13 changes: 8 additions & 5 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,11 +264,14 @@ namespace {
}

QualType Expr::getEnumCoercedType(const ASTContext &Ctx) const {
if (isa<EnumType>(this->getType()))
return this->getType();
else if (const auto *ECD = this->getEnumConstantDecl())
return Ctx.getTypeDeclType(cast<EnumDecl>(ECD->getDeclContext()));
return this->getType();
if (isa<EnumType>(getType()))
return getType();
if (const auto *ECD = getEnumConstantDecl()) {
const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
if (ED->isCompleteDefinition())
return Ctx.getTypeDeclType(ED);
}
return getType();
}

SourceLocation Expr::getExprLoc() const {
Expand Down
152 changes: 97 additions & 55 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5582,6 +5582,29 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info,
MSConstexprContextRAII ConstexprContext(
*Info.CurrentCall, hasSpecificAttr<MSConstexprAttr>(AS->getAttrs()) &&
isa<ReturnStmt>(SS));

auto LO = Info.getCtx().getLangOpts();
if (LO.CXXAssumptions && !LO.MSVCCompat) {
for (auto *Attr : AS->getAttrs()) {
auto *AA = dyn_cast<CXXAssumeAttr>(Attr);
if (!AA)
continue;

auto *Assumption = AA->getAssumption();
if (Assumption->isValueDependent())
return ESR_Failed;

bool Value;
if (!EvaluateAsBooleanCondition(Assumption, Value, Info))
return ESR_Failed;
if (!Value) {
Info.CCEDiag(Assumption->getExprLoc(),
diag::note_constexpr_assumption_failed);
return ESR_Failed;
}
}
}

return EvaluateStmt(Result, Info, SS, Case);
}

Expand Down Expand Up @@ -8494,6 +8517,53 @@ class LValueExprEvaluator
};
} // end anonymous namespace

/// Get an lvalue to a field of a lambda's closure type.
static bool HandleLambdaCapture(EvalInfo &Info, const Expr *E, LValue &Result,
const CXXMethodDecl *MD, const FieldDecl *FD,
bool LValueToRValueConversion) {
// Static lambda function call operators can't have captures. We already
// diagnosed this, so bail out here.
if (MD->isStatic()) {
assert(Info.CurrentCall->This == nullptr &&
"This should not be set for a static call operator");
return false;
}

// Start with 'Result' referring to the complete closure object...
if (MD->isExplicitObjectMemberFunction()) {
// Self may be passed by reference or by value.
const ParmVarDecl *Self = MD->getParamDecl(0);
if (Self->getType()->isReferenceType()) {
APValue *RefValue = Info.getParamSlot(Info.CurrentCall->Arguments, Self);
Result.setFrom(Info.Ctx, *RefValue);
} else {
const ParmVarDecl *VD = Info.CurrentCall->Arguments.getOrigParam(Self);
CallStackFrame *Frame =
Info.getCallFrameAndDepth(Info.CurrentCall->Arguments.CallIndex)
.first;
unsigned Version = Info.CurrentCall->Arguments.Version;
Result.set({VD, Frame->Index, Version});
}
} else
Result = *Info.CurrentCall->This;

// ... then update it to refer to the field of the closure object
// that represents the capture.
if (!HandleLValueMember(Info, E, Result, FD))
return false;

// And if the field is of reference type (or if we captured '*this' by
// reference), update 'Result' to refer to what
// the field refers to.
if (LValueToRValueConversion) {
APValue RVal;
if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result, RVal))
return false;
Result.setFrom(Info.Ctx, RVal);
}
return true;
}

/// Evaluate an expression as an lvalue. This can be legitimately called on
/// expressions which are not glvalues, in three cases:
/// * function designators in C, and
Expand Down Expand Up @@ -8538,37 +8608,8 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) {

if (auto *FD = Info.CurrentCall->LambdaCaptureFields.lookup(VD)) {
const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);

// Static lambda function call operators can't have captures. We already
// diagnosed this, so bail out here.
if (MD->isStatic()) {
assert(Info.CurrentCall->This == nullptr &&
"This should not be set for a static call operator");
return false;
}

// Start with 'Result' referring to the complete closure object...
if (MD->isExplicitObjectMemberFunction()) {
APValue *RefValue =
Info.getParamSlot(Info.CurrentCall->Arguments, MD->getParamDecl(0));
Result.setFrom(Info.Ctx, *RefValue);
} else
Result = *Info.CurrentCall->This;

// ... then update it to refer to the field of the closure object
// that represents the capture.
if (!HandleLValueMember(Info, E, Result, FD))
return false;
// And if the field is of reference type, update 'Result' to refer to what
// the field refers to.
if (FD->getType()->isReferenceType()) {
APValue RVal;
if (!handleLValueToRValueConversion(Info, E, FD->getType(), Result,
RVal))
return false;
Result.setFrom(Info.Ctx, RVal);
}
return true;
return HandleLambdaCapture(Info, E, Result, MD, FD,
FD->getType()->isReferenceType());
}
}

Expand Down Expand Up @@ -9046,45 +9087,46 @@ class PointerExprEvaluator
return Error(E);
}
bool VisitCXXThisExpr(const CXXThisExpr *E) {
// Can't look at 'this' when checking a potential constant expression.
if (Info.checkingPotentialConstantExpression())
return false;
if (!Info.CurrentCall->This) {
auto DiagnoseInvalidUseOfThis = [&] {
if (Info.getLangOpts().CPlusPlus11)
Info.FFDiag(E, diag::note_constexpr_this) << E->isImplicit();
else
Info.FFDiag(E);
};

// Can't look at 'this' when checking a potential constant expression.
if (Info.checkingPotentialConstantExpression())
return false;

bool IsExplicitLambda =
isLambdaCallWithExplicitObjectParameter(Info.CurrentCall->Callee);
if (!IsExplicitLambda) {
if (!Info.CurrentCall->This) {
DiagnoseInvalidUseOfThis();
return false;
}

Result = *Info.CurrentCall->This;
}
Result = *Info.CurrentCall->This;

if (isLambdaCallOperator(Info.CurrentCall->Callee)) {
// Ensure we actually have captured 'this'. If something was wrong with
// 'this' capture, the error would have been previously reported.
// Otherwise we can be inside of a default initialization of an object
// declared by lambda's body, so no need to return false.
if (!Info.CurrentCall->LambdaThisCaptureField)
return true;

// If we have captured 'this', the 'this' expression refers
// to the enclosing '*this' object (either by value or reference) which is
// either copied into the closure object's field that represents the
// '*this' or refers to '*this'.
// Update 'Result' to refer to the data member/field of the closure object
// that represents the '*this' capture.
if (!HandleLValueMember(Info, E, Result,
Info.CurrentCall->LambdaThisCaptureField))
return false;
// If we captured '*this' by reference, replace the field with its referent.
if (Info.CurrentCall->LambdaThisCaptureField->getType()
->isPointerType()) {
APValue RVal;
if (!handleLValueToRValueConversion(Info, E, E->getType(), Result,
RVal))
if (!Info.CurrentCall->LambdaThisCaptureField) {
if (IsExplicitLambda && !Info.CurrentCall->This) {
DiagnoseInvalidUseOfThis();
return false;
}

Result.setFrom(Info.Ctx, RVal);
return true;
}

const auto *MD = cast<CXXMethodDecl>(Info.CurrentCall->Callee);
return HandleLambdaCapture(
Info, E, Result, MD, Info.CurrentCall->LambdaThisCaptureField,
Info.CurrentCall->LambdaThisCaptureField->getType()->isPointerType());
}
return true;
}
Expand Down
Loading