Skip to content

Commit

Permalink
Merge from 'master' to 'sycl-web' (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
bader committed Feb 26, 2020
2 parents 7003df1 + 465dca7 commit 36b0516
Show file tree
Hide file tree
Showing 296 changed files with 12,554 additions and 2,921 deletions.
9 changes: 5 additions & 4 deletions clang-tools-extra/clangd/ClangdLSPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -761,7 +761,7 @@ void ClangdLSPServer::onWorkspaceSymbol(
void ClangdLSPServer::onPrepareRename(const TextDocumentPositionParams &Params,
Callback<llvm::Optional<Range>> Reply) {
Server->prepareRename(Params.textDocument.uri.file(), Params.position,
std::move(Reply));
RenameOpts, std::move(Reply));
}

void ClangdLSPServer::onRename(const RenameParams &Params,
Expand All @@ -772,8 +772,7 @@ void ClangdLSPServer::onRename(const RenameParams &Params,
return Reply(llvm::make_error<LSPError>(
"onRename called for non-added file", ErrorCode::InvalidParams));
Server->rename(
File, Params.position, Params.newName,
/*WantFormat=*/true,
File, Params.position, Params.newName, RenameOpts,
[File, Params, Reply = std::move(Reply),
this](llvm::Expected<FileEdits> Edits) mutable {
if (!Edits)
Expand Down Expand Up @@ -1230,12 +1229,14 @@ void ClangdLSPServer::onDocumentLink(
ClangdLSPServer::ClangdLSPServer(
class Transport &Transp, const FileSystemProvider &FSProvider,
const clangd::CodeCompleteOptions &CCOpts,
const clangd::RenameOptions &RenameOpts,
llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
const ClangdServer::Options &Opts)
: BackgroundContext(Context::current().clone()), Transp(Transp),
MsgHandler(new MessageHandler(*this)), FSProvider(FSProvider),
CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()),
CCOpts(CCOpts), RenameOpts(RenameOpts),
SupportedSymbolKinds(defaultSymbolKinds()),
SupportedCompletionItemKinds(defaultCompletionItemKinds()),
UseDirBasedCDB(UseDirBasedCDB),
CompileCommandsDir(std::move(CompileCommandsDir)), ClangdServerOpts(Opts),
Expand Down
3 changes: 3 additions & 0 deletions clang-tools-extra/clangd/ClangdLSPServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
// FIXME: Clean up signature around CDBs.
ClangdLSPServer(Transport &Transp, const FileSystemProvider &FSProvider,
const clangd::CodeCompleteOptions &CCOpts,
const clangd::RenameOptions &RenameOpts,
llvm::Optional<Path> CompileCommandsDir, bool UseDirBasedCDB,
llvm::Optional<OffsetEncoding> ForcedOffsetEncoding,
const ClangdServer::Options &Opts);
Expand Down Expand Up @@ -197,6 +198,8 @@ class ClangdLSPServer : private ClangdServer::Callbacks {
const FileSystemProvider &FSProvider;
/// Options used for code completion
clangd::CodeCompleteOptions CCOpts;
/// Options used for rename.
clangd::RenameOptions RenameOpts;
/// Options used for diagnostics.
ClangdDiagnosticOptions DiagOpts;
/// The supported kinds of the client.
Expand Down
29 changes: 18 additions & 11 deletions clang-tools-extra/clangd/ClangdServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB,
: nullptr),
GetClangTidyOptions(Opts.GetClangTidyOptions),
SuggestMissingIncludes(Opts.SuggestMissingIncludes),
CrossFileRename(Opts.CrossFileRename), TweakFilter(Opts.TweakFilter),
WorkspaceRoot(Opts.WorkspaceRoot),
TweakFilter(Opts.TweakFilter), WorkspaceRoot(Opts.WorkspaceRoot),
// Pass a callback into `WorkScheduler` to extract symbols from a newly
// parsed file and rebuild the file index synchronously each time an AST
// is parsed.
Expand Down Expand Up @@ -319,8 +318,9 @@ ClangdServer::formatOnType(llvm::StringRef Code, PathRef File, Position Pos,
}

void ClangdServer::prepareRename(PathRef File, Position Pos,
const RenameOptions &RenameOpts,
Callback<llvm::Optional<Range>> CB) {
auto Action = [Pos, File = File.str(), CB = std::move(CB),
auto Action = [Pos, File = File.str(), CB = std::move(CB), RenameOpts,
this](llvm::Expected<InputsAndAST> InpAST) mutable {
if (!InpAST)
return CB(InpAST.takeError());
Expand All @@ -338,14 +338,13 @@ void ClangdServer::prepareRename(PathRef File, Position Pos,
SM, CharSourceRange::getCharRange(TouchingIdentifier->location(),
TouchingIdentifier->endLocation()));

if (CrossFileRename)
if (RenameOpts.AllowCrossFile)
// FIXME: we now assume cross-file rename always succeeds, revisit this.
return CB(Range);

// Performing the local rename isn't substantially more expensive than
// doing an AST-based check, so we just rename and throw away the results.
auto Changes = clangd::rename({Pos, "dummy", AST, File, Index,
/*AllowCrossFile=*/false,
auto Changes = clangd::rename({Pos, "dummy", AST, File, Index, RenameOpts,
/*GetDirtyBuffer=*/nullptr});
if (!Changes) {
// LSP says to return null on failure, but that will result in a generic
Expand All @@ -359,10 +358,10 @@ void ClangdServer::prepareRename(PathRef File, Position Pos,
}

void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
bool WantFormat, Callback<FileEdits> CB) {
const RenameOptions &Opts, Callback<FileEdits> CB) {
// A snapshot of all file dirty buffers.
llvm::StringMap<std::string> Snapshot = WorkScheduler.getAllFileContents();
auto Action = [File = File.str(), NewName = NewName.str(), Pos, WantFormat,
auto Action = [File = File.str(), NewName = NewName.str(), Pos, Opts,
CB = std::move(CB), Snapshot = std::move(Snapshot),
this](llvm::Expected<InputsAndAST> InpAST) mutable {
if (!InpAST)
Expand All @@ -374,12 +373,12 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
return llvm::None;
return It->second;
};
auto Edits = clangd::rename({Pos, NewName, InpAST->AST, File, Index,
CrossFileRename, GetDirtyBuffer});
auto Edits = clangd::rename(
{Pos, NewName, InpAST->AST, File, Index, Opts, GetDirtyBuffer});
if (!Edits)
return CB(Edits.takeError());

if (WantFormat) {
if (Opts.WantFormat) {
auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents,
InpAST->Inputs.FS.get());
llvm::Error Err = llvm::Error::success();
Expand All @@ -395,6 +394,14 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
WorkScheduler.runWithAST("Rename", File, std::move(Action));
}

void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
bool WantFormat, Callback<FileEdits> CB) {
RenameOptions Opts;
Opts.WantFormat = WantFormat;
Opts.AllowCrossFile = false;
rename(File, Pos, NewName, Opts, std::move(CB));
}

// May generate several candidate selections, due to SelectionTree ambiguity.
// vector of pointers because GCC doesn't like non-copyable Selection.
static llvm::Expected<std::vector<std::unique_ptr<Tweak::Selection>>>
Expand Down
9 changes: 4 additions & 5 deletions clang-tools-extra/clangd/ClangdServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,9 +145,6 @@ class ClangdServer {
/// Enable semantic highlighting features.
bool SemanticHighlighting = false;

/// Enable cross-file rename feature.
bool CrossFileRename = false;

/// Returns true if the tweak should be enabled.
std::function<bool(const Tweak &)> TweakFilter = [](const Tweak &T) {
return !T.hidden(); // only enable non-hidden tweaks.
Expand Down Expand Up @@ -257,13 +254,17 @@ class ClangdServer {

/// Test the validity of a rename operation.
void prepareRename(PathRef File, Position Pos,
const RenameOptions &RenameOpts,
Callback<llvm::Optional<Range>> CB);

/// Rename all occurrences of the symbol at the \p Pos in \p File to
/// \p NewName.
/// If WantFormat is false, the final TextEdit will be not formatted,
/// embedders could use this method to get all occurrences of the symbol (e.g.
/// highlighting them in prepare stage).
void rename(PathRef File, Position Pos, llvm::StringRef NewName,
const RenameOptions &Opts, Callback<FileEdits> CB);
// FIXME: remove this compatibility method in favor above.
void rename(PathRef File, Position Pos, llvm::StringRef NewName,
bool WantFormat, Callback<FileEdits> CB);

Expand Down Expand Up @@ -343,8 +344,6 @@ class ClangdServer {
// can be caused by missing includes (e.g. member access in incomplete type).
bool SuggestMissingIncludes = false;

bool CrossFileRename = false;

std::function<bool(const Tweak &)> TweakFilter;

// GUARDED_BY(CachedCompletionFuzzyFindRequestMutex)
Expand Down
123 changes: 71 additions & 52 deletions clang-tools-extra/clangd/XRefs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

Expand Down Expand Up @@ -214,24 +215,34 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
}
}

auto CurLoc = sourceLocationInMainFile(SM, Pos);
if (!CurLoc) {
elog("locateSymbolAt failed to convert position to source location: {0}",
CurLoc.takeError());
return {};
}

// Macros are simple: there's no declaration/definition distinction.
// As a consequence, there's no need to look them up in the index either.
SourceLocation IdentStartLoc = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, AST.getSourceManager(), AST.getLangOpts()));
std::vector<LocatedSymbol> Result;
if (auto M = locateMacroAt(IdentStartLoc, AST.getPreprocessor())) {
if (auto Loc = makeLocation(AST.getASTContext(),
M->Info->getDefinitionLoc(), *MainFilePath)) {
LocatedSymbol Macro;
Macro.Name = std::string(M->Name);
Macro.PreferredDeclaration = *Loc;
Macro.Definition = Loc;
Result.push_back(std::move(Macro));

// Don't look at the AST or index if we have a macro result.
// (We'd just return declarations referenced from the macro's
// expansion.)
return Result;
const auto *TouchedIdentifier =
syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
if (TouchedIdentifier) {
if (auto M = locateMacroAt(TouchedIdentifier->location(),
AST.getPreprocessor())) {
if (auto Loc = makeLocation(AST.getASTContext(),
M->Info->getDefinitionLoc(), *MainFilePath)) {
LocatedSymbol Macro;
Macro.Name = std::string(M->Name);
Macro.PreferredDeclaration = *Loc;
Macro.Definition = Loc;
Result.push_back(std::move(Macro));

// Don't look at the AST or index if we have a macro result.
// (We'd just return declarations referenced from the macro's
// expansion.)
return Result;
}
}
}

Expand All @@ -244,15 +255,6 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
// Keep track of SymbolID -> index mapping, to fill in index data later.
llvm::DenseMap<SymbolID, size_t> ResultIndex;

SourceLocation SourceLoc;
if (auto L = sourceLocationInMainFile(SM, Pos)) {
SourceLoc = *L;
} else {
elog("locateSymbolAt failed to convert position to source location: {0}",
L.takeError());
return Result;
}

auto AddResultDecl = [&](const NamedDecl *D) {
const NamedDecl *Def = getDefinition(D);
const NamedDecl *Preferred = Def ? Def : D;
Expand All @@ -277,16 +279,15 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,
// Emit all symbol locations (declaration or definition) from AST.
DeclRelationSet Relations =
DeclRelation::TemplatePattern | DeclRelation::Alias;
for (const NamedDecl *D : getDeclAtPosition(AST, SourceLoc, Relations)) {
for (const NamedDecl *D : getDeclAtPosition(AST, *CurLoc, Relations)) {
// Special case: void foo() ^override: jump to the overridden method.
if (const auto *CMD = llvm::dyn_cast<CXXMethodDecl>(D)) {
const InheritableAttr* Attr = D->getAttr<OverrideAttr>();
const InheritableAttr *Attr = D->getAttr<OverrideAttr>();
if (!Attr)
Attr = D->getAttr<FinalAttr>();
const syntax::Token *Tok =
spelledIdentifierTouching(SourceLoc, AST.getTokens());
if (Attr && Tok &&
SM.getSpellingLoc(Attr->getLocation()) == Tok->location()) {
if (Attr && TouchedIdentifier &&
SM.getSpellingLoc(Attr->getLocation()) ==
TouchedIdentifier->location()) {
// We may be overridding multiple methods - offer them all.
for (const NamedDecl *ND : CMD->overridden_methods())
AddResultDecl(ND);
Expand All @@ -296,8 +297,9 @@ std::vector<LocatedSymbol> locateSymbolAt(ParsedAST &AST, Position Pos,

// Special case: the point of declaration of a template specialization,
// it's more useful to navigate to the template declaration.
if (SM.getMacroArgExpandedLocation(D->getLocation()) == IdentStartLoc) {
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
if (TouchedIdentifier &&
D->getLocation() == TouchedIdentifier->location()) {
AddResultDecl(CTSD->getSpecializedTemplate());
continue;
}
Expand Down Expand Up @@ -416,12 +418,12 @@ std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
// FIXME: show references to macro within file?
DeclRelationSet Relations =
DeclRelation::TemplatePattern | DeclRelation::Alias;
auto References = findRefs(
getDeclAtPosition(AST,
SM.getMacroArgExpandedLocation(getBeginningOfIdentifier(
Pos, SM, AST.getLangOpts())),
Relations),
AST);
auto CurLoc = sourceLocationInMainFile(SM, Pos);
if (!CurLoc) {
llvm::consumeError(CurLoc.takeError());
return {};
}
auto References = findRefs(getDeclAtPosition(AST, *CurLoc, Relations), AST);

// FIXME: we may get multiple DocumentHighlights with the same location and
// different kinds, deduplicate them.
Expand Down Expand Up @@ -456,11 +458,18 @@ ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
return Results;
}
auto URIMainFile = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
auto Loc = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
auto CurLoc = sourceLocationInMainFile(SM, Pos);
if (!CurLoc) {
llvm::consumeError(CurLoc.takeError());
return {};
}
SourceLocation SLocId;
if (const auto *IdentifierAtCursor =
syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens()))
SLocId = IdentifierAtCursor->location();
RefsRequest Req;

if (auto Macro = locateMacroAt(Loc, AST.getPreprocessor())) {
if (auto Macro = locateMacroAt(SLocId, AST.getPreprocessor())) {
// Handle references to macro.
if (auto MacroSID = getSymbolID(Macro->Name, Macro->Info, SM)) {
// Collect macro references from main file.
Expand All @@ -483,7 +492,7 @@ ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
// DeclRelation::Underlying.
DeclRelationSet Relations = DeclRelation::TemplatePattern |
DeclRelation::Alias | DeclRelation::Underlying;
auto Decls = getDeclAtPosition(AST, Loc, Relations);
auto Decls = getDeclAtPosition(AST, *CurLoc, Relations);

// We traverse the AST to find references in the main file.
auto MainFileRefs = findRefs(Decls, AST);
Expand Down Expand Up @@ -541,16 +550,19 @@ ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,

std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
const SourceManager &SM = AST.getSourceManager();
auto Loc = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
auto CurLoc = sourceLocationInMainFile(SM, Pos);
if (!CurLoc) {
llvm::consumeError(CurLoc.takeError());
return {};
}

std::vector<SymbolDetails> Results;

// We also want the targets of using-decls, so we include
// DeclRelation::Underlying.
DeclRelationSet Relations = DeclRelation::TemplatePattern |
DeclRelation::Alias | DeclRelation::Underlying;
for (const NamedDecl *D : getDeclAtPosition(AST, Loc, Relations)) {
for (const NamedDecl *D : getDeclAtPosition(AST, *CurLoc, Relations)) {
SymbolDetails NewSymbol;
std::string QName = printQualifiedName(*D);
auto SplitQName = splitQualifiedName(QName);
Expand All @@ -570,7 +582,13 @@ std::vector<SymbolDetails> getSymbolInfo(ParsedAST &AST, Position Pos) {
Results.push_back(std::move(NewSymbol));
}

if (auto M = locateMacroAt(Loc, AST.getPreprocessor())) {
const auto *IdentifierAtCursor =
syntax::spelledIdentifierTouching(*CurLoc, AST.getTokens());
if (!IdentifierAtCursor)
return Results;

if (auto M = locateMacroAt(IdentifierAtCursor->location(),
AST.getPreprocessor())) {
SymbolDetails NewMacro;
NewMacro.name = std::string(M->Name);
llvm::SmallString<32> USR;
Expand Down Expand Up @@ -747,17 +765,18 @@ const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos) {
};

const SourceManager &SM = AST.getSourceManager();
SourceLocation SourceLocationBeg = SM.getMacroArgExpandedLocation(
getBeginningOfIdentifier(Pos, SM, AST.getLangOpts()));
unsigned Offset = SM.getDecomposedSpellingLoc(SourceLocationBeg).second;
const CXXRecordDecl *Result = nullptr;
SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), Offset,
Offset, [&](SelectionTree ST) {
auto Offset = positionToOffset(SM.getBufferData(SM.getMainFileID()), Pos);
if (!Offset) {
llvm::consumeError(Offset.takeError());
return Result;
}
SelectionTree::createEach(AST.getASTContext(), AST.getTokens(), *Offset,
*Offset, [&](SelectionTree ST) {
Result = RecordFromNode(ST.commonAncestor());
return Result != nullptr;
});
return Result;

}

std::vector<const CXXRecordDecl *> typeParents(const CXXRecordDecl *CXXRD) {
Expand Down
Loading

0 comments on commit 36b0516

Please sign in to comment.