Path: blob/main/contrib/llvm-project/clang/lib/AST/AttrImpl.cpp
35259 views
//===--- AttrImpl.cpp - Classes for representing attributes -----*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains out-of-line methods for Attr classes.9//10//===----------------------------------------------------------------------===//1112#include "clang/AST/ASTContext.h"13#include "clang/AST/Attr.h"14#include "clang/AST/Expr.h"15#include "clang/AST/Type.h"16#include <optional>17using namespace clang;1819void LoopHintAttr::printPrettyPragma(raw_ostream &OS,20const PrintingPolicy &Policy) const {21unsigned SpellingIndex = getAttributeSpellingListIndex();22// For "#pragma unroll" and "#pragma nounroll" the string "unroll" or23// "nounroll" is already emitted as the pragma name.24if (SpellingIndex == Pragma_nounroll ||25SpellingIndex == Pragma_nounroll_and_jam)26return;27else if (SpellingIndex == Pragma_unroll ||28SpellingIndex == Pragma_unroll_and_jam) {29OS << ' ' << getValueString(Policy);30return;31}3233assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");34OS << ' ' << getOptionName(option) << getValueString(Policy);35}3637// Return a string containing the loop hint argument including the38// enclosing parentheses.39std::string LoopHintAttr::getValueString(const PrintingPolicy &Policy) const {40std::string ValueName;41llvm::raw_string_ostream OS(ValueName);42OS << "(";43if (state == Numeric)44value->printPretty(OS, nullptr, Policy);45else if (state == FixedWidth || state == ScalableWidth) {46if (value) {47value->printPretty(OS, nullptr, Policy);48if (state == ScalableWidth)49OS << ", scalable";50} else if (state == ScalableWidth)51OS << "scalable";52else53OS << "fixed";54} else if (state == Enable)55OS << "enable";56else if (state == Full)57OS << "full";58else if (state == AssumeSafety)59OS << "assume_safety";60else61OS << "disable";62OS << ")";63return ValueName;64}6566// Return a string suitable for identifying this attribute in diagnostics.67std::string68LoopHintAttr::getDiagnosticName(const PrintingPolicy &Policy) const {69unsigned SpellingIndex = getAttributeSpellingListIndex();70if (SpellingIndex == Pragma_nounroll)71return "#pragma nounroll";72else if (SpellingIndex == Pragma_unroll)73return "#pragma unroll" +74(option == UnrollCount ? getValueString(Policy) : "");75else if (SpellingIndex == Pragma_nounroll_and_jam)76return "#pragma nounroll_and_jam";77else if (SpellingIndex == Pragma_unroll_and_jam)78return "#pragma unroll_and_jam" +79(option == UnrollAndJamCount ? getValueString(Policy) : "");8081assert(SpellingIndex == Pragma_clang_loop && "Unexpected spelling");82return getOptionName(option) + getValueString(Policy);83}8485void OMPDeclareSimdDeclAttr::printPrettyPragma(86raw_ostream &OS, const PrintingPolicy &Policy) const {87if (getBranchState() != BS_Undefined)88OS << ' ' << ConvertBranchStateTyToStr(getBranchState());89if (auto *E = getSimdlen()) {90OS << " simdlen(";91E->printPretty(OS, nullptr, Policy);92OS << ")";93}94if (uniforms_size() > 0) {95OS << " uniform";96StringRef Sep = "(";97for (auto *E : uniforms()) {98OS << Sep;99E->printPretty(OS, nullptr, Policy);100Sep = ", ";101}102OS << ")";103}104alignments_iterator NI = alignments_begin();105for (auto *E : aligneds()) {106OS << " aligned(";107E->printPretty(OS, nullptr, Policy);108if (*NI) {109OS << ": ";110(*NI)->printPretty(OS, nullptr, Policy);111}112OS << ")";113++NI;114}115steps_iterator I = steps_begin();116modifiers_iterator MI = modifiers_begin();117for (auto *E : linears()) {118OS << " linear(";119if (*MI != OMPC_LINEAR_unknown)120OS << getOpenMPSimpleClauseTypeName(llvm::omp::Clause::OMPC_linear, *MI)121<< "(";122E->printPretty(OS, nullptr, Policy);123if (*MI != OMPC_LINEAR_unknown)124OS << ")";125if (*I) {126OS << ": ";127(*I)->printPretty(OS, nullptr, Policy);128}129OS << ")";130++I;131++MI;132}133}134135void OMPDeclareTargetDeclAttr::printPrettyPragma(136raw_ostream &OS, const PrintingPolicy &Policy) const {137// Use fake syntax because it is for testing and debugging purpose only.138if (getDevType() != DT_Any)139OS << " device_type(" << ConvertDevTypeTyToStr(getDevType()) << ")";140if (getMapType() != MT_To && getMapType() != MT_Enter)141OS << ' ' << ConvertMapTypeTyToStr(getMapType());142if (Expr *E = getIndirectExpr()) {143OS << " indirect(";144E->printPretty(OS, nullptr, Policy);145OS << ")";146} else if (getIndirect()) {147OS << " indirect";148}149}150151std::optional<OMPDeclareTargetDeclAttr *>152OMPDeclareTargetDeclAttr::getActiveAttr(const ValueDecl *VD) {153if (llvm::all_of(VD->redecls(), [](const Decl *D) { return !D->hasAttrs(); }))154return std::nullopt;155unsigned Level = 0;156OMPDeclareTargetDeclAttr *FoundAttr = nullptr;157for (const Decl *D : VD->redecls()) {158for (auto *Attr : D->specific_attrs<OMPDeclareTargetDeclAttr>()) {159if (Level <= Attr->getLevel()) {160Level = Attr->getLevel();161FoundAttr = Attr;162}163}164}165if (FoundAttr)166return FoundAttr;167return std::nullopt;168}169170std::optional<OMPDeclareTargetDeclAttr::MapTypeTy>171OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(const ValueDecl *VD) {172std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);173if (ActiveAttr)174return (*ActiveAttr)->getMapType();175return std::nullopt;176}177178std::optional<OMPDeclareTargetDeclAttr::DevTypeTy>179OMPDeclareTargetDeclAttr::getDeviceType(const ValueDecl *VD) {180std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);181if (ActiveAttr)182return (*ActiveAttr)->getDevType();183return std::nullopt;184}185186std::optional<SourceLocation>187OMPDeclareTargetDeclAttr::getLocation(const ValueDecl *VD) {188std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr = getActiveAttr(VD);189if (ActiveAttr)190return (*ActiveAttr)->getRange().getBegin();191return std::nullopt;192}193194namespace clang {195llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo &TI);196llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const OMPTraitInfo *TI);197}198199void OMPDeclareVariantAttr::printPrettyPragma(200raw_ostream &OS, const PrintingPolicy &Policy) const {201if (const Expr *E = getVariantFuncRef()) {202OS << "(";203E->printPretty(OS, nullptr, Policy);204OS << ")";205}206OS << " match(" << traitInfos << ")";207208auto PrintExprs = [&OS, &Policy](Expr **Begin, Expr **End) {209for (Expr **I = Begin; I != End; ++I) {210assert(*I && "Expected non-null Stmt");211if (I != Begin)212OS << ",";213(*I)->printPretty(OS, nullptr, Policy);214}215};216if (adjustArgsNothing_size()) {217OS << " adjust_args(nothing:";218PrintExprs(adjustArgsNothing_begin(), adjustArgsNothing_end());219OS << ")";220}221if (adjustArgsNeedDevicePtr_size()) {222OS << " adjust_args(need_device_ptr:";223PrintExprs(adjustArgsNeedDevicePtr_begin(), adjustArgsNeedDevicePtr_end());224OS << ")";225}226227auto PrintInteropInfo = [&OS](OMPInteropInfo *Begin, OMPInteropInfo *End) {228for (OMPInteropInfo *I = Begin; I != End; ++I) {229if (I != Begin)230OS << ", ";231OS << "interop(";232OS << getInteropTypeString(I);233OS << ")";234}235};236if (appendArgs_size()) {237OS << " append_args(";238PrintInteropInfo(appendArgs_begin(), appendArgs_end());239OS << ")";240}241}242243unsigned AlignedAttr::getAlignment(ASTContext &Ctx) const {244assert(!isAlignmentDependent());245if (getCachedAlignmentValue())246return *getCachedAlignmentValue();247248// Handle alignmentType case.249if (!isAlignmentExpr()) {250QualType T = getAlignmentType()->getType();251252// C++ [expr.alignof]p3:253// When alignof is applied to a reference type, the result is the254// alignment of the referenced type.255T = T.getNonReferenceType();256257if (T.getQualifiers().hasUnaligned())258return Ctx.getCharWidth();259260return Ctx.getTypeAlignInChars(T.getTypePtr()).getQuantity() *261Ctx.getCharWidth();262}263264// Handle alignmentExpr case.265if (alignmentExpr)266return alignmentExpr->EvaluateKnownConstInt(Ctx).getZExtValue() *267Ctx.getCharWidth();268269return Ctx.getTargetDefaultAlignForAttributeAligned();270}271272#include "clang/AST/AttrImpl.inc"273274275