1 //===--- 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 18 using namespace clang; 19 20 static 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 45 namespace { 46 47 template <typename T> 48 SourceLocation getArgLoc(T* Arg); 49 50 template <> 51 SourceLocation getArgLoc<Expr>(Expr *Arg) { 52 return Arg->getLocStart(); 53 } 54 55 template <> 56 SourceLocation 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 61 template <typename T> 62 SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) { 63 return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation(); 64 } 65 66 template <typename T> 67 SelectorLocationsKind 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 93 SelectorLocationsKind 94 clang::hasStandardSelectorLocs(Selector Sel, 95 ArrayRef<SourceLocation> SelLocs, 96 ArrayRef<Expr *> Args, 97 SourceLocation EndLoc) { 98 return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); 99 } 100 101 SourceLocation 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 } 109 110 SelectorLocationsKind 111 clang::hasStandardSelectorLocs(Selector Sel, 112 ArrayRef<SourceLocation> SelLocs, 113 ArrayRef<ParmVarDecl *> Args, 114 SourceLocation EndLoc) { 115 return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); 116 } 117 118 SourceLocation 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 } 126