10 #include "clang/AST/ASTContext.h"
11 #include "clang/AST/DeclTemplate.h"
12 #include "clang/AST/ExprCXX.h"
19 const auto NoFilter = [](
const NamedDecl *
D) {
return true; };
21 return D->isCXXInstanceMember();
24 return !
D->isCXXInstanceMember();
26 const auto ValueFilter = [](
const NamedDecl *
D) {
return isa<ValueDecl>(
D); };
27 const 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();
58 const Type *HeuristicResolver::getPointeeType(
const Type *T)
const {
62 if (T->isPointerType())
63 return T->castAs<PointerType>()->getPointeeType().getTypePtrOrNull();
69 auto ArrowOps = resolveDependentMember(
80 auto *TST = T->getAs<TemplateSpecializationType>();
83 if (TST->getNumArgs() == 0)
85 const TemplateArgument &FirstArg = TST->getArg(0);
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();
117 BaseType = getPointeeType(BaseType);
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(),
139 std::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>()) {
155 std::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(
177 std::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();
197 std::vector<const NamedDecl *>
198 HeuristicResolver::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()};
217 const 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: {
249 std::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);