Skip to content

Commit 2a5a4fd

Browse files
committed
Merge from 'master' to 'sycl-web' (#1)
2 parents 30a60bf + e24e95f commit 2a5a4fd

File tree

675 files changed

+27574
-5540
lines changed

Some content is hidden

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

675 files changed

+27574
-5540
lines changed

.git-blame-ignore-revs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@
1616

1717
# r280751: [Coding style change][lldb] Moved LLDB code base to use LLVM style
1818
b9c1b51e45b845debb76d8658edabca70ca56079
19+
20+
# r302421: That change incorrectly changed line endings in some libc++ files
21+
9669df28d4fd3c52d09f451186bd217cdc3322c0
22+
23+
# r302496: That is the revert of r302421
24+
ff63090b0e1072bd398b8efef8ae2291613a6ec9

clang-tools-extra/clangd/FindTarget.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include "llvm/Support/Casting.h"
3838
#include "llvm/Support/Compiler.h"
3939
#include "llvm/Support/raw_ostream.h"
40+
#include <iterator>
4041
#include <utility>
4142
#include <vector>
4243

@@ -76,6 +77,11 @@ std::vector<const NamedDecl *> getMembersReferencedViaDependentName(
7677
bool IsNonstaticMember) {
7778
if (!T)
7879
return {};
80+
if (auto *ET = T->getAs<EnumType>()) {
81+
auto Result =
82+
ET->getDecl()->lookup(NameFactory(ET->getDecl()->getASTContext()));
83+
return {Result.begin(), Result.end()};
84+
}
7985
if (auto *ICNT = T->getAs<InjectedClassNameType>()) {
8086
T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
8187
}

clang-tools-extra/clangd/FormattedString.cpp

Lines changed: 136 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "llvm/ADT/SmallVector.h"
1313
#include "llvm/ADT/StringExtras.h"
1414
#include "llvm/ADT/StringRef.h"
15+
#include "llvm/Support/Compiler.h"
1516
#include "llvm/Support/ErrorHandling.h"
1617
#include "llvm/Support/FormatVariadic.h"
1718
#include "llvm/Support/raw_ostream.h"
@@ -26,23 +27,143 @@ namespace clangd {
2627
namespace markup {
2728

2829
namespace {
30+
31+
// Is <contents a plausible start to an HTML tag?
32+
// Contents may not be the rest of the line, but it's the rest of the plain
33+
// text, so we expect to see at least the tag name.
34+
bool looksLikeTag(llvm::StringRef Contents) {
35+
if (Contents.empty())
36+
return false;
37+
if (Contents.front() == '!' || Contents.front() == '?' ||
38+
Contents.front() == '/')
39+
return true;
40+
// Check the start of the tag name.
41+
if (!llvm::isAlpha(Contents.front()))
42+
return false;
43+
// Drop rest of the tag name, and following whitespace.
44+
Contents = Contents
45+
.drop_while([](char C) {
46+
return llvm::isAlnum(C) || C == '-' || C == '_' || C == ':';
47+
})
48+
.drop_while(isWhitespace);
49+
// The rest of the tag consists of attributes, which have restrictive names.
50+
// If we hit '=', all bets are off (attribute values can contain anything).
51+
for (; !Contents.empty(); Contents = Contents.drop_front()) {
52+
if (llvm::isAlnum(Contents.front()) || isWhitespace(Contents.front()))
53+
continue;
54+
if (Contents.front() == '>' || Contents.startswith("/>"))
55+
return true; // May close the tag.
56+
if (Contents.front() == '=')
57+
return true; // Don't try to parse attribute values.
58+
return false; // Random punctuation means this isn't a tag.
59+
}
60+
return true; // Potentially incomplete tag.
61+
}
62+
63+
// Tests whether C should be backslash-escaped in markdown.
64+
// The string being escaped is Before + C + After. This is part of a paragraph.
65+
// StartsLine indicates whether `Before` is the start of the line.
66+
// After may not be everything until the end of the line.
67+
//
68+
// It's always safe to escape punctuation, but want minimal escaping.
69+
// The strategy is to escape the first character of anything that might start
70+
// a markdown grammar construct.
71+
bool needsLeadingEscape(char C, llvm::StringRef Before, llvm::StringRef After,
72+
bool StartsLine) {
73+
assert(Before.take_while(isWhitespace).empty());
74+
auto RulerLength = [&]() -> /*Length*/ unsigned {
75+
if (!StartsLine || !Before.empty())
76+
return false;
77+
llvm::StringRef A = After.rtrim();
78+
return llvm::all_of(A, [C](char D) { return C == D; }) ? 1 + A.size() : 0;
79+
};
80+
auto IsBullet = [&]() {
81+
return StartsLine && Before.empty() &&
82+
(After.empty() || After.startswith(" "));
83+
};
84+
auto SpaceSurrounds = [&]() {
85+
return (After.empty() || isWhitespace(After.front())) &&
86+
(Before.empty() || isWhitespace(Before.back()));
87+
};
88+
auto WordSurrounds = [&]() {
89+
return (!After.empty() && llvm::isAlnum(After.front())) &&
90+
(!Before.empty() && llvm::isAlnum(Before.back()));
91+
};
92+
93+
switch (C) {
94+
case '\\': // Escaped character.
95+
return true;
96+
case '`': // Code block or inline code
97+
// Any number of backticks can delimit an inline code block that can end
98+
// anywhere (including on another line). We must escape them all.
99+
return true;
100+
case '~': // Code block
101+
return StartsLine && Before.empty() && After.startswith("~~");
102+
case '#': { // ATX heading.
103+
if (!StartsLine || !Before.empty())
104+
return false;
105+
llvm::StringRef Rest = After.ltrim(C);
106+
return Rest.empty() || Rest.startswith(" ");
107+
}
108+
case ']': // Link or link reference.
109+
// We escape ] rather than [ here, because it's more constrained:
110+
// ](...) is an in-line link
111+
// ]: is a link reference
112+
// The following are only links if the link reference exists:
113+
// ] by itself is a shortcut link
114+
// ][...] is an out-of-line link
115+
// Because we never emit link references, we don't need to handle these.
116+
return After.startswith(":") || After.startswith("(");
117+
case '=': // Setex heading.
118+
return RulerLength() > 0;
119+
case '_': // Horizontal ruler or matched delimiter.
120+
if (RulerLength() >= 3)
121+
return true;
122+
// Not a delimiter if surrounded by space, or inside a word.
123+
// (The rules at word boundaries are subtle).
124+
return !(SpaceSurrounds() || WordSurrounds());
125+
case '-': // Setex heading, horizontal ruler, or bullet.
126+
if (RulerLength() > 0)
127+
return true;
128+
return IsBullet();
129+
case '+': // Bullet list.
130+
return IsBullet();
131+
case '*': // Bullet list, horizontal ruler, or delimiter.
132+
return IsBullet() || RulerLength() >= 3 || !SpaceSurrounds();
133+
case '<': // HTML tag (or autolink, which we choose not to escape)
134+
return looksLikeTag(After);
135+
case '>': // Quote marker. Needs escaping at start of line.
136+
return StartsLine && Before.empty();
137+
case '&': { // HTML entity reference
138+
auto End = After.find(';');
139+
if (End == llvm::StringRef::npos)
140+
return false;
141+
llvm::StringRef Content = After.substr(0, End);
142+
if (Content.consume_front("#")) {
143+
if (Content.consume_front("x") || Content.consume_front("X"))
144+
return llvm::all_of(Content, llvm::isHexDigit);
145+
return llvm::all_of(Content, llvm::isDigit);
146+
}
147+
return llvm::all_of(Content, llvm::isAlpha);
148+
}
149+
case '.': // Numbered list indicator. Escape 12. -> 12\. at start of line.
150+
case ')':
151+
return StartsLine && !Before.empty() &&
152+
llvm::all_of(Before, llvm::isDigit) && After.startswith(" ");
153+
default:
154+
return false;
155+
}
156+
}
157+
29158
/// Escape a markdown text block. Ensures the punctuation will not introduce
30159
/// any of the markdown constructs.
31-
std::string renderText(llvm::StringRef Input) {
32-
// Escaping ASCII punctuation ensures we can't start a markdown construct.
33-
constexpr llvm::StringLiteral Punctuation =
34-
R"txt(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)txt";
35-
160+
std::string renderText(llvm::StringRef Input, bool StartsLine) {
36161
std::string R;
37-
for (size_t From = 0; From < Input.size();) {
38-
size_t Next = Input.find_first_of(Punctuation, From);
39-
R += Input.substr(From, Next - From);
40-
if (Next == llvm::StringRef::npos)
41-
break;
42-
R += "\\";
43-
R += Input[Next];
44-
45-
From = Next + 1;
162+
for (unsigned I = 0; I < Input.size(); ++I) {
163+
if (needsLeadingEscape(Input[I], Input.substr(0, I), Input.substr(I + 1),
164+
StartsLine))
165+
R.push_back('\\');
166+
R.push_back(Input[I]);
46167
}
47168
return R;
48169
}
@@ -236,7 +357,7 @@ void Paragraph::renderMarkdown(llvm::raw_ostream &OS) const {
236357
OS << Sep;
237358
switch (C.Kind) {
238359
case Chunk::PlainText:
239-
OS << renderText(C.Contents);
360+
OS << renderText(C.Contents, Sep.empty());
240361
break;
241362
case Chunk::InlineCode:
242363
OS << renderInlineBlock(C.Contents);

clang-tools-extra/clangd/FormattedString.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class Document {
9595
BulletList &addBulletList();
9696

9797
/// Doesn't contain any trailing newlines.
98+
/// We try to make the markdown human-readable, e.g. avoid extra escaping.
99+
/// At least one client (coc.nvim) displays the markdown verbatim!
98100
std::string asMarkdown() const;
99101
/// Doesn't contain any trailing newlines.
100102
std::string asPlainText() const;

clang-tools-extra/clangd/unittests/FormattedStringTests.cpp

Lines changed: 85 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,96 @@ namespace clangd {
1717
namespace markup {
1818
namespace {
1919

20-
TEST(Render, Escaping) {
21-
// Check some ASCII punctuation
22-
Paragraph P;
23-
P.appendText("*!`");
24-
EXPECT_EQ(P.asMarkdown(), "\\*\\!\\`");
20+
std::string escape(llvm::StringRef Text) {
21+
return Paragraph().appendText(Text.str()).asMarkdown();
22+
}
23+
24+
MATCHER_P(escaped, C, "") {
25+
return testing::ExplainMatchResult(::testing::HasSubstr(std::string{'\\', C}),
26+
arg, result_listener);
27+
}
2528

29+
MATCHER(escapedNone, "") {
30+
return testing::ExplainMatchResult(::testing::Not(::testing::HasSubstr("\\")),
31+
arg, result_listener);
32+
}
33+
34+
TEST(Render, Escaping) {
2635
// Check all ASCII punctuation.
27-
P = Paragraph();
2836
std::string Punctuation = R"txt(!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~)txt";
29-
// Same text, with each character escaped.
30-
std::string EscapedPunctuation;
31-
EscapedPunctuation.reserve(2 * Punctuation.size());
32-
for (char C : Punctuation)
33-
EscapedPunctuation += std::string("\\") + C;
34-
P.appendText(Punctuation);
35-
EXPECT_EQ(P.asMarkdown(), EscapedPunctuation);
37+
std::string EscapedPunc = R"txt(!"#$%&'()\*+,-./:;<=>?@[\\]^\_\`{|}~)txt";
38+
EXPECT_EQ(escape(Punctuation), EscapedPunc);
39+
40+
// Inline code
41+
EXPECT_EQ(escape("`foo`"), R"(\`foo\`)");
42+
EXPECT_EQ(escape("`foo"), R"(\`foo)");
43+
EXPECT_EQ(escape("foo`"), R"(foo\`)");
44+
EXPECT_EQ(escape("``foo``"), R"(\`\`foo\`\`)");
45+
// Code blocks
46+
EXPECT_EQ(escape("```"), R"(\`\`\`)"); // This could also be inline code!
47+
EXPECT_EQ(escape("~~~"), R"(\~~~)");
48+
49+
// Rulers and headings
50+
EXPECT_THAT(escape("## Heading"), escaped('#'));
51+
EXPECT_THAT(escape("Foo # bar"), escapedNone());
52+
EXPECT_EQ(escape("---"), R"(\---)");
53+
EXPECT_EQ(escape("-"), R"(\-)");
54+
EXPECT_EQ(escape("==="), R"(\===)");
55+
EXPECT_EQ(escape("="), R"(\=)");
56+
EXPECT_EQ(escape("***"), R"(\*\*\*)"); // \** could start emphasis!
57+
58+
// HTML tags.
59+
EXPECT_THAT(escape("<pre"), escaped('<'));
60+
EXPECT_THAT(escape("< pre"), escapedNone());
61+
EXPECT_THAT(escape("if a<b then"), escaped('<'));
62+
EXPECT_THAT(escape("if a<b then c."), escapedNone());
63+
EXPECT_THAT(escape("if a<b then c='foo'."), escaped('<'));
64+
EXPECT_THAT(escape("std::vector<T>"), escaped('<'));
65+
EXPECT_THAT(escape("std::vector<std::string>"), escaped('<'));
66+
EXPECT_THAT(escape("std::map<int, int>"), escapedNone());
67+
// Autolinks
68+
EXPECT_THAT(escape("Email <[email protected]>"), escapedNone());
69+
EXPECT_THAT(escape("Website <http://foo.bar>"), escapedNone());
70+
71+
// Bullet lists.
72+
EXPECT_THAT(escape("- foo"), escaped('-'));
73+
EXPECT_THAT(escape("* foo"), escaped('*'));
74+
EXPECT_THAT(escape("+ foo"), escaped('+'));
75+
EXPECT_THAT(escape("+"), escaped('+'));
76+
EXPECT_THAT(escape("a + foo"), escapedNone());
77+
EXPECT_THAT(escape("a+ foo"), escapedNone());
78+
EXPECT_THAT(escape("1. foo"), escaped('.'));
79+
EXPECT_THAT(escape("a. foo"), escapedNone());
80+
81+
// Emphasis.
82+
EXPECT_EQ(escape("*foo*"), R"(\*foo\*)");
83+
EXPECT_EQ(escape("**foo**"), R"(\*\*foo\*\*)");
84+
EXPECT_THAT(escape("*foo"), escaped('*'));
85+
EXPECT_THAT(escape("foo *"), escapedNone());
86+
EXPECT_THAT(escape("foo * bar"), escapedNone());
87+
EXPECT_THAT(escape("foo_bar"), escapedNone());
88+
EXPECT_THAT(escape("foo _bar"), escaped('_'));
89+
EXPECT_THAT(escape("foo_ bar"), escaped('_'));
90+
EXPECT_THAT(escape("foo _ bar"), escapedNone());
91+
92+
// HTML entities.
93+
EXPECT_THAT(escape("fish &chips;"), escaped('&'));
94+
EXPECT_THAT(escape("fish & chips;"), escapedNone());
95+
EXPECT_THAT(escape("fish &chips"), escapedNone());
96+
EXPECT_THAT(escape("foo &#42; bar"), escaped('&'));
97+
EXPECT_THAT(escape("foo &#xaf; bar"), escaped('&'));
98+
EXPECT_THAT(escape("foo &?; bar"), escapedNone());
99+
100+
// Links.
101+
EXPECT_THAT(escape("[foo](bar)"), escaped(']'));
102+
EXPECT_THAT(escape("[foo]: bar"), escaped(']'));
103+
// No need to escape these, as the target never exists.
104+
EXPECT_THAT(escape("[foo][]"), escapedNone());
105+
EXPECT_THAT(escape("[foo][bar]"), escapedNone());
106+
EXPECT_THAT(escape("[foo]"), escapedNone());
36107

37108
// In code blocks we don't need to escape ASCII punctuation.
38-
P = Paragraph();
109+
Paragraph P = Paragraph();
39110
P.appendCode("* foo !+ bar * baz");
40111
EXPECT_EQ(P.asMarkdown(), "`* foo !+ bar * baz`");
41112

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1905,7 +1905,7 @@ TEST(Hover, PresentRulers) {
19051905
llvm::StringRef ExpectedMarkdown = R"md(### variable `foo`
19061906
19071907
---
1908-
Value \= `val`
1908+
Value = `val`
19091909
19101910
---
19111911
```cpp

clang-tools-extra/clangd/unittests/XRefsTests.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,14 @@ TEST(LocateSymbol, All) {
529529
void test(unique_ptr<S<T>>& V) {
530530
V->fo^o();
531531
}
532+
)cpp",
533+
534+
R"cpp(// Heuristic resolution of dependent enumerator
535+
template <typename T>
536+
struct Foo {
537+
enum class E { [[A]], B };
538+
E e = E::A^;
539+
};
532540
)cpp"};
533541
for (const char *Test : Tests) {
534542
Annotations T(Test);

clang/cmake/caches/Fuchsia-stage2.cmake

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ set(LLVM_TOOLCHAIN_TOOLS
195195
llvm-cxxfilt
196196
llvm-dwarfdump
197197
llvm-dwp
198+
llvm-gsymutil
198199
llvm-lib
199200
llvm-nm
200201
llvm-objcopy

clang/docs/HowToSetupToolingForLLVM.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ make a build directory and run CMake from it:
3737
If you want to use clang instead of GCC, you can add
3838
``-DCMAKE_C_COMPILER=/path/to/clang -DCMAKE_CXX_COMPILER=/path/to/clang++``.
3939
You can also use ``ccmake``, which provides a curses interface to configure
40-
CMake variables for lazy people.
40+
CMake variables.
4141

4242
As a result, the new ``compile_commands.json`` file should appear in the
4343
current directory. You should link it to the LLVM source tree so that

0 commit comments

Comments
 (0)