AttrImpl.cpp 7.4 KB

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