//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
//  This file defines the NestedNameSpecifier class, which represents
//  a C++ nested-name-specifier.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H

#include "clang/AST/DependenceFlags.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/PointerIntPair.h"
#include "llvm/Support/Compiler.h"
#include <cstdint>
#include <cstdlib>
#include <utility>

namespace clang {

class ASTContext;
class CXXRecordDecl;
class IdentifierInfo;
class LangOptions;
class NamespaceAliasDecl;
class NamespaceDecl;
struct PrintingPolicy;
class Type;
class TypeLoc;

/// Represents a C++ nested name specifier, such as
/// "\::std::vector<int>::".
///
/// C++ nested name specifiers are the prefixes to qualified
/// names. For example, "foo::" in "foo::x" is a nested name
/// specifier. Nested name specifiers are made up of a sequence of
/// specifiers, each of which can be a namespace, type, identifier
/// (for dependent names), decltype specifier, or the global specifier ('::').
/// The last two specifiers can only appear at the start of a
/// nested-namespace-specifier.
class NestedNameSpecifier : public llvm::FoldingSetNode {
  /// Enumeration describing
  enum StoredSpecifierKind {
    StoredIdentifier = 0,
    StoredDecl = 1,
    StoredTypeSpec = 2,
    StoredTypeSpecWithTemplate = 3
  };

  /// The nested name specifier that precedes this nested name
  /// specifier.
  ///
  /// The pointer is the nested-name-specifier that precedes this
  /// one. The integer stores one of the first four values of type
  /// SpecifierKind.
  llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;

  /// The last component in the nested name specifier, which
  /// can be an identifier, a declaration, or a type.
  ///
  /// When the pointer is NULL, this specifier represents the global
  /// specifier '::'. Otherwise, the pointer is one of
  /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
  /// specifier as encoded within the prefix.
  void* Specifier = nullptr;

public:
  /// The kind of specifier that completes this nested name
  /// specifier.
  enum SpecifierKind {
    /// An identifier, stored as an IdentifierInfo*.
    Identifier,

    /// A namespace, stored as a NamespaceDecl*.
    Namespace,

    /// A namespace alias, stored as a NamespaceAliasDecl*.
    NamespaceAlias,

    /// A type, stored as a Type*.
    TypeSpec,

    /// A type that was preceded by the 'template' keyword,
    /// stored as a Type*.
    TypeSpecWithTemplate,

    /// The global specifier '::'. There is no stored value.
    Global,

    /// Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
    /// the class it appeared in.
    Super
  };

private:
  /// Builds the global specifier.
  NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}

  /// Copy constructor used internally to clone nested name
  /// specifiers.
  NestedNameSpecifier(const NestedNameSpecifier &Other) = default;

  /// Either find or insert the given nested name specifier
  /// mockup in the given context.
  static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
                                           const NestedNameSpecifier &Mockup);

