aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp102
1 files changed, 19 insertions, 83 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 5f00293d39..ae45429952 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -941,95 +941,31 @@ Sema::BuildDeclarationNameExpr(SourceLocation Loc, NamedDecl *D,
// We may have found a field within an anonymous union or struct
// (C++ [class.union]).
+ // FIXME: This needs to happen post-isImplicitMemberReference?
if (FieldDecl *FD = dyn_cast<FieldDecl>(D))
if (cast<RecordDecl>(FD->getDeclContext())->isAnonymousStructOrUnion())
return BuildAnonymousStructUnionMemberReference(Loc, FD);
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(CurContext)) {
- if (!MD->isStatic()) {
- // C++ [class.mfct.nonstatic]p2:
- // [...] if name lookup (3.4.1) resolves the name in the
- // id-expression to a nonstatic nontype member of class X or of
- // a base class of X, the id-expression is transformed into a
- // class member access expression (5.2.5) using (*this) (9.3.2)
- // as the postfix-expression to the left of the '.' operator.
- DeclContext *Ctx = 0;
- QualType MemberType;
- if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
- Ctx = FD->getDeclContext();
- MemberType = FD->getType();
-
- if (const ReferenceType *RefType = MemberType->getAs<ReferenceType>())
- MemberType = RefType->getPointeeType();
- else if (!FD->isMutable())
- MemberType
- = Context.getQualifiedType(MemberType,
- Qualifiers::fromCVRMask(MD->getTypeQualifiers()));
- } else if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
- if (!Method->isStatic()) {
- Ctx = Method->getParent();
- MemberType = Method->getType();
- }
- } else if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(D)) {
- if (CXXMethodDecl *Method
- = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl())) {
- if (!Method->isStatic()) {
- Ctx = Method->getParent();
- MemberType = Context.OverloadTy;
- }
- }
- } else if (OverloadedFunctionDecl *Ovl
- = dyn_cast<OverloadedFunctionDecl>(D)) {
- // FIXME: We need an abstraction for iterating over one or more function
- // templates or functions. This code is far too repetitive!
- for (OverloadedFunctionDecl::function_iterator
- Func = Ovl->function_begin(),
- FuncEnd = Ovl->function_end();
- Func != FuncEnd; ++Func) {
- CXXMethodDecl *DMethod = 0;
- if (FunctionTemplateDecl *FunTmpl
- = dyn_cast<FunctionTemplateDecl>(*Func))
- DMethod = dyn_cast<CXXMethodDecl>(FunTmpl->getTemplatedDecl());
- else
- DMethod = dyn_cast<CXXMethodDecl>(*Func);
-
- if (DMethod && !DMethod->isStatic()) {
- Ctx = DMethod->getDeclContext();
- MemberType = Context.OverloadTy;
- break;
- }
- }
- }
-
- if (Ctx && Ctx->isRecord()) {
- QualType CtxType = Context.getTagDeclType(cast<CXXRecordDecl>(Ctx));
- QualType ThisType = Context.getTagDeclType(MD->getParent());
- if ((Context.getCanonicalType(CtxType)
- == Context.getCanonicalType(ThisType)) ||
- IsDerivedFrom(ThisType, CtxType)) {
- // Build the implicit member access expression.
- Expr *This = new (Context) CXXThisExpr(SourceLocation(),
- MD->getThisType(Context));
- MarkDeclarationReferenced(Loc, D);
- if (PerformObjectMemberConversion(This, D))
- return ExprError();
-
- bool ShouldCheckUse = true;
- if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
- // Don't diagnose the use of a virtual member function unless it's
- // explicitly qualified.
- if (MD->isVirtual() && (!SS || !SS->isSet()))
- ShouldCheckUse = false;
- }
+ // Cope with an implicit member access in a C++ non-static member function.
+ QualType ThisType, MemberType;
+ if (isImplicitMemberReference(SS, D, Loc, ThisType, MemberType)) {
+ Expr *This = new (Context) CXXThisExpr(SourceLocation(), ThisType);
+ MarkDeclarationReferenced(Loc, D);
+ if (PerformObjectMemberConversion(This, D))
+ return ExprError();
- if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc))
- return ExprError();
- return Owned(BuildMemberExpr(Context, This, true, SS, D,
- Loc, MemberType));
- }
- }
+ bool ShouldCheckUse = true;
+ if (CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ // Don't diagnose the use of a virtual member function unless it's
+ // explicitly qualified.
+ if (MD->isVirtual() && (!SS || !SS->isSet()))
+ ShouldCheckUse = false;
}
+
+ if (ShouldCheckUse && DiagnoseUseOfDecl(D, Loc))
+ return ExprError();
+ return Owned(BuildMemberExpr(Context, This, true, SS, D,
+ Loc, MemberType));
}
if (FieldDecl *FD = dyn_cast<FieldDecl>(D)) {