//===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Describes whether the identifier locations for a selector are "standard"
// or not.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/SelectorLocationsKind.h"
#include "clang/AST/Expr.h"

using namespace clang;

static SourceLocation getStandardSelLoc(unsigned Index,
                                        Selector Sel,
                                        bool WithArgSpace,
                                        SourceLocation ArgLoc,
                                        SourceLocation EndLoc) {
  unsigned NumSelArgs = Sel.getNumArgs();
  if (NumSelArgs == 0) {
    assert(Index == 0);
    if (EndLoc.isInvalid())
      return SourceLocation();
    IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0);
    unsigned Len = II ? II->getLength() : 0;
    return EndLoc.getLocWithOffset(-Len);
  }

  assert(Index < NumSelArgs);
  if (ArgLoc.isInvalid())
    return SourceLocation();
  IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index);
  unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1;
  if (WithArgSpace)
    ++Len;
  return ArgLoc.getLocWithOffset(-Len);
}

namespace {

template <typename T>
SourceLocation getArgLoc(T* Arg);

template <>
SourceLocation getArgLoc<Expr>(Expr *Arg) {
  return Arg->getLocStart();
}

template <>
SourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) {
  SourceLocation Loc = Arg->getLocStart();
  if (Loc.isInvalid())
    return Loc;
  // -1 to point to left paren of the method parameter's type.
  return Loc.getLocWithOffset(-1);
}

template <typename T>
SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) {
  return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation();
}

template <typename T>
SelectorLocationsKind hasStandardSelLocs(Selector Sel,
                                         ArrayRef<SourceLocation> SelLocs,
                                         ArrayRef<T *> Args,
                                         SourceLocation EndLoc) {
  // Are selector locations in standard position with no space between args ?
  unsigned i;
  for (i = 0; i != SelLocs.size(); ++i) {
    if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false,
                                             Args, EndLoc))
      break;
  }
  if (i == SelLocs.size())
    return SelLoc_StandardNoSpace;

  // Are selector locations in standard position with space between args ?
  for (i = 0; i != SelLocs.size(); ++i) {
    if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true,
                                             Args, EndLoc))
      return SelLoc_NonStandard;
  }

  return SelLoc_StandardWithSpace;
}

} // anonymous namespace

SelectorLocationsKind
clang::hasStandardSelectorLocs(Selector Sel,
                               ArrayRef<SourceLocation> SelLocs,
                               ArrayRef<Expr *> Args,
                               SourceLocation EndLoc) {
  return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
}

SourceLocation clang::getStandardSelectorLoc(unsigned Index,
                                             Selector Sel,
                                             bool WithArgSpace,
                                             ArrayRef<Expr *> Args,
                                             SourceLocation EndLoc) {
  return getStandardSelLoc(Index, Sel, WithArgSpace,
                           getArgLoc(Index, Args), EndLoc);
}

SelectorLocationsKind
clang::hasStandardSelectorLocs(Selector Sel,
                               ArrayRef<SourceLocation> SelLocs,
                               ArrayRef<ParmVarDecl *> Args,
                               SourceLocation EndLoc) {
  return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
}

SourceLocation clang::getStandardSelectorLoc(unsigned Index,
                                             Selector Sel,
                                             bool WithArgSpace,
                                             ArrayRef<ParmVarDecl *> Args,
                                             SourceLocation EndLoc) {
  return getStandardSelLoc(Index, Sel, WithArgSpace,
                           getArgLoc(Index, Args), EndLoc);
}
