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