//===- NestedNameSpecifier.cpp - C++ nested name specifiers ---------------===//
//
// 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.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DependenceFlags.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <cstring>

using namespace clang;

const NamespaceAndPrefixStorage *
NestedNameSpecifier::MakeNamespaceAndPrefixStorage(
    const ASTContext &Ctx, const NamespaceBaseDecl *Namespace,
    NestedNameSpecifier Prefix) {
  llvm::FoldingSetNodeID ID;
  NamespaceAndPrefixStorage::Profile(ID, Namespace, Prefix);

  void *InsertPos = nullptr;
  NamespaceAndPrefixStorage *S =
      Ctx.NamespaceAndPrefixStorages.FindNodeOrInsertPos(ID, InsertPos);
  if (!S) {
    S = new (Ctx, alignof(NamespaceAndPrefixStorage))
        NamespaceAndPrefixStorage(Namespace, Prefix);
    Ctx.NamespaceAndPrefixStorages.InsertNode(S, InsertPos);
  }
  return S;
}

bool NestedNameSpecifier::isFullyQualified() const {
  switch (getKind()) {
  case NestedNameSpecifier::Kind::Global:
    return true;
  case NestedNameSpecifier::Kind::Null:
  case NestedNameSpecifier::Kind::MicrosoftSuper:
    return false;
  case NestedNameSpecifier::Kind::Namespace:
    return getAsNamespaceAndPrefix().Prefix.isFullyQualified();
  case NestedNameSpecifier::Kind::Type:
    return getAsType()->getPrefix().isFullyQualified();
  }
  llvm_unreachable("Invalid NNS Kind!");
}

NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
  switch (getKind()) {
  case Kind::Null:
  case Kind::Global:
  case Kind::Namespace:
    return NestedNameSpecifierDependence::None;
  case Kind::MicrosoftSuper: {
    CXXRecordDecl *RD = getAsMicrosoftSuper();
    return RD->isDependentContext()
               ? NestedNameSpecifierDependence::DependentInstantiation |
                     NestedNameSpecifierDependence::Dependent
               : NestedNameSpecifierDependence::None;
  }
  case Kind::Type:
    return toNestedNameSpecifierDependence(getAsType()->getDependence());
  }
  llvm_unreachable("Invalid NNS Kind!");
}

/// Print this nested name specifier to the given output
/// stream.
void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
                                bool ResolveTemplateArguments,
                                bool PrintFinalScopeResOp) const {
  switch (getKind()) {
  case Kind::Namespace: {
    auto [Namespace, Prefix] = getAsNamespaceAndPrefix();
    Prefix.print(OS, Policy);
    if (const auto *NS = dyn_cast<NamespaceDecl>(Namespace)) {
      assert(!NS->isAnonymousNamespace());
      OS << NS->getName();
    } else {
      OS << cast<NamespaceAliasDecl>(Namespace)->getName();
    }
    break;
  }
  case Kind::Global:
    OS << "::";
    return;
  case Kind::MicrosoftSuper:
    OS << "__super";
    break;
  case Kind::Type: {
    PrintingPolicy InnerPolicy(Policy);
    InnerPolicy.SuppressTagKeyword = true;
    QualType(getAsType(), 0).print(OS, InnerPolicy);
    break;
  }
  case Kind::Null:
    return;
  }
  if (PrintFinalScopeResOp)
    OS << "::";
}

LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream *OS,
                                                const LangOptions *LO) const {
  print(OS ? *OS : llvm::errs(), LO ? *LO : LangOptions());
}

LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
  dump(/*OS=*/nullptr, &LO);
}
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const {
  dump(&OS);
}
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS,
                                                const LangOptions &LO) const {
  dump(&OS, &LO);
}

SourceLocation NestedNameSpecifierLoc::getBeginLoc() const {
  if (!Qualifier)
    return SourceLocation();

  NestedNameSpecifierLoc First = *this;
  while (NestedNameSpecifierLoc Prefix = First.getAsNamespaceAndPrefix().Prefix)
    First = Prefix;
  return First.getLocalSourceRange().getBegin();
}

static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
                   unsigned &BufferCapacity) {
  if (Start == End)
    return;

  if (BufferSize + (End - Start) > BufferCapacity) {
    // Reallocate the buffer.
    unsigned NewCapacity = std::max(
        (unsigned)(BufferCapacity ? BufferCapacity * 2 : sizeof(void *) * 2),
        (unsigned)(BufferSize + (End - Start)));
    if (!BufferCapacity) {
      char *NewBuffer = static_cast<char *>(llvm::safe_malloc(NewCapacity));
      if (Buffer)
        memcpy(NewBuffer, Buffer, BufferSize);
      Buffer = NewBuffer;
    } else {
      Buffer = static_cast<char *>(llvm::safe_realloc(Buffer, NewCapacity));
    }
    BufferCapacity = NewCapacity;
  }
  assert(Buffer && Start && End && End > Start && "Illegal memory buffer copy");
  memcpy(Buffer + BufferSize, Start, End - Start);
  BufferSize += End - Start;
}

/// Save a source location to the given buffer.
static void SaveSourceLocation(SourceLocation Loc, char *&Buffer,
                               unsigned &BufferSize, unsigned &BufferCapacity) {
  SourceLocation::UIntTy Raw = Loc.getRawEncoding();
  Append(reinterpret_cast<char *>(&Raw),
         reinterpret_cast<char *>(&Raw) + sizeof(Raw), Buffer, BufferSize,
         BufferCapacity);
}

