Skip to content

[NFC] Factor out common parts of ArraySections into its own class #89639

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 109 additions & 0 deletions clang/include/clang/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -6610,6 +6610,115 @@ class TypoExpr : public Expr {

};

// This is a sub-class for OpenMP and OpenACC array sections. OpenACC uses a
// very small subset of the functionality, so this class only exposes the things
// the two have in common. This type is not expected to be used directly,
// instead it is inherited from by the OMP and OpenACC variants.
//
// This type does not capture a 'stride', only a lower-bound and length (plus
// the base expression), but provides room via a template argument to get
// additional ones.
template <unsigned NumSubExprs, bool AllowNullExprs>
class ArraySectionExprBase : public Expr {
friend class ASTStmtReader;

enum { BASE, LOWER_BOUND, LENGTH, END_EXPR = NumSubExprs };
Stmt *SubExprs[END_EXPR];
SourceLocation ColonLocFirst;
SourceLocation RBracketLoc;

protected:
ArraySectionExprBase(StmtClass SC, Expr *Base, Expr *LowerBound, Expr *Length,
QualType Type, ExprValueKind VK, ExprObjectKind OK,
SourceLocation ColonLocFirst, SourceLocation RBracketLoc)
: Expr(SC, Type, VK, OK), ColonLocFirst(ColonLocFirst),
RBracketLoc(RBracketLoc) {
setBase(Base);
setLowerBound(LowerBound);
setLength(Length);
}

explicit ArraySectionExprBase(StmtClass SC, EmptyShell Shell)
: Expr(SC, Shell) {}

void setSubExpr(unsigned Idx, Expr *SubExpr) {
assert(Idx > LENGTH &&
"setting sub expression owned by ArraySectionExprBase: Should be "
"using the direct 'setter' functions");
assert((SubExpr || AllowNullExprs) && "Null expression when not allowed");
SubExprs[Idx] = SubExpr;
}

Expr *getSubExpr(unsigned Idx) {
assert(Idx > LENGTH &&
"getting sub expression owned by ArraySectionExprBase: Should be "
"using the direct 'getter' functions");
return cast_or_null<Expr>(SubExprs[Idx]);
}
const Expr *getSubExpr(unsigned Idx) const {
assert(Idx > LENGTH &&
"getting sub expression owned by ArraySectionExprBase: Should be "
"using the direct 'getter' functions");
return cast_or_null<Expr>(SubExprs[Idx]);
}

/// Set base of the array section.
void setBase(Expr *E) {
assert((E || AllowNullExprs) && "Null expression when not allowed");
SubExprs[BASE] = E;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you make it private or protected?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I made it protected (since I want the constructors of the inheritors to use it) and had to make ASTStmtReader a friend.

/// Set lower bound of the array section.
void setLowerBound(Expr *E) {
assert((E || AllowNullExprs) && "Null expression when not allowed");
SubExprs[LOWER_BOUND] = E;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same


/// Set length of the array section.
void setLength(Expr *E) {
assert((E || AllowNullExprs) && "Null expression when not allowed");
SubExprs[LENGTH] = E;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same


public:
/// Get base of the array section.
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }

/// Get lower bound of array section.
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
const Expr *getLowerBound() const {
return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
}

/// Get length of array section.
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }

SourceLocation getBeginLoc() const LLVM_READONLY {
return getBase()->getBeginLoc();
}

SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }

SourceLocation getColonLocFirst() const { return ColonLocFirst; }
void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }

SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }

SourceLocation getExprLoc() const LLVM_READONLY {
return getBase()->getExprLoc();
}
child_range children() {
return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}

const_child_range children() const {
return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}
};

