return Node->Parent && Node->Parent->ASTNode.get<TranslationUnitDecl>();
}
-// Returns the first visible context that contains this DeclContext.
-// For example: Returns ns1 for S1 and a.
-// namespace ns1 {
-// inline namespace ns2 { struct S1 {}; }
-// enum E { a, b, c, d };
-// }
-const DeclContext *visibleContext(const DeclContext *D) {
- while (D->isInlineNamespace() || D->isTransparentContext())
+// Return true if `LHS` is declared in `RHS`
+bool isDeclaredIn(const NamedDecl *LHS, const DeclContext *RHS) {
+ const auto *D = LHS->getDeclContext();
+ while (D->isInlineNamespace() || D->isTransparentContext()) {
+ if (D->Equals(RHS))
+ return true;
D = D->getParent();
- return D;
+ }
+ return D->Equals(RHS);
}
bool RemoveUsingNamespace::prepare(const Selection &Inputs) {
return; // This reference is already qualified.
for (auto *T : Ref.Targets) {
- if (!visibleContext(T->getDeclContext())
- ->Equals(TargetDirective->getNominatedNamespace()))
+ if (!isDeclaredIn(T, TargetDirective->getNominatedNamespace()))
return;
auto Kind = T->getDeclName().getNameKind();
// Avoid adding qualifiers before operators, e.g.
}
int main() { 1.5_w; }
+ )cpp"},
+ {
+ R"cpp(
+ namespace a { inline namespace b { void foobar(); } }
+ using namespace a::[[b]];
+ int main() { foobar(); }
+ )cpp",
+ R"cpp(
+ namespace a { inline namespace b { void foobar(); } }
+
+ int main() { a::b::foobar(); }
)cpp"}};
for (auto C : Cases)
EXPECT_EQ(C.second, apply(C.first)) << C.first;