clang-tools  15.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_HEURISTICRESOLVER_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_HEURISTICRESOLVER_H
11 
12 #include "clang/AST/Decl.h"
13 #include <vector>
14 
15 namespace clang {
16 
17 class ASTContext;
18 class CallExpr;
19 class CXXDependentScopeMemberExpr;
20 class DeclarationName;
21 class DependentScopeDeclRefExpr;
22 class NamedDecl;
23 class Type;
24 class UnresolvedUsingValueDecl;
25 
26 namespace clangd {
27 
28 // This class heuristic resolution of declarations and types in template code.
29 //
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
35 //
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.
41 //
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.
46 public:
47  HeuristicResolver(ASTContext &Ctx) : Ctx(Ctx) {}
48 
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;
65 
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.
69  const Type *
70  resolveNestedNameSpecifierToType(const NestedNameSpecifier *NNS) const;
71 
72 private:
73  ASTContext &Ctx;
74 
75  // Given a tag-decl type and a member name, heuristically resolve the
76  // name to one or more declarations.
77  // The current heuristic is simply to look up the name in the primary
78  // template. This is a heuristic because the template could potentially
79  // have specializations that declare different members.
80  // Multiple declarations could be returned if the name is overloaded
81  // (e.g. an overloaded method in the primary template).
82  // This heuristic will give the desired answer in many cases, e.g.
83  // for a call to vector<T>::size().
84  std::vector<const NamedDecl *> resolveDependentMember(
85  const Type *T, DeclarationName Name,
86  llvm::function_ref<bool(const NamedDecl *ND)> Filter) const;
87 
88  // Try to heuristically resolve the type of a possibly-dependent expression
89  // `E`.
90  const Type *resolveExprToType(const Expr *E) const;
91  std::vector<const NamedDecl *> resolveExprToDecls(const Expr *E) const;
92 
93  // Given the type T of a dependent expression that appears of the LHS of a
94  // "->", heuristically find a corresponding pointee type in whose scope we
95  // could look up the name appearing on the RHS.
96  const Type *getPointeeType(const Type *T) const;
97 };
98 
99 } // namespace clangd
100 } // namespace clang
101 
102 #endif
clang::clangd::HeuristicResolver::resolveMemberExpr
std::vector< const NamedDecl * > resolveMemberExpr(const CXXDependentScopeMemberExpr *ME) const
Definition: HeuristicResolver.cpp:91
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:225
clang::clangd::HeuristicResolver::resolveTemplateSpecializationType
std::vector< const NamedDecl * > resolveTemplateSpecializationType(const DependentTemplateSpecializationType *DTST) const
Definition: HeuristicResolver.cpp:178
clang::clangd::HeuristicResolver::resolveDeclRefExpr
std::vector< const NamedDecl * > resolveDeclRefExpr(const DependentScopeDeclRefExpr *RE) const
Definition: HeuristicResolver.cpp:133
clang::clangd::HeuristicResolver
Definition: HeuristicResolver.h:45
clang::clangd::HeuristicResolver::resolveTypeOfCallExpr
std::vector< const NamedDecl * > resolveTypeOfCallExpr(const CallExpr *CE) const
Definition: HeuristicResolver.cpp:140
clang::clangd::HeuristicResolver::HeuristicResolver
HeuristicResolver(ASTContext &Ctx)
Definition: HeuristicResolver.h:47
clang::clangd::HeuristicResolver::resolveDependentNameType
std::vector< const NamedDecl * > resolveDependentNameType(const DependentNameType *DNT) const
Definition: HeuristicResolver.cpp:170
clang::clangd::HeuristicResolver::resolveUsingValueDecl
std::vector< const NamedDecl * > resolveUsingValueDecl(const UnresolvedUsingValueDecl *UUVD) const
Definition: HeuristicResolver.cpp:164
Name
Token Name
Definition: MacroToEnumCheck.cpp:89
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:156