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