Skip to content

Commit 9bacd46

Browse files
committed
Merge from 'main' to 'sycl-web' (226 commits)
CONFLICT (modify/delete): llvm/test/ThinLTO/X86/constructor-alias.ll deleted in 885e610 and modified in HEAD. Version HEAD of llvm/test/ThinLTO/X86/constructor-alias.ll left in tree. CONFLICT (content): Merge conflict in llvm/test/LTO/Resolution/X86/comdat-mixed-lto.ll
2 parents 828dd3c + 885e610 commit 9bacd46

File tree

958 files changed

+35393
-14243
lines changed

Some content is hidden

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

958 files changed

+35393
-14243
lines changed

clang-tools-extra/clangd/Hover.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,17 @@ HoverInfo getDeducedTypeHoverContents(QualType QT, const syntax::Token &Tok,
777777
return HI;
778778
}
779779

780+
HoverInfo getStringLiteralContents(const StringLiteral *SL,
781+
const PrintingPolicy &PP) {
782+
HoverInfo HI;
783+
784+
HI.Name = "string-literal";
785+
HI.Size = (SL->getLength() + 1) * SL->getCharByteWidth();
786+
HI.Type = SL->getType().getAsString(PP).c_str();
787+
788+
return HI;
789+
}
790+
780791
bool isLiteral(const Expr *E) {
781792
// Unfortunately there's no common base Literal classes inherits from
782793
// (apart from Expr), therefore these exclusions.
@@ -785,7 +796,7 @@ bool isLiteral(const Expr *E) {
785796
llvm::isa<CXXNullPtrLiteralExpr>(E) ||
786797
llvm::isa<FixedPointLiteral>(E) || llvm::isa<FloatingLiteral>(E) ||
787798
llvm::isa<ImaginaryLiteral>(E) || llvm::isa<IntegerLiteral>(E) ||
788-
llvm::isa<StringLiteral>(E) || llvm::isa<UserDefinedLiteral>(E);
799+
llvm::isa<UserDefinedLiteral>(E);
789800
}
790801

791802
llvm::StringLiteral getNameForExpr(const Expr *E) {
@@ -810,6 +821,9 @@ llvm::Optional<HoverInfo> getHoverContents(const Expr *E, ParsedAST &AST,
810821
return llvm::None;
811822

812823
HoverInfo HI;
824+
// Print the type and the size for string literals
825+
if (const StringLiteral *SL = dyn_cast<StringLiteral>(E))
826+
return getStringLiteralContents(SL, PP);
813827
// For `this` expr we currently generate hover with pointee type.
814828
if (const CXXThisExpr *CTE = dyn_cast<CXXThisExpr>(E))
815829
return getThisExprHoverContents(CTE, AST.getASTContext(), PP);

clang-tools-extra/clangd/refactor/tweaks/RemoveUsingNamespace.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,12 +155,23 @@ Expected<Tweak::Effect> RemoveUsingNamespace::apply(const Selection &Inputs) {
155155
if (!visibleContext(T->getDeclContext())
156156
->Equals(TargetDirective->getNominatedNamespace()))
157157
return;
158+
auto Kind = T->getDeclName().getNameKind();
158159
// Avoid adding qualifiers before operators, e.g.
159160
// using namespace std;
160161
// cout << "foo"; // Must not changed to std::cout std:: << "foo"
161-
// FIXME: User-defined literals are not handled
162-
if (T->isInIdentifierNamespace(
163-
Decl::IdentifierNamespace::IDNS_NonMemberOperator))
162+
if (Kind == DeclarationName::CXXOperatorName)
163+
return;
164+
// Avoid adding qualifiers before user-defined literals, e.g.
165+
// using namespace std;
166+
// auto s = "foo"s; // Must not changed to auto s = "foo" std::s;
167+
// FIXME: Add a using-directive for user-defined literals
168+
// declared in an inline namespace, e.g.
169+
// using namespace s^td;
170+
// int main() { cout << "foo"s; }
171+
// change to
172+
// using namespace std::literals;
173+
// int main() { std::cout << "foo"s; }
174+
if (Kind == DeclarationName::NameKind::CXXLiteralOperatorName)
164175
return;
165176
}
166177
SourceLocation Loc = Ref.NameLoc;

clang-tools-extra/clangd/test/system-include-extractor.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
# CHECK: "method": "textDocument/publishDiagnostics",
6464
# CHECK-NEXT: "params": {
6565
# CHECK-NEXT: "diagnostics": [],
66-
# CHECK-NEXT: "uri": "file://INPUT_DIR/the-file.cpp",
66+
# CHECK-NEXT: "uri": "file://{{.*}}/the-file.cpp",
6767
---
6868
{"jsonrpc":"2.0","id":10000,"method":"shutdown"}
6969
---

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1300,7 +1300,6 @@ TEST(Hover, NoHover) {
13001300
"auto x = ^42.0i;",
13011301
"auto x = ^42;",
13021302
"auto x = ^nullptr;",
1303-
"auto x = ^\"asdf\";",
13041303
};
13051304

13061305
for (const auto &Test : Tests) {
@@ -1326,6 +1325,12 @@ TEST(Hover, All) {
13261325
HI.Type = "char";
13271326
HI.Value = "65 (0x41)";
13281327
}},
1328+
{"auto s = ^[[\"Hello, world!\"]]; // string literal",
1329+
[](HoverInfo &HI) {
1330+
HI.Name = "string-literal";
1331+
HI.Size = 14;
1332+
HI.Type = "const char[14]";
1333+
}},
13291334
{
13301335
R"cpp(// Local variable
13311336
int main() {

clang-tools-extra/clangd/unittests/tweaks/RemoveUsingNamespaceTests.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,21 @@ TEST_F(RemoveUsingNamespaceTest, All) {
249249
ns::Foo foo;
250250
foo + 10;
251251
}
252+
)cpp"},
253+
{// Does not qualify user-defined literals
254+
R"cpp(
255+
namespace ns {
256+
long double operator "" _w(long double);
257+
}
258+
using namespace n^s;
259+
int main() { 1.5_w; }
260+
)cpp",
261+
R"cpp(
262+
namespace ns {
263+
long double operator "" _w(long double);
264+
}
265+
266+
int main() { 1.5_w; }
252267
)cpp"}};
253268
for (auto C : Cases)
254269
EXPECT_EQ(C.second, apply(C.first)) << C.first;

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Analysis.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ namespace include_cleaner {
2828
/// that symbol may be provided by several headers.
2929
/// FIXME: Provide signals about the providing headers so the caller can filter
3030
/// and rank the results.
31-
using UsedSymbolCB = llvm::function_ref<void(SymbolReference SymRef,
31+
using UsedSymbolCB = llvm::function_ref<void(const SymbolReference &SymRef,
3232
llvm::ArrayRef<Header> Providers)>;
3333

3434
/// Find and report all references to symbols in a region of code.
3535
///
3636
/// The AST traversal is rooted at ASTRoots - typically top-level declarations
3737
/// of a single source file.
38-
/// FIXME: Handle macro uses.
38+
/// The references to macros must be recorded separately and provided.
3939
///
4040
/// This is the main entrypoint of the include-cleaner library, and can be used:
4141
/// - to diagnose missing includes: a referenced symbol is provided by
@@ -44,7 +44,9 @@ using UsedSymbolCB = llvm::function_ref<void(SymbolReference SymRef,
4444
/// the headers for any referenced symbol
4545
/// FIXME: Take in an include structure to improve location to header mappings
4646
/// (e.g. IWYU pragmas).
47-
void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB);
47+
void walkUsed(llvm::ArrayRef<Decl *> ASTRoots,
48+
llvm::ArrayRef<SymbolReference> MacroRefs, const SourceManager &,
49+
UsedSymbolCB CB);
4850

4951
} // namespace include_cleaner
5052
} // namespace clang

clang-tools-extra/include-cleaner/include/clang-include-cleaner/Record.h

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919

2020
#include "llvm/ADT/DenseMap.h"
2121
#include "llvm/ADT/DenseSet.h"
22+
#include "llvm/ADT/SmallVector.h"
23+
#include "llvm/ADT/StringRef.h"
24+
#include "llvm/Support/Allocator.h"
2225
#include "llvm/Support/FileSystem/UniqueID.h"
2326
#include "clang-include-cleaner/Types.h"
2427
#include "llvm/ADT/ArrayRef.h"
@@ -35,6 +38,7 @@ class Decl;
3538
class FileEntry;
3639
class Preprocessor;
3740
class PPCallbacks;
41+
class FileManager;
3842

3943
namespace include_cleaner {
4044

@@ -61,6 +65,11 @@ class PragmaIncludes {
6165
/// Returns "" if there is none.
6266
llvm::StringRef getPublic(const FileEntry *File) const;
6367

68+
/// Returns all direct exporter headers for the given header file.
69+
/// Returns empty if there is none.
70+
llvm::SmallVector<const FileEntry *> getExporters(const FileEntry *File,
71+
FileManager &FM) const;
72+
6473
private:
6574
class RecordPragma;
6675
/// 1-based Line numbers for the #include directives of the main file that
@@ -73,10 +82,21 @@ class PragmaIncludes {
7382
// !!NOTE: instead of using a FileEntry* to identify the physical file, we
7483
// deliberately use the UniqueID to ensure the result is stable across
7584
// FileManagers (for clangd's preamble and main-file builds).
76-
llvm::DenseMap<llvm::sys::fs::UniqueID, std::string /*VerbatimSpelling*/>
85+
llvm::DenseMap<llvm::sys::fs::UniqueID, llvm::StringRef /*VerbatimSpelling*/>
7786
IWYUPublic;
7887

79-
// FIXME: add other IWYU supports (export etc)
88+
/// A reverse map from the underlying header to its exporter headers.
89+
//
90+
// There's no way to get a FileEntry from a UniqueID, especially when it
91+
// hasn't been opened before. So store the full path and convert it to a
92+
// FileEntry by opening the file again through a FileManager.
93+
llvm::DenseMap<llvm::sys::fs::UniqueID,
94+
llvm::SmallVector</*RealPathNames*/ llvm::StringRef>>
95+
IWYUExportBy;
96+
97+
/// Owns the strings.
98+
llvm::BumpPtrAllocator Arena;
99+
80100
// FIXME: add support for clang use_instead pragma
81101
// FIXME: add selfcontained file.
82102
};

clang-tools-extra/include-cleaner/lib/Analysis.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,11 @@ toHeader(llvm::ArrayRef<tooling::stdlib::Header> Headers) {
2626
});
2727
return Result;
2828
}
29-
3029
} // namespace
31-
void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB) {
30+
31+
void walkUsed(llvm::ArrayRef<Decl *> ASTRoots,
32+
llvm::ArrayRef<SymbolReference> MacroRefs,
33+
const SourceManager &SM, UsedSymbolCB CB) {
3234
tooling::stdlib::Recognizer Recognizer;
3335
for (auto *Root : ASTRoots) {
3436
auto &SM = Root->getASTContext().getSourceManager();
@@ -45,7 +47,14 @@ void walkUsed(llvm::ArrayRef<Decl *> ASTRoots, UsedSymbolCB CB) {
4547
return CB({Loc, Symbol(ND), RT}, {Header(FE)});
4648
});
4749
}
48-
// FIXME: Handle references of macros.
50+
for (const SymbolReference &MacroRef : MacroRefs) {
51+
assert(MacroRef.Target.kind() == Symbol::Macro);
52+
// FIXME: Handle IWYU pragmas, non self-contained files.
53+
// FIXME: Handle macro locations.
54+
if (auto *FE = SM.getFileEntryForID(
55+
SM.getFileID(MacroRef.Target.macro().Definition)))
56+
CB(MacroRef, {Header(FE)});
57+
}
4958
}
5059

5160
} // namespace clang::include_cleaner

