1207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===//
2207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//
3207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//                     The LLVM Compiler Infrastructure
4207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//
5207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis// This file is distributed under the University of Illinois Open Source
6207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis// License. See LICENSE.TXT for details.
7207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//
8207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
9207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//
10207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis// Describes whether the identifier locations for a selector are "standard"
11207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis// or not.
12207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//
13207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis//===----------------------------------------------------------------------===//
14207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
15207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis#include "clang/AST/SelectorLocationsKind.h"
16207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis#include "clang/AST/Expr.h"
17207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
18207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidisusing namespace clang;
19207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
20207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidisstatic SourceLocation getStandardSelLoc(unsigned Index,
21207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                        Selector Sel,
22207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                        bool WithArgSpace,
23207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                        SourceLocation ArgLoc,
24207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                        SourceLocation EndLoc) {
25207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  unsigned NumSelArgs = Sel.getNumArgs();
26207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  if (NumSelArgs == 0) {
27207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    assert(Index == 0);
28207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    if (EndLoc.isInvalid())
29207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis      return SourceLocation();
30207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0);
31207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    unsigned Len = II ? II->getLength() : 0;
32207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    return EndLoc.getLocWithOffset(-Len);
33207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  }
34207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
35207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  assert(Index < NumSelArgs);
36207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  if (ArgLoc.isInvalid())
37207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    return SourceLocation();
38207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index);
39207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1;
40207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  if (WithArgSpace)
41207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    ++Len;
42207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  return ArgLoc.getLocWithOffset(-Len);
43207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis}
44207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
45207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidisnamespace {
46207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
47207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidistemplate <typename T>
48207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios KyrtzidisSourceLocation getArgLoc(T* Arg);
49207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
50207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidistemplate <>
51207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios KyrtzidisSourceLocation getArgLoc<Expr>(Expr *Arg) {
52207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  return Arg->getLocStart();
53207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis}
54207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
55491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidistemplate <>
56491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios KyrtzidisSourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) {
570d94094cdbfd531ec96b719e0c8339aff7463ff9Argyrios Kyrtzidis  SourceLocation Loc = Arg->getLocStart();
580d94094cdbfd531ec96b719e0c8339aff7463ff9Argyrios Kyrtzidis  if (Loc.isInvalid())
590d94094cdbfd531ec96b719e0c8339aff7463ff9Argyrios Kyrtzidis    return Loc;
60491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  // -1 to point to left paren of the method parameter's type.
610d94094cdbfd531ec96b719e0c8339aff7463ff9Argyrios Kyrtzidis  return Loc.getLocWithOffset(-1);
62491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis}
63491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
64207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidistemplate <typename T>
65207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios KyrtzidisSourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) {
66207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation();
67207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis}
68207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
69207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidistemplate <typename T>
70207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios KyrtzidisSelectorLocationsKind hasStandardSelLocs(Selector Sel,
71207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                         ArrayRef<SourceLocation> SelLocs,
72207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                         ArrayRef<T *> Args,
73207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                         SourceLocation EndLoc) {
74207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  // Are selector locations in standard position with no space between args ?
75207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  unsigned i;
76207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  for (i = 0; i != SelLocs.size(); ++i) {
77207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false,
78207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                             Args, EndLoc))
79207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis      break;
80207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  }
81207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  if (i == SelLocs.size())
82207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    return SelLoc_StandardNoSpace;
83207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
84207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  // Are selector locations in standard position with space between args ?
85207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  for (i = 0; i != SelLocs.size(); ++i) {
86207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis    if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true,
87207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                             Args, EndLoc))
88207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis      return SelLoc_NonStandard;
89207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  }
90207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
91207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  return SelLoc_StandardWithSpace;
92207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis}
93207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
94207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis} // anonymous namespace
95207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
96207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios KyrtzidisSelectorLocationsKind
97207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidisclang::hasStandardSelectorLocs(Selector Sel,
98207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                               ArrayRef<SourceLocation> SelLocs,
99207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                               ArrayRef<Expr *> Args,
100207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                               SourceLocation EndLoc) {
101207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
102207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis}
103207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis
104207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios KyrtzidisSourceLocation clang::getStandardSelectorLoc(unsigned Index,
105207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                             Selector Sel,
106207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                             bool WithArgSpace,
107207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                             ArrayRef<Expr *> Args,
108207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                                             SourceLocation EndLoc) {
109207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis  return getStandardSelLoc(Index, Sel, WithArgSpace,
110207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis                           getArgLoc(Index, Args), EndLoc);
111207180802c836fda8acbedb47a92f9d2bdca59c3Argyrios Kyrtzidis}
112491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
113491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios KyrtzidisSelectorLocationsKind
114491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidisclang::hasStandardSelectorLocs(Selector Sel,
115491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                               ArrayRef<SourceLocation> SelLocs,
116491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                               ArrayRef<ParmVarDecl *> Args,
117491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                               SourceLocation EndLoc) {
118491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
119491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis}
120491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis
121491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios KyrtzidisSourceLocation clang::getStandardSelectorLoc(unsigned Index,
122491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                             Selector Sel,
123491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                             bool WithArgSpace,
124491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                             ArrayRef<ParmVarDecl *> Args,
125491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                                             SourceLocation EndLoc) {
126491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis  return getStandardSelLoc(Index, Sel, WithArgSpace,
127491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis                           getArgLoc(Index, Args), EndLoc);
128491306a83c4f0f49f95a3bcbca8580cb98a91c7aArgyrios Kyrtzidis}
129