diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 15 | ||||
-rw-r--r-- | clang/lib/AST/DeclTemplate.cpp | 1 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 62 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 34 | ||||
-rw-r--r-- | clang/lib/AST/ExprClassification.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/StmtDumper.cpp | 32 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGBlocks.cpp | 28 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGObjC.cpp | 8 | ||||
-rw-r--r-- | clang/lib/Rewrite/RewriteObjC.cpp | 152 | ||||
-rw-r--r-- | clang/lib/Sema/SemaCXXCast.cpp | 55 | ||||
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 5 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 35 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 218 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 76 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprObjC.cpp | 57 | ||||
-rw-r--r-- | clang/lib/Sema/SemaObjCProperty.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 108 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 20 | ||||
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 54 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReaderStmt.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTWriterStmt.cpp | 6 |
21 files changed, 624 insertions, 368 deletions
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 159a2695348..b4edc5f22bf 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -2813,7 +2813,7 @@ Expr *ASTNodeImporter::VisitDeclRefExpr(DeclRefExpr *E) { Importer.Import(E->getQualifierRange()), ToD, Importer.Import(E->getLocation()), - T, + T, E->getValueKind(), /*FIXME:TemplateArgs=*/0); } @@ -2858,7 +2858,8 @@ Expr *ASTNodeImporter::VisitUnaryOperator(UnaryOperator *E) { return 0; return new (Importer.getToContext()) UnaryOperator(SubExpr, E->getOpcode(), - T, + T, E->getValueKind(), + E->getObjectKind(), Importer.Import(E->getOperatorLoc())); } @@ -2900,7 +2901,8 @@ Expr *ASTNodeImporter::VisitBinaryOperator(BinaryOperator *E) { return 0; return new (Importer.getToContext()) BinaryOperator(LHS, RHS, E->getOpcode(), - T, + T, E->getValueKind(), + E->getObjectKind(), Importer.Import(E->getOperatorLoc())); } @@ -2927,7 +2929,9 @@ Expr *ASTNodeImporter::VisitCompoundAssignOperator(CompoundAssignOperator *E) { return new (Importer.getToContext()) CompoundAssignOperator(LHS, RHS, E->getOpcode(), - T, CompLHSType, CompResultType, + T, E->getValueKind(), + E->getObjectKind(), + CompLHSType, CompResultType, Importer.Import(E->getOperatorLoc())); } @@ -2972,7 +2976,8 @@ Expr *ASTNodeImporter::VisitCStyleCastExpr(CStyleCastExpr *E) { if (ImportCastPath(E, BasePath)) return 0; - return CStyleCastExpr::Create(Importer.getToContext(), T, E->getCastKind(), + return CStyleCastExpr::Create(Importer.getToContext(), T, + E->getValueKind(), E->getCastKind(), SubExpr, &BasePath, TInfo, Importer.Import(E->getLParenLoc()), Importer.Import(E->getRParenLoc())); diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index cce434364fa..f21c9a3af32 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -318,6 +318,7 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() { dyn_cast<NonTypeTemplateParmDecl>(*Param)) { Expr *E = new (Context) DeclRefExpr(NTTP, NTTP->getType().getNonLValueExprType(Context), + Expr::getValueKindForType(NTTP->getType()), NTTP->getLocation()); TemplateArgs.push_back(TemplateArgument(E)); } else { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index b03594f8f98..c9206110753 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -194,8 +194,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, SourceLocation NameLoc, const TemplateArgumentListInfo *TemplateArgs, - QualType T) - : Expr(DeclRefExprClass, T, false, false), + QualType T, ExprValueKind VK) + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -216,8 +216,8 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifier *Qualifier, SourceRange QualifierRange, ValueDecl *D, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, - QualType T) - : Expr(DeclRefExprClass, T, false, false), + QualType T, ExprValueKind VK) + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false), DecoratedD(D, (Qualifier? HasQualifierFlag : 0) | (TemplateArgs ? HasExplicitTemplateArgumentListFlag : 0)), @@ -240,10 +240,11 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, ValueDecl *D, SourceLocation NameLoc, QualType T, + ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs) { return Create(Context, Qualifier, QualifierRange, D, DeclarationNameInfo(D->getDeclName(), NameLoc), - T, TemplateArgs); + T, VK, TemplateArgs); } DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, @@ -252,6 +253,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, ValueDecl *D, const DeclarationNameInfo &NameInfo, QualType T, + ExprValueKind VK, const TemplateArgumentListInfo *TemplateArgs) { std::size_t Size = sizeof(DeclRefExpr); if (Qualifier != 0) @@ -262,7 +264,7 @@ DeclRefExpr *DeclRefExpr::Create(ASTContext &Context, void *Mem = Context.Allocate(Size, llvm::alignOf<DeclRefExpr>()); return new (Mem) DeclRefExpr(Qualifier, QualifierRange, D, NameInfo, - TemplateArgs, T); + TemplateArgs, T, VK); } DeclRefExpr *DeclRefExpr::CreateEmpty(ASTContext &Context, bool HasQualifier, @@ -592,8 +594,9 @@ OverloadedOperatorKind UnaryOperator::getOverloadedOperator(Opcode Opc) { //===----------------------------------------------------------------------===// CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, - unsigned numargs, QualType t, SourceLocation rparenloc) - : Expr(SC, t, + unsigned numargs, QualType t, ExprValueKind VK, + SourceLocation rparenloc) + : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs), fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)), NumArgs(numargs) { @@ -607,8 +610,8 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, Expr **args, } CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, - QualType t, SourceLocation rparenloc) - : Expr(CallExprClass, t, + QualType t, ExprValueKind VK, SourceLocation rparenloc) + : Expr(CallExprClass, t, VK, OK_Ordinary, fn->isTypeDependent() || hasAnyTypeDependentArguments(args, numargs), fn->isValueDependent() || hasAnyValueDependentArguments(args,numargs)), NumArgs(numargs) { @@ -740,7 +743,8 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, OffsetOfNode* compsPtr, unsigned numComps, Expr** exprsPtr, unsigned numExprs, SourceLocation RParenLoc) - : Expr(OffsetOfExprClass, type, /*TypeDependent=*/false, + : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/tsi->getType()->isDependentType() || hasAnyTypeDependentArguments(exprsPtr, numExprs) || hasAnyValueDependentArguments(exprsPtr, numExprs)), @@ -771,7 +775,9 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, DeclAccessPair founddecl, DeclarationNameInfo nameinfo, const TemplateArgumentListInfo *targs, - QualType ty) { + QualType ty, + ExprValueKind vk, + ExprObjectKind ok) { std::size_t Size = sizeof(MemberExpr); bool hasQualOrFound = (qual != 0 || @@ -784,7 +790,8 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, Size += ExplicitTemplateArgumentList::sizeFor(*targs); void *Mem = C.Allocate(Size, llvm::alignOf<MemberExpr>()); - MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, ty); + MemberExpr *E = new (Mem) MemberExpr(base, isarrow, memberdecl, nameinfo, + ty, vk, ok); if (hasQualOrFound) { if (qual && qual->isDependent()) { @@ -964,7 +971,7 @@ ImplicitCastExpr *ImplicitCastExpr::CreateEmpty(ASTContext &C, CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T, - CastKind K, Expr *Op, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R) { @@ -972,7 +979,7 @@ CStyleCastExpr *CStyleCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CStyleCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CStyleCastExpr *E = - new (Buffer) CStyleCastExpr(T, K, Op, PathSize, WrittenTy, L, R); + new (Buffer) CStyleCastExpr(T, VK, K, Op, PathSize, WrittenTy, L, R); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -1089,7 +1096,7 @@ OverloadedOperatorKind BinaryOperator::getOverloadedOperator(Opcode Opc) { InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, Expr **initExprs, unsigned numInits, SourceLocation rbraceloc) - : Expr(InitListExprClass, QualType(), false, false), + : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false), InitExprs(C, numInits), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), UnionFieldInit(0), HadArrayRangeDesignator(false) @@ -2158,6 +2165,7 @@ void ExtVectorElementExpr::getEncodedElementAccess( } ObjCMessageExpr::ObjCMessageExpr(QualType T, + ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, @@ -2166,8 +2174,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) - : Expr(ObjCMessageExprClass, T, /*TypeDependent=*/false, - /*ValueDependent=*/false), + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, + /*TypeDependent=*/false, /*ValueDependent=*/false), NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass), HasMethod(Method != 0), SuperLoc(SuperLoc), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method @@ -2180,13 +2188,14 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, } ObjCMessageExpr::ObjCMessageExpr(QualType T, + ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) - : Expr(ObjCMessageExprClass, T, T->isDependentType(), + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), (T->isDependentType() || hasAnyValueDependentArguments(Args, NumArgs))), NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0), @@ -2200,13 +2209,14 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, } ObjCMessageExpr::ObjCMessageExpr(QualType T, + ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, ObjCMethodDecl *Method, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) - : Expr(ObjCMessageExprClass, T, Receiver->isTypeDependent(), + : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), (Receiver->isTypeDependent() || hasAnyValueDependentArguments(Args, NumArgs))), NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0), @@ -2220,6 +2230,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, SourceLocation SuperLoc, bool IsInstanceSuper, @@ -2231,12 +2242,13 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + NumArgs * sizeof(Expr *); void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); - return new (Mem) ObjCMessageExpr(T, LBracLoc, SuperLoc, IsInstanceSuper, + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, SuperLoc, IsInstanceSuper, SuperType, Sel, Method, Args, NumArgs, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, TypeSourceInfo *Receiver, Selector Sel, @@ -2246,11 +2258,12 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + NumArgs * sizeof(Expr *); void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); - return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args, NumArgs, RBracLoc); } ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, + ExprValueKind VK, SourceLocation LBracLoc, Expr *Receiver, Selector Sel, @@ -2260,7 +2273,7 @@ ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T, unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + NumArgs * sizeof(Expr *); void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment); - return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, + return new (Mem) ObjCMessageExpr(T, VK, LBracLoc, Receiver, Sel, Method, Args, NumArgs, RBracLoc); } @@ -2343,6 +2356,7 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumIndexExprs, Expr *Init) : Expr(DesignatedInitExprClass, Ty, + Init->getValueKind(), Init->getObjectKind(), Init->isTypeDependent(), Init->isValueDependent()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { @@ -2483,7 +2497,7 @@ void DesignatedInitExpr::ExpandDesignator(ASTContext &C, unsigned Idx, ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, SourceLocation rparenloc) -: Expr(ParenListExprClass, QualType(), +: Expr(ParenListExprClass, QualType(), VK_RValue, OK_Ordinary, hasAnyTypeDependentArguments(exprs, nexprs), hasAnyValueDependentArguments(exprs, nexprs)), NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 1820ff77074..63bf2dd091c 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -116,7 +116,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, SourceLocation startLoc, SourceLocation endLoc, SourceLocation constructorLParen, SourceLocation constructorRParen) - : Expr(CXXNewExprClass, ty, ty->isDependentType(), ty->isDependentType()), + : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, + ty->isDependentType(), ty->isDependentType()), GlobalNew(globalNew), Initializer(initializer), SubExprs(0), OperatorNew(operatorNew), OperatorDelete(operatorDelete), Constructor(constructor), @@ -247,7 +248,7 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, QualType T, bool HasTemplateArgs, UnresolvedSetIterator Begin, UnresolvedSetIterator End) - : Expr(K, T, Dependent, Dependent), + : Expr(K, T, VK_LValue, OK_Ordinary, Dependent, Dependent), Results(0), NumResults(0), NameInfo(NameInfo), Qualifier(Qualifier), QualifierRange(QRange), HasExplicitTemplateArgs(HasTemplateArgs) { @@ -436,6 +437,7 @@ const char *CXXNamedCastExpr::getCastName() const { } CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, @@ -444,7 +446,7 @@ CXXStaticCastExpr *CXXStaticCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CXXStaticCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXStaticCastExpr *E = - new (Buffer) CXXStaticCastExpr(T, K, Op, PathSize, WrittenTy, L); + new (Buffer) CXXStaticCastExpr(T, VK, K, Op, PathSize, WrittenTy, L); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -457,6 +459,7 @@ CXXStaticCastExpr *CXXStaticCastExpr::CreateEmpty(ASTContext &C, } CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T, + ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, @@ -465,7 +468,7 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CXXDynamicCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXDynamicCastExpr *E = - new (Buffer) CXXDynamicCastExpr(T, K, Op, PathSize, WrittenTy, L); + new (Buffer) CXXDynamicCastExpr(T, VK, K, Op, PathSize, WrittenTy, L); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -478,14 +481,15 @@ CXXDynamicCastExpr *CXXDynamicCastExpr::CreateEmpty(ASTContext &C, } CXXReinterpretCastExpr * -CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, CastKind K, Expr *Op, +CXXReinterpretCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, + CastKind K, Expr *Op, const CXXCastPath *BasePath, TypeSourceInfo *WrittenTy, SourceLocation L) { unsigned PathSize = (BasePath ? BasePath->size() : 0); void *Buffer = C.Allocate(sizeof(CXXReinterpretCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXReinterpretCastExpr *E = - new (Buffer) CXXReinterpretCastExpr(T, K, Op, PathSize, WrittenTy, L); + new (Buffer) CXXReinterpretCastExpr(T, VK, K, Op, PathSize, WrittenTy, L); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -497,10 +501,11 @@ CXXReinterpretCastExpr::CreateEmpty(ASTContext &C, unsigned PathSize) { return new (Buffer) CXXReinterpretCastExpr(EmptyShell(), PathSize); } -CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, Expr *Op, +CXXConstCastExpr *CXXConstCastExpr::Create(ASTContext &C, QualType T, + ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L) { - return new (C) CXXConstCastExpr(T, Op, WrittenTy, L); + return new (C) CXXConstCastExpr(T, VK, Op, WrittenTy, L); } CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) { @@ -508,7 +513,7 @@ CXXConstCastExpr *CXXConstCastExpr::CreateEmpty(ASTContext &C) { } CXXFunctionalCastExpr * -CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, +CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, ExprValueKind VK, TypeSourceInfo *Written, SourceLocation L, CastKind K, Expr *Op, const CXXCastPath *BasePath, SourceLocation R) { @@ -516,7 +521,7 @@ CXXFunctionalCastExpr::Create(ASTContext &C, QualType T, void *Buffer = C.Allocate(sizeof(CXXFunctionalCastExpr) + PathSize * sizeof(CXXBaseSpecifier*)); CXXFunctionalCastExpr *E = - new (Buffer) CXXFunctionalCastExpr(T, Written, L, K, Op, PathSize, R); + new (Buffer) CXXFunctionalCastExpr(T, VK, Written, L, K, Op, PathSize, R); if (PathSize) E->setCastPath(*BasePath); return E; } @@ -592,7 +597,7 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, bool ZeroInitialization, ConstructionKind ConstructKind, SourceRange ParenRange) -: Expr(SC, T, +: Expr(SC, T, VK_RValue, OK_Ordinary, T->isDependentType(), (T->isDependentType() || CallExpr::hasAnyValueDependentArguments(args, numargs))), @@ -615,7 +620,8 @@ CXXExprWithTemporaries::CXXExprWithTemporaries(ASTContext &C, CXXTemporary **temps, unsigned numtemps) : Expr(CXXExprWithTemporariesClass, subexpr->getType(), - subexpr->isTypeDependent(), subexpr->isValueDependent()), + subexpr->getValueKind(), subexpr->getObjectKind(), + subexpr->isTypeDependent(), subexpr->isValueDependent()), SubExpr(subexpr), Temps(0), NumTemps(0) { if (numtemps) { setNumTemporaries(C, numtemps); @@ -671,6 +677,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, SourceLocation RParenLoc) : Expr(CXXUnresolvedConstructExprClass, Type->getType().getNonReferenceType(), + VK_RValue, OK_Ordinary, Type->getType()->isDependentType(), true), Type(Type), LParenLoc(LParenLoc), @@ -722,7 +729,8 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) - : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, true, true), + : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, + VK_LValue, OK_Ordinary, true, true), Base(Base), BaseType(BaseType), IsArrow(IsArrow), HasExplicitTemplateArgs(TemplateArgs != 0), OperatorLoc(OperatorLoc), diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp index 60fbfd298f1..4677910798f 100644 --- a/clang/lib/AST/ExprClassification.cpp +++ b/clang/lib/AST/ExprClassification.cpp @@ -292,9 +292,7 @@ static Cl::Kinds ClassifyInternal(ASTContext &Ctx, const Expr *E) { } case Expr::CXXUuidofExprClass: - // Assume that Microsoft's __uuidof returns an lvalue, like typeid does. - // FIXME: Is this really the case? - return Cl::CL_LValue; + return Cl::CL_PRValue; } llvm_unreachable("unhandled expression kind in classification"); diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index afc9b509e7b..15a8d61c885 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -105,10 +105,27 @@ namespace { << " " << (void*)Node; DumpSourceRange(Node); } + void DumpValueKind(ExprValueKind K) { + switch (K) { + case VK_RValue: break; + case VK_LValue: OS << " lvalue"; break; + case VK_XValue: OS << " xvalue"; break; + } + } + void DumpObjectKind(ExprObjectKind K) { + switch (K) { + case OK_Ordinary: break; + case OK_BitField: OS << " bitfield"; break; + case OK_ObjCProperty: OS << " objcproperty"; break; + case OK_VectorComponent: OS << " vectorcomponent"; break; + } + } void DumpExpr(const Expr *Node) { DumpStmt(Node); OS << ' '; DumpType(Node->getType()); + DumpValueKind(Node->getValueKind()); + DumpObjectKind(Node->getObjectKind()); } void DumpSourceRange(const Stmt *Node); void DumpLocation(SourceLocation Loc); @@ -122,7 +139,6 @@ namespace { // Exprs void VisitExpr(Expr *Node); void VisitCastExpr(CastExpr *Node); - void VisitImplicitCastExpr(ImplicitCastExpr *Node); void VisitDeclRefExpr(DeclRefExpr *Node); void VisitPredefinedExpr(PredefinedExpr *Node); void VisitCharacterLiteral(CharacterLiteral *Node); @@ -344,20 +360,6 @@ void StmtDumper::VisitCastExpr(CastExpr *Node) { OS << ">"; } -void StmtDumper::VisitImplicitCastExpr(ImplicitCastExpr *Node) { - VisitCastExpr(Node); - switch (Node->getValueKind()) { - case VK_LValue: - OS << " lvalue"; - break; - case VK_XValue: - OS << " xvalue"; - break; - case VK_RValue: - break; - } -} - void StmtDumper::VisitDeclRefExpr(DeclRefExpr *Node) { DumpExpr(Node); diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp index c40cfaf6a97..8f3e0a63263 100644 --- a/clang/lib/CodeGen/CGBlocks.cpp +++ b/clang/lib/CodeGen/CGBlocks.cpp @@ -161,7 +161,7 @@ static void AllocateAllBlockDeclRefs(CodeGenFunction &CGF, CGBlockInfo &Info) { if (Info.NeedsObjCSelf) { ValueDecl *Self = cast<ObjCMethodDecl>(CGF.CurFuncDecl)->getSelfDecl(); BlockDeclRefExpr *BDRE = - new (CGF.getContext()) BlockDeclRefExpr(Self, Self->getType(), + new (CGF.getContext()) BlockDeclRefExpr(Self, Self->getType(), VK_RValue, SourceLocation(), false); Info.DeclRefs.push_back(BDRE); CGF.AllocateBlockDecl(BDRE); @@ -344,26 +344,26 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { if (BDRE->getCopyConstructorExpr()) { E = BDRE->getCopyConstructorExpr(); PushDestructorCleanup(E->getType(), Addr); - } - else { - E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD), - VD->getType().getNonReferenceType(), - SourceLocation()); - if (VD->getType()->isReferenceType()) { - E = new (getContext()) - UnaryOperator(const_cast<Expr*>(E), UO_AddrOf, - getContext().getPointerType(E->getType()), - SourceLocation()); - } + } else { + E = new (getContext()) DeclRefExpr(const_cast<ValueDecl*>(VD), + VD->getType().getNonReferenceType(), + Expr::getValueKindForType(VD->getType()), + SourceLocation()); + if (VD->getType()->isReferenceType()) { + E = new (getContext()) + UnaryOperator(const_cast<Expr*>(E), UO_AddrOf, + getContext().getPointerType(E->getType()), + VK_RValue, OK_Ordinary, SourceLocation()); } } } + } if (BDRE->isByRef()) { E = new (getContext()) UnaryOperator(const_cast<Expr*>(E), UO_AddrOf, getContext().getPointerType(E->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, SourceLocation()); } RValue r = EmitAnyExpr(E, AggValueSlot::forAddr(Addr, false, true)); @@ -932,7 +932,7 @@ CharUnits BlockFunction::getBlockOffset(CharUnits Size, CharUnits Align) { 0, QualType(PadTy), 0, SC_None, SC_None); Expr *E = new (getContext()) DeclRefExpr(PadDecl, PadDecl->getType(), - SourceLocation()); + VK_LValue, SourceLocation()); BlockLayout.push_back(E); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 7c2dfe8b23b..13f4d8f7965 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -393,9 +393,9 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); ObjCIvarDecl *Ivar = PID->getPropertyIvarDecl(); - DeclRefExpr Base(Self, Self->getType(), Loc); + DeclRefExpr Base(Self, Self->getType(), VK_RValue, Loc); ParmVarDecl *ArgDecl = *OMD->param_begin(); - DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), Loc); + DeclRefExpr Arg(ArgDecl, ArgDecl->getType(), VK_LValue, Loc); ObjCIvarRefExpr IvarRef(Ivar, Ivar->getType(), Loc, &Base, true, true); // The property type can differ from the ivar type in some situations with @@ -406,11 +406,11 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, Ivar->getType(), CK_BitCast, &Arg, VK_RValue); BinaryOperator Assign(&IvarRef, &ArgCasted, BO_Assign, - Ivar->getType(), Loc); + Ivar->getType(), VK_RValue, OK_Ordinary, Loc); EmitStmt(&Assign); } else { BinaryOperator Assign(&IvarRef, &Arg, BO_Assign, - Ivar->getType(), Loc); + Ivar->getType(), VK_RValue, OK_Ordinary, Loc); EmitStmt(&Assign); } } diff --git a/clang/lib/Rewrite/RewriteObjC.cpp b/clang/lib/Rewrite/RewriteObjC.cpp index a32b434a95c..7987c65ad21 100644 --- a/clang/lib/Rewrite/RewriteObjC.cpp +++ b/clang/lib/Rewrite/RewriteObjC.cpp @@ -456,7 +456,7 @@ namespace { CStyleCastExpr* NoTypeInfoCStyleCastExpr(ASTContext *Ctx, QualType Ty, CastKind Kind, Expr *E) { TypeSourceInfo *TInfo = Ctx->getTrivialTypeSourceInfo(Ty, SourceLocation()); - return CStyleCastExpr::Create(*Ctx, Ty, Kind, E, 0, TInfo, + return CStyleCastExpr::Create(*Ctx, Ty, VK_RValue, Kind, E, 0, TInfo, SourceLocation(), SourceLocation()); } } @@ -1265,6 +1265,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME?*/SourceLocation(), SuperLocation, /*IsInstanceSuper=*/true, @@ -1283,6 +1284,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitSetter(BinaryOperator *BinOp, Expr * MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME: */SourceLocation(), cast<Expr>(Receiver), Sel, OMD, @@ -1344,6 +1346,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { if (Super) MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME?*/SourceLocation(), SuperLocation, /*IsInstanceSuper=*/true, @@ -1359,6 +1362,7 @@ Stmt *RewriteObjC::RewritePropertyOrImplicitGetter(Expr *PropOrGetterRefExpr) { Receiver = PropGetters[Exp]; MsgExpr = ObjCMessageExpr::Create(*Context, Ty.getNonReferenceType(), + Expr::getValueKindForType(Ty), /*FIXME:*/SourceLocation(), cast<Expr>(Receiver), Sel, OMD, @@ -1420,14 +1424,15 @@ Stmt *RewriteObjC::RewriteObjCIvarRefExpr(ObjCIvarRefExpr *IV, IV->getBase()); // Don't forget the parens to enforce the proper binding. ParenExpr *PE = new (Context) ParenExpr(IV->getBase()->getLocStart(), - IV->getBase()->getLocEnd(), - castExpr); + IV->getBase()->getLocEnd(), + castExpr); replaced = true; if (IV->isFreeIvar() && CurMethodDef->getClassInterface() == iFaceDecl->getDecl()) { MemberExpr *ME = new (Context) MemberExpr(PE, true, D, - IV->getLocation(), - D->getType()); + IV->getLocation(), + D->getType(), + VK_LValue, OK_Ordinary); // delete IV; leak for now, see RewritePropertyOrImplicitSetter() usage for more info. return ME; } @@ -2135,7 +2140,8 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( QualType msgSendType = FD->getType(); // Create a reference to the objc_msgSend() declaration. - DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, msgSendType, SourceLocation()); + DeclRefExpr *DRE = + new (Context) DeclRefExpr(FD, msgSendType, VK_LValue, SourceLocation()); // Now, we cast the reference to a pointer to the objc_msgSend type. QualType pToFunc = Context->getPointerType(msgSendType); @@ -2147,7 +2153,8 @@ CallExpr *RewriteObjC::SynthesizeCallToFunctionDecl( CallExpr *Exp = new (Context) CallExpr(*Context, ICE, args, nargs, - FT->getCallResultType(*Context), EndLoc); + FT->getCallResultType(*Context), + VK_RValue, EndLoc); return Exp; } @@ -2662,10 +2669,12 @@ Stmt *RewriteObjC::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) { VarDecl *NewVD = VarDecl::Create(*Context, TUDecl, SourceLocation(), &Context->Idents.get(S), strType, 0, SC_Static, SC_None); - DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, SourceLocation()); + DeclRefExpr *DRE = new (Context) DeclRefExpr(NewVD, strType, VK_LValue, + SourceLocation()); Expr *Unop = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, + SourceLocation()); // cast to NSConstantString * CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Exp->getType(), CK_BitCast, Unop); @@ -2784,8 +2793,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), CK_BitCast, new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), - Context->getObjCIdType(), - SourceLocation())) + Context->getObjCIdType(), + VK_RValue, + SourceLocation())) ); // set the 'receiver'. // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) @@ -2824,10 +2834,12 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SynthSuperContructorFunctionDecl(); // Simulate a contructor call... DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, - superType, SourceLocation()); + superType, VK_LValue, + SourceLocation()); SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), - superType, SourceLocation()); + superType, VK_LValue, + SourceLocation()); // The code for super is a little tricky to prevent collision with // the structure definition in the header. The rewriter has it's own // internal definition (__rw_objc_super) that is uses. This is why @@ -2836,7 +2848,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, + SourceLocation()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), CK_BitCast, SuperRep); @@ -2849,11 +2862,13 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, TypeSourceInfo *superTInfo = Context->getTrivialTypeSourceInfo(superType); SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, - superType, ILE, false); + superType, VK_LValue, + ILE, false); // struct objc_super * SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, + SourceLocation()); } MsgExprs.push_back(SuperRep); break; @@ -2890,8 +2905,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(), CK_BitCast, new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(), - Context->getObjCIdType(), - SourceLocation())) + Context->getObjCIdType(), + VK_RValue, SourceLocation())) ); // set the 'receiver'. // (id)class_getSuperclass((Class)objc_getClass("CurrentClass")) @@ -2929,10 +2944,11 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, SynthSuperContructorFunctionDecl(); // Simulate a contructor call... DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl, - superType, SourceLocation()); + superType, VK_LValue, + SourceLocation()); SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), - superType, SourceLocation()); + superType, VK_LValue, SourceLocation()); // The code for super is a little tricky to prevent collision with // the structure definition in the header. The rewriter has it's own // internal definition (__rw_objc_super) that is uses. This is why @@ -2941,6 +2957,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // SuperRep = new (Context) UnaryOperator(SuperRep, UO_AddrOf, Context->getPointerType(SuperRep->getType()), + VK_RValue, OK_Ordinary, SourceLocation()); SuperRep = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(superType), @@ -2954,7 +2971,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, TypeSourceInfo *superTInfo = Context->getTrivialTypeSourceInfo(superType); SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo, - superType, ILE, false); + superType, VK_RValue, ILE, + false); } MsgExprs.push_back(SuperRep); break; @@ -3048,7 +3066,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // Create a reference to the objc_msgSend() declaration. DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType, - SourceLocation()); + VK_LValue, SourceLocation()); // Need to cast objc_msgSend to "void *" (to workaround a GCC bandaid). // If we don't do this cast, we get the following bizarre warning/note: @@ -3075,7 +3093,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, const FunctionType *FT = msgSendType->getAs<FunctionType>(); CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], MsgExprs.size(), - FT->getResultType(), EndLoc); + FT->getResultType(), VK_RValue, + EndLoc); Stmt *ReplacingStmt = CE; if (MsgSendStretFlavor) { // We have the method which returns a struct/union. Must also generate @@ -3085,7 +3104,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, // Create a reference to the objc_msgSend_stret() declaration. DeclRefExpr *STDRE = new (Context) DeclRefExpr(MsgSendStretFlavor, msgSendType, - SourceLocation()); + VK_LValue, SourceLocation()); // Need to cast objc_msgSend_stret to "void *" (see above comment). cast = NoTypeInfoCStyleCastExpr(Context, Context->getPointerType(Context->VoidTy), @@ -3106,7 +3125,8 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, FT = msgSendType->getAs<FunctionType>(); CallExpr *STCE = new (Context) CallExpr(*Context, PE, &MsgExprs[0], MsgExprs.size(), - FT->getResultType(), SourceLocation()); + FT->getResultType(), VK_RValue, + SourceLocation()); // Build sizeof(returnType) SizeOfAlignOfExpr *sizeofExpr = new (Context) SizeOfAlignOfExpr(true, @@ -3123,16 +3143,15 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp, llvm::APInt(IntSize, 8), Context->IntTy, SourceLocation()); - BinaryOperator *lessThanExpr = new (Context) BinaryOperator(sizeofExpr, limit, - BO_LE, - Context->IntTy, - SourceLocation()); + BinaryOperator *lessThanExpr = + new (Context) BinaryOperator(sizeofExpr, limit, BO_LE, Context->IntTy, + VK_RValue, OK_Ordinary, SourceLocation()); // (sizeof(returnType) <= 8 ? objc_msgSend(...) : objc_msgSend_stret(...)) ConditionalOperator *CondExpr = new (Context) ConditionalOperator(lessThanExpr, SourceLocation(), CE, SourceLocation(), STCE, (Expr*)0, - returnType); + returnType, VK_RValue); ReplacingStmt = new (Context) ParenExpr(SourceLocation(), SourceLocation(), CondExpr); } @@ -3174,10 +3193,11 @@ Stmt *RewriteObjC::RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp) { VarDecl *VD = VarDecl::Create(*Context, TUDecl, SourceLocation(), ID, getProtocolType(), 0, SC_Extern, SC_None); - DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), SourceLocation()); + DeclRefExpr *DRE = new (Context) DeclRefExpr(VD, getProtocolType(), VK_LValue, + SourceLocation()); Expr *DerefExpr = new (Context) UnaryOperator(DRE, UO_AddrOf, Context->getPointerType(DRE->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, SourceLocation()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, DerefExpr->getType(), CK_BitCast, DerefExpr); @@ -4565,7 +4585,7 @@ void RewriteObjC::GetBlockDeclRefExprs(Stmt *S) { if (HasLocalVariableExternalStorage(DRE->getDecl())) { BlockDeclRefExpr *BDRE = new (Context)BlockDeclRefExpr(DRE->getDecl(), DRE->getType(), - DRE->getLocation(), false); + VK_LValue, DRE->getLocation(), false); BlockDeclRefs.push_back(BDRE); } @@ -4667,7 +4687,7 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { SourceLocation(), cast<Expr>(LHSStmt), SourceLocation(), cast<Expr>(RHSStmt), (Expr*)0, - Exp->getType()); + Exp->getType(), VK_RValue); return CondExpr; } else if (const ObjCIvarRefExpr *IRE = dyn_cast<ObjCIvarRefExpr>(BlockExp)) { CPT = IRE->getType()->getAs<BlockPointerType>(); @@ -4720,7 +4740,8 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { &Context->Idents.get("FuncPtr"), Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); MemberExpr *ME = new (Context) MemberExpr(PE, true, FD, SourceLocation(), - FD->getType()); + FD->getType(), VK_LValue, + OK_Ordinary); CastExpr *FunkCast = NoTypeInfoCStyleCastExpr(Context, PtrToFuncCastType, @@ -4737,7 +4758,8 @@ Stmt *RewriteObjC::SynthesizeBlockCall(CallExpr *Exp, const Expr *BlockExp) { } CallExpr *CE = new (Context) CallExpr(*Context, PE, &BlkExprs[0], BlkExprs.size(), - Exp->getType(), SourceLocation()); + Exp->getType(), VK_RValue, + SourceLocation()); return CE; } @@ -4772,7 +4794,8 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { /*BitWidth=*/0, /*Mutable=*/true); MemberExpr *ME = new (Context) MemberExpr(DeclRefExp, isArrow, FD, SourceLocation(), - FD->getType()); + FD->getType(), VK_LValue, + OK_Ordinary); llvm::StringRef Name = VD->getName(); FD = FieldDecl::Create(*Context, 0, SourceLocation(), @@ -4780,7 +4803,7 @@ Stmt *RewriteObjC::RewriteBlockDeclRefExpr(Expr *DeclRefExp) { Context->VoidPtrTy, 0, /*BitWidth=*/0, /*Mutable=*/true); ME = new (Context) MemberExpr(ME, true, FD, SourceLocation(), - DeclRefExp->getType()); + DeclRefExp->getType(), VK_LValue, OK_Ordinary); @@ -4799,8 +4822,9 @@ Stmt *RewriteObjC::RewriteLocalVariableExternalStorage(DeclRefExpr *DRE) { if (VarDecl *Var = dyn_cast<VarDecl>(VD)) if (!ImportedLocalExternalDecls.count(Var)) return DRE; - Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, - DRE->getType(), DRE->getLocation()); + Expr *Exp = new (Context) UnaryOperator(DRE, UO_Deref, DRE->getType(), + VK_LValue, OK_Ordinary, + DRE->getLocation()); // Need parens to enforce precedence. ParenExpr *PE = new (Context) ParenExpr(SourceLocation(), SourceLocation(), Exp); @@ -5335,13 +5359,14 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, // Simulate a contructor call... FD = SynthBlockInitFunctionDecl(Tag); - DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, SourceLocation()); + DeclRefExpr *DRE = new (Context) DeclRefExpr(FD, FType, VK_RValue, + SourceLocation()); llvm::SmallVector<Expr*, 4> InitExprs; // Initialize the block function. FD = SynthBlockInitFunctionDecl(Func); - DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), + DeclRefExpr *Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, SourceLocation()); CastExpr *castExpr = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, Arg); @@ -5354,12 +5379,15 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, &Context->Idents.get(DescData.c_str()), Context->VoidPtrTy, 0, SC_Static, SC_None); - UnaryOperator *DescRefExpr = new (Context) UnaryOperator( - new (Context) DeclRefExpr(NewVD, - Context->VoidPtrTy, SourceLocation()), - UO_AddrOf, - Context->getPointerType(Context->VoidPtrTy), - SourceLocation()); + UnaryOperator *DescRefExpr = + new (Context) UnaryOperator(new (Context) DeclRefExpr(NewVD, + Context->VoidPtrTy, + VK_LValue, + SourceLocation()), + UO_AddrOf, + Context->getPointerType(Context->VoidPtrTy), + VK_RValue, OK_Ordinary, + SourceLocation()); InitExprs.push_back(DescRefExpr); // Add initializers for any closure decl refs. @@ -5371,26 +5399,29 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, if (isObjCType((*I)->getType())) { // FIXME: Conform to ABI ([[obj retain] autorelease]). FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, - SourceLocation()); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation()); } } else if (isTopLevelBlockPointerType((*I)->getType())) { FD = SynthBlockInitFunctionDecl((*I)->getName()); - Arg = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Arg = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); Exp = NoTypeInfoCStyleCastExpr(Context, Context->VoidPtrTy, CK_BitCast, Arg); } else { FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); if (HasLocalVariableExternalStorage(*I)) { QualType QT = (*I)->getType(); QT = Context->getPointerType(QT); - Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, - SourceLocation()); + Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, QT, VK_RValue, + OK_Ordinary, SourceLocation()); } } @@ -5411,10 +5442,11 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, QualType castT = Context->getPointerType(Context->getTagDeclType(RD)); FD = SynthBlockInitFunctionDecl((*I)->getName()); - Exp = new (Context) DeclRefExpr(FD, FD->getType(), SourceLocation()); + Exp = new (Context) DeclRefExpr(FD, FD->getType(), VK_LValue, + SourceLocation()); Exp = new (Context) UnaryOperator(Exp, UO_AddrOf, - Context->getPointerType(Exp->getType()), - SourceLocation()); + Context->getPointerType(Exp->getType()), + VK_RValue, OK_Ordinary, SourceLocation()); Exp = NoTypeInfoCStyleCastExpr(Context, castT, CK_BitCast, Exp); InitExprs.push_back(Exp); } @@ -5429,10 +5461,10 @@ Stmt *RewriteObjC::SynthBlockInitExpr(BlockExpr *Exp, InitExprs.push_back(FlagExp); } NewRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0], InitExprs.size(), - FType, SourceLocation()); + FType, VK_LValue, SourceLocation()); NewRep = new (Context) UnaryOperator(NewRep, UO_AddrOf, Context->getPointerType(NewRep->getType()), - SourceLocation()); + VK_RValue, OK_Ordinary, SourceLocation()); NewRep = NoTypeInfoCStyleCastExpr(Context, FType, CK_BitCast, NewRep); BlockDeclRefs.clear(); diff --git a/clang/lib/Sema/SemaCXXCast.cpp b/clang/lib/Sema/SemaCXXCast.cpp index e57e89e4a48..06c2758a9bd 100644 --- a/clang/lib/Sema/SemaCXXCast.cpp +++ b/clang/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/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index d04addd2103..ed45de53f26 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f7638f80d91..77f604a6536 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/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/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 2cb92b6db68..25c27fe6285 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/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 == Compatible && + getLangOptions().ObjCNonFragileABI && + LHSType->isObjCObjectType()) + Diag(Loc, diag::err_assignment_requires_nonfragile_object) + << LHSType; + // If the RHS is a unary plus or minus, check to see if they = and + are // right next to each other. If so, the user may have typo'd "x =+ 4" // instead of "x += 4". @@ -7148,14 +7214,20 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, // The following two variables are used for compound assignment operators QualType CompLHSTy; // Type of LHS after promotions for computation QualType CompResultTy; // Type of computation result + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; switch (Opc) { case BO_Assign: ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, QualType()); + if (getLangOptions().CPlusPlus) { + VK = rhs->getValueKind(); + OK = rhs->getObjectKind(); + } break; case BO_PtrMemD: case BO_PtrMemI: - ResultTy = CheckPointerToMemberOperands(lhs, rhs, OpLoc, + ResultTy = CheckPointerToMemberOperands(lhs, rhs, VK, OpLoc, Opc == BO_PtrMemI); break; case BO_Mul: @@ -7198,7 +7270,7 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, case BO_MulAssign: case BO_DivAssign: CompResultTy = CheckMultiplyDivideOperands(lhs, rhs, OpLoc, true, - Opc == BO_DivAssign); + Opc == BO_DivAssign); CompLHSTy = CompResultTy; if (!CompResultTy.isNull()) ResultTy = CheckAssignmentOperands(lhs, rhs, OpLoc, CompResultTy); @@ -7236,21 +7308,25 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, break; case BO_Comma: ResultTy = CheckCommaOperands(lhs, rhs, OpLoc); + if (getLangOptions().CPlusPlus) { + VK = rhs->getValueKind(); + OK = rhs->getObjectKind(); + } break; } if (ResultTy.isNull()) return ExprError(); - if (ResultTy->isObjCObjectType() && LangOpts.ObjCNonFragileABI) { - if (Opc >= BO_Assign && Opc <= BO_OrAssign) - Diag(OpLoc, diag::err_assignment_requires_nonfragile_object) - << ResultTy; - } if (CompResultTy.isNull()) - return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, OpLoc)); - else - return Owned(new (Context) CompoundAssignOperator(lhs, rhs, Opc, ResultTy, - CompLHSTy, CompResultTy, - OpLoc)); + return Owned(new (Context) BinaryOperator(lhs, rhs, Opc, ResultTy, + VK, OK, OpLoc)); + + if (getLangOptions().CPlusPlus) { + VK = VK_LValue; + OK = lhs->getObjectKind(); + } + return Owned(new (Context) CompoundAssignOperator(lhs, rhs, Opc, ResultTy, + VK, OK, CompLHSTy, + CompResultTy, OpLoc)); } /// SuggestParentheses - Emit a diagnostic together with a fixit hint that wraps @@ -7470,10 +7546,15 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, Expr *Input) { UnaryOperatorKind Opc = static_cast<UnaryOperatorKind>(OpcIn); + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; QualType resultType; switch (Opc) { case UO_PreInc: case UO_PreDec: + VK = VK_LValue; + OK = Input->getObjectKind(); + // fallthrough case UO_PostInc: case UO_PostDec: resultType = CheckIncrementDecrementOperand(Input, OpLoc, @@ -7488,6 +7569,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Deref: DefaultFunctionArrayLvalueConversion(Input); resultType = CheckIndirectionOperand(Input, OpLoc); + VK = VK_LValue; break; case UO_Plus: case UO_Minus: @@ -7558,15 +7640,22 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, case UO_Real: case UO_Imag: resultType = CheckRealImagOperand(Input, OpLoc, Opc == UO_Real); + // _Real and _Imag map ordinary l-values into ordinary l-values. + if (Input->getValueKind() != VK_RValue && + Input->getObjectKind() == OK_Ordinary) + VK = Input->getValueKind(); break; case UO_Extension: resultType = Input->getType(); + VK = Input->getValueKind(); + OK = Input->getObjectKind(); break; } if (resultType.isNull()) return ExprError(); - return Owned(new (Context) UnaryOperator(Input, Opc, resultType, OpLoc)); + return Owned(new (Context) UnaryOperator(Input, Opc, resultType, + VK, OK, OpLoc)); } ExprResult Sema::BuildUnaryOp(Scope *S, SourceLocation OpLoc, @@ -7884,6 +7973,8 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, SourceLocation RPLoc) { assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)"); + ExprValueKind VK = VK_RValue; + ExprObjectKind OK = OK_Ordinary; QualType resType; bool ValueDependent = false; if (CondExpr->isTypeDependent() || CondExpr->isValueDependent()) { @@ -7899,13 +7990,16 @@ ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, << CondExpr->getSourceRange()); // If the condition is > zero, then the AST type is the same as the LSHExpr. - resType = condEval.getZExtValue() ? LHSExpr->getType() : RHSExpr->getType(); - ValueDependent = condEval.getZExtValue() ? LHSExpr->isValueDependent() - : RHSExpr->isValueDependent(); + Expr *ActiveExpr = condEval.getZExtValue() ? LHSExpr : RHSExpr; + + resType = ActiveExpr->getType(); + ValueDependent = ActiveExpr->isValueDependent(); + VK = ActiveExpr->getValueKind(); + OK = ActiveExpr->getObjectKind(); } return Owned(new (Context) ChooseExpr(BuiltinLoc, CondExpr, LHSExpr, RHSExpr, - resType, RPLoc, + resType, VK, OK, RPLoc, resType->isDependentType(), ValueDependent)); } @@ -8154,8 +8248,8 @@ ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc, } ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, - Expr *E, TypeSourceInfo *TInfo, - SourceLocation RPLoc) { + Expr *E, TypeSourceInfo *TInfo, + SourceLocation RPLoc) { Expr *OrigExpr = E; // Get the va_list type diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 70e9a97fc67..fbd36fd61d7 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -605,9 +605,10 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // if (NumExprs == 1) { CastKind Kind = CK_Invalid; + ExprValueKind VK = VK_RValue; CXXCastPath BasePath; if (CheckCastTypes(TInfo->getTypeLoc().getSourceRange(), Ty, Exprs[0], - Kind, BasePath, + Kind, VK, BasePath, /*FunctionalStyle=*/true)) return ExprError(); @@ -615,7 +616,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, return Owned(CXXFunctionalCastExpr::Create(Context, Ty.getNonLValueExprType(Context), - TInfo, TyBeginLoc, Kind, + VK, TInfo, TyBeginLoc, Kind, Exprs[0], &BasePath, RParenLoc)); } @@ -1582,8 +1583,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, /// \brief Check the use of the given variable as a C++ condition in an if, /// while, do-while, or switch statement. ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, - SourceLocation StmtLoc, - bool ConvertToBoolean) { + SourceLocation StmtLoc, + bool ConvertToBoolean) { QualType T = ConditionVar->getType(); // C++ [stmt.select]p2: @@ -1599,7 +1600,8 @@ ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, Expr *Condition = DeclRefExpr::Create(Context, 0, SourceRange(), ConditionVar, ConditionVar->getLocation(), - ConditionVar->getType().getNonReferenceType()); + ConditionVar->getType().getNonReferenceType(), + Expr::getValueKindForType(ConditionVar->getType())); if (ConvertToBoolean && CheckBooleanCondition(Condition, StmtLoc)) return ExprError(); @@ -2331,8 +2333,10 @@ ExprResult Sema::BuildUnaryTypeTrait(UnaryTypeTrait UTT, RParen, Context.BoolTy)); } -QualType Sema::CheckPointerToMemberOperands( - Expr *&lex, Expr *&rex, SourceLocation Loc, bool isIndirect) { +QualType Sema::CheckPointerToMemberOperands(Expr *&lex, Expr *&rex, + ExprValueKind &VK, + SourceLocation Loc, + bool isIndirect) { const char *OpSpelling = isIndirect ? "->*" : ".*"; // C++ 5.5p2 // The binary operator .* [p3: ->*] binds its second operand, which shall @@ -2361,7 +2365,7 @@ QualType Sema::CheckPointerToMemberOperands( QualType LType = lex->getType(); if (isIndirect) { if (const PointerType *Ptr = LType->getAs<PointerType>()) - LType = Ptr->getPointeeType().getNonReferenceType(); + LType = Ptr->getPointeeType(); else { Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling << 1 << LType @@ -2402,6 +2406,7 @@ QualType Sema::CheckPointerToMemberOperands( Diag(Loc, diag::err_pointer_to_member_type) << isIndirect; return QualType(); } + // C++ 5.5p2 // The result is an object or a function of the type specified by the // second operand. @@ -2416,6 +2421,21 @@ QualType Sema::CheckPointerToMemberOperands( // We probably need a "MemberFunctionClosureType" or something like that. QualType Result = MemPtr->getPointeeType(); Result = Context.getCVRQualifiedType(Result, LType.getCVRQualifiers()); + + // C++ [expr.mptr.oper]p6: + // The result of a .* expression whose second operand is a pointer + // to a data member is of the same value category as its + // first operand. The result of a .* expression whose second + // operand is a pointer to a member function is a prvalue. The + // result of an ->* expression is an lvalue if its second operand + // is a pointer to data member and a prvalue otherwise. + if (Result->isFunctionType()) + VK = VK_RValue; + else if (isIndirect) + VK = VK_LValue; + else + VK = lex->getValueKind(); + return Result; } @@ -2573,7 +2593,7 @@ static bool ConvertForConditional(Sema &Self, Expr *&E, QualType T) { /// See C++ [expr.cond]. Note that LHS is never null, even for the GNU x ?: y /// extension. In this case, LHS == Cond. (But they're not aliases.) QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, - Expr *&SAVE, + Expr *&SAVE, ExprValueKind &VK, SourceLocation QuestionLoc) { // FIXME: Handle C99's complex types, vector types, block pointers and Obj-C++ // interface pointers. @@ -2591,6 +2611,9 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, return QualType(); } + // Assume r-value. + VK = VK_RValue; + // Either of the arguments dependent? if (LHS->isTypeDependent() || RHS->isTypeDependent()) return Context.DependentTy; @@ -2670,19 +2693,20 @@ QualType Sema::CXXCheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, } // C++0x 5.16p4 - // If the second and third operands are lvalues and have the same type, - // the result is of that type [...] + // If the second and third operands are glvalues of the same value + // category and have the same type, the result is of that type and + // value category and it is a bit-field if the second or the third + // operand is a bit-field, or if both are bit-fields. + // We can't support the bitfield parts of that correctly right now, + // though, so we just require both sides to be ordinary values. bool Same = Context.hasSameType(LTy, RTy); - if (Same && LHS->isLvalue(Context) == Expr::LV_Valid && - RHS->isLvalue(Context) == Expr::LV_Valid) { - // In this context, property reference is really a message call and - // is not considered an l-value. - bool lhsProperty = (isa<ObjCPropertyRefExpr>(LHS) || - isa<ObjCImplicitSetterGetterRefExpr>(LHS)); - bool rhsProperty = (isa<ObjCPropertyRefExpr>(RHS) || - isa<ObjCImplicitSetterGetterRefExpr>(RHS)); - if (!lhsProperty && !rhsProperty) - return LTy; + if (Same && + LHS->getValueKind() != VK_RValue && + LHS->getValueKind() == RHS->getValueKind() && + LHS->getObjectKind() == OK_Ordinary && + RHS->getObjectKind() == OK_Ordinary) { + VK = LHS->getValueKind(); + return LTy; } // C++0x 5.16p5 @@ -3456,11 +3480,15 @@ CXXMemberCallExpr *Sema::BuildCXXMemberCallExpr(Expr *Exp, MemberExpr *ME = new (Context) MemberExpr(Exp, /*IsArrow=*/false, Method, - SourceLocation(), Method->getType()); - QualType ResultType = Method->getCallResultType(); + SourceLocation(), Method->getType(), + VK_RValue, OK_Ordinary); + QualType ResultType = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultType); + ResultType = ResultType.getNonLValueExprType(Context); + MarkDeclarationReferenced(Exp->getLocStart(), Method); CXXMemberCallExpr *CE = - new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, + new (Context) CXXMemberCallExpr(Context, ME, 0, 0, ResultType, VK, Exp->getLocEnd()); return CE; } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index be87a42a3cf..a99a72f3c85 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -199,7 +199,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Selector Sel, ObjCMethodDecl *Method, bool isClassMessage, SourceLocation lbrac, SourceLocation rbrac, - QualType &ReturnType) { + QualType &ReturnType, ExprValueKind &VK) { if (!Method) { // Apply default argument promotion as for (C99 6.5.2.2p6). for (unsigned i = 0; i != NumArgs; i++) { @@ -214,10 +214,12 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, Diag(lbrac, DiagID) << Sel << isClassMessage << SourceRange(lbrac, rbrac); ReturnType = Context.getObjCIdType(); + VK = VK_RValue; return false; } ReturnType = Method->getSendResultType(); + VK = Expr::getValueKindForType(Method->getResultType()); unsigned NumNamedArgs = Sel.getNumArgs(); // Method might have more arguments than selector indicates. This is due @@ -226,8 +228,8 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs, NumNamedArgs = Method->param_size(); // FIXME. This need be cleaned up. if (NumArgs < NumNamedArgs) { - Diag(lbrac, diag::err_typecheck_call_too_few_args) << 2 - << NumNamedArgs << NumArgs; + Diag(lbrac, diag::err_typecheck_call_too_few_args) + << 2 << NumNamedArgs << NumArgs; return false; } @@ -357,13 +359,16 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, Selector Sel = PP.getSelectorTable().getNullarySelector(Member); ObjCMethodDecl *Getter = IFace->lookupInstanceMethod(Sel); if (DiagnosePropertyAccessorMismatch(PD, Getter, MemberLoc)) - ResTy = Getter->getSendResultType(); + ResTy = Getter->getResultType(); + if (Super) return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy, + VK_LValue, OK_ObjCProperty, MemberLoc, SuperLoc, SuperType)); else return Owned(new (Context) ObjCPropertyRefExpr(PD, ResTy, + VK_LValue, OK_ObjCProperty, MemberLoc, BaseExpr)); } // Check protocols on qualified interfaces. @@ -374,11 +379,15 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, if (DiagnoseUseOfDecl(PD, MemberLoc)) return ExprError(); if (Super) - return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), - MemberLoc, - SuperLoc, SuperType)); + return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), + VK_LValue, + OK_ObjCProperty, + MemberLoc, + SuperLoc, SuperType)); else return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(), + VK_LValue, + OK_ObjCProperty, MemberLoc, BaseExpr)); } @@ -426,12 +435,12 @@ HandleExprPropertyRefExpr(const ObjCObjectPointerType *OPT, PType = Getter->getSendResultType(); if (Super) return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, - Setter, MemberLoc, - SuperLoc, SuperType)); + VK_LValue, OK_ObjCProperty, + Setter, MemberLoc, SuperLoc, SuperType)); else return Owned(new (Context) ObjCImplicitSetterGetterRefExpr(Getter, PType, - Setter, MemberLoc, - BaseExpr)); + VK_LValue, OK_ObjCProperty, + Setter, MemberLoc, BaseExpr)); } @@ -546,7 +555,8 @@ ActOnClassPropertyRefExpr(IdentifierInfo &receiverName, PType = (*PI)->getType(); } return Owned(new (Context) ObjCImplicitSetterGetterRefExpr( - Getter, PType, Setter, + Getter, PType, VK_LValue, OK_ObjCProperty, + Setter, propertyNameLoc, IFace, receiverNameLoc)); } return ExprError(Diag(propertyNameLoc, diag::err_property_not_found) @@ -751,8 +761,9 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, unsigned NumArgs = ArgsIn.size(); Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release()); assert(SuperLoc.isInvalid() && "Message to super with dependent type"); - return Owned(ObjCMessageExpr::Create(Context, ReceiverType, LBracLoc, - ReceiverTypeInfo, Sel, /*Method=*/0, + return Owned(ObjCMessageExpr::Create(Context, ReceiverType, + VK_RValue, LBracLoc, ReceiverTypeInfo, + Sel, /*Method=*/0, Args, NumArgs, RBracLoc)); } @@ -790,21 +801,23 @@ ExprResult Sema::BuildClassMessage(TypeSourceInfo *ReceiverTypeInfo, // Check the argument types and determine the result type. QualType ReturnType; + ExprValueKind VK = VK_RValue; + unsigned NumArgs = ArgsIn.size(); Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release()); if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, true, - LBracLoc, RBracLoc, ReturnType)) + LBracLoc, RBracLoc, ReturnType, VK)) return ExprError(); // Construct the appropriate ObjCMessageExpr. Expr *Result; if (SuperLoc.isValid()) - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/false, ReceiverType, Sel, Method, Args, NumArgs, RBracLoc); else - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, ReceiverTypeInfo, Sel, Method, Args, NumArgs, RBracLoc); return MaybeBindToTemporary(Result); @@ -889,7 +902,7 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release()); assert(SuperLoc.isInvalid() && "Message to super with dependent type"); return Owned(ObjCMessageExpr::Create(Context, Context.DependentTy, - LBracLoc, Receiver, Sel, + VK_RValue, LBracLoc, Receiver, Sel, /*Method=*/0, Args, NumArgs, RBracLoc)); } @@ -1050,8 +1063,9 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, unsigned NumArgs = ArgsIn.size(); Expr **Args = reinterpret_cast<Expr **>(ArgsIn.release()); QualType ReturnType; + ExprValueKind VK = VK_RValue; if (CheckMessageArgumentTypes(Args, NumArgs, Sel, Method, false, - LBracLoc, RBracLoc, ReturnType)) + LBracLoc, RBracLoc, ReturnType, VK)) return ExprError(); if (!ReturnType->isVoidType()) { @@ -1063,12 +1077,13 @@ ExprResult Sema::BuildInstanceMessage(Expr *Receiver, // Construct the appropriate ObjCMessageExpr instance. Expr *Result; if (SuperLoc.isValid()) - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, SuperLoc, /*IsInstanceSuper=*/true, ReceiverType, Sel, Method, Args, NumArgs, RBracLoc); else - Result = ObjCMessageExpr::Create(Context, ReturnType, LBracLoc, Receiver, + Result = ObjCMessageExpr::Create(Context, ReturnType, VK, LBracLoc, + Receiver, Sel, Method, Args, NumArgs, RBracLoc); return MaybeBindToTemporary(Result); } diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 65002f3ea03..607b7b1782a 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -485,8 +485,8 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // FIXME. Eventually we want to do this for Objective-C as well. ImplicitParamDecl *SelfDecl = getterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = - new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(), - SourceLocation()); + new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), + VK_RValue, SourceLocation()); Expr *IvarRefExpr = new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, SelfExpr, true, true); @@ -512,15 +512,15 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, // FIXME. Eventually we want to do this for Objective-C as well. ImplicitParamDecl *SelfDecl = setterMethod->getSelfDecl(); DeclRefExpr *SelfExpr = - new (Context) DeclRefExpr(SelfDecl,SelfDecl->getType(), - SourceLocation()); + new (Context) DeclRefExpr(SelfDecl, SelfDecl->getType(), + VK_RValue, SourceLocation()); Expr *lhs = new (Context) ObjCIvarRefExpr(Ivar, Ivar->getType(), AtLoc, SelfExpr, true, true); ObjCMethodDecl::param_iterator P = setterMethod->param_begin(); ParmVarDecl *Param = (*P); - Expr *rhs = new (Context) DeclRefExpr(Param,Param->getType(), - SourceLocation()); + Expr *rhs = new (Context) DeclRefExpr(Param, Param->getType(), + VK_LValue, SourceLocation()); ExprResult Res = BuildBinOp(S, lhs->getLocEnd(), BO_Assign, lhs, rhs); PIDecl->setSetterCXXAssignment(Res.takeAs<Expr>()); diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 65d6bc8f7a0..a0e4816683b 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -33,6 +33,16 @@ namespace clang { using namespace sema; +/// A convenience routine for creating a decayed reference to a +/// function. +static Expr * +CreateFunctionRefExpr(Sema &S, FunctionDecl *Fn, + SourceLocation Loc = SourceLocation()) { + Expr *E = new (S.Context) DeclRefExpr(Fn, Fn->getType(), VK_LValue, Loc); + S.DefaultFunctionArrayConversion(E); + return E; +} + static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType, bool InOverloadResolution, StandardConversionSequence &SCS); @@ -3895,7 +3905,7 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, // call on the stack and we don't need its arguments to be // well-formed. DeclRefExpr ConversionRef(Conversion, Conversion->getType(), - From->getLocStart()); + VK_LValue, From->getLocStart()); ImplicitCastExpr ConversionFn(ImplicitCastExpr::OnStack, Context.getPointerType(Conversion->getType()), CK_FunctionToPointerDecay, @@ -3909,10 +3919,12 @@ Sema::AddConversionCandidate(CXXConversionDecl *Conversion, return; } + ExprValueKind VK = Expr::getValueKindForType(Conversion->getConversionType()); + // Note that it is safe to allocate CallExpr on the stack here because // there are 0 arguments (i.e., nothing is allocated using ASTContext's // allocator). - CallExpr Call(Context, &ConversionFn, 0, 0, CallResultType, + CallExpr Call(Context, &ConversionFn, 0, 0, CallResultType, VK, From->getLocStart()); ImplicitConversionSequence ICS = TryCopyInitialization(*this, &Call, ToType, @@ -7086,6 +7098,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, return Owned(new (Context) UnaryOperator(Input, Opc, Context.DependentTy, + VK_RValue, OK_Ordinary, OpLoc)); CXXRecordDecl *NamingClass = 0; // because lookup ignores member operators @@ -7097,6 +7110,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, &Args[0], NumArgs, Context.DependentTy, + VK_RValue, OpLoc)); } @@ -7151,18 +7165,18 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, unsigned OpcIn, DiagnoseUseOfDecl(Best->FoundDecl, OpLoc); - // Determine the result type - QualType ResultTy = FnDecl->getCallResultType(); + // Determine the result type. + QualType ResultTy = FnDecl->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(), - SourceLocation()); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl); Args[0] = Input; CallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, Op, FnExpr, - Args, NumArgs, ResultTy, OpLoc); + Args, NumArgs, ResultTy, VK, OpLoc); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, FnDecl)) @@ -7248,10 +7262,14 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, // BinaryOperator or CompoundAssignment. if (Opc <= BO_Assign || Opc > BO_OrAssign) return Owned(new (Context) BinaryOperator(Args[0], Args[1], Opc, - Context.DependentTy, OpLoc)); + Context.DependentTy, + VK_RValue, OK_Ordinary, + OpLoc)); return Owned(new (Context) CompoundAssignOperator(Args[0], Args[1], Opc, Context.DependentTy, + VK_LValue, + OK_Ordinary, Context.DependentTy, Context.DependentTy, OpLoc)); @@ -7269,6 +7287,7 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, return Owned(new (Context) CXXOperatorCallExpr(Context, Op, Fn, Args, 2, Context.DependentTy, + VK_RValue, OpLoc)); } @@ -7362,19 +7381,17 @@ Sema::CreateOverloadedBinOp(SourceLocation OpLoc, DiagnoseUseOfDecl(Best->FoundDecl, OpLoc); - // Determine the result type - QualType ResultTy - = FnDecl->getType()->getAs<FunctionType>() - ->getCallResultType(Context); + // Determine the result type. + QualType ResultTy = FnDecl->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(), - OpLoc); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, OpLoc); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, Op, FnExpr, - Args, 2, ResultTy, OpLoc); + Args, 2, ResultTy, VK, OpLoc); if (CheckCallReturnType(FnDecl->getResultType(), OpLoc, TheCall, FnDecl)) @@ -7474,6 +7491,7 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, return Owned(new (Context) CXXOperatorCallExpr(Context, OO_Subscript, Fn, Args, 2, Context.DependentTy, + VK_RValue, RLoc)); } @@ -7521,19 +7539,17 @@ Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc, Args[1] = InputInit.takeAs<Expr>(); // Determine the result type - QualType ResultTy - = FnDecl->getType()->getAs<FunctionType>() - ->getCallResultType(Context); + QualType ResultTy = FnDecl->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); // Build the actual expression node. - Expr *FnExpr = new (Context) DeclRefExpr(FnDecl, FnDecl->getType(), - LLoc); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, FnDecl, LLoc); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Subscript, FnExpr, Args, 2, - ResultTy, RLoc); + ResultTy, VK, RLoc); if (CheckCallReturnType(FnDecl->getResultType(), LLoc, TheCall, FnDecl)) @@ -7704,11 +7720,14 @@ Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, MemExpr = cast<MemberExpr>(MemExprE->IgnoreParens()); } + QualType ResultType = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultType); + ResultType = ResultType.getNonLValueExprType(Context); + assert(Method && "Member call to something that isn't a method?"); CXXMemberCallExpr *TheCall = new (Context) CXXMemberCallExpr(Context, MemExprE, Args, NumArgs, - Method->getCallResultType(), - RParenLoc); + ResultType, VK, RParenLoc); // Check for a valid return type. if (CheckCallReturnType(Method->getResultType(), MemExpr->getMemberLoc(), @@ -7909,17 +7928,18 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) MethodArgs[ArgIdx + 1] = Args[ArgIdx]; - Expr *NewFn = new (Context) DeclRefExpr(Method, Method->getType(), - SourceLocation()); - UsualUnaryConversions(NewFn); + Expr *NewFn = CreateFunctionRefExpr(*this, Method); // Once we've built TheCall, all of the expressions are properly // owned. - QualType ResultTy = Method->getCallResultType(); + QualType ResultTy = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); + CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Call, NewFn, MethodArgs, NumArgs + 1, - ResultTy, RParenLoc); + ResultTy, VK, RParenLoc); delete [] MethodArgs; if (CheckCallReturnType(Method->getResultType(), LParenLoc, TheCall, @@ -8064,14 +8084,14 @@ Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc) { return ExprError(); // Build the operator call. - Expr *FnExpr = new (Context) DeclRefExpr(Method, Method->getType(), - SourceLocation()); - UsualUnaryConversions(FnExpr); + Expr *FnExpr = CreateFunctionRefExpr(*this, Method); - QualType ResultTy = Method->getCallResultType(); + QualType ResultTy = Method->getResultType(); + ExprValueKind VK = Expr::getValueKindForType(ResultTy); + ResultTy = ResultTy.getNonLValueExprType(Context); CXXOperatorCallExpr *TheCall = new (Context) CXXOperatorCallExpr(Context, OO_Arrow, FnExpr, - &Base, 1, ResultTy, OpLoc); + &Base, 1, ResultTy, VK, OpLoc); if (CheckCallReturnType(Method->getResultType(), OpLoc, TheCall, Method)) @@ -8140,8 +8160,9 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, QualType MemPtrType = Context.getMemberPointerType(Fn->getType(), ClassType.getTypePtr()); - return new (Context) UnaryOperator(SubExpr, UO_AddrOf, - MemPtrType, UnOp->getOperatorLoc()); + return new (Context) UnaryOperator(SubExpr, UO_AddrOf, MemPtrType, + VK_RValue, OK_Ordinary, + UnOp->getOperatorLoc()); } } Expr *SubExpr = FixOverloadedFunctionReference(UnOp->getSubExpr(), @@ -8151,6 +8172,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, return new (Context) UnaryOperator(SubExpr, UO_AddrOf, Context.getPointerType(SubExpr->getType()), + VK_RValue, OK_Ordinary, UnOp->getOperatorLoc()); } @@ -8168,6 +8190,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Fn, ULE->getNameLoc(), Fn->getType(), + VK_LValue, TemplateArgs); } @@ -8181,7 +8204,8 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Expr *Base; - // If we're filling in + // If we're filling in a static method where we used to have an + // implicit member access, rewrite to a simple decl ref. if (MemExpr->isImplicitAccess()) { if (cast<CXXMethodDecl>(Fn)->isStatic()) { return DeclRefExpr::Create(Context, @@ -8190,6 +8214,7 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Fn, MemExpr->getMemberLoc(), Fn->getType(), + VK_LValue, TemplateArgs); } else { SourceLocation Loc = MemExpr->getMemberLoc(); @@ -8210,7 +8235,10 @@ Expr *Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found, Found, MemExpr->getMemberNameInfo(), TemplateArgs, - Fn->getType()); + Fn->getType(), + cast<CXXMethodDecl>(Fn)->isStatic() + ? VK_LValue : VK_RValue, + OK_Ordinary); } llvm_unreachable("Invalid reference to overloaded function"); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 3f4a1af7727..4c25bc32df5 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3361,9 +3361,10 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, CXXScopeSpec SS; SS.setScopeRep(Qualifier); ExprResult RefExpr = BuildDeclRefExpr(VD, - VD->getType().getNonReferenceType(), - Loc, - &SS); + VD->getType().getNonReferenceType(), + VK_LValue, + Loc, + &SS); if (RefExpr.isInvalid()) return ExprError(); @@ -3390,7 +3391,7 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, if (ParamType->isPointerType()) { // When the non-type template parameter is a pointer, take the // address of the declaration. - ExprResult RefExpr = BuildDeclRefExpr(VD, T, Loc); + ExprResult RefExpr = BuildDeclRefExpr(VD, T, VK_LValue, Loc); if (RefExpr.isInvalid()) return ExprError(); @@ -3410,13 +3411,18 @@ Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get()); } + ExprValueKind VK = VK_RValue; + // If the non-type template parameter has reference type, qualify the // resulting declaration reference with the extra qualifiers on the // type that the reference refers to. - if (const ReferenceType *TargetRef = ParamType->getAs<ReferenceType>()) - T = Context.getQualifiedType(T, TargetRef->getPointeeType().getQualifiers()); + if (const ReferenceType *TargetRef = ParamType->getAs<ReferenceType>()) { + VK = VK_LValue; + T = Context.getQualifiedType(T, + TargetRef->getPointeeType().getQualifiers()); + } - return BuildDeclRefExpr(VD, T, Loc); + return BuildDeclRefExpr(VD, T, VK, Loc); } /// \brief Construct a new expression that refers to the given diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index bae703daa30..807346c4c57 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -1142,26 +1142,32 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildMemberExpr(Expr *Base, SourceLocation OpLoc, - bool isArrow, - NestedNameSpecifier *Qualifier, - SourceRange QualifierRange, - const DeclarationNameInfo &MemberNameInfo, - ValueDecl *Member, - NamedDecl *FoundDecl, + bool isArrow, + NestedNameSpecifier *Qualifier, + SourceRange QualifierRange, + const DeclarationNameInfo &MemberNameInfo, + ValueDecl *Member, + NamedDecl *FoundDecl, const TemplateArgumentListInfo *ExplicitTemplateArgs, - NamedDecl *FirstQualifierInScope) { + NamedDecl *FirstQualifierInScope) { if (!Member->getDeclName()) { - // We have a reference to an unnamed field. + // We have a reference to an unnamed field. This is always the + // base of an anonymous struct/union member access, i.e. the + // field is always of record type. assert(!Qualifier && "Can't have an unnamed field with a qualifier!"); + assert(Member->getType()->isRecordType() && + "unnamed member not of record type?"); if (getSema().PerformObjectMemberConversion(Base, Qualifier, FoundDecl, Member)) return ExprError(); + ExprValueKind VK = isArrow ? VK_LValue : Base->getValueKind(); MemberExpr *ME = new (getSema().Context) MemberExpr(Base, isArrow, Member, MemberNameInfo, - cast<FieldDecl>(Member)->getType()); + cast<FieldDecl>(Member)->getType(), + VK, OK_Ordinary); return getSema().Owned(ME); } @@ -1903,18 +1909,21 @@ public: // perform semantic analysis again. if (Super) return Owned( - new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, - Setter, - NameLoc, - SuperLoc, - SuperTy)); + new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, + VK_LValue, + OK_Ordinary, + Setter, + NameLoc, + SuperLoc, + SuperTy)); else return Owned( - new (getSema().Context) ObjCImplicitSetterGetterRefExpr( - Getter, T, - Setter, - NameLoc, - Base)); + new (getSema().Context) ObjCImplicitSetterGetterRefExpr(Getter, T, + VK_LValue, + OK_Ordinary, + Setter, + NameLoc, + Base)); } /// \brief Build a new Objective-C "isa" expression. @@ -1948,8 +1957,8 @@ public: /// By default, performs semantic analysis to build the new expression. /// Subclasses may override this routine to provide different behavior. ExprResult RebuildShuffleVectorExpr(SourceLocation BuiltinLoc, - MultiExprArg SubExprs, - SourceLocation RParenLoc) { + MultiExprArg SubExprs, + SourceLocation RParenLoc) { // Find the declaration for __builtin_shufflevector const IdentifierInfo &Name = SemaRef.Context.Idents.get("__builtin_shufflevector"); @@ -1961,7 +1970,7 @@ public: FunctionDecl *Builtin = cast<FunctionDecl>(*Lookup.first); Expr *Callee = new (SemaRef.Context) DeclRefExpr(Builtin, Builtin->getType(), - BuiltinLoc); + VK_LValue, BuiltinLoc); SemaRef.UsualUnaryConversions(Callee); // Build the CallExpr @@ -1970,6 +1979,7 @@ public: CallExpr *TheCall = new (SemaRef.Context) CallExpr(SemaRef.Context, Callee, Subs, NumSubExprs, Builtin->getCallResultType(), + Expr::getValueKindForType(Builtin->getResultType()), RParenLoc); ExprResult OwnedCall(SemaRef.Owned(TheCall)); diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 26077c5fb74..6d578f616ed 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -59,7 +59,7 @@ namespace clang { /// \brief The number of record fields required for the Expr class /// itself. - static const unsigned NumExprFields = NumStmtFields + 3; + static const unsigned NumExprFields = NumStmtFields + 5; /// \brief Read and initialize a ExplicitTemplateArgumentList structure. void ReadExplicitTemplateArgumentList(ExplicitTemplateArgumentList &ArgList, @@ -400,6 +400,8 @@ void ASTStmtReader::VisitExpr(Expr *E) { E->setType(Reader.GetType(Record[Idx++])); E->setTypeDependent(Record[Idx++]); E->setValueDependent(Record[Idx++]); + E->setValueKind(static_cast<ExprValueKind>(Record[Idx++])); + E->setObjectKind(static_cast<ExprObjectKind>(Record[Idx++])); assert(Idx == NumExprFields && "Incorrect expression field count"); } @@ -625,7 +627,6 @@ void ASTStmtReader::VisitConditionalOperator(ConditionalOperator *E) { void ASTStmtReader::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - E->setValueKind(static_cast<ExprValueKind>(Record[Idx++])); } void ASTStmtReader::VisitExplicitCastExpr(ExplicitCastExpr *E) { @@ -1284,7 +1285,6 @@ void ASTStmtReader::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { void ASTStmtReader::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); - E->setValueKind(static_cast<ExprValueKind>(Record[Idx++])); } Stmt *ASTReader::ReadStmt(PerFileData &F) { @@ -1523,6 +1523,8 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { DeclAccessPair FoundDecl = DeclAccessPair::make(FoundD, AS); QualType T = GetType(Record[Idx++]); + ExprValueKind VK = static_cast<ExprValueKind>(Record[Idx++]); + ExprObjectKind OK = static_cast<ExprObjectKind>(Record[Idx++]); Expr *Base = ReadSubExpr(); ValueDecl *MemberD = cast<ValueDecl>(GetDecl(Record[Idx++])); SourceLocation MemberLoc = ReadSourceLocation(F, Record, Idx); @@ -1531,7 +1533,7 @@ Stmt *ASTReader::ReadStmtFromStream(PerFileData &F) { S = MemberExpr::Create(*Context, Base, IsArrow, NNS, QualifierRange, MemberD, FoundDecl, MemberNameInfo, - NumTemplateArgs ? &ArgInfo : 0, T); + NumTemplateArgs ? &ArgInfo : 0, T, VK, OK); ReadDeclarationNameLoc(F, cast<MemberExpr>(S)->MemberDNLoc, MemberD->getDeclName(), Record, Idx); break; diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index efbfd944017..495c3d05ffe 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -360,6 +360,8 @@ void ASTStmtWriter::VisitExpr(Expr *E) { Writer.AddTypeRef(E->getType(), Record); Record.push_back(E->isTypeDependent()); Record.push_back(E->isValueDependent()); + Record.push_back(E->getValueKind()); + Record.push_back(E->getObjectKind()); } void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) { @@ -555,6 +557,8 @@ void ASTStmtWriter::VisitMemberExpr(MemberExpr *E) { Record.push_back(FoundDecl.getAccess()); Writer.AddTypeRef(E->getType(), Record); + Record.push_back(E->getValueKind()); + Record.push_back(E->getObjectKind()); Writer.AddStmt(E->getBase()); Writer.AddDeclRef(E->getMemberDecl(), Record); Writer.AddSourceLocation(E->getMemberLoc(), Record); @@ -612,7 +616,6 @@ void ASTStmtWriter::VisitConditionalOperator(ConditionalOperator *E) { void ASTStmtWriter::VisitImplicitCastExpr(ImplicitCastExpr *E) { VisitCastExpr(E); - Record.push_back(E->getValueKind()); Code = serialization::EXPR_IMPLICIT_CAST; } @@ -1297,7 +1300,6 @@ void ASTStmtWriter::VisitCXXNoexceptExpr(CXXNoexceptExpr *E) { void ASTStmtWriter::VisitOpaqueValueExpr(OpaqueValueExpr *E) { VisitExpr(E); - Record.push_back(E->getValueKind()); Code = serialization::EXPR_OPAQUE_VALUE; } |