Skip to content

Commit

Permalink
[clangd] Fix an assertion failure in TargetFinder's heuristic resolut…
Browse files Browse the repository at this point in the history
…ion of dependent type.

The assertion is not true anymore after D82739, this patch just removes
it, and rename related functions.

And also fixes a missing cases.

Differential Revision: https://reviews.llvm.org/D84837
  • Loading branch information
hokein committed Jul 30, 2020
1 parent 07bb824 commit cd4e8d7
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
28 changes: 14 additions & 14 deletions clang-tools-extra/clangd/FindTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,13 +163,12 @@ const Type *getPointeeType(const Type *T) {
}

// Forward declaration, needed as this function is mutually recursive
// with resolveDependentExprToDecls.
const Type *resolveDependentExprToType(const Expr *E);
// with resolveExprToDecls.
const Type *resolveExprToType(const Expr *E);

// Try to heuristically resolve a dependent expression `E` to one
// Try to heuristically resolve a possibly-dependent expression `E` to one
// or more declarations that it likely references.
std::vector<const NamedDecl *> resolveDependentExprToDecls(const Expr *E) {
assert(E->isTypeDependent());
std::vector<const NamedDecl *> resolveExprToDecls(const Expr *E) {
if (const auto *ME = dyn_cast<CXXDependentScopeMemberExpr>(E)) {
const Type *BaseType = ME->getBaseType().getTypePtrOrNull();
if (ME->isArrow()) {
Expand All @@ -183,7 +182,7 @@ std::vector<const NamedDecl *> resolveDependentExprToDecls(const Expr *E) {
// can get further by analyzing the depedent expression.
Expr *Base = ME->isImplicitAccess() ? nullptr : ME->getBase();
if (Base && BT->getKind() == BuiltinType::Dependent) {
BaseType = resolveDependentExprToType(Base);
BaseType = resolveExprToType(Base);
}
}
return getMembersReferencedViaDependentName(
Expand All @@ -197,7 +196,7 @@ std::vector<const NamedDecl *> resolveDependentExprToDecls(const Expr *E) {
/*IsNonstaticMember=*/false);
}
if (const auto *CE = dyn_cast<CallExpr>(E)) {
const auto *CalleeType = resolveDependentExprToType(CE->getCallee());
const auto *CalleeType = resolveExprToType(CE->getCallee());
if (!CalleeType)
return {};
if (const auto *FnTypePtr = CalleeType->getAs<PointerType>())
Expand All @@ -209,15 +208,16 @@ std::vector<const NamedDecl *> resolveDependentExprToDecls(const Expr *E) {
}
}
}
if (const auto *ME = dyn_cast<MemberExpr>(E)) {
if (const auto *ME = dyn_cast<MemberExpr>(E))
return {ME->getMemberDecl()};
}
if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
return {DRE->getFoundDecl()};
return {};
}

// Try to heuristically resolve the type of a dependent expression `E`.
const Type *resolveDependentExprToType(const Expr *E) {
std::vector<const NamedDecl *> Decls = resolveDependentExprToDecls(E);
// Try to heuristically resolve the type of a possibly-dependent expression `E`.
const Type *resolveExprToType(const Expr *E) {
std::vector<const NamedDecl *> Decls = resolveExprToDecls(E);
if (Decls.size() != 1) // Names an overload set -- just bail.
return nullptr;
if (const auto *TD = dyn_cast<TypeDecl>(Decls[0])) {
Expand Down Expand Up @@ -426,12 +426,12 @@ struct TargetFinder {
}
void
VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E) {
for (const NamedDecl *D : resolveDependentExprToDecls(E)) {
for (const NamedDecl *D : resolveExprToDecls(E)) {
Outer.add(D, Flags);
}
}
void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E) {
for (const NamedDecl *D : resolveDependentExprToDecls(E)) {
for (const NamedDecl *D : resolveExprToDecls(E)) {
Outer.add(D, Flags);
}
}
Expand Down
14 changes: 14 additions & 0 deletions clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,20 @@ TEST_F(TargetDeclTest, DependentExprs) {
};
)cpp";
EXPECT_DECLS("CXXDependentScopeMemberExpr", "int aaaa");

Code = R"cpp(
class Foo {
public:
static Foo k(int);
template <typename T> T convert() const;
};
template <typename T>
void test() {
Foo::k(T()).template [[convert]]<T>();
}
)cpp";
EXPECT_DECLS("CXXDependentScopeMemberExpr",
"template <typename T> T convert() const");
}

TEST_F(TargetDeclTest, ObjC) {
Expand Down

0 comments on commit cd4e8d7

Please sign in to comment.