//===- USRGeneration.cpp - Routines for USR generation --------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/UnifiedSymbolResolution/USRGeneration.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/ODRHash.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace clang::index;

//===----------------------------------------------------------------------===//
// USR generation.
//===----------------------------------------------------------------------===//

/// Print only the offset part of \p Loc
/// \returns true on error.
static bool printLocOffset(llvm::raw_ostream &OS, SourceLocation Loc,
                           const SourceManager &SM) {
  if (Loc.isInvalid())
    return true;
  if (SM.getExpansionLoc(Loc) == SM.getSpellingLoc(Loc)) {
    // Use the offest into the FileID to represent the location.  Using
    // a line/column can cause us to look back at the original source file,
    // which is expensive.
    OS << '@' << SM.getDecomposedLoc(Loc).second;
    return false;
  }
  // In case expansion and spelling locations differ, we need both of them to
  // make the USR distinguishable:
  OS << '@' << SM.getDecomposedLoc(SM.getExpansionLoc(Loc)).second;
  OS << '@' << SM.getDecomposedLoc(SM.getSpellingLoc(Loc)).second;
  return false;
}

/// Print \p Loc including both the file and offset, if \p IncludeOffset is
/// true.  Print only the file of \p Loc otherwise.
/// \returns true on error.
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
                     const SourceManager &SM, bool IncludeOffset) {
  if (Loc.isInvalid()) {
    return true;
  }
  Loc = SM.getExpansionLoc(Loc);
  const FileIDAndOffset &Decomposed = SM.getDecomposedLoc(Loc);
  OptionalFileEntryRef FE = SM.getFileEntryRefForID(Decomposed.first);
  if (FE) {
    OS << llvm::sys::path::filename(FE->getName());
  } else {
    // This case really isn't interesting.
    return true;
  }
  if (IncludeOffset) {
    // Use the offest into the FileID to represent the location.  Using
    // a line/column can cause us to look back at the original source file,
    // which is expensive.
    printLocOffset(OS, Loc, SM);
  }
  return false;
}

static StringRef GetExternalSourceContainer(const NamedDecl *D) {
  if (!D)
    return StringRef();
  if (auto *attr = D->getExternalSourceSymbolAttr()) {
    return attr->getDefinedIn();
  }
  return StringRef();
}

namespace {
class USRGenerator : public ConstDeclVisitor<USRGenerator> {
  SmallVectorImpl<char> &Buf;
  llvm::raw_svector_ostream Out;
  ASTContext *Context;
  const LangOptions &LangOpts;
  bool IgnoreResults = false;
  // The flag below ensures that, when a source location needs to be printed,
  // the filename is printed at most once during the recursive visit.  The
  // offset part may be printed multiple times, since sub-decls along the
  // visit may each need a distinct location to disambiguate them.
  bool GeneratedFilename = false;

  llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;

public:
  USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf,
               const LangOptions &LangOpts)
      : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
    // Add the USR space prefix.
    Out << getUSRSpacePrefix();
  }

  bool ignoreResults() const { return IgnoreResults; }

  // Visitation methods from generating USRs from AST elements.
  void VisitDeclContext(const DeclContext *D);
  void VisitFieldDecl(const FieldDecl *D);
  void VisitFunctionDecl(const FunctionDecl *D);
  void VisitNamedDecl(const NamedDecl *D);
  void VisitNamespaceDecl(const NamespaceDecl *D);
  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
  void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
                              const ObjCCategoryDecl *CatD = nullptr);
  void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
  void VisitTagDecl(const TagDecl *D);
  void VisitTypedefDecl(const TypedefDecl *D);
  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
  void VisitVarDecl(const VarDecl *D);
  void VisitBindingDecl(const BindingDecl *D);
  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
  void VisitConceptDecl(const ConceptDecl *D);

  void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
    IgnoreResults = true; // No USRs for linkage specs themselves.
  }

  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
    IgnoreResults = true;
  }

  void VisitUsingDecl(const UsingDecl *D) {
    VisitDeclContext(D->getDeclContext());
    Out << "@UD@";

    bool EmittedDeclName = !EmitDeclName(D);
    assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
    (void)EmittedDeclName;
  }

  bool ShouldGenerateLocation(const NamedDecl *D);

  bool isLocal(const NamedDecl *D) {
    return D->getParentFunctionOrMethod() != nullptr;
  }

  void GenExtSymbolContainer(const NamedDecl *D);

  /// Generate the string component containing the location of the
  ///  declaration.
  bool GenLoc(const Decl *D, bool IncludeOffset);

  /// String generation methods used both by the visitation methods
  /// and from other clients that want to directly generate USRs.  These
  /// methods do not construct complete USRs (which incorporate the parents
  /// of an AST element), but only the fragments concerning the AST element
  /// itself.

  /// Generate a USR for an Objective-C class.
  void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
                    StringRef CategoryContextExtSymbolDefinedIn) {
    generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
                            CategoryContextExtSymbolDefinedIn);
  }

  /// Generate a USR for an Objective-C class category.
  void GenObjCCategory(StringRef cls, StringRef cat, StringRef clsExt,
                       StringRef catExt) {
    generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
  }

  /// Generate a USR fragment for an Objective-C property.
  void GenObjCProperty(StringRef prop, bool isClassProp) {
    generateUSRForObjCProperty(prop, isClassProp, Out);
  }

  /// Generate a USR for an Objective-C protocol.
  void GenObjCProtocol(StringRef prot, StringRef ext) {
    generateUSRForObjCProtocol(prot, Out, ext);
  }

  void VisitType(QualType T);
  void VisitTemplateParameterList(const TemplateParameterList *Params);
  void VisitTemplateName(TemplateName Name);
  void VisitTemplateArgument(const TemplateArgument &Arg);

  void VisitMSGuidDecl(const MSGuidDecl *D);
  void VisitTemplateParamObjectDecl(const TemplateParamObjectDecl *D);

  /// Emit a Decl's name using NamedDecl::printName() and return true if
  ///  the decl had no name.
  bool EmitDeclName(const NamedDecl *D);
};
} // end anonymous namespace