public:
  NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;

  /// Builds a specifier combining a prefix and an identifier.
  ///
  /// The prefix must be dependent, since nested name specifiers
  /// referencing an identifier are only permitted when the identifier
  /// cannot be resolved.
  static NestedNameSpecifier *Create(const ASTContext &Context,
                                     NestedNameSpecifier *Prefix,
                                     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.
  static NestedNameSpecifier *Create(const ASTContext &Context,
                                     NestedNameSpecifier *Prefix,
                                     NamespaceAliasDecl *Alias);

  /// Builds a nested name specifier that names a type.
  static NestedNameSpecifier *Create(const ASTContext &Context,
                                     NestedNameSpecifier *Prefix,
                                     bool Template, const Type *T);

  /// Builds a specifier that consists of just an identifier.
  ///
  /// The nested-name-specifier is assumed to be dependent, but has no
  /// prefix because the prefix is implied by something outside of the
  /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
  /// type.
  static NestedNameSpecifier *Create(const ASTContext &Context,
                                     IdentifierInfo *II);

  /// Returns the nested name specifier representing the global
  /// scope.
  static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);

  /// Returns the nested name specifier representing the __super scope
  /// for the given CXXRecordDecl.
  static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
                                             CXXRecordDecl *RD);

  /// Return the prefix of this nested name specifier.
  ///
  /// The prefix contains all of the parts of the nested name
  /// specifier that precede this current specifier. For example, for a
  /// nested name specifier that represents "foo::bar::", the current
  /// specifier will contain "bar::" and the prefix will contain
  /// "foo::".
  NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }

  /// Determine what kind of nested name specifier is stored.
  SpecifierKind getKind() const;

  /// Retrieve the identifier stored in this nested name
  /// specifier.
  IdentifierInfo *getAsIdentifier() const {
    if (Prefix.getInt() == StoredIdentifier)
      return (IdentifierInfo *)Specifier;

    return nullptr;
  }

  /// Retrieve the namespace stored in this nested name
  /// specifier.
  NamespaceDecl *getAsNamespace() const;

  /// Retrieve the namespace alias stored in this nested name
  /// specifier.
  NamespaceAliasDecl *getAsNamespaceAlias() const;

  /// Retrieve the record declaration stored in this nested name
  /// specifier.
  CXXRecordDecl *getAsRecordDecl() const;

  /// Retrieve the type stored in this nested name specifier.
  const Type *getAsType() const {
    if (Prefix.getInt() == StoredTypeSpec ||
        Prefix.getInt() == StoredTypeSpecWithTemplate)
      return (const Type *)Specifier;

    return nullptr;
  }

  NestedNameSpecifierDependence getDependence() const;

  /// Whether this nested name specifier refers to a dependent
  /// type or not.
  bool isDependent() const;

  /// Whether this nested name specifier involves a template
  /// parameter.
  bool isInstantiationDependent() const;

  /// Whether this nested-name-specifier contains an unexpanded
  /// parameter pack (for C++11 variadic templates).
  bool containsUnexpandedParameterPack() const;

  /// Whether this nested name specifier contains an error.
  bool containsErrors() const;

  /// Print this nested name specifier to the given output stream. If
  /// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
  /// `ns::SomeTemplate<int, MyClass>` instead of
  /// `ns::SomeTemplate<Container::value_type, T>`.
  void print(raw_ostream &OS, const PrintingPolicy &Policy,
             bool ResolveTemplateArguments = false) const;

  void Profile(llvm::FoldingSetNodeID &ID) const {
    ID.AddPointer(Prefix.getOpaqueValue());
    ID.AddPointer(Specifier);
  }

  /// Dump the nested name specifier to standard output to aid
  /// in debugging.
  void dump(const LangOptions &LO) const;
  void dump() const;
  void dump(llvm::raw_ostream &OS) const;
  void dump(llvm::raw_ostream &OS, const LangOptions &LO) const;
};

/// A C++ nested-name-specifier augmented with source location
/// information.
class NestedNameSpecifierLoc {
  NestedNameSpecifier *Qualifier = nullptr;
  void *Data = nullptr;

  /// Determines the data length for the last component in the
  /// given nested-name-specifier.
  static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);

  /// Determines the data length for the entire
  /// nested-name-specifier.
  static unsigned getDataLength(NestedNameSpecifier *Qualifier);

