aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExpr.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-08-06 03:17:00 +0000
committerDouglas Gregor <dgregor@apple.com>2009-08-06 03:17:00 +0000
commitfe85cedd58df7daed29201703cfb8806e12876d0 (patch)
tree3839a33ad270a9f4ed978e24e87a93d3ad409fdd /lib/Sema/SemaExpr.cpp
parent4403a5e1f956fa86d515492dbe7c7a2817d8780d (diff)
Support nested-name-specifiers for C++ member access expressions, e.g.,
this->Base::foo from James Porter! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@78278 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExpr.cpp')
-rw-r--r--lib/Sema/SemaExpr.cpp39
1 files changed, 33 insertions, 6 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index ffc6d13bb4..76296c690c 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -2103,7 +2103,11 @@ Action::OwningExprResult
Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
tok::TokenKind OpKind, SourceLocation MemberLoc,
IdentifierInfo &Member,
- DeclPtrTy ObjCImpDecl) {
+ DeclPtrTy ObjCImpDecl, const CXXScopeSpec *SS) {
+ // FIXME: handle the CXXScopeSpec for proper lookup of qualified-ids
+ if (SS && SS->isInvalid())
+ return ExprError();
+
Expr *BaseExpr = Base.takeAs<Expr>();
assert(BaseExpr && "no record expression");
@@ -2126,9 +2130,6 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
BaseType = PT->getPointeeType();
else if (BaseType->isObjCObjectPointerType())
;
- else if (getLangOptions().CPlusPlus && BaseType->isRecordType())
- return Owned(BuildOverloadedArrowExpr(S, BaseExpr, OpLoc,
- MemberLoc, Member));
else
return ExprError(Diag(MemberLoc,
diag::err_typecheck_member_reference_arrow)
@@ -2164,12 +2165,38 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
BaseExpr->getSourceRange()))
return ExprError();
+ DeclContext *DC = RDecl;
+ if (SS && SS->isSet()) {
+ // If the member name was a qualified-id, look into the
+ // nested-name-specifier.
+ DC = computeDeclContext(*SS, false);
+
+ // FIXME: If DC is not computable, we should build a
+ // CXXUnresolvedMemberExpr.
+ assert(DC && "Cannot handle non-computable dependent contexts in lookup");
+ }
+
// The record definition is complete, now make sure the member is valid.
- // FIXME: Qualified name lookup for C++ is a bit more complicated than this.
LookupResult Result
- = LookupQualifiedName(RDecl, DeclarationName(&Member),
+ = LookupQualifiedName(DC, DeclarationName(&Member),
LookupMemberName, false);
+ if (SS && SS->isSet())
+ {
+ QualType BaseTypeCanon
+ = Context.getCanonicalType(BaseType).getUnqualifiedType();
+ QualType MemberTypeCanon
+ = Context.getCanonicalType(
+ Context.getTypeDeclType(
+ dyn_cast<TypeDecl>(Result.getAsDecl()->getDeclContext())));
+
+ if (BaseTypeCanon != MemberTypeCanon &&
+ !IsDerivedFrom(BaseTypeCanon, MemberTypeCanon))
+ return ExprError(Diag(SS->getBeginLoc(),
+ diag::err_not_direct_base_or_virtual)
+ << MemberTypeCanon << BaseTypeCanon);
+ }
+
if (!Result)
return ExprError(Diag(MemberLoc, diag::err_typecheck_no_member)
<< &Member << BaseExpr->getSourceRange());