//===----------------------------------------------------------------------===//
// Generating USRs from ASTS.
//===----------------------------------------------------------------------===//

bool USRGenerator::EmitDeclName(const NamedDecl *D) {
  DeclarationName N = D->getDeclName();
  if (N.isEmpty())
    return true;
  Out << N;
  return false;
}

bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
  if (D->isExternallyVisible())
    return false;
  if (D->getParentFunctionOrMethod())
    return true;
  SourceLocation Loc = D->getLocation();
  if (Loc.isInvalid())
    return false;
  const SourceManager &SM = Context->getSourceManager();
  return !SM.isInSystemHeader(Loc);
}

void USRGenerator::VisitDeclContext(const DeclContext *DC) {
  if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
    Visit(D);
  else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs.
    VisitDeclContext(DC->getParent());
}

void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
  // The USR for an ivar declared in a class extension is based on the
  // ObjCInterfaceDecl, not the ObjCCategoryDecl.
  if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
    Visit(ID);
  else
    VisitDeclContext(D->getDeclContext());
  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
  if (EmitDeclName(D)) {
    // Bit fields can be anonymous.
    IgnoreResults = true;
    return;
  }
}

void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;

  if (D->getType().isNull()) {
    IgnoreResults = true;
    return;
  }

  const unsigned StartSize = Buf.size();
  VisitDeclContext(D->getDeclContext());
  if (Buf.size() == StartSize)
    GenExtSymbolContainer(D);

  bool IsTemplate = false;
  if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
    IsTemplate = true;
    Out << "@FT@";
    VisitTemplateParameterList(FunTmpl->getTemplateParameters());
  } else
    Out << "@F@";

  PrintingPolicy Policy(LangOpts);
  // Forward references can have different template argument names. Suppress the
  // template argument names in constructors to make their USR more stable.
  Policy.SuppressTemplateArgsInCXXConstructors = true;
  D->getDeclName().print(Out, Policy);

  if ((!LangOpts.CPlusPlus || D->isExternC()) &&
      !D->hasAttr<OverloadableAttr>())
    return;

  if (D->isFunctionTemplateSpecialization()) {
    Out << '<';
    if (const TemplateArgumentList *SpecArgs =
            D->getTemplateSpecializationArgs()) {
      for (const auto &Arg : SpecArgs->asArray()) {
        Out << '#';
        VisitTemplateArgument(Arg);
      }
    } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
                   D->getTemplateSpecializationArgsAsWritten()) {
      for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
        Out << '#';
        VisitTemplateArgument(ArgLoc.getArgument());
      }
    }
    Out << '>';
  }

  QualType CanonicalType = D->getType().getCanonicalType();
  // Mangle in type information for the arguments.
  if (const auto *FPT = CanonicalType->getAs<FunctionProtoType>()) {
    for (QualType PT : FPT->param_types()) {
      Out << '#';
      VisitType(PT);
    }
  }
  if (D->isVariadic())
    Out << '.';
  if (IsTemplate) {
    // Function templates can be overloaded by return type, for example:
    // \code
    //   template <class T> typename T::A foo() {}
    //   template <class T> typename T::B foo() {}
    // \endcode
    Out << '#';
    VisitType(D->getReturnType());
  }
  Out << '#';
  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
    if (MD->isStatic())
      Out << 'S';
    // FIXME: OpenCL: Need to consider address spaces
    if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
      Out << (char)('0' + quals);
    switch (MD->getRefQualifier()) {
    case RQ_None:
      break;
    case RQ_LValue:
      Out << '&';
      break;
    case RQ_RValue:
      Out << "&&";
      break;
    }
  }
}

