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