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 |
11 | |
12 | #include "clang/AST/Decl.h" |
13 | #include <vector> |
14 | |
15 | namespace clang { |
16 | |
17 | class ASTContext; |
18 | class CallExpr; |
19 | class CXXBasePath; |
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. |
46 | class HeuristicResolver { |
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 | // Given the type T of a dependent expression that appears of the LHS of a |
74 | // "->", heuristically find a corresponding pointee type in whose scope we |
75 | // could look up the name appearing on the RHS. |
76 | const Type *getPointeeType(const Type *T) const; |
77 | |
78 | private: |
79 | ASTContext &Ctx; |
80 | }; |
81 | |
82 | } // namespace clangd |
83 | } // namespace clang |
84 | |
85 | #endif |
86 | |