Skip to content

Commit eff9613

Browse files
authored
merge main into amd-staging (llvm#3507)
2 parents 74b0f80 + 5216908 commit eff9613

File tree

866 files changed

+13508
-12341
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

866 files changed

+13508
-12341
lines changed

.ci/generate_test_report_lib.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,65 @@
1212
"https://github.com/llvm/llvm-project/issues and add the "
1313
"`infrastructure` label."
1414
)
15+
# The maximum number of lines to pull from a ninja failure.
16+
NINJA_LOG_SIZE_THRESHOLD = 500
17+
18+
19+
def _parse_ninja_log(ninja_log: list[str]) -> list[tuple[str, str]]:
20+
"""Parses an individual ninja log."""
21+
failures = []
22+
index = 0
23+
while index < len(ninja_log):
24+
while index < len(ninja_log) and not ninja_log[index].startswith("FAILED:"):
25+
index += 1
26+
if index == len(ninja_log):
27+
# We hit the end of the log without finding a build failure, go to
28+
# the next log.
29+
return failures
30+
# We are trying to parse cases like the following:
31+
#
32+
# [4/5] test/4.stamp
33+
# FAILED: touch test/4.stamp
34+
# touch test/4.stamp
35+
#
36+
# index will point to the line that starts with Failed:. The progress
37+
# indicator is the line before this ([4/5] test/4.stamp) and contains a pretty
38+
# printed version of the target being built (test/4.stamp). We use this line
39+
# and remove the progress information to get a succinct name for the target.
40+
failing_action = ninja_log[index - 1].split("] ")[1]
41+
failure_log = []
42+
while (
43+
index < len(ninja_log)
44+
and not ninja_log[index].startswith("[")
45+
and not ninja_log[index].startswith("ninja: build stopped:")
46+
and len(failure_log) < NINJA_LOG_SIZE_THRESHOLD
47+
):
48+
failure_log.append(ninja_log[index])
49+
index += 1
50+
failures.append((failing_action, "\n".join(failure_log)))
51+
return failures
52+
53+
54+
def find_failure_in_ninja_logs(ninja_logs: list[list[str]]) -> list[tuple[str, str]]:
55+
"""Extracts failure messages from ninja output.
56+
57+
This function takes stdout/stderr from ninja in the form of a list of files
58+
represented as a list of lines. This function then returns tuples containing
59+
the name of the target and the error message.
60+
61+
Args:
62+
ninja_logs: A list of files in the form of a list of lines representing the log
63+
files captured from ninja.
64+
65+
Returns:
66+
A list of tuples. The first string is the name of the target that failed. The
67+
second string is the error message.
68+
"""
69+
failures = []
70+
for ninja_log in ninja_logs:
71+
log_failures = _parse_ninja_log(ninja_log)
72+
failures.extend(log_failures)
73+
return failures
1574

1675

1776
# Set size_limit to limit the byte size of the report. The default is 1MB as this

.ci/generate_test_report_lib_test.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,111 @@ def junit_from_xml(xml):
1919

2020

