forked from OSchip/llvm-project
Instantiate unresolved using declarations.
llvm-svn: 80366
This commit is contained in:
parent
8b899e4247
commit
4bd7875b9c
|
@ -1610,7 +1610,7 @@ public:
|
|||
return TargetNestedNameDecl;
|
||||
}
|
||||
|
||||
/// isTypeName - Return true if using decl had 'typename'.
|
||||
/// isTypeName - Return true if using decl has 'typename'.
|
||||
bool isTypeName() const { return IsTypeName; }
|
||||
|
||||
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
|
@ -1651,6 +1651,23 @@ class UnresolvedUsingDecl : public NamedDecl {
|
|||
IsTypeName(IsTypeNameArg) { }
|
||||
|
||||
public:
|
||||
/// \brief Returns the source range that covers the nested-name-specifier
|
||||
/// preceding the namespace name.
|
||||
SourceRange getTargetNestedNameRange() const { return TargetNestedNameRange; }
|
||||
|
||||
/// \brief Get target nested name declaration.
|
||||
NestedNameSpecifier* getTargetNestedNameSpecifier() {
|
||||
return TargetNestedNameSpecifier;
|
||||
}
|
||||
|
||||
/// \brief Returns the source location of the target declaration name.
|
||||
SourceLocation getTargetNameLocation() const { return TargetNameLocation; }
|
||||
|
||||
/// \brief Returns the source location of the target declaration name.
|
||||
DeclarationName getTargetName() const { return TargetName; }
|
||||
|
||||
bool isTypeName() const { return IsTypeName; }
|
||||
|
||||
static UnresolvedUsingDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation UsingLoc,
|
||||
SourceRange TargetNNR,
|
||||
|
|
|
@ -2160,8 +2160,9 @@ NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
|
|||
<< NNS << RD->getDeclName();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LookupContext = cast<RecordType>(Ty)->getDecl();
|
||||
|
||||
QualType BaseTy = Context.getCanonicalType(QualType(Ty, 0));
|
||||
LookupContext = BaseTy->getAs<RecordType>()->getDecl();
|
||||
} else {
|
||||
// C++0x N2914 [namespace.udecl]p8:
|
||||
// A using-declaration for a class member shall be a member-declaration.
|
||||
|
|
|
@ -58,7 +58,8 @@ namespace {
|
|||
Decl *VisitClassTemplateDecl(ClassTemplateDecl *D);
|
||||
Decl *VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
|
||||
Decl *VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D);
|
||||
|
||||
Decl *VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
|
||||
|
||||
// Base case. FIXME: Remove once we can instantiate everything.
|
||||
Decl *VisitDecl(Decl *) {
|
||||
assert(false && "Template instantiation of unknown declaration kind!");
|
||||
|
@ -740,6 +741,24 @@ Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl(
|
|||
return Inst;
|
||||
}
|
||||
|
||||
Decl *
|
||||
TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
|
||||
NestedNameSpecifier *NNS =
|
||||
SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
|
||||
D->getTargetNestedNameRange(),
|
||||
TemplateArgs);
|
||||
if (!NNS)
|
||||
return 0;
|
||||
|
||||
CXXScopeSpec SS;
|
||||
SS.setRange(D->getTargetNestedNameRange());
|
||||
SS.setScopeRep(NNS);
|
||||
|
||||
return SemaRef.BuildUsingDeclaration(D->getLocation(), SS,
|
||||
D->getTargetNameLocation(),
|
||||
D->getTargetName(), 0, D->isTypeName());
|
||||
}
|
||||
|
||||
Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
|
||||
const TemplateArgumentList &TemplateArgs) {
|
||||
TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs);
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
// RUN: clang-cc -fsyntax-only -verify %s
|
||||
|
||||
template<typename T> struct A {
|
||||
void f() { }
|
||||
struct N { };
|
||||
};
|
||||
|
||||
template<typename T> struct B : A<T> {
|
||||
using A<T>::f;
|
||||
using A<T>::N;
|
||||
|
||||
using A<T>::foo; // expected-error{{no member named 'foo'}}
|
||||
using A<double>::f; // expected-error{{using declaration refers into 'A<double>::', which is not a base class of 'B'}}
|
||||
};
|
||||
|
||||
B<int> a; // expected-note{{in instantiation of template class 'struct B<int>' requested here}}
|
Loading…
Reference in New Issue