/// \brief Fetches list of variables associated with this clause.
MutableArrayRef<Expr *> getVarRefs() {
return MutableArrayRef<Expr *>(
- reinterpret_cast<Expr **>(
- reinterpret_cast<char *>(this) +
- llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())),
- NumVars);
+ static_cast<T *>(this)->template getTrailingObjects<Expr *>(), NumVars);
}
/// \brief Sets the list of variables for this clause.
void setVarRefs(ArrayRef<Expr *> VL) {
assert(VL.size() == NumVars &&
"Number of variables is not the same as the preallocated buffer");
- std::copy(
- VL.begin(), VL.end(),
- reinterpret_cast<Expr **>(
- reinterpret_cast<char *>(this) +
- llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<Expr *>())));
+ std::copy(VL.begin(), VL.end(),
+ static_cast<T *>(this)->template getTrailingObjects<Expr *>());
}
/// \brief Build a clause with \a N variables
/// \brief Fetches list of all variables in the clause.
ArrayRef<const Expr *> getVarRefs() const {
return llvm::makeArrayRef(
- reinterpret_cast<const Expr *const *>(
- reinterpret_cast<const char *>(this) +
- llvm::RoundUpToAlignment(sizeof(T), llvm::alignOf<const Expr *>())),
+ static_cast<const T *>(this)->template getTrailingObjects<Expr *>(),
NumVars);
}
};
/// In this example directive '#pragma omp parallel' has clause 'private'
/// with the variables 'a' and 'b'.
///
-class OMPPrivateClause : public OMPVarListClause<OMPPrivateClause> {
+class OMPPrivateClause final
+ : public OMPVarListClause<OMPPrivateClause>,
+ private llvm::TrailingObjects<OMPPrivateClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
///
/// In this example directive '#pragma omp parallel' has clause 'firstprivate'
/// with the variables 'a' and 'b'.
///
-class OMPFirstprivateClause : public OMPVarListClause<OMPFirstprivateClause> {
+class OMPFirstprivateClause final
+ : public OMPVarListClause<OMPFirstprivateClause>,
+ private llvm::TrailingObjects<OMPFirstprivateClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
/// \endcode
/// In this example directive '#pragma omp simd' has clause 'lastprivate'
/// with the variables 'a' and 'b'.
-class OMPLastprivateClause : public OMPVarListClause<OMPLastprivateClause> {
+class OMPLastprivateClause final
+ : public OMPVarListClause<OMPLastprivateClause>,
+ private llvm::TrailingObjects<OMPLastprivateClause, Expr *> {
// There are 4 additional tail-allocated arrays at the end of the class:
// 1. Contains list of pseudo variables with the default initialization for
// each non-firstprivate variables. Used in codegen for initialization of
// Required for proper codegen of final assignment performed by the
// lastprivate clause.
//
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
/// In this example directive '#pragma omp parallel' has clause 'shared'
/// with the variables 'a' and 'b'.
///
-class OMPSharedClause : public OMPVarListClause<OMPSharedClause> {
+class OMPSharedClause final
+ : public OMPVarListClause<OMPSharedClause>,
+ private llvm::TrailingObjects<OMPSharedClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
/// \brief Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// In this example directive '#pragma omp parallel' has clause 'reduction'
/// with operator '+' and the variables 'a' and 'b'.
///
-class OMPReductionClause : public OMPVarListClause<OMPReductionClause> {
+class OMPReductionClause final
+ : public OMPVarListClause<OMPReductionClause>,
+ private llvm::TrailingObjects<OMPReductionClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Location of ':'.
SourceLocation ColonLoc;
/// In this example directive '#pragma omp simd' has clause 'linear'
/// with variables 'a', 'b' and linear step '2'.
///
-class OMPLinearClause : public OMPVarListClause<OMPLinearClause> {
+class OMPLinearClause final
+ : public OMPVarListClause<OMPLinearClause>,
+ private llvm::TrailingObjects<OMPLinearClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Modifier of 'linear' clause.
OpenMPLinearClauseKind Modifier;
/// In this example directive '#pragma omp simd' has clause 'aligned'
/// with variables 'a', 'b' and alignment '8'.
///
-class OMPAlignedClause : public OMPVarListClause<OMPAlignedClause> {
+class OMPAlignedClause final
+ : public OMPVarListClause<OMPAlignedClause>,
+ private llvm::TrailingObjects<OMPAlignedClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Location of ':'.
SourceLocation ColonLoc;
/// In this example directive '#pragma omp parallel' has clause 'copyin'
/// with the variables 'a' and 'b'.
///
-class OMPCopyinClause : public OMPVarListClause<OMPCopyinClause> {
+class OMPCopyinClause final
+ : public OMPVarListClause<OMPCopyinClause>,
+ private llvm::TrailingObjects<OMPCopyinClause, Expr *> {
// Class has 3 additional tail allocated arrays:
// 1. List of helper expressions for proper generation of assignment operation
// required for copyin clause. This list represents sources.
// threadprivate variables to local instances of that variables in other
// implicit threads.
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
///
/// In this example directive '#pragma omp single' has clause 'copyprivate'
/// with the variables 'a' and 'b'.
///
-class OMPCopyprivateClause : public OMPVarListClause<OMPCopyprivateClause> {
+class OMPCopyprivateClause final
+ : public OMPVarListClause<OMPCopyprivateClause>,
+ private llvm::TrailingObjects<OMPCopyprivateClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Build clause with number of variables \a N.
///
/// In this example directive '#pragma omp flush' has implicit clause 'flush'
/// with the variables 'a' and 'b'.
///
-class OMPFlushClause : public OMPVarListClause<OMPFlushClause> {
+class OMPFlushClause final
+ : public OMPVarListClause<OMPFlushClause>,
+ private llvm::TrailingObjects<OMPFlushClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
/// \brief Build clause with number of variables \a N.
///
/// \param StartLoc Starting location of the clause.
/// In this example directive '#pragma omp task' with clause 'depend' with the
/// variables 'a' and 'b' with dependency 'in'.
///
-class OMPDependClause : public OMPVarListClause<OMPDependClause> {
+class OMPDependClause final
+ : public OMPVarListClause<OMPDependClause>,
+ private llvm::TrailingObjects<OMPDependClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Dependency type (one of in, out, inout).
OpenMPDependClauseKind DepKind;
/// In this example directive '#pragma omp target' has clause 'map'
/// with the variables 'a' and 'b'.
///
-class OMPMapClause : public OMPVarListClause<OMPMapClause> {
+class OMPMapClause final : public OMPVarListClause<OMPMapClause>,
+ private llvm::TrailingObjects<OMPMapClause, Expr *> {
+ friend TrailingObjects;
+ friend class OMPVarListClause;
friend class OMPClauseReader;
/// \brief Map type modifier for the 'map' clause.
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL) {
// Allocate space for private variables and initializer expressions.
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
- llvm::alignOf<Expr *>()) +
- 2 * sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * VL.size()));
OMPPrivateClause *Clause =
new (Mem) OMPPrivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
OMPPrivateClause *OMPPrivateClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPPrivateClause),
- llvm::alignOf<Expr *>()) +
- 2 * sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(2 * N));
return new (Mem) OMPPrivateClause(N);
}
SourceLocation LParenLoc, SourceLocation EndLoc,
ArrayRef<Expr *> VL, ArrayRef<Expr *> PrivateVL,
ArrayRef<Expr *> InitVL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
- llvm::alignOf<Expr *>()) +
- 3 * sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * VL.size()));
OMPFirstprivateClause *Clause =
new (Mem) OMPFirstprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
OMPFirstprivateClause *OMPFirstprivateClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFirstprivateClause),
- llvm::alignOf<Expr *>()) +
- 3 * sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(3 * N));
return new (Mem) OMPFirstprivateClause(N);
}
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
- llvm::alignOf<Expr *>()) +
- 5 * sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
OMPLastprivateClause *Clause =
new (Mem) OMPLastprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
OMPLastprivateClause *OMPLastprivateClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLastprivateClause),
- llvm::alignOf<Expr *>()) +
- 5 * sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
return new (Mem) OMPLastprivateClause(N);
}
SourceLocation LParenLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
OMPSharedClause *Clause =
new (Mem) OMPSharedClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
}
OMPSharedClause *OMPSharedClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPSharedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
return new (Mem) OMPSharedClause(N);
}
ArrayRef<Expr *> PL, ArrayRef<Expr *> IL, Expr *Step, Expr *CalcStep) {
// Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
// (Step and CalcStep).
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
- llvm::alignOf<Expr *>()) +
- (5 * VL.size() + 2) * sizeof(Expr *));
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size() + 2));
OMPLinearClause *Clause = new (Mem) OMPLinearClause(
StartLoc, LParenLoc, Modifier, ModifierLoc, ColonLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
unsigned NumVars) {
// Allocate space for 4 lists (Vars, Inits, Updates, Finals) and 2 expressions
// (Step and CalcStep).
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPLinearClause),
- llvm::alignOf<Expr *>()) +
- (5 * NumVars + 2) * sizeof(Expr *));
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * NumVars + 2));
return new (Mem) OMPLinearClause(NumVars);
}
OMPAlignedClause::Create(const ASTContext &C, SourceLocation StartLoc,
SourceLocation LParenLoc, SourceLocation ColonLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, Expr *A) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * (VL.size() + 1));
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size() + 1));
OMPAlignedClause *Clause = new (Mem)
OMPAlignedClause(StartLoc, LParenLoc, ColonLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
OMPAlignedClause *OMPAlignedClause::CreateEmpty(const ASTContext &C,
unsigned NumVars) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPAlignedClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * (NumVars + 1));
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(NumVars + 1));
return new (Mem) OMPAlignedClause(NumVars);
}
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
OMPCopyinClause *Clause =
new (Mem) OMPCopyinClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
}
OMPCopyinClause *OMPCopyinClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyinClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
return new (Mem) OMPCopyinClause(N);
}
const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation EndLoc, ArrayRef<Expr *> VL, ArrayRef<Expr *> SrcExprs,
ArrayRef<Expr *> DstExprs, ArrayRef<Expr *> AssignmentOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * VL.size()));
OMPCopyprivateClause *Clause =
new (Mem) OMPCopyprivateClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
OMPCopyprivateClause *OMPCopyprivateClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPCopyprivateClause),
- llvm::alignOf<Expr *>()) +
- 4 * sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(4 * N));
return new (Mem) OMPCopyprivateClause(N);
}
NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
- llvm::alignOf<Expr *>()) +
- 5 * sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
OMPReductionClause *Clause = new (Mem) OMPReductionClause(
StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
Clause->setVarRefs(VL);
OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPReductionClause),
- llvm::alignOf<Expr *>()) +
- 5 * sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
return new (Mem) OMPReductionClause(N);
}
SourceLocation LParenLoc,
SourceLocation EndLoc,
ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
OMPFlushClause *Clause =
new (Mem) OMPFlushClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
}
OMPFlushClause *OMPFlushClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPFlushClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
return new (Mem) OMPFlushClause(N);
}
SourceLocation LParenLoc, SourceLocation EndLoc,
OpenMPDependClauseKind DepKind, SourceLocation DepLoc,
SourceLocation ColonLoc, ArrayRef<Expr *> VL) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
OMPDependClause *Clause =
new (Mem) OMPDependClause(StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
}
OMPDependClause *OMPDependClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(llvm::RoundUpToAlignment(sizeof(OMPDependClause),
- llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
return new (Mem) OMPDependClause(N);
}
OpenMPMapClauseKind TypeModifier,
OpenMPMapClauseKind Type,
SourceLocation TypeLoc) {
- void *Mem = C.Allocate(
- llvm::RoundUpToAlignment(sizeof(OMPMapClause), llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * VL.size());
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(VL.size()));
OMPMapClause *Clause = new (Mem) OMPMapClause(
TypeModifier, Type, TypeLoc, StartLoc, LParenLoc, EndLoc, VL.size());
Clause->setVarRefs(VL);
}
OMPMapClause *OMPMapClause::CreateEmpty(const ASTContext &C, unsigned N) {
- void *Mem = C.Allocate(
- llvm::RoundUpToAlignment(sizeof(OMPMapClause), llvm::alignOf<Expr *>()) +
- sizeof(Expr *) * N);
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(N));
return new (Mem) OMPMapClause(N);
}