1 //===--- HeuristicResolver.h - Resolution of dependent names -----*- C++-*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEURISTICRESOLVER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEURISTICRESOLVER_H
12 #include "clang/AST/Decl.h"
19 class CXXDependentScopeMemberExpr
;
20 class DeclarationName
;
21 class DependentScopeDeclRefExpr
;
24 class UnresolvedUsingValueDecl
;
28 // This class heuristic resolution of declarations and types in template code.
30 // As a compiler, clang only needs to perform certain types of processing on
31 // template code (such as resolving dependent names to declarations, or
32 // resolving the type of a dependent expression) after instantiation. Indeed,
33 // C++ language features such as template specialization mean such resolution
34 // cannot be done accurately before instantiation
36 // However, template code is written and read in uninstantiated form, and clangd
37 // would like to provide editor features like go-to-definition in template code
38 // where possible. To this end, clangd attempts to resolve declarations and
39 // types in uninstantiated code by using heuristics, understanding that the
40 // results may not be fully accurate but that this is better than nothing.
42 // At this time, the heuristic used is a simple but effective one: assume that
43 // template instantiations are based on the primary template definition and not
44 // not a specialization. More advanced heuristics may be added in the future.
45 class HeuristicResolver
{
47 HeuristicResolver(ASTContext
&Ctx
) : Ctx(Ctx
) {}
49 // Try to heuristically resolve certain types of expressions, declarations, or
50 // types to one or more likely-referenced declarations.
51 std::vector
<const NamedDecl
*>
52 resolveMemberExpr(const CXXDependentScopeMemberExpr
*ME
) const;
53 std::vector
<const NamedDecl
*>
54 resolveDeclRefExpr(const DependentScopeDeclRefExpr
*RE
) const;
55 std::vector
<const NamedDecl
*>
56 resolveTypeOfCallExpr(const CallExpr
*CE
) const;
57 std::vector
<const NamedDecl
*>
58 resolveCalleeOfCallExpr(const CallExpr
*CE
) const;
59 std::vector
<const NamedDecl
*>
60 resolveUsingValueDecl(const UnresolvedUsingValueDecl
*UUVD
) const;
61 std::vector
<const NamedDecl
*>
62 resolveDependentNameType(const DependentNameType
*DNT
) const;
63 std::vector
<const NamedDecl
*> resolveTemplateSpecializationType(
64 const DependentTemplateSpecializationType
*DTST
) const;
66 // Try to heuristically resolve a dependent nested name specifier
67 // to the type it likely denotes. Note that *dependent* name specifiers always
68 // denote types, not namespaces.
70 resolveNestedNameSpecifierToType(const NestedNameSpecifier
*NNS
) const;
72 // Given the type T of a dependent expression that appears of the LHS of a
73 // "->", heuristically find a corresponding pointee type in whose scope we
74 // could look up the name appearing on the RHS.
75 const Type
*getPointeeType(const Type
*T
) const;
80 // Given a tag-decl type and a member name, heuristically resolve the
81 // name to one or more declarations.
82 // The current heuristic is simply to look up the name in the primary
83 // template. This is a heuristic because the template could potentially
84 // have specializations that declare different members.
85 // Multiple declarations could be returned if the name is overloaded
86 // (e.g. an overloaded method in the primary template).
87 // This heuristic will give the desired answer in many cases, e.g.
88 // for a call to vector<T>::size().
89 std::vector
<const NamedDecl
*> resolveDependentMember(
90 const Type
*T
, DeclarationName Name
,
91 llvm::function_ref
<bool(const NamedDecl
*ND
)> Filter
) const;
93 // Try to heuristically resolve the type of a possibly-dependent expression
95 const Type
*resolveExprToType(const Expr
*E
) const;
96 std::vector
<const NamedDecl
*> resolveExprToDecls(const Expr
*E
) const;