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