public:
  /// Construct an empty nested-name-specifier.
  NestedNameSpecifierLoc() = default;

  /// Construct a nested-name-specifier with source location information
  /// from
  NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
      : Qualifier(Qualifier), Data(Data) {}

  /// Evaluates true when this nested-name-specifier location is
  /// non-empty.
  explicit operator bool() const { return Qualifier; }

  /// Evaluates true when this nested-name-specifier location is
  /// empty.
  bool hasQualifier() const { return Qualifier; }

  /// Retrieve the nested-name-specifier to which this instance
  /// refers.
  NestedNameSpecifier *getNestedNameSpecifier() const {
    return Qualifier;
  }

  /// Retrieve the opaque pointer that refers to source-location data.
  void *getOpaqueData() const { return Data; }

  /// Retrieve the source range covering the entirety of this
  /// nested-name-specifier.
  ///
  /// For example, if this instance refers to a nested-name-specifier
  /// \c \::std::vector<int>::, the returned source range would cover
  /// from the initial '::' to the last '::'.
  SourceRange getSourceRange() const LLVM_READONLY;

  /// Retrieve the source range covering just the last part of
  /// this nested-name-specifier, not including the prefix.
  ///
  /// For example, if this instance refers to a nested-name-specifier
  /// \c \::std::vector<int>::, the returned source range would cover
  /// from "vector" to the last '::'.
  SourceRange getLocalSourceRange() const;

  /// Retrieve the location of the beginning of this
  /// nested-name-specifier.
  SourceLocation getBeginLoc() const {
    return getSourceRange().getBegin();
  }

  /// Retrieve the location of the end of this
  /// nested-name-specifier.
  SourceLocation getEndLoc() const {
    return getSourceRange().getEnd();
  }

  /// Retrieve the location of the beginning of this
  /// component of the nested-name-specifier.
  SourceLocation getLocalBeginLoc() const {
    return getLocalSourceRange().getBegin();
  }

  /// Retrieve the location of the end of this component of the
  /// nested-name-specifier.
  SourceLocation getLocalEndLoc() const {
    return getLocalSourceRange().getEnd();
  }

  /// Return the prefix of this nested-name-specifier.
  ///
  /// For example, if this instance refers to a nested-name-specifier
  /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
  /// returned prefix may be empty, if this is the first component of
  /// the nested-name-specifier.
  NestedNameSpecifierLoc getPrefix() const {
    if (!Qualifier)
      return *this;

    return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
  }

  /// For a nested-name-specifier that refers to a type,
  /// retrieve the type with source-location information.
  TypeLoc getTypeLoc() const;

  /// Determines the data length for the entire
  /// nested-name-specifier.
  unsigned getDataLength() const { return getDataLength(Qualifier); }

  friend bool operator==(NestedNameSpecifierLoc X,
                         NestedNameSpecifierLoc Y) {
    return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
  }

  friend bool operator!=(NestedNameSpecifierLoc X,
                         NestedNameSpecifierLoc Y) {
    return !(X == Y);
  }
};

/// Class that aids in the construction of nested-name-specifiers along
/// with source-location information for all of the components of the
/// nested-name-specifier.
class NestedNameSpecifierLocBuilder {
  /// The current representation of the nested-name-specifier we're
  /// building.
  NestedNameSpecifier *Representation = nullptr;

  /// Buffer used to store source-location information for the
  /// nested-name-specifier.
  ///
  /// Note that we explicitly manage the buffer (rather than using a
  /// SmallVector) because \c Declarator expects it to be possible to memcpy()
  /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
  char *Buffer = nullptr;

  /// The size of the buffer used to store source-location information
  /// for the nested-name-specifier.
  unsigned BufferSize = 0;

