r317676 - Moved QualTypeNames.h from Tooling to AST.

Ilya Biryukov via cfe-commits cfe-commits at lists.llvm.org
Wed Nov 8 02:39:03 PST 2017


Author: ibiryukov
Date: Wed Nov  8 02:39:03 2017
New Revision: 317676

URL: http://llvm.org/viewvc/llvm-project?rev=317676&view=rev
Log:
Moved QualTypeNames.h from Tooling to AST.

Summary:
For code reuse in SemaCodeComplete.
Note that the tests for QualTypeNames are still in Tooling as they use
Tooling's common testing code.

Reviewers: rsmith, saugustine, rnk, klimek, bkramer

Reviewed By: rnk

Subscribers: cfe-commits, mgorny

Differential Revision: https://reviews.llvm.org/D39224

Added:
    cfe/trunk/include/clang/AST/QualTypeNames.h
      - copied, changed from r317672, cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h
    cfe/trunk/lib/AST/QualTypeNames.cpp
      - copied, changed from r317672, cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp
Removed:
    cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h
    cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp
Modified:
    cfe/trunk/lib/AST/CMakeLists.txt
    cfe/trunk/lib/Tooling/Core/CMakeLists.txt
    cfe/trunk/unittests/Tooling/QualTypeNamesTest.cpp

Copied: cfe/trunk/include/clang/AST/QualTypeNames.h (from r317672, cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/QualTypeNames.h?p2=cfe/trunk/include/clang/AST/QualTypeNames.h&p1=cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h&r1=317672&r2=317676&rev=317676&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h (original)
+++ cfe/trunk/include/clang/AST/QualTypeNames.h Wed Nov  8 02:39:03 2017
@@ -56,8 +56,8 @@
 //
 // ===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
-#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
+#ifndef LLVM_CLANG_AST_QUALTYPENAMES_H
+#define LLVM_CLANG_AST_QUALTYPENAMES_H
 
 #include "clang/AST/ASTContext.h"
 
@@ -71,9 +71,20 @@ namespace TypeName {
 /// \param[in] Ctx - the ASTContext to be used.
 /// \param[in] WithGlobalNsPrefix - If true, then the global namespace
 /// specifier "::" will be prepended to the fully qualified name.
-std::string getFullyQualifiedName(QualType QT,
-                                  const ASTContext &Ctx,
+std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx,
                                   bool WithGlobalNsPrefix = false);
-}  // end namespace TypeName
-}  // end namespace clang
-#endif  // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
+
+/// \brief Generates a QualType that can be used to name the same type
+/// if used at the end of the current translation unit. This ignores
+/// issues such as type shadowing.
+///
+/// \param[in] QT - the type for which the fully qualified type will be
+/// returned.
+/// \param[in] Ctx - the ASTContext to be used.
+/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
+/// specifier "::" should be prepended or not.
+QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
+                               bool WithGlobalNsPrefix = false);
+} // end namespace TypeName
+} // end namespace clang
+#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H

Removed: cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h?rev=317675&view=auto
==============================================================================
--- cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h (original)
+++ cfe/trunk/include/clang/Tooling/Core/QualTypeNames.h (removed)
@@ -1,79 +0,0 @@
-//===--- QualTypeNames.h - Generate Complete QualType Names ----*- C++ -*-===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-// ===----------------------------------------------------------------------===//
-//
-// \file
-// Functionality to generate the fully-qualified names of QualTypes,
-// including recursively expanding any subtypes and template
-// parameters.
-//
-// More precisely: Generates a name that can be used to name the same
-// type if used at the end of the current translation unit--with
-// certain limitations. See below.
-//
-// This code desugars names only very minimally, so in this code:
-//
-// namespace A {
-//   struct X {};
-// }
-// using A::X;
-// namespace B {
-//   using std::tuple;
-//   typedef tuple<X> TX;
-//   TX t;
-// }
-//
-// B::t's type is reported as "B::TX", rather than std::tuple<A::X>.
-//
-// Also, this code replaces types found via using declarations with
-// their more qualified name, so for the code:
-//
-// using std::tuple;
-// tuple<int> TInt;
-//
-// TInt's type will be named, "std::tuple<int>".
-//
-// Limitations:
-//
-// Some types have ambiguous names at the end of a translation unit,
-// are not namable at all there, or are special cases in other ways.
-//
-// 1) Types with only local scope will have their local names:
-//
-// void foo() {
-//   struct LocalType {} LocalVar;
-// }
-//
-// LocalVar's type will be named, "struct LocalType", without any
-// qualification.
-//
-// 2) Types that have been shadowed are reported normally, but a
-// client using that name at the end of the translation unit will be
-// referring to a different type.
-//
-// ===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
-#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H
-
-#include "clang/AST/ASTContext.h"
-
-namespace clang {
-namespace TypeName {
-/// \brief Get the fully qualified name for a type. This includes full
-/// qualification of all template parameters etc.
-///
-/// \param[in] QT - the type for which the fully qualified name will be
-/// returned.
-/// \param[in] Ctx - the ASTContext to be used.
-/// \param[in] WithGlobalNsPrefix - If true, then the global namespace
-/// specifier "::" will be prepended to the fully qualified name.
-std::string getFullyQualifiedName(QualType QT,
-                                  const ASTContext &Ctx,
-                                  bool WithGlobalNsPrefix = false);
-}  // end namespace TypeName
-}  // end namespace clang
-#endif  // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H