void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
  VisitDeclContext(D->getDeclContext());
  Out << "@";

  if (EmitDeclName(D)) {
    // The string can be empty if the declaration has no name; e.g., it is
    // the ParmDecl with no name for declaration of a function pointer type,
    // e.g.: void  (*f)(void *);
    // In this case, don't generate a USR.
    IgnoreResults = true;
  }
}

void USRGenerator::VisitVarDecl(const VarDecl *D) {
  // VarDecls can be declared 'extern' within a function or method body,
  // but their enclosing DeclContext is the function, not the TU.  We need
  // to check the storage class to correctly generate the USR.
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;

  VisitDeclContext(D->getDeclContext());

  if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
    Out << "@VT";
    VisitTemplateParameterList(VarTmpl->getTemplateParameters());
  } else if (const VarTemplatePartialSpecializationDecl *PartialSpec =
                 dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
    Out << "@VP";
    VisitTemplateParameterList(PartialSpec->getTemplateParameters());
  }

  // Variables always have simple names.
  StringRef s = D->getName();

  // The string can be empty if the declaration has no name; e.g., it is
  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
  //    void  (*f)(void *);
  // In this case, don't generate a USR.
  if (s.empty())
    IgnoreResults = true;
  else
    Out << '@' << s;

  // For a template specialization, mangle the template arguments.
  if (const VarTemplateSpecializationDecl *Spec =
          dyn_cast<VarTemplateSpecializationDecl>(D)) {
    const TemplateArgumentList &Args = Spec->getTemplateArgs();
    Out << '>';
    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
      Out << '#';
      VisitTemplateArgument(Args.get(I));
    }
  }
}

void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
  if (isLocal(D) && GenLoc(D, /*IncludeOffset=*/true))
    return;
  VisitNamedDecl(D);
}

void USRGenerator::VisitNonTypeTemplateParmDecl(
    const NonTypeTemplateParmDecl *D) {
  GenLoc(D, /*IncludeOffset=*/true);
}

void USRGenerator::VisitTemplateTemplateParmDecl(
    const TemplateTemplateParmDecl *D) {
  GenLoc(D, /*IncludeOffset=*/true);
}

void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
  if (IgnoreResults)
    return;
  VisitDeclContext(D->getDeclContext());
  if (D->isAnonymousNamespace()) {
    Out << "@aN";
    return;
  }
  Out << "@N@" << D->getName();
}

void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
  VisitFunctionDecl(D->getTemplatedDecl());
}

void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
  VisitTagDecl(D->getTemplatedDecl());
}

void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
  VisitDeclContext(D->getDeclContext());
  if (!IgnoreResults)
    Out << "@NA@" << D->getName();
}

static const ObjCCategoryDecl *getCategoryContext(const NamedDecl *D) {
  if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
    return CD;
  if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
    return ICD->getCategoryDecl();
  return nullptr;
}

void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
  const DeclContext *container = D->getDeclContext();
  if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
    Visit(pd);
  } else {
    // The USR for a method declared in a class extension or category is based
    // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
    const ObjCInterfaceDecl *ID = D->getClassInterface();
    if (!ID) {
      IgnoreResults = true;
      return;
    }
    auto *CD = getCategoryContext(D);
    VisitObjCContainerDecl(ID, CD);
  }
  // Ideally we would use 'GenObjCMethod', but this is such a hot path
  // for Objective-C code that we don't want to use
  // DeclarationName::getAsString().
  Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
      << DeclarationName(D->getSelector());
}

void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
                                          const ObjCCategoryDecl *CatD) {
  switch (D->getKind()) {
  default:
    llvm_unreachable("Invalid ObjC container.");
  case Decl::ObjCInterface:
  case Decl::ObjCImplementation:
    GenObjCClass(D->getName(), GetExternalSourceContainer(D),
                 GetExternalSourceContainer(CatD));
    break;
  case Decl::ObjCCategory: {
    const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
    const ObjCInterfaceDecl *ID = CD->getClassInterface();
    if (!ID) {
      // Handle invalid code where the @interface might not
      // have been specified.
      // FIXME: We should be able to generate this USR even if the
      // @interface isn't available.
      IgnoreResults = true;
      return;
    }
    // Specially handle class extensions, which are anonymous categories.
    // We want to mangle in the location to uniquely distinguish them.
    if (CD->IsClassExtension()) {
      Out << "objc(ext)" << ID->getName() << '@';
      GenLoc(CD, /*IncludeOffset=*/true);
    } else
      GenObjCCategory(ID->getName(), CD->getName(),
                      GetExternalSourceContainer(ID),
                      GetExternalSourceContainer(CD));

    break;
  }
  case Decl::ObjCCategoryImpl: {
    const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
    const ObjCInterfaceDecl *ID = CD->getClassInterface();
    if (!ID) {
      // Handle invalid code where the @interface might not
      // have been specified.
      // FIXME: We should be able to generate this USR even if the
      // @interface isn't available.
      IgnoreResults = true;
      return;
    }
    GenObjCCategory(ID->getName(), CD->getName(),
                    GetExternalSourceContainer(ID),
                    GetExternalSourceContainer(CD));
    break;
  }
  case Decl::ObjCProtocol: {
    const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
    GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
    break;
  }
  }
}

