[clang-tools-extra] r375226 - [clangd] Report declaration references in findExplicitReferences.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 18 05:07:19 PDT 2019
Author: hokein
Date: Fri Oct 18 05:07:19 2019
New Revision: 375226
URL: http://llvm.org/viewvc/llvm-project?rev=375226&view=rev
Log:
[clangd] Report declaration references in findExplicitReferences.
Reviewers: ilya-biryukov
Subscribers: MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D68977
Modified:
clang-tools-extra/trunk/clangd/AST.cpp
clang-tools-extra/trunk/clangd/AST.h
clang-tools-extra/trunk/clangd/FindTarget.cpp
clang-tools-extra/trunk/clangd/FindTarget.h
clang-tools-extra/trunk/clangd/XRefs.cpp
clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp
clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
Modified: clang-tools-extra/trunk/clangd/AST.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.cpp?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/AST.cpp (original)
+++ clang-tools-extra/trunk/clangd/AST.cpp Fri Oct 18 05:07:19 2019
@@ -103,16 +103,12 @@ static bool isAnonymous(const Declaratio
return N.isIdentifier() && !N.getAsIdentifierInfo();
}
-/// Returns a nested name specifier of \p ND if it was present in the source,
-/// e.g.
-/// void ns::something::foo() -> returns 'ns::something'
-/// void foo() -> returns null
-static NestedNameSpecifier *getQualifier(const NamedDecl &ND) {
+NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND) {
if (auto *V = llvm::dyn_cast<DeclaratorDecl>(&ND))
- return V->getQualifier();
+ return V->getQualifierLoc();
if (auto *T = llvm::dyn_cast<TagDecl>(&ND))
- return T->getQualifier();
- return nullptr;
+ return T->getQualifierLoc();
+ return NestedNameSpecifierLoc();
}
std::string printUsingNamespaceName(const ASTContext &Ctx,
@@ -153,7 +149,7 @@ std::string printName(const ASTContext &
}
// Print nested name qualifier if it was written in the source code.
- if (auto *Qualifier = getQualifier(ND))
+ if (auto *Qualifier = getQualifierLoc(ND).getNestedNameSpecifier())
Qualifier->print(Out, PP);
// Print the name itself.
ND.getDeclName().print(Out, PP);
Modified: clang-tools-extra/trunk/clangd/AST.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/AST.h?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/AST.h (original)
+++ clang-tools-extra/trunk/clangd/AST.h Fri Oct 18 05:07:19 2019
@@ -104,6 +104,12 @@ bool isImplicitTemplateInstantiation(con
/// explicit specialization.
bool isExplicitTemplateSpecialization(const NamedDecl *D);
+/// Returns a nested name specifier loc of \p ND if it was present in the
+/// source, e.g.
+/// void ns::something::foo() -> returns 'ns::something'
+/// void foo() -> returns null
+NestedNameSpecifierLoc getQualifierLoc(const NamedDecl &ND);
+
} // namespace clangd
} // namespace clang
Modified: clang-tools-extra/trunk/clangd/FindTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/FindTarget.cpp?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/FindTarget.cpp (original)
+++ clang-tools-extra/trunk/clangd/FindTarget.cpp Fri Oct 18 05:07:19 2019
@@ -412,63 +412,86 @@ explicitReferenceTargets(DynTypedNode N,
return Targets;
}
-Optional<ReferenceLoc> refInDecl(const Decl *D) {
+llvm::SmallVector<ReferenceLoc, 2> refInDecl(const Decl *D) {
struct Visitor : ConstDeclVisitor<Visitor> {
- llvm::Optional<ReferenceLoc> Ref;
+ llvm::SmallVector<ReferenceLoc, 2> Refs;
void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
- Ref = ReferenceLoc{D->getQualifierLoc(),
- D->getIdentLocation(),
- {D->getNominatedNamespaceAsWritten()}};
+ // We want to keep it as non-declaration references, as the
+ // "using namespace" declaration doesn't have a name.
+ Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
+ D->getIdentLocation(),
+ /*IsDecl=*/false,
+ {D->getNominatedNamespaceAsWritten()}});
}
void VisitUsingDecl(const UsingDecl *D) {
- Ref = ReferenceLoc{D->getQualifierLoc(), D->getLocation(),
- explicitReferenceTargets(DynTypedNode::create(*D),
- DeclRelation::Underlying)};
+ // "using ns::identifer;" is a non-declaration reference.
+ Refs.push_back(
+ ReferenceLoc{D->getQualifierLoc(), D->getLocation(), /*IsDecl=*/false,
+ explicitReferenceTargets(DynTypedNode::create(*D),
+ DeclRelation::Underlying)});
}
void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
- Ref = ReferenceLoc{D->getQualifierLoc(),
- D->getTargetNameLoc(),
- {D->getAliasedNamespace()}};
+ // For namespace alias, "namespace Foo = Target;", we add two references.
+ // Add a declaration reference for Foo.
+ VisitNamedDecl(D);
+ // Add a non-declaration reference for Target.
+ Refs.push_back(ReferenceLoc{D->getQualifierLoc(),
+ D->getTargetNameLoc(),
+ /*IsDecl=*/false,
+ {D->getAliasedNamespace()}});
+ }
+
+ void VisitNamedDecl(const NamedDecl *ND) {
+ // FIXME: decide on how to surface destructors when we need them.
+ if (llvm::isa<CXXDestructorDecl>(ND))
+ return;
+ Refs.push_back(ReferenceLoc{
+ getQualifierLoc(*ND), ND->getLocation(), /*IsDecl=*/true, {ND}});
}
};
Visitor V;
V.Visit(D);
- return V.Ref;
+ return V.Refs;
}
-Optional<ReferenceLoc> refInExpr(const Expr *E) {
+llvm::SmallVector<ReferenceLoc, 2> refInExpr(const Expr *E) {
struct Visitor : ConstStmtVisitor<Visitor> {
// FIXME: handle more complicated cases, e.g. ObjC, designated initializers.
- llvm::Optional<ReferenceLoc> Ref;
+ llvm::SmallVector<ReferenceLoc, 2> Refs;
void VisitDeclRefExpr(const DeclRefExpr *E) {
- Ref = ReferenceLoc{
- E->getQualifierLoc(), E->getNameInfo().getLoc(), {E->getFoundDecl()}};
+ Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
+ E->getNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ {E->getFoundDecl()}});
}
void VisitMemberExpr(const MemberExpr *E) {
- Ref = ReferenceLoc{E->getQualifierLoc(),
- E->getMemberNameInfo().getLoc(),
- {E->getFoundDecl()}};
+ Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
+ E->getMemberNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ {E->getFoundDecl()}});
}
void VisitOverloadExpr(const OverloadExpr *E) {
- Ref = ReferenceLoc{E->getQualifierLoc(), E->getNameInfo().getLoc(),
- llvm::SmallVector<const NamedDecl *, 1>(
- E->decls().begin(), E->decls().end())};
+ Refs.push_back(ReferenceLoc{E->getQualifierLoc(),
+ E->getNameInfo().getLoc(),
+ /*IsDecl=*/false,
+ llvm::SmallVector<const NamedDecl *, 1>(
+ E->decls().begin(), E->decls().end())});
}
};
Visitor V;
V.Visit(E);
- return V.Ref;
+ return V.Refs;
}
-Optional<ReferenceLoc> refInTypeLoc(TypeLoc L) {
+llvm::SmallVector<ReferenceLoc, 2> refInTypeLoc(TypeLoc L) {
struct Visitor : TypeLocVisitor<Visitor> {
llvm::Optional<ReferenceLoc> Ref;
@@ -483,13 +506,17 @@ Optional<ReferenceLoc> refInTypeLoc(Type
}
void VisitTagTypeLoc(TagTypeLoc L) {
- Ref =
- ReferenceLoc{NestedNameSpecifierLoc(), L.getNameLoc(), {L.getDecl()}};
+ Ref = ReferenceLoc{NestedNameSpecifierLoc(),
+ L.getNameLoc(),
+ /*IsDecl=*/false,
+ {L.getDecl()}};
}
void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
- Ref =
- ReferenceLoc{NestedNameSpecifierLoc(), L.getNameLoc(), {L.getDecl()}};
+ Ref = ReferenceLoc{NestedNameSpecifierLoc(),
+ L.getNameLoc(),
+ /*IsDecl=*/false,
+ {L.getDecl()}};
}
void VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc L) {
@@ -502,14 +529,14 @@ Optional<ReferenceLoc> refInTypeLoc(Type
// 2. 'vector<int>' with mask 'Underlying'.
// we want to return only #1 in this case.
Ref = ReferenceLoc{
- NestedNameSpecifierLoc(), L.getTemplateNameLoc(),
+ NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()),
DeclRelation::Alias)};
}
void VisitDeducedTemplateSpecializationTypeLoc(
DeducedTemplateSpecializationTypeLoc L) {
Ref = ReferenceLoc{
- NestedNameSpecifierLoc(), L.getNameLoc(),
+ NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()),
DeclRelation::Alias)};
}
@@ -517,25 +544,29 @@ Optional<ReferenceLoc> refInTypeLoc(Type
void VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc L) {
Ref = ReferenceLoc{
- L.getQualifierLoc(), L.getTemplateNameLoc(),
+ L.getQualifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()))};
}
void VisitDependentNameTypeLoc(DependentNameTypeLoc L) {
Ref = ReferenceLoc{
- L.getQualifierLoc(), L.getNameLoc(),
+ L.getQualifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()))};
}
void VisitTypedefTypeLoc(TypedefTypeLoc L) {
- Ref = ReferenceLoc{
- NestedNameSpecifierLoc(), L.getNameLoc(), {L.getTypedefNameDecl()}};
+ Ref = ReferenceLoc{NestedNameSpecifierLoc(),
+ L.getNameLoc(),
+ /*IsDecl=*/false,
+ {L.getTypedefNameDecl()}};
}
};
Visitor V;
V.Visit(L.getUnqualifiedLoc());
- return V.Ref;
+ if (!V.Ref)
+ return {};
+ return {*V.Ref};
}
class ExplicitReferenceColletor
@@ -575,6 +606,7 @@ public:
case TemplateArgument::TemplateExpansion:
reportReference(ReferenceLoc{A.getTemplateQualifierLoc(),
A.getTemplateNameLoc(),
+ /*IsDecl=*/false,
{A.getArgument()
.getAsTemplateOrTemplatePattern()
.getAsTemplateDecl()}},
@@ -625,34 +657,33 @@ private:
/// be references. However, declarations can have references inside them,
/// e.g. 'namespace foo = std' references namespace 'std' and this
/// function will return the corresponding reference.
- llvm::Optional<ReferenceLoc> explicitReference(DynTypedNode N) {
+ llvm::SmallVector<ReferenceLoc, 2> explicitReference(DynTypedNode N) {
if (auto *D = N.get<Decl>())
return refInDecl(D);
if (auto *E = N.get<Expr>())
return refInExpr(E);
if (auto *NNSL = N.get<NestedNameSpecifierLoc>())
- return ReferenceLoc{NNSL->getPrefix(), NNSL->getLocalBeginLoc(),
- explicitReferenceTargets(DynTypedNode::create(
- *NNSL->getNestedNameSpecifier()))};
+ return {ReferenceLoc{NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false,
+ explicitReferenceTargets(DynTypedNode::create(
+ *NNSL->getNestedNameSpecifier()))}};
if (const TypeLoc *TL = N.get<TypeLoc>())
return refInTypeLoc(*TL);
if (const CXXCtorInitializer *CCI = N.get<CXXCtorInitializer>()) {
if (CCI->isBaseInitializer())
return refInTypeLoc(CCI->getBaseClassLoc());
assert(CCI->isAnyMemberInitializer());
- return ReferenceLoc{NestedNameSpecifierLoc(),
- CCI->getMemberLocation(),
- {CCI->getAnyMember()}};
+ return {ReferenceLoc{NestedNameSpecifierLoc(),
+ CCI->getMemberLocation(),
+ /*IsDecl=*/false,
+ {CCI->getAnyMember()}}};
}
// We do not have location information for other nodes (QualType, etc)
- return llvm::None;
+ return {};
}
void visitNode(DynTypedNode N) {
- auto Ref = explicitReference(N);
- if (!Ref)
- return;
- reportReference(*Ref, N);
+ for (const auto &R : explicitReference(N))
+ reportReference(R, N);
}
void reportReference(const ReferenceLoc &Ref, DynTypedNode N) {
@@ -727,6 +758,8 @@ llvm::raw_ostream &operator<<(llvm::raw_
PrintingPolicy(LangOptions()));
OS << "'";
}
+ if (R.IsDecl)
+ OS << ", decl";
return OS;
}
Modified: clang-tools-extra/trunk/clangd/FindTarget.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/FindTarget.h?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/FindTarget.h (original)
+++ clang-tools-extra/trunk/clangd/FindTarget.h Fri Oct 18 05:07:19 2019
@@ -86,6 +86,8 @@ struct ReferenceLoc {
NestedNameSpecifierLoc Qualifier;
/// Start location of the last name part, i.e. 'foo' in 'ns::foo<int>'.
SourceLocation NameLoc;
+ /// True if the reference is a declaration or definition;
+ bool IsDecl = false;
// FIXME: add info about template arguments.
/// A list of targets referenced by this name. Normally this has a single
/// element, but multiple is also possible, e.g. in case of using declarations
Modified: clang-tools-extra/trunk/clangd/XRefs.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/XRefs.cpp?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/XRefs.cpp (original)
+++ clang-tools-extra/trunk/clangd/XRefs.cpp Fri Oct 18 05:07:19 2019
@@ -1308,7 +1308,8 @@ llvm::DenseSet<const Decl *> getNonLocal
llvm::DenseSet<const Decl *> DeclRefs;
findExplicitReferences(FD, [&](ReferenceLoc Ref) {
for (const Decl *D : Ref.Targets) {
- if (!index::isFunctionLocalSymbol(D) && !D->isTemplateParameter())
+ if (!index::isFunctionLocalSymbol(D) && !D->isTemplateParameter() &&
+ !Ref.IsDecl)
DeclRefs.insert(D);
}
});
Modified: clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/FindTargetTests.cpp Fri Oct 18 05:07:19 2019
@@ -622,53 +622,61 @@ TEST_F(FindExplicitReferencesTest, All)
struct Struct { int a; };
using Typedef = int;
void foo() {
- $0^Struct x;
- $1^Typedef y;
- static_cast<$2^Struct*>(0);
+ $0^Struct $1^x;
+ $2^Typedef $3^y;
+ static_cast<$4^Struct*>(0);
}
)cpp",
"0: targets = {Struct}\n"
- "1: targets = {Typedef}\n"
- "2: targets = {Struct}\n"},
+ "1: targets = {x}, decl\n"
+ "2: targets = {Typedef}\n"
+ "3: targets = {y}, decl\n"
+ "4: targets = {Struct}\n"},
// Name qualifiers.
{R"cpp(
namespace a { namespace b { struct S { typedef int type; }; } }
void foo() {
- $0^a::$1^b::$2^S x;
- using namespace $3^a::$4^b;
- $5^S::$6^type y;
+ $0^a::$1^b::$2^S $3^x;
+ using namespace $4^a::$5^b;
+ $6^S::$7^type $8^y;
}
)cpp",
"0: targets = {a}\n"
"1: targets = {a::b}, qualifier = 'a::'\n"
"2: targets = {a::b::S}, qualifier = 'a::b::'\n"
- "3: targets = {a}\n"
- "4: targets = {a::b}, qualifier = 'a::'\n"
- "5: targets = {a::b::S}\n"
- "6: targets = {a::b::S::type}, qualifier = 'struct S::'\n"},
+ "3: targets = {x}, decl\n"
+ "4: targets = {a}\n"
+ "5: targets = {a::b}, qualifier = 'a::'\n"
+ "6: targets = {a::b::S}\n"
+ "7: targets = {a::b::S::type}, qualifier = 'struct S::'\n"
+ "8: targets = {y}, decl\n"},
// Simple templates.
{R"cpp(
template <class T> struct vector { using value_type = T; };
template <> struct vector<bool> { using value_type = bool; };
void foo() {
- $0^vector<int> vi;
- $1^vector<bool> vb;
+ $0^vector<int> $1^vi;
+ $2^vector<bool> $3^vb;
}
)cpp",
"0: targets = {vector<int>}\n"
- "1: targets = {vector<bool>}\n"},
+ "1: targets = {vi}, decl\n"
+ "2: targets = {vector<bool>}\n"
+ "3: targets = {vb}, decl\n"},
// Template type aliases.
{R"cpp(
template <class T> struct vector { using value_type = T; };
template <> struct vector<bool> { using value_type = bool; };
template <class T> using valias = vector<T>;
void foo() {
- $0^valias<int> vi;
- $1^valias<bool> vb;
+ $0^valias<int> $1^vi;
+ $2^valias<bool> $3^vb;
}
)cpp",
"0: targets = {valias}\n"
- "1: targets = {valias}\n"},
+ "1: targets = {vi}, decl\n"
+ "2: targets = {valias}\n"
+ "3: targets = {vb}, decl\n"},
// MemberExpr should know their using declaration.
{R"cpp(
struct X { void func(int); }
@@ -710,13 +718,14 @@ TEST_F(FindExplicitReferencesTest, All)
};
void foo() {
- for (int x : $0^vector()) {
- $1^x = 10;
+ for (int $0^x : $1^vector()) {
+ $2^x = 10;
}
}
)cpp",
- "0: targets = {vector}\n"
- "1: targets = {x}\n"},
+ "0: targets = {x}, decl\n"
+ "1: targets = {vector}\n"
+ "2: targets = {x}\n"},
// Handle UnresolvedLookupExpr.
{R"cpp(
namespace ns1 { void func(char*); }
@@ -752,39 +761,42 @@ TEST_F(FindExplicitReferencesTest, All)
void foo() {
static_cast<$0^T>(0);
$1^T();
- $2^T t;
+ $2^T $3^t;
}
)cpp",
"0: targets = {T}\n"
"1: targets = {T}\n"
- "2: targets = {T}\n"},
+ "2: targets = {T}\n"
+ "3: targets = {t}, decl\n"},
// Non-type template parameters.
{R"cpp(
template <int I>
void foo() {
- int x = $0^I;
+ int $0^x = $1^I;
}
)cpp",
- "0: targets = {I}\n"},
+ "0: targets = {x}, decl\n"
+ "1: targets = {I}\n"},
// Template template parameters.
{R"cpp(
template <class T> struct vector {};
template <template<class> class TT, template<class> class ...TP>
void foo() {
- $0^TT<int> x;
- $1^foo<$2^TT>();
- $3^foo<$4^vector>()
- $5^foo<$6^TP...>();
+ $0^TT<int> $1^x;
+ $2^foo<$3^TT>();
+ $4^foo<$5^vector>()
+ $6^foo<$7^TP...>();
}
)cpp",
"0: targets = {TT}\n"
- "1: targets = {foo}\n"
- "2: targets = {TT}\n"
- "3: targets = {foo}\n"
- "4: targets = {vector}\n"
- "5: targets = {foo}\n"
- "6: targets = {TP}\n"},
+ "1: targets = {x}, decl\n"
+ "2: targets = {foo}\n"
+ "3: targets = {TT}\n"
+ "4: targets = {foo}\n"
+ "5: targets = {vector}\n"
+ "6: targets = {foo}\n"
+ "7: targets = {TP}\n"},
// Non-type template parameters with declarations.
{R"cpp(
int func();
@@ -792,13 +804,37 @@ TEST_F(FindExplicitReferencesTest, All)
template <int(*FuncParam)()>
void foo() {
- $0^wrapper<$1^func> w;
- $2^FuncParam();
+ $0^wrapper<$1^func> $2^w;
+ $3^FuncParam();
}
)cpp",
"0: targets = {wrapper<&func>}\n"
"1: targets = {func}\n"
- "2: targets = {FuncParam}\n"},
+ "2: targets = {w}, decl\n"
+ "3: targets = {FuncParam}\n"},
+ {R"cpp(
+ namespace ns {}
+ class S {};
+ void foo() {
+ class $0^Foo { $1^Foo(); ~$2^Foo(); int $3^field; };
+ int $4^Var;
+ enum $5^E { $6^ABC };
+ typedef int $7^INT;
+ using $8^INT2 = int;
+ namespace $9^NS = $10^ns;
+ }
+ )cpp",
+ "0: targets = {Foo}, decl\n"
+ "1: targets = {foo()::Foo::Foo}, decl\n"
+ "2: targets = {Foo}\n"
+ "3: targets = {foo()::Foo::field}, decl\n"
+ "4: targets = {Var}, decl\n"
+ "5: targets = {E}, decl\n"
+ "6: targets = {foo()::ABC}, decl\n"
+ "7: targets = {INT}, decl\n"
+ "8: targets = {INT2}, decl\n"
+ "9: targets = {NS}, decl\n"
+ "10: targets = {ns}\n"},
};
for (const auto &C : Cases) {
Modified: clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp?rev=375226&r1=375225&r2=375226&view=diff
==============================================================================
--- clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp (original)
+++ clang-tools-extra/trunk/clangd/unittests/XRefsTests.cpp Fri Oct 18 05:07:19 2019
@@ -2284,7 +2284,8 @@ TEST(GetNonLocalDeclRefs, All) {
if (const auto *ND = llvm::dyn_cast<NamedDecl>(D))
Names.push_back(ND->getQualifiedNameAsString());
}
- EXPECT_THAT(Names, UnorderedElementsAreArray(C.ExpectedDecls));
+ EXPECT_THAT(Names, UnorderedElementsAreArray(C.ExpectedDecls))
+ << File.code();
}
}
More information about the cfe-commits
mailing list