1*67e74705SXin Li //===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // Describes whether the identifier locations for a selector are "standard"
11*67e74705SXin Li // or not.
12*67e74705SXin Li //
13*67e74705SXin Li //===----------------------------------------------------------------------===//
14*67e74705SXin Li
15*67e74705SXin Li #include "clang/AST/SelectorLocationsKind.h"
16*67e74705SXin Li #include "clang/AST/Expr.h"
17*67e74705SXin Li
18*67e74705SXin Li using namespace clang;
19*67e74705SXin Li
getStandardSelLoc(unsigned Index,Selector Sel,bool WithArgSpace,SourceLocation ArgLoc,SourceLocation EndLoc)20*67e74705SXin Li static SourceLocation getStandardSelLoc(unsigned Index,
21*67e74705SXin Li Selector Sel,
22*67e74705SXin Li bool WithArgSpace,
23*67e74705SXin Li SourceLocation ArgLoc,
24*67e74705SXin Li SourceLocation EndLoc) {
25*67e74705SXin Li unsigned NumSelArgs = Sel.getNumArgs();
26*67e74705SXin Li if (NumSelArgs == 0) {
27*67e74705SXin Li assert(Index == 0);
28*67e74705SXin Li if (EndLoc.isInvalid())
29*67e74705SXin Li return SourceLocation();
30*67e74705SXin Li IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0);
31*67e74705SXin Li unsigned Len = II ? II->getLength() : 0;
32*67e74705SXin Li return EndLoc.getLocWithOffset(-Len);
33*67e74705SXin Li }
34*67e74705SXin Li
35*67e74705SXin Li assert(Index < NumSelArgs);
36*67e74705SXin Li if (ArgLoc.isInvalid())
37*67e74705SXin Li return SourceLocation();
38*67e74705SXin Li IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index);
39*67e74705SXin Li unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1;
40*67e74705SXin Li if (WithArgSpace)
41*67e74705SXin Li ++Len;
42*67e74705SXin Li return ArgLoc.getLocWithOffset(-Len);
43*67e74705SXin Li }
44*67e74705SXin Li
45*67e74705SXin Li namespace {
46*67e74705SXin Li
47*67e74705SXin Li template <typename T>
48*67e74705SXin Li SourceLocation getArgLoc(T* Arg);
49*67e74705SXin Li
50*67e74705SXin Li template <>
getArgLoc(Expr * Arg)51*67e74705SXin Li SourceLocation getArgLoc<Expr>(Expr *Arg) {
52*67e74705SXin Li return Arg->getLocStart();
53*67e74705SXin Li }
54*67e74705SXin Li
55*67e74705SXin Li template <>
getArgLoc(ParmVarDecl * Arg)56*67e74705SXin Li SourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) {
57*67e74705SXin Li SourceLocation Loc = Arg->getLocStart();
58*67e74705SXin Li if (Loc.isInvalid())
59*67e74705SXin Li return Loc;
60*67e74705SXin Li // -1 to point to left paren of the method parameter's type.
61*67e74705SXin Li return Loc.getLocWithOffset(-1);
62*67e74705SXin Li }
63*67e74705SXin Li
64*67e74705SXin Li template <typename T>
getArgLoc(unsigned Index,ArrayRef<T * > Args)65*67e74705SXin Li SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) {
66*67e74705SXin Li return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation();
67*67e74705SXin Li }
68*67e74705SXin Li
69*67e74705SXin Li template <typename T>
hasStandardSelLocs(Selector Sel,ArrayRef<SourceLocation> SelLocs,ArrayRef<T * > Args,SourceLocation EndLoc)70*67e74705SXin Li SelectorLocationsKind hasStandardSelLocs(Selector Sel,
71*67e74705SXin Li ArrayRef<SourceLocation> SelLocs,
72*67e74705SXin Li ArrayRef<T *> Args,
73*67e74705SXin Li SourceLocation EndLoc) {
74*67e74705SXin Li // Are selector locations in standard position with no space between args ?
75*67e74705SXin Li unsigned i;
76*67e74705SXin Li for (i = 0; i != SelLocs.size(); ++i) {
77*67e74705SXin Li if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false,
78*67e74705SXin Li Args, EndLoc))
79*67e74705SXin Li break;
80*67e74705SXin Li }
81*67e74705SXin Li if (i == SelLocs.size())
82*67e74705SXin Li return SelLoc_StandardNoSpace;
83*67e74705SXin Li
84*67e74705SXin Li // Are selector locations in standard position with space between args ?
85*67e74705SXin Li for (i = 0; i != SelLocs.size(); ++i) {
86*67e74705SXin Li if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true,
87*67e74705SXin Li Args, EndLoc))
88*67e74705SXin Li return SelLoc_NonStandard;
89*67e74705SXin Li }
90*67e74705SXin Li
91*67e74705SXin Li return SelLoc_StandardWithSpace;
92*67e74705SXin Li }
93*67e74705SXin Li
94*67e74705SXin Li } // anonymous namespace
95*67e74705SXin Li
96*67e74705SXin Li SelectorLocationsKind
hasStandardSelectorLocs(Selector Sel,ArrayRef<SourceLocation> SelLocs,ArrayRef<Expr * > Args,SourceLocation EndLoc)97*67e74705SXin Li clang::hasStandardSelectorLocs(Selector Sel,
98*67e74705SXin Li ArrayRef<SourceLocation> SelLocs,
99*67e74705SXin Li ArrayRef<Expr *> Args,
100*67e74705SXin Li SourceLocation EndLoc) {
101*67e74705SXin Li return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
102*67e74705SXin Li }
103*67e74705SXin Li
getStandardSelectorLoc(unsigned Index,Selector Sel,bool WithArgSpace,ArrayRef<Expr * > Args,SourceLocation EndLoc)104*67e74705SXin Li SourceLocation clang::getStandardSelectorLoc(unsigned Index,
105*67e74705SXin Li Selector Sel,
106*67e74705SXin Li bool WithArgSpace,
107*67e74705SXin Li ArrayRef<Expr *> Args,
108*67e74705SXin Li SourceLocation EndLoc) {
109*67e74705SXin Li return getStandardSelLoc(Index, Sel, WithArgSpace,
110*67e74705SXin Li getArgLoc(Index, Args), EndLoc);
111*67e74705SXin Li }
112*67e74705SXin Li
113*67e74705SXin Li SelectorLocationsKind
hasStandardSelectorLocs(Selector Sel,ArrayRef<SourceLocation> SelLocs,ArrayRef<ParmVarDecl * > Args,SourceLocation EndLoc)114*67e74705SXin Li clang::hasStandardSelectorLocs(Selector Sel,
115*67e74705SXin Li ArrayRef<SourceLocation> SelLocs,
116*67e74705SXin Li ArrayRef<ParmVarDecl *> Args,
117*67e74705SXin Li SourceLocation EndLoc) {
118*67e74705SXin Li return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
119*67e74705SXin Li }
120*67e74705SXin Li
getStandardSelectorLoc(unsigned Index,Selector Sel,bool WithArgSpace,ArrayRef<ParmVarDecl * > Args,SourceLocation EndLoc)121*67e74705SXin Li SourceLocation clang::getStandardSelectorLoc(unsigned Index,
122*67e74705SXin Li Selector Sel,
123*67e74705SXin Li bool WithArgSpace,
124*67e74705SXin Li ArrayRef<ParmVarDecl *> Args,
125*67e74705SXin Li SourceLocation EndLoc) {
126*67e74705SXin Li return getStandardSelLoc(Index, Sel, WithArgSpace,
127*67e74705SXin Li getArgLoc(Index, Args), EndLoc);
128*67e74705SXin Li }
129