clang API Documentation

SelectorLocationsKind.cpp
Go to the documentation of this file.
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 }