diff options
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 92 |
1 files changed, 56 insertions, 36 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 7b016c6574..545ac2746d 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -60,6 +60,9 @@ enum IMAKind { /// The reference may be to an unresolved using declaration. IMA_Unresolved, + /// The reference is a contextually-permitted abstract member reference. + IMA_Abstract, + /// The reference may be to an unresolved using declaration and the /// context is not an instance method. IMA_Unresolved_StaticContext, @@ -105,7 +108,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, NamedDecl *D = *I; if (D->isCXXInstanceMember()) { - if (dyn_cast<FieldDecl>(D) || dyn_cast<IndirectFieldDecl>(D)) + if (dyn_cast<FieldDecl>(D) || dyn_cast<MSPropertyDecl>(D) + || dyn_cast<IndirectFieldDecl>(D)) isField = true; CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext()); @@ -119,19 +123,32 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, // member reference. if (Classes.empty()) return IMA_Static; - - bool IsCXX11UnevaluatedField = false; - if (SemaRef.getLangOpts().CPlusPlus11 && isField) { - // C++11 [expr.prim.general]p12: - // An id-expression that denotes a non-static data member or non-static - // member function of a class can only be used: - // (...) - // - if that id-expression denotes a non-static data member and it - // appears in an unevaluated operand. - const Sema::ExpressionEvaluationContextRecord& record - = SemaRef.ExprEvalContexts.back(); - if (record.Context == Sema::Unevaluated) - IsCXX11UnevaluatedField = true; + + // C++11 [expr.prim.general]p12: + // An id-expression that denotes a non-static data member or non-static + // member function of a class can only be used: + // (...) + // - if that id-expression denotes a non-static data member and it + // appears in an unevaluated operand. + // + // This rule is specific to C++11. However, we also permit this form + // in unevaluated inline assembly operands, like the operand to a SIZE. + IMAKind AbstractInstanceResult = IMA_Static; // happens to be 'false' + assert(!AbstractInstanceResult); + switch (SemaRef.ExprEvalContexts.back().Context) { + case Sema::Unevaluated: + if (isField && SemaRef.getLangOpts().CPlusPlus11) + AbstractInstanceResult = IMA_Field_Uneval_Context; + break; + + case Sema::UnevaluatedAbstract: + AbstractInstanceResult = IMA_Abstract; + break; + + case Sema::ConstantEvaluated: + case Sema::PotentiallyEvaluated: + case Sema::PotentiallyEvaluatedIfUsed: + break; } // If the current context is not an instance method, it can't be @@ -140,8 +157,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, if (hasNonInstance) return IMA_Mixed_StaticContext; - return IsCXX11UnevaluatedField ? IMA_Field_Uneval_Context - : IMA_Error_StaticContext; + return AbstractInstanceResult ? AbstractInstanceResult + : IMA_Error_StaticContext; } CXXRecordDecl *contextClass; @@ -171,8 +188,8 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, // which case it's an error if any of those members are selected). if (isProvablyNotDerivedFrom(SemaRef, contextClass, Classes)) return hasNonInstance ? IMA_Mixed_Unrelated : - IsCXX11UnevaluatedField ? IMA_Field_Uneval_Context : - IMA_Error_Unrelated; + AbstractInstanceResult ? AbstractInstanceResult : + IMA_Error_Unrelated; return (hasNonInstance ? IMA_Mixed : IMA_Instance); } @@ -232,6 +249,7 @@ Sema::BuildPossibleImplicitMemberExpr(const CXXScopeSpec &SS, << R.getLookupNameInfo().getName(); // Fall through. case IMA_Static: + case IMA_Abstract: case IMA_Mixed_StaticContext: case IMA_Unresolved_StaticContext: if (TemplateArgs || TemplateKWLoc.isValid()) @@ -778,6 +796,19 @@ Sema::BuildAnonymousStructUnionMemberReference(const CXXScopeSpec &SS, return Owned(result); } +static ExprResult +BuildMSPropertyRefExpr(Sema &S, Expr *BaseExpr, bool IsArrow, + const CXXScopeSpec &SS, + MSPropertyDecl *PD, + const DeclarationNameInfo &NameInfo) { + // Property names are always simple identifiers and therefore never + // require any interesting additional storage. + return new (S.Context) MSPropertyRefExpr(BaseExpr, PD, IsArrow, + S.Context.PseudoObjectTy, VK_LValue, + SS.getWithLocInContext(S.Context), + NameInfo.getLoc()); +} + /// \brief Build a MemberExpr AST node. static MemberExpr *BuildMemberExpr(Sema &SemaRef, ASTContext &C, Expr *Base, bool isArrow, @@ -935,6 +966,10 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, return BuildFieldReferenceExpr(*this, BaseExpr, IsArrow, SS, FD, FoundDecl, MemberNameInfo); + if (MSPropertyDecl *PD = dyn_cast<MSPropertyDecl>(MemberDecl)) + return BuildMSPropertyRefExpr(*this, BaseExpr, IsArrow, SS, PD, + MemberNameInfo); + if (IndirectFieldDecl *FD = dyn_cast<IndirectFieldDecl>(MemberDecl)) // We may have found a field within an anonymous union or struct // (C++ [class.union]). @@ -1130,30 +1165,15 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, // There's an implicit 'isa' ivar on all objects. // But we only actually find it this way on objects of type 'id', // apparently. - if (OTy->isObjCId() && Member->isStr("isa")) { - Diag(MemberLoc, diag::warn_objc_isa_use); + if (OTy->isObjCId() && Member->isStr("isa")) return Owned(new (Context) ObjCIsaExpr(BaseExpr.take(), IsArrow, MemberLoc, + OpLoc, Context.getObjCClassType())); - } - if (ShouldTryAgainWithRedefinitionType(*this, BaseExpr)) return LookupMemberExpr(R, BaseExpr, IsArrow, OpLoc, SS, ObjCImpDecl, HasTemplateArgs); goto fail; } - else if (Member && Member->isStr("isa")) { - // If an ivar is (1) the first ivar in a root class and (2) named `isa`, - // then issue the same deprecated warning that id->isa gets. - ObjCInterfaceDecl *ClassDeclared = 0; - if (ObjCIvarDecl *IV = - IDecl->lookupInstanceVariable(Member, ClassDeclared)) { - if (!ClassDeclared->getSuperClass() - && (*ClassDeclared->ivar_begin()) == IV) { - Diag(MemberLoc, diag::warn_objc_isa_use); - Diag(IV->getLocation(), diag::note_ivar_decl); - } - } - } if (RequireCompleteType(OpLoc, BaseType, diag::err_typecheck_incomplete_tag, BaseExpr.get())) @@ -1267,7 +1287,7 @@ Sema::LookupMemberExpr(LookupResult &R, ExprResult &BaseExpr, } ObjCIvarRefExpr *Result = new (Context) ObjCIvarRefExpr(IV, IV->getType(), - MemberLoc, + MemberLoc, OpLoc, BaseExpr.take(), IsArrow); |