Skip to content

Commit 96644b7

Browse files
Merge from 'master' to 'sycl-web' (#3)
CONFLICT (content): Merge conflict in clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp
2 parents e6e086b + 1b0ca81 commit 96644b7

File tree

228 files changed

+8144
-1777
lines changed

Some content is hidden

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

228 files changed

+8144
-1777
lines changed

clang-tools-extra/clangd/CMakeLists.txt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,17 +168,18 @@ if ( CLANGD_BUILD_XPC )
168168
add_subdirectory(xpc)
169169
endif ()
170170

171+
if (CLANGD_ENABLE_REMOTE)
172+
include(FindGRPC)
173+
endif()
174+
171175
if(CLANG_INCLUDE_TESTS)
172-
add_subdirectory(test)
173-
add_subdirectory(unittests)
176+
add_subdirectory(test)
177+
add_subdirectory(unittests)
174178
endif()
175179

176180
# FIXME(kirillbobyrev): Document this in the LLVM docs once remote index is stable.
177181
option(CLANGD_ENABLE_REMOTE "Use gRPC library to enable remote index support for Clangd" OFF)
178182
set(GRPC_INSTALL_PATH "" CACHE PATH "Path to gRPC library manual installation.")
179183

180-
if (CLANGD_ENABLE_REMOTE)
181-
include(FindGRPC)
182-
endif()
183184
add_subdirectory(index/remote)
184185
add_subdirectory(index/dex/dexp)

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -625,6 +625,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params,
625625
}},
626626
{"typeHierarchyProvider", true},
627627
{"memoryUsageProvider", true}, // clangd extension.
628+
{"callHierarchyProvider", true},
628629
}}}};
629630
if (Opts.Encoding)
630631
Result["offsetEncoding"] = *Opts.Encoding;
@@ -1224,6 +1225,26 @@ void ClangdLSPServer::onResolveTypeHierarchy(
12241225
std::move(Reply));
12251226
}
12261227