void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
  // The USR for a property declared in a class extension or category is based
  // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
  if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
    VisitObjCContainerDecl(ID, getCategoryContext(D));
  else
    Visit(cast<Decl>(D->getDeclContext()));
  GenObjCProperty(D->getName(), D->isClassProperty());
}

void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
  if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
    VisitObjCPropertyDecl(PD);
    return;
  }

  IgnoreResults = true;
}

void USRGenerator::VisitTagDecl(const TagDecl *D) {
  // Add the location of the tag decl to handle resolution across
  // translation units.
  if (!isa<EnumDecl>(D) && ShouldGenerateLocation(D) &&
      GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;

  GenExtSymbolContainer(D);

  D = D->getCanonicalDecl();
  VisitDeclContext(D->getDeclContext());

  bool AlreadyStarted = false;
  if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
    if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
      AlreadyStarted = true;

      switch (D->getTagKind()) {
      case TagTypeKind::Interface:
      case TagTypeKind::Class:
      case TagTypeKind::Struct:
        Out << "@ST";
        break;
      case TagTypeKind::Union:
        Out << "@UT";
        break;
      case TagTypeKind::Enum:
        llvm_unreachable("enum template");
      }
      VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
    } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec =
                   dyn_cast<ClassTemplatePartialSpecializationDecl>(
                       CXXRecord)) {
      AlreadyStarted = true;

      switch (D->getTagKind()) {
      case TagTypeKind::Interface:
      case TagTypeKind::Class:
      case TagTypeKind::Struct:
        Out << "@SP";
        break;
      case TagTypeKind::Union:
        Out << "@UP";
        break;
      case TagTypeKind::Enum:
        llvm_unreachable("enum partial specialization");
      }
      VisitTemplateParameterList(PartialSpec->getTemplateParameters());
    }
  }

  if (!AlreadyStarted) {
    switch (D->getTagKind()) {
    case TagTypeKind::Interface:
    case TagTypeKind::Class:
    case TagTypeKind::Struct:
      Out << "@S";
      break;
    case TagTypeKind::Union:
      Out << "@U";
      break;
    case TagTypeKind::Enum:
      Out << "@E";
      break;
    }
  }

  Out << '@';
  assert(Buf.size() > 0);
  const unsigned off = Buf.size() - 1;

  if (EmitDeclName(D)) {
    if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
      Buf[off] = 'A';
      Out << '@' << *TD;
    } else {
      if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
        printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
      } else {
        Buf[off] = 'a';
        if (auto *ED = dyn_cast<EnumDecl>(D)) {
          // Distinguish USRs of anonymous enums by using their first
          // enumerator.
          auto enum_range = ED->enumerators();
          if (enum_range.begin() != enum_range.end()) {
            Out << '@' << **enum_range.begin();
          }
        }
      }
    }
  }

  // For a class template specialization, mangle the template arguments.
  if (const ClassTemplateSpecializationDecl *Spec =
          dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    const TemplateArgumentList &Args = Spec->getTemplateArgs();
    Out << '>';
    for (unsigned I = 0, N = Args.size(); I != N; ++I) {
      Out << '#';
      VisitTemplateArgument(Args.get(I));
    }
  }
}

void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;
  const DeclContext *DC = D->getDeclContext();
  if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
    Visit(DCN);
  Out << "@T@";
  Out << D->getName();
}

void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
  GenLoc(D, /*IncludeOffset=*/true);
}

void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
  StringRef Container = GetExternalSourceContainer(D);
  if (!Container.empty())
    Out << "@M@" << Container;
}

bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
  // Guard against null declarations in invalid code.
  if (!D) {
    IgnoreResults = true;
    return true;
  }
  // Do nothing if no need to print the offset nor the filename:
  if (!IncludeOffset && GeneratedFilename)
    return IgnoreResults;

  bool PrintErr = false;

  // Use the location of canonical decl.
  D = D->getCanonicalDecl();
  if (!GeneratedFilename) {
    GeneratedFilename = true;
    PrintErr = printLoc(Out, D->getBeginLoc(), Context->getSourceManager(),
                        IncludeOffset);
  } else {
    PrintErr =
        printLocOffset(Out, D->getBeginLoc(), Context->getSourceManager());
  }
  IgnoreResults = IgnoreResults || PrintErr;
  return IgnoreResults;
}

