summaryrefslogtreecommitdiffstats
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.h78
1 files changed, 76 insertions, 2 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index a3be7d0..2a5b4c0 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -598,7 +598,7 @@ public:
/// \brief Determine whether this expression involves a call to any function
/// that is not trivial.
- bool hasNonTrivialCall(ASTContext &Ctx);
+ bool hasNonTrivialCall(const ASTContext &Ctx) const;
/// EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded
/// integer. This must be called on an expression that constant folds to an
@@ -2273,7 +2273,7 @@ public:
/// \brief Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
- bool isUnevaluatedBuiltinCall(ASTContext &Ctx) const;
+ bool isUnevaluatedBuiltinCall(const ASTContext &Ctx) const;
/// getCallReturnType - Get the return type of the call expr. This is not
/// always the type of the expr itself, if the return type is a reference
@@ -4267,6 +4267,80 @@ public:
}
};
+/// \brief Represents a place-holder for an object not to be initialized by
+/// anything.
+///
+/// This only makes sense when it appears as part of an updater of a
+/// DesignatedInitUpdateExpr (see below). The base expression of a DIUE
+/// initializes a big object, and the NoInitExpr's mark the spots within the
+/// big object not to be overwritten by the updater.
+///
+/// \see DesignatedInitUpdateExpr
+class NoInitExpr : public Expr {
+public:
+ explicit NoInitExpr(QualType ty)
+ : Expr(NoInitExprClass, ty, VK_RValue, OK_Ordinary,
+ false, false, ty->isInstantiationDependentType(), false) { }
+
+ explicit NoInitExpr(EmptyShell Empty)
+ : Expr(NoInitExprClass, Empty) { }
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == NoInitExprClass;
+ }
+
+ SourceLocation getLocStart() const LLVM_READONLY { return SourceLocation(); }
+ SourceLocation getLocEnd() const LLVM_READONLY { return SourceLocation(); }
+
+ // Iterators
+ child_range children() { return child_range(); }
+};
+
+// In cases like:
+// struct Q { int a, b, c; };
+// Q *getQ();
+// void foo() {
+// struct A { Q q; } a = { *getQ(), .q.b = 3 };
+// }
+//
+// We will have an InitListExpr for a, with type A, and then a
+// DesignatedInitUpdateExpr for "a.q" with type Q. The "base" for this DIUE
+// is the call expression *getQ(); the "updater" for the DIUE is ".q.b = 3"
+//
+class DesignatedInitUpdateExpr : public Expr {
+ // BaseAndUpdaterExprs[0] is the base expression;
+ // BaseAndUpdaterExprs[1] is an InitListExpr overwriting part of the base.
+ Stmt *BaseAndUpdaterExprs[2];
+
+public:
+ DesignatedInitUpdateExpr(const ASTContext &C, SourceLocation lBraceLoc,
+ Expr *baseExprs, SourceLocation rBraceLoc);
+
+ explicit DesignatedInitUpdateExpr(EmptyShell Empty)
+ : Expr(DesignatedInitUpdateExprClass, Empty) { }
+
+ SourceLocation getLocStart() const LLVM_READONLY;
+ SourceLocation getLocEnd() const LLVM_READONLY;
+
+ static bool classof(const Stmt *T) {
+ return T->getStmtClass() == DesignatedInitUpdateExprClass;
+ }
+
+ Expr *getBase() const { return cast<Expr>(BaseAndUpdaterExprs[0]); }
+ void setBase(Expr *Base) { BaseAndUpdaterExprs[0] = Base; }
+
+ InitListExpr *getUpdater() const {
+ return cast<InitListExpr>(BaseAndUpdaterExprs[1]);
+ }
+ void setUpdater(Expr *Updater) { BaseAndUpdaterExprs[1] = Updater; }
+
+ // Iterators
+ // children = the base and the updater
+ child_range children() {
+ return child_range(&BaseAndUpdaterExprs[0], &BaseAndUpdaterExprs[0] + 2);
+ }
+};
+
/// \brief Represents an implicitly-generated value initialization of
/// an object of a given type.
///
OpenPOWER on IntegriCloud