2121
class TestReports(unittest.TestCase):
22+
def test_find_failure_ninja_logs(self):
23+
failures = generate_test_report_lib.find_failure_in_ninja_logs(
24+
[
25+
[
26+
"[1/5] test/1.stamp",
27+
"[2/5] test/2.stamp",
28+
"[3/5] test/3.stamp",
29+
"[4/5] test/4.stamp",
30+
"FAILED: touch test/4.stamp",
31+
"Wow! This system is really broken!",
32+
"[5/5] test/5.stamp",
33+
],
34+
]
35+
)
36+
self.assertEqual(len(failures), 1)
37+
self.assertEqual(
38+
failures[0],
39+
(
40+
"test/4.stamp",
41+
dedent(
42+
"""\
43+
FAILED: touch test/4.stamp
44+
Wow! This system is really broken!"""
45+
),
46+
),
47+
)
48+
49+
def test_no_failure_ninja_log(self):
50+
failures = generate_test_report_lib.find_failure_in_ninja_logs(
51+
[
52+
[
53+
"[1/3] test/1.stamp",
54+
"[2/3] test/2.stamp",
55+
"[3/3] test/3.stamp",
56+
]
57+
]
58+
)
59+
self.assertEqual(failures, [])
60+
61+
def test_ninja_log_end(self):
62+
failures = generate_test_report_lib.find_failure_in_ninja_logs(
63+
[
64+
[
65+
"[1/3] test/1.stamp",
66+
"[2/3] test/2.stamp",
67+
"[3/3] test/3.stamp",
68+
"FAILED: touch test/3.stamp",
69+
"Wow! This system is really broken!",
70+
"ninja: build stopped: subcommand failed.",
71+
]
72+
]
73+
)
74+
self.assertEqual(len(failures), 1)
75+
self.assertEqual(
76+
failures[0],
77+
(
78+
"test/3.stamp",
79+
dedent(
80+
"""\
81+
FAILED: touch test/3.stamp
82+
Wow! This system is really broken!"""
83+
),
84+
),
85+
)
86+
87+
def test_ninja_log_multiple_failures(self):
88+
failures = generate_test_report_lib.find_failure_in_ninja_logs(
89+
[
90+
[
91+
"[1/5] test/1.stamp",
92+
"[2/5] test/2.stamp",
93+
"FAILED: touch test/2.stamp",
94+
"Wow! This system is really broken!",
95+
"[3/5] test/3.stamp",
96+
"[4/5] test/4.stamp",
97+
"FAILED: touch test/4.stamp",
98+
"Wow! This system is maybe broken!",
99+
"[5/5] test/5.stamp",
100+
]
101+
]
102+
)
103+
self.assertEqual(len(failures), 2)
104+
self.assertEqual(
105+
failures[0],
106+
(
107+
"test/2.stamp",
108+
dedent(
109+
"""\
110+
FAILED: touch test/2.stamp
111+
Wow! This system is really broken!"""
112+
),
113+
),
114+
)
115+
self.assertEqual(
116+
failures[1],
117+
(
118+
"test/4.stamp",
119+
dedent(
120+
"""\
121+
FAILED: touch test/4.stamp
122+
Wow! This system is maybe broken!"""
123+
),
124+
),
125+
)
126+
22127
def test_title_only(self):
23128
self.assertEqual(
24129
generate_test_report_lib.generate_report("Foo", 0, []),

.github/workflows/premerge.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,6 @@ jobs:
3535
with:
3636
fetch-depth: 2
3737
- name: Build and Test
38-
# Mark the job as a success even if the step fails so that people do
39-
# not get notified while the new premerge pipeline is in an
40-
# experimental state.
4138
run: |
4239
git config --global --add safe.directory '*'
4340
@@ -109,9 +106,6 @@ jobs:
109106
echo "windows-projects=${projects_to_build}" >> $GITHUB_OUTPUT
110107
echo "windows-check-targets=${project_check_targets}" >> $GITHUB_OUTPUT
111108
- name: Build and Test
112-
# Mark the job as a success even if the step fails so that people do
113-
# not get notified while the new premerge pipeline is in an
114-
# experimental state.
115109
if: ${{ steps.vars.outputs.windows-projects != '' }}
116110
shell: cmd
117111
run: |

bolt/lib/Passes/FrameOptimizer.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,11 @@ Error FrameOptimizerPass::runOnFunctions(BinaryContext &BC) {
224224
if (opts::FrameOptimization == FOP_NONE)
225225
return Error::success();
226226

227+
if (!BC.isX86()) {
228+
BC.errs() << "BOLT-ERROR: " << getName() << " is supported only on X86\n";
229+
exit(1);
230+
}
231+
227232
std::unique_ptr<BinaryFunctionCallGraph> CG;
228233
std::unique_ptr<FrameAnalysis> FA;
229234
std::unique_ptr<RegAnalysis> RA;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Checks that non-fully supported passes on AArch64 are handled appropriately.
2+
3+
// REQUIRES: system-linux,asserts,target=aarch64{{.*}}
4+
5+
RUN: %clang %cflags %p/../Inputs/hello.c -o %t -Wl,-q
6+
RUN: not llvm-bolt %t -o %t.bolt --frame-opt=all 2>&1 | FileCheck %s
7+
8+
CHECK: BOLT-ERROR: frame-optimizer is supported only on X86

clang-tools-extra/clangd/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ add_clang_library(clangDaemon STATIC
108108
SemanticHighlighting.cpp
109109
SemanticSelection.cpp
110110
SourceCode.cpp
111+
SymbolDocumentation.cpp
111112
SystemIncludeExtractor.cpp
112113
TidyProvider.cpp
113114
TUScheduler.cpp

clang-tools-extra/clangd/CodeCompletionStrings.cpp

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "CodeCompletionStrings.h"
10+
#include "Config.h"
11+
#include "SymbolDocumentation.h"
1012
#include "clang-c/Index.h"
1113
#include "clang/AST/ASTContext.h"
14+
#include "clang/AST/Comment.h"
15+
#include "clang/AST/Decl.h"
1216
#include "clang/AST/RawCommentList.h"
1317
#include "clang/Basic/SourceManager.h"
1418
#include "clang/Sema/CodeCompleteConsumer.h"
1519
#include "llvm/Support/Compiler.h"
1620
#include "llvm/Support/JSON.h"
21+
#include "llvm/Support/raw_ostream.h"
1722
#include <limits>
1823
#include <utility>
1924

@@ -100,16 +105,51 @@ std::string getDeclComment(const ASTContext &Ctx, const NamedDecl &Decl) {
100105
// the comments for namespaces.
101106
return "";
102107
}
103-
const RawComment *RC = getCompletionComment(Ctx, &Decl);
104-
if (!RC)
105-
return "";
106-
// Sanity check that the comment does not come from the PCH. We choose to not
107-
// write them into PCH, because they are racy and slow to load.
108-
assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc()));
109-
std::string Doc =
110-
RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics());
111-
if (!looksLikeDocComment(Doc))
112-
return "";
108+
109+
const RawComment *RC = nullptr;
110+
const Config &Cfg = Config::current();
111+
112+
std::string Doc;
113+
114+
if (Cfg.Documentation.CommentFormat == Config::CommentFormatPolicy::Doxygen &&
115+
isa<ParmVarDecl>(Decl)) {
116+
// Parameters are documented in their declaration context (function or
117+
// template function).
118+
const NamedDecl *ND = dyn_cast<NamedDecl>(Decl.getDeclContext());
119+
if (!ND)
120+
return "";
121+
122+
RC = getCompletionComment(Ctx, ND);
123+
if (!RC)
124+
return "";
125+
126+
// Sanity check that the comment does not come from the PCH. We choose to
127+
// not write them into PCH, because they are racy and slow to load.
128+
assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc()));
129+
130+
comments::FullComment *FC = RC->parse(Ctx, /*PP=*/nullptr, ND);
131+
if (!FC)
132+
return "";
133+
134+
SymbolDocCommentVisitor V(FC, Ctx.getLangOpts().CommentOpts);
135+
std::string RawDoc;
136+
llvm::raw_string_ostream OS(RawDoc);
137+
138+
V.parameterDocToString(dyn_cast<ParmVarDecl>(&Decl)->getName(), OS);
139+
140+
Doc = StringRef(RawDoc).trim().str();
141+
} else {
142+
RC = getCompletionComment(Ctx, &Decl);
143+
if (!RC)
144+
return "";
145+
// Sanity check that the comment does not come from the PCH. We choose to
146+
// not write them into PCH, because they are racy and slow to load.
147+
assert(!Ctx.getSourceManager().isLoadedSourceLocation(RC->getBeginLoc()));
148+
Doc = RC->getFormattedText(Ctx.getSourceManager(), Ctx.getDiagnostics());
149+
if (!looksLikeDocComment(Doc))
150+
return "";
151+
}
152+
113153
// Clang requires source to be UTF-8, but doesn't enforce this in comments.
114154
if (!llvm::json::isUTF8(Doc))
115155
Doc = llvm::json::fixUTF8(Doc);

