diff options
author | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-05-02 19:39:53 +0000 |
commit | 110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab (patch) | |
tree | 64a10f4c4154739d4a8191d7e1b52ce497f4ebd6 /lib/AST/ExprClassification.cpp | |
parent | a0fb00f9837bd0d2e5948f16f6a6b82a7a628f51 (diff) | |
download | FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.zip FreeBSD-src-110eaaceddcec790f7e6a5e3bf1261c9aa1e73ab.tar.gz |
Vendor import of clang trunk r130700:
http://llvm.org/svn/llvm-project/cfe/trunk@130700
Diffstat (limited to 'lib/AST/ExprClassification.cpp')
-rw-r--r-- | lib/AST/ExprClassification.cpp | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/lib/AST/ExprClassification.cpp b/lib/AST/ExprClassification.cpp index 890898a..888a93c 100644 --- a/lib/AST/ExprClassification.cpp +++ b/lib/AST/ExprClassification.cpp @@ -61,8 +61,10 @@ Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const { if (TR->isFunctionType() || TR == Ctx.OverloadTy) kind = Cl::CL_Function; // No void either, but qualified void is OK because it is "other than void". - else if (TR->isVoidType() && !Ctx.getCanonicalType(TR).hasQualifiers()) - kind = Cl::CL_Void; + // Void "lvalues" are classified as addressable void values, which are void + // expressions whose address can be taken. + else if (TR->isVoidType() && !TR.hasQualifiers()) + kind = (kind == Cl::CL_LValue ? Cl::CL_AddressableVoid : Cl::CL_Void); } // Enable this assertion for testing. @@ -71,10 +73,12 @@ Cl Expr::ClassifyImpl(ASTContext &Ctx, SourceLocation *Loc) const { case Cl::CL_XValue: assert(getValueKind() == VK_XValue); break; case Cl::CL_Function: case Cl::CL_Void: + case Cl::CL_AddressableVoid: case Cl::CL_DuplicateVectorComponents: case Cl::CL_MemberFunction: case Cl::CL_SubObjCPropertySetting: case Cl::CL_ClassTemporary: + case Cl::CL_ObjCMessageRValue: case Cl::CL_PRValue: assert(getValueKind() == VK_RValue); break; } @@ -128,7 +132,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // Expressions that are prvalues. case Expr::CXXBoolLiteralExprClass: case Expr::CXXPseudoDestructorExprClass: - case Expr::SizeOfAlignOfExprClass: + case Expr::UnaryExprOrTypeTraitExprClass: case Expr::CXXNewExprClass: case Expr::CXXThisExprClass: case Expr::CXXNullPtrLiteralExprClass: @@ -148,6 +152,8 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::CXXScalarValueInitExprClass: case Expr::UnaryTypeTraitExprClass: case Expr::BinaryTypeTraitExprClass: + case Expr::ArrayTypeTraitExprClass: + case Expr::ExpressionTraitExprClass: case Expr::ObjCSelectorExprClass: case Expr::ObjCProtocolExprClass: case Expr::ObjCStringLiteralClass: @@ -169,6 +175,9 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { // C++ [expr.prim.general]p3: The result is an lvalue if the entity is a // function or variable and a prvalue otherwise. case Expr::DeclRefExprClass: + if (E->getType() == Ctx.UnknownAnyTy) + return isa<FunctionDecl>(cast<DeclRefExpr>(E)->getDecl()) + ? Cl::CL_PRValue : Cl::CL_LValue; return ClassifyDecl(Ctx, cast<DeclRefExpr>(E)->getDecl()); // We deal with names referenced from blocks the same way. case Expr::BlockDeclRefExprClass: @@ -229,6 +238,14 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ParenExprClass: return ClassifyInternal(Ctx, cast<ParenExpr>(E)->getSubExpr()); + // C1X 6.5.1.1p4: [A generic selection] is an lvalue, a function designator, + // or a void expression if its result expression is, respectively, an + // lvalue, a function designator, or a void expression. + case Expr::GenericSelectionExprClass: + if (cast<GenericSelectionExpr>(E)->isResultDependent()) + return Cl::CL_PRValue; + return ClassifyInternal(Ctx,cast<GenericSelectionExpr>(E)->getResultExpr()); + case Expr::BinaryOperatorClass: case Expr::CompoundAssignOperatorClass: // C doesn't have any binary expressions that are lvalues. @@ -293,7 +310,8 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { case Expr::ObjCMessageExprClass: if (const ObjCMethodDecl *Method = cast<ObjCMessageExpr>(E)->getMethodDecl()) { - return ClassifyUnnamed(Ctx, Method->getResultType()); + Cl::Kinds kind = ClassifyUnnamed(Ctx, Method->getResultType()); + return (kind == Cl::CL_PRValue) ? Cl::CL_ObjCMessageRValue : kind; } return Cl::CL_PRValue; @@ -373,6 +391,10 @@ static Cl::Kinds ClassifyUnnamed(ASTContext &Ctx, QualType T) { } static Cl::Kinds ClassifyMemberExpr(ASTContext &Ctx, const MemberExpr *E) { + if (E->getType() == Ctx.UnknownAnyTy) + return (isa<FunctionDecl>(E->getMemberDecl()) + ? Cl::CL_PRValue : Cl::CL_LValue); + // Handle C first, it's easier. if (!Ctx.getLangOptions().CPlusPlus) { // C99 6.5.2.3p3 @@ -546,11 +568,13 @@ Expr::LValueClassification Expr::ClassifyLValue(ASTContext &Ctx) const { case Cl::CL_LValue: return LV_Valid; case Cl::CL_XValue: return LV_InvalidExpression; case Cl::CL_Function: return LV_NotObjectType; - case Cl::CL_Void: return LV_IncompleteVoidType; + case Cl::CL_Void: return LV_InvalidExpression; + case Cl::CL_AddressableVoid: return LV_IncompleteVoidType; case Cl::CL_DuplicateVectorComponents: return LV_DuplicateVectorComponents; case Cl::CL_MemberFunction: return LV_MemberFunction; case Cl::CL_SubObjCPropertySetting: return LV_SubObjCPropertySetting; case Cl::CL_ClassTemporary: return LV_ClassTemporary; + case Cl::CL_ObjCMessageRValue: return LV_InvalidMessageExpression; case Cl::CL_PRValue: return LV_InvalidExpression; } llvm_unreachable("Unhandled kind"); @@ -564,11 +588,13 @@ Expr::isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc) const { case Cl::CL_LValue: break; case Cl::CL_XValue: return MLV_InvalidExpression; case Cl::CL_Function: return MLV_NotObjectType; - case Cl::CL_Void: return MLV_IncompleteVoidType; + case Cl::CL_Void: return MLV_InvalidExpression; + case Cl::CL_AddressableVoid: return MLV_IncompleteVoidType; case Cl::CL_DuplicateVectorComponents: return MLV_DuplicateVectorComponents; case Cl::CL_MemberFunction: return MLV_MemberFunction; case Cl::CL_SubObjCPropertySetting: return MLV_SubObjCPropertySetting; case Cl::CL_ClassTemporary: return MLV_ClassTemporary; + case Cl::CL_ObjCMessageRValue: return MLV_InvalidMessageExpression; case Cl::CL_PRValue: return VC.getModifiable() == Cl::CM_LValueCast ? MLV_LValueCast : MLV_InvalidExpression; |