diff options
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 83 |
1 files changed, 74 insertions, 9 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 9c345f8a69a3d..283621889f802 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -142,6 +142,7 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, AbstractInstanceResult = IMA_Abstract; break; + case Sema::DiscardedStatement: case Sema::ConstantEvaluated: case Sema::PotentiallyEvaluated: case Sema::PotentiallyEvaluatedIfUsed: @@ -380,7 +381,8 @@ static Decl *FindGetterSetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDe const Selector &Sel, ASTContext &Context) { if (Member) - if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(Member)) + if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration( + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) return PD; if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel)) return OMD; @@ -401,7 +403,8 @@ static Decl *FindGetterSetterNameDecl(const ObjCObjectPointerType *QIdTy, Decl *GDecl = nullptr; for (const auto *I : QIdTy->quals()) { if (Member) - if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration(Member)) { + if (ObjCPropertyDecl *PD = I->FindPropertyDeclaration( + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { GDecl = PD; break; } @@ -900,6 +903,32 @@ static bool IsInFnTryBlockHandler(const Scope *S) { return false; } +static VarDecl * +getVarTemplateSpecialization(Sema &S, VarTemplateDecl *VarTempl, + const TemplateArgumentListInfo *TemplateArgs, + const DeclarationNameInfo &MemberNameInfo, + SourceLocation TemplateKWLoc) { + + if (!TemplateArgs) { + S.Diag(MemberNameInfo.getBeginLoc(), diag::err_template_decl_ref) + << /*Variable template*/ 1 << MemberNameInfo.getName() + << MemberNameInfo.getSourceRange(); + + S.Diag(VarTempl->getLocation(), diag::note_template_decl_here); + + return nullptr; + } + DeclResult VDecl = S.CheckVarTemplateId( + VarTempl, TemplateKWLoc, MemberNameInfo.getLoc(), *TemplateArgs); + if (VDecl.isInvalid()) + return nullptr; + VarDecl *Var = cast<VarDecl>(VDecl.get()); + if (!Var->getTemplateSpecializationKind()) + Var->setTemplateSpecializationKind(TSK_ImplicitInstantiation, + MemberNameInfo.getLoc()); + return Var; +} + ExprResult Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, SourceLocation OpLoc, bool IsArrow, @@ -1067,9 +1096,23 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, // Handle the implicit-member-access case. if (!BaseExpr) { // If this is not an instance member, convert to a non-member access. - if (!MemberDecl->isCXXInstanceMember()) - return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl); - + if (!MemberDecl->isCXXInstanceMember()) { + // If this is a variable template, get the instantiated variable + // declaration corresponding to the supplied template arguments + // (while emitting diagnostics as necessary) that will be referenced + // by this expression. + assert((!TemplateArgs || isa<VarTemplateDecl>(MemberDecl)) && + "How did we get template arguments here sans a variable template"); + if (isa<VarTemplateDecl>(MemberDecl)) { + MemberDecl = getVarTemplateSpecialization( + *this, cast<VarTemplateDecl>(MemberDecl), TemplateArgs, + R.getLookupNameInfo(), TemplateKWLoc); + if (!MemberDecl) + return ExprError(); + } + return BuildDeclarationNameExpr(SS, R.getLookupNameInfo(), MemberDecl, + FoundDecl, TemplateArgs); + } SourceLocation Loc = R.getNameLoc(); if (SS.getRange().isValid()) Loc = SS.getRange().getBegin(); @@ -1125,6 +1168,15 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType, TemplateKWLoc, Enum, FoundDecl, MemberNameInfo, Enum->getType(), VK_RValue, OK_Ordinary); } + if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) { + if (VarDecl *Var = getVarTemplateSpecialization( + *this, VarTempl, TemplateArgs, MemberNameInfo, TemplateKWLoc)) + return BuildMemberExpr(*this, Context, BaseExpr, IsArrow, OpLoc, SS, + TemplateKWLoc, Var, FoundDecl, MemberNameInfo, + Var->getType().getNonReferenceType(), VK_LValue, + OK_Ordinary); + return ExprError(); + } // We found something that we didn't expect. Complain. if (isa<TypeDecl>(MemberDecl)) @@ -1324,7 +1376,9 @@ static ExprResult LookupMemberExpr(Sema &S, LookupResult &R, D = CAT->getClassInterface(); ClassDeclared = cast<ObjCInterfaceDecl>(D); } else { - if (IsArrow && IDecl->FindPropertyDeclaration(Member)) { + if (IsArrow && + IDecl->FindPropertyDeclaration( + Member, ObjCPropertyQueryKind::OBJC_PR_query_instance)) { S.Diag(MemberLoc, diag::err_property_found_suggest) << Member << BaseExpr.get()->getType() << FixItHint::CreateReplacement(OpLoc, "."); @@ -1731,9 +1785,20 @@ BuildFieldReferenceExpr(Sema &S, Expr *BaseExpr, bool IsArrow, FoundDecl, Field); if (Base.isInvalid()) return ExprError(); - return BuildMemberExpr(S, S.Context, Base.get(), IsArrow, OpLoc, SS, - /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, - MemberNameInfo, MemberType, VK, OK); + MemberExpr *ME = + BuildMemberExpr(S, S.Context, Base.get(), IsArrow, OpLoc, SS, + /*TemplateKWLoc=*/SourceLocation(), Field, FoundDecl, + MemberNameInfo, MemberType, VK, OK); + + // Build a reference to a private copy for non-static data members in + // non-static member functions, privatized by OpenMP constructs. + if (S.getLangOpts().OpenMP && IsArrow && + !S.CurContext->isDependentContext() && + isa<CXXThisExpr>(Base.get()->IgnoreParenImpCasts())) { + if (auto *PrivateCopy = S.IsOpenMPCapturedDecl(Field)) + return S.getOpenMPCapturedExpr(PrivateCopy, VK, OK, OpLoc); + } + return ME; } /// Builds an implicit member access expression. The current context |