/// Save a pointer to the given buffer.
static void SavePointer(void *Ptr, char *&Buffer, unsigned &BufferSize,
                        unsigned &BufferCapacity) {
  Append(reinterpret_cast<char *>(&Ptr),
         reinterpret_cast<char *>(&Ptr) + sizeof(void *),
         Buffer, BufferSize, BufferCapacity);
}

NestedNameSpecifierLocBuilder::
NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other)
    : Representation(Other.Representation) {
  if (!Other.Buffer)
    return;

  if (Other.BufferCapacity == 0) {
    // Shallow copy is okay.
    Buffer = Other.Buffer;
    BufferSize = Other.BufferSize;
    return;
  }

  // Deep copy
  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
         BufferCapacity);
}

NestedNameSpecifierLocBuilder &
NestedNameSpecifierLocBuilder::
operator=(const NestedNameSpecifierLocBuilder &Other) {
  Representation = Other.Representation;

  if (Buffer && Other.Buffer && BufferCapacity >= Other.BufferSize) {
    // Re-use our storage.
    BufferSize = Other.BufferSize;
    memcpy(Buffer, Other.Buffer, BufferSize);
    return *this;
  }

  // Free our storage, if we have any.
  if (BufferCapacity) {
    free(Buffer);
    BufferCapacity = 0;
  }

  if (!Other.Buffer) {
    // Empty.
    Buffer = nullptr;
    BufferSize = 0;
    return *this;
  }

  if (Other.BufferCapacity == 0) {
    // Shallow copy is okay.
    Buffer = Other.Buffer;
    BufferSize = Other.BufferSize;
    return *this;
  }

  // Deep copy.
  BufferSize = 0;
  Append(Other.Buffer, Other.Buffer + Other.BufferSize, Buffer, BufferSize,
         BufferCapacity);
  return *this;
}

void NestedNameSpecifierLocBuilder::Make(ASTContext &Context, TypeLoc TL,
                                         SourceLocation ColonColonLoc) {
  assert(!Representation);
  Representation = NestedNameSpecifier(TL.getTypePtr());

  // Push source-location info into the buffer.
  SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}

void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
                                           const NamespaceBaseDecl *Namespace,
                                           SourceLocation NamespaceLoc,
                                           SourceLocation ColonColonLoc) {
  Representation = NestedNameSpecifier(Context, Namespace, Representation);

  // Push source-location info into the buffer.
  SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}

void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
                                               SourceLocation ColonColonLoc) {
  assert(!Representation && "Already have a nested-name-specifier!?");
  Representation = NestedNameSpecifier::getGlobal();

  // Push source-location info into the buffer.
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}

void NestedNameSpecifierLocBuilder::MakeMicrosoftSuper(
    ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc,
    SourceLocation ColonColonLoc) {
  Representation = NestedNameSpecifier(RD);

  // Push source-location info into the buffer.
  SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
  SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}

void NestedNameSpecifierLocBuilder::PushTrivial(ASTContext &Context,
                                                NestedNameSpecifier Qualifier,
                                                SourceRange R) {
  // Construct bogus (but well-formed) source information for the
  // nested-name-specifier.
  switch (Qualifier.getKind()) {
  case NestedNameSpecifier::Kind::Null:
    return;
  case NestedNameSpecifier::Kind::Namespace: {
    auto [_1, Prefix] = Qualifier.getAsNamespaceAndPrefix();
    PushTrivial(Context, Prefix, R.getBegin());
    SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
    break;
  }
  case NestedNameSpecifier::Kind::Type: {
    TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(
        QualType(Qualifier.getAsType(), 0), R.getBegin());
    SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
                BufferCapacity);
    break;
  }
  case NestedNameSpecifier::Kind::Global:
  case NestedNameSpecifier::Kind::MicrosoftSuper:
    break;
  }
  SaveSourceLocation(R.getEnd(), Buffer, BufferSize, BufferCapacity);
}

void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
  if (BufferCapacity)
    free(Buffer);

  if (!Other) {
    Representation = std::nullopt;
    BufferSize = 0;
    return;
  }

  // Rather than copying the data (which is wasteful), "adopt" the
  // pointer (which points into the ASTContext) but set the capacity to zero to
  // indicate that we don't own it.
  Representation = Other.getNestedNameSpecifier();
  Buffer = static_cast<char *>(Other.getOpaqueData());
  BufferSize = Other.getDataLength();
  BufferCapacity = 0;
}

NestedNameSpecifierLoc
NestedNameSpecifierLocBuilder::getWithLocInContext(ASTContext &Context) const {
  if (!Representation)
    return NestedNameSpecifierLoc();

  // If we adopted our data pointer from elsewhere in the AST context, there's
  // no need to copy the memory.
  if (BufferCapacity == 0)
    return NestedNameSpecifierLoc(Representation, Buffer);

  // FIXME: After copying the source-location information, should we free
  // our (temporary) buffer and adopt the ASTContext-allocated memory?
  // Doing so would optimize repeated calls to getWithLocInContext().
  void *Mem = Context.Allocate(BufferSize, alignof(void *));
  memcpy(Mem, Buffer, BufferSize);
  return NestedNameSpecifierLoc(Representation, Mem);
}
