diff options
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r-- | include/clang/AST/Expr.h | 186 |
1 files changed, 118 insertions, 68 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index f2648b9a4a045..b4bb0b6b64408 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]; |