static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
                           NestedNameSpecifier NNS) {
  // FIXME: Encode the qualifier, don't just print it.
  PrintingPolicy PO(LangOpts);
  PO.SuppressTagKeyword = true;
  PO.SuppressUnwrittenScope = true;
  PO.ConstantArraySizeAsWritten = false;
  PO.AnonymousTagNameStyle =
      llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
  NNS.print(Out, PO);
}

void USRGenerator::VisitType(QualType T) {
  // This method mangles in USR information for types.  It can possibly
  // just reuse the naming-mangling logic used by codegen, although the
  // requirements for USRs might not be the same.
  ASTContext &Ctx = *Context;

  do {
    T = Ctx.getCanonicalType(T);
    Qualifiers Q = T.getQualifiers();
    unsigned qVal = 0;
    if (Q.hasConst())
      qVal |= 0x1;
    if (Q.hasVolatile())
      qVal |= 0x2;
    if (Q.hasRestrict())
      qVal |= 0x4;
    if (qVal)
      Out << ((char)('0' + qVal));

    // Mangle in ObjC GC qualifiers?

    if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
      Out << 'P';
      T = Expansion->getPattern();
    }

    if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
      switch (BT->getKind()) {
      case BuiltinType::Void:
        Out << 'v';
        break;
      case BuiltinType::Bool:
        Out << 'b';
        break;
      case BuiltinType::UChar:
        Out << 'c';
        break;
      case BuiltinType::Char8:
        Out << 'u';
        break;
      case BuiltinType::Char16:
        Out << 'q';
        break;
      case BuiltinType::Char32:
        Out << 'w';
        break;
      case BuiltinType::UShort:
        Out << 's';
        break;
      case BuiltinType::UInt:
        Out << 'i';
        break;
      case BuiltinType::ULong:
        Out << 'l';
        break;
      case BuiltinType::ULongLong:
        Out << 'k';
        break;
      case BuiltinType::UInt128:
        Out << 'j';
        break;
      case BuiltinType::Char_U:
      case BuiltinType::Char_S:
        Out << 'C';
        break;
      case BuiltinType::SChar:
        Out << 'r';
        break;
      case BuiltinType::WChar_S:
      case BuiltinType::WChar_U:
        Out << 'W';
        break;
      case BuiltinType::Short:
        Out << 'S';
        break;
      case BuiltinType::Int:
        Out << 'I';
        break;
      case BuiltinType::Long:
        Out << 'L';
        break;
      case BuiltinType::LongLong:
        Out << 'K';
        break;
      case BuiltinType::Int128:
        Out << 'J';
        break;
      case BuiltinType::Float16:
      case BuiltinType::Half:
        Out << 'h';
        break;
      case BuiltinType::Float:
        Out << 'f';
        break;
      case BuiltinType::Double:
        Out << 'd';
        break;
      case BuiltinType::LongDouble:
        Out << 'D';
        break;
      case BuiltinType::Float128:
        Out << 'Q';
        break;
      case BuiltinType::NullPtr:
        Out << 'n';
        break;
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << #Suffix << "_" << #ImgType;                               \
    break;
#include "clang/Basic/OpenCLImageTypes.def"
#define EXT_OPAQUE_TYPE(ExtType, Id, Ext)                                      \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << #ExtType;                                                 \
    break;
#include "clang/Basic/OpenCLExtensionTypes.def"
      case BuiltinType::OCLEvent:
        Out << "@BT@OCLEvent";
        break;
      case BuiltinType::OCLClkEvent:
        Out << "@BT@OCLClkEvent";
        break;
      case BuiltinType::OCLQueue:
        Out << "@BT@OCLQueue";
        break;
      case BuiltinType::OCLReserveID:
        Out << "@BT@OCLReserveID";
        break;
      case BuiltinType::OCLSampler:
        Out << "@BT@OCLSampler";
        break;
#define SVE_TYPE(Name, Id, SingletonId)                                        \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << #Name;                                                    \
    break;
#include "clang/Basic/AArch64ACLETypes.def"
#define PPC_VECTOR_TYPE(Name, Id, Size)                                        \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << #Name;                                                    \
    break;
#include "clang/Basic/PPCTypes.def"
#define RVV_TYPE(Name, Id, SingletonId)                                        \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << Name;                                                     \
    break;
#include "clang/Basic/RISCVVTypes.def"
#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/WebAssemblyReferenceTypes.def"
#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align)                       \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << #Name;                                                    \
    break;
#include "clang/Basic/AMDGPUTypes.def"
#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId)                            \
  case BuiltinType::Id:                                                        \
    Out << "@BT@" << #Name;                                                    \
    break;
#include "clang/Basic/HLSLIntangibleTypes.def"
      case BuiltinType::ShortAccum:
        Out << "@BT@ShortAccum";
        break;
      case BuiltinType::Accum:
        Out << "@BT@Accum";
        break;
      case BuiltinType::LongAccum:
        Out << "@BT@LongAccum";
        break;
      case BuiltinType::UShortAccum:
        Out << "@BT@UShortAccum";
        break;
      case BuiltinType::UAccum:
        Out << "@BT@UAccum";
        break;
      case BuiltinType::ULongAccum:
        Out << "@BT@ULongAccum";
        break;
      case BuiltinType::ShortFract:
        Out << "@BT@ShortFract";
        break;
      case BuiltinType::Fract:
        Out << "@BT@Fract";
        break;
      case BuiltinType::LongFract:
        Out << "@BT@LongFract";
        break;
      case BuiltinType::UShortFract:
        Out << "@BT@UShortFract";
        break;
      case BuiltinType::UFract:
        Out << "@BT@UFract";
        break;
      case BuiltinType::ULongFract:
        Out << "@BT@ULongFract";
        break;
      case BuiltinType::SatShortAccum:
        Out << "@BT@SatShortAccum";
        break;
      case BuiltinType::SatAccum:
        Out << "@BT@SatAccum";
        break;
      case BuiltinType::SatLongAccum:
        Out << "@BT@SatLongAccum";
        break;
      case BuiltinType::SatUShortAccum:
        Out << "@BT@SatUShortAccum";
        break;
      case BuiltinType::SatUAccum:
        Out << "@BT@SatUAccum";
        break;
      case BuiltinType::SatULongAccum:
        Out << "@BT@SatULongAccum";
        break;
      case BuiltinType::SatShortFract:
        Out << "@BT@SatShortFract";
        break;
      case BuiltinType::SatFract:
        Out << "@BT@SatFract";
        break;
      case BuiltinType::SatLongFract:
        Out << "@BT@SatLongFract";
        break;
      case BuiltinType::SatUShortFract:
        Out << "@BT@SatUShortFract";
        break;
      case BuiltinType::SatUFract:
        Out << "@BT@SatUFract";
        break;
      case BuiltinType::SatULongFract:
        Out << "@BT@SatULongFract";
        break;
      case BuiltinType::BFloat16:
        Out << "@BT@__bf16";
        break;
      case BuiltinType::Ibm128:
        Out << "@BT@__ibm128";
        break;
      case BuiltinType::ObjCId:
        Out << 'o';
        break;
      case BuiltinType::ObjCClass:
        Out << 'O';
        break;
      case BuiltinType::ObjCSel:
        Out << 'e';
        break;
#define BUILTIN_TYPE(Id, SingletonId)
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
      case BuiltinType::Dependent:
        // If you're adding a new builtin type, please add its name prefixed
        // with "@BT@" to `Out` (see cases above).
        IgnoreResults = true;
        break;
      }
      return;
    }

    // If we have already seen this (non-built-in) type, use a substitution
    // encoding.  Otherwise, record this as a substitution.
    auto [Substitution, Inserted] =
        TypeSubstitutions.try_emplace(T.getTypePtr(), TypeSubstitutions.size());
    if (!Inserted) {
      Out << 'S' << Substitution->second << '_';
      return;
    }

    if (const PointerType *PT = T->getAs<PointerType>()) {
      Out << '*';
      T = PT->getPointeeType();
      continue;
    }
    if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
      Out << '*';
      T = OPT->getPointeeType();
      continue;
    }
    if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
      Out << "&&";
      T = RT->getPointeeType();
      continue;
    }
    if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
      Out << '&';
      T = RT->getPointeeType();
      continue;
    }
    if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
      Out << 'F';
      VisitType(FT->getReturnType());
      Out << '(';
      for (const auto &I : FT->param_types()) {
        Out << '#';
        VisitType(I);
      }
      Out << ')';
      if (FT->isVariadic())
        Out << '.';
      return;
    }
    if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
      Out << 'B';
      T = BT->getPointeeType();
      continue;
    }
    if (const ComplexType *CT = T->getAs<ComplexType>()) {
      Out << '<';
      T = CT->getElementType();
      continue;
    }
    if (const TagType *TT = T->getAs<TagType>()) {
      if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) {
        T = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Ctx);
      } else {
        Out << '$';
        VisitTagDecl(TT->getDecl());
        return;
      }
    }
    if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
      Out << '$';
      VisitObjCInterfaceDecl(OIT->getDecl());
      return;
    }
    if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
      Out << 'Q';
      VisitType(OIT->getBaseType());
      for (auto *Prot : OIT->getProtocols())
        VisitObjCProtocolDecl(Prot);
      return;
    }
    if (const TemplateTypeParmType *TTP =
            T->getAsCanonical<TemplateTypeParmType>()) {
      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
      return;
    }
    if (const TemplateSpecializationType *Spec =
            T->getAs<TemplateSpecializationType>()) {
      Out << '>';
      VisitTemplateName(Spec->getTemplateName());
      Out << Spec->template_arguments().size();
      for (const auto &Arg : Spec->template_arguments())
        VisitTemplateArgument(Arg);
      return;
    }
    if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
      Out << '^';
      printQualifier(Out, LangOpts, DNT->getQualifier());
      Out << ':' << DNT->getIdentifier()->getName();
      return;
    }
    if (const auto *VT = T->getAs<VectorType>()) {
      Out << (T->isExtVectorType() ? ']' : '[');
      Out << VT->getNumElements();
      T = VT->getElementType();
      continue;
    }
    if (const auto *const AT = dyn_cast<ArrayType>(T)) {
      Out << '{';
      switch (AT->getSizeModifier()) {
      case ArraySizeModifier::Static:
        Out << 's';
        break;
      case ArraySizeModifier::Star:
        Out << '*';
        break;
      case ArraySizeModifier::Normal:
        Out << 'n';
        break;
      }
      if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
        Out << CAT->getSize();

      T = AT->getElementType();
      continue;
    }

    // Unhandled type.
    Out << ' ';
    break;
  } while (true);
}

