[cfe-commits] r101065 - in /cfe/trunk: lib/Sema/Lookup.h lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplate.cpp test/CXX/temp/temp.res/temp.local/p3.cpp
Douglas Gregor
dgregor at apple.com
Mon Apr 12 13:54:26 PDT 2010
Author: dgregor
Date: Mon Apr 12 15:54:26 2010
New Revision: 101065
URL: http://llvm.org/viewvc/llvm-project?rev=101065&view=rev
Log:
Implement C++ [temp.local]p4, which specifies how we eliminate
name-lookup ambiguities when there are multiple base classes that are
all specializations of the same class template. This is part of a
general cleanup for ambiguities in template-name lookup. Fixes
PR6717.
Added:
cfe/trunk/test/CXX/temp/temp.res/temp.local/p3.cpp
Modified:
cfe/trunk/lib/Sema/Lookup.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
Modified: cfe/trunk/lib/Sema/Lookup.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Lookup.h?rev=101065&r1=101064&r2=101065&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Lookup.h (original)
+++ cfe/trunk/lib/Sema/Lookup.h Mon Apr 12 15:54:26 2010
@@ -343,6 +343,11 @@
} else {
ResultKind = Found;
resolveKind();
+
+ if (Paths && (ResultKind != Ambiguous)) {
+ deletePaths(Paths);
+ Paths = 0;
+ }
}
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=101065&r1=101064&r2=101065&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Apr 12 15:54:26 2010
@@ -2454,7 +2454,8 @@
}
}
- assert(BaseType->isDependentType() || Name.isDependentName());
+ assert(BaseType->isDependentType() || Name.isDependentName() ||
+ isDependentScopeSpecifier(SS));
// Get the type being accessed in BaseType. If this is an arrow, the BaseExpr
// must have pointer type, and the accessed type is the pointee.
@@ -3200,7 +3201,8 @@
Expr *Base = BaseArg.takeAs<Expr>();
OwningExprResult Result(*this);
- if (Base->getType()->isDependentType() || Name.isDependentName()) {
+ if (Base->getType()->isDependentType() || Name.isDependentName() ||
+ isDependentScopeSpecifier(SS)) {
Result = ActOnDependentMemberExpr(ExprArg(*this, Base), Base->getType(),
IsArrow, OpLoc,
SS, FirstQualifierInScope,
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=101065&r1=101064&r2=101065&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon Apr 12 15:54:26 2010
@@ -63,14 +63,34 @@
}
static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) {
+ // The set of class templates we've already seen.
+ llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates;
LookupResult::Filter filter = R.makeFilter();
while (filter.hasNext()) {
NamedDecl *Orig = filter.next();
NamedDecl *Repl = isAcceptableTemplateName(C, Orig->getUnderlyingDecl());
if (!Repl)
filter.erase();
- else if (Repl != Orig)
+ else if (Repl != Orig) {
+
+ // C++ [temp.local]p3:
+ // A lookup that finds an injected-class-name (10.2) can result in an
+ // ambiguity in certain cases (for example, if it is found in more than
+ // one base class). If all of the injected-class-names that are found
+ // refer to specializations of the same class template, and if the name
+ // is followed by a template-argument-list, the reference refers to the
+ // class template itself and not a specialization thereof, and is not
+ // ambiguous.
+ //
+ // FIXME: Will we eventually have to do the same for alias templates?
+ if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl))
+ if (!ClassTemplates.insert(ClassTmpl)) {
+ filter.erase();
+ continue;
+ }
+
filter.replace(Repl);
+ }
}
filter.done();
}
@@ -109,7 +129,7 @@
LookupOrdinaryName);
R.suppressDiagnostics();
LookupTemplateName(R, S, SS, ObjectType, EnteringContext);
- if (R.empty())
+ if (R.empty() || R.isAmbiguous())
return TNK_Non_template;
TemplateName Template;
@@ -227,10 +247,6 @@
LookupName(Found, S);
}
- // FIXME: Cope with ambiguous name-lookup results.
- assert(!Found.isAmbiguous() &&
- "Cannot handle template name-lookup ambiguities");
-
if (Found.empty() && !isDependent) {
// If we did not find any names, attempt to correct any typos.
DeclarationName Name = Found.getLookupName();
@@ -271,8 +287,7 @@
LookupOrdinaryName);
LookupName(FoundOuter, S);
FilterAcceptableTemplateNames(Context, FoundOuter);
- // FIXME: Handle ambiguities in this lookup better
-
+
if (FoundOuter.empty()) {
// - if the name is not found, the name found in the class of the
// object expression is used, otherwise
Added: cfe/trunk/test/CXX/temp/temp.res/temp.local/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/temp/temp.res/temp.local/p3.cpp?rev=101065&view=auto
==============================================================================
--- cfe/trunk/test/CXX/temp/temp.res/temp.local/p3.cpp (added)
+++ cfe/trunk/test/CXX/temp/temp.res/temp.local/p3.cpp Mon Apr 12 15:54:26 2010
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify %s
+
+template <class T> struct Base { // expected-note 4 {{member found by ambiguous name lookup}}
+ static void f();
+};
+
+struct X0 { };
+
+template <class T> struct Derived: Base<int>, Base<char> {
+ typename Derived::Base b; // expected-error{{member 'Base' found in multiple base classes of different types}}
+ typename Derived::Base<double> d; // OK
+
+ void g(X0 *t) {
+ t->Derived::Base<T>::f();
+ t->Base<T>::f();
+ t->Base::f(); // expected-error{{member 'Base' found in multiple base classes of different types}} \
+ // expected-error{{no member named 'f' in 'X0'}} \
+ // expected-error{{expected a class or namespace}}
+ }
+};
+
+namespace PR6717 {
+ template <typename T>
+ class WebVector {
+ }
+
+ WebVector(const WebVector<T>& other) { }
+
+ template <typename C>
+ WebVector<T>& operator=(const C& other) { } // expected-error{{unknown type name 'WebVector'}} \
+ // expected-error{{unqualified-id}}
+}
More information about the cfe-commits
mailing list