/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 | 51 | SpellingIndex == Pragma_nounroll_and_jam) |
26 | 1 | return; |
27 | 51 | else if (SpellingIndex == Pragma_unroll || |
28 | 49 | SpellingIndex == Pragma_unroll_and_jam) { |
29 | 2 | OS << ' ' << getValueString(Policy); |
30 | 2 | return; |
31 | 2 | } |
32 | | |
33 | 49 | assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling"); |
34 | 49 | 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 | 4 | } else if (state == ScalableWidth) |
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 OS.str(); |
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 | 6 | (option == UnrollCount ? getValueString(Policy) : ""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 | 41 | return getOptionName(option) + getValueString(Policy); |
83 | 41 | } |
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 | 80 | 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 | 52 | 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 | 230 | raw_ostream &OS, const PrintingPolicy &Policy) const { |
137 | | // Use fake syntax because it is for testing and debugging purpose only. |
138 | 230 | if (getDevType() != DT_Any) |
139 | 14 | OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")"; |
140 | 230 | if (getMapType() != MT_To) |
141 | 28 | OS << ' ' << ConvertMapTypeTyToStr(getMapType()); |
142 | 230 | } |
143 | | |
144 | | llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> |
145 | 544k | OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) { |
146 | 544k | if (!VD->hasAttrs()) |
147 | 483k | return llvm::None; |
148 | 60.9k | unsigned Level = 0; |
149 | 60.9k | const OMPDeclareTargetDeclAttr *FoundAttr = nullptr; |
150 | 12.5k | for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) { |
151 | 12.5k | if (Level < Attr->getLevel()) { |
152 | 12.5k | Level = Attr->getLevel(); |
153 | 12.5k | FoundAttr = Attr; |
154 | 12.5k | } |
155 | 12.5k | } |
156 | 60.9k | if (FoundAttr) |
157 | 12.4k | return FoundAttr->getMapType(); |
158 | | |
159 | 48.4k | return llvm::None; |
160 | 48.4k | } |
161 | | |
162 | | llvm::Optional<OMPDeclareTargetDeclAttr::DevTypeTy> |
163 | 360k | OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) { |
164 | 360k | if (!VD->hasAttrs()) |
165 | 287k | return llvm::None; |
166 | 73.1k | unsigned Level = 0; |
167 | 73.1k | const OMPDeclareTargetDeclAttr *FoundAttr = nullptr; |
168 | 9.56k | for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) { |
169 | 9.56k | if (Level < Attr->getLevel()) { |
170 | 9.56k | Level = Attr->getLevel(); |
171 | 9.56k | FoundAttr = Attr; |
172 | 9.56k | } |
173 | 9.56k | } |
174 | 73.1k | if (FoundAttr) |
175 | 9.56k | return FoundAttr->getDevType(); |
176 | | |
177 | 63.5k | return llvm::None; |
178 | 63.5k | } |
179 | | |
180 | | llvm::Optional<SourceLocation> |
181 | 381 | OMPDeclareTargetDeclAttr::getLocation(const ValueDecl *VD) { |
182 | 381 | if (!VD->hasAttrs()) |
183 | 297 | return llvm::None; |
184 | 84 | unsigned Level = 0; |
185 | 84 | const OMPDeclareTargetDeclAttr *FoundAttr = nullptr; |
186 | 84 | for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) { |
187 | 84 | if (Level < Attr->getLevel()) { |
188 | 84 | Level = Attr->getLevel(); |
189 | 84 | FoundAttr = Attr; |
190 | 84 | } |
191 | 84 | } |
192 | 84 | if (FoundAttr) |
193 | 84 | return FoundAttr->getRange().getBegin(); |
194 | | |
195 | 0 | return llvm::None; |
196 | 0 | } |
197 | | |
198 | | namespace clang { |
199 | | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI); |
200 | | llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI); |
201 | | } |
202 | | |
203 | | void OMPDeclareVariantAttr::printPrettyPragma( |
204 | 80 | raw_ostream &OS, const PrintingPolicy &Policy) const { |
205 | 80 | if (const Expr *E = getVariantFuncRef()) { |
206 | 80 | OS << "("; |
207 | 80 | E->printPretty(OS, nullptr, Policy); |
208 | 80 | OS << ")"; |
209 | 80 | } |
210 | 80 | OS << " match(" << traitInfos << ")"; |
211 | 80 | } |
212 | | |
213 | | #include "clang/AST/AttrImpl.inc" |