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