SelectorLocationsKind.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //===--- SelectorLocationsKind.cpp - Kind of selector locations -*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. // Describes whether the identifier locations for a selector are "standard"
  10. // or not.
  11. //
  12. //===----------------------------------------------------------------------===//
  13. #include "clang/AST/SelectorLocationsKind.h"
  14. #include "clang/AST/Expr.h"
  15. using namespace clang;
  16. static SourceLocation getStandardSelLoc(unsigned Index,
  17. Selector Sel,
  18. bool WithArgSpace,
  19. SourceLocation ArgLoc,
  20. SourceLocation EndLoc) {
  21. unsigned NumSelArgs = Sel.getNumArgs();
  22. if (NumSelArgs == 0) {
  23. assert(Index == 0);
  24. if (EndLoc.isInvalid())
  25. return SourceLocation();
  26. IdentifierInfo *II = Sel.getIdentifierInfoForSlot(0);
  27. unsigned Len = II ? II->getLength() : 0;
  28. return EndLoc.getLocWithOffset(-Len);
  29. }
  30. assert(Index < NumSelArgs);
  31. if (ArgLoc.isInvalid())
  32. return SourceLocation();
  33. IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Index);
  34. unsigned Len = /* selector id */ (II ? II->getLength() : 0) + /* ':' */ 1;
  35. if (WithArgSpace)
  36. ++Len;
  37. return ArgLoc.getLocWithOffset(-Len);
  38. }
  39. namespace {
  40. template <typename T>
  41. SourceLocation getArgLoc(T* Arg);
  42. template <>
  43. SourceLocation getArgLoc<Expr>(Expr *Arg) {
  44. return Arg->getBeginLoc();
  45. }
  46. template <>
  47. SourceLocation getArgLoc<ParmVarDecl>(ParmVarDecl *Arg) {
  48. SourceLocation Loc = Arg->getBeginLoc();
  49. if (Loc.isInvalid())
  50. return Loc;
  51. // -1 to point to left paren of the method parameter's type.
  52. return Loc.getLocWithOffset(-1);
  53. }
  54. template <typename T>
  55. SourceLocation getArgLoc(unsigned Index, ArrayRef<T*> Args) {
  56. return Index < Args.size() ? getArgLoc(Args[Index]) : SourceLocation();
  57. }
  58. template <typename T>
  59. SelectorLocationsKind hasStandardSelLocs(Selector Sel,
  60. ArrayRef<SourceLocation> SelLocs,
  61. ArrayRef<T *> Args,
  62. SourceLocation EndLoc) {
  63. // Are selector locations in standard position with no space between args ?
  64. unsigned i;
  65. for (i = 0; i != SelLocs.size(); ++i) {
  66. if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/false,
  67. Args, EndLoc))
  68. break;
  69. }
  70. if (i == SelLocs.size())
  71. return SelLoc_StandardNoSpace;
  72. // Are selector locations in standard position with space between args ?
  73. for (i = 0; i != SelLocs.size(); ++i) {
  74. if (SelLocs[i] != getStandardSelectorLoc(i, Sel, /*WithArgSpace=*/true,
  75. Args, EndLoc))
  76. return SelLoc_NonStandard;
  77. }
  78. return SelLoc_StandardWithSpace;
  79. }
  80. } // anonymous namespace
  81. SelectorLocationsKind
  82. clang::hasStandardSelectorLocs(Selector Sel,
  83. ArrayRef<SourceLocation> SelLocs,
  84. ArrayRef<Expr *> Args,
  85. SourceLocation EndLoc) {
  86. return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
  87. }
  88. SourceLocation clang::getStandardSelectorLoc(unsigned Index,
  89. Selector Sel,
  90. bool WithArgSpace,
  91. ArrayRef<Expr *> Args,
  92. SourceLocation EndLoc) {
  93. return getStandardSelLoc(Index, Sel, WithArgSpace,
  94. getArgLoc(Index, Args), EndLoc);
  95. }
  96. SelectorLocationsKind
  97. clang::hasStandardSelectorLocs(Selector Sel,
  98. ArrayRef<SourceLocation> SelLocs,
  99. ArrayRef<ParmVarDecl *> Args,
  100. SourceLocation EndLoc) {
  101. return hasStandardSelLocs(Sel, SelLocs, Args, EndLoc);
  102. }
  103. SourceLocation clang::getStandardSelectorLoc(unsigned Index,
  104. Selector Sel,
  105. bool WithArgSpace,
  106. ArrayRef<ParmVarDecl *> Args,
  107. SourceLocation EndLoc) {
  108. return getStandardSelLoc(Index, Sel, WithArgSpace,
  109. getArgLoc(Index, Args), EndLoc);
  110. }