[cfe-commits] r153858 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/CXX/special/class.inhctor/elsewhere.cpp test/CXX/special/class.inhctor/p3.cpp test/CXX/special/class.inhctor/p7.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Sun Apr 1 18:30:27 PDT 2012
Author: rsmith
Date: Sun Apr 1 20:30:27 2012
New Revision: 153858
URL: http://llvm.org/viewvc/llvm-project?rev=153858&view=rev
Log:
Basic semantic analysis support for inheriting constructor declarations in
dependent contexts.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/CXX/special/class.inhctor/elsewhere.cpp
cfe/trunk/test/CXX/special/class.inhctor/p3.cpp
cfe/trunk/test/CXX/special/class.inhctor/p7.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Apr 1 20:30:27 2012
@@ -2978,7 +2978,7 @@
bool IsTypeName,
SourceLocation TypenameLoc);
- bool CheckInheritedConstructorUsingDecl(UsingDecl *UD);
+ bool CheckInheritingConstructorUsingDecl(UsingDecl *UD);
Decl *ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Sun Apr 1 20:30:27 2012
@@ -118,7 +118,7 @@
//
// We therefore do not perform any name lookup if the result would
// refer to a member of an unknown specialization.
- if (!isClassName)
+ if (!isClassName && !IsCtorOrDtorName)
return ParsedType();
// We know from the grammar that this name refers to a type,
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sun Apr 1 20:30:27 2012
@@ -6290,9 +6290,9 @@
return UD;
}
- // Constructor inheriting using decls get special treatment.
+ // The normal rules do not apply to inheriting constructor declarations.
if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) {
- if (CheckInheritedConstructorUsingDecl(UD))
+ if (CheckInheritingConstructorUsingDecl(UD))
UD->setInvalidDecl();
return UD;
}
@@ -6362,11 +6362,8 @@
}
/// Additional checks for a using declaration referring to a constructor name.
-bool Sema::CheckInheritedConstructorUsingDecl(UsingDecl *UD) {
- if (UD->isTypeName()) {
- // FIXME: Cannot specify typename when specifying constructor
- return true;
- }
+bool Sema::CheckInheritingConstructorUsingDecl(UsingDecl *UD) {
+ assert(!UD->isTypeName() && "expecting a constructor name");
const Type *SourceType = UD->getQualifier()->getAsType();
assert(SourceType &&
@@ -6381,6 +6378,8 @@
CanQualType BaseType = BaseIt->getType()->getCanonicalTypeUnqualified();
if (CanonicalSourceType == BaseType)
break;
+ if (BaseIt->getType()->isDependentType())
+ break;
}
if (BaseIt == BaseE) {
@@ -6392,7 +6391,8 @@
return true;
}
- BaseIt->setInheritConstructors();
+ if (!CurContext->isDependentContext())
+ BaseIt->setInheritConstructors();
return false;
}
@@ -7041,7 +7041,6 @@
Context.getCanonicalType(CtorIt->getType()).getTypePtr());
}
- Scope *S = getScopeForContext(ClassDecl);
DeclarationName CreatedCtorName =
Context.DeclarationNames.getCXXConstructorName(
ClassDecl->getTypeForDecl()->getCanonicalTypeUnqualified());
@@ -7063,10 +7062,12 @@
CtorE = BaseDecl->ctor_end();
CtorIt != CtorE; ++CtorIt) {
// Find the using declaration for inheriting this base's constructors.
+ // FIXME: Don't perform name lookup just to obtain a source location!
DeclarationName Name =
Context.DeclarationNames.getCXXConstructorName(CanonicalBase);
- UsingDecl *UD = dyn_cast_or_null<UsingDecl>(
- LookupSingleName(S, Name,SourceLocation(), LookupUsingDeclName));
+ LookupResult Result(*this, Name, SourceLocation(), LookupUsingDeclName);
+ LookupQualifiedName(Result, CurContext);
+ UsingDecl *UD = Result.getAsSingle<UsingDecl>();
SourceLocation UsingLoc = UD ? UD->getLocation() :
ClassDecl->getLocation();
@@ -7177,7 +7178,6 @@
NewCtor->setParams(ParamDecls);
NewCtor->setInheritedConstructor(BaseCtor);
- PushOnScopeChains(NewCtor, S, false);
ClassDecl->addDecl(NewCtor);
result.first->second.second = NewCtor;
}
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sun Apr 1 20:30:27 2012
@@ -1856,6 +1856,12 @@
if (NewUD->isInvalidDecl())
return NewUD;
+ if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName) {
+ if (SemaRef.CheckInheritingConstructorUsingDecl(NewUD))
+ NewUD->setInvalidDecl();
+ return NewUD;
+ }
+
bool isFunctionScope = Owner->isFunctionOrMethod();
// Process the shadow decls.
Modified: cfe/trunk/test/CXX/special/class.inhctor/elsewhere.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.inhctor/elsewhere.cpp?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.inhctor/elsewhere.cpp (original)
+++ cfe/trunk/test/CXX/special/class.inhctor/elsewhere.cpp Sun Apr 1 20:30:27 2012
@@ -29,3 +29,29 @@
struct D1 : I1 {
using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}}
};
+
+template<typename T> struct A {};
+
+template<typename T> struct B : A<bool>, A<char> {
+ using A<T>::A; // expected-error {{'A<double>::', which is not a base class of 'B<double>'}}
+};
+B<bool> bb;
+B<char> bc;
+B<double> bd; // expected-note {{here}}
+
+template<typename T> struct C : A<T> {
+ using A<bool>::A; // expected-error {{'A<bool>::', which is not a base class of 'C<char>'}}
+};
+C<bool> cb;
+C<char> cc; // expected-note {{here}}
+
+template<typename T> struct D : A<T> {};
+template<typename T> struct E : D<T> {
+ using A<bool>::A; // expected-error {{'A<bool>' is not a direct base of 'E<bool>', can not inherit}}
+};
+E<bool> eb; // expected-note {{here}}
+
+template<typename T> struct F : D<bool> {
+ using A<T>::A; // expected-error {{'A<bool>' is not a direct base of 'F<bool>'}}
+};
+F<bool> fb; // expected-note {{here}}
Modified: cfe/trunk/test/CXX/special/class.inhctor/p3.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.inhctor/p3.cpp?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.inhctor/p3.cpp (original)
+++ cfe/trunk/test/CXX/special/class.inhctor/p3.cpp Sun Apr 1 20:30:27 2012
@@ -28,3 +28,21 @@
using B3::B3; // expected-note {{candidate constructor (inherited)}}
};
D3 fd3() { return 1; } // expected-error {{no viable conversion}}
+
+template<typename T> struct T1 : B1 {
+ using B1::B1;
+};
+template<typename T> struct T2 : T1<T> {
+ using T1<int>::T1;
+};
+template<typename T> struct T3 : T1<int> {
+ using T1<T>::T1;
+};
+struct U {
+ friend T1<int>::T1(int);
+ friend T1<int>::T1(int, int);
+ friend T2<int>::T2(int);
+ friend T2<int>::T2(int, int);
+ friend T3<int>::T3(int);
+ friend T3<int>::T3(int, int);
+};
Modified: cfe/trunk/test/CXX/special/class.inhctor/p7.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.inhctor/p7.cpp?rev=153858&r1=153857&r2=153858&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.inhctor/p7.cpp (original)
+++ cfe/trunk/test/CXX/special/class.inhctor/p7.cpp Sun Apr 1 20:30:27 2012
@@ -2,7 +2,7 @@
// Straight from the standard
struct B1 {
- B1(int); // expected-note {{previous constructor}}
+ B1(int); // expected-note {{previous constructor}} expected-note {{conflicting constructor}}
};
struct B2 {
B2(int); // expected-note {{conflicting constructor}}
@@ -16,3 +16,14 @@
using B2::B2;
D2(int);
};
+
+template<typename T> struct B3 {
+ B3(T); // expected-note {{previous constructor}}
+};
+template<typename T> struct B4 : B3<T>, B1 {
+ B4();
+ using B3<T>::B3; // expected-note {{inherited here}}
+ using B1::B1; // expected-error {{already inherited}}
+};
+B4<char> b4c;
+B4<int> b4i; // expected-note {{here}}
More information about the cfe-commits
mailing list