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