[cfe-commits] r89184 - in /cfe/trunk: include/clang/AST/ include/clang/Basic/ include/clang/Parse/ lib/AST/ lib/Parse/ lib/Sema/ test/CXX/dcl.dcl/basic.namespace/namespace.udecl/ test/SemaCXX/
John McCall
rjmccall at apple.com
Tue Nov 17 18:36:19 PST 2009
Author: rjmccall
Date: Tue Nov 17 20:36:19 2009
New Revision: 89184
URL: http://llvm.org/viewvc/llvm-project?rev=89184&view=rev
Log:
Incremental progress on using declarations. Split UnresolvedUsingDecl into
two classes, one for typenames and one for values; this seems to have some
support from Doug if not necessarily from the extremely-vague-on-this-point
standard. Track the location of the 'typename' keyword in a using-typename
decl. Make a new lookup result for unresolved values and deal with it in
most places.
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/DeclNodes.def
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/include/clang/Parse/Action.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/DeclPrinter.cpp
cfe/trunk/lib/Parse/MinimalAction.cpp
cfe/trunk/lib/Parse/ParseDeclCXX.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
cfe/trunk/test/SemaCXX/using-decl-templates.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Nov 17 20:36:19 2009
@@ -56,7 +56,6 @@
class TranslationUnitDecl;
class TypeDecl;
class TypedefDecl;
- class UnresolvedUsingDecl;
class UsingDecl;
namespace Builtin { class Context; }
@@ -205,7 +204,7 @@
///
/// This mapping will contain an entry that maps from the UsingDecl in
/// B<int> to the UnresolvedUsingDecl in B<T>.
- llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
+ llvm::DenseMap<UsingDecl *, NamedDecl *>
InstantiatedFromUnresolvedUsingDecl;
llvm::DenseMap<FieldDecl *, FieldDecl *> InstantiatedFromUnnamedFieldDecl;
@@ -285,12 +284,11 @@
/// \brief If this using decl is instantiated from an unresolved using decl,
/// return it.
- UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
+ NamedDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
/// \brief Note that the using decl \p Inst is an instantiation of
/// the unresolved using decl \p Tmpl of a class template.
- void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst,
- UnresolvedUsingDecl *Tmpl);
+ void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *Inst, NamedDecl *Tmpl);
FieldDecl *getInstantiatedFromUnnamedFieldDecl(FieldDecl *Field);
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Nov 17 20:36:19 2009
@@ -1766,31 +1766,88 @@
static bool classof(const UsingDecl *D) { return true; }
};
-/// UnresolvedUsingDecl - Represents a using declaration whose name can not
-/// yet be resolved.
-class UnresolvedUsingDecl : public NamedDecl {
+/// UnresolvedUsingValueDecl - Represents a dependent using
+/// declaration which was not marked with 'typename'. Unlike
+/// non-dependent using declarations, these *only* bring through
+/// non-types; otherwise they would break two-phase lookup.
+///
+/// template <class T> class A : public Base<T> {
+/// using Base<T>::foo;
+/// };
+class UnresolvedUsingValueDecl : public ValueDecl {
/// \brief The source range that covers the nested-name-specifier
/// preceding the declaration name.
SourceRange TargetNestedNameRange;
- /// \brief The source location of the target declaration name.
- SourceLocation TargetNameLocation;
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
NestedNameSpecifier *TargetNestedNameSpecifier;
- DeclarationName TargetName;
+ UnresolvedUsingValueDecl(DeclContext *DC, QualType Ty,
+ SourceLocation UsingLoc, SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName)
+ : ValueDecl(Decl::UnresolvedUsingValue, DC, TargetNameLoc, TargetName, Ty),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TargetNestedNameSpecifier(TargetNNS)
+ { }
- // \brief Has 'typename' keyword.
- bool IsTypeName;
+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 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
+
+ static UnresolvedUsingValueDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Decl::UnresolvedUsingValue;
+ }
+ static bool classof(const UnresolvedUsingValueDecl *D) { return true; }
+};
+
+/// UnresolvedUsingTypenameDecl - Represents a dependent using
+/// declaration which was marked with 'typename'.
+///
+/// template <class T> class A : public Base<T> {
+/// using typename Base<T>::foo;
+/// };
+///
+/// The type associated with a unresolved using typename decl is
+/// currently always a typename type.
+class UnresolvedUsingTypenameDecl : public TypeDecl {
+ /// \brief The source range that covers the nested-name-specifier
+ /// preceding the declaration name.
+ SourceRange TargetNestedNameRange;
+
+ /// \brief The source location of the 'using' keyword
+ SourceLocation UsingLocation;
+
+ /// \brief The source location of the 'typename' keyword
+ SourceLocation TypenameLocation;
- UnresolvedUsingDecl(DeclContext *DC, SourceLocation UsingLoc,
- SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc, DeclarationName TargetName,
- bool IsTypeNameArg)
- : NamedDecl(Decl::UnresolvedUsing, DC, UsingLoc, TargetName),
- TargetNestedNameRange(TargetNNR), TargetNameLocation(TargetNameLoc),
- TargetNestedNameSpecifier(TargetNNS), TargetName(TargetName),
- IsTypeName(IsTypeNameArg) { }
+ NestedNameSpecifier *TargetNestedNameSpecifier;
+
+ UnresolvedUsingTypenameDecl(DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, IdentifierInfo *TargetName)
+ : TypeDecl(Decl::UnresolvedUsingTypename, DC, TargetNameLoc, TargetName),
+ TargetNestedNameRange(TargetNNR), UsingLocation(UsingLoc),
+ TypenameLocation(TypenameLoc), TargetNestedNameSpecifier(TargetNNS)
+ { }
public:
/// \brief Returns the source range that covers the nested-name-specifier
@@ -1802,26 +1859,22 @@
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; }
+ /// \brief Returns the source location of the 'using' keyword.
+ SourceLocation getUsingLoc() const { return UsingLocation; }
- bool isTypeName() const { return IsTypeName; }
+ /// \brief Returns the source location of the 'typename' keyword.
+ SourceLocation getTypenameLoc() const { return TypenameLocation; }
- static UnresolvedUsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc,
- DeclarationName TargetName,
- bool IsTypeNameArg);
+ static UnresolvedUsingTypenameDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR, NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc, DeclarationName TargetName);
static bool classof(const Decl *D) {
- return D->getKind() == Decl::UnresolvedUsing;
+ return D->getKind() == Decl::UnresolvedUsingTypename;
}
- static bool classof(const UnresolvedUsingDecl *D) { return true; }
+ static bool classof(const UnresolvedUsingTypenameDecl *D) { return true; }
};
/// StaticAssertDecl - Represents a C++0x static_assert declaration.
Modified: cfe/trunk/include/clang/AST/DeclNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclNodes.def?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclNodes.def (original)
+++ cfe/trunk/include/clang/AST/DeclNodes.def Tue Nov 17 20:36:19 2009
@@ -81,6 +81,7 @@
DECL(NamespaceAlias, NamedDecl)
ABSTRACT_DECL(Type, NamedDecl)
DECL(Typedef, TypeDecl)
+ DECL(UnresolvedUsingTypename, TypeDecl)
ABSTRACT_DECL(Tag, TypeDecl)
DECL(Enum, TagDecl)
DECL(Record, TagDecl)
@@ -91,6 +92,7 @@
DECL(TemplateTypeParm, TypeDecl)
ABSTRACT_DECL(Value, NamedDecl)
DECL(EnumConstant, ValueDecl)
+ DECL(UnresolvedUsingValue, ValueDecl)
ABSTRACT_DECL(Declarator, ValueDecl)
DECL(Function, DeclaratorDecl)
DECL(CXXMethod, FunctionDecl)
@@ -109,7 +111,6 @@
DECL(ClassTemplate, TemplateDecl)
DECL(TemplateTemplateParm, TemplateDecl)
DECL(Using, NamedDecl)
- DECL(UnresolvedUsing, NamedDecl)
DECL(UsingShadow, NamedDecl)
DECL(ObjCMethod, NamedDecl)
DECL(ObjCContainer, NamedDecl)
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Nov 17 20:36:19 2009
@@ -103,6 +103,8 @@
"using declaration requires a qualified name">;
def err_using_typename_non_type : Error<
"'typename' keyword used on a non-type">;
+def err_using_dependent_value_is_type : Error<
+ "dependent using declaration resolved to type without 'typename'">;
def err_using_decl_nested_name_specifier_is_not_a_base_class : Error<
"using declaration refers into '%0', which is not a base class of %1">;
def err_using_decl_can_not_refer_to_class_member : Error<
@@ -115,6 +117,8 @@
"using declaration can not refer to a destructor">;
def err_using_decl_template_id : Error<
"using declaration can not refer to a template specialization">;
+def note_using_decl_target : Note<
+ "target of using declaration">;
def err_invalid_thread : Error<
"'__thread' is only allowed on variable declarations">;
Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Tue Nov 17 20:36:19 2009
@@ -1203,6 +1203,8 @@
/// 'typename' keyword. FIXME: This will eventually be split into a
/// separate action.
///
+ /// \param TypenameLoc the location of the 'typename' keyword, if present
+ ///
/// \returns a representation of the using declaration.
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
@@ -1210,7 +1212,8 @@
const CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
- bool IsTypeName);
+ bool IsTypeName,
+ SourceLocation TypenameLoc);
/// ActOnParamDefaultArgument - Parse default argument for function parameter
virtual void ActOnParamDefaultArgument(DeclPtrTy param,
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Nov 17 20:36:19 2009
@@ -256,9 +256,9 @@
= new (*this) MemberSpecializationInfo(Tmpl, TSK);
}
-UnresolvedUsingDecl *
+NamedDecl *
ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) {
- llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>::const_iterator Pos
+ llvm::DenseMap<UsingDecl *, NamedDecl *>::const_iterator Pos
= InstantiatedFromUnresolvedUsingDecl.find(UUD);
if (Pos == InstantiatedFromUnresolvedUsingDecl.end())
return 0;
@@ -268,7 +268,10 @@
void
ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
- UnresolvedUsingDecl *UUD) {
+ NamedDecl *UUD) {
+ assert((isa<UnresolvedUsingValueDecl>(UUD) ||
+ isa<UnresolvedUsingTypenameDecl>(UUD)) &&
+ "original declaration is not an unresolved using decl");
assert(!InstantiatedFromUnresolvedUsingDecl[UD] &&
"Already noted what using decl what instantiated from");
InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Tue Nov 17 20:36:19 2009
@@ -212,8 +212,9 @@
case UsingShadow:
return 0; // we'll actually overwrite this later
- case UnresolvedUsing:
- return IDNS_Tag | IDNS_Ordinary | IDNS_Using;
+ case UnresolvedUsingValue:
+ case UnresolvedUsingTypename:
+ return IDNS_Ordinary | IDNS_Using;
case Using:
return IDNS_Using;
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Tue Nov 17 20:36:19 2009
@@ -920,15 +920,30 @@
return new (C) UsingDecl(DC, L, NNR, UL, TargetNNS, Name, IsTypeNameArg);
}
-UnresolvedUsingDecl *UnresolvedUsingDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceRange TargetNNR,
- NestedNameSpecifier *TargetNNS,
- SourceLocation TargetNameLoc,
- DeclarationName TargetName,
- bool IsTypeNameArg) {
- return new (C) UnresolvedUsingDecl(DC, UsingLoc, TargetNNR, TargetNNS,
- TargetNameLoc, TargetName, IsTypeNameArg);
+UnresolvedUsingValueDecl *
+UnresolvedUsingValueDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation UsingLoc,
+ SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName) {
+ return new (C) UnresolvedUsingValueDecl(DC, C.DependentTy, UsingLoc,
+ TargetNNR, TargetNNS,
+ TargetNameLoc, TargetName);
+}
+
+UnresolvedUsingTypenameDecl *
+UnresolvedUsingTypenameDecl::Create(ASTContext &C, DeclContext *DC,
+ SourceLocation UsingLoc,
+ SourceLocation TypenameLoc,
+ SourceRange TargetNNR,
+ NestedNameSpecifier *TargetNNS,
+ SourceLocation TargetNameLoc,
+ DeclarationName TargetName) {
+ return new (C) UnresolvedUsingTypenameDecl(DC, UsingLoc, TypenameLoc,
+ TargetNNR, TargetNNS,
+ TargetNameLoc,
+ TargetName.getAsIdentifierInfo());
}
StaticAssertDecl *StaticAssertDecl::Create(ASTContext &C, DeclContext *DC,
Modified: cfe/trunk/lib/AST/DeclPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclPrinter.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Tue Nov 17 20:36:19 2009
@@ -71,7 +71,8 @@
void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
- void VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
+ void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
+ void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
void VisitUsingDecl(UsingDecl *D);
void VisitUsingShadowDecl(UsingShadowDecl *D);
};
@@ -829,10 +830,17 @@
Out << D->getNameAsString();
}
-void DeclPrinter::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
+void
+DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ Out << "using typename ";
+ D->getTargetNestedNameSpecifier()->print(Out, Policy);
+ Out << D->getDeclName().getAsString();
+}
+
+void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
Out << "using ";
D->getTargetNestedNameSpecifier()->print(Out, Policy);
- Out << D->getTargetName().getAsString();
+ Out << D->getDeclName().getAsString();
}
void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
Modified: cfe/trunk/lib/Parse/MinimalAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/MinimalAction.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/MinimalAction.cpp (original)
+++ cfe/trunk/lib/Parse/MinimalAction.cpp Tue Nov 17 20:36:19 2009
@@ -49,7 +49,8 @@
const CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
- bool IsTypeName) {
+ bool IsTypeName,
+ SourceLocation TypenameLoc) {
// FIXME: Parser seems to assume that Action::ActOn* takes ownership over
// passed AttributeList, however other actions don't free it, is it
Modified: cfe/trunk/lib/Parse/ParseDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDeclCXX.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDeclCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDeclCXX.cpp Tue Nov 17 20:36:19 2009
@@ -283,11 +283,13 @@
SourceLocation &DeclEnd,
AccessSpecifier AS) {
CXXScopeSpec SS;
+ SourceLocation TypenameLoc;
bool IsTypeName;
// Ignore optional 'typename'.
// FIXME: This is wrong; we should parse this as a typename-specifier.
if (Tok.is(tok::kw_typename)) {
+ TypenameLoc = Tok.getLocation();
ConsumeToken();
IsTypeName = true;
}
@@ -330,7 +332,7 @@
tok::semi);
return Actions.ActOnUsingDeclaration(CurScope, AS, UsingLoc, SS, Name,
- AttrList, IsTypeName);
+ AttrList, IsTypeName, TypenameLoc);
}
/// ParseStaticAssertDeclaration - Parse C++0x static_assert-declaratoion.
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Tue Nov 17 20:36:19 2009
@@ -1110,6 +1110,11 @@
/// functions into an OverloadedFunctionDecl.
FoundOverloaded,
+ /// @brief Name lookup found an unresolvable value declaration
+ /// and cannot yet complete. This only happens in C++ dependent
+ /// contexts with dependent using declarations.
+ FoundUnresolvedValue,
+
/// @brief Name lookup results in an ambiguity; use
/// getAmbiguityKind to figure out what kind of ambiguity
/// we have.
@@ -1417,6 +1422,7 @@
assert(ResultKind != NotFound || Decls.size() == 0);
assert(ResultKind != Found || Decls.size() == 1);
assert(ResultKind == NotFound || ResultKind == Found ||
+ ResultKind == FoundUnresolvedValue ||
(ResultKind == Ambiguous && Ambiguity == AmbiguousBaseSubobjects)
|| Decls.size() > 1);
assert((Paths != NULL) == (ResultKind == Ambiguous &&
@@ -2017,7 +2023,9 @@
SourceLocation IdentLoc,
DeclarationName Name,
AttributeList *AttrList,
- bool IsTypeName);
+ bool IsInstantiation,
+ bool IsTypeName,
+ SourceLocation TypenameLoc);
virtual DeclPtrTy ActOnUsingDeclaration(Scope *CurScope,
AccessSpecifier AS,
@@ -2025,7 +2033,8 @@
const CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
- bool IsTypeName);
+ bool IsTypeName,
+ SourceLocation TypenameLoc);
/// AddCXXDirectInitializerToDecl - This action is called immediately after
/// ActOnDeclarator, when a C++ direct initializer is present.
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Nov 17 20:36:19 2009
@@ -94,6 +94,7 @@
switch (Result.getResultKind()) {
case LookupResult::NotFound:
case LookupResult::FoundOverloaded:
+ case LookupResult::FoundUnresolvedValue:
return 0;
case LookupResult::Ambiguous:
@@ -166,6 +167,10 @@
} else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
T = Context.getObjCInterfaceType(IDecl);
+ } else if (UnresolvedUsingTypenameDecl *UUDecl =
+ dyn_cast<UnresolvedUsingTypenameDecl>(IIDecl)) {
+ // FIXME: preserve source structure information.
+ T = Context.getTypenameType(UUDecl->getTargetNestedNameSpecifier(), &II);
} else {
// If it's not plausibly a type, suppress diagnostics.
Result.suppressDiagnostics();
@@ -2446,7 +2451,9 @@
}
static bool isUsingDecl(Decl *D) {
- return isa<UsingDecl>(D) || isa<UnresolvedUsingDecl>(D);
+ return isa<UsingDecl>(D) ||
+ isa<UnresolvedUsingTypenameDecl>(D) ||
+ isa<UnresolvedUsingValueDecl>(D);
}
/// \brief Data used with FindOverriddenMethod
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Nov 17 20:36:19 2009
@@ -2809,7 +2809,8 @@
const CXXScopeSpec &SS,
UnqualifiedId &Name,
AttributeList *AttrList,
- bool IsTypeName) {
+ bool IsTypeName,
+ SourceLocation TypenameLoc) {
assert(S->getFlags() & Scope::DeclScope && "Invalid Scope.");
switch (Name.getKind()) {
@@ -2837,7 +2838,9 @@
DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
Name.getSourceRange().getBegin(),
- TargetName, AttrList, IsTypeName);
+ TargetName, AttrList,
+ /* IsInstantiation */ false,
+ IsTypeName, TypenameLoc);
if (UD) {
PushOnScopeChains(UD, S);
UD->setAccess(AS);
@@ -2872,13 +2875,20 @@
return Shadow;
}
+/// Builds a using declaration.
+///
+/// \param IsInstantiation - Whether this call arises from an
+/// instantiation of an unresolved using declaration. We treat
+/// the lookup differently for these declarations.
NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
SourceLocation UsingLoc,
const CXXScopeSpec &SS,
SourceLocation IdentLoc,
DeclarationName Name,
AttributeList *AttrList,
- bool IsTypeName) {
+ bool IsInstantiation,
+ bool IsTypeName,
+ SourceLocation TypenameLoc) {
assert(!SS.isInvalid() && "Invalid CXXScopeSpec.");
assert(IdentLoc.isValid() && "Invalid TargetName location.");
@@ -2895,9 +2905,16 @@
DeclContext *LookupContext = computeDeclContext(SS);
if (!LookupContext) {
- return UnresolvedUsingDecl::Create(Context, CurContext, UsingLoc,
- SS.getRange(), NNS,
- IdentLoc, Name, IsTypeName);
+ if (IsTypeName) {
+ return UnresolvedUsingTypenameDecl::Create(Context, CurContext,
+ UsingLoc, TypenameLoc,
+ SS.getRange(), NNS,
+ IdentLoc, Name);
+ } else {
+ return UnresolvedUsingValueDecl::Create(Context, CurContext,
+ UsingLoc, SS.getRange(), NNS,
+ IdentLoc, Name);
+ }
}
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(CurContext)) {
@@ -2929,7 +2946,12 @@
// hide tag declarations: tag names are visible through the using
// declaration even if hidden by ordinary names.
LookupResult R(*this, Name, IdentLoc, LookupOrdinaryName);
- R.setHideTags(false);
+
+ // We don't hide tags behind ordinary decls if we're in a
+ // non-dependent context, but in a dependent context, this is
+ // important for the stability of two-phase lookup.
+ if (!IsInstantiation)
+ R.setHideTags(false);
LookupQualifiedName(R, LookupContext);
@@ -2942,11 +2964,27 @@
if (R.isAmbiguous())
return 0;
- if (IsTypeName &&
- (R.getResultKind() != LookupResult::Found
- || !isa<TypeDecl>(R.getFoundDecl()))) {
- Diag(IdentLoc, diag::err_using_typename_non_type);
- return 0;
+ if (IsTypeName) {
+ // If we asked for a typename and got a non-type decl, error out.
+ if (R.getResultKind() != LookupResult::Found
+ || !isa<TypeDecl>(R.getFoundDecl())) {
+ Diag(IdentLoc, diag::err_using_typename_non_type);
+ for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
+ Diag((*I)->getUnderlyingDecl()->getLocation(),
+ diag::note_using_decl_target);
+ return 0;
+ }
+ } else {
+ // If we asked for a non-typename and we got a type, error out,
+ // but only if this is an instantiation of an unresolved using
+ // decl. Otherwise just silently find the type name.
+ if (IsInstantiation &&
+ R.getResultKind() == LookupResult::Found &&
+ isa<TypeDecl>(R.getFoundDecl())) {
+ Diag(IdentLoc, diag::err_using_dependent_value_is_type);
+ Diag(R.getFoundDecl()->getLocation(), diag::note_using_decl_target);
+ return 0;
+ }
}
// C++0x N2914 [namespace.udecl]p6:
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Nov 17 20:36:19 2009
@@ -977,7 +977,7 @@
else if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
return BuildDeclRefExpr(Template, Context.OverloadTy, Loc,
false, false, SS);
- else if (UnresolvedUsingDecl *UD = dyn_cast<UnresolvedUsingDecl>(D))
+ else if (UnresolvedUsingValueDecl *UD = dyn_cast<UnresolvedUsingValueDecl>(D))
return BuildDeclRefExpr(UD, Context.DependentTy, Loc,
/*TypeDependent=*/true,
/*ValueDependent=*/true, SS);
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Tue Nov 17 20:36:19 2009
@@ -245,7 +245,12 @@
unsigned N = Decls.size();
// Fast case: no possible ambiguity.
- if (N <= 1) return;
+ if (N == 0) return;
+ if (N == 1) {
+ if (isa<UnresolvedUsingValueDecl>(Decls[0]))
+ ResultKind = FoundUnresolvedValue;
+ return;
+ }
// Don't do any extra resolution if we've already resolved as ambiguous.
if (ResultKind == Ambiguous) return;
@@ -254,6 +259,7 @@
bool Ambiguous = false;
bool HasTag = false, HasFunction = false, HasNonFunction = false;
+ bool HasUnresolved = false;
unsigned UniqueTagIndex = 0;
@@ -266,12 +272,15 @@
// If it's not unique, pull something off the back (and
// continue at this index).
Decls[I] = Decls[--N];
- } else if (isa<UnresolvedUsingDecl>(D)) {
- // FIXME: support unresolved using decls
+ } else if (isa<UnresolvedUsingValueDecl>(D)) {
+ // FIXME: support unresolved using value declarations
Decls[I] = Decls[--N];
} else {
// Otherwise, do some decl type analysis and then continue.
- if (isa<TagDecl>(D)) {
+
+ if (isa<UnresolvedUsingValueDecl>(D)) {
+ HasUnresolved = true;
+ } else if (isa<TagDecl>(D)) {
if (HasTag)
Ambiguous = true;
UniqueTagIndex = I;
@@ -296,7 +305,8 @@
// wherever the object, function, or enumerator name is visible.
// But it's still an error if there are distinct tag types found,
// even if they're not visible. (ref?)
- if (HideTags && HasTag && !Ambiguous && (HasFunction || HasNonFunction))
+ if (HideTags && HasTag && !Ambiguous && !HasUnresolved &&
+ (HasFunction || HasNonFunction))
Decls[UniqueTagIndex] = Decls[--N];
Decls.set_size(N);
@@ -306,6 +316,8 @@
if (Ambiguous)
setAmbiguous(LookupResult::AmbiguousReference);
+ else if (HasUnresolved)
+ ResultKind = LookupResult::FoundUnresolvedValue;
else if (N > 1)
ResultKind = LookupResult::FoundOverloaded;
else
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Tue Nov 17 20:36:19 2009
@@ -4501,6 +4501,10 @@
Referenced = Result.getFoundDecl();
break;
+ case LookupResult::FoundUnresolvedValue:
+ llvm::llvm_unreachable("unresolved using decl in non-dependent context");
+ return QualType();
+
case LookupResult::FoundOverloaded:
DiagID = diag::err_typename_nested_not_type;
Referenced = *Result.begin();
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Tue Nov 17 20:36:19 2009
@@ -66,7 +66,8 @@
Decl *VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D);
Decl *VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D);
Decl *VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
- Decl *VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
+ Decl *VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
+ Decl *VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
// Base case. FIXME: Remove once we can instantiate everything.
Decl *VisitDecl(Decl *D) {
@@ -1025,8 +1026,33 @@
return Inst;
}
-Decl *
-TemplateDeclInstantiator::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
+Decl * TemplateDeclInstantiator
+ ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
+ NestedNameSpecifier *NNS =
+ SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
+ D->getTargetNestedNameRange(),
+ TemplateArgs);
+ if (!NNS)
+ return 0;
+
+ CXXScopeSpec SS;
+ SS.setRange(D->getTargetNestedNameRange());
+ SS.setScopeRep(NNS);
+
+ NamedDecl *UD =
+ SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
+ D->getUsingLoc(), SS, D->getLocation(),
+ D->getDeclName(), 0,
+ /*instantiation*/ true,
+ /*typename*/ true, D->getTypenameLoc());
+ if (UD)
+ SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD),
+ D);
+ return UD;
+}
+
+Decl * TemplateDeclInstantiator
+ ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
NestedNameSpecifier *NNS =
SemaRef.SubstNestedNameSpecifier(D->getTargetNestedNameSpecifier(),
D->getTargetNestedNameRange(),
@@ -1040,8 +1066,10 @@
NamedDecl *UD =
SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
- D->getLocation(), SS, D->getTargetNameLocation(),
- D->getDeclName(), 0, D->isTypeName());
+ D->getUsingLoc(), SS, D->getLocation(),
+ D->getDeclName(), 0,
+ /*instantiation*/ true,
+ /*typename*/ false, SourceLocation());
if (UD)
SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD),
D);
@@ -1724,7 +1752,13 @@
return false;
}
-static bool isInstantiationOf(UnresolvedUsingDecl *Pattern,
+static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern,
+ UsingDecl *Instance,
+ ASTContext &C) {
+ return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern;
+}
+
+static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern,
UsingDecl *Instance,
ASTContext &C) {
return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern;
@@ -1747,7 +1781,15 @@
static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
if (D->getKind() != Other->getKind()) {
- if (UnresolvedUsingDecl *UUD = dyn_cast<UnresolvedUsingDecl>(D)) {
+ if (UnresolvedUsingTypenameDecl *UUD
+ = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
+ if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+ return isInstantiationOf(UUD, UD, Ctx);
+ }
+ }
+
+ if (UnresolvedUsingValueDecl *UUD
+ = dyn_cast<UnresolvedUsingValueDecl>(D)) {
if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
return isInstantiationOf(UUD, UD, Ctx);
}
Modified: cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp (original)
+++ cfe/trunk/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp Tue Nov 17 20:36:19 2009
@@ -7,11 +7,11 @@
class foo {};
test<0> foo(foo); // expected-note {{candidate}}
-namespace A {
+namespace Test0 {
class foo { int x; };
test<1> foo(class foo);
- namespace B {
+ namespace A {
test<2> foo(class ::foo); // expected-note {{candidate}}
void test0() {
@@ -22,7 +22,7 @@
}
void test1() {
- using A::foo;
+ using Test0::foo;
class foo a;
test<1> _ = (foo)(a);
@@ -37,8 +37,31 @@
// But basic unqualified lookup is not.
test<2> _1 = (foo)(a);
- class A::foo b;
+ class Test0::foo b;
test<2> _2 = (foo)(b); // expected-error {{incompatible type passing}}
}
}
}
+
+namespace Test1 {
+ namespace A {
+ class a {};
+ }
+
+ namespace B {
+ typedef class {} b;
+ }
+
+ namespace C {
+ int c(); // expected-note {{target of using declaration}}
+ }
+
+ namespace D {
+ using typename A::a;
+ using typename B::b;
+ using typename C::c; // expected-error {{'typename' keyword used on a non-type}}
+
+ a _1 = A::a();
+ b _2 = B::b();
+ }
+}
Modified: cfe/trunk/test/SemaCXX/using-decl-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/using-decl-templates.cpp?rev=89184&r1=89183&r2=89184&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/using-decl-templates.cpp (original)
+++ cfe/trunk/test/SemaCXX/using-decl-templates.cpp Tue Nov 17 20:36:19 2009
@@ -2,12 +2,12 @@
template<typename T> struct A {
void f() { }
- struct N { };
+ struct N { }; // expected-note{{target of using declaration}}
};
template<typename T> struct B : A<T> {
using A<T>::f;
- using A<T>::N;
+ using A<T>::N; // expected-error{{dependent using declaration resolved to type without 'typename'}}
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'}}
More information about the cfe-commits
mailing list