clang-tools-extra/clangd/ConfigFragment.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,15 +315,15 @@ struct Fragment {
315315
/// AngledHeaders (i.e. a header matches a regex in both QuotedHeaders and
316316
/// AngledHeaders), system headers use <> and non-system headers use "".
317317
/// These can match any suffix of the header file in question.
318-
/// Matching is performed against the header text, not its absolute path
318+
/// Matching is performed against the absolute path of the header
319319
/// within the project.
320320
std::vector<Located<std::string>> QuotedHeaders;
321321
/// List of regexes for headers that should always be included with a
322322
/// <>-style include. By default, and in case of a conflict with
323323
/// AngledHeaders (i.e. a header matches a regex in both QuotedHeaders and
324324
/// AngledHeaders), system headers use <> and non-system headers use "".
325325
/// These can match any suffix of the header file in question.
326-
/// Matching is performed against the header text, not its absolute path
326+
/// Matching is performed against the absolute path of the header
327327
/// within the project.
328328
std::vector<Located<std::string>> AngledHeaders;
329329
};

clang-tools-extra/clangd/Headers.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,17 @@ IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
304304
// FIXME: should we allow (some limited number of) "../header.h"?
305305
if (llvm::sys::path::is_absolute(Suggested))
306306
return std::nullopt;
307+
auto HeaderPath = llvm::sys::path::convert_to_slash(InsertedHeader.File);
307308
bool IsAngled = false;
308309
for (auto &Filter : AngledHeaders) {
309-
if (Filter(Suggested)) {
310+
if (Filter(HeaderPath)) {
310311
IsAngled = true;
311312
break;
312313
}
313314
}
314315
bool IsQuoted = false;
315316
for (auto &Filter : QuotedHeaders) {
316-
if (Filter(Suggested)) {
317+
if (Filter(HeaderPath)) {
317318
IsQuoted = true;
318319
break;
319320
}
@@ -324,7 +325,7 @@ IncludeInserter::calculateIncludePath(const HeaderFile &InsertedHeader,
324325
if (IsAngled && IsQuoted) {
325326
elog("Header '{0}' matches both quoted and angled regexes, default will "
326327
"be used.",
327-
Suggested);
328+
HeaderPath);
328329
}
329330
IsAngled = IsAngledByDefault;
330331
}

0 commit comments

Comments
 (0)