void USRGenerator::VisitTemplateParameterList(
    const TemplateParameterList *Params) {
  if (!Params)
    return;
  Out << '>' << Params->size();
  for (TemplateParameterList::const_iterator P = Params->begin(),
                                             PEnd = Params->end();
       P != PEnd; ++P) {
    Out << '#';
    if (isa<TemplateTypeParmDecl>(*P)) {
      if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
        Out << 'p';
      Out << 'T';
      continue;
    }

    if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
      if (NTTP->isParameterPack())
        Out << 'p';
      Out << 'N';
      VisitType(NTTP->getType());
      continue;
    }

    TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
    if (TTP->isParameterPack())
      Out << 'p';
    Out << 't';
    VisitTemplateParameterList(TTP->getTemplateParameters());
  }
}

void USRGenerator::VisitTemplateName(TemplateName Name) {
  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
    if (TemplateTemplateParmDecl *TTP =
            dyn_cast<TemplateTemplateParmDecl>(Template)) {
      Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
      return;
    }

    Visit(Template);
    return;
  }

  // FIXME: Visit dependent template names.
}

void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
  switch (Arg.getKind()) {
  case TemplateArgument::Null:
    break;

  case TemplateArgument::Declaration:
    Visit(Arg.getAsDecl());
    break;

  case TemplateArgument::NullPtr:
    break;

  case TemplateArgument::TemplateExpansion:
    Out << 'P'; // pack expansion of...
    [[fallthrough]];
  case TemplateArgument::Template:
    VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
    break;

  case TemplateArgument::Expression:
    // FIXME: Visit expressions.
    break;

  case TemplateArgument::Pack:
    Out << 'p' << Arg.pack_size();
    for (const auto &P : Arg.pack_elements())
      VisitTemplateArgument(P);
    break;

  case TemplateArgument::Type:
    VisitType(Arg.getAsType());
    break;

  case TemplateArgument::Integral:
    Out << 'V';
    VisitType(Arg.getIntegralType());
    Out << Arg.getAsIntegral();
    break;

  case TemplateArgument::StructuralValue: {
    Out << 'S';
    VisitType(Arg.getStructuralValueType());
    ODRHash Hash{};
    Hash.AddStructuralValue(Arg.getAsStructuralValue());
    Out << Hash.CalculateHash();
    break;
  }
  }
}

