summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprMember.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExprMember.cpp')
-rw-r--r--lib/Sema/SemaExprMember.cpp83
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