10#include "clang/AST/ASTContext.h"
11#include "clang/AST/DeclTemplate.h"
12#include "clang/AST/ExprCXX.h"
19const auto NoFilter = [](
const NamedDecl *D) {
return true; };
21 return D->isCXXInstanceMember();
24 return !D->isCXXInstanceMember();
26const auto ValueFilter = [](
const NamedDecl *D) {
return isa<ValueDecl>(D); };
27const auto TypeFilter = [](
const NamedDecl *D) {
return isa<TypeDecl>(D); };
29 return isa<TemplateDecl>(D);
38 if (
const auto *RT = T->getAs<RecordType>())
39 return dyn_cast<CXXRecordDecl>(RT->getDecl());
41 if (
const auto *ICNT = T->getAs<InjectedClassNameType>())
42 T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
46 const auto *TST = T->getAs<TemplateSpecializationType>();
50 const ClassTemplateDecl *TD = dyn_cast_or_null<ClassTemplateDecl>(
51 TST->getTemplateName().getAsTemplateDecl());
55 return TD->getTemplatedDecl();
62 if (T->isPointerType())
63 return T->castAs<PointerType>()->
getPointeeType().getTypePtrOrNull();
69 auto ArrowOps = resolveDependentMember(
80 auto *TST = T->getAs<TemplateSpecializationType>();
83 if (TST->template_arguments().size() == 0)
85 const TemplateArgument &FirstArg = TST->template_arguments()[0];
86 if (FirstArg.getKind() != TemplateArgument::Type)
88 return FirstArg.getAsType().getTypePtrOrNull();
92 const CXXDependentScopeMemberExpr *ME)
const {
104 if (NestedNameSpecifier *NNS = ME->getQualifier()) {
107 resolveDependentMember(QualifierType, ME->getMember(),
NoFilter);
115 const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
121 if (
const auto *BT = BaseType->getAs<BuiltinType>()) {
125 Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase();
126 if (Base && BT->getKind() == BuiltinType::Dependent) {
127 BaseType = resolveExprToType(Base);
130 return resolveDependentMember(BaseType, ME->getMember(),
NoFilter);
134 const DependentScopeDeclRefExpr *RE)
const {
135 return resolveDependentMember(RE->getQualifier()->getAsType(),
139std::vector<const NamedDecl *>
141 const auto *CalleeType = resolveExprToType(
CE->getCallee());
144 if (
const auto *FnTypePtr = CalleeType->getAs<PointerType>())
145 CalleeType = FnTypePtr->getPointeeType().getTypePtr();
146 if (
const FunctionType *FnType = CalleeType->getAs<FunctionType>()) {
155std::vector<const NamedDecl *>
157 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(
CE->getCalleeDecl())) {
161 return resolveExprToDecls(
CE->getCallee());
165 const UnresolvedUsingValueDecl *UUVD)
const {
166 return resolveDependentMember(UUVD->getQualifier()->getAsType(),
171 const DependentNameType *DNT)
const {
172 return resolveDependentMember(
177std::vector<const NamedDecl *>
179 const DependentTemplateSpecializationType *DTST)
const {
180 return resolveDependentMember(
186 if (Decls.size() != 1)
188 if (
const auto *TD = dyn_cast<TypeDecl>(Decls[0])) {
189 return TD->getTypeForDecl();
191 if (
const auto *VD = dyn_cast<ValueDecl>(Decls[0])) {
192 return VD->getType().getTypePtrOrNull();
197std::vector<const NamedDecl *>
198HeuristicResolver::resolveExprToDecls(
const Expr *
E)
const {
199 if (
const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(
E)) {
202 if (
const auto *RE = dyn_cast<DependentScopeDeclRefExpr>(
E)) {
205 if (
const auto *OE = dyn_cast<OverloadExpr>(
E)) {
206 return {OE->decls_begin(), OE->decls_end()};
208 if (
const auto *
CE = dyn_cast<CallExpr>(
E)) {
211 if (
const auto *ME = dyn_cast<MemberExpr>(
E))
212 return {ME->getMemberDecl()};
217const Type *HeuristicResolver::resolveExprToType(
const Expr *
E)
const {
218 std::vector<const NamedDecl *> Decls = resolveExprToDecls(
E);
222 return E->getType().getTypePtr();
226 const NestedNameSpecifier *NNS)
const {
234 switch (NNS->getKind()) {
235 case NestedNameSpecifier::TypeSpec:
236 case NestedNameSpecifier::TypeSpecWithTemplate:
237 return NNS->getAsType();
238 case NestedNameSpecifier::Identifier: {
249std::vector<const NamedDecl *> HeuristicResolver::resolveDependentMember(
250 const Type *T, DeclarationName
Name,
251 llvm::function_ref<
bool(
const NamedDecl *ND)> Filter)
const {
254 if (
auto *ET = T->getAs<EnumType>()) {
255 auto Result = ET->getDecl()->lookup(
Name);
256 return {Result.begin(), Result.end()};
259 if (!RD->hasDefinition())
261 RD = RD->getDefinition();
262 return RD->lookupDependentName(
Name, Filter);
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
const Type * resolveDeclsToType(const std::vector< const NamedDecl * > &Decls)
@ Type
An inlay hint that for a type annotation.
const auto TemplateFilter
const auto NonStaticFilter
CXXRecordDecl * resolveTypeToRecordDecl(const Type *T)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//