1228+
void ClangdLSPServer::onPrepareCallHierarchy(
1229+
const CallHierarchyPrepareParams &Params,
1230+
Callback<std::vector<CallHierarchyItem>> Reply) {
1231+
Server->prepareCallHierarchy(Params.textDocument.uri.file(), Params.position,
1232+
std::move(Reply));
1233+
}
1234+
1235+
void ClangdLSPServer::onCallHierarchyIncomingCalls(
1236+
const CallHierarchyIncomingCallsParams &Params,
1237+
Callback<std::vector<CallHierarchyIncomingCall>> Reply) {
1238+
Server->incomingCalls(Params.item, std::move(Reply));
1239+
}
1240+
1241+
void ClangdLSPServer::onCallHierarchyOutgoingCalls(
1242+
const CallHierarchyOutgoingCallsParams &Params,
1243+
Callback<std::vector<CallHierarchyOutgoingCall>> Reply) {
1244+
// FIXME: To be implemented.
1245+
Reply(std::vector<CallHierarchyOutgoingCall>{});
1246+
}
1247+
12271248
void ClangdLSPServer::applyConfiguration(
12281249
const ConfigurationSettings &Settings) {
12291250
// Per-file update to the compilation database.
@@ -1468,6 +1489,9 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp,
14681489
MsgHandler->bind("textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo);
14691490
MsgHandler->bind("textDocument/typeHierarchy", &ClangdLSPServer::onTypeHierarchy);
14701491
MsgHandler->bind("typeHierarchy/resolve", &ClangdLSPServer::onResolveTypeHierarchy);
1492+
MsgHandler->bind("textDocument/prepareCallHierarchy", &ClangdLSPServer::onPrepareCallHierarchy);
1493+
MsgHandler->bind("callHierarchy/incomingCalls", &ClangdLSPServer::onCallHierarchyIncomingCalls);
1494+
MsgHandler->bind("callHierarchy/outgoingCalls", &ClangdLSPServer::onCallHierarchyOutgoingCalls);
14711495
MsgHandler->bind("textDocument/selectionRange", &ClangdLSPServer::onSelectionRange);
14721496
MsgHandler->bind("textDocument/documentLink", &ClangdLSPServer::onDocumentLink);
14731497
MsgHandler->bind("textDocument/semanticTokens/full", &ClangdLSPServer::onSemanticTokens);

clang-tools-extra/clangd/ClangdLSPServer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,14 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
135135
Callback<llvm::Optional<TypeHierarchyItem>>);
136136
void onResolveTypeHierarchy(const ResolveTypeHierarchyItemParams &,
137137
Callback<llvm::Optional<TypeHierarchyItem>>);
138+
void onPrepareCallHierarchy(const CallHierarchyPrepareParams &,
139+
Callback<std::vector<CallHierarchyItem>>);
140+
void onCallHierarchyIncomingCalls(
141+
const CallHierarchyIncomingCallsParams &,
142+
Callback<std::vector<CallHierarchyIncomingCall>>);
143+
void onCallHierarchyOutgoingCalls(
144+
const CallHierarchyOutgoingCallsParams &,
145+
Callback<std::vector<CallHierarchyOutgoingCall>>);
138146
void onChangeConfiguration(const DidChangeConfigurationParams &);
139147
void onSymbolInfo(const TextDocumentPositionParams &,
140148
Callback<std::vector<SymbolDetails>>);

clang-tools-extra/clangd/ClangdServer.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -674,8 +674,31 @@ void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve,
674674
void ClangdServer::resolveTypeHierarchy(
675675
TypeHierarchyItem Item, int Resolve, TypeHierarchyDirection Direction,
676676
Callback<llvm::Optional<TypeHierarchyItem>> CB) {
677-
clangd::resolveTypeHierarchy(Item, Resolve, Direction, Index);
678-
CB(Item);
677+
WorkScheduler.run(
678+
"Resolve Type Hierarchy", "", [=, CB = std::move(CB)]() mutable {
679+
clangd::resolveTypeHierarchy(Item, Resolve, Direction, Index);
680+
CB(Item);
681+
});
682+
}
683+
684+
void ClangdServer::prepareCallHierarchy(
685+
PathRef File, Position Pos, Callback<std::vector<CallHierarchyItem>> CB) {
686+
auto Action = [File = File.str(), Pos,
687+
CB = std::move(CB)](Expected<InputsAndAST> InpAST) mutable {
688+
if (!InpAST)
689+
return CB(InpAST.takeError());
690+
CB(clangd::prepareCallHierarchy(InpAST->AST, Pos, File));
691+
};
692+
WorkScheduler.runWithAST("Call Hierarchy", File, std::move(Action));
693+
}
694+
695+
void ClangdServer::incomingCalls(
696+
const CallHierarchyItem &Item,
697+
Callback<std::vector<CallHierarchyIncomingCall>> CB) {
698+
WorkScheduler.run("Incoming Calls", "",
699+
[CB = std::move(CB), Item, this]() mutable {
700+
CB(clangd::incomingCalls(Item, Index));
701+
});
679702
}
680703

681704
void ClangdServer::onFileEvent(const DidChangeWatchedFilesParams &Params) {

clang-tools-extra/clangd/ClangdServer.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,14 @@ class ClangdServer {
242242
TypeHierarchyDirection Direction,
243243
Callback<llvm::Optional<TypeHierarchyItem>> CB);
244244

245+
/// Get information about call hierarchy for a given position.
246+
void prepareCallHierarchy(PathRef File, Position Pos,
247+
Callback<std::vector<CallHierarchyItem>> CB);
248+
249+
/// Resolve incoming calls for a given call hierarchy item.
250+
void incomingCalls(const CallHierarchyItem &Item,
251+
Callback<std::vector<CallHierarchyIncomingCall>>);
252+
245253
/// Retrieve the top symbols from the workspace matching a query.
246254
void workspaceSymbols(StringRef Query, int Limit,
247255
Callback<std::vector<SymbolInformation>> CB);

clang-tools-extra/clangd/DumpAST.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,14 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
234234
return UnaryOperator::getOpcodeStr(UO->getOpcode()).str();
235235
if (const auto *CCO = dyn_cast<CXXConstructExpr>(S))
236236
return CCO->getConstructor()->getNameAsString();
237+
if (const auto *CTE = dyn_cast<CXXThisExpr>(S)) {
238+
bool Const = CTE->getType()->getPointeeType().isLocalConstQualified();
239+
if (CTE->isImplicit())
240+
return Const ? "const, implicit" : "implicit";
241+
if (Const)
242+
return "const";
243+
return "";
244+
}
237245
if (isa<IntegerLiteral>(S) || isa<FloatingLiteral>(S) ||
238246
isa<FixedPointLiteral>(S) || isa<CharacterLiteral>(S) ||
239247
isa<ImaginaryLiteral>(S) || isa<CXXBoolLiteralExpr>(S))

clang-tools-extra/clangd/XRefs.cpp

Lines changed: 141 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "clang/Index/USRGeneration.h"
4848
#include "clang/Tooling/Syntax/Tokens.h"
4949
#include "llvm/ADT/ArrayRef.h"
50+
#include "llvm/ADT/MapVector.h"
5051
#include "llvm/ADT/None.h"
5152
#include "llvm/ADT/STLExtras.h"
5253
#include "llvm/ADT/ScopeExit.h"
@@ -1339,9 +1340,9 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LocatedSymbol &S) {
13391340
return OS;
13401341
}
13411342

1342-
// FIXME(nridge): Reduce duplication between this function and declToSym().
1343-
static llvm::Optional<TypeHierarchyItem>
1344-
declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
1343+
template <typename HierarchyItem>
1344+
static llvm::Optional<HierarchyItem> declToHierarchyItem(const NamedDecl &ND) {
1345+
ASTContext &Ctx = ND.getASTContext();
13451346
auto &SM = Ctx.getSourceManager();
13461347
SourceLocation NameLoc = nameLocation(ND, Ctx.getSourceManager());
13471348
SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc()));
@@ -1365,54 +1366,84 @@ declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) {
13651366
// correctly.
13661367
SymbolKind SK = indexSymbolKindToSymbolKind(SymInfo.Kind);
13671368

1368-
TypeHierarchyItem THI;
1369-
THI.name = printName(Ctx, ND);
1370-
THI.kind = SK;
1371-
THI.deprecated = ND.isDeprecated();
1372-
THI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
1373-
sourceLocToPosition(SM, DeclRange->getEnd())};
1374-
THI.selectionRange = Range{NameBegin, NameEnd};
1375-
if (!THI.range.contains(THI.selectionRange)) {
1369+
HierarchyItem HI;
1370+
HI.name = printName(Ctx, ND);
1371+
HI.kind = SK;
1372+
HI.range = Range{sourceLocToPosition(SM, DeclRange->getBegin()),
1373+
sourceLocToPosition(SM, DeclRange->getEnd())};
1374+
HI.selectionRange = Range{NameBegin, NameEnd};
1375+
if (!HI.range.contains(HI.selectionRange)) {
13761376
// 'selectionRange' must be contained in 'range', so in cases where clang
13771377
// reports unrelated ranges we need to reconcile somehow.
1378-
THI.range = THI.selectionRange;
1378+
HI.range = HI.selectionRange;
13791379
}
13801380

1381-
THI.uri = URIForFile::canonicalize(*FilePath, *TUPath);
1381+
HI.uri = URIForFile::canonicalize(*FilePath, *TUPath);
13821382

13831383
// Compute the SymbolID and store it in the 'data' field.
13841384
// This allows typeHierarchy/resolve to be used to
13851385
// resolve children of items returned in a previous request
13861386
// for parents.
13871387
if (auto ID = getSymbolID(&ND))
1388-
THI.data = ID.str();
1388+
HI.data = ID.str();
1389+
1390+
return HI;
1391+
}
13891392

