aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaStmtAttr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaStmtAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaStmtAttr.cpp51
1 files changed, 28 insertions, 23 deletions
diff --git a/clang/lib/Sema/SemaStmtAttr.cpp b/clang/lib/Sema/SemaStmtAttr.cpp
index b03c055a4f50..6d443837a4c5 100644
--- a/clang/lib/Sema/SemaStmtAttr.cpp
+++ b/clang/lib/Sema/SemaStmtAttr.cpp
@@ -19,6 +19,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/StringExtras.h"
+#include <optional>
using namespace clang;
using namespace sema;
@@ -306,21 +307,33 @@ CheckForIncompatibleAttributes(Sema &S,
if (!DiagnoseMutualExclusions(S, Attrs))
return;
- // There are 6 categories of loop hints attributes: vectorize, interleave,
- // unroll, unroll_and_jam, pipeline and distribute. Except for distribute they
- // come in two variants: a state form and a numeric form. The state form
- // selectively defaults/enables/disables the transformation for the loop
- // (for unroll, default indicates full unrolling rather than enabling the
- // transformation). The numeric form form provides an integer hint (for
- // example, unroll count) to the transformer. The following array accumulates
- // the hints encountered while iterating through the attributes to check for
- // compatibility.
+ enum CategoryType {
+ // For the following categories, they come in two variants: a state form and
+ // a numeric form. The state form may be one of default, enable, and
+ // disable. The numeric form provides an integer hint (for example, unroll
+ // count) to the transformer.
+ Vectorize,
+ Interleave,
+ UnrollAndJam,
+ Pipeline,
+ // For unroll, default indicates full unrolling rather than enabling the
+ // transformation.
+ Unroll,
+ // The loop distribution transformation only has a state form that is
+ // exposed by #pragma clang loop distribute (enable | disable).
+ Distribute,
+ // The vector predication only has a state form that is exposed by
+ // #pragma clang loop vectorize_predicate (enable | disable).
+ VectorizePredicate,
+ // This serves as a indicator to how many category are listed in this enum.
+ NumberOfCategories
+ };
+ // The following array accumulates the hints encountered while iterating
+ // through the attributes to check for compatibility.
struct {
const LoopHintAttr *StateAttr;
const LoopHintAttr *NumericAttr;
- } HintAttrs[] = {{nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr},
- {nullptr, nullptr}, {nullptr, nullptr}, {nullptr, nullptr},
- {nullptr, nullptr}};
+ } HintAttrs[CategoryType::NumberOfCategories] = {};
for (const auto *I : Attrs) {
const LoopHintAttr *LH = dyn_cast<LoopHintAttr>(I);
@@ -329,16 +342,8 @@ CheckForIncompatibleAttributes(Sema &S,
if (!LH)
continue;
+ CategoryType Category = CategoryType::NumberOfCategories;
LoopHintAttr::OptionType Option = LH->getOption();
- enum {
- Vectorize,
- Interleave,
- Unroll,
- UnrollAndJam,
- Distribute,
- Pipeline,
- VectorizePredicate
- } Category;
switch (Option) {
case LoopHintAttr::Vectorize:
case LoopHintAttr::VectorizeWidth:
@@ -369,7 +374,7 @@ CheckForIncompatibleAttributes(Sema &S,
break;
};
- assert(Category < sizeof(HintAttrs) / sizeof(HintAttrs[0]));
+ assert(Category != NumberOfCategories && "Unhandled loop hint option");
auto &CategoryState = HintAttrs[Category];
const LoopHintAttr *PrevAttr;
if (Option == LoopHintAttr::Vectorize ||
@@ -420,7 +425,7 @@ static Attr *handleOpenCLUnrollHint(Sema &S, Stmt *St, const ParsedAttr &A,
unsigned UnrollFactor = 0;
if (A.getNumArgs() == 1) {
Expr *E = A.getArgAsExpr(0);
- Optional<llvm::APSInt> ArgVal;
+ std::optional<llvm::APSInt> ArgVal;
if (!(ArgVal = E->getIntegerConstantExpr(S.Context))) {
S.Diag(A.getLoc(), diag::err_attribute_argument_type)