  /// The capacity of the buffer used to store source-location
  /// information for the nested-name-specifier.
  unsigned BufferCapacity = 0;

public:
  NestedNameSpecifierLocBuilder() = default;
  NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);

  NestedNameSpecifierLocBuilder &
  operator=(const NestedNameSpecifierLocBuilder &Other);

  ~NestedNameSpecifierLocBuilder() {
    if (BufferCapacity)
      free(Buffer);
  }

  /// Retrieve the representation of the nested-name-specifier.
  NestedNameSpecifier *getRepresentation() const { return Representation; }

  /// Extend the current nested-name-specifier by another
  /// nested-name-specifier component of the form 'type::'.
  ///
  /// \param Context The AST context in which this nested-name-specifier
  /// resides.
  ///
  /// \param TemplateKWLoc The location of the 'template' keyword, if present.
  ///
  /// \param TL The TypeLoc that describes the type preceding the '::'.
  ///
  /// \param ColonColonLoc The location of the trailing '::'.
  void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL,
              SourceLocation ColonColonLoc);

  /// Extend the current nested-name-specifier by another
  /// nested-name-specifier component of the form 'identifier::'.
  ///
  /// \param Context The AST context in which this nested-name-specifier
  /// resides.
  ///
  /// \param Identifier The identifier.
  ///
  /// \param IdentifierLoc The location of the identifier.
  ///
  /// \param ColonColonLoc The location of the trailing '::'.
  void Extend(ASTContext &Context, IdentifierInfo *Identifier,
              SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);

  /// Extend the current nested-name-specifier by another
  /// nested-name-specifier component of the form 'namespace::'.
  ///
  /// \param Context The AST context in which this nested-name-specifier
  /// resides.
  ///
  /// \param Namespace The namespace.
  ///
  /// \param NamespaceLoc The location of the namespace name.
  ///
  /// \param ColonColonLoc The location of the trailing '::'.
  void Extend(ASTContext &Context, NamespaceDecl *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);

  /// Turns this (empty) nested-name-specifier into '__super'
  /// nested-name-specifier.
  ///
  /// \param Context The AST context in which this nested-name-specifier
  /// resides.
  ///
  /// \param RD The declaration of the class in which nested-name-specifier
  /// appeared.
  ///
  /// \param SuperLoc The location of the '__super' keyword.
  /// name.
  ///
  /// \param ColonColonLoc The location of the trailing '::'.
  void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
                 SourceLocation SuperLoc, SourceLocation ColonColonLoc);

  /// Make a new nested-name-specifier from incomplete source-location
  /// information.
  ///
  /// This routine should be used very, very rarely, in cases where we
  /// need to synthesize a nested-name-specifier. Most code should instead use
  /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
  void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
                   SourceRange R);

  /// Adopt an existing nested-name-specifier (with source-range
  /// information).
  void Adopt(NestedNameSpecifierLoc Other);

  /// Retrieve the source range covered by this nested-name-specifier.
  SourceRange getSourceRange() const LLVM_READONLY {
    return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
  }

  /// Retrieve a nested-name-specifier with location information,
  /// copied into the given AST context.
  ///
  /// \param Context The context into which this nested-name-specifier will be
  /// copied.
  NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;

  /// Retrieve a nested-name-specifier with location
  /// information based on the information in this builder.
  ///
  /// This loc will contain references to the builder's internal data and may
  /// be invalidated by any change to the builder.
  NestedNameSpecifierLoc getTemporary() const {
    return NestedNameSpecifierLoc(Representation, Buffer);
  }

  /// Clear out this builder, and prepare it to build another
  /// nested-name-specifier with source-location information.
  void Clear() {
    Representation = nullptr;
    BufferSize = 0;
  }

  /// Retrieve the underlying buffer.
  ///
  /// \returns A pair containing a pointer to the buffer of source-location
  /// data and the size of the source-location data that resides in that
  /// buffer.
  std::pair<char *, unsigned> getBuffer() const {
    return std::make_pair(Buffer, BufferSize);
  }
};

/// Insertion operator for diagnostics.  This allows sending
/// NestedNameSpecifiers into a diagnostic with <<.
inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
                                             NestedNameSpecifier *NNS) {
  DB.AddTaggedVal(reinterpret_cast<uint64_t>(NNS),
                  DiagnosticsEngine::ak_nestednamespec);
  return DB;
}

} // namespace clang

namespace llvm {

template <> struct DenseMapInfo<clang::NestedNameSpecifierLoc> {
  using FirstInfo = DenseMapInfo<clang::NestedNameSpecifier *>;
  using SecondInfo = DenseMapInfo<void *>;

  static clang::NestedNameSpecifierLoc getEmptyKey() {
    return clang::NestedNameSpecifierLoc(FirstInfo::getEmptyKey(),
                                         SecondInfo::getEmptyKey());
  }

  static clang::NestedNameSpecifierLoc getTombstoneKey() {
    return clang::NestedNameSpecifierLoc(FirstInfo::getTombstoneKey(),
                                         SecondInfo::getTombstoneKey());
  }

  static unsigned getHashValue(const clang::NestedNameSpecifierLoc &PairVal) {
    return hash_combine(
        FirstInfo::getHashValue(PairVal.getNestedNameSpecifier()),
        SecondInfo::getHashValue(PairVal.getOpaqueData()));
  }

  static bool isEqual(const clang::NestedNameSpecifierLoc &LHS,
                      const clang::NestedNameSpecifierLoc &RHS) {
    return LHS == RHS;
  }
};
} // namespace llvm

#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