1390-
return THI;
1393+
static llvm::Optional<TypeHierarchyItem>
1394+
declToTypeHierarchyItem(const NamedDecl &ND) {
1395+
auto Result = declToHierarchyItem<TypeHierarchyItem>(ND);
1396+
if (Result)
1397+
Result->deprecated = ND.isDeprecated();
1398+
return Result;
13911399
}
13921400

1393-
static Optional<TypeHierarchyItem>
1394-
symbolToTypeHierarchyItem(const Symbol &S, const SymbolIndex *Index,
1395-
PathRef TUPath) {
1401+
static llvm::Optional<CallHierarchyItem>
1402+
declToCallHierarchyItem(const NamedDecl &ND) {
1403+
auto Result = declToHierarchyItem<CallHierarchyItem>(ND);
1404+
if (Result && ND.isDeprecated())
1405+
Result->tags.push_back(SymbolTag::Deprecated);
1406+
return Result;
1407+
}
1408+
1409+
template <typename HierarchyItem>
1410+
static llvm::Optional<HierarchyItem> symbolToHierarchyItem(const Symbol &S,
1411+
PathRef TUPath) {
13961412
auto Loc = symbolToLocation(S, TUPath);
13971413
if (!Loc) {
1398-
log("Type hierarchy: {0}", Loc.takeError());
1414+
elog("Failed to convert symbol to hierarchy item: {0}", Loc.takeError());
13991415
return llvm::None;
14001416
}
1401-
TypeHierarchyItem THI;
1402-
THI.name = std::string(S.Name);
1403-
THI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind);
1404-
THI.deprecated = (S.Flags & Symbol::Deprecated);
1405-
THI.selectionRange = Loc->range;
1417+
HierarchyItem HI;
1418+
HI.name = std::string(S.Name);
1419+
HI.kind = indexSymbolKindToSymbolKind(S.SymInfo.Kind);
1420+
HI.selectionRange = Loc->range;
14061421
// FIXME: Populate 'range' correctly
14071422
// (https://github.com/clangd/clangd/issues/59).
1408-
THI.range = THI.selectionRange;
1409-
THI.uri = Loc->uri;
1423+
HI.range = HI.selectionRange;
1424+
HI.uri = Loc->uri;
14101425
// Store the SymbolID in the 'data' field. The client will
1411-
// send this back in typeHierarchy/resolve, allowing us to
1412-
// continue resolving additional levels of the type hierarchy.
1413-
THI.data = S.ID.str();
1426+
// send this back in requests to resolve additional levels
1427+
// of the hierarchy.
1428+
HI.data = S.ID.str();
1429+
1430+
return HI;
1431+
}
14141432

