xref: /aosp_15_r20/external/clang/lib/AST/SelectorLocationsKind.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
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