1 //===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains out-of-line methods for Attr classes.
11 //===----------------------------------------------------------------------===//
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
;
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
)
27 else if (SpellingIndex
== Pragma_unroll
||
28 SpellingIndex
== Pragma_unroll_and_jam
) {
29 OS
<< ' ' << getValueString(Policy
);
33 assert(SpellingIndex
== Pragma_clang_loop
&& "Unexpected spelling");
34 OS
<< ' ' << getOptionName(option
) << getValueString(Policy
);
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
);
44 value
->printPretty(OS
, nullptr, Policy
);
45 else if (state
== FixedWidth
|| state
== ScalableWidth
) {
47 value
->printPretty(OS
, nullptr, Policy
);
48 if (state
== ScalableWidth
)
50 } else if (state
== ScalableWidth
)
54 } else if (state
== Enable
)
56 else if (state
== Full
)
58 else if (state
== AssumeSafety
)
59 OS
<< "assume_safety";
66 // Return a string suitable for identifying this attribute in diagnostics.
68 LoopHintAttr::getDiagnosticName(const PrintingPolicy
&Policy
) const {
69 unsigned SpellingIndex
= getAttributeSpellingListIndex();
70 if (SpellingIndex
== Pragma_nounroll
)
71 return "#pragma nounroll";
72 else if (SpellingIndex
== Pragma_unroll
)
73 return "#pragma unroll" +
74 (option
== UnrollCount
? getValueString(Policy
) : "");
75 else if (SpellingIndex
== Pragma_nounroll_and_jam
)
76 return "#pragma nounroll_and_jam";
77 else if (SpellingIndex
== Pragma_unroll_and_jam
)
78 return "#pragma unroll_and_jam" +
79 (option
== UnrollAndJamCount
? getValueString(Policy
) : "");
81 assert(SpellingIndex
== Pragma_clang_loop
&& "Unexpected spelling");
82 return getOptionName(option
) + getValueString(Policy
);
85 void OMPDeclareSimdDeclAttr::printPrettyPragma(
86 raw_ostream
&OS
, const PrintingPolicy
&Policy
) const {
87 if (getBranchState() != BS_Undefined
)
88 OS
<< ' ' << ConvertBranchStateTyToStr(getBranchState());
89 if (auto *E
= getSimdlen()) {
91 E
->printPretty(OS
, nullptr, Policy
);
94 if (uniforms_size() > 0) {
97 for (auto *E
: uniforms()) {
99 E
->printPretty(OS
, nullptr, Policy
);
104 alignments_iterator NI
= alignments_begin();
105 for (auto *E
: aligneds()) {
107 E
->printPretty(OS
, nullptr, Policy
);
110 (*NI
)->printPretty(OS
, nullptr, Policy
);
115 steps_iterator I
= steps_begin();
116 modifiers_iterator MI
= modifiers_begin();
117 for (auto *E
: linears()) {
119 if (*MI
!= OMPC_LINEAR_unknown
)
120 OS
<< getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear
, *MI
)
122 E
->printPretty(OS
, nullptr, Policy
);
123 if (*MI
!= OMPC_LINEAR_unknown
)
127 (*I
)->printPretty(OS
, nullptr, Policy
);
135 void OMPDeclareTargetDeclAttr::printPrettyPragma(
136 raw_ostream
&OS
, const PrintingPolicy
&Policy
) const {
137 // Use fake syntax because it is for testing and debugging purpose only.
138 if (getDevType() != DT_Any
)
139 OS
<< " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")";
140 if (getMapType() != MT_To
)
141 OS
<< ' ' << ConvertMapTypeTyToStr(getMapType());
142 if (Expr
*E
= getIndirectExpr()) {
144 E
->printPretty(OS
, nullptr, Policy
);
146 } else if (getIndirect()) {
151 llvm::Optional
<OMPDeclareTargetDeclAttr
*>
152 OMPDeclareTargetDeclAttr::getActiveAttr(const ValueDecl
*VD
) {
156 OMPDeclareTargetDeclAttr
*FoundAttr
= nullptr;
157 for (auto *Attr
: VD
->specific_attrs
<OMPDeclareTargetDeclAttr
>()) {
158 if (Level
<= Attr
->getLevel()) {
159 Level
= Attr
->getLevel();
168 llvm::Optional
<OMPDeclareTargetDeclAttr::MapTypeTy
>
169 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl
*VD
) {
170 llvm::Optional
<OMPDeclareTargetDeclAttr
*> ActiveAttr
= getActiveAttr(VD
);
172 return ActiveAttr
.value()->getMapType();
176 llvm::Optional
<OMPDeclareTargetDeclAttr::DevTypeTy
>
177 OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl
*VD
) {
178 llvm::Optional
<OMPDeclareTargetDeclAttr
*> ActiveAttr
= getActiveAttr(VD
);
180 return ActiveAttr
.value()->getDevType();
184 llvm::Optional
<SourceLocation
>
185 OMPDeclareTargetDeclAttr::getLocation(const ValueDecl
*VD
) {
186 llvm::Optional
<OMPDeclareTargetDeclAttr
*> ActiveAttr
= getActiveAttr(VD
);
188 return ActiveAttr
.value()->getRange().getBegin();
193 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, const OMPTraitInfo
&TI
);
194 llvm::raw_ostream
&operator<<(llvm::raw_ostream
&OS
, const OMPTraitInfo
*TI
);
197 void OMPDeclareVariantAttr::printPrettyPragma(
198 raw_ostream
&OS
, const PrintingPolicy
&Policy
) const {
199 if (const Expr
*E
= getVariantFuncRef()) {
201 E
->printPretty(OS
, nullptr, Policy
);
204 OS
<< " match(" << traitInfos
<< ")";
206 auto PrintExprs
= [&OS
, &Policy
](Expr
**Begin
, Expr
**End
) {
207 for (Expr
**I
= Begin
; I
!= End
; ++I
) {
208 assert(*I
&& "Expected non-null Stmt");
211 (*I
)->printPretty(OS
, nullptr, Policy
);
214 if (adjustArgsNothing_size()) {
215 OS
<< " adjust_args(nothing:";
216 PrintExprs(adjustArgsNothing_begin(), adjustArgsNothing_end());
219 if (adjustArgsNeedDevicePtr_size()) {
220 OS
<< " adjust_args(need_device_ptr:";
221 PrintExprs(adjustArgsNeedDevicePtr_begin(), adjustArgsNeedDevicePtr_end());
225 auto PrintInteropInfo
= [&OS
](OMPInteropInfo
*Begin
, OMPInteropInfo
*End
) {
226 for (OMPInteropInfo
*I
= Begin
; I
!= End
; ++I
) {
230 OS
<< getInteropTypeString(I
);
234 if (appendArgs_size()) {
235 OS
<< " append_args(";
236 PrintInteropInfo(appendArgs_begin(), appendArgs_end());
241 #include "clang/AST/AttrImpl.inc"