void USRGenerator::VisitUnresolvedUsingValueDecl(
    const UnresolvedUsingValueDecl *D) {
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;
  VisitDeclContext(D->getDeclContext());
  Out << "@UUV@";
  printQualifier(Out, LangOpts, D->getQualifier());
  EmitDeclName(D);
}

void USRGenerator::VisitUnresolvedUsingTypenameDecl(
    const UnresolvedUsingTypenameDecl *D) {
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;
  VisitDeclContext(D->getDeclContext());
  Out << "@UUT@";
  printQualifier(Out, LangOpts, D->getQualifier());
  Out << D->getName(); // Simple name.
}

void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
    return;
  VisitDeclContext(D->getDeclContext());
  Out << "@CT@";
  EmitDeclName(D);
}

void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
  VisitDeclContext(D->getDeclContext());
  Out << "@MG@";
  D->NamedDecl::printName(Out);
}

void USRGenerator::VisitTemplateParamObjectDecl(
    const TemplateParamObjectDecl *D) {
  Out << "@TPO@";
  VisitType(D->getType());
  ODRHash Hash{};
  Hash.AddStructuralValue(D->getValue());
  Out << Hash.CalculateHash();
}

//===----------------------------------------------------------------------===//
// USR generation functions.
//===----------------------------------------------------------------------===//

