[clang] 4a9eaad - [Clang][AST][NFC] Introduce `NamespaceBaseDecl` (#149123)
via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 17 18:01:51 PDT 2025
Author: Yanzuo Liu
Date: 2025-07-18T09:01:47+08:00
New Revision: 4a9eaad9e1283b872788832d5bce7e7945b97c78
URL: https://github.com/llvm/llvm-project/commit/4a9eaad9e1283b872788832d5bce7e7945b97c78
DIFF: https://github.com/llvm/llvm-project/commit/4a9eaad9e1283b872788832d5bce7e7945b97c78.diff
LOG: [Clang][AST][NFC] Introduce `NamespaceBaseDecl` (#149123)
Add `NamespaceBaseDecl` as common base class of `NamespaceDecl` and
`NamespaceAliasDecl`. This simplifies `NestedNameSpecifier` a bit.
Co-authored-by: Matheus Izvekov <mizvekov at gmail.com>
Added:
Modified:
clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
clang-tools-extra/clangd/AST.cpp
clang-tools-extra/clangd/CodeComplete.cpp
clang-tools-extra/clangd/DumpAST.cpp
clang-tools-extra/clangd/FindTarget.cpp
clang-tools-extra/clangd/IncludeFixer.cpp
clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
clang-tools-extra/include-cleaner/lib/WalkAST.cpp
clang/include/clang/AST/AbstractBasicReader.h
clang/include/clang/AST/AbstractBasicWriter.h
clang/include/clang/AST/Decl.h
clang/include/clang/AST/DeclCXX.h
clang/include/clang/AST/NestedNameSpecifier.h
clang/include/clang/AST/PropertiesBase.td
clang/include/clang/AST/RecursiveASTVisitor.h
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/include/clang/Basic/DeclNodes.td
clang/include/clang/Sema/DeclSpec.h
clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
clang/lib/AST/ASTContext.cpp
clang/lib/AST/ASTImporter.cpp
clang/lib/AST/ASTStructuralEquivalence.cpp
clang/lib/AST/DeclCXX.cpp
clang/lib/AST/ItaniumMangle.cpp
clang/lib/AST/NestedNameSpecifier.cpp
clang/lib/AST/ODRHash.cpp
clang/lib/AST/QualTypeNames.cpp
clang/lib/AST/TextNodeDumper.cpp
clang/lib/ExtractAPI/DeclarationFragments.cpp
clang/lib/Index/IndexTypeSourceInfo.cpp
clang/lib/Parse/ParseDeclCXX.cpp
clang/lib/Sema/DeclSpec.cpp
clang/lib/Sema/SemaCXXScopeSpec.cpp
clang/lib/Sema/SemaDeclCXX.cpp
clang/lib/Sema/SemaExprCXX.cpp
clang/lib/Sema/SemaLookup.cpp
clang/lib/Sema/SemaTemplate.cpp
clang/lib/Sema/TreeTransform.h
clang/lib/Serialization/ASTReader.cpp
clang/lib/Serialization/ASTReaderDecl.cpp
clang/lib/Serialization/ASTWriter.cpp
clang/lib/Tooling/Syntax/BuildTree.cpp
clang/tools/libclang/CIndex.cpp
clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
clang/unittests/Tooling/RefactoringTest.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index 33642c407a3a9..bfa2ab51a6d03 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -45,7 +45,7 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
// We still conservatively put a "std::" in front of the forward because
// we don't know whether the code also had a "using std::forward;".
Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
- } else if (const NamespaceDecl *Namespace = NNS->getAsNamespace()) {
+ } else if (const NamespaceBaseDecl *Namespace = NNS->getAsNamespace()) {
if (Namespace->getName() == "std") {
if (!NNS->getPrefix()) {
// Called as "std::move".
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
index 2dfaca19a8981..86992cd8a141b 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
@@ -36,7 +36,8 @@ void UnusedAliasDeclsCheck::check(const MatchFinder::MatchResult &Result) {
if (const auto *NestedName =
Result.Nodes.getNodeAs<NestedNameSpecifier>("nns")) {
- if (const auto *AliasDecl = NestedName->getAsNamespaceAlias()) {
+ if (const auto *AliasDecl = dyn_cast_if_present<NamespaceAliasDecl>(
+ NestedName->getAsNamespace())) {
FoundDecls[AliasDecl] = CharSourceRange();
}
}
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 6cf38ddf3d914..dd28806e008ed 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -282,7 +282,8 @@ class RenamerClangTidyVisitor
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc Loc) {
if (const NestedNameSpecifier *Spec = Loc.getNestedNameSpecifier()) {
- if (const NamespaceDecl *Decl = Spec->getAsNamespace())
+ if (const auto *Decl =
+ dyn_cast_if_present<NamespaceDecl>(Spec->getAsNamespace()))
Check->addUsage(Decl, Loc.getLocalSourceRange(), SM);
}
diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index e274236527817..f2631e5abb6a3 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -666,12 +666,14 @@ std::string getQualification(ASTContext &Context,
return getQualification(
Context, DestContext, ND->getDeclContext(),
[&](NestedNameSpecifier *NNS) {
- if (NNS->getKind() != NestedNameSpecifier::Namespace)
+ const NamespaceDecl *NS =
+ dyn_cast_if_present<NamespaceDecl>(NNS->getAsNamespace());
+ if (!NS)
return false;
- const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
+ NS = NS->getCanonicalDecl();
return llvm::any_of(VisibleNamespaceDecls,
- [CanonNSD](const NamespaceDecl *NSD) {
- return NSD->getCanonicalDecl() == CanonNSD;
+ [NS](const NamespaceDecl *NSD) {
+ return NSD->getCanonicalDecl() == NS;
});
});
}
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index d5907e3143bf6..184c3c962f063 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -1470,7 +1470,6 @@ bool allowIndex(CodeCompletionContext &CC) {
switch (NameSpec->getKind()) {
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
return true;
case NestedNameSpecifier::Super:
case NestedNameSpecifier::TypeSpec:
diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp
index 8f24477ecd3de..c6075e75e9a6b 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -158,7 +158,6 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
NNS_KIND(TypeSpec);
NNS_KIND(Global);
NNS_KIND(Super);
- NNS_KIND(NamespaceAlias);
#undef NNS_KIND
}
llvm_unreachable("Unhandled SpecifierKind enum");
@@ -281,8 +280,6 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
return NNS.getAsIdentifier()->getName().str() + "::";
case NestedNameSpecifier::Namespace:
return NNS.getAsNamespace()->getNameAsString() + "::";
- case NestedNameSpecifier::NamespaceAlias:
- return NNS.getAsNamespaceAlias()->getNameAsString() + "::";
default:
return "";
}
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 91fd3b0f8567b..b1089577ba819 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -491,9 +491,6 @@ struct TargetFinder {
case NestedNameSpecifier::Namespace:
add(NNS->getAsNamespace(), Flags);
return;
- case NestedNameSpecifier::NamespaceAlias:
- add(NNS->getAsNamespaceAlias(), Flags);
- return;
case NestedNameSpecifier::Identifier:
if (Resolver) {
add(Resolver->resolveNestedNameSpecifierToType(NNS), Flags);
diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp
index 4ff021c4c390a..50bc2bd7ccb94 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -403,25 +403,27 @@ std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
if (auto *Nested = SS->getScopeRep()) {
if (Nested->getKind() == NestedNameSpecifier::Global) {
Result.ResolvedScope = "";
- } else if (const auto *NS = Nested->getAsNamespace()) {
- std::string SpecifiedNS = printNamespaceScope(*NS);
- std::optional<std::string> Spelling = getSpelledSpecifier(*SS, SM);
-
- // Check the specifier spelled in the source.
- // If the resolved scope doesn't end with the spelled scope, the
- // resolved scope may come from a sema typo correction. For example,
- // sema assumes that "clangd::" is a typo of "clang::" and uses
- // "clang::" as the specified scope in:
- // namespace clang { clangd::X; }
- // In this case, we use the "typo" specifier as extra scope instead
- // of using the scope assumed by sema.
- if (!Spelling || llvm::StringRef(SpecifiedNS).ends_with(*Spelling)) {
- Result.ResolvedScope = std::move(SpecifiedNS);
+ } else if (const NamespaceBaseDecl *NSB = Nested->getAsNamespace()) {
+ if (const auto *NS = dyn_cast<NamespaceDecl>(NSB)) {
+ std::string SpecifiedNS = printNamespaceScope(*NS);
+ std::optional<std::string> Spelling = getSpelledSpecifier(*SS, SM);
+
+ // Check the specifier spelled in the source.
+ // If the resolved scope doesn't end with the spelled scope, the
+ // resolved scope may come from a sema typo correction. For example,
+ // sema assumes that "clangd::" is a typo of "clang::" and uses
+ // "clang::" as the specified scope in:
+ // namespace clang { clangd::X; }
+ // In this case, we use the "typo" specifier as extra scope instead
+ // of using the scope assumed by sema.
+ if (!Spelling || llvm::StringRef(SpecifiedNS).ends_with(*Spelling)) {
+ Result.ResolvedScope = std::move(SpecifiedNS);
+ } else {
+ Result.UnresolvedScope = std::move(*Spelling);
+ }
} else {
- Result.UnresolvedScope = std::move(*Spelling);
+ Result.ResolvedScope = printNamespaceScope(*cast<NamespaceAliasDecl>(NSB)->getNamespace());
}
- } else if (const auto *ANS = Nested->getAsNamespaceAlias()) {
- Result.ResolvedScope = printNamespaceScope(*ANS->getNamespace());
} else {
// We don't fix symbols in scopes that are not top-level e.g. class
// members, as we don't collect includes for them.
diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
index 00c05ebdb5216..67fc451a6a1a1 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
@@ -173,7 +173,8 @@ findInsertionPoint(const Tweak::Selection &Inputs,
if (SM.isBeforeInTranslationUnit(Inputs.Cursor, U->getUsingLoc()))
// "Usings" is sorted, so we're done.
break;
- if (const auto *Namespace = U->getQualifier()->getAsNamespace()) {
+ if (const auto *Namespace = dyn_cast_if_present<NamespaceDecl>(
+ U->getQualifier()->getAsNamespace())) {
if (Namespace->getCanonicalDecl() ==
QualifierToRemove.getNestedNameSpecifier()
->getAsNamespace()
@@ -232,7 +233,10 @@ findInsertionPoint(const Tweak::Selection &Inputs,
bool isNamespaceForbidden(const Tweak::Selection &Inputs,
const NestedNameSpecifier &Namespace) {
- std::string NamespaceStr = printNamespaceScope(*Namespace.getAsNamespace());
+ const auto *NS = dyn_cast<NamespaceDecl>(Namespace.getAsNamespace());
+ if (!NS)
+ return true;
+ std::string NamespaceStr = printNamespaceScope(*NS);
for (StringRef Banned : Config::current().Style.FullyQualifiedNamespaces) {
StringRef PrefixMatch = NamespaceStr;
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index baff90faa6eae..49cc13606f4c2 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -140,7 +140,6 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
return true;
switch (Qual->getKind()) {
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
return true;
case NestedNameSpecifier::TypeSpec:
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 514f4cef3a694..0a2db9e205c7c 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -269,12 +269,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
case NestedNameSpecifier::Namespace:
cur = NestedNameSpecifier::Create(ctx, cur,
- asImpl().readNamespaceDeclRef());
- continue;
-
- case NestedNameSpecifier::NamespaceAlias:
- cur = NestedNameSpecifier::Create(ctx, cur,
- asImpl().readNamespaceAliasDeclRef());
+ asImpl().readNamespaceBaseDeclRef());
continue;
case NestedNameSpecifier::TypeSpec:
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index fedde8a2e46c5..c105bbbe45c92 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -251,11 +251,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
continue;
case NestedNameSpecifier::Namespace:
- asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
- continue;
-
- case NestedNameSpecifier::NamespaceAlias:
- asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
+ asImpl().writeNamespaceBaseDeclRef(NNS->getAsNamespace());
continue;
case NestedNameSpecifier::TypeSpec:
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index c75e29c861f82..08fe1f881503b 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -565,8 +565,28 @@ class LabelDecl : public NamedDecl {
static bool classofKind(Kind K) { return K == Label; }
};
+/// Represents C++ namespaces and their aliases.
+///
+/// FIXME: Move `NamespaceBaseDecl` and `NamespaceDecl` to "DeclCXX.h" or
+/// explain why not moving.
+class NamespaceBaseDecl : public NamedDecl {
+protected:
+ using NamedDecl::NamedDecl;
+
+public:
+ NamespaceDecl *getNamespace();
+ const NamespaceDecl *getNamespace() const {
+ return const_cast<NamespaceBaseDecl *>(this)->getNamespace();
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K >= firstNamespaceBase && K <= lastNamespaceBase;
+ }
+};
+
/// Represent a C++ namespace.
-class NamespaceDecl : public NamedDecl,
+class NamespaceDecl : public NamespaceBaseDecl,
public DeclContext,
public Redeclarable<NamespaceDecl> {
/// The starting location of the source range, pointing
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 77bc3cad72ed9..33ae3d604020b 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -3186,7 +3186,7 @@ class UsingDirectiveDecl : public NamedDecl {
/// \code
/// namespace Foo = Bar;
/// \endcode
-class NamespaceAliasDecl : public NamedDecl,
+class NamespaceAliasDecl : public NamespaceBaseDecl,
public Redeclarable<NamespaceAliasDecl> {
friend class ASTDeclReader;
@@ -3203,14 +3203,14 @@ class NamespaceAliasDecl : public NamedDecl,
/// The Decl that this alias points to, either a NamespaceDecl or
/// a NamespaceAliasDecl.
- NamedDecl *Namespace;
+ NamespaceBaseDecl *Namespace;
NamespaceAliasDecl(ASTContext &C, DeclContext *DC,
SourceLocation NamespaceLoc, SourceLocation AliasLoc,
IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), redeclarable_base(C),
- NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
+ SourceLocation IdentLoc, NamespaceBaseDecl *Namespace)
+ : NamespaceBaseDecl(NamespaceAlias, DC, AliasLoc, Alias),
+ redeclarable_base(C), NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
QualifierLoc(QualifierLoc), Namespace(Namespace) {}
void anchor() override;
@@ -3222,13 +3222,11 @@ class NamespaceAliasDecl : public NamedDecl,
NamespaceAliasDecl *getMostRecentDeclImpl() override;
public:
- static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace);
+ static NamespaceAliasDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc,
+ NamespaceBaseDecl *Namespace);
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
@@ -3282,7 +3280,7 @@ class NamespaceAliasDecl : public NamedDecl,
/// Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
- NamedDecl *getAliasedNamespace() const { return Namespace; }
+ NamespaceBaseDecl *getAliasedNamespace() const { return Namespace; }
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h
index 952c79753d10a..1614f9d7c94e4 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -31,8 +31,7 @@ class ASTContext;
class CXXRecordDecl;
class IdentifierInfo;
class LangOptions;
-class NamespaceAliasDecl;
-class NamespaceDecl;
+class NamespaceBaseDecl;
struct PrintingPolicy;
class Type;
class TypeLoc;
@@ -79,12 +78,9 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
/// An identifier, stored as an IdentifierInfo*.
Identifier,
- /// A namespace, stored as a NamespaceDecl*.
+ /// A namespace-like entity, stored as a NamespaceBaseDecl*.
Namespace,
- /// A namespace alias, stored as a NamespaceAliasDecl*.
- NamespaceAlias,
-
/// A type, stored as a Type*.
TypeSpec,
@@ -121,15 +117,10 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
NestedNameSpecifier *Prefix,
const IdentifierInfo *II);
- /// Builds a nested name specifier that names a namespace.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceDecl *NS);
-
- /// Builds a nested name specifier that names a namespace alias.
+ /// Builds a nested name specifier that names a namespace or namespace alias.
static NestedNameSpecifier *Create(const ASTContext &Context,
NestedNameSpecifier *Prefix,
- const NamespaceAliasDecl *Alias);
+ const NamespaceBaseDecl *NS);
/// Builds a nested name specifier that names a type.
static NestedNameSpecifier *
@@ -174,13 +165,9 @@ class NestedNameSpecifier : public llvm::FoldingSetNode {
return nullptr;
}
- /// Retrieve the namespace stored in this nested name
+ /// Retrieve the namespace or namespace alias stored in this nested name
/// specifier.
- NamespaceDecl *getAsNamespace() const;
-
- /// Retrieve the namespace alias stored in this nested name
- /// specifier.
- NamespaceAliasDecl *getAsNamespaceAlias() const;
+ NamespaceBaseDecl *getAsNamespace() const;
/// Retrieve the record declaration stored in this nested name
/// specifier.
@@ -425,29 +412,15 @@ class NestedNameSpecifierLocBuilder {
/// \param Context The AST context in which this nested-name-specifier
/// resides.
///
- /// \param Namespace The namespace.
+ /// \param Namespace The namespace or namespace alias.
///
- /// \param NamespaceLoc The location of the namespace name.
+ /// \param NamespaceLoc The location of the namespace name or the namespace
+ // alias.
///
/// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ void Extend(ASTContext &Context, NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace-alias::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
/// Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 1215056ffde1b..0438e4dfbafac 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -91,6 +91,7 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"FunctionDecl", DeclRef>;
def NamedDeclRef :
SubclassPropertyType<"NamedDecl", DeclRef>;
+ def NamespaceBaseDeclRef : SubclassPropertyType<"NamespaceBaseDecl", DeclRef>;
def NamespaceDeclRef :
SubclassPropertyType<"NamespaceDecl", DeclRef>;
def NamespaceAliasDeclRef :
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 5cb2f57edffe4..519a811775c01 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -789,7 +789,6 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Super:
return true;
@@ -813,7 +812,6 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Super:
return true;
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index b364b6556d0b3..08c898f7758ec 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -7894,9 +7894,9 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
/// matches "ns::"
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
internal::Matcher<NamespaceDecl>, InnerMatcher) {
- if (!Node.getAsNamespace())
- return false;
- return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
+ if (auto *NS = dyn_cast_if_present<NamespaceDecl>(Node.getAsNamespace()))
+ return InnerMatcher.matches(*NS, Finder, Builder);
+ return false;
}
/// Matches attributes.
diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td
index f1ebaf1db3fc0..8d6731b50f509 100644
--- a/clang/include/clang/Basic/DeclNodes.td
+++ b/clang/include/clang/Basic/DeclNodes.td
@@ -15,9 +15,10 @@ def PragmaComment : DeclNode<Decl>;
def PragmaDetectMismatch : DeclNode<Decl>;
def ExternCContext : DeclNode<Decl>, DeclContext;
def Named : DeclNode<Decl, "named declarations", 1>;
- def Namespace : DeclNode<Named, "namespaces">, DeclContext;
+ def NamespaceBase : DeclNode<Named, "namespace declarations", 1>;
+ def Namespace : DeclNode<NamespaceBase, "namespaces">, DeclContext;
+ def NamespaceAlias : DeclNode<NamespaceBase>;
def UsingDirective : DeclNode<Named>;
- def NamespaceAlias : DeclNode<Named>;
def Label : DeclNode<Named, "labels">;
def Type : DeclNode<Named, "types", 1>;
def TypedefName : DeclNode<Type, "typedefs", 1>;
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 4b7c8d609735f..e5680813e74de 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -44,8 +44,7 @@ namespace clang {
class TypeLoc;
class LangOptions;
class IdentifierInfo;
- class NamespaceAliasDecl;
- class NamespaceDecl;
+ class NamespaceBaseDecl;
class ObjCDeclSpec;
class Sema;
class Declarator;
@@ -129,29 +128,15 @@ class CXXScopeSpec {
/// \param Context The AST context in which this nested-name-specifier
/// resides.
///
- /// \param Namespace The namespace.
+ /// \param Namespace The namespace or the namespace alias.
///
- /// \param NamespaceLoc The location of the namespace name.
+ /// \param NamespaceLoc The location of the namespace name or the namespace
+ /// alias.
///
/// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ void Extend(ASTContext &Context, NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace-alias::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
/// Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
diff --git a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index 015dbba26f688..271232e66626e 100644
--- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -115,7 +115,8 @@ class RecursiveSymbolVisitor
// The base visitor will visit NNSL prefixes, so we should only look at
// the current NNS.
if (NNS) {
- const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
+ const auto *ND = dyn_cast_if_present<NamespaceDecl>(
+ NNS.getNestedNameSpecifier()->getAsNamespace());
if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
return false;
}
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 50bd93a143a28..232a4b6557b92 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -7387,21 +7387,9 @@ bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X,
return hasSameTemplateName(TAX.getAsTemplate(), TAY.getAsTemplate());
}
-static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) {
- if (auto *NS = X->getAsNamespace())
- return NS;
- if (auto *NAS = X->getAsNamespaceAlias())
- return NAS->getNamespace();
- return nullptr;
-}
-
static bool isSameQualifier(const NestedNameSpecifier *X,
const NestedNameSpecifier *Y) {
- if (auto *NSX = getNamespace(X)) {
- auto *NSY = getNamespace(Y);
- if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl())
- return false;
- } else if (X->getKind() != Y->getKind())
+ if (X->getKind() != Y->getKind())
return false;
// FIXME: For namespaces and types, we're permitted to check that the entity
@@ -7412,8 +7400,8 @@ static bool isSameQualifier(const NestedNameSpecifier *X,
return false;
break;
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- // We've already checked that we named the same namespace.
+ if (!declaresSameEntity(X->getAsNamespace(), Y->getAsNamespace()))
+ return false;
break;
case NestedNameSpecifier::TypeSpec:
if (X->getAsType()->getCanonicalTypeInternal() !=
@@ -7836,17 +7824,10 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
NNS->getAsIdentifier());
case NestedNameSpecifier::Namespace:
- // A namespace is canonical; build a nested-name-specifier with
- // this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, nullptr,
- NNS->getAsNamespace()->getFirstDecl());
-
- case NestedNameSpecifier::NamespaceAlias:
// A namespace is canonical; build a nested-name-specifier with
// this namespace and no prefix.
return NestedNameSpecifier::Create(
- *this, nullptr,
- NNS->getAsNamespaceAlias()->getNamespace()->getFirstDecl());
+ *this, nullptr, NNS->getAsNamespace()->getNamespace()->getFirstDecl());
// The
diff erence between TypeSpec and TypeSpecWithTemplate is that the
// latter will have the 'template' keyword when printed.
@@ -13698,26 +13679,27 @@ static NestedNameSpecifier *getCommonNNS(ASTContext &Ctx,
R = NestedNameSpecifier::Create(Ctx, P, II);
break;
}
- case NestedNameSpecifier::SpecifierKind::Namespace:
- case NestedNameSpecifier::SpecifierKind::NamespaceAlias: {
- assert(K2 == NestedNameSpecifier::SpecifierKind::Namespace ||
- K2 == NestedNameSpecifier::SpecifierKind::NamespaceAlias);
+ case NestedNameSpecifier::SpecifierKind::Namespace: {
+ assert(K2 == NestedNameSpecifier::SpecifierKind::Namespace);
// The prefixes for namespaces are not significant, its declaration
// identifies it uniquely.
NestedNameSpecifier *P =
::getCommonNNS(Ctx, NNS1->getPrefix(), NNS2->getPrefix(),
/*IsSame=*/false);
- NamespaceAliasDecl *A1 = NNS1->getAsNamespaceAlias(),
- *A2 = NNS2->getAsNamespaceAlias();
- // Are they the same namespace alias?
- if (declaresSameEntity(A1, A2)) {
- R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(A1, A2));
+ NamespaceBaseDecl *Namespace1 = NNS1->getAsNamespace(),
+ *Namespace2 = NNS2->getAsNamespace();
+ auto Kind = Namespace1->getKind();
+ if (Kind != Namespace2->getKind() ||
+ (Kind == Decl::NamespaceAlias &&
+ !declaresSameEntity(Namespace1, Namespace2))) {
+ R = NestedNameSpecifier::Create(
+ Ctx, P,
+ ::getCommonDeclChecked(Namespace1->getNamespace(),
+ Namespace2->getNamespace()));
break;
}
- // Otherwise, look at the namespaces only.
- NamespaceDecl *N1 = A1 ? A1->getNamespace() : NNS1->getAsNamespace(),
- *N2 = A2 ? A2->getNamespace() : NNS2->getAsNamespace();
- R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(N1, N2));
+ R = NestedNameSpecifier::Create(
+ Ctx, P, ::getCommonDeclChecked(Namespace1, Namespace2));
break;
}
case NestedNameSpecifier::SpecifierKind::TypeSpec: {
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 4d3bd985739fb..b5f6c5a8c6abe 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -10063,17 +10063,10 @@ ASTImporter::Import(NestedNameSpecifier *FromNNS) {
case NestedNameSpecifier::Namespace:
if (ExpectedDecl NSOrErr = Import(FromNNS->getAsNamespace())) {
return NestedNameSpecifier::Create(ToContext, Prefix,
- cast<NamespaceDecl>(*NSOrErr));
+ cast<NamespaceBaseDecl>(*NSOrErr));
} else
return NSOrErr.takeError();
- case NestedNameSpecifier::NamespaceAlias:
- if (ExpectedDecl NSADOrErr = Import(FromNNS->getAsNamespaceAlias()))
- return NestedNameSpecifier::Create(ToContext, Prefix,
- cast<NamespaceAliasDecl>(*NSADOrErr));
- else
- return NSADOrErr.takeError();
-
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
@@ -10139,11 +10132,6 @@ ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
ToLocalEndLoc);
break;
- case NestedNameSpecifier::NamespaceAlias:
- Builder.Extend(getToContext(), Spec->getAsNamespaceAlias(),
- ToLocalBeginLoc, ToLocalEndLoc);
- break;
-
case NestedNameSpecifier::TypeSpec: {
SourceLocation ToTLoc;
if (Error Err = importInto(ToTLoc, NNS.getTypeLoc().getBeginLoc()))
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 3aa6b37844103..289c6d7737de7 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -598,9 +598,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case NestedNameSpecifier::Namespace:
return IsStructurallyEquivalent(Context, NNS1->getAsNamespace(),
NNS2->getAsNamespace());
- case NestedNameSpecifier::NamespaceAlias:
- return IsStructurallyEquivalent(Context, NNS1->getAsNamespaceAlias(),
- NNS2->getAsNamespaceAlias());
case NestedNameSpecifier::TypeSpec:
return IsStructurallyEquivalent(Context, QualType(NNS1->getAsType(), 0),
QualType(NNS2->getAsType(), 0));
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 4514965009793..673e3f73858c7 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -3211,6 +3211,12 @@ UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C,
SourceLocation(), nullptr, nullptr);
}
+NamespaceDecl *NamespaceBaseDecl::getNamespace() {
+ if (auto *Alias = dyn_cast<NamespaceAliasDecl>(this))
+ return Alias->getNamespace();
+ return cast<NamespaceDecl>(this);
+}
+
NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
if (auto *NA = dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
return NA->getNamespace();
@@ -3221,7 +3227,7 @@ NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, NamespaceDecl *PrevDecl,
bool Nested)
- : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+ : NamespaceBaseDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
redeclarable_base(C), LocStart(StartLoc) {
setInline(Inline);
setNested(Nested);
@@ -3268,13 +3274,11 @@ NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() {
return getMostRecentDecl();
}
-NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace) {
+NamespaceAliasDecl *NamespaceAliasDecl::Create(
+ ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc,
+ NamespaceBaseDecl *Namespace) {
// FIXME: Preserve the aliased namespace as written.
if (auto *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
Namespace = NS->getFirstDecl();
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 0520987ce6b3a..6d082b31a9caa 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -1384,14 +1384,6 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
Out << "sr";
mangleSourceNameWithAbiTags(qualifier->getAsNamespace());
break;
- case NestedNameSpecifier::NamespaceAlias:
- if (qualifier->getPrefix())
- mangleUnresolvedPrefix(qualifier->getPrefix(),
- /*recursive*/ true);
- else
- Out << "sr";
- mangleSourceNameWithAbiTags(qualifier->getAsNamespaceAlias());
- break;
case NestedNameSpecifier::TypeSpec: {
const Type *type = qualifier->getAsType();
@@ -2185,11 +2177,7 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
llvm_unreachable("Can't mangle __super specifier");
case NestedNameSpecifier::Namespace:
- mangleName(qualifier->getAsNamespace());
- return;
-
- case NestedNameSpecifier::NamespaceAlias:
- mangleName(qualifier->getAsNamespaceAlias()->getNamespace());
+ mangleName(qualifier->getAsNamespace()->getNamespace());
return;
case NestedNameSpecifier::TypeSpec:
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index db1ad89565189..56f74b92412d2 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -66,10 +66,9 @@ NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context,
return FindOrInsert(Context, Mockup);
}
-NestedNameSpecifier *
-NestedNameSpecifier::Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceDecl *NS) {
+NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context,
+ NestedNameSpecifier *Prefix,
+ const NamespaceBaseDecl *NS) {
assert(NS && "Namespace cannot be NULL");
assert((!Prefix ||
(Prefix->getAsType() == nullptr &&
@@ -78,23 +77,7 @@ NestedNameSpecifier::Create(const ASTContext &Context,
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
Mockup.Prefix.setInt(StoredDecl);
- Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
- return FindOrInsert(Context, Mockup);
-}
-
-NestedNameSpecifier *
-NestedNameSpecifier::Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceAliasDecl *Alias) {
- assert(Alias && "Namespace alias cannot be NULL");
- assert((!Prefix ||
- (Prefix->getAsType() == nullptr &&
- Prefix->getAsIdentifier() == nullptr)) &&
- "Broken nested name specifier");
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredDecl);
- Mockup.Specifier = const_cast<NamespaceAliasDecl *>(Alias);
+ Mockup.Specifier = const_cast<NamespaceBaseDecl *>(NS);
return FindOrInsert(Context, Mockup);
}
@@ -147,9 +130,7 @@ NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
case StoredDecl: {
NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
- if (isa<CXXRecordDecl>(ND))
- return Super;
- return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
+ return isa<CXXRecordDecl>(ND) ? Super : Namespace;
}
case StoredTypeSpec:
@@ -159,18 +140,11 @@ NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
llvm_unreachable("Invalid NNS Kind!");
}
-/// Retrieve the namespace stored in this nested name specifier.
-NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
+/// Retrieve the namespace or namespace alias stored in this nested name
+/// specifier.
+NamespaceBaseDecl *NestedNameSpecifier::getAsNamespace() const {
if (Prefix.getInt() == StoredDecl)
- return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
-
- return nullptr;
-}
-
-/// Retrieve the namespace alias stored in this nested name specifier.
-NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
- if (Prefix.getInt() == StoredDecl)
- return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
+ return dyn_cast<NamespaceBaseDecl>(static_cast<NamedDecl *>(Specifier));
return nullptr;
}
@@ -204,7 +178,6 @@ NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
}
case Namespace:
- case NamespaceAlias:
case Global:
return NestedNameSpecifierDependence::None;
@@ -284,7 +257,6 @@ NestedNameSpecifier::translateToType(const ASTContext &Context) const {
}
case SpecifierKind::Global:
case SpecifierKind::Namespace:
- case SpecifierKind::NamespaceAlias:
case SpecifierKind::Super:
// These are not representable as types.
return nullptr;
@@ -305,16 +277,16 @@ void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
OS << getAsIdentifier()->getName();
break;
- case Namespace:
- if (getAsNamespace()->isAnonymousNamespace())
- return;
-
- OS << getAsNamespace()->getName();
- break;
-
- case NamespaceAlias:
- OS << getAsNamespaceAlias()->getName();
+ case Namespace: {
+ NamespaceBaseDecl *Namespace = getAsNamespace();
+ if (const auto *NS = dyn_cast<NamespaceDecl>(Namespace)) {
+ assert(!NS->isAnonymousNamespace());
+ OS << NS->getName();
+ } else {
+ OS << cast<NamespaceAliasDecl>(Namespace)->getName();
+ }
break;
+ }
case Global:
OS << "::";
@@ -367,7 +339,6 @@ NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Super:
// The location of the identifier or namespace name.
Length += sizeof(SourceLocation::UIntTy);
@@ -418,7 +389,6 @@ SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Super:
return SourceRange(
LoadSourceLocation(Data, Offset),
@@ -569,7 +539,7 @@ void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
}
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
- NamespaceDecl *Namespace,
+ NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc,
SourceLocation ColonColonLoc) {
Representation = NestedNameSpecifier::Create(Context, Representation,
@@ -580,17 +550,6 @@ void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}
-void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
- NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc,
- SourceLocation ColonColonLoc) {
- Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
-
- // Push source-location info into the buffer.
- SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-}
-
void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
SourceLocation ColonColonLoc) {
assert(!Representation && "Already have a nested-name-specifier!?");
@@ -627,7 +586,6 @@ void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
break;
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 7fdfcfa3014f3..bd87d4418484b 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -127,9 +127,6 @@ void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
case NestedNameSpecifier::Namespace:
AddDecl(NNS->getAsNamespace());
break;
- case NestedNameSpecifier::NamespaceAlias:
- AddDecl(NNS->getAsNamespaceAlias());
- break;
case NestedNameSpecifier::TypeSpec:
AddType(NNS->getAsType());
break;
diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp
index 39703d6d7b882..b43bcd8d1f1c1 100644
--- a/clang/lib/AST/QualTypeNames.cpp
+++ b/clang/lib/AST/QualTypeNames.cpp
@@ -218,16 +218,7 @@ static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
return Scope;
case NestedNameSpecifier::Namespace:
return TypeName::createNestedNameSpecifier(
- Ctx, Scope->getAsNamespace(), WithGlobalNsPrefix);
- case NestedNameSpecifier::NamespaceAlias:
- // Namespace aliases are only valid for the duration of the
- // scope where they were introduced, and therefore are often
- // invalid at the end of the TU. So use the namespace name more
- // likely to be valid at the end of the TU.
- return TypeName::createNestedNameSpecifier(
- Ctx,
- Scope->getAsNamespaceAlias()->getNamespace()->getCanonicalDecl(),
- WithGlobalNsPrefix);
+ Ctx, Scope->getAsNamespace()->getNamespace(), WithGlobalNsPrefix);
case NestedNameSpecifier::Identifier:
// A function or some other construct that makes it un-namable
// at the end of the TU. Skip the current component of the name,
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 9d7c2757d6ee4..3d9397fb0b540 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1050,10 +1050,6 @@ void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *N
OS << " "; // "Namespace" is printed as the decl kind.
dumpBareDeclRef(NNS->getAsNamespace());
break;
- case NestedNameSpecifier::NamespaceAlias:
- OS << " "; // "NamespaceAlias" is printed as the decl kind.
- dumpBareDeclRef(NNS->getAsNamespaceAlias());
- break;
case NestedNameSpecifier::TypeSpec:
OS << " TypeSpec";
dumpType(QualType(NNS->getAsType(), 0));
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 791afc1a97575..51a6f6b779e77 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -220,8 +220,9 @@ DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
break;
case NestedNameSpecifier::Namespace: {
- const NamespaceDecl *NS = NNS->getAsNamespace();
- if (NS->isAnonymousNamespace())
+ const NamespaceBaseDecl *NS = NNS->getAsNamespace();
+ if (const auto *Namespace = dyn_cast<NamespaceDecl>(NS);
+ Namespace && Namespace->isAnonymousNamespace())
return Fragments;
SmallString<128> USR;
index::generateUSRForDecl(NS, USR);
@@ -230,16 +231,6 @@ DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
break;
}
- case NestedNameSpecifier::NamespaceAlias: {
- const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias();
- SmallString<128> USR;
- index::generateUSRForDecl(Alias, USR);
- Fragments.append(Alias->getName(),
- DeclarationFragments::FragmentKind::Identifier, USR,
- Alias);
- break;
- }
-
case NestedNameSpecifier::Global:
// The global specifier `::` at the beginning. No stored value.
break;
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 98b5513128fbe..adc33b3abd822 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -271,10 +271,6 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
Loc, Parent, DC, SymbolRoleSet());
break;
- case NestedNameSpecifier::NamespaceAlias:
- handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
- Loc, Parent, DC, SymbolRoleSet());
- break;
case NestedNameSpecifier::TypeSpec:
indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index 9cae4f9a23ef0..31392d1dd8d4b 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -591,8 +591,7 @@ bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
NextToken().isRegularKeywordAttribute() ||
NextToken().is(tok::kw___attribute)) &&
D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
- !D.SS.getScopeRep()->getAsNamespace() &&
- !D.SS.getScopeRep()->getAsNamespaceAlias()) {
+ D.SS.getScopeRep()->getKind() != NestedNameSpecifier::Namespace) {
SourceLocation IdLoc = ConsumeToken();
ParsedType Type =
Actions.getInheritingConstructorName(D.SS, IdLoc, *LastII);
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index ee5a862c32509..f0f1d66f66e93 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -72,7 +72,7 @@ void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
"NestedNameSpecifierLoc range computation incorrect");
}
-void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
+void CXXScopeSpec::Extend(ASTContext &Context, NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc,
SourceLocation ColonColonLoc) {
Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
@@ -85,19 +85,6 @@ void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
"NestedNameSpecifierLoc range computation incorrect");
}
-void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc,
- SourceLocation ColonColonLoc) {
- Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
-
- if (Range.getBegin().isInvalid())
- Range.setBegin(AliasLoc);
- Range.setEnd(ColonColonLoc);
-
- assert(Range == Builder.getSourceRange() &&
- "NestedNameSpecifierLoc range computation incorrect");
-}
-
void CXXScopeSpec::MakeGlobal(ASTContext &Context,
SourceLocation ColonColonLoc) {
Builder.MakeGlobal(Context, ColonColonLoc);
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index ab83f625d2849..6ac04837708f6 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -137,10 +137,7 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
llvm_unreachable("Dependent nested-name-specifier has no DeclContext");
case NestedNameSpecifier::Namespace:
- return NNS->getAsNamespace();
-
- case NestedNameSpecifier::NamespaceAlias:
- return NNS->getAsNamespaceAlias()->getNamespace();
+ return NNS->getAsNamespace()->getNamespace();
case NestedNameSpecifier::TypeSpec: {
const TagType *Tag = NNS->getAsType()->getAs<TagType>();
@@ -992,7 +989,6 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
switch (Qualifier->getKind()) {
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
// These are always namespace scopes. We never want to enter a
// namespace scope from anything but a file context.
return CurContext->getRedeclContext()->isFileContext();
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index c8638420aebb5..f5b4614576086 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11930,7 +11930,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
/// is a namespace alias, returns the namespace it points to.
-static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
+static inline NamespaceDecl *getNamespaceDecl(NamespaceBaseDecl *D) {
if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D))
return AD->getNamespace();
return dyn_cast_or_null<NamespaceDecl>(D);
@@ -13829,7 +13829,7 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc,
}
}
assert(!R.isAmbiguous() && !R.empty());
- NamedDecl *ND = R.getRepresentativeDecl();
+ auto *ND = cast<NamespaceBaseDecl>(R.getRepresentativeDecl());
// Check if we have a previous declaration with the same name.
LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index f851c9e1d5015..fd95f4ec54229 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -518,7 +518,6 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Super:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
return false;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 6d6e07a2c03c7..8bde18f64f80b 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -4560,15 +4560,14 @@ static void getNestedNameSpecifierIdentifiers(
II = NNS->getAsIdentifier();
break;
- case NestedNameSpecifier::Namespace:
- if (NNS->getAsNamespace()->isAnonymousNamespace())
+ case NestedNameSpecifier::Namespace: {
+ const NamespaceBaseDecl *Namespace = NNS->getAsNamespace();
+ if (const auto *NS = dyn_cast<NamespaceDecl>(Namespace);
+ NS && NS->isAnonymousNamespace())
return;
- II = NNS->getAsNamespace()->getIdentifier();
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- II = NNS->getAsNamespaceAlias()->getIdentifier();
+ II = Namespace->getIdentifier();
break;
+ }
case NestedNameSpecifier::TypeSpec:
II = QualType(NNS->getAsType(), 0).getBaseTypeIdentifier();
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index b76619fc50268..698d1270be634 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -6299,7 +6299,6 @@ bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
switch (NNS->getKind()) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Global:
case NestedNameSpecifier::Super:
return false;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 3e38f8b183dfd..286c2b486c0f9 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4621,22 +4621,12 @@ NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
}
case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS =
- cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
- Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
+ auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
+ Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
break;
}
- case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias =
- cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
- Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
- SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
- Q.getLocalEndLoc());
- break;
- }
-
case NestedNameSpecifier::Global:
// There is no meaningful transformation that one could perform on the
// global scope.
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index d0bb7fb1d06ad..3596d2240167e 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -10107,19 +10107,12 @@ ASTRecordReader::readNestedNameSpecifierLoc() {
}
case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS = readDeclAs<NamespaceDecl>();
+ auto *NS = readDeclAs<NamespaceBaseDecl>();
SourceRange Range = readSourceRange();
Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());
break;
}
- case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias = readDeclAs<NamespaceAliasDecl>();
- SourceRange Range = readSourceRange();
- Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());
- break;
- }
-
case NestedNameSpecifier::TypeSpec: {
TypeSourceInfo *T = readTypeSourceInfo();
if (!T)
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index b918bfbd549c3..bd84a9741d01b 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1889,7 +1889,7 @@ void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->NamespaceLoc = readSourceLocation();
D->IdentLoc = readSourceLocation();
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- D->Namespace = readDeclAs<NamedDecl>();
+ D->Namespace = readDeclAs<NamespaceBaseDecl>();
mergeRedeclarable(D, Redecl);
}
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 847283e9842e5..e868afeb1a145 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7093,11 +7093,6 @@ void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
AddSourceRange(NNS.getLocalSourceRange());
break;
- case NestedNameSpecifier::NamespaceAlias:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
-
case NestedNameSpecifier::TypeSpec:
AddTypeRef(NNS.getTypeLoc().getType());
AddTypeLoc(NNS.getTypeLoc());
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index caac719caf8e8..eb9fa7a7fa1e8 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -950,7 +950,6 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
case NestedNameSpecifier::Global:
return syntax::NodeKind::GlobalNameSpecifier;
case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
case NestedNameSpecifier::Identifier:
return syntax::NodeKind::IdentifierNameSpecifier;
case NestedNameSpecifier::TypeSpec: {
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 9089984fa4a54..75afa87947be4 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1438,10 +1438,6 @@ bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
return Visit(
MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
- case NestedNameSpecifier::NamespaceAlias:
- return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
- Range.getBegin(), TU));
-
case NestedNameSpecifier::TypeSpec: {
// If the type has a form where we know that the beginning of the source
// range matches up with a reference cursor. Visit the appropriate reference
@@ -1483,13 +1479,6 @@ bool CursorVisitor::VisitNestedNameSpecifierLoc(
break;
- case NestedNameSpecifier::NamespaceAlias:
- if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
- Q.getLocalBeginLoc(), TU)))
- return true;
-
- break;
-
case NestedNameSpecifier::TypeSpec:
if (Visit(Q.getTypeLoc()))
return true;
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
index ddc663e2b6fd3..23a2df42ff08c 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
@@ -25,8 +25,8 @@ class NestedNameSpecifiersVisitor : public ExpectedLocationVisitor {
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
if (!NNS)
return true;
- if (const NamespaceDecl *ND =
- NNS.getNestedNameSpecifier()->getAsNamespace())
+ if (const auto *ND = dyn_cast_if_present<NamespaceDecl>(
+ NNS.getNestedNameSpecifier()->getAsNamespace()))
Match(ND->getName(), NNS.getLocalBeginLoc());
return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS);
}
diff --git a/clang/unittests/Tooling/RefactoringTest.cpp b/clang/unittests/Tooling/RefactoringTest.cpp
index 254d95bc20cb0..35d114343b517 100644
--- a/clang/unittests/Tooling/RefactoringTest.cpp
+++ b/clang/unittests/Tooling/RefactoringTest.cpp
@@ -748,7 +748,8 @@ class NestedNameSpecifierAVisitor : public TestVisitor {
public:
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLoc) override {
if (NNSLoc.getNestedNameSpecifier()) {
- if (const NamespaceDecl* NS = NNSLoc.getNestedNameSpecifier()->getAsNamespace()) {
+ if (const auto *NS = dyn_cast_if_present<NamespaceDecl>(
+ NNSLoc.getNestedNameSpecifier()->getAsNamespace())) {
if (NS->getName() == "a") {
Replace = Replacement(*SM, &NNSLoc, "", Context->getLangOpts());
}
More information about the cfe-commits
mailing list