clang-tools  14.0.0git
HeuristicResolver.h
Go to the documentation of this file.
1 //===--- HeuristicResolver.h - Resolution of dependent names -----*- C++-*-===//
2 //
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
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEURISTIC_RESOLVER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEURISTIC_RESOLVER_H
11 
12 #include "clang/AST/Decl.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include <vector>
15 
16 namespace clang {
17 
18 class ASTContext;
19 class CallExpr;
20 class CXXDependentScopeMemberExpr;
21 class DeclarationName;
22 class DependentScopeDeclRefExpr;
23 class NamedDecl;
24 class Type;
25 class UnresolvedUsingValueDecl;
26 
27 namespace clangd {
28 
29 // This class heuristic resolution of declarations and types in template code.
30 //
31 // As a compiler, clang only needs to perform certain types of processing on
32 // template code (such as resolving dependent names to declarations, or
33 // resolving the type of a dependent expression) after instantiation. Indeed,
34 // C++ language features such as template specialization mean such resolution
35 // cannot be done accurately before instantiation
36 //
37 // However, template code is written and read in uninstantiated form, and clangd
38 // would like to provide editor features like go-to-definition in template code
39 // where possible. To this end, clangd attempts to resolve declarations and
40 // types in uninstantiated code by using heuristics, understanding that the
41 // results may not be fully accurate but that this is better than nothing.
42 //
43 // At this time, the heuristic used is a simple but effective one: assume that
44 // template instantiations are based on the primary template definition and not
45 // not a specialization. More advanced heuristics may be added in the future.
47 public:
48  HeuristicResolver(ASTContext &Ctx) : Ctx(Ctx) {}
49 
50  // Try to heuristically resolve certain types of expressions, declarations, or
51  // types to one or more likely-referenced declarations.
52  std::vector<const NamedDecl *>
53  resolveMemberExpr(const CXXDependentScopeMemberExpr *ME) const;
54  std::vector<const NamedDecl *>
55  resolveDeclRefExpr(const DependentScopeDeclRefExpr *RE) const;
56  std::vector<const NamedDecl *>
57  resolveTypeOfCallExpr(const CallExpr *CE) const;
58  std::vector<const NamedDecl *>
59  resolveCalleeOfCallExpr(const CallExpr *CE) const;
60  std::vector<const NamedDecl *>
61  resolveUsingValueDecl(const UnresolvedUsingValueDecl *UUVD) const;
62  std::vector<const NamedDecl *>
63  resolveDependentNameType(const DependentNameType *DNT) const;
64  std::vector<const NamedDecl *> resolveTemplateSpecializationType(
65  const DependentTemplateSpecializationType *DTST) const;
66 
67  // Try to heuristically resolve a dependent nested name specifier
68  // to the type it likely denotes. Note that *dependent* name specifiers always
69  // denote types, not namespaces.
70  const Type *
71  resolveNestedNameSpecifierToType(const NestedNameSpecifier *NNS) const;
72 
73 private:
74  ASTContext &Ctx;
75 
76  // Given a tag-decl type and a member name, heuristically resolve the
77  // name to one or more declarations.
78  // The current heuristic is simply to look up the name in the primary
79  // template. This is a heuristic because the template could potentially
80  // have specializations that declare different members.
81  // Multiple declarations could be returned if the name is overloaded
82  // (e.g. an overloaded method in the primary template).
83  // This heuristic will give the desired answer in many cases, e.g.
84  // for a call to vector<T>::size().
85  std::vector<const NamedDecl *> resolveDependentMember(
86  const Type *T, DeclarationName Name,
87  llvm::function_ref<bool(const NamedDecl *ND)> Filter) const;
88 
89  // Try to heuristically resolve the type of a possibly-dependent expression
90  // `E`.
91  const Type *resolveExprToType(const Expr *E) const;
92  std::vector<const NamedDecl *> resolveExprToDecls(const Expr *E) const;
93 
94  // Given the type T of a dependent expression that appears of the LHS of a
95  // "->", heuristically find a corresponding pointee type in whose scope we
96  // could look up the name appearing on the RHS.
97  const Type *getPointeeType(const Type *T) const;
98 };
99 
100 } // namespace clangd
101 } // namespace clang
102 
103 #endif
clang::clangd::HeuristicResolver::resolveMemberExpr
std::vector< const NamedDecl * > resolveMemberExpr(const CXXDependentScopeMemberExpr *ME) const
Definition: HeuristicResolver.cpp:92
E
const Expr * E
Definition: AvoidBindCheck.cpp:88
Type
NodeType Type
Definition: HTMLGenerator.cpp:73
clang::clangd::HeuristicResolver::resolveNestedNameSpecifierToType
const Type * resolveNestedNameSpecifierToType(const NestedNameSpecifier *NNS) const
Definition: HeuristicResolver.cpp:226
clang::clangd::HeuristicResolver::resolveTemplateSpecializationType
std::vector< const NamedDecl * > resolveTemplateSpecializationType(const DependentTemplateSpecializationType *DTST) const
Definition: HeuristicResolver.cpp:179
clang::clangd::HeuristicResolver::resolveDeclRefExpr
std::vector< const NamedDecl * > resolveDeclRefExpr(const DependentScopeDeclRefExpr *RE) const
Definition: HeuristicResolver.cpp:134
clang::clangd::HeuristicResolver
Definition: HeuristicResolver.h:46
clang::clangd::HeuristicResolver::resolveTypeOfCallExpr
std::vector< const NamedDecl * > resolveTypeOfCallExpr(const CallExpr *CE) const
Definition: HeuristicResolver.cpp:141
clang::clangd::HeuristicResolver::HeuristicResolver
HeuristicResolver(ASTContext &Ctx)
Definition: HeuristicResolver.h:48
Name
static constexpr llvm::StringLiteral Name
Definition: UppercaseLiteralSuffixCheck.cpp:28
clang::clangd::HeuristicResolver::resolveDependentNameType
std::vector< const NamedDecl * > resolveDependentNameType(const DependentNameType *DNT) const
Definition: HeuristicResolver.cpp:171
clang::clangd::HeuristicResolver::resolveUsingValueDecl
std::vector< const NamedDecl * > resolveUsingValueDecl(const UnresolvedUsingValueDecl *UUVD) const
Definition: HeuristicResolver.cpp:165
CE
CaptureExpr CE
Definition: AvoidBindCheck.cpp:67
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
clang::clangd::HeuristicResolver::resolveCalleeOfCallExpr
std::vector< const NamedDecl * > resolveCalleeOfCallExpr(const CallExpr *CE) const
Definition: HeuristicResolver.cpp:157