diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/SemaCXXCast.cpp | 55 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 35 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 218 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 76 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 57 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 12 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 108 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 54 |
10 files changed, 416 insertions, 224 deletions
diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index e57e89e4a4..06c2758a9b 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -44,17 +44,21 @@ enum CastType { static void CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange); static void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange, CastKind &Kind); static void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, CastKind &Kind, CXXCastPath &BasePath); static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange, CastKind &Kind, @@ -156,44 +160,46 @@ Sema::BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, Diag(Ex->getLocStart(), diag::err_invalid_use_of_bound_member_func) << Ex->getSourceRange(); + ExprValueKind VK = VK_RValue; switch (Kind) { default: llvm_unreachable("Unknown C++ cast!"); case tok::kw_const_cast: if (!TypeDependent) - CheckConstCast(*this, Ex, DestType, OpRange, DestRange); + CheckConstCast(*this, Ex, DestType, VK, OpRange, DestRange); return Owned(CXXConstCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Ex, DestTInfo, OpLoc)); + VK, Ex, DestTInfo, OpLoc)); case tok::kw_dynamic_cast: { CastKind Kind = CK_Dependent; CXXCastPath BasePath; if (!TypeDependent) - CheckDynamicCast(*this, Ex, DestType, OpRange, DestRange, Kind, BasePath); + CheckDynamicCast(*this, Ex, DestType, VK, OpRange, DestRange, + Kind, BasePath); return Owned(CXXDynamicCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, &BasePath, DestTInfo, + VK, Kind, Ex, &BasePath, DestTInfo, OpLoc)); } case tok::kw_reinterpret_cast: { CastKind Kind = CK_Dependent; if (!TypeDependent) - CheckReinterpretCast(*this, Ex, DestType, OpRange, DestRange, Kind); + CheckReinterpretCast(*this, Ex, DestType, VK, OpRange, DestRange, Kind); return Owned(CXXReinterpretCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, 0, + VK, Kind, Ex, 0, DestTInfo, OpLoc)); } case tok::kw_static_cast: { CastKind Kind = CK_Dependent; CXXCastPath BasePath; if (!TypeDependent) - CheckStaticCast(*this, Ex, DestType, OpRange, Kind, BasePath); + CheckStaticCast(*this, Ex, DestType, VK, OpRange, Kind, BasePath); return Owned(CXXStaticCastExpr::Create(Context, DestType.getNonLValueExprType(Context), - Kind, Ex, &BasePath, + VK, Kind, Ex, &BasePath, DestTInfo, OpLoc)); } } @@ -315,7 +321,7 @@ CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) { /// checked downcasts in class hierarchies. static void CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, + ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange, CastKind &Kind, CXXCastPath &BasePath) { QualType OrigDestType = DestType, OrigSrcType = SrcExpr->getType(); @@ -326,11 +332,12 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, QualType DestPointee; const PointerType *DestPointer = DestType->getAs<PointerType>(); - const ReferenceType *DestReference = DestType->getAs<ReferenceType>(); + const ReferenceType *DestReference = 0; if (DestPointer) { DestPointee = DestPointer->getPointeeType(); - } else if (DestReference) { + } else if ((DestReference = DestType->getAs<ReferenceType>())) { DestPointee = DestReference->getPointeeType(); + VK = isa<LValueReferenceType>(DestReference) ? VK_LValue : VK_RValue; } else { Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr) << OrigDestType << DestRange; @@ -447,9 +454,10 @@ CheckDynamicCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// const char *str = "literal"; /// legacy_function(const_cast\<char*\>(str)); void -CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, +CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, ExprValueKind &VK, const SourceRange &OpRange, const SourceRange &DestRange) { - if (!DestType->isLValueReferenceType()) + VK = Expr::getValueKindForType(DestType); + if (VK == VK_RValue) Self.DefaultFunctionArrayLvalueConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; @@ -466,9 +474,10 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// char *bytes = reinterpret_cast\<char*\>(int_ptr); void CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, const SourceRange &DestRange, - CastKind &Kind) { - if (!DestType->isLValueReferenceType()) + ExprValueKind &VK, const SourceRange &OpRange, + const SourceRange &DestRange, CastKind &Kind) { + VK = Expr::getValueKindForType(DestType); + if (VK == VK_RValue) Self.DefaultFunctionArrayLvalueConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; @@ -498,8 +507,8 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, /// implicit conversions explicit and getting rid of data loss warnings. void CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, - const SourceRange &OpRange, CastKind &Kind, - CXXCastPath &BasePath) { + ExprValueKind &VK, const SourceRange &OpRange, + CastKind &Kind, CXXCastPath &BasePath) { // This test is outside everything else because it's the only case where // a non-lvalue-reference target type does not lead to decay. // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". @@ -508,7 +517,8 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, return; } - if (!DestType->isLValueReferenceType() && !DestType->isRecordType()) + VK = Expr::getValueKindForType(DestType); + if (VK == VK_RValue && !DestType->isRecordType()) Self.DefaultFunctionArrayLvalueConversion(SrcExpr); unsigned msg = diag::err_bad_cxx_cast_generic; @@ -1345,8 +1355,8 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, } bool -Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, - CastKind &Kind, +Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, + Expr *&CastExpr, CastKind &Kind, CXXCastPath &BasePath, bool FunctionalStyle) { if (CastExpr->isBoundMemberFunction(Context)) @@ -1368,7 +1378,8 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, Expr *&CastExpr, return false; } - if (!CastTy->isLValueReferenceType() && !CastTy->isRecordType()) + VK = Expr::getValueKindForType(CastTy); + if (VK == VK_RValue && !CastTy->isRecordType()) DefaultFunctionArrayLvalueConversion(CastExpr); // C++ [expr.cast]p5: The conversions performed by diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index d04addd210..ed45de53f2 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -487,8 +487,9 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // GCC does an implicit conversion to the pointer or integer ValType. This // can fail in some cases (1i -> int**), check for this error case now. CastKind Kind = CK_Invalid; + ExprValueKind VK = VK_RValue; CXXCastPath BasePath; - if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, BasePath)) + if (CheckCastTypes(Arg->getSourceRange(), ValType, Arg, Kind, VK, BasePath)) return ExprError(); // Okay, we have something that *can* be converted to the right type. Check @@ -497,7 +498,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // pass in 42. The 42 gets converted to char. This is even more strange // for things like 45.123 -> char, etc. // FIXME: Do this check. - ImpCastExprToType(Arg, ValType, Kind, VK_RValue, &BasePath); + ImpCastExprToType(Arg, ValType, Kind, VK, &BasePath); TheCall->setArg(i+1, Arg); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f7638f80d9..77f604a653 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1515,7 +1515,8 @@ BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, Expr *CopyCtorArg = DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, - Constructor->getLocation(), ParamType, 0); + Constructor->getLocation(), ParamType, + VK_LValue, 0); // Cast to the base class to avoid ambiguities. QualType ArgTy = @@ -1577,7 +1578,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, Expr *MemberExprBase = DeclRefExpr::Create(SemaRef.Context, 0, SourceRange(), Param, - Loc, ParamType, 0); + Loc, ParamType, VK_LValue, 0); // Build a reference to this field within the parameter. CXXScopeSpec SS; @@ -1622,7 +1623,7 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, // Create a reference to the iteration variable. ExprResult IterationVarRef - = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, Loc); + = SemaRef.BuildDeclRefExpr(IterationVar, SizeType, VK_RValue, Loc); assert(!IterationVarRef.isInvalid() && "Reference to invented variable cannot fail!"); @@ -4635,7 +4636,7 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, // Create a reference to the iteration variable; we'll use this several // times throughout. Expr *IterationVarRef - = S.BuildDeclRefExpr(IterationVar, SizeType, Loc).takeAs<Expr>(); + = S.BuildDeclRefExpr(IterationVar, SizeType, VK_RValue, Loc).take(); assert(IterationVarRef && "Reference to invented variable cannot fail!"); // Create the DeclStmt that holds the iteration variable. @@ -4646,15 +4647,14 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, Upper.zextOrTrunc(S.Context.getTypeSize(SizeType)); Expr *Comparison = new (S.Context) BinaryOperator(IterationVarRef, - IntegerLiteral::Create(S.Context, - Upper, SizeType, Loc), - BO_NE, S.Context.BoolTy, Loc); + IntegerLiteral::Create(S.Context, Upper, SizeType, Loc), + BO_NE, S.Context.BoolTy, + VK_RValue, OK_Ordinary, Loc); // Create the pre-increment of the iteration variable. Expr *Increment - = new (S.Context) UnaryOperator(IterationVarRef, - UO_PreInc, - SizeType, Loc); + = new (S.Context) UnaryOperator(IterationVarRef, UO_PreInc, SizeType, + VK_LValue, OK_Ordinary, Loc); // Subscript the "from" and "to" expressions with the iteration variable. From = AssertSuccess(S.CreateBuiltinArraySubscriptExpr(From, Loc, @@ -4663,10 +4663,9 @@ BuildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, IterationVarRef, Loc)); // Build the copy for an individual element of the array. - StmtResult Copy = BuildSingleCopyAssign(S, Loc, - ArrayTy->getElementType(), - To, From, - CopyingBaseSubobject, Depth+1); + StmtResult Copy = BuildSingleCopyAssign(S, Loc, ArrayTy->getElementType(), + To, From, CopyingBaseSubobject, + Depth + 1); if (Copy.isInvalid()) return StmtError(); @@ -4907,7 +4906,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, // Construct a reference to the "other" object. We'll be using this // throughout the generated ASTs. - Expr *OtherRef = BuildDeclRefExpr(Other, OtherRefType, Loc).takeAs<Expr>(); + Expr *OtherRef = BuildDeclRefExpr(Other, OtherRefType, VK_RValue, Loc).take(); assert(OtherRef && "Reference to parameter cannot fail!"); // Construct the "this" pointer. We'll be using this throughout the generated @@ -5068,7 +5067,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CollectableMemCpyRef = BuildDeclRefExpr(CollectableMemCpy, CollectableMemCpy->getType(), - Loc, 0).takeAs<Expr>(); + VK_LValue, Loc, 0).take(); assert(CollectableMemCpyRef && "Builtin reference cannot fail"); } } @@ -5088,7 +5087,7 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation, BuiltinMemCpyRef = BuildDeclRefExpr(BuiltinMemCpy, BuiltinMemCpy->getType(), - Loc, 0).takeAs<Expr>(); + VK_LValue, Loc, 0).take(); assert(BuiltinMemCpyRef && "Builtin reference cannot fail"); } @@ -6105,7 +6104,7 @@ VarDecl *Sema::BuildExceptionDeclaration(Scope *S, // it can be destroyed later. InitializedEntity Entity = InitializedEntity::InitializeVariable(ExDecl); Expr *ExDeclRef = DeclRefExpr::Create(Context, 0, SourceRange(), ExDecl, - Loc, ExDeclType, 0); + Loc, ExDeclType, VK_LValue, 0); InitializationKind Kind = InitializationKind::CreateCopy(Loc, SourceLocation()); InitializationSequence InitSeq(*this, Entity, Kind, &ExDeclRef, 1); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2cb92b6db6..25c27fe628 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -743,15 +743,16 @@ static bool ShouldSnapshotBlockValueReference(Sema &S, BlockScopeInfo *CurBlock, ExprResult -Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, SourceLocation Loc, - const CXXScopeSpec *SS) { +Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, + SourceLocation Loc, const CXXScopeSpec *SS) { DeclarationNameInfo NameInfo(D->getDeclName(), Loc); - return BuildDeclRefExpr(D, Ty, NameInfo, SS); + return BuildDeclRefExpr(D, Ty, VK, NameInfo, SS); } /// BuildDeclRefExpr - Build a DeclRefExpr. ExprResult Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, + ExprValueKind VK, const DeclarationNameInfo &NameInfo, const CXXScopeSpec *SS) { if (Context.getCanonicalType(Ty) == Context.UndeducedAutoTy) { @@ -785,7 +786,7 @@ Sema::BuildDeclRefExpr(ValueDecl *D, QualType Ty, return Owned(DeclRefExpr::Create(Context, SS? (NestedNameSpecifier *)SS->getScopeRep() : 0, SS? SS->getRange() : SourceRange(), - D, NameInfo, Ty)); + D, NameInfo, Ty, VK)); } /// \brief Given a field that represents a member of an anonymous @@ -845,8 +846,9 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, // BaseObject is an anonymous struct/union variable (and is, // therefore, not part of another non-anonymous record). MarkDeclarationReferenced(Loc, BaseObject); - BaseObjectExpr = new (Context) DeclRefExpr(BaseObject,BaseObject->getType(), - Loc); + BaseObjectExpr = + new (Context) DeclRefExpr(BaseObject, BaseObject->getType(), + VK_LValue, Loc); BaseQuals = Context.getCanonicalType(BaseObject->getType()).getQualifiers(); } else if (BaseObjectExpr) { @@ -899,13 +901,14 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, for (llvm::SmallVector<FieldDecl *, 4>::reverse_iterator FI = AnonFields.rbegin(), FIEnd = AnonFields.rend(); FI != FIEnd; ++FI) { - QualType MemberType = (*FI)->getType(); + FieldDecl *Field = *FI; + QualType MemberType = Field->getType(); Qualifiers MemberTypeQuals = Context.getCanonicalType(MemberType).getQualifiers(); // CVR attributes from the base are picked up by members, // except that 'mutable' members don't pick up 'const'. - if ((*FI)->isMutable()) + if (Field->isMutable()) ResultQuals.removeConst(); // GC attributes are never picked up by members. @@ -922,7 +925,9 @@ Sema::BuildAnonymousStructUnionMemberReference(SourceLocation Loc, PerformObjectMemberConversion(Result, /*FIXME:Qualifier=*/0, *FI, *FI); // FIXME: Might this end up being a qualified name? Result = new (Context) MemberExpr(Result, BaseObjectIsPointer, *FI, - OpLoc, MemberType); + OpLoc, MemberType, VK_LValue, + Field->isBitField() ? + OK_BitField : OK_Ordinary); BaseObjectIsPointer = false; ResultQuals = NewQuals; } @@ -1526,7 +1531,8 @@ ExprResult Sema::ActOnIdExpression(Scope *S, if (const FunctionProtoType *Proto = T->getAs<FunctionProtoType>()) NoProtoType = Context.getFunctionNoProtoType(Proto->getResultType(), Proto->getExtInfo()); - return BuildDeclRefExpr(Func, NoProtoType, NameLoc, &SS); + // Note that functions are r-values in C. + return BuildDeclRefExpr(Func, NoProtoType, VK_RValue, NameLoc, &SS); } } @@ -1916,6 +1922,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo, QualType Ty, + ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = 0) { NestedNameSpecifier *Qualifier = 0; SourceRange QualifierRange; @@ -1926,7 +1933,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, return MemberExpr::Create(C, Base, isArrow, Qualifier, QualifierRange, Member, FoundDecl, MemberNameInfo, - TemplateArgs, Ty); + TemplateArgs, Ty, VK, OK); } /// Builds an implicit member access expression. The current context @@ -2083,6 +2090,18 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, return Owned(ULE); } +static ExprValueKind getValueKindForDecl(ASTContext &Context, + const ValueDecl *D) { + if (isa<VarDecl>(D) || isa<FieldDecl>(D)) return VK_LValue; + if (!Context.getLangOptions().CPlusPlus) return VK_RValue; + if (isa<FunctionDecl>(D)) { + if (isa<CXXMethodDecl>(D) && cast<CXXMethodDecl>(D)->isInstance()) + return VK_RValue; + return VK_LValue; + } + return Expr::getValueKindForType(D->getType()); +} + /// \brief Complete semantic analysis for a reference to the given declaration. ExprResult @@ -2126,6 +2145,8 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, if (VD->isInvalidDecl()) return ExprError(); + ExprValueKind VK = getValueKindForDecl(Context, VD); + // If the identifier reference is inside a block, and it refers to a value // that is outside the block, create a BlockDeclRefExpr instead of a // DeclRefExpr. This ensures the value is treated as a copy-in snapshot when @@ -2150,6 +2171,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, MarkDeclarationReferenced(Loc, VD); QualType ExprTy = VD->getType().getNonReferenceType(); + // The BlocksAttr indicates the variable is bound by-reference. bool byrefVar = (VD->getAttr<BlocksAttr>() != 0); QualType T = VD->getType(); @@ -2160,17 +2182,17 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, bool constAdded = !ExprTy.isConstQualified(); // Variable will be bound by-copy, make it const within the closure. ExprTy.addConst(); - BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, false, - constAdded); + BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, VK, + Loc, false, constAdded); } else - BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, Loc, true); + BDRE = new (Context) BlockDeclRefExpr(VD, ExprTy, VK, Loc, true); if (getLangOptions().CPlusPlus) { if (!T->isDependentType() && !T->isReferenceType()) { Expr *E = new (Context) DeclRefExpr(const_cast<ValueDecl*>(BDRE->getDecl()), T, - SourceLocation()); + VK, SourceLocation()); if (T->getAs<RecordType>()) if (!T->isUnionType()) { ExprResult Res = PerformCopyInitialization( @@ -2191,7 +2213,7 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, // If this reference is not in a block or if the referenced variable is // within the block, create a normal DeclRefExpr. - return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), + return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), VK, NameInfo, &SS); } @@ -2624,7 +2646,9 @@ Sema::ActOnArraySubscriptExpr(Scope *S, Expr *Base, SourceLocation LLoc, if (getLangOptions().CPlusPlus && (LHSExp->isTypeDependent() || RHSExp->isTypeDependent())) { return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, - Context.DependentTy, RLoc)); + Context.DependentTy, + VK_LValue, OK_Ordinary, + RLoc)); } if (getLangOptions().CPlusPlus && @@ -2651,6 +2675,8 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, DefaultFunctionArrayLvalueConversion(RHSExp); QualType LHSTy = LHSExp->getType(), RHSTy = RHSExp->getType(); + ExprValueKind VK = VK_LValue; + ExprObjectKind OK = OK_Ordinary; // C99 6.5.2.1p2: the expression e1[e2] is by definition precisely equivalent // to the expression *((e1)+(e2)). This means the array "Base" may actually be @@ -2685,6 +2711,9 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, } else if (const VectorType *VTy = LHSTy->getAs<VectorType>()) { BaseExpr = LHSExp; // vectors: V[123] IndexExpr = RHSExp; + VK = LHSExp->getValueKind(); + if (VK != VK_RValue) + OK = OK_VectorComponent; // FIXME: need to deal with const... ResultType = VTy->getElementType(); @@ -2756,7 +2785,7 @@ Sema::CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, } return Owned(new (Context) ArraySubscriptExpr(LHSExp, RHSExp, - ResultType, RLoc)); + ResultType, VK, OK, RLoc)); } QualType Sema:: @@ -3240,11 +3269,17 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return BuildAnonymousStructUnionMemberReference(MemberLoc, FD, BaseExpr, OpLoc); + // x.a is an l-value if 'a' has a reference type. Otherwise: + // x.a is an l-value/x-value/pr-value if the base is (and note + // that *x is always an l-value). + ExprValueKind VK = IsArrow ? VK_LValue : BaseExpr->getValueKind(); + // Figure out the type of the member; see C99 6.5.2.3p3, C++ [expr.ref] QualType MemberType = FD->getType(); - if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) + if (const ReferenceType *Ref = MemberType->getAs<ReferenceType>()) { MemberType = Ref->getPointeeType(); - else { + VK = VK_LValue; + } else { Qualifiers BaseQuals = BaseType.getQualifiers(); BaseQuals.removeObjCGCAttr(); if (FD->isMutable()) BaseQuals.removeConst(); @@ -3262,28 +3297,34 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return ExprError(); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, FD, FoundDecl, MemberNameInfo, - MemberType)); + MemberType, VK, + FD->isBitField() ? OK_BitField : OK_Ordinary)); } if (VarDecl *Var = dyn_cast<VarDecl>(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, Var); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, Var, FoundDecl, MemberNameInfo, - Var->getType().getNonReferenceType())); + Var->getType().getNonReferenceType(), + Expr::getValueKindForType(Var->getType()), + OK_Ordinary)); } - if (FunctionDecl *MemberFn = dyn_cast<FunctionDecl>(MemberDecl)) { + if (CXXMethodDecl *MemberFn = dyn_cast<CXXMethodDecl>(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, MemberFn, FoundDecl, MemberNameInfo, - MemberFn->getType())); + MemberFn->getType(), + MemberFn->isInstance() ? VK_RValue : VK_LValue, + OK_Ordinary)); } + assert(!isa<FunctionDecl>(MemberDecl) && "member function not C++ method?"); if (EnumConstantDecl *Enum = dyn_cast<EnumConstantDecl>(MemberDecl)) { MarkDeclarationReferenced(MemberLoc, MemberDecl); return Owned(BuildMemberExpr(Context, BaseExpr, IsArrow, SS, Enum, FoundDecl, MemberNameInfo, - Enum->getType())); + Enum->getType(), VK_RValue, OK_Ordinary)); } Owned(BaseExpr); @@ -3435,7 +3476,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, PType = (*(Setter->param_end() -1))->getType(); // FIXME: we must check that the setter has property type. return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, - PType, + PType, VK_LValue, + OK_ObjCProperty, Setter, MemberLoc, BaseExpr)); } return ExprError(Diag(MemberLoc, diag::err_property_not_found) @@ -3599,6 +3641,7 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, return ExprError(); return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), + VK_LValue, OK_ObjCProperty, MemberLoc, BaseExpr)); } @@ -3615,6 +3658,8 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, SMD = dyn_cast<ObjCMethodDecl>(SDecl); QualType PType = OMD->getSendResultType(); return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(OMD, PType, + VK_LValue, + OK_ObjCProperty, SMD, MemberLoc, BaseExpr)); @@ -3647,7 +3692,9 @@ Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr, QualType ret = CheckExtVectorComponent(BaseType, OpLoc, Member, MemberLoc); if (ret.isNull()) return ExprError(); - return Owned(new (Context) ExtVectorElementExpr(ret, BaseExpr, *Member, + return Owned(new (Context) ExtVectorElementExpr(ret, + BaseExpr->getValueKind(), + BaseExpr, *Member, MemberLoc)); } @@ -3959,7 +4006,7 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, } return Owned(new (Context) CallExpr(Context, Fn, 0, 0, Context.VoidTy, - RParenLoc)); + VK_RValue, RParenLoc)); } // Determine whether this is a dependent call inside a C++ template, @@ -3974,7 +4021,8 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, if (Dependent) return Owned(new (Context) CallExpr(Context, Fn, Args, NumArgs, - Context.DependentTy, RParenLoc)); + Context.DependentTy, VK_RValue, + RParenLoc)); // Determine whether this is a call to an object (C++ [over.call.object]). if (Fn->getType()->isRecordType()) @@ -4014,10 +4062,11 @@ Sema::ActOnCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, if (const FunctionProtoType *FPT = BO->getType()->getAs<FunctionProtoType>()) { QualType ResultTy = FPT->getCallResultType(Context); + ExprValueKind VK = Expr::getValueKindForType(FPT->getResultType()); CXXMemberCallExpr *TheCall = new (Context) CXXMemberCallExpr(Context, BO, Args, - NumArgs, ResultTy, + NumArgs, ResultTy, VK, RParenLoc); if (CheckCallReturnType(FPT->getResultType(), @@ -4081,6 +4130,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, CallExpr *TheCall = new (Context) CallExpr(Context, Fn, Args, NumArgs, Context.BoolTy, + VK_RValue, RParenLoc); const FunctionType *FuncT; @@ -4108,6 +4158,7 @@ Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl, // We know the result type of the call, set it. TheCall->setType(FuncT->getCallResultType(Context)); + TheCall->setValueKind(Expr::getValueKindForType(FuncT->getResultType())); if (const FunctionProtoType *Proto = dyn_cast<FunctionProtoType>(FuncT)) { if (ConvertArgumentsForCall(TheCall, Fn, FDecl, Proto, Args, NumArgs, @@ -4243,8 +4294,11 @@ Sema::BuildCompoundLiteralExpr(SourceLocation LParenLoc, TypeSourceInfo *TInfo, return ExprError(); } + // In C, compound literals are l-values for some reason. + ExprValueKind VK = getLangOptions().CPlusPlus ? VK_RValue : VK_LValue; + return Owned(new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, - literalExpr, isFileScope)); + VK, literalExpr, isFileScope)); } ExprResult @@ -4388,16 +4442,18 @@ static CastKind PrepareScalarCast(Sema &S, Expr *&Src, QualType DestTy) { } /// CheckCastTypes - Check type constraints for casting between types. -bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, - CastKind& Kind, - CXXCastPath &BasePath, - bool FunctionalStyle) { +bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, + Expr *&castExpr, CastKind& Kind, ExprValueKind &VK, + CXXCastPath &BasePath, bool FunctionalStyle) { if (getLangOptions().CPlusPlus) return CXXCheckCStyleCast(SourceRange(TyR.getBegin(), castExpr->getLocEnd()), - castType, castExpr, Kind, BasePath, + castType, VK, castExpr, Kind, BasePath, FunctionalStyle); + // We only support r-value casts in C. + VK = VK_RValue; + DefaultFunctionArrayLvalueConversion(castExpr); // C99 6.5.4p2: the cast type needs to be void or scalar and the expression @@ -4574,14 +4630,15 @@ ExprResult Sema::BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *castExpr) { CastKind Kind = CK_Invalid; + ExprValueKind VK = VK_RValue; CXXCastPath BasePath; if (CheckCastTypes(SourceRange(LParenLoc, RParenLoc), Ty->getType(), castExpr, - Kind, BasePath)) + Kind, VK, BasePath)) return ExprError(); return Owned(CStyleCastExpr::Create(Context, Ty->getType().getNonLValueExprType(Context), - Kind, castExpr, &BasePath, Ty, + VK, Kind, castExpr, &BasePath, Ty, LParenLoc, RParenLoc)); } @@ -4669,7 +4726,7 @@ ExprResult Sema::ActOnParenOrParenListExpr(SourceLocation L, /// In that case, lhs = cond. /// C99 6.5.15 QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, - Expr *&SAVE, + Expr *&SAVE, ExprValueKind &VK, SourceLocation QuestionLoc) { // If both LHS and RHS are overloaded functions, try to resolve them. if (Context.hasSameType(LHS->getType(), RHS->getType()) && @@ -4688,7 +4745,9 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, // C++ is sufficiently different to merit its own checker. if (getLangOptions().CPlusPlus) - return CXXCheckConditionalOperands(Cond, LHS, RHS, SAVE, QuestionLoc); + return CXXCheckConditionalOperands(Cond, LHS, RHS, SAVE, VK, QuestionLoc); + + VK = VK_RValue; UsualUnaryConversions(Cond); if (SAVE) { @@ -5053,15 +5112,16 @@ ExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc, LHSExpr = SAVEExpr = CondExpr; } + ExprValueKind VK = VK_RValue; QualType result = CheckConditionalOperands(CondExpr, LHSExpr, RHSExpr, - SAVEExpr, QuestionLoc); + SAVEExpr, VK, QuestionLoc); if (result.isNull()) return ExprError(); return Owned(new (Context) ConditionalOperator(CondExpr, QuestionLoc, LHSExpr, ColonLoc, RHSExpr, SAVEExpr, - result)); + result, VK)); } // CheckPointerTypesForAssignment - This is a very tricky routine (despite @@ -5499,7 +5559,7 @@ static void ConstructTransparentUnion(ASTContext &C, Expr *&E, // union type from this initializer list. TypeSourceInfo *unionTInfo = C.getTrivialTypeSourceInfo(UnionType); E = new (C) CompoundLiteralExpr(SourceLocation(), unionTInfo, UnionType, - Initializer, false); + VK_RValue, Initializer, false); } Sema::AssignConvertType @@ -6649,6 +6709,12 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, LHSType->isObjCObjectPointerType()))) ConvTy = Compatible; + if (ConvTy == Compat |