diff options
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 26 | ||||
-rw-r--r-- | test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp | 20 |
2 files changed, 39 insertions, 7 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8e1e0afaa6..dc0b6db050 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -732,11 +732,23 @@ static bool IsProvablyNotDerivedFrom(Sema &SemaRef, return true; } -static bool IsInstanceMember(NamedDecl *D) { - if (isa<EnumConstantDecl>(D)) - return false; +/// Determines if this a C++ class member. +static bool IsClassMember(NamedDecl *D) { + DeclContext *DC = D->getDeclContext(); + + // C++0x [class.mem]p1: + // The enumerators of an unscoped enumeration defined in + // the class are members of the class. + // FIXME: support C++0x scoped enumerations. + if (isa<EnumDecl>(DC)) + DC = DC->getParent(); - assert(isa<CXXRecordDecl>(D->getDeclContext()) && + return DC->isRecord(); +} + +/// Determines if this is an instance member of a class. +static bool IsInstanceMember(NamedDecl *D) { + assert(IsClassMember(D) && "checking whether non-member is instance member"); if (isa<FieldDecl>(D)) return true; @@ -798,7 +810,7 @@ enum IMAKind { /// not be caught until template-instantiation. static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef, const LookupResult &R) { - assert(!R.empty() && isa<CXXRecordDecl>((*R.begin())->getDeclContext())); + assert(!R.empty() && IsClassMember(*R.begin())); bool isStaticContext = (!isa<CXXMethodDecl>(SemaRef.CurContext) || @@ -1010,7 +1022,7 @@ Sema::OwningExprResult Sema::ActOnIdExpression(Scope *S, // class member access expression. // But note that &SomeClass::foo is grammatically distinct, even // though we don't parse it that way. - if (!R.empty() && (*R.begin())->getDeclContext()->isRecord()) { + if (!R.empty() && IsClassMember(*R.begin())) { bool isAbstractMemberPointer = (isAddressOfOperand && !SS.isEmpty()); if (!isAbstractMemberPointer) { @@ -1274,7 +1286,7 @@ bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS, // -- a declaration of a class member // Since using decls preserve this property, we check this on the // original decl. - if (D->getDeclContext()->isRecord()) + if (IsClassMember(D)) return false; // C++0x [basic.lookup.argdep]p3: diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp new file mode 100644 index 0000000000..ae5590cd3c --- /dev/null +++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p3.cpp @@ -0,0 +1,20 @@ +// RUN: clang-cc -fsyntax-only -verify %s + +// FIXME: embellish + +namespace test0 { + namespace A { + class Foo { + }; + + void foo(const Foo &foo); + } + + class Test { + enum E { foo = 0 }; + + void test() { + foo(A::Foo()); // expected-error {{not a function}} + } + }; +} |