/// Frontend produces RecoveryExprs on semantic errors that prevent creating
/// other well-formed expressions. E.g. when type-checking of a binary operator
/// fails, we cannot produce a BinaryOperator expression. Instead, we can choose
Expand Down
76 changes: 15 additions & 61 deletions clang/include/clang/AST/ExprOpenMP.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,92 +53,46 @@ namespace clang {
/// When the length is absent it defaults to ⌈(size − lower-bound)/stride⌉,
/// where size is the size of the array dimension. When the lower-bound is
/// absent it defaults to 0.
class OMPArraySectionExpr : public Expr {
enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
Stmt *SubExprs[END_EXPR];
SourceLocation ColonLocFirst;
namespace OMPArraySectionIndices {
enum { BASE, LOWER_BOUND, LENGTH, STRIDE, END_EXPR };
}
class OMPArraySectionExpr
: public ArraySectionExprBase<OMPArraySectionIndices::END_EXPR,
/*AllowNullExprs=*/true> {
SourceLocation ColonLocSecond;
SourceLocation RBracketLoc;

public:
OMPArraySectionExpr(Expr *Base, Expr *LowerBound, Expr *Length, Expr *Stride,
QualType Type, ExprValueKind VK, ExprObjectKind OK,
SourceLocation ColonLocFirst,
SourceLocation ColonLocSecond, SourceLocation RBracketLoc)
: Expr(OMPArraySectionExprClass, Type, VK, OK),
ColonLocFirst(ColonLocFirst), ColonLocSecond(ColonLocSecond),
RBracketLoc(RBracketLoc) {
SubExprs[BASE] = Base;
SubExprs[LOWER_BOUND] = LowerBound;
SubExprs[LENGTH] = Length;
SubExprs[STRIDE] = Stride;
: ArraySectionExprBase(OMPArraySectionExprClass, Base, LowerBound, Length,
Type, VK, OK, ColonLocFirst, RBracketLoc) {
setSubExpr(OMPArraySectionIndices::STRIDE, Stride);
setDependence(computeDependence(this));
}

/// Create an empty array section expression.
explicit OMPArraySectionExpr(EmptyShell Shell)
: Expr(OMPArraySectionExprClass, Shell) {}

/// An array section can be written only as Base[LowerBound:Length].

/// Get base of the array section.
Expr *getBase() { return cast<Expr>(SubExprs[BASE]); }
const Expr *getBase() const { return cast<Expr>(SubExprs[BASE]); }
/// Set base of the array section.
void setBase(Expr *E) { SubExprs[BASE] = E; }
: ArraySectionExprBase(OMPArraySectionExprClass, Shell) {}

/// Return original type of the base expression for array section.
static QualType getBaseOriginalType(const Expr *Base);

/// Get lower bound of array section.
Expr *getLowerBound() { return cast_or_null<Expr>(SubExprs[LOWER_BOUND]); }
const Expr *getLowerBound() const {
return cast_or_null<Expr>(SubExprs[LOWER_BOUND]);
}
/// Set lower bound of the array section.
void setLowerBound(Expr *E) { SubExprs[LOWER_BOUND] = E; }

/// Get length of array section.
Expr *getLength() { return cast_or_null<Expr>(SubExprs[LENGTH]); }
const Expr *getLength() const { return cast_or_null<Expr>(SubExprs[LENGTH]); }
/// Set length of the array section.
void setLength(Expr *E) { SubExprs[LENGTH] = E; }

/// Get stride of array section.
Expr *getStride() { return cast_or_null<Expr>(SubExprs[STRIDE]); }
const Expr *getStride() const { return cast_or_null<Expr>(SubExprs[STRIDE]); }
/// Set length of the array section.
void setStride(Expr *E) { SubExprs[STRIDE] = E; }

SourceLocation getBeginLoc() const LLVM_READONLY {
return getBase()->getBeginLoc();
Expr *getStride() { return getSubExpr(OMPArraySectionIndices::STRIDE); }
const Expr *getStride() const {
return getSubExpr(OMPArraySectionIndices::STRIDE);
}
SourceLocation getEndLoc() const LLVM_READONLY { return RBracketLoc; }

SourceLocation getColonLocFirst() const { return ColonLocFirst; }
void setColonLocFirst(SourceLocation L) { ColonLocFirst = L; }
/// Set length of the array section.
void setStride(Expr *E) { setSubExpr(OMPArraySectionIndices::STRIDE, E); }

SourceLocation getColonLocSecond() const { return ColonLocSecond; }
void setColonLocSecond(SourceLocation L) { ColonLocSecond = L; }

SourceLocation getRBracketLoc() const { return RBracketLoc; }
void setRBracketLoc(SourceLocation L) { RBracketLoc = L; }

SourceLocation getExprLoc() const LLVM_READONLY {
return getBase()->getExprLoc();
}

static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPArraySectionExprClass;
}

child_range children() {
return child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}

const_child_range children() const {
return const_child_range(&SubExprs[BASE], &SubExprs[END_EXPR]);
}
};

/// An explicit cast in C or a C-style cast in C++, which uses the syntax
Expand Down
Loading