1415-
return std::move(THI);
1433+
static llvm::Optional<TypeHierarchyItem>
1434+
symbolToTypeHierarchyItem(const Symbol &S, PathRef TUPath) {
1435+
auto Result = symbolToHierarchyItem<TypeHierarchyItem>(S, TUPath);
1436+
if (Result)
1437+
Result->deprecated = (S.Flags & Symbol::Deprecated);
1438+
return Result;
1439+
}
1440+
1441+
static llvm::Optional<CallHierarchyItem>
1442+
symbolToCallHierarchyItem(const Symbol &S, PathRef TUPath) {
1443+
auto Result = symbolToHierarchyItem<CallHierarchyItem>(S, TUPath);
1444+
if (Result && (S.Flags & Symbol::Deprecated))
1445+
Result->tags.push_back(SymbolTag::Deprecated);
1446+
return Result;
14161447
}
14171448

14181449
static void fillSubTypes(const SymbolID &ID,
@@ -1423,7 +1454,7 @@ static void fillSubTypes(const SymbolID &ID,
14231454
Req.Predicate = RelationKind::BaseOf;
14241455
Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
14251456
if (Optional<TypeHierarchyItem> ChildSym =
1426-
symbolToTypeHierarchyItem(Object, Index, TUPath)) {
1457+
symbolToTypeHierarchyItem(Object, TUPath)) {
14271458
if (Levels > 1) {
14281459
ChildSym->children.emplace();
14291460
fillSubTypes(Object.ID, *ChildSym->children, Index, Levels - 1, TUPath);
@@ -1452,7 +1483,7 @@ static void fillSuperTypes(const CXXRecordDecl &CXXRD, ASTContext &ASTCtx,
14521483

14531484
for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) {
14541485
if (Optional<TypeHierarchyItem> ParentSym =
1455-
declToTypeHierarchyItem(ASTCtx, *ParentDecl)) {
1486+
declToTypeHierarchyItem(*ParentDecl)) {
14561487
ParentSym->parents.emplace();
14571488
fillSuperTypes(*ParentDecl, ASTCtx, *ParentSym->parents, RPSet);
14581489
SuperTypes.emplace_back(std::move(*ParentSym));
@@ -1574,8 +1605,7 @@ getTypeHierarchy(ParsedAST &AST, Position Pos, int ResolveLevels,
15741605
CXXRD = CTSD->getTemplateInstantiationPattern();
15751606
}
15761607

1577-
Optional<TypeHierarchyItem> Result =
1578-
declToTypeHierarchyItem(AST.getASTContext(), *CXXRD);
1608+
Optional<TypeHierarchyItem> Result = declToTypeHierarchyItem(*CXXRD);
15791609
if (!Result)
15801610
return Result;
15811611

@@ -1617,6 +1647,83 @@ void resolveTypeHierarchy(TypeHierarchyItem &Item, int ResolveLevels,
16171647
}
16181648
}
16191649

1650+
std::vector<CallHierarchyItem>
1651+
prepareCallHierarchy(ParsedAST &AST, Position Pos, PathRef TUPath) {
1652+
std::vector<CallHierarchyItem> Result;
1653+
const auto &SM = AST.getSourceManager();
1654+
auto Loc = sourceLocationInMainFile(SM, Pos);
1655+
if (!Loc) {
1656+
elog("prepareCallHierarchy failed to convert position to source location: "
1657+
"{0}",
1658+
Loc.takeError());
1659+
return Result;
1660+
}
1661+
for (const NamedDecl *Decl : getDeclAtPosition(AST, *Loc, {})) {
1662+
if (!Decl->isFunctionOrFunctionTemplate())
1663+
continue;
1664+
if (auto CHI = declToCallHierarchyItem(*Decl))
1665+
Result.emplace_back(std::move(*CHI));
1666+
}
1667+
return Result;
1668+
}
1669+
1670+
std::vector<CallHierarchyIncomingCall>
1671+
incomingCalls(const CallHierarchyItem &Item, const SymbolIndex *Index) {
1672+
std::vector<CallHierarchyIncomingCall> Results;
1673+
if (!Index || Item.data.empty())
1674+
return Results;
1675+
auto ID = SymbolID::fromStr(Item.data);
1676+
if (!ID) {
1677+
elog("incomingCalls failed to find symbol: {0}", ID.takeError());
1678+
return Results;
1679+
}
1680+
// In this function, we find incoming calls based on the index only.
1681+
// In principle, the AST could have more up-to-date information about
1682+
// occurrences within the current file. However, going from a SymbolID
1683+
// to an AST node isn't cheap, particularly when the declaration isn't
1684+
// in the main file.
1685+
// FIXME: Consider also using AST information when feasible.
1686+
RefsRequest Request;
1687+
Request.IDs.insert(*ID);
1688+
// We could restrict more specifically to calls by introducing a new RefKind,
1689+
// but non-call references (such as address-of-function) can still be
1690+
// interesting as they can indicate indirect calls.
1691+
Request.Filter = RefKind::Reference;
1692+
// Initially store the ranges in a map keyed by SymbolID of the caller.
1693+
// This allows us to group different calls with the same caller
1694+
// into the same CallHierarchyIncomingCall.
1695+
llvm::DenseMap<SymbolID, std::vector<Range>> CallsIn;
1696+
// We can populate the ranges based on a refs request only. As we do so, we
1697+
// also accumulate the container IDs into a lookup request.
1698+
LookupRequest ContainerLookup;
1699+
Index->refs(Request, [&](const Ref &R) {
1700+
auto Loc = indexToLSPLocation(R.Location, Item.uri.file());
1701+
if (!Loc) {
1702+
elog("incomingCalls failed to convert location: {0}", Loc.takeError());
1703+
return;
1704+
}
1705+
auto It = CallsIn.try_emplace(R.Container, std::vector<Range>{}).first;
1706+
It->second.push_back(Loc->range);
1707+
1708+
ContainerLookup.IDs.insert(R.Container);
1709+
});
1710+
// Perform the lookup request and combine its results with CallsIn to
1711+
// get complete CallHierarchyIncomingCall objects.
1712+
Index->lookup(ContainerLookup, [&](const Symbol &Caller) {
1713+
auto It = CallsIn.find(Caller.ID);
1714+
assert(It != CallsIn.end());
1715+
if (auto CHI = symbolToCallHierarchyItem(Caller, Item.uri.file()))
1716+
Results.push_back(
1717+
CallHierarchyIncomingCall{std::move(*CHI), std::move(It->second)});
1718+
});
1719+
// Sort results by name of container.
1720+
llvm::sort(Results, [](const CallHierarchyIncomingCall &A,
1721+
const CallHierarchyIncomingCall &B) {
1722+
return A.from.name < B.from.name;
1723+
});
1724+
return Results;
1725+
}
1726+
16201727
llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
16211728
const FunctionDecl *FD) {
16221729
if (!FD->hasBody())

0 commit comments

Comments
 (0)