clang-tools-extra/include-cleaner/lib/Record.cpp

Lines changed: 95 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,24 @@ static llvm::Optional<StringRef> parseIWYUPragma(const char *Text) {
118118
class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
119119
public:
120120
RecordPragma(const CompilerInstance &CI, PragmaIncludes *Out)
121-
: SM(CI.getSourceManager()), Out(Out) {}
121+
: SM(CI.getSourceManager()), Out(Out), UniqueStrings(Arena) {}
122122

123123
void FileChanged(SourceLocation Loc, FileChangeReason Reason,
124124
SrcMgr::CharacteristicKind FileType,
125125
FileID PrevFID) override {
126126
InMainFile = SM.isWrittenInMainFile(Loc);
127127
}
128128

129+
void EndOfMainFile() override {
130+
for (auto &It : Out->IWYUExportBy) {
131+
llvm::sort(It.getSecond());
132+
It.getSecond().erase(
133+
std::unique(It.getSecond().begin(), It.getSecond().end()),
134+
It.getSecond().end());
135+
}
136+
Out->Arena = std::move(Arena);
137+
}
138+
129139
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok,
130140
llvm::StringRef FileName, bool IsAngled,
131141
CharSourceRange /*FilenameRange*/,
@@ -134,14 +144,35 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
134144
llvm::StringRef /*RelativePath*/,
135145
const clang::Module * /*Imported*/,
136146
SrcMgr::CharacteristicKind FileKind) override {
137-
if (!InMainFile)
138-
return;
139-
int HashLine =
140-
SM.getLineNumber(SM.getMainFileID(), SM.getFileOffset(HashLoc));
141-
if (LastPragmaKeepInMainFileLine == HashLine)
147+
FileID HashFID = SM.getFileID(HashLoc);
148+
int HashLine = SM.getLineNumber(HashFID, SM.getFileOffset(HashLoc));
149+
checkForExport(HashFID, HashLine, File ? &File->getFileEntry() : nullptr);
150+
151+
if (InMainFile && LastPragmaKeepInMainFileLine == HashLine)
142152
Out->ShouldKeep.insert(HashLine);
143153
}
144154

