| Anton Korobeynikov | 3d364fd | 2010-01-10 14:38:13 +0000 | [diff] [blame] | 1 | //===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===// |
| 2 | // |
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 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 |
| Anton Korobeynikov | 3d364fd | 2010-01-10 14:38:13 +0000 | [diff] [blame] | 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | // |
| Benjamin Kramer | 845e32c | 2015-03-19 16:06:49 +0000 | [diff] [blame] | 9 | // This file contains out-of-line methods for Attr classes. |
| Anton Korobeynikov | 3d364fd | 2010-01-10 14:38:13 +0000 | [diff] [blame] | 10 | // |
| 11 | //===----------------------------------------------------------------------===// |
| 12 | |
| Anton Korobeynikov | 3d364fd | 2010-01-10 14:38:13 +0000 | [diff] [blame] | 13 | #include "clang/AST/ASTContext.h" |
| Mehdi Amini | 9670f84 | 2016-07-18 19:02:11 +0000 | [diff] [blame] | 14 | #include "clang/AST/Attr.h" |
| Alexis Hunt | dcfba7b | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 15 | #include "clang/AST/Expr.h" |
| Chandler Carruth | 3a02247 | 2012-12-04 09:13:33 +0000 | [diff] [blame] | 16 | #include "clang/AST/Type.h" |
| Anton Korobeynikov | 3d364fd | 2010-01-10 14:38:13 +0000 | [diff] [blame] | 17 | using namespace clang; |
| 18 | |
| Reid Kleckner | 26d254f | 2020-03-11 20:22:14 -0700 | [diff] [blame] | 19 | void LoopHintAttr::printPrettyPragma(raw_ostream &OS, |
| 20 | const PrintingPolicy &Policy) const { |
| 21 | unsigned SpellingIndex = getAttributeSpellingListIndex(); |
| 22 | // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or |
| 23 | // "nounroll" is already emitted as the pragma name. |
| 24 | if (SpellingIndex == Pragma_nounroll || |
| 25 | SpellingIndex == Pragma_nounroll_and_jam) |
| 26 | return; |
| 27 | else if (SpellingIndex == Pragma_unroll || |
| 28 | SpellingIndex == Pragma_unroll_and_jam) { |
| 29 | OS << ' ' << getValueString(Policy); |
| 30 | return; |
| 31 | } |
| 32 | |
| 33 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); |
| 34 | OS << ' ' << getOptionName(option) << getValueString(Policy); |
| 35 | } |
| 36 | |
| 37 | // Return a string containing the loop hint argument including the |
| 38 | // enclosing parentheses. |
| 39 | std::string LoopHintAttr::getValueString(const PrintingPolicy &Policy) const { |
| 40 | std::string ValueName; |
| 41 | llvm::raw_string_ostream OS(ValueName); |
| 42 | OS << "("; |
| 43 | if (state == Numeric) |
| 44 | value->printPretty(OS, nullptr, Policy); |
| 45 | else if (state == Enable) |
| 46 | OS << "enable"; |
| 47 | else if (state == Full) |
| 48 | OS << "full"; |
| 49 | else if (state == AssumeSafety) |
| 50 | OS << "assume_safety"; |
| 51 | else |
| 52 | OS << "disable"; |
| 53 | OS << ")"; |
| 54 | return OS.str(); |
| 55 | } |
| 56 | |
| 57 | // Return a string suitable for identifying this attribute in diagnostics. |
| 58 | std::string |
| 59 | LoopHintAttr::getDiagnosticName(const PrintingPolicy &Policy) const { |
| 60 | unsigned SpellingIndex = getAttributeSpellingListIndex(); |
| 61 | if (SpellingIndex == Pragma_nounroll) |
| 62 | return "#pragma nounroll"; |
| 63 | else if (SpellingIndex == Pragma_unroll) |
| 64 | return "#pragma unroll" + |
| 65 | (option == UnrollCount ? getValueString(Policy) : ""); |
| 66 | else if (SpellingIndex == Pragma_nounroll_and_jam) |
| 67 | return "#pragma nounroll_and_jam"; |
| 68 | else if (SpellingIndex == Pragma_unroll_and_jam) |
| 69 | return "#pragma unroll_and_jam" + |
| 70 | (option == UnrollAndJamCount ? getValueString(Policy) : ""); |
| 71 | |
| 72 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); |
| 73 | return getOptionName(option) + getValueString(Policy); |
| 74 | } |
| 75 | |
| 76 | void OMPDeclareSimdDeclAttr::printPrettyPragma( |
| 77 | raw_ostream &OS, const PrintingPolicy &Policy) const { |
| 78 | if (getBranchState() != BS_Undefined) |
| 79 | OS << ' ' << ConvertBranchStateTyToStr(getBranchState()); |
| 80 | if (auto *E = getSimdlen()) { |
| 81 | OS << " simdlen("; |
| 82 | E->printPretty(OS, nullptr, Policy); |
| 83 | OS << ")"; |
| 84 | } |
| 85 | if (uniforms_size() > 0) { |
| 86 | OS << " uniform"; |
| 87 | StringRef Sep = "("; |
| 88 | for (auto *E : uniforms()) { |
| 89 | OS << Sep; |
| 90 | E->printPretty(OS, nullptr, Policy); |
| 91 | Sep = ", "; |
| 92 | } |
| 93 | OS << ")"; |
| 94 | } |
| 95 | alignments_iterator NI = alignments_begin(); |
| 96 | for (auto *E : aligneds()) { |
| 97 | OS << " aligned("; |
| 98 | E->printPretty(OS, nullptr, Policy); |
| 99 | if (*NI) { |
| 100 | OS << ": "; |
| 101 | (*NI)->printPretty(OS, nullptr, Policy); |
| 102 | } |
| 103 | OS << ")"; |
| 104 | ++NI; |
| 105 | } |
| 106 | steps_iterator I = steps_begin(); |
| 107 | modifiers_iterator MI = modifiers_begin(); |
| 108 | for (auto *E : linears()) { |
| 109 | OS << " linear("; |
| 110 | if (*MI != OMPC_LINEAR_unknown) |
| Johannes Doerfert | 1858f4b | 2020-04-02 02:23:22 -0500 | [diff] [blame^] | 111 | OS << getOpenMPSimpleClauseTypeName(OMPC_linear, *MI) << "("; |
| Reid Kleckner | 26d254f | 2020-03-11 20:22:14 -0700 | [diff] [blame] | 112 | E->printPretty(OS, nullptr, Policy); |
| 113 | if (*MI != OMPC_LINEAR_unknown) |
| 114 | OS << ")"; |
| 115 | if (*I) { |
| 116 | OS << ": "; |
| 117 | (*I)->printPretty(OS, nullptr, Policy); |
| 118 | } |
| 119 | OS << ")"; |
| 120 | ++I; |
| 121 | ++MI; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | void OMPDeclareTargetDeclAttr::printPrettyPragma( |
| 126 | raw_ostream &OS, const PrintingPolicy &Policy) const { |
| 127 | // Use fake syntax because it is for testing and debugging purpose only. |
| 128 | if (getDevType() != DT_Any) |
| 129 | OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")"; |
| 130 | if (getMapType() != MT_To) |
| 131 | OS << ' ' << ConvertMapTypeTyToStr(getMapType()); |
| 132 | } |
| 133 | |
| 134 | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> |
| 135 | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) { |
| 136 | if (!VD->hasAttrs()) |
| 137 | return llvm::None; |
| 138 | if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) |
| 139 | return Attr->getMapType(); |
| 140 | |
| 141 | return llvm::None; |
| 142 | } |
| 143 | |
| 144 | llvm::Optional<OMPDeclareTargetDeclAttr::DevTypeTy> |
| 145 | OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) { |
| 146 | if (!VD->hasAttrs()) |
| 147 | return llvm::None; |
| 148 | if (const auto *Attr = VD->getAttr<OMPDeclareTargetDeclAttr>()) |
| 149 | return Attr->getDevType(); |
| 150 | |
| 151 | return llvm::None; |
| 152 | } |
| 153 | |
| 154 | void OMPDeclareVariantAttr::printPrettyPragma( |
| 155 | raw_ostream &OS, const PrintingPolicy &Policy) const { |
| 156 | if (const Expr *E = getVariantFuncRef()) { |
| 157 | OS << "("; |
| 158 | E->printPretty(OS, nullptr, Policy); |
| 159 | OS << ")"; |
| 160 | } |
| 161 | OS << " match("; |
| Johannes Doerfert | 55eca28 | 2020-03-13 23:42:05 -0500 | [diff] [blame] | 162 | traitInfos->print(OS, Policy); |
| Reid Kleckner | 26d254f | 2020-03-11 20:22:14 -0700 | [diff] [blame] | 163 | OS << ")"; |
| 164 | } |
| 165 | |
| Alexis Hunt | dcfba7b | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 166 | #include "clang/AST/AttrImpl.inc" |