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
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const19 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.
getValueString(const PrintingPolicy & Policy) const39 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
getDiagnosticName(const PrintingPolicy & Policy) const59 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
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const76 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)
111 OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI)
112 << "(";
113 E->printPretty(OS, nullptr, Policy);
114 if (*MI != OMPC_LINEAR_unknown)
115 OS << ")";
116 if (*I) {
117 OS << ": ";
118 (*I)->printPretty(OS, nullptr, Policy);
119 }
120 OS << ")";
121 ++I;
122 ++MI;
123 }
124 }
125
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const126 void OMPDeclareTargetDeclAttr::printPrettyPragma(
127 raw_ostream &OS, const PrintingPolicy &Policy) const {
128 // Use fake syntax because it is for testing and debugging purpose only.
129 if (getDevType() != DT_Any)
130 OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")";
131 if (getMapType() != MT_To)
132 OS << ' ' << ConvertMapTypeTyToStr(getMapType());
133 }
134
135 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy>
isDeclareTargetDeclaration(const ValueDecl * VD)136 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) {
137 if (!VD->hasAttrs())
138 return llvm::None;
139 unsigned Level = 0;
140 const OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
141 for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
142 if (Level < Attr->getLevel()) {
143 Level = Attr->getLevel();
144 FoundAttr = Attr;
145 }
146 }
147 if (FoundAttr)
148 return FoundAttr->getMapType();
149
150 return llvm::None;
151 }
152
153 llvm::Optional<OMPDeclareTargetDeclAttr::DevTypeTy>
getDeviceType(const ValueDecl * VD)154 OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) {
155 if (!VD->hasAttrs())
156 return llvm::None;
157 unsigned Level = 0;
158 const OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
159 for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
160 if (Level < Attr->getLevel()) {
161 Level = Attr->getLevel();
162 FoundAttr = Attr;
163 }
164 }
165 if (FoundAttr)
166 return FoundAttr->getDevType();
167
168 return llvm::None;
169 }
170
171 llvm::Optional<SourceLocation>
getLocation(const ValueDecl * VD)172 OMPDeclareTargetDeclAttr::getLocation(const ValueDecl *VD) {
173 if (!VD->hasAttrs())
174 return llvm::None;
175 unsigned Level = 0;
176 const OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
177 for (const auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
178 if (Level < Attr->getLevel()) {
179 Level = Attr->getLevel();
180 FoundAttr = Attr;
181 }
182 }
183 if (FoundAttr)
184 return FoundAttr->getRange().getBegin();
185
186 return llvm::None;
187 }
188
189 namespace clang {
190 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);
191 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
192 }
193
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const194 void OMPDeclareVariantAttr::printPrettyPragma(
195 raw_ostream &OS, const PrintingPolicy &Policy) const {
196 if (const Expr *E = getVariantFuncRef()) {
197 OS << "(";
198 E->printPretty(OS, nullptr, Policy);
199 OS << ")";
200 }
201 OS << " match(" << traitInfos << ")";
202 }
203
204 #include "clang/AST/AttrImpl.inc"
205