1226586Sdim//===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===// 2226586Sdim// 3226586Sdim// The LLVM Compiler Infrastructure 4226586Sdim// 5226586Sdim// This file is distributed under the University of Illinois Open Source 6226586Sdim// License. See LICENSE.TXT for details. 7226586Sdim// 8226586Sdim//===----------------------------------------------------------------------===// 9226586Sdim// 10226586Sdim// Describes whether the identifier locations for a selector are "standard" 11226586Sdim// or not. 12226586Sdim// 13226586Sdim//===----------------------------------------------------------------------===// 14226586Sdim 15226586Sdim#include "clang/AST/SelectorLocationsKind.h" 16226586Sdim#include "clang/AST/Expr.h" 17226586Sdim 18226586Sdimusing namespace clang; 19226586Sdim 20226586Sdimstatic SourceLocation getStandardSelLoc(unsigned Index, 21226586Sdim Selector Sel, 22226586Sdim bool WithArgSpace, 23226586Sdim SourceLocation ArgLoc, 24226586Sdim SourceLocation EndLoc) { 25226586Sdim unsigned NumSelArgs = Sel.getNumArgs(); 26226586Sdim if (NumSelArgs == 0) { 27226586Sdim assert(Index == 0); 28226586Sdim if (EndLoc.isInvalid()) 29226586Sdim return SourceLocation(); 30226586Sdim IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0); 31226586Sdim unsigned Len = II ? II->getLength() : 0; 32226586Sdim return EndLoc.getLocWithOffset(-Len); 33226586Sdim } 34226586Sdim 35226586Sdim assert(Index < NumSelArgs); 36226586Sdim if (ArgLoc.isInvalid()) 37226586Sdim return SourceLocation(); 38226586Sdim IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index); 39226586Sdim unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1; 40226586Sdim if (WithArgSpace) 41226586Sdim ++Len; 42226586Sdim return ArgLoc.getLocWithOffset(-Len); 43226586Sdim} 44226586Sdim 45226586Sdimnamespace { 46226586Sdim 47226586Sdimtemplate <typename T> 48226586SdimSourceLocation getArgLoc(T* Arg); 49226586Sdim 50226586Sdimtemplate <> 51226586SdimSourceLocation getArgLoc<Expr>(Expr *Arg) { 52226586Sdim return Arg->getLocStart(); 53226586Sdim} 54226586Sdim 55226586Sdimtemplate <> 56226586SdimSourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) { 57226586Sdim SourceLocation Loc = Arg->getLocStart(); 58226586Sdim if (Loc.isInvalid()) 59226586Sdim return Loc; 60226586Sdim // -1 to point to left paren of the method parameter's type. 61226586Sdim return Loc.getLocWithOffset(-1); 62226586Sdim} 63226586Sdim 64226586Sdimtemplate <typename T> 65226586SdimSourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) { 66226586Sdim return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation(); 67226586Sdim} 68226586Sdim 69226586Sdimtemplate <typename T> 70226586SdimSelectorLocationsKind hasStandardSelLocs(Selector Sel, 71226586Sdim ArrayRef<SourceLocation> SelLocs, 72226586Sdim ArrayRef<T *> Args, 73226586Sdim SourceLocation EndLoc) { 74226586Sdim // Are selector locations in standard position with no space between args ? 75226586Sdim unsigned i; 76226586Sdim for (i = 0; i != SelLocs.size(); ++i) { 77226586Sdim if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false, 78226586Sdim Args, EndLoc)) 79226586Sdim break; 80226586Sdim } 81226586Sdim if (i == SelLocs.size()) 82226586Sdim return SelLoc_StandardNoSpace; 83226586Sdim 84226586Sdim // Are selector locations in standard position with space between args ? 85226586Sdim for (i = 0; i != SelLocs.size(); ++i) { 86226586Sdim if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true, 87226586Sdim Args, EndLoc)) 88226586Sdim return SelLoc_NonStandard; 89226586Sdim } 90226586Sdim 91226586Sdim return SelLoc_StandardWithSpace; 92226586Sdim} 93226586Sdim 94226586Sdim} // anonymous namespace 95226586Sdim 96226586SdimSelectorLocationsKind 97226586Sdimclang::hasStandardSelectorLocs(Selector Sel, 98226586Sdim ArrayRef<SourceLocation> SelLocs, 99226586Sdim ArrayRef<Expr *> Args, 100226586Sdim SourceLocation EndLoc) { 101226586Sdim return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); 102226586Sdim} 103226586Sdim 104226586SdimSourceLocation clang::getStandardSelectorLoc(unsigned Index, 105226586Sdim Selector Sel, 106226586Sdim bool WithArgSpace, 107226586Sdim ArrayRef<Expr *> Args, 108226586Sdim SourceLocation EndLoc) { 109226586Sdim return getStandardSelLoc(Index, Sel, WithArgSpace, 110226586Sdim getArgLoc(Index, Args), EndLoc); 111226586Sdim} 112226586Sdim 113226586SdimSelectorLocationsKind 114226586Sdimclang::hasStandardSelectorLocs(Selector Sel, 115226586Sdim ArrayRef<SourceLocation> SelLocs, 116226586Sdim ArrayRef<ParmVarDecl *> Args, 117226586Sdim SourceLocation EndLoc) { 118226586Sdim return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); 119226586Sdim} 120226586Sdim 121226586SdimSourceLocation clang::getStandardSelectorLoc(unsigned Index, 122226586Sdim Selector Sel, 123226586Sdim bool WithArgSpace, 124226586Sdim ArrayRef<ParmVarDecl *> Args, 125226586Sdim SourceLocation EndLoc) { 126226586Sdim return getStandardSelLoc(Index, Sel, WithArgSpace, 127226586Sdim getArgLoc(Index, Args), EndLoc); 128226586Sdim} 129