diff options
Diffstat (limited to 'include/clang/AST/Expr.h')
-rw-r--r-- | include/clang/AST/Expr.h | 143 |
1 files changed, 120 insertions, 23 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 66639e2..8076443 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -162,9 +162,6 @@ public: }; isLvalueResult isLvalue(ASTContext &Ctx) const; - // Same as above, but excluding checks for non-object and void types in C - isLvalueResult isLvalueInternal(ASTContext &Ctx) const; - /// isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, /// does not have an incomplete type, does not have a const-qualified type, /// and if it is a structure or union, does not have any member (including, @@ -194,6 +191,95 @@ public: isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc = 0) const; + /// \brief The return type of classify(). Represents the C++0x expression + /// taxonomy. + class Classification { + public: + /// \brief The various classification results. Most of these mean prvalue. + enum Kinds { + CL_LValue, + CL_XValue, + CL_Function, // Functions cannot be lvalues in C. + CL_Void, // Void cannot be an lvalue in C. + CL_DuplicateVectorComponents, // A vector shuffle with dupes. + CL_MemberFunction, // An expression referring to a member function + CL_SubObjCPropertySetting, + CL_ClassTemporary, // A prvalue of class type + CL_PRValue // A prvalue for any other reason, of any other type + }; + /// \brief The results of modification testing. + enum ModifiableType { + CM_Untested, // testModifiable was false. + CM_Modifiable, + CM_RValue, // Not modifiable because it's an rvalue + CM_Function, // Not modifiable because it's a function; C++ only + CM_LValueCast, // Same as CM_RValue, but indicates GCC cast-as-lvalue ext + CM_NotBlockQualified, // Not captured in the closure + CM_NoSetterProperty,// Implicit assignment to ObjC property without setter + CM_ConstQualified, + CM_ArrayType, + CM_IncompleteType + }; + + private: + friend class Expr; + + unsigned short Kind; + unsigned short Modifiable; + + explicit Classification(Kinds k, ModifiableType m) + : Kind(k), Modifiable(m) + {} + + public: + Classification() {} + + Kinds getKind() const { return static_cast<Kinds>(Kind); } + ModifiableType getModifiable() const { + assert(Modifiable != CM_Untested && "Did not test for modifiability."); + return static_cast<ModifiableType>(Modifiable); + } + bool isLValue() const { return Kind == CL_LValue; } + bool isXValue() const { return Kind == CL_XValue; } + bool isGLValue() const { return Kind <= CL_XValue; } + bool isPRValue() const { return Kind >= CL_Function; } + bool isRValue() const { return Kind >= CL_XValue; } + bool isModifiable() const { return getModifiable() == CM_Modifiable; } + }; + /// \brief classify - Classify this expression according to the C++0x + /// expression taxonomy. + /// + /// C++0x defines ([basic.lval]) a new taxonomy of expressions to replace the + /// old lvalue vs rvalue. This function determines the type of expression this + /// is. There are three expression types: + /// - lvalues are classical lvalues as in C++03. + /// - prvalues are equivalent to rvalues in C++03. + /// - xvalues are expressions yielding unnamed rvalue references, e.g. a + /// function returning an rvalue reference. + /// lvalues and xvalues are collectively referred to as glvalues, while + /// prvalues and xvalues together form rvalues. + /// If a + Classification Classify(ASTContext &Ctx) const { + return ClassifyImpl(Ctx, 0); + } + + /// \brief classifyModifiable - Classify this expression according to the + /// C++0x expression taxonomy, and see if it is valid on the left side + /// of an assignment. + /// + /// This function extends classify in that it also tests whether the + /// expression is modifiable (C99 6.3.2.1p1). + /// \param Loc A source location that might be filled with a relevant location + /// if the expression is not modifiable. + Classification ClassifyModifiable(ASTContext &Ctx, SourceLocation &Loc) const{ + return ClassifyImpl(Ctx, &Loc); + } + +private: + Classification ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const; + +public: + /// \brief If this expression refers to a bit-field, retrieve the /// declaration of that bit-field. FieldDecl *getBitField(); @@ -414,6 +500,7 @@ struct ExplicitTemplateArgumentList { void initializeFrom(const TemplateArgumentListInfo &List); void copyInto(TemplateArgumentListInfo &List) const; + static std::size_t sizeFor(unsigned NumTemplateArgs); static std::size_t sizeFor(const TemplateArgumentListInfo &List); }; @@ -474,27 +561,21 @@ class DeclRefExpr : public Expr { ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, QualType T); + + /// \brief Construct an empty declaration reference expression. + explicit DeclRefExpr(EmptyShell Empty) + : Expr(DeclRefExprClass, Empty) { } -protected: /// \brief Computes the type- and value-dependence flags for this /// declaration reference expression. void computeDependence(); - DeclRefExpr(StmtClass SC, ValueDecl *d, QualType t, SourceLocation l) : - Expr(SC, t, false, false), DecoratedD(d, 0), Loc(l) { - computeDependence(); - } - public: DeclRefExpr(ValueDecl *d, QualType t, SourceLocation l) : Expr(DeclRefExprClass, t, false, false), DecoratedD(d, 0), Loc(l) { computeDependence(); } - /// \brief Construct an empty declaration reference expression. - explicit DeclRefExpr(EmptyShell Empty) - : Expr(DeclRefExprClass, Empty) { } - static DeclRefExpr *Create(ASTContext &Context, NestedNameSpecifier *Qualifier, SourceRange QualifierRange, @@ -502,6 +583,10 @@ public: SourceLocation NameLoc, QualType T, const TemplateArgumentListInfo *TemplateArgs = 0); + + /// \brief Construct an empty declaration reference expression. + static DeclRefExpr *CreateEmpty(ASTContext &Context, + bool HasQualifier, unsigned NumTemplateArgs); ValueDecl *getDecl() { return DecoratedD.getPointer(); } const ValueDecl *getDecl() const { return DecoratedD.getPointer(); } @@ -591,6 +676,9 @@ public: // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); + + friend class PCHStmtReader; + friend class PCHStmtWriter; }; /// PredefinedExpr - [C99 6.4.2.2] - A predefined identifier such as __func__. @@ -1560,11 +1648,6 @@ public: Base(base), MemberDecl(memberdecl), MemberLoc(l), IsArrow(isarrow), HasQualifierOrFoundDecl(false), HasExplicitTemplateArgumentList(false) {} - /// \brief Build an empty member reference expression. - explicit MemberExpr(EmptyShell Empty) - : Expr(MemberExprClass, Empty), HasQualifierOrFoundDecl(false), - HasExplicitTemplateArgumentList(false) { } - static MemberExpr *Create(ASTContext &C, Expr *base, bool isarrow, NestedNameSpecifier *qual, SourceRange qualrange, ValueDecl *memberdecl, DeclAccessPair founddecl, @@ -1937,6 +2020,7 @@ public: } const CXXBaseSpecifierArray& getBasePath() const { return BasePath; } + CXXBaseSpecifierArray& getBasePath() { return BasePath; } static bool classof(const Stmt *T) { return T->getStmtClass() >= firstCastExprConstant && @@ -2169,7 +2253,8 @@ public: /// predicates to categorize the respective opcodes. bool isMultiplicativeOp() const { return Opc >= Mul && Opc <= Rem; } - bool isAdditiveOp() const { return Opc == Add || Opc == Sub; } + static bool isAdditiveOp(Opcode Opc) { return Opc == Add || Opc == Sub; } + bool isAdditiveOp() const { return isAdditiveOp(Opc); } static bool isShiftOp(Opcode Opc) { return Opc == Shl || Opc == Shr; } bool isShiftOp() const { return isShiftOp(Opc); } @@ -3153,7 +3238,7 @@ public: ~ParenListExpr() {} /// \brief Build an empty paren list. - //explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } + explicit ParenListExpr(EmptyShell Empty) : Expr(ParenListExprClass, Empty) { } unsigned getNumExprs() const { return NumExprs; } @@ -3183,6 +3268,9 @@ public: // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); + + friend class PCHStmtReader; + friend class PCHStmtWriter; }; @@ -3305,12 +3393,15 @@ class BlockDeclRefExpr : public Expr { SourceLocation Loc; bool IsByRef : 1; bool ConstQualAdded : 1; + Stmt *CopyConstructorVal; public: // FIXME: Fix type/value dependence! BlockDeclRefExpr(ValueDecl *d, QualType t, SourceLocation l, bool ByRef, - bool constAdded = false) - : Expr(BlockDeclRefExprClass, t, false, false), D(d), Loc(l), IsByRef(ByRef), - ConstQualAdded(constAdded) {} + bool constAdded = false, + Stmt *copyConstructorVal = 0) + : Expr(BlockDeclRefExprClass, t, (!t.isNull() && t->isDependentType()),false), + D(d), Loc(l), IsByRef(ByRef), + ConstQualAdded(constAdded), CopyConstructorVal(copyConstructorVal) {} // \brief Build an empty reference to a declared variable in a // block. @@ -3331,6 +3422,12 @@ public: bool isConstQualAdded() const { return ConstQualAdded; } void setConstQualAdded(bool C) { ConstQualAdded = C; } + + const Expr *getCopyConstructorExpr() const + { return cast_or_null<Expr>(CopyConstructorVal); } + Expr *getCopyConstructorExpr() + { return cast_or_null<Expr>(CopyConstructorVal); } + void setCopyConstructorExpr(Expr *E) { CopyConstructorVal = E; } static bool classof(const Stmt *T) { return T->getStmtClass() == BlockDeclRefExprClass; |