aboutsummaryrefslogtreecommitdiff
path: root/include/clang/AST/Expr.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r--include/clang/AST/Expr.h139
1 files changed, 134 insertions, 5 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index 9179c7736a9a..41ae6d2b721e 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -445,6 +445,11 @@ public:
return const_cast<Expr*>(this)->getSourceBitField();
}
+ Decl *getReferencedDeclOfCallee();
+ const Decl *getReferencedDeclOfCallee() const {
+ return const_cast<Expr*>(this)->getReferencedDeclOfCallee();
+ }
+
/// \brief If this expression is an l-value for an Objective C
/// property, find the underlying property reference expression.
const ObjCPropertyRefExpr *getObjCProperty() const;
@@ -823,12 +828,22 @@ public:
/// behavior if the object isn't dynamically of the derived type.
const CXXRecordDecl *getBestDynamicClassType() const;
+ /// \brief Get the inner expression that determines the best dynamic class.
+ /// If this is a prvalue, we guarantee that it is of the most-derived type
+ /// for the object itself.
+ const Expr *getBestDynamicClassTypeExpr() const;
+
/// Walk outwards from an expression we want to bind a reference to and
/// find the expression whose lifetime needs to be extended. Record
/// the LHSs of comma expressions and adjustments needed along the path.
const Expr *skipRValueSubobjectAdjustments(
SmallVectorImpl<const Expr *> &CommaLHS,
SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+ const Expr *skipRValueSubobjectAdjustments() const {
+ SmallVector<const Expr *, 8> CommaLHSs;
+ SmallVector<SubobjectAdjustment, 8> Adjustments;
+ return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+ }
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
@@ -2406,8 +2421,8 @@ public:
/// \brief Retrieve the member declaration to which this expression refers.
///
- /// The returned declaration will either be a FieldDecl or (in C++)
- /// a CXXMethodDecl.
+ /// The returned declaration will be a FieldDecl or (in C++) a VarDecl (for
+ /// static data members), a CXXMethodDecl, or an EnumConstantDecl.
ValueDecl *getMemberDecl() const { return MemberDecl; }
void setMemberDecl(ValueDecl *D) { MemberDecl = D; }
@@ -3771,17 +3786,26 @@ public:
/// \brief Build an empty initializer list.
explicit InitListExpr(EmptyShell Empty)
- : Expr(InitListExprClass, Empty) { }
+ : Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
unsigned getNumInits() const { return InitExprs.size(); }
/// \brief Retrieve the set of initializers.
Expr **getInits() { return reinterpret_cast<Expr **>(InitExprs.data()); }
+ /// \brief Retrieve the set of initializers.
+ Expr * const *getInits() const {
+ return reinterpret_cast<Expr * const *>(InitExprs.data());
+ }
+
ArrayRef<Expr *> inits() {
return llvm::makeArrayRef(getInits(), getNumInits());
}
+ ArrayRef<Expr *> inits() const {
+ return llvm::makeArrayRef(getInits(), getNumInits());
+ }
+
const Expr *getInit(unsigned Init) const {
assert(Init < getNumInits() && "Initializer access out of range!");
return cast_or_null<Expr>(InitExprs[Init]);
@@ -3862,7 +3886,7 @@ public:
// Explicit InitListExpr's originate from source code (and have valid source
// locations). Implicit InitListExpr's are created by the semantic analyzer.
- bool isExplicit() {
+ bool isExplicit() const {
return LBraceLoc.isValid() && RBraceLoc.isValid();
}
@@ -3870,6 +3894,11 @@ public:
// literal or an @encode?
bool isStringLiteralInit() const;
+ /// Is this a transparent initializer list (that is, an InitListExpr that is
+ /// purely syntactic, and whose semantics are that of the sole contained
+ /// initializer)?
+ bool isTransparent() const;
+
SourceLocation getLBraceLoc() const { return LBraceLoc; }
void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
SourceLocation getRBraceLoc() const { return RBraceLoc; }
@@ -4304,6 +4333,98 @@ public:
}
};
+/// \brief Represents a loop initializing the elements of an array.
+///
+/// The need to initialize the elements of an array occurs in a number of
+/// contexts:
+///
+/// * in the implicit copy/move constructor for a class with an array member
+/// * when a lambda-expression captures an array by value
+/// * when a decomposition declaration decomposes an array
+///
+/// There are two subexpressions: a common expression (the source array)
+/// that is evaluated once up-front, and a per-element initializer that
+/// runs once for each array element.
+///
+/// Within the per-element initializer, the common expression may be referenced
+/// via an OpaqueValueExpr, and the current index may be obtained via an
+/// ArrayInitIndexExpr.
+class ArrayInitLoopExpr : public Expr {
+ Stmt *SubExprs[2];
+
+ explicit ArrayInitLoopExpr(EmptyShell Empty)
+ : Expr(ArrayInitLoopExprClass, Empty), SubExprs{} {}
+
+public:
+ explicit ArrayInitLoopExpr(QualType T, Expr *CommonInit, Expr *ElementInit)
+ : Expr(ArrayInitLoopExprClass, T, VK_RValue, OK_Ordinary, false,
+ CommonInit->isValueDependent() || ElementInit->isValueDependent(),
+ T->isInstantiationDependentType(),
+ CommonInit->containsUnexpandedParameterPack() ||
+ ElementInit->containsUnexpandedParameterPack()),
+ SubExprs{CommonInit, ElementInit} {}
+
+ /// Get the common subexpression shared by all initializations (the source
+ /// array).
+ OpaqueValueExpr *getCommonExpr() const {
+ return cast<OpaqueValueExpr>(SubExprs[0]);
+ }
+
+ /// Get the initializer to use for each array element.
+ Expr *getSubExpr() const { return cast<Expr>(SubExprs[1]); }
+
+ llvm::APInt getArraySize() const {
+ return cast<ConstantArrayType>(getType()->castAsArrayTypeUnsafe())
+ ->getSize();
+ }
+
+ static bool classof(const Stmt *S) {
+ return S->getStmtClass() == ArrayInitLoopExprClass;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY {
+ return getCommonExpr()->getLocStart();
+ }
+ SourceLocation getLocEnd() const LLVM_READONLY {
+ return getCommonExpr()->getLocEnd();
+ }
+
+ child_range children() {
+ return child_range(SubExprs, SubExprs + 2);
+ }
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+ friend class ASTStmtWriter;
+};
+
+/// \brief Represents the index of the current element of an array being
+/// initialized by an ArrayInitLoopExpr. This can only appear within the
+/// subexpression of an ArrayInitLoopExpr.
+class ArrayInitIndexExpr : public Expr {
+ explicit ArrayInitIndexExpr(EmptyShell Empty)
+ : Expr(ArrayInitIndexExprClass, Empty) {}
+
+public:
+ explicit ArrayInitIndexExpr(QualType T)
+ : Expr(ArrayInitIndexExprClass, T, VK_RValue, OK_Ordinary,
+ false, false, false, false) {}
+
+ static bool classof(const Stmt *S) {
+ return S->getStmtClass() == ArrayInitIndexExprClass;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+ child_range children() {
+ return child_range(child_iterator(), child_iterator());
+ }
+
+ friend class ASTReader;
+ friend class ASTStmtReader;
+};
+
/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///
@@ -4447,11 +4568,19 @@ public:
return cast<Expr>(SubExprs[END_EXPR+i]);
}
Expr *getAssocExpr(unsigned i) { return cast<Expr>(SubExprs[END_EXPR+i]); }
-
+ ArrayRef<Expr *> getAssocExprs() const {
+ return NumAssocs
+ ? llvm::makeArrayRef(
+ &reinterpret_cast<Expr **>(SubExprs)[END_EXPR], NumAssocs)
+ : None;
+ }
const TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) const {
return AssocTypes[i];
}
TypeSourceInfo *getAssocTypeSourceInfo(unsigned i) { return AssocTypes[i]; }
+ ArrayRef<TypeSourceInfo *> getAssocTypeSourceInfos() const {
+ return NumAssocs ? llvm::makeArrayRef(&AssocTypes[0], NumAssocs) : None;
+ }
QualType getAssocType(unsigned i) const {
if (const TypeSourceInfo *TS = getAssocTypeSourceInfo(i))