static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
                                                 StringRef CatSymDefinedIn,
                                                 raw_ostream &OS) {
  if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
    return;
  if (CatSymDefinedIn.empty()) {
    OS << "@M@" << ClsSymDefinedIn << '@';
    return;
  }
  OS << "@CM@" << CatSymDefinedIn << '@';
  if (ClsSymDefinedIn != CatSymDefinedIn) {
    OS << ClsSymDefinedIn << '@';
  }
}

void clang::index::generateUSRForObjCClass(
    StringRef Cls, raw_ostream &OS, StringRef ExtSymDefinedIn,
    StringRef CategoryContextExtSymbolDefinedIn) {
  combineClassAndCategoryExtContainers(ExtSymDefinedIn,
                                       CategoryContextExtSymbolDefinedIn, OS);
  OS << "objc(cs)" << Cls;
}

void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
                                              raw_ostream &OS,
                                              StringRef ClsSymDefinedIn,
                                              StringRef CatSymDefinedIn) {
  combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
  OS << "objc(cy)" << Cls << '@' << Cat;
}

void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
  OS << '@' << Ivar;
}

void clang::index::generateUSRForObjCMethod(StringRef Sel,
                                            bool IsInstanceMethod,
                                            raw_ostream &OS) {
  OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
}

void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
                                              raw_ostream &OS) {
  OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
}

void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
                                              StringRef ExtSymDefinedIn) {
  if (!ExtSymDefinedIn.empty())
    OS << "@M@" << ExtSymDefinedIn << '@';
  OS << "objc(pl)" << Prot;
}

void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
                                            StringRef ExtSymDefinedIn) {
  if (!ExtSymDefinedIn.empty())
    OS << "@M@" << ExtSymDefinedIn;
  OS << "@E@" << EnumName;
}

void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
                                              raw_ostream &OS) {
  OS << '@' << EnumConstantName;
}

bool clang::index::generateUSRForDecl(const Decl *D,
                                      SmallVectorImpl<char> &Buf) {
  if (!D)
    return true;
  return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
}

bool clang::index::generateUSRForDecl(const Decl *D, SmallVectorImpl<char> &Buf,
                                      const LangOptions &LangOpts) {
  if (!D)
    return true;
  // We don't ignore decls with invalid source locations. Implicit decls, like
  // C++'s operator new function, can have invalid locations but it is fine to
  // create USRs that can identify them.

  // Check if the declaration has explicit external USR specified.
  auto *CD = D->getCanonicalDecl();
  if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
    if (!ExternalSymAttr->getUSR().empty()) {
      llvm::raw_svector_ostream Out(Buf);
      Out << ExternalSymAttr->getUSR();
      return false;
    }
  }
  USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
  UG.Visit(D);
  return UG.ignoreResults();
}

bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
                                       const SourceManager &SM,
                                       SmallVectorImpl<char> &Buf) {
  if (!MD)
    return true;
  return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(), SM,
                             Buf);
}

bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
                                       const SourceManager &SM,
                                       SmallVectorImpl<char> &Buf) {
  if (MacroName.empty())
    return true;

  llvm::raw_svector_ostream Out(Buf);

  // Assume that system headers are sane.  Don't put source location
  // information into the USR if the macro comes from a system header.
  bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);

  Out << getUSRSpacePrefix();
  if (ShouldGenerateLocation)
    printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
  Out << "@macro@";
  Out << MacroName;
  return false;
}

bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
                                      SmallVectorImpl<char> &Buf) {
  return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
}

bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
                                      SmallVectorImpl<char> &Buf,
                                      const LangOptions &LangOpts) {
  if (T.isNull())
    return true;
  T = T.getCanonicalType();

  USRGenerator UG(&Ctx, Buf, LangOpts);
  UG.VisitType(T);
  return UG.ignoreResults();
}

bool clang::index::generateFullUSRForModule(const Module *Mod,
                                            raw_ostream &OS) {
  if (!Mod->Parent)
    return generateFullUSRForTopLevelModuleName(Mod->Name, OS);
  if (generateFullUSRForModule(Mod->Parent, OS))
    return true;
  return generateUSRFragmentForModule(Mod, OS);
}

bool clang::index::generateFullUSRForTopLevelModuleName(StringRef ModName,
                                                        raw_ostream &OS) {
  OS << getUSRSpacePrefix();
  return generateUSRFragmentForModuleName(ModName, OS);
}

bool clang::index::generateUSRFragmentForModule(const Module *Mod,
                                                raw_ostream &OS) {
  return generateUSRFragmentForModuleName(Mod->Name, OS);
}

bool clang::index::generateUSRFragmentForModuleName(StringRef ModName,
                                                    raw_ostream &OS) {
  OS << "@M@" << ModName;
  return false;
}
