clang-tools 17.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
15namespace clang {
16
17class ASTContext;
18class CallExpr;
19class CXXDependentScopeMemberExpr;
20class DeclarationName;
21class DependentScopeDeclRefExpr;
22class NamedDecl;
23class Type;
24class UnresolvedUsingValueDecl;
25
26namespace 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.
46public:
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 // 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;
76
77private:
78 ASTContext &Ctx;
79
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;
92
93 // Try to heuristically resolve the type of a possibly-dependent expression
94 // `E`.
95 const Type *resolveExprToType(const Expr *E) const;
96 std::vector<const NamedDecl *> resolveExprToDecls(const Expr *E) const;
97};
98
99} // namespace clangd
100} // namespace clang
101
102#endif
const Expr * E
CaptureExpr CE
NodeType Type
Token Name
std::vector< const NamedDecl * > resolveMemberExpr(const CXXDependentScopeMemberExpr *ME) const
std::vector< const NamedDecl * > resolveDeclRefExpr(const DependentScopeDeclRefExpr *RE) const
const Type * getPointeeType(const Type *T) const
std::vector< const NamedDecl * > resolveDependentNameType(const DependentNameType *DNT) const
std::vector< const NamedDecl * > resolveUsingValueDecl(const UnresolvedUsingValueDecl *UUVD) const
std::vector< const NamedDecl * > resolveCalleeOfCallExpr(const CallExpr *CE) const
const Type * resolveNestedNameSpecifierToType(const NestedNameSpecifier *NNS) const
std::vector< const NamedDecl * > resolveTemplateSpecializationType(const DependentTemplateSpecializationType *DTST) const
std::vector< const NamedDecl * > resolveTypeOfCallExpr(const CallExpr *CE) const
@ Type
An inlay hint that for a type annotation.
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//