xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/AST/AttrImpl.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg //  This file contains out-of-line methods for Attr classes.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "clang/AST/ASTContext.h"
147330f729Sjoerg #include "clang/AST/Attr.h"
157330f729Sjoerg #include "clang/AST/Expr.h"
167330f729Sjoerg #include "clang/AST/Type.h"
177330f729Sjoerg using namespace clang;
187330f729Sjoerg 
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const19*e038c9c4Sjoerg void LoopHintAttr::printPrettyPragma(raw_ostream &OS,
20*e038c9c4Sjoerg                                      const PrintingPolicy &Policy) const {
21*e038c9c4Sjoerg   unsigned SpellingIndex = getAttributeSpellingListIndex();
22*e038c9c4Sjoerg   // For "#pragma unroll" and "#pragma nounroll" the string "unroll" or
23*e038c9c4Sjoerg   // "nounroll" is already emitted as the pragma name.
24*e038c9c4Sjoerg   if (SpellingIndex == Pragma_nounroll ||
25*e038c9c4Sjoerg       SpellingIndex == Pragma_nounroll_and_jam)
26*e038c9c4Sjoerg     return;
27*e038c9c4Sjoerg   else if (SpellingIndex == Pragma_unroll ||
28*e038c9c4Sjoerg            SpellingIndex == Pragma_unroll_and_jam) {
29*e038c9c4Sjoerg     OS << ' ' << getValueString(Policy);
30*e038c9c4Sjoerg     return;
31*e038c9c4Sjoerg   }
32*e038c9c4Sjoerg 
33*e038c9c4Sjoerg   assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
34*e038c9c4Sjoerg   OS << ' ' << getOptionName(option) << getValueString(Policy);
35*e038c9c4Sjoerg }
36*e038c9c4Sjoerg 
37*e038c9c4Sjoerg // Return a string containing the loop hint argument including the
38*e038c9c4Sjoerg // enclosing parentheses.
getValueString(const PrintingPolicy & Policy) const39*e038c9c4Sjoerg std::string LoopHintAttr::getValueString(const PrintingPolicy &Policy) const {
40*e038c9c4Sjoerg   std::string ValueName;
41*e038c9c4Sjoerg   llvm::raw_string_ostream OS(ValueName);
42*e038c9c4Sjoerg   OS << "(";
43*e038c9c4Sjoerg   if (state == Numeric)
44*e038c9c4Sjoerg     value->printPretty(OS, nullptr, Policy);
45*e038c9c4Sjoerg   else if (state == FixedWidth || state == ScalableWidth) {
46*e038c9c4Sjoerg     if (value) {
47*e038c9c4Sjoerg       value->printPretty(OS, nullptr, Policy);
48*e038c9c4Sjoerg       if (state == ScalableWidth)
49*e038c9c4Sjoerg         OS << ", scalable";
50*e038c9c4Sjoerg     } else if (state == ScalableWidth)
51*e038c9c4Sjoerg       OS << "scalable";
52*e038c9c4Sjoerg     else
53*e038c9c4Sjoerg       OS << "fixed";
54*e038c9c4Sjoerg   } else if (state == Enable)
55*e038c9c4Sjoerg     OS << "enable";
56*e038c9c4Sjoerg   else if (state == Full)
57*e038c9c4Sjoerg     OS << "full";
58*e038c9c4Sjoerg   else if (state == AssumeSafety)
59*e038c9c4Sjoerg     OS << "assume_safety";
60*e038c9c4Sjoerg   else
61*e038c9c4Sjoerg     OS << "disable";
62*e038c9c4Sjoerg   OS << ")";
63*e038c9c4Sjoerg   return OS.str();
64*e038c9c4Sjoerg }
65*e038c9c4Sjoerg 
66*e038c9c4Sjoerg // Return a string suitable for identifying this attribute in diagnostics.
67*e038c9c4Sjoerg std::string
getDiagnosticName(const PrintingPolicy & Policy) const68*e038c9c4Sjoerg LoopHintAttr::getDiagnosticName(const PrintingPolicy &Policy) const {
69*e038c9c4Sjoerg   unsigned SpellingIndex = getAttributeSpellingListIndex();
70*e038c9c4Sjoerg   if (SpellingIndex == Pragma_nounroll)
71*e038c9c4Sjoerg     return "#pragma nounroll";
72*e038c9c4Sjoerg   else if (SpellingIndex == Pragma_unroll)
73*e038c9c4Sjoerg     return "#pragma unroll" +
74*e038c9c4Sjoerg            (option == UnrollCount ? getValueString(Policy) : "");
75*e038c9c4Sjoerg   else if (SpellingIndex == Pragma_nounroll_and_jam)
76*e038c9c4Sjoerg     return "#pragma nounroll_and_jam";
77*e038c9c4Sjoerg   else if (SpellingIndex == Pragma_unroll_and_jam)
78*e038c9c4Sjoerg     return "#pragma unroll_and_jam" +
79*e038c9c4Sjoerg            (option == UnrollAndJamCount ? getValueString(Policy) : "");
80*e038c9c4Sjoerg 
81*e038c9c4Sjoerg   assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");
82*e038c9c4Sjoerg   return getOptionName(option) + getValueString(Policy);
83*e038c9c4Sjoerg }
84*e038c9c4Sjoerg 
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const85*e038c9c4Sjoerg void OMPDeclareSimdDeclAttr::printPrettyPragma(
86*e038c9c4Sjoerg     raw_ostream &OS, const PrintingPolicy &Policy) const {
87*e038c9c4Sjoerg   if (getBranchState() != BS_Undefined)
88*e038c9c4Sjoerg     OS << ' ' << ConvertBranchStateTyToStr(getBranchState());
89*e038c9c4Sjoerg   if (auto *E = getSimdlen()) {
90*e038c9c4Sjoerg     OS << " simdlen(";
91*e038c9c4Sjoerg     E->printPretty(OS, nullptr, Policy);
92*e038c9c4Sjoerg     OS << ")";
93*e038c9c4Sjoerg   }
94*e038c9c4Sjoerg   if (uniforms_size() > 0) {
95*e038c9c4Sjoerg     OS << " uniform";
96*e038c9c4Sjoerg     StringRef Sep = "(";
97*e038c9c4Sjoerg     for (auto *E : uniforms()) {
98*e038c9c4Sjoerg       OS << Sep;
99*e038c9c4Sjoerg       E->printPretty(OS, nullptr, Policy);
100*e038c9c4Sjoerg       Sep = ", ";
101*e038c9c4Sjoerg     }
102*e038c9c4Sjoerg     OS << ")";
103*e038c9c4Sjoerg   }
104*e038c9c4Sjoerg   alignments_iterator NI = alignments_begin();
105*e038c9c4Sjoerg   for (auto *E : aligneds()) {
106*e038c9c4Sjoerg     OS << " aligned(";
107*e038c9c4Sjoerg     E->printPretty(OS, nullptr, Policy);
108*e038c9c4Sjoerg     if (*NI) {
109*e038c9c4Sjoerg       OS << ": ";
110*e038c9c4Sjoerg       (*NI)->printPretty(OS, nullptr, Policy);
111*e038c9c4Sjoerg     }
112*e038c9c4Sjoerg     OS << ")";
113*e038c9c4Sjoerg     ++NI;
114*e038c9c4Sjoerg   }
115*e038c9c4Sjoerg   steps_iterator I = steps_begin();
116*e038c9c4Sjoerg   modifiers_iterator MI = modifiers_begin();
117*e038c9c4Sjoerg   for (auto *E : linears()) {
118*e038c9c4Sjoerg     OS << " linear(";
119*e038c9c4Sjoerg     if (*MI != OMPC_LINEAR_unknown)
120*e038c9c4Sjoerg       OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI)
121*e038c9c4Sjoerg          << "(";
122*e038c9c4Sjoerg     E->printPretty(OS, nullptr, Policy);
123*e038c9c4Sjoerg     if (*MI != OMPC_LINEAR_unknown)
124*e038c9c4Sjoerg       OS << ")";
125*e038c9c4Sjoerg     if (*I) {
126*e038c9c4Sjoerg       OS << ": ";
127*e038c9c4Sjoerg       (*I)->printPretty(OS, nullptr, Policy);
128*e038c9c4Sjoerg     }
129*e038c9c4Sjoerg     OS << ")";
130*e038c9c4Sjoerg     ++I;
131*e038c9c4Sjoerg     ++MI;
132*e038c9c4Sjoerg   }
133*e038c9c4Sjoerg }
134*e038c9c4Sjoerg 
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const135*e038c9c4Sjoerg void OMPDeclareTargetDeclAttr::printPrettyPragma(
136*e038c9c4Sjoerg     raw_ostream &OS, const PrintingPolicy &Policy) const {
137*e038c9c4Sjoerg   // Use fake syntax because it is for testing and debugging purpose only.
138*e038c9c4Sjoerg   if (getDevType() != DT_Any)
139*e038c9c4Sjoerg     OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")";
140*e038c9c4Sjoerg   if (getMapType() != MT_To)
141*e038c9c4Sjoerg     OS << ' ' << ConvertMapTypeTyToStr(getMapType());
142*e038c9c4Sjoerg }
143*e038c9c4Sjoerg 
144*e038c9c4Sjoerg llvm::Optional<OMPDeclareTargetDeclAttr *>
getActiveAttr(const ValueDecl * VD)145*e038c9c4Sjoerg OMPDeclareTargetDeclAttr::getActiveAttr(const ValueDecl *VD) {
146*e038c9c4Sjoerg   if (!VD->hasAttrs())
147*e038c9c4Sjoerg     return llvm::None;
148*e038c9c4Sjoerg   unsigned Level = 0;
149*e038c9c4Sjoerg   OMPDeclareTargetDeclAttr *FoundAttr = nullptr;
150*e038c9c4Sjoerg   for (auto *Attr : VD->specific_attrs<OMPDeclareTargetDeclAttr>()) {
151*e038c9c4Sjoerg     if (Level <= Attr->getLevel()) {
152*e038c9c4Sjoerg       Level = Attr->getLevel();
153*e038c9c4Sjoerg       FoundAttr = Attr;
154*e038c9c4Sjoerg     }
155*e038c9c4Sjoerg   }
156*e038c9c4Sjoerg   if (FoundAttr)
157*e038c9c4Sjoerg     return FoundAttr;
158*e038c9c4Sjoerg   return llvm::None;
159*e038c9c4Sjoerg }
160*e038c9c4Sjoerg 
161*e038c9c4Sjoerg llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy>
isDeclareTargetDeclaration(const ValueDecl * VD)162*e038c9c4Sjoerg OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) {
163*e038c9c4Sjoerg   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
164*e038c9c4Sjoerg   if (ActiveAttr.hasValue())
165*e038c9c4Sjoerg     return ActiveAttr.getValue()->getMapType();
166*e038c9c4Sjoerg   return llvm::None;
167*e038c9c4Sjoerg }
168*e038c9c4Sjoerg 
169*e038c9c4Sjoerg llvm::Optional<OMPDeclareTargetDeclAttr::DevTypeTy>
getDeviceType(const ValueDecl * VD)170*e038c9c4Sjoerg OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) {
171*e038c9c4Sjoerg   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
172*e038c9c4Sjoerg   if (ActiveAttr.hasValue())
173*e038c9c4Sjoerg     return ActiveAttr.getValue()->getDevType();
174*e038c9c4Sjoerg   return llvm::None;
175*e038c9c4Sjoerg }
176*e038c9c4Sjoerg 
177*e038c9c4Sjoerg llvm::Optional<SourceLocation>
getLocation(const ValueDecl * VD)178*e038c9c4Sjoerg OMPDeclareTargetDeclAttr::getLocation(const ValueDecl *VD) {
179*e038c9c4Sjoerg   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
180*e038c9c4Sjoerg   if (ActiveAttr.hasValue())
181*e038c9c4Sjoerg     return ActiveAttr.getValue()->getRange().getBegin();
182*e038c9c4Sjoerg   return llvm::None;
183*e038c9c4Sjoerg }
184*e038c9c4Sjoerg 
185*e038c9c4Sjoerg namespace clang {
186*e038c9c4Sjoerg llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);
187*e038c9c4Sjoerg llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);
188*e038c9c4Sjoerg }
189*e038c9c4Sjoerg 
printPrettyPragma(raw_ostream & OS,const PrintingPolicy & Policy) const190*e038c9c4Sjoerg void OMPDeclareVariantAttr::printPrettyPragma(
191*e038c9c4Sjoerg     raw_ostream &OS, const PrintingPolicy &Policy) const {
192*e038c9c4Sjoerg   if (const Expr *E = getVariantFuncRef()) {
193*e038c9c4Sjoerg     OS << "(";
194*e038c9c4Sjoerg     E->printPretty(OS, nullptr, Policy);
195*e038c9c4Sjoerg     OS << ")";
196*e038c9c4Sjoerg   }
197*e038c9c4Sjoerg   OS << " match(" << traitInfos << ")";
198*e038c9c4Sjoerg }
199*e038c9c4Sjoerg 
2007330f729Sjoerg #include "clang/AST/AttrImpl.inc"
201