Skip to content

Commit f5216d4

Browse files
committed
[LLVM][Clang] Add and enable strict mode for getTrailingObjects
Under strict mode, the templated `getTrailingObjects` can be called only when there is > 1 trailing types. The strict mode can be disabled on a per-call basis when its not possible to know statically if there will be a single or multiple trailing types (like in OpenMPClause.h).
1 parent c0cc81c commit f5216d4

File tree

4 files changed

+47
-28
lines changed

4 files changed

+47
-28
lines changed

clang/include/clang/AST/OpenMPClause.h

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,8 @@ template <class T> class OMPVarListClause : public OMPClause {
295295

296296
/// Fetches list of variables associated with this clause.
297297
MutableArrayRef<Expr *> getVarRefs() {
298-
return static_cast<T *>(this)->template getTrailingObjects<Expr *>(NumVars);
298+
return static_cast<T *>(this)
299+
->template getTrailingObjects<Expr *, /*Strict=*/false>(NumVars);
299300
}
300301

301302
/// Sets the list of variables for this clause.
@@ -334,8 +335,8 @@ template <class T> class OMPVarListClause : public OMPClause {
334335

335336
/// Fetches list of all variables in the clause.
336337
ArrayRef<const Expr *> getVarRefs() const {
337-
return static_cast<const T *>(this)->template getTrailingObjects<Expr *>(
338-
NumVars);
338+
return static_cast<const T *>(this)
339+
->template getTrailingObjects<Expr *, /*Strict=*/false>(NumVars);
339340
}
340341
};
341342

@@ -380,7 +381,8 @@ template <class T> class OMPDirectiveListClause : public OMPClause {
380381

381382
MutableArrayRef<OpenMPDirectiveKind> getDirectiveKinds() {
382383
return static_cast<T *>(this)
383-
->template getTrailingObjects<OpenMPDirectiveKind>(NumKinds);
384+
->template getTrailingObjects<OpenMPDirectiveKind, /*Strict=*/false>(
385+
NumKinds);
384386
}
385387

386388
void setDirectiveKinds(ArrayRef<OpenMPDirectiveKind> DK) {
@@ -5901,15 +5903,17 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
59015903
/// Get the unique declarations that are in the trailing objects of the
59025904
/// class.
59035905
MutableArrayRef<ValueDecl *> getUniqueDeclsRef() {
5904-
return static_cast<T *>(this)->template getTrailingObjects<ValueDecl *>(
5905-
NumUniqueDeclarations);
5906+
return static_cast<T *>(this)
5907+
->template getTrailingObjects<ValueDecl *, /*Strict=*/false>(
5908+
NumUniqueDeclarations);
59065909
}
59075910

59085911
/// Get the unique declarations that are in the trailing objects of the
59095912
/// class.
59105913
ArrayRef<ValueDecl *> getUniqueDeclsRef() const {
59115914
return static_cast<const T *>(this)
5912-
->template getTrailingObjects<ValueDecl *>(NumUniqueDeclarations);
5915+
->template getTrailingObjects<ValueDecl *, /*Strict=*/false>(
5916+
NumUniqueDeclarations);
59135917
}
59145918

59155919
/// Set the unique declarations that are in the trailing objects of the
@@ -5923,15 +5927,17 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
59235927
/// Get the number of lists per declaration that are in the trailing
59245928
/// objects of the class.
59255929
MutableArrayRef<unsigned> getDeclNumListsRef() {
5926-
return static_cast<T *>(this)->template getTrailingObjects<unsigned>(
5927-
NumUniqueDeclarations);
5930+
return static_cast<T *>(this)
5931+
->template getTrailingObjects<unsigned, /*Strict=*/false>(
5932+
NumUniqueDeclarations);
59285933
}
59295934

59305935
/// Get the number of lists per declaration that are in the trailing
59315936
/// objects of the class.
59325937
ArrayRef<unsigned> getDeclNumListsRef() const {
5933-
return static_cast<const T *>(this)->template getTrailingObjects<unsigned>(
5934-
NumUniqueDeclarations);
5938+
return static_cast<const T *>(this)
5939+
->template getTrailingObjects<unsigned, /*Strict=*/false>(
5940+
NumUniqueDeclarations);
59355941
}
59365942

59375943
/// Set the number of lists per declaration that are in the trailing
@@ -5946,7 +5952,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
59465952
/// objects of the class. They are appended after the number of lists.
59475953
MutableArrayRef<unsigned> getComponentListSizesRef() {
59485954
return MutableArrayRef<unsigned>(
5949-
static_cast<T *>(this)->template getTrailingObjects<unsigned>() +
5955+
static_cast<T *>(this)
5956+
->template getTrailingObjects<unsigned, /*Strict=*/false>() +
59505957
NumUniqueDeclarations,
59515958
NumComponentLists);
59525959
}
@@ -5955,7 +5962,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
59555962
/// objects of the class. They are appended after the number of lists.
59565963
ArrayRef<unsigned> getComponentListSizesRef() const {
59575964
return ArrayRef<unsigned>(
5958-
static_cast<const T *>(this)->template getTrailingObjects<unsigned>() +
5965+
static_cast<const T *>(this)
5966+
->template getTrailingObjects<unsigned, /*Strict=*/false>() +
59595967
NumUniqueDeclarations,
59605968
NumComponentLists);
59615969
}
@@ -5971,13 +5979,15 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
59715979
/// Get the components that are in the trailing objects of the class.
59725980
MutableArrayRef<MappableComponent> getComponentsRef() {
59735981
return static_cast<T *>(this)
5974-
->template getTrailingObjects<MappableComponent>(NumComponents);
5982+
->template getTrailingObjects<MappableComponent, /*Strict=*/false>(
5983+
NumComponents);
59755984
}
59765985

59775986
/// Get the components that are in the trailing objects of the class.
59785987
ArrayRef<MappableComponent> getComponentsRef() const {
59795988
return static_cast<const T *>(this)
5980-
->template getTrailingObjects<MappableComponent>(NumComponents);
5989+
->template getTrailingObjects<MappableComponent, /*Strict=*/false>(
5990+
NumComponents);
59815991
}
59825992

59835993
/// Set the components that are in the trailing objects of the class.
@@ -6084,7 +6094,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
60846094
assert(SupportsMapper &&
60856095
"Must be a clause that is possible to have user-defined mappers");
60866096
return llvm::MutableArrayRef<Expr *>(
6087-
static_cast<T *>(this)->template getTrailingObjects<Expr *>() +
6097+
static_cast<T *>(this)
6098+
->template getTrailingObjects<Expr *, /*Strict=*/false>() +
60886099
OMPVarListClause<T>::varlist_size(),
60896100
OMPVarListClause<T>::varlist_size());
60906101
}
@@ -6095,7 +6106,8 @@ class OMPMappableExprListClause : public OMPVarListClause<T>,
60956106
assert(SupportsMapper &&
60966107
"Must be a clause that is possible to have user-defined mappers");
60976108
return llvm::ArrayRef<Expr *>(
6098-
static_cast<const T *>(this)->template getTrailingObjects<Expr *>() +
6109+
static_cast<const T *>(this)
6110+
->template getTrailingObjects<Expr *, /*Strict=*/false>() +
60996111
OMPVarListClause<T>::varlist_size(),
61006112
OMPVarListClause<T>::varlist_size());
61016113
}

clang/lib/AST/Expr.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2024,7 +2024,8 @@ CXXBaseSpecifier **CastExpr::path_buffer() {
20242024
#define ABSTRACT_STMT(x)
20252025
#define CASTEXPR(Type, Base) \
20262026
case Stmt::Type##Class: \
2027-
return static_cast<Type *>(this)->getTrailingObjects<CXXBaseSpecifier *>();
2027+
return static_cast<Type *>(this) \
2028+
->getTrailingObjects<CXXBaseSpecifier *, /*Strict=*/false>();
20282029
#define STMT(Type, Base)
20292030
#include "clang/AST/StmtNodes.inc"
20302031
default:

llvm/include/llvm/Support/TrailingObjects.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
282282
/// Returns a pointer to the trailing object array of the given type
283283
/// (which must be one of those specified in the class template). The
284284
/// array may have zero or more elements in it.
285-
template <typename T> const T *getTrailingObjects() const {
285+
template <typename T, bool Strict = true>
286+
const T *getTrailingObjects() const {
287+
static_assert(!Strict || sizeof...(TrailingTys) > 1);
286288
verifyTrailingObjectsAssertions();
287289
// Forwards to an impl function with overloads, since member
288290
// function templates can't be specialized.
@@ -294,7 +296,8 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
294296
/// Returns a pointer to the trailing object array of the given type
295297
/// (which must be one of those specified in the class template). The
296298
/// array may have zero or more elements in it.
297-
template <typename T> T *getTrailingObjects() {
299+
template <typename T, bool Strict = true> T *getTrailingObjects() {
300+
static_assert(!Strict || sizeof...(TrailingTys) > 1);
298301
verifyTrailingObjectsAssertions();
299302
// Forwards to an impl function with overloads, since member
300303
// function templates can't be specialized.
@@ -310,23 +313,25 @@ class TrailingObjects : private trailing_objects_internal::TrailingObjectsImpl<
310313
static_assert(sizeof...(TrailingTys) == 1,
311314
"Can use non-templated getTrailingObjects() only when there "
312315
"is a single trailing type");
313-
return getTrailingObjects<FirstTrailingType>();
316+
return getTrailingObjects<FirstTrailingType, /*Strict=*/false>();
314317
}
315318

316319
FirstTrailingType *getTrailingObjects() {
317320
static_assert(sizeof...(TrailingTys) == 1,
318321
"Can use non-templated getTrailingObjects() only when there "
319322
"is a single trailing type");
320-
return getTrailingObjects<FirstTrailingType>();
323+
return getTrailingObjects<FirstTrailingType, /*Strict=*/false>();
321324
}
322325

323326
// Functions that return the trailing objects as ArrayRefs.
324-
template <typename T> MutableArrayRef<T> getTrailingObjects(size_t N) {
325-
return MutableArrayRef(getTrailingObjects<T>(), N);
327+
template <typename T, bool Strict = true>
328+
MutableArrayRef<T> getTrailingObjects(size_t N) {
329+
return MutableArrayRef(getTrailingObjects<T, Strict>(), N);
326330
}
327331

328-
template <typename T> ArrayRef<T> getTrailingObjects(size_t N) const {
329-
return ArrayRef(getTrailingObjects<T>(), N);
332+
template <typename T, bool Strict = true>
333+
ArrayRef<T> getTrailingObjects(size_t N) const {
334+
return ArrayRef(getTrailingObjects<T, Strict>(), N);
330335
}
331336

332337
MutableArrayRef<FirstTrailingType> getTrailingObjects(size_t N) {

llvm/unittests/Support/TrailingObjectsTest.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,12 @@ TEST(TrailingObjects, OneArg) {
123123
EXPECT_EQ(Class1::totalSizeToAlloc<short>(3),
124124
sizeof(Class1) + sizeof(short) * 3);
125125

126-
EXPECT_EQ(C->getTrailingObjects<short>(), reinterpret_cast<short *>(C + 1));
126+
EXPECT_EQ(C->getTrailingObjects(), reinterpret_cast<short *>(C + 1));
127127
EXPECT_EQ(C->get(0), 1);
128128
EXPECT_EQ(C->get(2), 3);
129129

130-
EXPECT_EQ(C->getTrailingObjects(), C->getTrailingObjects<short>());
130+
EXPECT_EQ(C->getTrailingObjects(),
131+
(C->getTrailingObjects<short, /*Strict=*/false>()));
131132

132133
delete C;
133134
}

0 commit comments

Comments
 (0)