155+
void checkForExport(FileID IncludingFile, int HashLine,
156+
const FileEntry *IncludedHeader) {
157+
if (ExportStack.empty())
158+
return;
159+
auto &Top = ExportStack.back();
160+
if (Top.SeenAtFile != IncludingFile)
161+
return;
162+
// Make sure current include is covered by the export pragma.
163+
if ((Top.Block && HashLine > Top.SeenAtLine) ||
164+
Top.SeenAtLine == HashLine) {
165+
if (IncludedHeader)
166+
Out->IWYUExportBy[IncludedHeader->getUniqueID()].push_back(
167+
Top.FullPath);
168+
// main-file #include with export pragma should never be removed.
169+
if (Top.SeenAtFile == SM.getMainFileID())
170+
Out->ShouldKeep.insert(HashLine);
171+
}
172+
if (!Top.Block) // Pop immediately for single-line export pragma.
173+
ExportStack.pop_back();
174+
}
175+
145176
bool HandleComment(Preprocessor &PP, SourceRange Range) override {
146177
auto &SM = PP.getSourceManager();
147178
auto Pragma = parseIWYUPragma(SM.getCharacterData(Range.getBegin()));
@@ -153,11 +184,32 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
153184
if (auto *FE = SM.getFileEntryForID(SM.getFileID(Range.getBegin())))
154185
Out->IWYUPublic.insert(
155186
{FE->getLastRef().getUniqueID(),
156-
Pragma->startswith("<") || Pragma->startswith("\"")
157-
? Pragma->str()
158-
: ("\"" + *Pragma + "\"").str()});
187+
save(Pragma->startswith("<") || Pragma->startswith("\"")
188+
? (*Pragma)
189+
: ("\"" + *Pragma + "\"").str())});
159190
return false;
160191
}
192+
FileID CommentFID = SM.getFileID(Range.getBegin());
193+
int CommentLine = SM.getLineNumber(SM.getFileID(Range.getBegin()),
194+
SM.getFileOffset(Range.getBegin()));
195+
// Record export pragma.
196+
if (Pragma->startswith("export")) {
197+
ExportStack.push_back(
198+
{CommentLine, CommentFID,
199+
save(SM.getFileEntryForID(CommentFID)->tryGetRealPathName()),
200+
false});
201+
} else if (Pragma->startswith("begin_exports")) {
202+
ExportStack.push_back(
203+
{CommentLine, CommentFID,
204+
save(SM.getFileEntryForID(CommentFID)->tryGetRealPathName()), true});
205+
} else if (Pragma->startswith("end_exports")) {
206+
// FIXME: be robust on unmatching cases. We should only pop the stack if
207+
// the begin_exports and end_exports is in the same file.
208+
if (!ExportStack.empty()) {
209+
assert(ExportStack.back().Block);
210+
ExportStack.pop_back();
211+
}
212+
}
161213

