[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 closed https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
HighCommander4 wrote: (Rebased) https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 updated
https://github.com/llvm/llvm-project/pull/130473
>From f6c57947b12d8c22e8e54757fc03ff1e407aa12e Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:36:25 -0500
Subject: [PATCH 1/6] Change the parameter type of resolveTypeToTagDecl() to
QualType
---
clang/lib/Sema/HeuristicResolver.cpp | 18 --
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 4544d75ea73c4..a93b9d1ce8a64 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -76,7 +76,7 @@ class HeuristicResolverImpl {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
+ TagDecl *resolveTypeToTagDecl(QualType T);
// Helper function for simplifying a type.
// `Type` is the type to simplify.
@@ -133,8 +133,10 @@ TemplateName getReferencedTemplateName(const Type *T) {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a CXXRecordDecl in which we can try name lookup.
-TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) {
- assert(T);
+TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
+ const Type *T = QT.getTypePtrOrNull();
+ if (!T)
+return nullptr;
// Unwrap type sugar such as type aliases.
T = T->getCanonicalTypeInternal().getTypePtr();
@@ -330,8 +332,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr
*CE) {
if (const auto *FnTypePtr = CalleeType->getAs())
CalleeType = FnTypePtr->getPointeeType();
if (const FunctionType *FnType = CalleeType->getAs()) {
-if (const auto *D =
-resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) {
+if (const auto *D = resolveTypeToTagDecl(FnType->getReturnType())) {
return {D};
}
}
@@ -442,7 +443,7 @@ bool findOrdinaryMember(const CXXRecordDecl *RD,
CXXBasePath &Path,
bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses(
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
DeclarationName Name) {
- TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr());
+ TagDecl *TD = resolveTypeToTagDecl(Specifier->getType());
if (const auto *RD = dyn_cast_if_present(TD)) {
return findOrdinaryMember(RD, Path, Name);
}
@@ -485,10 +486,7 @@ std::vector
HeuristicResolverImpl::lookupDependentName(
std::vector HeuristicResolverImpl::resolveDependentMember(
QualType QT, DeclarationName Name,
llvm::function_ref Filter) {
- const Type *T = QT.getTypePtrOrNull();
- if (!T)
-return {};
- TagDecl *TD = resolveTypeToTagDecl(T);
+ TagDecl *TD = resolveTypeToTagDecl(QT);
if (!TD)
return {};
if (auto *ED = dyn_cast(TD)) {
>From a8b885fc950ad6dda24123027f98a9e77fed3785 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:43:25 -0500
Subject: [PATCH 2/6] Expose resolveTypeToTagDecl() publically in
HeuristicResolver
---
clang/include/clang/Sema/HeuristicResolver.h | 4
clang/lib/Sema/HeuristicResolver.cpp | 9 -
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..c971b9a6a7b51 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,10 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
private:
ASTContext &Ctx;
};
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index a93b9d1ce8a64..c75ded526e29f 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -48,6 +48,7 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
private:
ASTContext &Ctx;
@@ -73,11 +74,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(QualType T);
-
// Helper function for simplifying a type.
// `Type` is the type to simplify.
// `E` is
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
@@ -54,8 +54,9 @@ IdentifierInfo *Parser::getSEHExceptKeyword() {
}
Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
-: PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
- Diags(PP.getDiagnostics()), StackHandler(Diags),
+: PP(pp),
+ PreferredType(&actions.getASTContext(), pp.isCodeCompletionEnabled()),
HighCommander4 wrote:
I actually tried this initially, but `PreferredTypeBuilder` has its assignment
operator called
[here](https://searchfox.org/llvm/rev/71f629fc2a93e41577c09bdd782b2ba524ed5fea/clang/include/clang/Parse/Parser.h#1061),
and that does not compile if it has a member of reference type.
https://github.com/llvm/llvm-project/pull/130473
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
@@ -5346,27 +5348,11 @@ AddRecordMembersCompletionResults(Sema &SemaRef,
ResultBuilder &Results,
// Returns the RecordDecl inside the BaseType, falling back to primary template
// in case of specializations. Since we might not have a decl for the
// instantiation/specialization yet, e.g. dependent code.
-static RecordDecl *getAsRecordDecl(QualType BaseType) {
- BaseType = BaseType.getNonReferenceType();
- if (auto *RD = BaseType->getAsRecordDecl()) {
-if (const auto *CTSD =
-llvm::dyn_cast(RD)) {
- // Template might not be instantiated yet, fall back to primary template
- // in such cases.
- if (CTSD->getTemplateSpecializationKind() == TSK_Undeclared)
-RD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
-}
-return RD;
- }
-
- if (const auto *TST = BaseType->getAs()) {
-if (const auto *TD = dyn_cast_or_null(
-TST->getTemplateName().getAsTemplateDecl())) {
- return TD->getTemplatedDecl();
-}
- }
zyn0217 wrote:
I might be missing something, do we now call
`resolveTemplateSpecializationType` somewhere?
https://github.com/llvm/llvm-project/pull/130473
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/zyn0217 edited https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/zyn0217 approved this pull request. https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/zyn0217 commented: Thanks for consistently working on this! https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
@@ -5346,27 +5348,11 @@ AddRecordMembersCompletionResults(Sema &SemaRef,
ResultBuilder &Results,
// Returns the RecordDecl inside the BaseType, falling back to primary template
// in case of specializations. Since we might not have a decl for the
// instantiation/specialization yet, e.g. dependent code.
-static RecordDecl *getAsRecordDecl(QualType BaseType) {
- BaseType = BaseType.getNonReferenceType();
- if (auto *RD = BaseType->getAsRecordDecl()) {
-if (const auto *CTSD =
-llvm::dyn_cast(RD)) {
- // Template might not be instantiated yet, fall back to primary template
- // in such cases.
- if (CTSD->getTemplateSpecializationKind() == TSK_Undeclared)
-RD = CTSD->getSpecializedTemplate()->getTemplatedDecl();
-}
-return RD;
- }
-
- if (const auto *TST = BaseType->getAs()) {
-if (const auto *TD = dyn_cast_or_null(
-TST->getTemplateName().getAsTemplateDecl())) {
- return TD->getTemplatedDecl();
-}
- }
zyn0217 wrote:
Oh nevermind it's inside resolveTypeToTagDecl
https://github.com/llvm/llvm-project/pull/130473
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
@@ -54,8 +54,9 @@ IdentifierInfo *Parser::getSEHExceptKeyword() {
}
Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
-: PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
- Diags(PP.getDiagnostics()), StackHandler(Diags),
+: PP(pp),
+ PreferredType(&actions.getASTContext(), pp.isCodeCompletionEnabled()),
zyn0217 wrote:
nit: I think we have a preference of using references than pointers if it is
known to be non-null.
https://github.com/llvm/llvm-project/pull/130473
___
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
HighCommander4 wrote: Review ping :) https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
HighCommander4 wrote: (I messed things up a bit here by merging a PR that was stacked on top of this into this one. Marking as Draft until I sort that out.) https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 ready_for_review https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 converted_to_draft https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
HighCommander4 wrote: (Rebased) https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 updated
https://github.com/llvm/llvm-project/pull/130473
>From ea2b2409894092ddc7b3fea5a6bee887e4d62235 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:36:25 -0500
Subject: [PATCH 1/6] Change the parameter type of resolveTypeToTagDecl() to
QualType
---
clang/lib/Sema/HeuristicResolver.cpp | 18 --
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 4544d75ea73c4..a93b9d1ce8a64 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -76,7 +76,7 @@ class HeuristicResolverImpl {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
+ TagDecl *resolveTypeToTagDecl(QualType T);
// Helper function for simplifying a type.
// `Type` is the type to simplify.
@@ -133,8 +133,10 @@ TemplateName getReferencedTemplateName(const Type *T) {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a CXXRecordDecl in which we can try name lookup.
-TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) {
- assert(T);
+TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
+ const Type *T = QT.getTypePtrOrNull();
+ if (!T)
+return nullptr;
// Unwrap type sugar such as type aliases.
T = T->getCanonicalTypeInternal().getTypePtr();
@@ -330,8 +332,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr
*CE) {
if (const auto *FnTypePtr = CalleeType->getAs())
CalleeType = FnTypePtr->getPointeeType();
if (const FunctionType *FnType = CalleeType->getAs()) {
-if (const auto *D =
-resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) {
+if (const auto *D = resolveTypeToTagDecl(FnType->getReturnType())) {
return {D};
}
}
@@ -442,7 +443,7 @@ bool findOrdinaryMember(const CXXRecordDecl *RD,
CXXBasePath &Path,
bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses(
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
DeclarationName Name) {
- TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr());
+ TagDecl *TD = resolveTypeToTagDecl(Specifier->getType());
if (const auto *RD = dyn_cast_if_present(TD)) {
return findOrdinaryMember(RD, Path, Name);
}
@@ -485,10 +486,7 @@ std::vector
HeuristicResolverImpl::lookupDependentName(
std::vector HeuristicResolverImpl::resolveDependentMember(
QualType QT, DeclarationName Name,
llvm::function_ref Filter) {
- const Type *T = QT.getTypePtrOrNull();
- if (!T)
-return {};
- TagDecl *TD = resolveTypeToTagDecl(T);
+ TagDecl *TD = resolveTypeToTagDecl(QT);
if (!TD)
return {};
if (auto *ED = dyn_cast(TD)) {
>From d49ea63cb81e1762dbb3292fedd2d1885f0c94f7 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:43:25 -0500
Subject: [PATCH 2/6] Expose resolveTypeToTagDecl() publically in
HeuristicResolver
---
clang/include/clang/Sema/HeuristicResolver.h | 4
clang/lib/Sema/HeuristicResolver.cpp | 9 -
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..c971b9a6a7b51 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,10 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
private:
ASTContext &Ctx;
};
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index a93b9d1ce8a64..c75ded526e29f 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -48,6 +48,7 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
private:
ASTContext &Ctx;
@@ -73,11 +74,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(QualType T);
-
// Helper function for simplifying a type.
// `Type` is the type to simplify.
// `E` is
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 updated
https://github.com/llvm/llvm-project/pull/130473
>From 909de4a22dcda164b8fcb539e0907a77f99b3b00 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:36:25 -0500
Subject: [PATCH 1/6] Change the parameter type of resolveTypeToTagDecl() to
QualType
---
clang/lib/Sema/HeuristicResolver.cpp | 18 --
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 7aecd2a73b539..3c7918165ee42 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -75,7 +75,7 @@ class HeuristicResolverImpl {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
+ TagDecl *resolveTypeToTagDecl(QualType T);
// Helper function for simplifying a type.
// `Type` is the type to simplify.
@@ -132,8 +132,10 @@ TemplateName getReferencedTemplateName(const Type *T) {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a CXXRecordDecl in which we can try name lookup.
-TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) {
- assert(T);
+TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
+ const Type *T = QT.getTypePtrOrNull();
+ if (!T)
+return nullptr;
// Unwrap type sugar such as type aliases.
T = T->getCanonicalTypeInternal().getTypePtr();
@@ -315,8 +317,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr
*CE) {
if (const auto *FnTypePtr = CalleeType->getAs())
CalleeType = FnTypePtr->getPointeeType();
if (const FunctionType *FnType = CalleeType->getAs()) {
-if (const auto *D =
-resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) {
+if (const auto *D = resolveTypeToTagDecl(FnType->getReturnType())) {
return {D};
}
}
@@ -427,7 +428,7 @@ bool findOrdinaryMember(const CXXRecordDecl *RD,
CXXBasePath &Path,
bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses(
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
DeclarationName Name) {
- TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr());
+ TagDecl *TD = resolveTypeToTagDecl(Specifier->getType());
if (const auto *RD = dyn_cast_if_present(TD)) {
return findOrdinaryMember(RD, Path, Name);
}
@@ -470,10 +471,7 @@ std::vector
HeuristicResolverImpl::lookupDependentName(
std::vector HeuristicResolverImpl::resolveDependentMember(
QualType QT, DeclarationName Name,
llvm::function_ref Filter) {
- const Type *T = QT.getTypePtrOrNull();
- if (!T)
-return {};
- TagDecl *TD = resolveTypeToTagDecl(T);
+ TagDecl *TD = resolveTypeToTagDecl(QT);
if (!TD)
return {};
if (auto *ED = dyn_cast(TD)) {
>From d5be29e9f997ae707aff3d5d5c5255d3b87af9a2 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:43:25 -0500
Subject: [PATCH 2/6] Expose resolveTypeToTagDecl() publically in
HeuristicResolver
---
clang/include/clang/Sema/HeuristicResolver.h | 4
clang/lib/Sema/HeuristicResolver.cpp | 9 -
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..c971b9a6a7b51 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,10 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
private:
ASTContext &Ctx;
};
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 3c7918165ee42..11fe786fa91c6 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -47,6 +47,7 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
private:
ASTContext &Ctx;
@@ -72,11 +73,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(QualType T);
-
// Helper function for simplifying a type.
// `Type` is the type to simplify.
// `E` is
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
HighCommander4 wrote: Fixed now. Resubmitting for review. https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 updated
https://github.com/llvm/llvm-project/pull/130473
>From 66e5ed1f1fcfe5a52d110ae228ddd51bd487ee16 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:36:25 -0500
Subject: [PATCH 1/7] Change the parameter type of resolveTypeToTagDecl() to
QualType
---
clang/lib/Sema/HeuristicResolver.cpp | 18 --
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 7aecd2a73b539..3c7918165ee42 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -75,7 +75,7 @@ class HeuristicResolverImpl {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
+ TagDecl *resolveTypeToTagDecl(QualType T);
// Helper function for simplifying a type.
// `Type` is the type to simplify.
@@ -132,8 +132,10 @@ TemplateName getReferencedTemplateName(const Type *T) {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a CXXRecordDecl in which we can try name lookup.
-TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) {
- assert(T);
+TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
+ const Type *T = QT.getTypePtrOrNull();
+ if (!T)
+return nullptr;
// Unwrap type sugar such as type aliases.
T = T->getCanonicalTypeInternal().getTypePtr();
@@ -315,8 +317,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr
*CE) {
if (const auto *FnTypePtr = CalleeType->getAs())
CalleeType = FnTypePtr->getPointeeType();
if (const FunctionType *FnType = CalleeType->getAs()) {
-if (const auto *D =
-resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) {
+if (const auto *D = resolveTypeToTagDecl(FnType->getReturnType())) {
return {D};
}
}
@@ -427,7 +428,7 @@ bool findOrdinaryMember(const CXXRecordDecl *RD,
CXXBasePath &Path,
bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses(
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
DeclarationName Name) {
- TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr());
+ TagDecl *TD = resolveTypeToTagDecl(Specifier->getType());
if (const auto *RD = dyn_cast_if_present(TD)) {
return findOrdinaryMember(RD, Path, Name);
}
@@ -470,10 +471,7 @@ std::vector
HeuristicResolverImpl::lookupDependentName(
std::vector HeuristicResolverImpl::resolveDependentMember(
QualType QT, DeclarationName Name,
llvm::function_ref Filter) {
- const Type *T = QT.getTypePtrOrNull();
- if (!T)
-return {};
- TagDecl *TD = resolveTypeToTagDecl(T);
+ TagDecl *TD = resolveTypeToTagDecl(QT);
if (!TD)
return {};
if (auto *ED = dyn_cast(TD)) {
>From efa9503da4dcef74003f08493eb48c3d119cba0f Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:43:25 -0500
Subject: [PATCH 2/7] Expose resolveTypeToTagDecl() publically in
HeuristicResolver
---
clang/include/clang/Sema/HeuristicResolver.h | 4
clang/lib/Sema/HeuristicResolver.cpp | 9 -
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..c971b9a6a7b51 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,10 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
private:
ASTContext &Ctx;
};
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 3c7918165ee42..11fe786fa91c6 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -47,6 +47,7 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
private:
ASTContext &Ctx;
@@ -72,11 +73,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(QualType T);
-
// Helper function for simplifying a type.
// `Type` is the type to simplify.
// `E` is
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 ready_for_review https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
HighCommander4 wrote: I split the PR up into a few commits for easier reviewing. The high-level idea here is that the helper function `getAsRecordDecl()` in SemaCodeComplete.cpp is doing similar things to HeuristicResolver (specifically, `simplifyType` and `resolveTypeToRecordDecl`), but HeuristicResolver is handling a few more cases, and to get code completion to benefit from those cases the patch gets the helper function to use HeuristicResolver. There was one case, `TSK_Undeclared`, that `getAsRecordDecl()` handled but HeuristicResolver didn't. I contemplated adding a standalone test case for that to HeuristicResolverTests but it's not easy because the situation only arises during code completion when the AST is not fully built. The case does have test coverage, in `clang/test/CodeCompletion/desig-init.cpp` (this test fails without the `TSK_Undeclared` handling). https://github.com/llvm/llvm-project/pull/130473 ___ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
llvmbot wrote:
@llvm/pr-subscribers-clang
Author: Nathan Ridge (HighCommander4)
Changes
Fixes https://github.com/llvm/llvm-project/issues/130468
---
Full diff: https://github.com/llvm/llvm-project/pull/130473.diff
6 Files Affected:
- (modified) clang/include/clang/Sema/HeuristicResolver.h (+12)
- (modified) clang/include/clang/Sema/Sema.h (+3-1)
- (modified) clang/lib/Parse/Parser.cpp (+3-2)
- (modified) clang/lib/Sema/HeuristicResolver.cpp (+25-24)
- (modified) clang/lib/Sema/SemaCodeComplete.cpp (+15-28)
- (modified) clang/test/CodeCompletion/member-access.cpp (+4-2)
``diff
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..df60d3359c6a6 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,18 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
+ // Simplify the type `Type`.
+ // `E` is the expression whose type `Type` is, if known. This sometimes
+ // contains information relevant to the type that's not stored in `Type`
+ // itself.
+ // If `UnwrapPointer` is true, exactly only pointer type will be unwrapped
+ // during simplification, and the operation fails if no pointer type is
found.
+ QualType simplifyType(QualType Type, const Expr *E, bool UnwrapPointer);
+
private:
ASTContext &Ctx;
};
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index fdef57e84ee3d..89ce852b0a09f 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -290,7 +290,8 @@ class FileNullabilityMap {
/// parameter. This avoids updating the type on hot paths in the parser.
class PreferredTypeBuilder {
public:
- PreferredTypeBuilder(bool Enabled) : Enabled(Enabled) {}
+ PreferredTypeBuilder(ASTContext *Ctx, bool Enabled)
+ : Ctx(Ctx), Enabled(Enabled) {}
void enterCondition(Sema &S, SourceLocation Tok);
void enterReturn(Sema &S, SourceLocation Tok);
@@ -336,6 +337,7 @@ class PreferredTypeBuilder {
}
private:
+ ASTContext *Ctx;
bool Enabled;
/// Start position of a token for which we store expected type.
SourceLocation ExpectedLoc;
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 0710542f5e938..09e784a8e04de 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -52,8 +52,9 @@ IdentifierInfo *Parser::getSEHExceptKeyword() {
}
Parser::Parser(Preprocessor &pp, Sema &actions, bool skipFunctionBodies)
-: PP(pp), PreferredType(pp.isCodeCompletionEnabled()), Actions(actions),
- Diags(PP.getDiagnostics()), GreaterThanIsOperator(true),
+: PP(pp),
+ PreferredType(&actions.getASTContext(), pp.isCodeCompletionEnabled()),
+ Actions(actions), Diags(PP.getDiagnostics()),
GreaterThanIsOperator(true),
ColonIsSacred(false), InMessageExpression(false),
TemplateParameterDepth(0), ParsingInObjCContainer(false) {
SkipFunctionBodies = pp.isCodeCompletionEnabled() || skipFunctionBodies;
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 7aecd2a73b539..d377379c627db 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -47,6 +47,8 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
+ QualType simplifyType(QualType Type, const Expr *E, bool UnwrapPointer);
private:
ASTContext &Ctx;
@@ -72,20 +74,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
-
- // Helper function for simplifying a type.
- // `Type` is the type to simplify.
- // `E` is the expression whose type `Type` is, if known. This sometimes
- // contains information relevant to the type that's not stored in `Type`
- // itself.
- // If `UnwrapPointer` is true, exactly only pointer type will be unwrapped
- // during simplification, and the operation fails if no pointer type is
found.
- QualType simplifyType(QualType Type, const Expr *E, bool UnwrapPointer);
-
bool findOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
DeclarationName Name);
@@ -132,8 +120,10 @@ TemplateName getRe
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 updated
https://github.com/llvm/llvm-project/pull/130473
>From 66e5ed1f1fcfe5a52d110ae228ddd51bd487ee16 Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:36:25 -0500
Subject: [PATCH 1/6] Change the parameter type of resolveTypeToTagDecl() to
QualType
---
clang/lib/Sema/HeuristicResolver.cpp | 18 --
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 7aecd2a73b539..3c7918165ee42 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -75,7 +75,7 @@ class HeuristicResolverImpl {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
+ TagDecl *resolveTypeToTagDecl(QualType T);
// Helper function for simplifying a type.
// `Type` is the type to simplify.
@@ -132,8 +132,10 @@ TemplateName getReferencedTemplateName(const Type *T) {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a CXXRecordDecl in which we can try name lookup.
-TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) {
- assert(T);
+TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
+ const Type *T = QT.getTypePtrOrNull();
+ if (!T)
+return nullptr;
// Unwrap type sugar such as type aliases.
T = T->getCanonicalTypeInternal().getTypePtr();
@@ -315,8 +317,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr
*CE) {
if (const auto *FnTypePtr = CalleeType->getAs())
CalleeType = FnTypePtr->getPointeeType();
if (const FunctionType *FnType = CalleeType->getAs()) {
-if (const auto *D =
-resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) {
+if (const auto *D = resolveTypeToTagDecl(FnType->getReturnType())) {
return {D};
}
}
@@ -427,7 +428,7 @@ bool findOrdinaryMember(const CXXRecordDecl *RD,
CXXBasePath &Path,
bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses(
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
DeclarationName Name) {
- TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr());
+ TagDecl *TD = resolveTypeToTagDecl(Specifier->getType());
if (const auto *RD = dyn_cast_if_present(TD)) {
return findOrdinaryMember(RD, Path, Name);
}
@@ -470,10 +471,7 @@ std::vector
HeuristicResolverImpl::lookupDependentName(
std::vector HeuristicResolverImpl::resolveDependentMember(
QualType QT, DeclarationName Name,
llvm::function_ref Filter) {
- const Type *T = QT.getTypePtrOrNull();
- if (!T)
-return {};
- TagDecl *TD = resolveTypeToTagDecl(T);
+ TagDecl *TD = resolveTypeToTagDecl(QT);
if (!TD)
return {};
if (auto *ED = dyn_cast(TD)) {
>From efa9503da4dcef74003f08493eb48c3d119cba0f Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:43:25 -0500
Subject: [PATCH 2/6] Expose resolveTypeToTagDecl() publically in
HeuristicResolver
---
clang/include/clang/Sema/HeuristicResolver.h | 4
clang/lib/Sema/HeuristicResolver.cpp | 9 -
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..c971b9a6a7b51 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,10 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
private:
ASTContext &Ctx;
};
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 3c7918165ee42..11fe786fa91c6 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -47,6 +47,7 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
private:
ASTContext &Ctx;
@@ -72,11 +73,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(QualType T);
-
// Helper function for simplifying a type.
// `Type` is the type to simplify.
// `E` is
[clang] [clang][CodeComplete] Use HeuristicResolver in getAsRecordDecl() (PR #130473)
https://github.com/HighCommander4 created
https://github.com/llvm/llvm-project/pull/130473
Fixes https://github.com/llvm/llvm-project/issues/130468
>From 0999f2fb15b6703fc9f5c4ba5c9e21c14a90b4ed Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:36:25 -0500
Subject: [PATCH 1/4] Change the parameter type of resolveTypeToTagDecl() to
QualType
---
clang/lib/Sema/HeuristicResolver.cpp | 18 --
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 7aecd2a73b539..3c7918165ee42 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -75,7 +75,7 @@ class HeuristicResolverImpl {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(const Type *T);
+ TagDecl *resolveTypeToTagDecl(QualType T);
// Helper function for simplifying a type.
// `Type` is the type to simplify.
@@ -132,8 +132,10 @@ TemplateName getReferencedTemplateName(const Type *T) {
// Helper function for HeuristicResolver::resolveDependentMember()
// which takes a possibly-dependent type `T` and heuristically
// resolves it to a CXXRecordDecl in which we can try name lookup.
-TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(const Type *T) {
- assert(T);
+TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
+ const Type *T = QT.getTypePtrOrNull();
+ if (!T)
+return nullptr;
// Unwrap type sugar such as type aliases.
T = T->getCanonicalTypeInternal().getTypePtr();
@@ -315,8 +317,7 @@ HeuristicResolverImpl::resolveTypeOfCallExpr(const CallExpr
*CE) {
if (const auto *FnTypePtr = CalleeType->getAs())
CalleeType = FnTypePtr->getPointeeType();
if (const FunctionType *FnType = CalleeType->getAs()) {
-if (const auto *D =
-resolveTypeToTagDecl(FnType->getReturnType().getTypePtr())) {
+if (const auto *D = resolveTypeToTagDecl(FnType->getReturnType())) {
return {D};
}
}
@@ -427,7 +428,7 @@ bool findOrdinaryMember(const CXXRecordDecl *RD,
CXXBasePath &Path,
bool HeuristicResolverImpl::findOrdinaryMemberInDependentClasses(
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
DeclarationName Name) {
- TagDecl *TD = resolveTypeToTagDecl(Specifier->getType().getTypePtr());
+ TagDecl *TD = resolveTypeToTagDecl(Specifier->getType());
if (const auto *RD = dyn_cast_if_present(TD)) {
return findOrdinaryMember(RD, Path, Name);
}
@@ -470,10 +471,7 @@ std::vector
HeuristicResolverImpl::lookupDependentName(
std::vector HeuristicResolverImpl::resolveDependentMember(
QualType QT, DeclarationName Name,
llvm::function_ref Filter) {
- const Type *T = QT.getTypePtrOrNull();
- if (!T)
-return {};
- TagDecl *TD = resolveTypeToTagDecl(T);
+ TagDecl *TD = resolveTypeToTagDecl(QT);
if (!TD)
return {};
if (auto *ED = dyn_cast(TD)) {
>From a3c77212039245d9f4704567fd426f36a29e947f Mon Sep 17 00:00:00 2001
From: Nathan Ridge
Date: Sun, 9 Mar 2025 01:43:25 -0500
Subject: [PATCH 2/4] Expose resolveTypeToTagDecl() publically in
HeuristicResolver
---
clang/include/clang/Sema/HeuristicResolver.h | 4
clang/lib/Sema/HeuristicResolver.cpp | 9 -
2 files changed, 8 insertions(+), 5 deletions(-)
diff --git a/clang/include/clang/Sema/HeuristicResolver.h
b/clang/include/clang/Sema/HeuristicResolver.h
index f511815b40199..c971b9a6a7b51 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -81,6 +81,10 @@ class HeuristicResolver {
// could look up the name appearing on the RHS.
const QualType getPointeeType(QualType T) const;
+ // Heuristically resolve a possibly-dependent type `T` to a TagDecl
+ // in which a member's name can be looked up.
+ TagDecl *resolveTypeToTagDecl(QualType T) const;
+
private:
ASTContext &Ctx;
};
diff --git a/clang/lib/Sema/HeuristicResolver.cpp
b/clang/lib/Sema/HeuristicResolver.cpp
index 3c7918165ee42..11fe786fa91c6 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -47,6 +47,7 @@ class HeuristicResolverImpl {
std::vector
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
llvm::function_ref Filter);
+ TagDecl *resolveTypeToTagDecl(QualType T);
private:
ASTContext &Ctx;
@@ -72,11 +73,6 @@ class HeuristicResolverImpl {
QualType resolveExprToType(const Expr *E);
std::vector resolveExprToDecls(const Expr *E);
- // Helper function for HeuristicResolver::resolveDependentMember()
- // which takes a possibly-dependent type `T` and heuristically
- // resolves it to a TagDecl in which we can try name lookup.
- TagDecl *resolveTypeToTagDecl(QualType T);
-
// Helper function for simplifying a
