summaryrefslogtreecommitdiffstats
path: root/clang-tools-extra/clangd/XRefs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tools-extra/clangd/XRefs.cpp')
-rw-r--r--clang-tools-extra/clangd/XRefs.cpp537
1 files changed, 0 insertions, 537 deletions
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 3165633e60f..de10e3c48e2 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -10,7 +10,6 @@
#include "CodeCompletionStrings.h"
#include "FindSymbols.h"
#include "FindTarget.h"
-#include "FormattedString.h"
#include "Logger.h"
#include "ParsedAST.h"
#include "Protocol.h"
@@ -20,15 +19,12 @@
#include "index/Index.h"
#include "index/Merge.h"
#include "index/Relation.h"
-#include "index/SymbolCollector.h"
#include "index/SymbolLocation.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/ExprCXX.h"
-#include "clang/AST/PrettyPrinter.h"
-#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
@@ -44,7 +40,6 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
-#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
@@ -396,500 +391,6 @@ std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
return Result;
}
-static PrintingPolicy printingPolicyForDecls(PrintingPolicy Base) {
- PrintingPolicy Policy(Base);
-
- Policy.AnonymousTagLocations = false;
- Policy.TerseOutput = true;
- Policy.PolishForDeclaration = true;
- Policy.ConstantsAsWritten = true;
- Policy.SuppressTagKeyword = false;
-
- return Policy;
-}
-
-/// Given a declaration \p D, return a human-readable string representing the
-/// local scope in which it is declared, i.e. class(es) and method name. Returns
-/// an empty string if it is not local.
-static std::string getLocalScope(const Decl *D) {
- std::vector<std::string> Scopes;
- const DeclContext *DC = D->getDeclContext();
- auto GetName = [](const TypeDecl *D) {
- if (!D->getDeclName().isEmpty()) {
- PrintingPolicy Policy = D->getASTContext().getPrintingPolicy();
- Policy.SuppressScope = true;
- return declaredType(D).getAsString(Policy);
- }
- if (auto RD = dyn_cast<RecordDecl>(D))
- return ("(anonymous " + RD->getKindName() + ")").str();
- return std::string("");
- };
- while (DC) {
- if (const TypeDecl *TD = dyn_cast<TypeDecl>(DC))
- Scopes.push_back(GetName(TD));
- else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC))
- Scopes.push_back(FD->getNameAsString());
- DC = DC->getParent();
- }
-
- return llvm::join(llvm::reverse(Scopes), "::");
-}
-
-/// Returns the human-readable representation for namespace containing the
-/// declaration \p D. Returns empty if it is contained global namespace.
-static std::string getNamespaceScope(const Decl *D) {
- const DeclContext *DC = D->getDeclContext();
-
- if (const TypeDecl *TD = dyn_cast<TypeDecl>(DC))
- return getNamespaceScope(TD);
- if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC))
- return getNamespaceScope(FD);
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
- return ND->getQualifiedNameAsString();
-
- return "";
-}
-
-static std::string printDefinition(const Decl *D) {
- std::string Definition;
- llvm::raw_string_ostream OS(Definition);
- PrintingPolicy Policy =
- printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
- Policy.IncludeTagDefinition = false;
- Policy.SuppressTemplateArgsInCXXConstructors = true;
- D->print(OS, Policy);
- OS.flush();
- return Definition;
-}
-
-static void printParams(llvm::raw_ostream &OS,
- const std::vector<HoverInfo::Param> &Params) {
- for (size_t I = 0, E = Params.size(); I != E; ++I) {
- if (I)
- OS << ", ";
- OS << Params.at(I);
- }
-}
-
-static std::vector<HoverInfo::Param>
-fetchTemplateParameters(const TemplateParameterList *Params,
- const PrintingPolicy &PP) {
- assert(Params);
- std::vector<HoverInfo::Param> TempParameters;
-
- for (const Decl *Param : *Params) {
- HoverInfo::Param P;
- P.Type.emplace();
- if (const auto TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
- P.Type = TTP->wasDeclaredWithTypename() ? "typename" : "class";
- if (TTP->isParameterPack())
- *P.Type += "...";
-
- if (!TTP->getName().empty())
- P.Name = TTP->getNameAsString();
- if (TTP->hasDefaultArgument())
- P.Default = TTP->getDefaultArgument().getAsString(PP);
- } else if (const auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
- if (IdentifierInfo *II = NTTP->getIdentifier())
- P.Name = II->getName().str();
-
- llvm::raw_string_ostream Out(*P.Type);
- NTTP->getType().print(Out, PP);
- if (NTTP->isParameterPack())
- Out << "...";
-
- if (NTTP->hasDefaultArgument()) {
- P.Default.emplace();
- llvm::raw_string_ostream Out(*P.Default);
- NTTP->getDefaultArgument()->printPretty(Out, nullptr, PP);
- }
- } else if (const auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
- llvm::raw_string_ostream OS(*P.Type);
- OS << "template <";
- printParams(OS,
- fetchTemplateParameters(TTPD->getTemplateParameters(), PP));
- OS << "> class"; // FIXME: TemplateTemplateParameter doesn't store the
- // info on whether this param was a "typename" or
- // "class".
- if (!TTPD->getName().empty())
- P.Name = TTPD->getNameAsString();
- if (TTPD->hasDefaultArgument()) {
- P.Default.emplace();
- llvm::raw_string_ostream Out(*P.Default);
- TTPD->getDefaultArgument().getArgument().print(PP, Out);
- }
- }
- TempParameters.push_back(std::move(P));
- }
-
- return TempParameters;
-}
-
-static const FunctionDecl *getUnderlyingFunction(const Decl *D) {
- // Extract lambda from variables.
- if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D)) {
- auto QT = VD->getType();
- if (!QT.isNull()) {
- while (!QT->getPointeeType().isNull())
- QT = QT->getPointeeType();
-
- if (const auto *CD = QT->getAsCXXRecordDecl())
- return CD->getLambdaCallOperator();
- }
- }
-
- // Non-lambda functions.
- return D->getAsFunction();
-}
-
-// Look up information about D from the index, and add it to Hover.
-static void enhanceFromIndex(HoverInfo &Hover, const Decl *D,
- const SymbolIndex *Index) {
- if (!Index || !llvm::isa<NamedDecl>(D))
- return;
- const NamedDecl &ND = *cast<NamedDecl>(D);
- // We only add documentation, so don't bother if we already have some.
- if (!Hover.Documentation.empty())
- return;
- // Skip querying for non-indexable symbols, there's no point.
- // We're searching for symbols that might be indexed outside this main file.
- if (!SymbolCollector::shouldCollectSymbol(ND, ND.getASTContext(),
- SymbolCollector::Options(),
- /*IsMainFileOnly=*/false))
- return;
- auto ID = getSymbolID(&ND);
- if (!ID)
- return;
- LookupRequest Req;
- Req.IDs.insert(*ID);
- Index->lookup(
- Req, [&](const Symbol &S) { Hover.Documentation = S.Documentation; });
-}
-
-// Populates Type, ReturnType, and Parameters for function-like decls.
-static void fillFunctionTypeAndParams(HoverInfo &HI, const Decl *D,
- const FunctionDecl *FD,
- const PrintingPolicy &Policy) {
- HI.Parameters.emplace();
- for (const ParmVarDecl *PVD : FD->parameters()) {
- HI.Parameters->emplace_back();
- auto &P = HI.Parameters->back();
- if (!PVD->getType().isNull()) {
- P.Type.emplace();
- llvm::raw_string_ostream OS(*P.Type);
- PVD->getType().print(OS, Policy);
- } else {
- std::string Param;
- llvm::raw_string_ostream OS(Param);
- PVD->dump(OS);
- OS.flush();
- elog("Got param with null type: {0}", Param);
- }
- if (!PVD->getName().empty())
- P.Name = PVD->getNameAsString();
- if (PVD->hasDefaultArg()) {
- P.Default.emplace();
- llvm::raw_string_ostream Out(*P.Default);
- PVD->getDefaultArg()->printPretty(Out, nullptr, Policy);
- }
- }
-
- if (const auto* CCD = llvm::dyn_cast<CXXConstructorDecl>(FD)) {
- // Constructor's "return type" is the class type.
- HI.ReturnType = declaredType(CCD->getParent()).getAsString(Policy);
- // Don't provide any type for the constructor itself.
- } else if (const auto* CDD = llvm::dyn_cast<CXXDestructorDecl>(FD)){
- HI.ReturnType = "void";
- } else {
- HI.ReturnType = FD->getReturnType().getAsString(Policy);
-
- QualType FunctionType = FD->getType();
- if (const VarDecl *VD = llvm::dyn_cast<VarDecl>(D)) // Lambdas
- FunctionType = VD->getType().getDesugaredType(D->getASTContext());
- HI.Type = FunctionType.getAsString(Policy);
- }
- // FIXME: handle variadics.
-}
-
-/// Generate a \p Hover object given the declaration \p D.
-static HoverInfo getHoverContents(const Decl *D, const SymbolIndex *Index) {
- HoverInfo HI;
- const ASTContext &Ctx = D->getASTContext();
-
- HI.NamespaceScope = getNamespaceScope(D);
- if (!HI.NamespaceScope->empty())
- HI.NamespaceScope->append("::");
- HI.LocalScope = getLocalScope(D);
- if (!HI.LocalScope.empty())
- HI.LocalScope.append("::");
-
- PrintingPolicy Policy = printingPolicyForDecls(Ctx.getPrintingPolicy());
- if (const NamedDecl *ND = llvm::dyn_cast<NamedDecl>(D)) {
- HI.Documentation = getDeclComment(Ctx, *ND);
- HI.Name = printName(Ctx, *ND);
- }
-
- HI.Kind = indexSymbolKindToSymbolKind(index::getSymbolInfo(D).Kind);
-
- // Fill in template params.
- if (const TemplateDecl *TD = D->getDescribedTemplate()) {
- HI.TemplateParameters =
- fetchTemplateParameters(TD->getTemplateParameters(), Policy);
- D = TD;
- } else if (const FunctionDecl *FD = D->getAsFunction()) {
- if (const auto FTD = FD->getDescribedTemplate()) {
- HI.TemplateParameters =
- fetchTemplateParameters(FTD->getTemplateParameters(), Policy);
- D = FTD;
- }
- }
-
- // Fill in types and params.
- if (const FunctionDecl *FD = getUnderlyingFunction(D)) {
- fillFunctionTypeAndParams(HI, D, FD, Policy);
- } else if (const auto *VD = dyn_cast<ValueDecl>(D)) {
- HI.Type.emplace();
- llvm::raw_string_ostream OS(*HI.Type);
- VD->getType().print(OS, Policy);
- }
-
- // Fill in value with evaluated initializer if possible.
- // FIXME(kadircet): Also set Value field for expressions like "sizeof" and
- // function calls.
- if (const auto *Var = dyn_cast<VarDecl>(D)) {
- if (const Expr *Init = Var->getInit()) {
- Expr::EvalResult Result;
- if (!Init->isValueDependent() && Init->EvaluateAsRValue(Result, Ctx)) {
- HI.Value.emplace();
- llvm::raw_string_ostream ValueOS(*HI.Value);
- Result.Val.printPretty(ValueOS, const_cast<ASTContext &>(Ctx),
- Init->getType());
- }
- }
- } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
- // Dependent enums (e.g. nested in template classes) don't have values yet.
- if (!ECD->getType()->isDependentType())
- HI.Value = ECD->getInitVal().toString(10);
- }
-
- HI.Definition = printDefinition(D);
- enhanceFromIndex(HI, D, Index);
- return HI;
-}
-
-/// Generate a \p Hover object given the type \p T.
-static HoverInfo getHoverContents(QualType T, const Decl *D, ASTContext &ASTCtx,
- const SymbolIndex *Index) {
- HoverInfo HI;
- llvm::raw_string_ostream OS(HI.Name);
- PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
- T.print(OS, Policy);
- OS.flush();
-
- if (D) {
- HI.Kind = indexSymbolKindToSymbolKind(index::getSymbolInfo(D).Kind);
- enhanceFromIndex(HI, D, Index);
- }
- return HI;
-}
-
-/// Generate a \p Hover object given the macro \p MacroDecl.
-static HoverInfo getHoverContents(const DefinedMacro &Macro, ParsedAST &AST) {
- HoverInfo HI;
- SourceManager &SM = AST.getSourceManager();
- HI.Name = Macro.Name;
- HI.Kind = indexSymbolKindToSymbolKind(
- index::getSymbolInfoForMacro(*Macro.Info).Kind);
- // FIXME: Populate documentation
- // FIXME: Pupulate parameters
-
- // Try to get the full definition, not just the name
- SourceLocation StartLoc = Macro.Info->getDefinitionLoc();
- SourceLocation EndLoc = Macro.Info->getDefinitionEndLoc();
- if (EndLoc.isValid()) {
- EndLoc = Lexer::getLocForEndOfToken(EndLoc, 0, SM,
- AST.getASTContext().getLangOpts());
- bool Invalid;
- StringRef Buffer = SM.getBufferData(SM.getFileID(StartLoc), &Invalid);
- if (!Invalid) {
- unsigned StartOffset = SM.getFileOffset(StartLoc);
- unsigned EndOffset = SM.getFileOffset(EndLoc);
- if (EndOffset <= Buffer.size() && StartOffset < EndOffset)
- HI.Definition =
- ("#define " + Buffer.substr(StartOffset, EndOffset - StartOffset))
- .str();
- }
- }
- return HI;
-}
-
-namespace {
-/// Computes the deduced type at a given location by visiting the relevant
-/// nodes. We use this to display the actual type when hovering over an "auto"
-/// keyword or "decltype()" expression.
-/// FIXME: This could have been a lot simpler by visiting AutoTypeLocs but it
-/// seems that the AutoTypeLocs that can be visited along with their AutoType do
-/// not have the deduced type set. Instead, we have to go to the appropriate
-/// DeclaratorDecl/FunctionDecl and work our back to the AutoType that does have
-/// a deduced type set. The AST should be improved to simplify this scenario.
-class DeducedTypeVisitor : public RecursiveASTVisitor<DeducedTypeVisitor> {
- SourceLocation SearchedLocation;
-
-public:
- DeducedTypeVisitor(SourceLocation SearchedLocation)
- : SearchedLocation(SearchedLocation) {}
-
- // Handle auto initializers:
- //- auto i = 1;
- //- decltype(auto) i = 1;
- //- auto& i = 1;
- //- auto* i = &a;
- bool VisitDeclaratorDecl(DeclaratorDecl *D) {
- if (!D->getTypeSourceInfo() ||
- D->getTypeSourceInfo()->getTypeLoc().getBeginLoc() != SearchedLocation)
- return true;
-
- if (auto *AT = D->getType()->getContainedAutoType()) {
- if (!AT->getDeducedType().isNull()) {
- DeducedType = AT->getDeducedType();
- this->D = D;
- }
- }
- return true;
- }
-
- // Handle auto return types:
- //- auto foo() {}
- //- auto& foo() {}
- //- auto foo() -> int {}
- //- auto foo() -> decltype(1+1) {}
- //- operator auto() const { return 10; }
- bool VisitFunctionDecl(FunctionDecl *D) {
- if (!D->getTypeSourceInfo())
- return true;
- // Loc of auto in return type (c++14).
- auto CurLoc = D->getReturnTypeSourceRange().getBegin();
- // Loc of "auto" in operator auto()
- if (CurLoc.isInvalid() && dyn_cast<CXXConversionDecl>(D))
- CurLoc = D->getTypeSourceInfo()->getTypeLoc().getBeginLoc();
- // Loc of "auto" in function with traling return type (c++11).
- if (CurLoc.isInvalid())
- CurLoc = D->getSourceRange().getBegin();
- if (CurLoc != SearchedLocation)
- return true;
-
- const AutoType *AT = D->getReturnType()->getContainedAutoType();
- if (AT && !AT->getDeducedType().isNull()) {
- DeducedType = AT->getDeducedType();
- this->D = D;
- } else if (auto DT = dyn_cast<DecltypeType>(D->getReturnType())) {
- // auto in a trailing return type just points to a DecltypeType and
- // getContainedAutoType does not unwrap it.
- if (!DT->getUnderlyingType().isNull()) {
- DeducedType = DT->getUnderlyingType();
- this->D = D;
- }
- } else if (!D->getReturnType().isNull()) {
- DeducedType = D->getReturnType();
- this->D = D;
- }
- return true;
- }
-
- // Handle non-auto decltype, e.g.:
- // - auto foo() -> decltype(expr) {}
- // - decltype(expr);
- bool VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
- if (TL.getBeginLoc() != SearchedLocation)
- return true;
-
- // A DecltypeType's underlying type can be another DecltypeType! E.g.
- // int I = 0;
- // decltype(I) J = I;
- // decltype(J) K = J;
- const DecltypeType *DT = dyn_cast<DecltypeType>(TL.getTypePtr());
- while (DT && !DT->getUnderlyingType().isNull()) {
- DeducedType = DT->getUnderlyingType();
- D = DT->getAsTagDecl();
- DT = dyn_cast<DecltypeType>(DeducedType.getTypePtr());
- }
- return true;
- }
-
- QualType DeducedType;
- const Decl *D = nullptr;
-};
-} // namespace
-
-/// Retrieves the deduced type at a given location (auto, decltype).
-/// SourceLocationBeg must point to the first character of the token
-llvm::Optional<QualType> getDeducedType(ParsedAST &AST,
- SourceLocation SourceLocationBeg) {
- Token Tok;
- auto &ASTCtx = AST.getASTContext();
- // Only try to find a deduced type if the token is auto or decltype.
- if (!SourceLocationBeg.isValid() ||
- Lexer::getRawToken(SourceLocationBeg, Tok, ASTCtx.getSourceManager(),
- ASTCtx.getLangOpts(), false) ||
- !Tok.is(tok::raw_identifier)) {
- return {};
- }
- AST.getPreprocessor().LookUpIdentifierInfo(Tok);
- if (!(Tok.is(tok::kw_auto) || Tok.is(tok::kw_decltype)))
- return {};
-
- DeducedTypeVisitor V(SourceLocationBeg);
- V.TraverseAST(AST.getASTContext());
- return V.DeducedType;
-}
-
-/// Retrieves the deduced type at a given location (auto, decltype).
-bool hasDeducedType(ParsedAST &AST, SourceLocation SourceLocationBeg) {
- return (bool)getDeducedType(AST, SourceLocationBeg);
-}
-
-llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos,
- format::FormatStyle Style,
- const SymbolIndex *Index) {
- const SourceManager &SM = AST.getSourceManager();
- llvm::Optional<HoverInfo> HI;
- SourceLocation SourceLocationBeg = SM.getMacroArgExpandedLocation(
- getBeginningOfIdentifier(Pos, SM, AST.getASTContext().getLangOpts()));
-
- if (hasDeducedType(AST, SourceLocationBeg)) {
- DeducedTypeVisitor V(SourceLocationBeg);
- V.TraverseAST(AST.getASTContext());
- if (!V.DeducedType.isNull())
- HI = getHoverContents(V.DeducedType, V.D, AST.getASTContext(), Index);
- }
-
- if (!HI) {
- if (auto M = locateMacroAt(SourceLocationBeg, AST.getPreprocessor())) {
- HI = getHoverContents(*M, AST);
- } else {
- DeclRelationSet Relations =
- DeclRelation::TemplatePattern | DeclRelation::Alias;
- auto Decls = getDeclAtPosition(AST, SourceLocationBeg, Relations);
- if (!Decls.empty())
- HI = getHoverContents(Decls.front(), Index);
- }
- }
-
- if (!HI)
- return llvm::None;
-
- auto Replacements = format::reformat(
- Style, HI->Definition, tooling::Range(0, HI->Definition.size()));
- if (auto Formatted =
- tooling::applyAllReplacements(HI->Definition, Replacements))
- HI->Definition = *Formatted;
-
- HI->SymRange =
- getTokenRange(AST.getASTContext().getSourceManager(),
- AST.getASTContext().getLangOpts(), SourceLocationBeg);
- return HI;
-}
-
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
const SymbolIndex *Index) {
if (!Limit)
@@ -1255,44 +756,6 @@ void resolveTypeHierarchy(TypeHierarchyItem &Item, int ResolveLevels,
}
}
-FormattedString HoverInfo::present() const {
- FormattedString Output;
- if (NamespaceScope) {
- Output.appendText("Declared in");
- // Drop trailing "::".
- if (!LocalScope.empty())
- Output.appendInlineCode(llvm::StringRef(LocalScope).drop_back(2));
- else if (NamespaceScope->empty())
- Output.appendInlineCode("global namespace");
- else
- Output.appendInlineCode(llvm::StringRef(*NamespaceScope).drop_back(2));
- }
-
- if (!Definition.empty()) {
- Output.appendCodeBlock(Definition);
- } else {
- // Builtin types
- Output.appendCodeBlock(Name);
- }
-
- if (!Documentation.empty())
- Output.appendText(Documentation);
- return Output;
-}
-
-llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
- const HoverInfo::Param &P) {
- std::vector<llvm::StringRef> Output;
- if (P.Type)
- Output.push_back(*P.Type);
- if (P.Name)
- Output.push_back(*P.Name);
- OS << llvm::join(Output, " ");
- if (P.Default)
- OS << " = " << *P.Default;
- return OS;
-}
-
llvm::DenseSet<const Decl *> getNonLocalDeclRefs(ParsedAST &AST,
const FunctionDecl *FD) {
if (!FD->hasBody())
OpenPOWER on IntegriCloud