diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h --- a/clang-tools-extra/clangd/AST.h +++ b/clang-tools-extra/clangd/AST.h @@ -42,13 +42,6 @@ /// this function. SourceLocation nameLocation(const clang::Decl &D, const SourceManager &SM); -/// Returns the qualified name of ND. The scope doesn't contain unwritten scopes -/// like inline namespaces. -std::string printQualifiedName(const NamedDecl &ND); - -/// Returns the first enclosing namespace scope starting from \p DC. -std::string printNamespaceScope(const DeclContext &DC); - /// Returns the name of the namespace inside the 'using namespace' directive, as /// written in the code. E.g., passing 'using namespace ::std' will result in /// '::std'. diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -171,21 +171,6 @@ return SM.getExpansionLoc(L); } -std::string printQualifiedName(const NamedDecl &ND) { - std::string QName; - llvm::raw_string_ostream OS(QName); - PrintingPolicy Policy(ND.getASTContext().getLangOpts()); - // Note that inline namespaces are treated as transparent scopes. This - // reflects the way they're most commonly used for lookup. Ideally we'd - // include them, but at query time it's hard to find all the inline - // namespaces to query: the preamble doesn't have a dedicated list. - Policy.SuppressUnwrittenScope = true; - ND.printQualifiedName(OS, Policy); - OS.flush(); - assert(!StringRef(QName).startswith("::")); - return QName; -} - static bool isAnonymous(const DeclarationName &N) { return N.isIdentifier() && !N.getAsIdentifierInfo(); } @@ -280,14 +265,6 @@ return TemplateArgs; } -std::string printNamespaceScope(const DeclContext &DC) { - for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent()) - if (const auto *NS = dyn_cast(Ctx)) - if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace()) - return printQualifiedName(*NS) + "::"; - return ""; -} - static llvm::StringRef getNameOrErrForObjCInterface(const ObjCInterfaceDecl *ID) { return ID ? ID->getName() : "<>"; diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -4659,6 +4659,13 @@ return "$ompvariant"; } +/// Returns the qualified name of ND. The scope doesn't contain unwritten scopes +/// like inline namespaces. +std::string printQualifiedName(const NamedDecl &ND); + +/// Returns the first enclosing namespace scope starting from \p DC. +std::string printNamespaceScope(const DeclContext &DC); + } // namespace clang #endif // LLVM_CLANG_AST_DECL_H diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -5191,3 +5191,31 @@ ExportDecl *ExportDecl::CreateDeserialized(ASTContext &C, unsigned ID) { return new (C, ID) ExportDecl(nullptr, SourceLocation()); } + +//===----------------------------------------------------------------------===// +// Helpers +//===----------------------------------------------------------------------===// + +std::string clang::printQualifiedName(const NamedDecl &ND) { + std::string QName; + llvm::raw_string_ostream OS(QName); + clang::PrintingPolicy Policy(ND.getASTContext().getLangOpts()); + // Note that inline namespaces are treated as transparent scopes. This + // reflects the way they're most commonly used for lookup. Ideally we'd + // include them, but at query time it's hard to find all the inline + // namespaces to query: the preamble doesn't have a dedicated list. + Policy.SuppressUnwrittenScope = true; + ND.printQualifiedName(OS, Policy); + OS.flush(); + assert(!StringRef(QName).startswith("::")); + return QName; +} + +/// Returns the first enclosing namespace scope starting from \p DC. +std::string clang::printNamespaceScope(const DeclContext &DC) { + for (const auto *Ctx = &DC; Ctx != nullptr; Ctx = Ctx->getParent()) + if (const auto *NS = dyn_cast(Ctx)) + if (!NS->isAnonymousNamespace() && !NS->isInlineNamespace()) + return clang::printQualifiedName(*NS) + "::"; + return ""; +}