23void LoopHintAttr::printPrettyPragma(raw_ostream &OS,
25 unsigned SpellingIndex = getAttributeSpellingListIndex();
28 if (SpellingIndex == Pragma_nounroll ||
29 SpellingIndex == Pragma_nounroll_and_jam)
31 else if (SpellingIndex == Pragma_unroll ||
32 SpellingIndex == Pragma_unroll_and_jam) {
33 OS <<
' ' << getValueString(Policy);
37 assert(SpellingIndex == Pragma_clang_loop &&
"Unexpected spelling");
43std::string LoopHintAttr::getValueString(
const PrintingPolicy &Policy)
const {
44 std::string ValueName;
45 llvm::raw_string_ostream
OS(ValueName);
48 value->printPretty(OS,
nullptr, Policy);
49 else if (state == FixedWidth || state == ScalableWidth) {
51 value->printPretty(OS,
nullptr, Policy);
52 if (state == ScalableWidth)
54 }
else if (state == ScalableWidth)
58 }
else if (state == Enable)
60 else if (state ==
Full)
62 else if (state == AssumeSafety)
63 OS <<
"assume_safety";
72LoopHintAttr::getDiagnosticName(
const PrintingPolicy &Policy)
const {
73 unsigned SpellingIndex = getAttributeSpellingListIndex();
74 if (SpellingIndex == Pragma_nounroll)
75 return "#pragma nounroll";
76 else if (SpellingIndex == Pragma_unroll)
77 return "#pragma unroll" +
78 (option == UnrollCount ? getValueString(Policy) :
"");
79 else if (SpellingIndex == Pragma_nounroll_and_jam)
80 return "#pragma nounroll_and_jam";
81 else if (SpellingIndex == Pragma_unroll_and_jam)
82 return "#pragma unroll_and_jam" +
83 (option == UnrollAndJamCount ? getValueString(Policy) :
"");
85 assert(SpellingIndex == Pragma_clang_loop &&
"Unexpected spelling");
89void OMPDeclareSimdDeclAttr::printPrettyPragma(
91 if (getBranchState() != BS_Undefined)
92 OS <<
' ' << ConvertBranchStateTyToStr(getBranchState());
93 if (
auto *E = getSimdlen()) {
95 E->printPretty(OS,
nullptr, Policy);
98 if (uniforms_size() > 0) {
101 for (
auto *E : uniforms()) {
103 E->printPretty(OS,
nullptr, Policy);
108 alignments_iterator NI = alignments_begin();
109 for (
auto *E : aligneds()) {
111 E->printPretty(OS,
nullptr, Policy);
114 (*NI)->printPretty(OS,
nullptr, Policy);
119 steps_iterator I = steps_begin();
120 modifiers_iterator MI = modifiers_begin();
121 for (
auto *E : linears()) {
126 E->printPretty(OS,
nullptr, Policy);
131 (*I)->printPretty(OS,
nullptr, Policy);
139void OMPDeclareTargetDeclAttr::printPrettyPragma(
142 if (getDevType() != DT_Any)
143 OS <<
" device_type(" << ConvertDevTypeTyToStr(getDevType()) <<
")";
144 if (getMapType() != MT_To && getMapType() != MT_Enter)
145 OS <<
' ' << ConvertMapTypeTyToStr(getMapType());
146 if (
Expr *E = getIndirectExpr()) {
148 E->printPretty(OS,
nullptr, Policy);
150 }
else if (getIndirect()) {
155std::optional<OMPDeclareTargetDeclAttr *>
156OMPDeclareTargetDeclAttr::getActiveAttr(
const ValueDecl *VD) {
157 if (llvm::all_of(VD->
redecls(), [](
const Decl *D) { return !D->hasAttrs(); }))
160 OMPDeclareTargetDeclAttr *FoundAttr =
nullptr;
164 Level =
Attr->getLevel();
174std::optional<OMPDeclareTargetDeclAttr::MapTypeTy>
175OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
const ValueDecl *VD) {
176 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
178 return (*ActiveAttr)->getMapType();
182std::optional<OMPDeclareTargetDeclAttr::DevTypeTy>
183OMPDeclareTargetDeclAttr::getDeviceType(
const ValueDecl *VD) {
184 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
186 return (*ActiveAttr)->getDevType();
190std::optional<SourceLocation>
191OMPDeclareTargetDeclAttr::getLocation(
const ValueDecl *VD) {
192 std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);
194 return (*ActiveAttr)->getRange().getBegin();
199llvm::raw_ostream &
operator<<(llvm::raw_ostream &OS,
const OMPTraitInfo &TI);
200llvm::raw_ostream &
operator<<(llvm::raw_ostream &OS,
const OMPTraitInfo *TI);
203void OMPDeclareVariantAttr::printPrettyPragma(
205 if (
const Expr *E = getVariantFuncRef()) {
207 E->printPretty(OS,
nullptr, Policy);
210 OS <<
" match(" << traitInfos <<
")";
216 OS <<
"omp_num_args";
218 OS << (Bound.IsSubtraction ?
"-" :
"+");
221 Bound.E->printPretty(OS,
nullptr, Policy);
225 assert(Item.E &&
"expected adjust_args expression");
226 Item.E->printPretty(OS,
nullptr, Policy);
229 PrintBound(Item.Lower);
231 PrintBound(Item.Upper);
234 OS <<
" adjust_args("
237 if (Desc->AdjustOp == OMPC_ADJUST_ARGS_need_device_ptr &&
240 switch (Desc->NeedDevicePtrModifier) {
241 case OMPC_NEED_DEVICE_PTR_fb_nullify:
244 case OMPC_NEED_DEVICE_PTR_fb_preserve:
248 llvm_unreachable(
"unexpected need_device_ptr modifier");
257 llvm::interleave(Items, PrintItem, [&OS] {
OS <<
","; });
267 if (!I->Prefs.empty()) {
268 OS <<
"prefer_type(";
269 if (I->HasPreferAttrs) {
271 for (
const auto &P : I->Prefs) {
275 P.Fr->printPretty(OS,
nullptr, Policy);
278 bool NeedSep = P.Fr !=
nullptr;
279 for (
Expr *A : P.Attrs) {
292 for (
const auto &P : I->Prefs) {
295 P.Fr->printPretty(OS,
nullptr, Policy);
301 OS << getInteropTypeString(I);
305 if (appendArgs_size()) {
306 OS <<
" append_args(";
307 PrintInteropInfo(appendArgs_begin(), appendArgs_end());
312unsigned AlignedAttr::getAlignment(
ASTContext &Ctx)
const {
313 assert(!isAlignmentDependent());
314 if (getCachedAlignmentValue())
315 return *getCachedAlignmentValue();
318 if (!isAlignmentExpr()) {
319 QualType T = getAlignmentType()->getType();
324 T =
T.getNonReferenceType();
326 if (
T.getQualifiers().hasUnaligned())
335 return alignmentExpr->EvaluateKnownConstInt(Ctx).getZExtValue() *
352#define USE_DEFAULT_EQUALITY \
353 (std::is_same_v<T, StringRef> || std::is_same_v<T, VersionTuple> || \
354 std::is_same_v<T, IdentifierInfo *> || std::is_same_v<T, char *> || \
355 std::is_enum_v<T> || std::is_integral_v<T>)
358typename std::enable_if_t<!USE_DEFAULT_EQUALITY, bool>
364typename std::enable_if_t<USE_DEFAULT_EQUALITY, bool>
384bool equalAttrArgs(
T *A1_B,
T *A1_E,
T *A2_B,
T *A2_E,
386 if (A1_E - A1_B != A2_E - A2_B)
389 for (; A1_B != A1_E; ++A1_B, ++A2_B)
390 if (!equalAttrArgs(*A1_B, *A2_B, Context))
397bool equalAttrArgs<Attr *>(
Attr *A1,
Attr *A2,
405bool equalAttrArgs<Expr *>(
Expr *A1,
Expr *A2,
410static bool equalOMPAdjustArgsExprs(
Expr *A,
Expr *B,
414 return equalAttrArgs(A, B, Context);
421 equalOMPAdjustArgsExprs(A.
E, B.
E, Context);
427 return A.
Kind == B.
Kind && equalOMPAdjustArgsExprs(A.
E, B.
E, Context) &&
428 equalOMPAdjustArgsBounds(A.
Lower, B.
Lower, Context) &&
429 equalOMPAdjustArgsBounds(A.
Upper, B.
Upper, Context);
433bool equalAttrArgs<OMPAdjustArgsDescriptor *>(
440 for (
unsigned I : llvm::seq<unsigned>(A->
items().size()))
441 if (!equalOMPAdjustArgsItems(A->
items()[I], B->
items()[I], Context))
453bool equalAttrArgs<const IdentifierInfo *>(
459bool areAlignedAttrsEqual(
const AlignedAttr &A1,
const AlignedAttr &A2,
461 if (A1.getSpelling() != A2.getSpelling())
464 if (A1.isAlignmentExpr() != A2.isAlignmentExpr())
467 if (A1.isAlignmentExpr())
468 return equalAttrArgs(A1.getAlignmentExpr(), A2.getAlignmentExpr(), Context);
470 return equalAttrArgs(A1.getAlignmentType()->getType(),
471 A2.getAlignmentType()->getType(), Context);
482#define USE_DEFAULT_PROFILE \
483 (std::is_same_v<T, StringRef> || std::is_same_v<T, VersionTuple> || \
484 std::is_same_v<T, IdentifierInfo *> || \
485 std::is_same_v<T, const IdentifierInfo *> || std::is_enum_v<T> || \
486 std::is_integral_v<T>)
489typename std::enable_if_t<!USE_DEFAULT_PROFILE>
490profileAttrArg(llvm::FoldingSetNodeID &,
const ASTContext &,
T) {
491 llvm_unreachable(
"profile not implemented for this type");
495typename std::enable_if_t<USE_DEFAULT_PROFILE>
496profileAttrArg(llvm::FoldingSetNodeID &ID,
const ASTContext &,
T V) {
497 if constexpr (std::is_same_v<T, StringRef>)
499 else if constexpr (std::is_same_v<T, VersionTuple>) {
500 ID.AddInteger(
V.getMajor());
501 ID.AddInteger(
V.getMinor().value_or(0));
502 ID.AddInteger(
V.getSubminor().value_or(0));
503 ID.AddInteger(
V.getBuild().value_or(0));
504 }
else if constexpr (std::is_same_v<T, IdentifierInfo *> ||
505 std::is_same_v<T, const IdentifierInfo *>)
508 ID.AddInteger(
static_cast<long long>(
V));
512inline void profileAttrArg<ParamIdx>(llvm::FoldingSetNodeID &ID,
520inline void profileAttrArg(llvm::FoldingSetNodeID &ID,
const ASTContext &Ctx,
522 ID.AddInteger(End - Begin);
523 for (; Begin != End; ++Begin)
524 profileAttrArg(ID, Ctx, *Begin);
528inline void profileAttrArg<Attr *>(llvm::FoldingSetNodeID &ID,
531 ID.AddPointer(
nullptr);
539inline void profileAttrArg<Expr *>(llvm::FoldingSetNodeID &ID,
544static void profileOMPAdjustArgsExpr(llvm::FoldingSetNodeID &ID,
546 ID.AddBoolean(E !=
nullptr);
548 profileAttrArg(ID, Ctx, E);
551static void profileOMPAdjustArgsBound(llvm::FoldingSetNodeID &ID,
554 ID.AddInteger(Bound.
Kind);
556 profileOMPAdjustArgsExpr(ID, Ctx, Bound.
E);
559static void profileOMPAdjustArgsItem(llvm::FoldingSetNodeID &ID,
562 ID.AddInteger(Item.
Kind);
563 profileOMPAdjustArgsExpr(ID, Ctx, Item.
E);
564 profileOMPAdjustArgsBound(ID, Ctx, Item.
Lower);
565 profileOMPAdjustArgsBound(ID, Ctx, Item.
Upper);
570profileAttrArg<OMPAdjustArgsDescriptor *>(llvm::FoldingSetNodeID &ID,
575 ID.AddInteger(Desc->
items().size());
577 profileOMPAdjustArgsItem(ID, Ctx, Item);
581inline void profileAttrArg<QualType>(llvm::FoldingSetNodeID &ID,
583 ID.AddPointer(
T.getCanonicalType().getAsOpaquePtr());
586void profileAlignedAttr(
const AlignedAttr &A, llvm::FoldingSetNodeID &ID,
588 ID.AddInteger(A.getSpellingListIndex());
589 ID.AddBoolean(A.isAlignmentExpr());
590 if (A.isAlignmentExpr())
591 profileAttrArg(ID, Ctx, A.getAlignmentExpr());
593 profileAttrArg(ID, Ctx, A.getAlignmentType()->getType());
597#include "clang/AST/AttrImpl.inc"
Defines the clang::ASTContext interface.
static StringRef getOptionName(StringRef Option, const char Delimiter='=')
This file defines OpenMP AST classes for clauses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getTargetDefaultAlignForAttributeAligned() const
Return the default alignment for attribute((aligned)) on this target, to be used if no alignment valu...
uint64_t getCharWidth() const
Return the size of the character type, in bits.
Attr - This represents one attribute.
bool isEquivalent(const Attr &Other, StructuralEquivalenceContext &Context) const
attr::Kind getKind() const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Ctx) const
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
Decl - This represents one declaration (or definition), e.g.
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
This represents one expression.
One of these records is kept for each identifier that is lexed.
Describes the source-level contents of one OpenMP 'adjust_args' clause.
ArrayRef< OMPAdjustArgsItem > items() const
OpenMPNeedDevicePtrModifier NeedDevicePtrModifier
OpenMPAdjustArgsOpKind AdjustOp
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
bool isValid() const
Is this parameter index valid?
unsigned getASTIndex() const
Get the parameter index as it would normally be encoded at the AST level of representation: zero-orig...
A (possibly-)qualified type.
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical, bool ProfileLambdaExpr=false) const
Produce a unique representation of the given statement.
StringLiteral - This represents a string literal expression, e.g.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isEquivalent(StructuralEquivalenceContext &Context, QualType T1, QualType T2)
Determine structural equivalence of two types.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
Top level wrappers for InstallAPI frontend operations.
@ OMPC_NEED_DEVICE_PTR_unknown
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
const FunctionProtoType * T
@ Full
Match, but we didn't check for full match.
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
U cast(CodeGen::Address addr)
One bound of a parameter range.
Expr * E
The bound expression, or the logical offset for a NumArgs bound.
One item in an OpenMP 'adjust_args' parameter list.
Expr * E
A named parameter or positional expression for a Single item.
Describes how types, statements, expressions, and declarations should be printed.