162214
if (InMainFile) {
163215
if (!Pragma->startswith("keep"))
@@ -176,18 +228,35 @@ class PragmaIncludes::RecordPragma : public PPCallbacks, public CommentHandler {
176228
// This code stores the last location of "IWYU pragma: keep" (or export)
177229
// comment in the main file, so that when next InclusionDirective is
178230
// called, it will know that the next inclusion is behind the IWYU pragma.
179-
LastPragmaKeepInMainFileLine = SM.getLineNumber(
180-
SM.getMainFileID(), SM.getFileOffset(Range.getBegin()));
231+
LastPragmaKeepInMainFileLine = CommentLine;
181232
}
182233
return false;
183234
}
184235

185236
private:
237+
StringRef save(llvm::StringRef S) { return UniqueStrings.save(S); }
238+
186239
bool InMainFile = false;
187240
const SourceManager &SM;
188241
PragmaIncludes *Out;
242+
llvm::BumpPtrAllocator Arena;
243+
/// Intern table for strings. Contents are on the arena.
244+
llvm::StringSaver UniqueStrings;
189245
// Track the last line "IWYU pragma: keep" was seen in the main file, 1-based.
190246
int LastPragmaKeepInMainFileLine = -1;
247+
struct ExportPragma {
248+
// The line number where we saw the begin_exports or export pragma.
249+
int SeenAtLine = 0; // 1-based line number.
250+
// The file where we saw the pragma.
251+
FileID SeenAtFile;
252+
// FullPath of the file SeenAtFile.
253+
StringRef FullPath;
254+
// true if it is a block begin/end_exports pragma; false if it is a
255+
// single-line export pragma.
256+
bool Block = false;
257+
};
258+
// A stack for tracking all open begin_exports or single-line export.
259+
std::vector<ExportPragma> ExportStack;
191260
};
192261

193262
void PragmaIncludes::record(const CompilerInstance &CI) {
@@ -203,6 +272,21 @@ llvm::StringRef PragmaIncludes::getPublic(const FileEntry *F) const {
203272
return It->getSecond();
204273
}
205274

275+
llvm::SmallVector<const FileEntry *>
276+
PragmaIncludes::getExporters(const FileEntry *File, FileManager &FM) const {
277+
auto It = IWYUExportBy.find(File->getUniqueID());
278+
if (It == IWYUExportBy.end())
279+
return {};
280+
281+
llvm::SmallVector<const FileEntry *> Results;
282+
for (auto Export : It->getSecond()) {
283+
// FIMXE: log the failing cases?
284+
if (auto FE = expectedToOptional(FM.getFileRef(Export)))
285+
Results.push_back(*FE);
286+
}
287+
return Results;
288+
}
289+
206290
std::unique_ptr<ASTConsumer> RecordedAST::record() {
207291
class Recorder : public ASTConsumer {
208292
RecordedAST *Out;

0 commit comments

Comments
 (0)