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.h186
1 files changed, 118 insertions, 68 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index f2648b9a4a04..b4bb0b6b6440 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -293,8 +293,8 @@ public:
/// \param Loc [in,out] - A source location which *may* be filled
/// in with the location of the expression making this a
/// non-modifiable lvalue, if specified.
- isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx,
- SourceLocation *Loc = 0) const;
+ isModifiableLvalueResult
+ isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = nullptr) const;
/// \brief The return type of classify(). Represents the C++11 expression
/// taxonomy.
@@ -372,7 +372,7 @@ public:
/// lvalues and xvalues are collectively referred to as glvalues, while
/// prvalues and xvalues together form rvalues.
Classification Classify(ASTContext &Ctx) const {
- return ClassifyImpl(Ctx, 0);
+ return ClassifyImpl(Ctx, nullptr);
}
/// \brief ClassifyModifiable - Classify this expression according to the
@@ -483,10 +483,10 @@ public:
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx,
- SourceLocation *Loc = 0,
+ SourceLocation *Loc = nullptr,
bool isEvaluated = true) const;
bool isIntegerConstantExpr(const ASTContext &Ctx,
- SourceLocation *Loc = 0) const;
+ SourceLocation *Loc = nullptr) const;
/// isCXX98IntegralConstantExpr - Return true if this expression is an
/// integral constant expression in C++98. Can only be used in C++.
@@ -497,8 +497,8 @@ public:
///
/// Note: This does not perform the implicit conversions required by C++11
/// [expr.const]p5.
- bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = 0,
- SourceLocation *Loc = 0) const;
+ bool isCXX11ConstantExpr(const ASTContext &Ctx, APValue *Result = nullptr,
+ SourceLocation *Loc = nullptr) const;
/// isPotentialConstantExpr - Return true if this function's definition
/// might be usable in a constant expression in C++11, if it were marked
@@ -508,9 +508,22 @@ public:
SmallVectorImpl<
PartialDiagnosticAt> &Diags);
+ /// isPotentialConstantExprUnevaluted - Return true if this expression might
+ /// be usable in a constant expression in C++11 in an unevaluated context, if
+ /// it were in function FD marked constexpr. Return false if the function can
+ /// never produce a constant expression, along with diagnostics describing
+ /// why not.
+ static bool isPotentialConstantExprUnevaluated(Expr *E,
+ const FunctionDecl *FD,
+ SmallVectorImpl<
+ PartialDiagnosticAt> &Diags);
+
/// isConstantInitializer - Returns true if this expression can be emitted to
/// IR as a constant, and thus can be used as a constant initializer in C.
- bool isConstantInitializer(ASTContext &Ctx, bool ForRef) const;
+ /// If this expression is not constant and Culprit is non-null,
+ /// it is used to store the address of first non constant expr.
+ bool isConstantInitializer(ASTContext &Ctx, bool ForRef,
+ const Expr **Culprit = nullptr) const;
/// EvalStatus is a struct with detailed info about an evaluation in progress.
struct EvalStatus {
@@ -527,7 +540,7 @@ public:
/// expression *is* a constant expression, no notes will be produced.
SmallVectorImpl<PartialDiagnosticAt> *Diag;
- EvalStatus() : HasSideEffects(false), Diag(0) {}
+ EvalStatus() : HasSideEffects(false), Diag(nullptr) {}
// hasSideEffects - Return true if the evaluated expression has
// side effects.
@@ -584,7 +597,7 @@ public:
/// integer. This must be called on an expression that constant folds to an
/// integer.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx,
- SmallVectorImpl<PartialDiagnosticAt> *Diag=0) const;
+ SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr) const;
void EvaluateForOverflow(const ASTContext &Ctx) const;
@@ -600,6 +613,14 @@ public:
const VarDecl *VD,
SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+ /// EvaluateWithSubstitution - Evaluate an expression as if from the context
+ /// of a call to the given function with the given arguments, inside an
+ /// unevaluated context. Returns true if the expression could be folded to a
+ /// constant.
+ bool EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
+ const FunctionDecl *Callee,
+ ArrayRef<const Expr*> Args) const;
+
/// \brief Enumeration used to describe the kind of Null pointer constant
/// returned from \c isNullPointerConstant().
enum NullPointerConstantKind {
@@ -681,6 +702,9 @@ public:
/// or CastExprs, returning their operand.
Expr *IgnoreParenCasts() LLVM_READONLY;
+ /// Ignore casts. Strip off any CastExprs, returning their operand.
+ Expr *IgnoreCasts() LLVM_READONLY;
+
/// IgnoreParenImpCasts - Ignore parentheses and implicit casts. Strip off
/// any ParenExpr or ImplicitCastExprs, returning their operand.
Expr *IgnoreParenImpCasts() LLVM_READONLY;
@@ -742,6 +766,11 @@ public:
const Expr *IgnoreParenCasts() const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenCasts();
}
+ /// Strip off casts, but keep parentheses.
+ const Expr *IgnoreCasts() const LLVM_READONLY {
+ return const_cast<Expr*>(this)->IgnoreCasts();
+ }
+
const Expr *IgnoreParenNoopCasts(ASTContext &Ctx) const LLVM_READONLY {
return const_cast<Expr*>(this)->IgnoreParenNoopCasts(Ctx);
}
@@ -764,11 +793,6 @@ public:
SmallVectorImpl<const Expr *> &CommaLHS,
SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
- /// Skip irrelevant expressions to find what should be materialize for
- /// binding with a reference.
- const Expr *
- findMaterializedTemporary(const MaterializeTemporaryExpr *&MTE) const;
-
static bool classof(const Stmt *T) {
return T->getStmtClass() >= firstExprConstant &&
T->getStmtClass() <= lastExprConstant;
@@ -793,7 +817,7 @@ class OpaqueValueExpr : public Expr {
public:
OpaqueValueExpr(SourceLocation Loc, QualType T, ExprValueKind VK,
ExprObjectKind OK = OK_Ordinary,
- Expr *SourceExpr = 0)
+ Expr *SourceExpr = nullptr)
: Expr(OpaqueValueExprClass, T, VK, OK,
T->isDependentType(),
T->isDependentType() ||
@@ -937,25 +961,19 @@ public:
computeDependence(D->getASTContext());
}
- static DeclRefExpr *Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D,
- bool isEnclosingLocal,
- SourceLocation NameLoc,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
-
- static DeclRefExpr *Create(const ASTContext &Context,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateKWLoc,
- ValueDecl *D,
- bool isEnclosingLocal,
- const DeclarationNameInfo &NameInfo,
- QualType T, ExprValueKind VK,
- NamedDecl *FoundD = 0,
- const TemplateArgumentListInfo *TemplateArgs = 0);
+ static DeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+ SourceLocation NameLoc, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
+
+ static DeclRefExpr *
+ Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKWLoc, ValueDecl *D, bool isEnclosingLocal,
+ const DeclarationNameInfo &NameInfo, QualType T, ExprValueKind VK,
+ NamedDecl *FoundD = nullptr,
+ const TemplateArgumentListInfo *TemplateArgs = nullptr);
/// \brief Construct an empty declaration reference expression.
static DeclRefExpr *CreateEmpty(const ASTContext &Context,
@@ -985,7 +1003,7 @@ public:
/// that precedes the name. Otherwise, returns NULL.
NestedNameSpecifier *getQualifier() const {
if (!hasQualifier())
- return 0;
+ return nullptr;
return getInternalQualifierLoc().getNestedNameSpecifier();
}
@@ -1021,7 +1039,7 @@ public:
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!hasTemplateKWAndArgsInfo())
- return 0;
+ return nullptr;
if (hasFoundDecl())
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(
@@ -1085,7 +1103,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -1100,7 +1118,7 @@ public:
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
- return 0;
+ return nullptr;
return getExplicitTemplateArgs().getTemplateArgs();
}
@@ -1151,6 +1169,7 @@ public:
Function,
LFunction, // Same as Function, but as wide string.
FuncDName,
+ FuncSig,
PrettyFunction,
/// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
/// 'virtual' keyword is omitted for virtual member functions.
@@ -1862,7 +1881,7 @@ private:
explicit OffsetOfExpr(unsigned numComps, unsigned numExprs)
: Expr(OffsetOfExprClass, EmptyShell()),
- TSInfo(0), NumComps(numComps), NumExprs(numExprs) {}
+ TSInfo(nullptr), NumComps(numComps), NumExprs(numExprs) {}
public:
@@ -2213,6 +2232,13 @@ public:
typedef ExprIterator arg_iterator;
typedef ConstExprIterator const_arg_iterator;
+ typedef llvm::iterator_range<arg_iterator> arg_range;
+ typedef llvm::iterator_range<const_arg_iterator> arg_const_range;
+
+ arg_range arguments() { return arg_range(arg_begin(), arg_end()); }
+ arg_const_range arguments() const {
+ return arg_const_range(arg_begin(), arg_end());
+ }
arg_iterator arg_begin() { return SubExprs+PREARGS_START+getNumPreArgs(); }
arg_iterator arg_end() {
@@ -2238,9 +2264,9 @@ public:
/// this function call.
unsigned getNumCommas() const { return NumArgs ? NumArgs - 1 : 0; }
- /// isBuiltinCall - If this is a call to a builtin, return the builtin ID. If
- /// not, return 0.
- unsigned isBuiltinCall() const;
+ /// getBuiltinCallee - If this is a call to a builtin, return the builtin ID
+ /// of the callee. If not, return 0.
+ unsigned getBuiltinCallee() const;
/// \brief Returns \c true if this is a call to a builtin which does not
/// evaluate side-effects within its arguments.
@@ -2392,14 +2418,14 @@ public:
/// \brief Determines whether this member expression actually had
/// a C++ nested-name-specifier prior to the name of the member, e.g.,
/// x->Base::foo.
- bool hasQualifier() const { return getQualifier() != 0; }
+ bool hasQualifier() const { return getQualifier() != nullptr; }
/// \brief If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
NestedNameSpecifier *getQualifier() const {
if (!HasQualifierOrFoundDecl)
- return 0;
+ return nullptr;
return getMemberQualifier()->QualifierLoc.getNestedNameSpecifier();
}
@@ -2417,7 +2443,7 @@ public:
/// \brief Return the optional template keyword and arguments info.
ASTTemplateKWAndArgsInfo *getTemplateKWAndArgsInfo() {
if (!HasTemplateKWAndArgsInfo)
- return 0;
+ return nullptr;
if (!HasQualifierOrFoundDecl)
return reinterpret_cast<ASTTemplateKWAndArgsInfo *>(this + 1);
@@ -2485,7 +2511,7 @@ public:
/// This points to the same data as getExplicitTemplateArgs(), but
/// returns null if there are no explicit template arguments.
const ASTTemplateArgumentListInfo *getOptionalExplicitTemplateArgs() const {
- if (!hasExplicitTemplateArgs()) return 0;
+ if (!hasExplicitTemplateArgs()) return nullptr;
return &getExplicitTemplateArgs();
}
@@ -2493,7 +2519,7 @@ public:
/// template-id.
const TemplateArgumentLoc *getTemplateArgs() const {
if (!hasExplicitTemplateArgs())
- return 0;
+ return nullptr;
return getExplicitTemplateArgs().getTemplateArgs();
}
@@ -2633,7 +2659,7 @@ public:
private:
Stmt *Op;
- void CheckCastConsistency() const;
+ bool CastConsistency() const;
const CXXBaseSpecifier * const *path_buffer() const {
return const_cast<CastExpr*>(this)->path_buffer();
@@ -2664,9 +2690,7 @@ protected:
assert(kind != CK_Invalid && "creating cast with invalid cast kind");
CastExprBits.Kind = kind;
setBasePathSize(BasePathSize);
-#ifndef NDEBUG
- CheckCastConsistency();
-#endif
+ assert(CastConsistency());
}
/// \brief Construct an empty cast.
@@ -3422,7 +3446,7 @@ public:
/// \brief Build an empty vector-shuffle expression.
explicit ShuffleVectorExpr(EmptyShell Empty)
- : Expr(ShuffleVectorExprClass, Empty), SubExprs(0) { }
+ : Expr(ShuffleVectorExprClass, Empty), SubExprs(nullptr) { }
SourceLocation getBuiltinLoc() const { return BuiltinLoc; }
void setBuiltinLoc(SourceLocation L) { BuiltinLoc = L; }
@@ -3774,6 +3798,14 @@ public:
void setInit(unsigned Init, Expr *expr) {
assert(Init < getNumInits() && "Initializer access out of range!");
InitExprs[Init] = expr;
+
+ if (expr) {
+ ExprBits.TypeDependent |= expr->isTypeDependent();
+ ExprBits.ValueDependent |= expr->isValueDependent();
+ ExprBits.InstantiationDependent |= expr->isInstantiationDependent();
+ ExprBits.ContainsUnexpandedParameterPack |=
+ expr->containsUnexpandedParameterPack();
+ }
}
/// \brief Reserve space for some number of initializers.
@@ -3824,8 +3856,8 @@ public:
return const_cast<InitListExpr *>(this)->getInitializedFieldInUnion();
}
void setInitializedFieldInUnion(FieldDecl *FD) {
- assert((FD == 0
- || getInitializedFieldInUnion() == 0
+ assert((FD == nullptr
+ || getInitializedFieldInUnion() == nullptr
|| getInitializedFieldInUnion() == FD)
&& "Only one field of a union may be initialized at a time!");
ArrayFillerOrUnionFieldInit = FD;
@@ -3848,10 +3880,10 @@ public:
bool isSemanticForm() const { return AltForm.getInt(); }
InitListExpr *getSemanticForm() const {
- return isSemanticForm() ? 0 : AltForm.getPointer();
+ return isSemanticForm() ? nullptr : AltForm.getPointer();
}
InitListExpr *getSyntacticForm() const {
- return isSemanticForm() ? AltForm.getPointer() : 0;
+ return isSemanticForm() ? AltForm.getPointer() : nullptr;
}
void setSyntacticForm(InitListExpr *Init) {
@@ -3877,6 +3909,7 @@ public:
// Iterators
child_range children() {
+ // FIXME: This does not include the array filler expression.
if (InitExprs.empty()) return child_range();
return child_range(&InitExprs[0], &InitExprs[0] + InitExprs.size());
}
@@ -3953,7 +3986,7 @@ private:
explicit DesignatedInitExpr(unsigned NumSubExprs)
: Expr(DesignatedInitExprClass, EmptyShell()),
- NumDesignators(0), NumSubExprs(NumSubExprs), Designators(0) { }
+ NumDesignators(0), NumSubExprs(NumSubExprs), Designators(nullptr) { }
public:
/// A field designator, e.g., ".x".
@@ -4050,7 +4083,7 @@ public:
FieldDecl *getField() const {
assert(Kind == FieldDesignator && "Only valid on a field designator");
if (Field.NameOrField & 0x01)
- return 0;
+ return nullptr;
else
return reinterpret_cast<FieldDecl *>(Field.NameOrField);
}
@@ -4134,6 +4167,17 @@ public:
return Designators + NumDesignators;
}
+ typedef llvm::iterator_range<designators_iterator> designators_range;
+ designators_range designators() {
+ return designators_range(designators_begin(), designators_end());
+ }
+
+ typedef llvm::iterator_range<const_designators_iterator>
+ designators_const_range;
+ designators_const_range designators() const {
+ return designators_const_range(designators_begin(), designators_end());
+ }
+
typedef std::reverse_iterator<designators_iterator>
reverse_designators_iterator;
reverse_designators_iterator designators_rbegin() {
@@ -4186,18 +4230,14 @@ public:
/// and array-range designators.
unsigned getNumSubExprs() const { return NumSubExprs; }
- Expr *getSubExpr(unsigned Idx) {
+ Expr *getSubExpr(unsigned Idx) const {
assert(Idx < NumSubExprs && "Subscript out of range");
- char* Ptr = static_cast<char*>(static_cast<void *>(this));
- Ptr += sizeof(DesignatedInitExpr);
- return reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx];
+ return cast<Expr>(reinterpret_cast<Stmt *const *>(this + 1)[Idx]);
}
void setSubExpr(unsigned Idx, Expr *E) {
assert(Idx < NumSubExprs && "Subscript out of range");
- char* Ptr = static_cast<char*>(static_cast<void *>(this));
- Ptr += sizeof(DesignatedInitExpr);
- reinterpret_cast<Expr**>(reinterpret_cast<void**>(Ptr))[Idx] = E;
+ reinterpret_cast<Stmt **>(this + 1)[Idx] = E;
}
/// \brief Replaces the designator at index @p Idx with the series
@@ -4621,7 +4661,7 @@ class PseudoObjectExpr : public Expr {
public:
/// NoResult - A value for the result index indicating that there is
/// no semantic result.
- enum LLVM_ENUM_INT_TYPE(unsigned) { NoResult = ~0U };
+ enum : unsigned { NoResult = ~0U };
static PseudoObjectExpr *Create(const ASTContext &Context, Expr *syntactic,
ArrayRef<Expr*> semantic,
@@ -4646,7 +4686,7 @@ public:
/// Return the result-bearing expression, or null if there is none.
Expr *getResultExpr() {
if (PseudoObjectExprBits.ResultIndex == 0)
- return 0;
+ return nullptr;
return getSubExprsBuffer()[PseudoObjectExprBits.ResultIndex];
}
const Expr *getResultExpr() const {
@@ -4713,6 +4753,16 @@ public:
BI_First = 0
};
+ // The ABI values for various atomic memory orderings.
+ enum AtomicOrderingKind {
+ AO_ABI_memory_order_relaxed = 0,
+ AO_ABI_memory_order_consume = 1,
+ AO_ABI_memory_order_acquire = 2,
+ AO_ABI_memory_order_release = 3,
+ AO_ABI_memory_order_acq_rel = 4,
+ AO_ABI_memory_order_seq_cst = 5
+ };
+
private:
enum { PTR, ORDER, VAL1, ORDER_FAIL, VAL2, WEAK, END_EXPR };
Stmt* SubExprs[END_EXPR];