AttrImpl.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. //===--- AttrImpl.cpp - Classes for representing attributes -----*- 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. // This file contains out-of-line methods for Attr classes.
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #include "clang/AST/ASTContext.h"
  13. #include "clang/AST/Attr.h"
  14. #include "clang/AST/Expr.h"
  15. #include "clang/AST/Type.h"
  16. #include <optional>
  17. using namespace clang;
  18. void LoopHintAttr::printPrettyPragma(raw_ostream &OS,
  19. const PrintingPolicy &Policy) const {
  20. unsigned SpellingIndex = getAttributeSpellingListIndex();
  21. // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
  22. // "nounroll" is already emitted as the pragma name.
  23. if (SpellingIndex == Pragma_nounroll ||
  24. SpellingIndex == Pragma_nounroll_and_jam)
  25. return;
  26. else if (SpellingIndex == Pragma_unroll ||
  27. SpellingIndex == Pragma_unroll_and_jam) {
  28. OS << ' ' << getValueString(Policy);
  29. return;
  30. }
  31. assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
  32. OS << ' ' << getOptionName(option) << getValueString(Policy);
  33. }
  34. // Return a string containing the loop hint argument including the
  35. // enclosing parentheses.
  36. std::string LoopHintAttr::getValueString(const PrintingPolicy &Policy) const {
  37. std::string ValueName;
  38. llvm::raw_string_ostream OS(ValueName);
  39. OS << "(";
  40. if (state == Numeric)
  41. value->printPretty(OS, nullptr, Policy);
  42. else if (state == FixedWidth || state == ScalableWidth) {
  43. if (value) {
  44. value->printPretty(OS, nullptr, Policy);
  45. if (state == ScalableWidth)
  46. OS << ", scalable";
  47. } else if (state == ScalableWidth)
  48. OS << "scalable";
  49. else
  50. OS << "fixed";
  51. } else if (state == Enable)
  52. OS << "enable";
  53. else if (state == Full)
  54. OS << "full";
  55. else if (state == AssumeSafety)
  56. OS << "assume_safety";
  57. else
  58. OS << "disable";
  59. OS << ")";
  60. return ValueName;
  61. }
  62. // Return a string suitable for identifying this attribute in diagnostics.
  63. std::string
  64. LoopHintAttr::getDiagnosticName(const PrintingPolicy &Policy) const {
  65. unsigned SpellingIndex = getAttributeSpellingListIndex();
  66. if (SpellingIndex == Pragma_nounroll)
  67. return "#pragma nounroll";
  68. else if (SpellingIndex == Pragma_unroll)
  69. return "#pragma unroll" +
  70. (option == UnrollCount ? getValueString(Policy) : "");
  71. else if (SpellingIndex == Pragma_nounroll_and_jam)
  72. return "#pragma nounroll_and_jam";
  73. else if (SpellingIndex == Pragma_unroll_and_jam)
  74. return "#pragma unroll_and_jam" +
  75. (option == UnrollAndJamCount ? getValueString(Policy) : "");
  76. assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
  77. return getOptionName(option) + getValueString(Policy);
  78. }
  79. void OMPDeclareSimdDeclAttr::printPrettyPragma(
  80. raw_ostream &OS, const PrintingPolicy &Policy) const {
  81. if (getBranchState() != BS_Undefined)
  82. OS << ' ' << ConvertBranchStateTyToStr(getBranchState());
  83. if (auto *E = getSimdlen()) {
  84. OS << " simdlen(";
  85. E->printPretty(OS, nullptr, Policy);
  86. OS << ")";
  87. }
  88. if (uniforms_size() > 0) {
  89. OS << " uniform";
  90. StringRef Sep = "(";
  91. for (auto *E : uniforms()) {
  92. OS << Sep;
  93. E->printPretty(OS, nullptr, Policy);
  94. Sep = ", ";
  95. }
  96. OS << ")";
  97. }
  98. alignments_iterator NI = alignments_begin();
  99. for (auto *E : aligneds()) {
  100. OS << " aligned(";
  101. E->printPretty(OS, nullptr, Policy);
  102. if (*NI) {
  103. OS << ": ";
  104. (*NI)->printPretty(OS, nullptr, Policy);
  105. }
  106. OS << ")";
  107. ++NI;
  108. }
  109. steps_iterator I = steps_begin();
  110. modifiers_iterator MI = modifiers_begin();
  111. for (auto *E : linears()) {
  112. OS << " linear(";
  113. if (*MI != OMPC_LINEAR_unknown)
  114. OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI)
  115. << "(";
  116. E->printPretty(OS, nullptr, Policy);
  117. if (*MI != OMPC_LINEAR_unknown)
  118. OS << ")";
  119. if (*I) {
  120. OS << ": ";
  121. (*I)->printPretty(OS, nullptr, Policy);
  122. }
  123. OS << ")";
  124. ++I;
  125. ++MI;
  126. }
  127. }
  128. void OMPDeclareTargetDeclAttr::printPrettyPragma(
  129. raw_ostream &OS, const PrintingPolicy &Policy) const {
  130. // Use fake syntax because it is for testing and debugging purpose only.
  131. if (getDevType() != DT_Any)
  132. OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")";
  133. if (getMapType() != MT_To && getMapType() != MT_Enter)
  134. OS << ' ' << ConvertMapTypeTyToStr(getMapType());
  135. if (Expr *E = getIndirectExpr()) {
  136. OS << " indirect(";
  137. E->printPretty(OS, nullptr, Policy);
  138. OS << ")";
  139. } else if (getIndirect()) {
  140. OS << " indirect";
  141. }
  142. }
  143. std::optional<OMPDeclareTargetDeclAttr *>
  144. OMPDeclareTargetDeclAttr::getActiveAttr(const ValueDecl *VD) {
  145. if (!VD->hasAttrs())
  146. return std::nullopt;
  147. unsigned Level = 0;
  148. OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
  149. for (auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
  150. if (Level <= Attr->getLevel()) {
  151. Level = Attr->getLevel();
  152. FoundAttr = Attr;
  153. }
  154. }
  155. if (FoundAttr)
  156. return FoundAttr;
  157. return std::nullopt;
  158. }
  159. std::optional<OMPDeclareTargetDeclAttr::MapTypeTy>
  160. OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) {
  161. std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
  162. if (ActiveAttr)
  163. return (*ActiveAttr)->getMapType();
  164. return std::nullopt;
  165. }
  166. std::optional<OMPDeclareTargetDeclAttr::DevTypeTy>
  167. OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) {
  168. std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
  169. if (ActiveAttr)
  170. return (*ActiveAttr)->getDevType();
  171. return std::nullopt;
  172. }
  173. std::optional<SourceLocation>
  174. OMPDeclareTargetDeclAttr::getLocation(const ValueDecl *VD) {
  175. std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
  176. if (ActiveAttr)
  177. return (*ActiveAttr)->getRange().getBegin();
  178. return std::nullopt;
  179. }
  180. namespace clang {
  181. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);
  182. llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
  183. }
  184. void OMPDeclareVariantAttr::printPrettyPragma(
  185. raw_ostream &OS, const PrintingPolicy &Policy) const {
  186. if (const Expr *E = getVariantFuncRef()) {
  187. OS << "(";
  188. E->printPretty(OS, nullptr, Policy);
  189. OS << ")";
  190. }
  191. OS << " match(" << traitInfos << ")";
  192. auto PrintExprs = [&OS, &Policy](Expr **Begin, Expr **End) {
  193. for (Expr **I = Begin; I != End; ++I) {
  194. assert(*I && "Expected non-null Stmt");
  195. if (I != Begin)
  196. OS << ",";
  197. (*I)->printPretty(OS, nullptr, Policy);
  198. }
  199. };
  200. if (adjustArgsNothing_size()) {
  201. OS << " adjust_args(nothing:";
  202. PrintExprs(adjustArgsNothing_begin(), adjustArgsNothing_end());
  203. OS << ")";
  204. }
  205. if (adjustArgsNeedDevicePtr_size()) {
  206. OS << " adjust_args(need_device_ptr:";
  207. PrintExprs(adjustArgsNeedDevicePtr_begin(), adjustArgsNeedDevicePtr_end());
  208. OS << ")";
  209. }
  210. auto PrintInteropInfo = [&OS](OMPInteropInfo *Begin, OMPInteropInfo *End) {
  211. for (OMPInteropInfo *I = Begin; I != End; ++I) {
  212. if (I != Begin)
  213. OS << ", ";
  214. OS << "interop(";
  215. OS << getInteropTypeString(I);
  216. OS << ")";
  217. }
  218. };
  219. if (appendArgs_size()) {
  220. OS << " append_args(";
  221. PrintInteropInfo(appendArgs_begin(), appendArgs_end());
  222. OS << ")";
  223. }
  224. }
  225. #include "clang/AST/AttrImpl.inc"