Modified: cfe/trunk/lib/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=317676&r1=317675&r2=317676&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CMakeLists.txt (original)
+++ cfe/trunk/lib/AST/CMakeLists.txt Wed Nov  8 02:39:03 2017
@@ -49,6 +49,7 @@ add_clang_library(clangAST
   ODRHash.cpp
   OpenMPClause.cpp
   ParentMap.cpp
+  QualTypeNames.cpp
   RawCommentList.cpp
   RecordLayout.cpp
   RecordLayoutBuilder.cpp

Copied: cfe/trunk/lib/AST/QualTypeNames.cpp (from r317672, cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp)
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/QualTypeNames.cpp?p2=cfe/trunk/lib/AST/QualTypeNames.cpp&p1=cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp&r1=317672&r2=317676&rev=317676&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp (original)
+++ cfe/trunk/lib/AST/QualTypeNames.cpp Wed Nov  8 02:39:03 2017
@@ -9,11 +9,11 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Tooling/Core/QualTypeNames.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/DeclarationName.h"
 #include "clang/AST/GlobalDecl.h"
 #include "clang/AST/Mangle.h"
+#include "clang/AST/QualTypeNames.h"
 
 #include <stdio.h>
 #include <memory>
@@ -21,17 +21,6 @@
 namespace clang {
 
 namespace TypeName {
-/// \brief Generates a QualType that can be used to name the same type
-/// if used at the end of the current translation unit. This ignores
-/// issues such as type shadowing.
-///
-/// \param[in] QT - the type for which the fully qualified type will be
-/// returned.
-/// \param[in] Ctx - the ASTContext to be used.
-/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
-/// specifier "::" should be prepended or not.
-static QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
-                                      bool WithGlobalNsPrefix);
 
 /// \brief Create a NestedNameSpecifier for Namesp and its enclosing
 /// scopes.

Modified: cfe/trunk/lib/Tooling/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Core/CMakeLists.txt?rev=317676&r1=317675&r2=317676&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/Tooling/Core/CMakeLists.txt Wed Nov  8 02:39:03 2017
@@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS support)
 add_clang_library(clangToolingCore
   Lookup.cpp
   Replacement.cpp
-  QualTypeNames.cpp
   Diagnostic.cpp
 
   LINK_LIBS

Removed: cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp?rev=317675&view=auto
==============================================================================
--- cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp (original)
+++ cfe/trunk/lib/Tooling/Core/QualTypeNames.cpp (removed)
@@ -1,477 +0,0 @@
-//===------- QualTypeNames.cpp - Generate Complete QualType Names ---------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "clang/Tooling/Core/QualTypeNames.h"
-#include "clang/AST/DeclTemplate.h"
-#include "clang/AST/DeclarationName.h"
-#include "clang/AST/GlobalDecl.h"
-#include "clang/AST/Mangle.h"
-
-#include <stdio.h>
-#include <memory>
-
-namespace clang {
-
-namespace TypeName {
-/// \brief Generates a QualType that can be used to name the same type
-/// if used at the end of the current translation unit. This ignores
-/// issues such as type shadowing.
-///
-/// \param[in] QT - the type for which the fully qualified type will be
-/// returned.
-/// \param[in] Ctx - the ASTContext to be used.
-/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
-/// specifier "::" should be prepended or not.
-static QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
-                                      bool WithGlobalNsPrefix);
-
-/// \brief Create a NestedNameSpecifier for Namesp and its enclosing
-/// scopes.
-///
-/// \param[in] Ctx - the AST Context to be used.
-/// \param[in] Namesp - the NamespaceDecl for which a NestedNameSpecifier
-/// is requested.
-/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
-/// specifier "::" should be prepended or not.
-static NestedNameSpecifier *createNestedNameSpecifier(
-    const ASTContext &Ctx,
-    const NamespaceDecl *Namesp,
-    bool WithGlobalNsPrefix);
-
-/// \brief Create a NestedNameSpecifier for TagDecl and its enclosing
-/// scopes.
-///
-/// \param[in] Ctx - the AST Context to be used.
-/// \param[in] TD - the TagDecl for which a NestedNameSpecifier is
-/// requested.
-/// \param[in] FullyQualify - Convert all template arguments into fully
-/// qualified names.
-/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
-/// specifier "::" should be prepended or not.
-static NestedNameSpecifier *createNestedNameSpecifier(
-    const ASTContext &Ctx, const TypeDecl *TD,
-    bool FullyQualify, bool WithGlobalNsPrefix);
-
-static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
-    const ASTContext &Ctx, const Decl *decl,
-    bool FullyQualified, bool WithGlobalNsPrefix);
-
-static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
-    const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix);
-
-static bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
-                                          TemplateName &TName,
-                                          bool WithGlobalNsPrefix) {
-  bool Changed = false;
-  NestedNameSpecifier *NNS = nullptr;
-
-  TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
-  // ArgTDecl won't be NULL because we asserted that this isn't a
-  // dependent context very early in the call chain.
-  assert(ArgTDecl != nullptr);
-  QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName();
-
-  if (QTName && !QTName->hasTemplateKeyword()) {
-    NNS = QTName->getQualifier();
-    NestedNameSpecifier *QNNS = getFullyQualifiedNestedNameSpecifier(
-        Ctx, NNS, WithGlobalNsPrefix);
-    if (QNNS != NNS) {
-      Changed = true;
-      NNS = QNNS;
-    } else {
-      NNS = nullptr;
-    }
-  } else {
-    NNS = createNestedNameSpecifierForScopeOf(
-        Ctx, ArgTDecl, true, WithGlobalNsPrefix);
-  }
-  if (NNS) {
-    TName = Ctx.getQualifiedTemplateName(NNS,
-                                         /*TemplateKeyword=*/false, ArgTDecl);
-    Changed = true;
-  }
-  return Changed;
-}
-
-static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx,
-                                              TemplateArgument &Arg,
-                                              bool WithGlobalNsPrefix) {
-  bool Changed = false;
-
-  // Note: we do not handle TemplateArgument::Expression, to replace it
-  // we need the information for the template instance decl.
-
-  if (Arg.getKind() == TemplateArgument::Template) {
-    TemplateName TName = Arg.getAsTemplate();
-    Changed = getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
-    if (Changed) {
-      Arg = TemplateArgument(TName);
-    }
-  } else if (Arg.getKind() == TemplateArgument::Type) {
-    QualType SubTy = Arg.getAsType();
-    // Check if the type needs more desugaring and recurse.
-    QualType QTFQ = getFullyQualifiedType(SubTy, Ctx, WithGlobalNsPrefix);
-    if (QTFQ != SubTy) {
-      Arg = TemplateArgument(QTFQ);
-      Changed = true;
-    }
-  }
-  return Changed;
-}
-
-static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx,
-                                                 const Type *TypePtr,
-                                                 bool WithGlobalNsPrefix) {
-  // DependentTemplateTypes exist within template declarations and
-  // definitions. Therefore we shouldn't encounter them at the end of
-  // a translation unit. If we do, the caller has made an error.
-  assert(!isa<DependentTemplateSpecializationType>(TypePtr));
-  // In case of template specializations, iterate over the arguments
-  // and fully qualify them as well.
-  if (const auto *TST = dyn_cast<const TemplateSpecializationType>(TypePtr)) {
-    bool MightHaveChanged = false;
-    SmallVector<TemplateArgument, 4> FQArgs;
-    for (TemplateSpecializationType::iterator I = TST->begin(), E = TST->end();
-         I != E; ++I) {
-      // Cheap to copy and potentially modified by
-      // getFullyQualifedTemplateArgument.
-      TemplateArgument Arg(*I);
-      MightHaveChanged |= getFullyQualifiedTemplateArgument(
-          Ctx, Arg, WithGlobalNsPrefix);
-      FQArgs.push_back(Arg);
-    }
-
-    // If a fully qualified arg is different from the unqualified arg,
-    // allocate new type in the AST.
-    if (MightHaveChanged) {
-      QualType QT = Ctx.getTemplateSpecializationType(
-          TST->getTemplateName(), FQArgs,
-          TST->getCanonicalTypeInternal());
-      // getTemplateSpecializationType returns a fully qualified
-      // version of the specialization itself, so no need to qualify
-      // it.
-      return QT.getTypePtr();
-    }
-  } else if (const auto *TSTRecord = dyn_cast<const RecordType>(TypePtr)) {
-    // We are asked to fully qualify and we have a Record Type,
-    // which can point to a template instantiation with no sugar in any of
-    // its template argument, however we still need to fully qualify them.
-
-    if (const auto *TSTDecl =
-        dyn_cast<ClassTemplateSpecializationDecl>(TSTRecord->getDecl())) {
-      const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
-
-      bool MightHaveChanged = false;
-      SmallVector<TemplateArgument, 4> FQArgs;
-      for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
-        // cheap to copy and potentially modified by
-        // getFullyQualifedTemplateArgument
-        TemplateArgument Arg(TemplateArgs[I]);
-        MightHaveChanged |= getFullyQualifiedTemplateArgument(
-            Ctx, Arg, WithGlobalNsPrefix);
-        FQArgs.push_back(Arg);
-      }
-
-      // If a fully qualified arg is different from the unqualified arg,
-      // allocate new type in the AST.
-      if (MightHaveChanged) {
-        TemplateName TN(TSTDecl->getSpecializedTemplate());
-        QualType QT = Ctx.getTemplateSpecializationType(
-            TN, FQArgs,
-            TSTRecord->getCanonicalTypeInternal());
-        // getTemplateSpecializationType returns a fully qualified
-        // version of the specialization itself, so no need to qualify
-        // it.
-        return QT.getTypePtr();
-      }
-    }
-  }
-  return TypePtr;
-}
-
-static NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
-                                           bool FullyQualify,
-                                           bool WithGlobalNsPrefix) {
-  const DeclContext *DC = D->getDeclContext();
-  if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
-    while (NS && NS->isInline()) {
-      // Ignore inline namespace;
-      NS = dyn_cast<NamespaceDecl>(NS->getDeclContext());
-    }
-    if (NS->getDeclName()) {
-      return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
-    }
-    return nullptr;  // no starting '::', no anonymous
-  } else if (const auto *TD = dyn_cast<TagDecl>(DC)) {
-    return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
-  } else if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC)) {
-    return createNestedNameSpecifier(
-        Ctx, TDD, FullyQualify, WithGlobalNsPrefix);
-  } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
-    return NestedNameSpecifier::GlobalSpecifier(Ctx);
-  }
-  return nullptr;  // no starting '::' if |WithGlobalNsPrefix| is false
-}
-
-/// \brief Return a fully qualified version of this name specifier.
-static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
-    const ASTContext &Ctx, NestedNameSpecifier *Scope,
-    bool WithGlobalNsPrefix) {
-  switch (Scope->getKind()) {
-    case NestedNameSpecifier::Global:
-      // Already fully qualified
-      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);
-    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,
-      // but use the name of it's prefix.
-      return getFullyQualifiedNestedNameSpecifier(
-          Ctx, Scope->getPrefix(), WithGlobalNsPrefix);
-    case NestedNameSpecifier::Super:
-    case NestedNameSpecifier::TypeSpec:
-    case NestedNameSpecifier::TypeSpecWithTemplate: {
-      const Type *Type = Scope->getAsType();
-      // Find decl context.
-      const TagDecl *TD = nullptr;
-      if (const TagType *TagDeclType = Type->getAs<TagType>()) {
-        TD = TagDeclType->getDecl();
-      } else {
-        TD = Type->getAsCXXRecordDecl();
-      }
-      if (TD) {
-        return TypeName::createNestedNameSpecifier(Ctx, TD,
-                                                   true /*FullyQualified*/,
-                                                   WithGlobalNsPrefix);
-      } else if (const auto *TDD = dyn_cast<TypedefType>(Type)) {
-        return TypeName::createNestedNameSpecifier(Ctx, TDD->getDecl(),
-                                                   true /*FullyQualified*/,
-                                                   WithGlobalNsPrefix);
-      }
-      return Scope;
-    }
-  }
-  llvm_unreachable("bad NNS kind");
-}
-
-/// \brief Create a nested name specifier for the declaring context of
-/// the type.
-static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
-    const ASTContext &Ctx, const Decl *Decl,
-    bool FullyQualified, bool WithGlobalNsPrefix) {
-  assert(Decl);
-
-  const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
-  const auto *Outer = dyn_cast_or_null<NamedDecl>(DC);
-  const auto *OuterNS = dyn_cast_or_null<NamespaceDecl>(DC);
-  if (Outer && !(OuterNS && OuterNS->isAnonymousNamespace())) {
-    if (const auto *CxxDecl = dyn_cast<CXXRecordDecl>(DC)) {
-      if (ClassTemplateDecl *ClassTempl =
-              CxxDecl->getDescribedClassTemplate()) {
-        // We are in the case of a type(def) that was declared in a
-        // class template but is *not* type dependent.  In clang, it
-        // gets attached to the class template declaration rather than
-        // any specific class template instantiation.  This result in
-        // 'odd' fully qualified typename:
-        //
-        //    vector<_Tp,_Alloc>::size_type
-        //
-        // Make the situation is 'useable' but looking a bit odd by
-        // picking a random instance as the declaring context.
-        if (ClassTempl->spec_begin() != ClassTempl->spec_end()) {
-          Decl = *(ClassTempl->spec_begin());
-          Outer = dyn_cast<NamedDecl>(Decl);
-          OuterNS = dyn_cast<NamespaceDecl>(Decl);
-        }
-      }
-    }
-
-    if (OuterNS) {
-      return createNestedNameSpecifier(Ctx, OuterNS, WithGlobalNsPrefix);
-    } else if (const auto *TD = dyn_cast<TagDecl>(Outer)) {
-      return createNestedNameSpecifier(
-          Ctx, TD, FullyQualified, WithGlobalNsPrefix);
-    } else if (dyn_cast<TranslationUnitDecl>(Outer)) {
-      // Context is the TU. Nothing needs to be done.
-      return nullptr;
-    } else {
-      // Decl's context was neither the TU, a namespace, nor a
-      // TagDecl, which means it is a type local to a scope, and not
-      // accessible at the end of the TU.
-      return nullptr;
-    }
-  } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
-    return NestedNameSpecifier::GlobalSpecifier(Ctx);
-  }
-  return nullptr;
-}
-
-/// \brief Create a nested name specifier for the declaring context of
-/// the type.
-static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
-    const ASTContext &Ctx, const Type *TypePtr,
-    bool FullyQualified, bool WithGlobalNsPrefix) {
-  if (!TypePtr) return nullptr;
-
-  Decl *Decl = nullptr;
-  // There are probably other cases ...
-  if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
-    Decl = TDT->getDecl();
-  } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
-    Decl = TagDeclType->getDecl();
-  } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
-    Decl = TST->getTemplateName().getAsTemplateDecl();
-  } else {
-    Decl = TypePtr->getAsCXXRecordDecl();
-  }
-
-  if (!Decl) return nullptr;
-
-  return createNestedNameSpecifierForScopeOf(
-      Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
-}
-
-NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
-                                               const NamespaceDecl *Namespace,
-                                               bool WithGlobalNsPrefix) {
-  while (Namespace && Namespace->isInline()) {
-    // Ignore inline namespace;
-    Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
-  }
-  if (!Namespace) return nullptr;
-
-  bool FullyQualified = true;  // doesn't matter, DeclContexts are namespaces
-  return NestedNameSpecifier::Create(
-      Ctx,
-      createOuterNNS(Ctx, Namespace, FullyQualified, WithGlobalNsPrefix),
-      Namespace);
-}
-
-NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
-                                               const TypeDecl *TD,
-                                               bool FullyQualify,
-                                               bool WithGlobalNsPrefix) {
-  return NestedNameSpecifier::Create(
-      Ctx,
-      createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
-      false /*No TemplateKeyword*/,
-      TD->getTypeForDecl());
-}
-
-/// \brief Return the fully qualified type, including fully-qualified
-/// versions of any template parameters.
-QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
-                               bool WithGlobalNsPrefix) {
-  // In case of myType* we need to strip the pointer first, fully
-  // qualify and attach the pointer once again.
-  if (isa<PointerType>(QT.getTypePtr())) {
-    // Get the qualifiers.
-    Qualifiers Quals = QT.getQualifiers();
-    QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
-    QT = Ctx.getPointerType(QT);
-    // Add back the qualifiers.
-    QT = Ctx.getQualifiedType(QT, Quals);
-    return QT;
-  }
-
-  // In case of myType& we need to strip the reference first, fully
-  // qualify and attach the reference once again.
-  if (isa<ReferenceType>(QT.getTypePtr())) {
-    // Get the qualifiers.
-    bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
-    Qualifiers Quals = QT.getQualifiers();
-    QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
-    // Add the r- or l-value reference type back to the fully
-    // qualified one.
-    if (IsLValueRefTy)
-      QT = Ctx.getLValueReferenceType(QT);
-    else
-      QT = Ctx.getRValueReferenceType(QT);
-    // Add back the qualifiers.
-    QT = Ctx.getQualifiedType(QT, Quals);
-    return QT;
-  }
-
-  // Remove the part of the type related to the type being a template
-  // parameter (we won't report it as part of the 'type name' and it
-  // is actually make the code below to be more complex (to handle
-  // those)
-  while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
-    // Get the qualifiers.
-    Qualifiers Quals = QT.getQualifiers();
-
-    QT = dyn_cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
-
-    // Add back the qualifiers.
-    QT = Ctx.getQualifiedType(QT, Quals);
-  }
-
-  NestedNameSpecifier *Prefix = nullptr;
-  // Local qualifiers are attached to the QualType outside of the
-  // elaborated type.  Retrieve them before descending into the
-  // elaborated type.
-  Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
-  QT = QualType(QT.getTypePtr(), 0);
-  ElaboratedTypeKeyword Keyword = ETK_None;
-  if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
-    QT = ETypeInput->getNamedType();
-    assert(!QT.hasLocalQualifiers());
-    Keyword = ETypeInput->getKeyword();
-  }
-  // Create a nested name specifier if needed.
-  Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
-                                               true /*FullyQualified*/,
-                                               WithGlobalNsPrefix);
-
-  // In case of template specializations iterate over the arguments and
-  // fully qualify them as well.
-  if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
-      isa<const RecordType>(QT.getTypePtr())) {
-    // We are asked to fully qualify and we have a Record Type (which
-    // may point to a template specialization) or Template
-    // Specialization Type. We need to fully qualify their arguments.
-
-    const Type *TypePtr = getFullyQualifiedTemplateType(
-        Ctx, QT.getTypePtr(), WithGlobalNsPrefix);
-    QT = QualType(TypePtr, 0);
-  }
-  if (Prefix || Keyword != ETK_None) {
-    QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
-  }
-  QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
-  return QT;
-}
-
-std::string getFullyQualifiedName(QualType QT,
-                                  const ASTContext &Ctx,
-                                  bool WithGlobalNsPrefix) {
-  PrintingPolicy Policy(Ctx.getPrintingPolicy());
-  Policy.SuppressScope = false;
-  Policy.AnonymousTagLocations = false;
-  Policy.PolishForDeclaration = true;
-  Policy.SuppressUnwrittenScope = true;
-  QualType FQQT = getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
-  return FQQT.getAsString(Policy);
-}
-
-}  // end namespace TypeName
-}  // end namespace clang

Modified: cfe/trunk/unittests/Tooling/QualTypeNamesTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Tooling/QualTypeNamesTest.cpp?rev=317676&r1=317675&r2=317676&view=diff
==============================================================================
--- cfe/trunk/unittests/Tooling/QualTypeNamesTest.cpp (original)
+++ cfe/trunk/unittests/Tooling/QualTypeNamesTest.cpp Wed Nov  8 02:39:03 2017
@@ -7,7 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/Tooling/Core/QualTypeNames.h"
+#include "clang/AST/QualTypeNames.h"
 #include "TestVisitor.h"
 using namespace clang;
 




More information about the cfe-commits mailing list