clang API Documentation
00001 //===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Describes whether the identifier locations for a selector are "standard" 00011 // or not. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "clang/AST/SelectorLocationsKind.h" 00016 #include "clang/AST/Expr.h" 00017 00018 using namespace clang; 00019 00020 static SourceLocation getStandardSelLoc(unsigned Index, 00021 Selector Sel, 00022 bool WithArgSpace, 00023 SourceLocation ArgLoc, 00024 SourceLocation EndLoc) { 00025 unsigned NumSelArgs = Sel.getNumArgs(); 00026 if (NumSelArgs == 0) { 00027 assert(Index == 0); 00028 if (EndLoc.isInvalid()) 00029 return SourceLocation(); 00030 IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0); 00031 unsigned Len = II ? II->getLength() : 0; 00032 return EndLoc.getLocWithOffset(-Len); 00033 } 00034 00035 assert(Index < NumSelArgs); 00036 if (ArgLoc.isInvalid()) 00037 return SourceLocation(); 00038 IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index); 00039 unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1; 00040 if (WithArgSpace) 00041 ++Len; 00042 return ArgLoc.getLocWithOffset(-Len); 00043 } 00044 00045 namespace { 00046 00047 template <typename T> 00048 SourceLocation getArgLoc(T* Arg); 00049 00050 template <> 00051 SourceLocation getArgLoc<Expr>(Expr *Arg) { 00052 return Arg->getLocStart(); 00053 } 00054 00055 template <> 00056 SourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) { 00057 SourceLocation Loc = Arg->getLocStart(); 00058 if (Loc.isInvalid()) 00059 return Loc; 00060 // -1 to point to left paren of the method parameter's type. 00061 return Loc.getLocWithOffset(-1); 00062 } 00063 00064 template <typename T> 00065 SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) { 00066 return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation(); 00067 } 00068 00069 template <typename T> 00070 SelectorLocationsKind hasStandardSelLocs(Selector Sel, 00071 ArrayRef<SourceLocation> SelLocs, 00072 ArrayRef<T *> Args, 00073 SourceLocation EndLoc) { 00074 // Are selector locations in standard position with no space between args ? 00075 unsigned i; 00076 for (i = 0; i != SelLocs.size(); ++i) { 00077 if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false, 00078 Args, EndLoc)) 00079 break; 00080 } 00081 if (i == SelLocs.size()) 00082 return SelLoc_StandardNoSpace; 00083 00084 // Are selector locations in standard position with space between args ? 00085 for (i = 0; i != SelLocs.size(); ++i) { 00086 if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true, 00087 Args, EndLoc)) 00088 return SelLoc_NonStandard; 00089 } 00090 00091 return SelLoc_StandardWithSpace; 00092 } 00093 00094 } // anonymous namespace 00095 00096 SelectorLocationsKind 00097 clang::hasStandardSelectorLocs(Selector Sel, 00098 ArrayRef<SourceLocation> SelLocs, 00099 ArrayRef<Expr *> Args, 00100 SourceLocation EndLoc) { 00101 return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); 00102 } 00103 00104 SourceLocation clang::getStandardSelectorLoc(unsigned Index, 00105 Selector Sel, 00106 bool WithArgSpace, 00107 ArrayRef<Expr *> Args, 00108 SourceLocation EndLoc) { 00109 return getStandardSelLoc(Index, Sel, WithArgSpace, 00110 getArgLoc(Index, Args), EndLoc); 00111 } 00112 00113 SelectorLocationsKind 00114 clang::hasStandardSelectorLocs(Selector Sel, 00115 ArrayRef<SourceLocation> SelLocs, 00116 ArrayRef<ParmVarDecl *> Args, 00117 SourceLocation EndLoc) { 00118 return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc); 00119 } 00120 00121 SourceLocation clang::getStandardSelectorLoc(unsigned Index, 00122 Selector Sel, 00123 bool WithArgSpace, 00124 ArrayRef<ParmVarDecl *> Args, 00125 SourceLocation EndLoc) { 00126 return getStandardSelLoc(Index, Sel, WithArgSpace, 00127 getArgLoc(Index, Args), EndLoc); 00128 }