[cfe-commits] r89048 - in /cfe/trunk: include/clang/AST/DeclBase.h include/clang/AST/DeclCXX.h include/clang/AST/DeclNodes.def lib/AST/Decl.cpp lib/AST/DeclBase.cpp lib/AST/DeclCXX.cpp lib/AST/DeclPrinter.cpp lib/Sema/Sema.h lib/Sema/SemaCodeComplete.cpp lib/Sema/SemaDeclCXX.cpp lib/Sema/SemaLookup.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp
John McCall
rjmccall at apple.com
Mon Nov 16 21:59:44 PST 2009
Author: rjmccall
Date: Mon Nov 16 23:59:44 2009
New Revision: 89048
URL: http://llvm.org/viewvc/llvm-project?rev=89048&view=rev
Log:
Instead of hanging a using declaration's target decls directly off the using
decl, create shadow declarations and put them in scope like normal.
Work in progress.
Modified:
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/include/clang/AST/DeclNodes.def
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/DeclCXX.cpp
cfe/trunk/lib/AST/DeclPrinter.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaCodeComplete.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaLookup.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon Nov 16 23:59:44 2009
@@ -79,9 +79,11 @@
/// namespaces, labels, tags, members and ordinary
/// identifiers. These are meant as bitmasks, so that searches in
/// C++ can look into the "tag" namespace during ordinary lookup. We
- /// use additional namespaces for Objective-C entities. We also
- /// put C++ friend declarations (of previously-undeclared entities) in
- /// shadow namespaces.
+ /// use additional namespaces for Objective-C entities. We also put
+ /// C++ friend declarations (of previously-undeclared entities) in
+ /// shadow namespaces, and 'using' declarations (as opposed to their
+ /// implicit shadow declarations) can be found in their own
+ /// namespace.
enum IdentifierNamespace {
IDNS_Label = 0x1,
IDNS_Tag = 0x2,
@@ -91,7 +93,8 @@
IDNS_ObjCImplementation = 0x20,
IDNS_ObjCCategoryImpl = 0x40,
IDNS_OrdinaryFriend = 0x80,
- IDNS_TagFriend = 0x100
+ IDNS_TagFriend = 0x100,
+ IDNS_Using = 0x200
};
/// ObjCDeclQualifier - Qualifier used on types in method declarations
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Nov 16 23:59:44 2009
@@ -1644,6 +1644,56 @@
static bool classof(const NamespaceAliasDecl *D) { return true; }
};
+/// UsingShadowDecl - Represents a shadow declaration introduced into
+/// a scope by a (resolved) using declaration. For example,
+///
+/// namespace A {
+/// void foo();
+/// }
+/// namespace B {
+/// using A::foo(); // <- a UsingDecl
+/// // Also creates a UsingShadowDecl for A::foo in B
+/// }
+///
+class UsingShadowDecl : public NamedDecl {
+ /// The referenced declaration.
+ NamedDecl *Underlying;
+
+ /// The using declaration which introduced this decl.
+ UsingDecl *Using;
+
+ UsingShadowDecl(DeclContext *DC, SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target)
+ : NamedDecl(UsingShadow, DC, Loc, Target->getDeclName()),
+ Underlying(Target), Using(Using) {
+ IdentifierNamespace = Target->getIdentifierNamespace();
+ setImplicit();
+ }
+
+public:
+ static UsingShadowDecl *Create(ASTContext &C, DeclContext *DC,
+ SourceLocation Loc, UsingDecl *Using,
+ NamedDecl *Target) {
+ return new (C) UsingShadowDecl(DC, Loc, Using, Target);
+ }
+
+ /// Gets the underlying declaration which has been brought into the
+ /// local scope.
+ NamedDecl *getTargetDecl() const {
+ return Underlying;
+ }
+
+ /// Gets the using declaration to which this declaration is tied.
+ UsingDecl *getUsingDecl() const {
+ return Using;
+ }
+
+ static bool classof(const Decl *D) {
+ return D->getKind() == Decl::UsingShadow;
+ }
+ static bool classof(const UsingShadowDecl *D) { return true; }
+};
+
/// UsingDecl - Represents a C++ using-declaration. For example:
/// using someNameSpace::someIdentifier;
class UsingDecl : public NamedDecl {
@@ -1651,29 +1701,26 @@
/// preceding the declaration name.
SourceRange NestedNameRange;
- /// \brief The source location of the target declaration name.
- SourceLocation TargetNameLocation;
-
/// \brief The source location of the "using" location itself.
SourceLocation UsingLocation;
- /// \brief Target declaration.
- NamedDecl* TargetDecl;
-
/// \brief Target nested name specifier.
- NestedNameSpecifier* TargetNestedNameDecl;
+ NestedNameSpecifier* TargetNestedName;
+
+ /// \brief The collection of shadow declarations associated with
+ /// this using declaration. This set can change as a class is
+ /// processed.
+ llvm::SmallPtrSet<UsingShadowDecl*, 8> Shadows;
// \brief Has 'typename' keyword.
bool IsTypeName;
UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
- SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg)
- : NamedDecl(Decl::Using, DC, L, Target->getDeclName()),
- NestedNameRange(NNR), TargetNameLocation(TargetNL),
- UsingLocation(UL), TargetDecl(Target),
- TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) {
- this->IdentifierNamespace = TargetDecl->getIdentifierNamespace();
+ SourceLocation UL, NestedNameSpecifier* TargetNNS,
+ DeclarationName Name, bool IsTypeNameArg)
+ : NamedDecl(Decl::Using, DC, L, Name),
+ NestedNameRange(NNR), UsingLocation(UL), TargetNestedName(TargetNNS),
+ IsTypeName(IsTypeNameArg) {
}
public:
@@ -1681,28 +1728,37 @@
/// preceding the namespace name.
SourceRange getNestedNameRange() { return NestedNameRange; }
- /// \brief Returns the source location of the target declaration name.
- SourceLocation getTargetNameLocation() { return TargetNameLocation; }
-
/// \brief Returns the source location of the "using" location itself.
SourceLocation getUsingLocation() { return UsingLocation; }
- /// \brief getTargetDecl - Returns target specified by using-decl.
- NamedDecl *getTargetDecl() { return TargetDecl; }
- const NamedDecl *getTargetDecl() const { return TargetDecl; }
-
/// \brief Get target nested name declaration.
NestedNameSpecifier* getTargetNestedNameDecl() {
- return TargetNestedNameDecl;
+ return TargetNestedName;
}
/// isTypeName - Return true if using decl has 'typename'.
bool isTypeName() const { return IsTypeName; }
+ typedef llvm::SmallPtrSet<UsingShadowDecl*,8>::const_iterator shadow_iterator;
+ shadow_iterator shadow_begin() const { return Shadows.begin(); }
+ shadow_iterator shadow_end() const { return Shadows.end(); }
+
+ void addShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.insert(S)) {
+ assert(false && "declaration already in set");
+ }
+ }
+ void removeShadowDecl(UsingShadowDecl *S) {
+ assert(S->getUsingDecl() == this);
+ if (!Shadows.erase(S)) {
+ assert(false && "declaration not in set");
+ }
+ }
+
static UsingDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
- SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg);
+ SourceLocation IdentL, SourceRange NNR, SourceLocation UsingL,
+ NestedNameSpecifier* TargetNNS, DeclarationName Name, bool IsTypeNameArg);
static bool classof(const Decl *D) {
return D->getKind() == Decl::Using;
Modified: cfe/trunk/include/clang/AST/DeclNodes.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclNodes.def?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclNodes.def (original)
+++ cfe/trunk/include/clang/AST/DeclNodes.def Mon Nov 16 23:59:44 2009
@@ -110,6 +110,7 @@
DECL(TemplateTemplateParm, TemplateDecl)
DECL(Using, NamedDecl)
DECL(UnresolvedUsing, NamedDecl)
+ DECL(UsingShadow, NamedDecl)
DECL(ObjCMethod, NamedDecl)
DECL(ObjCContainer, NamedDecl)
DECL(ObjCCategory, ObjCContainerDecl)
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon Nov 16 23:59:44 2009
@@ -289,6 +289,10 @@
if (isa<ObjCInterfaceDecl>(this) && isa<ObjCCompatibleAliasDecl>(OldD))
return true;
+ if (isa<UsingShadowDecl>(this) && isa<UsingShadowDecl>(OldD))
+ return cast<UsingShadowDecl>(this)->getTargetDecl() ==
+ cast<UsingShadowDecl>(OldD)->getTargetDecl();
+
// For non-function declarations, if the declarations are of the
// same kind then this must be a redeclaration, or semantic analysis
// would not have given us the new declaration.
@@ -308,7 +312,7 @@
NamedDecl *NamedDecl::getUnderlyingDecl() {
NamedDecl *ND = this;
while (true) {
- if (UsingDecl *UD = dyn_cast<UsingDecl>(ND))
+ if (UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(ND))
ND = UD->getTargetDecl();
else if (ObjCCompatibleAliasDecl *AD
= dyn_cast<ObjCCompatibleAliasDecl>(ND))
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Nov 16 23:59:44 2009
@@ -97,7 +97,7 @@
}
bool Decl::isFunctionOrFunctionTemplate() const {
- if (const UsingDecl *UD = dyn_cast<UsingDecl>(this))
+ if (const UsingShadowDecl *UD = dyn_cast<UsingShadowDecl>(this))
return UD->getTargetDecl()->isFunctionOrFunctionTemplate();
return isa<FunctionDecl>(this) || isa<FunctionTemplateDecl>(this);
@@ -189,10 +189,11 @@
unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) {
switch (DeclKind) {
- default:
- if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast)
- return IDNS_Ordinary;
- assert(0 && "Unknown decl kind!");
+ case Function:
+ case CXXMethod:
+ case CXXConstructor:
+ case CXXDestructor:
+ case CXXConversion:
case OverloadedFunction:
case Typedef:
case EnumConstant:
@@ -200,8 +201,6 @@
case ImplicitParam:
case ParmVar:
case NonTypeTemplateParm:
- case Using:
- case UnresolvedUsing:
case ObjCMethod:
case ObjCContainer:
case ObjCCategory:
@@ -210,6 +209,15 @@
case ObjCCompatibleAlias:
return IDNS_Ordinary;
+ case UsingShadow:
+ return 0; // we'll actually overwrite this later
+
+ case UnresolvedUsing:
+ return IDNS_Tag | IDNS_Ordinary | IDNS_Using;
+
+ case Using:
+ return IDNS_Using;
+
case ObjCProtocol:
return IDNS_ObjCProtocol;
@@ -256,6 +264,8 @@
case ClassTemplatePartialSpecialization:
return 0;
}
+
+ return 0;
}
void Decl::addAttr(Attr *NewAttr) {
Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Mon Nov 16 23:59:44 2009
@@ -914,11 +914,10 @@
}
UsingDecl *UsingDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
- SourceLocation UL, NamedDecl* Target,
- NestedNameSpecifier* TargetNNS, bool IsTypeNameArg) {
- return new (C) UsingDecl(DC, L, NNR, TargetNL, UL, Target,
- TargetNNS, IsTypeNameArg);
+ SourceLocation L, SourceRange NNR, SourceLocation UL,
+ NestedNameSpecifier* TargetNNS, DeclarationName Name,
+ bool IsTypeNameArg) {
+ return new (C) UsingDecl(DC, L, NNR, UL, TargetNNS, Name, IsTypeNameArg);
}
UnresolvedUsingDecl *UnresolvedUsingDecl::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=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclPrinter.cpp (original)
+++ cfe/trunk/lib/AST/DeclPrinter.cpp Mon Nov 16 23:59:44 2009
@@ -73,6 +73,7 @@
void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
void VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D);
void VisitUsingDecl(UsingDecl *D);
+ void VisitUsingShadowDecl(UsingShadowDecl *D);
};
}
@@ -825,7 +826,7 @@
void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
Out << "using ";
D->getTargetNestedNameDecl()->print(Out, Policy);
- Out << D->getTargetDecl()->getNameAsString();
+ Out << D->getNameAsString();
}
void DeclPrinter::VisitUnresolvedUsingDecl(UnresolvedUsingDecl *D) {
@@ -833,3 +834,7 @@
D->getTargetNestedNameSpecifier()->print(Out, Policy);
Out << D->getTargetName().getAsString();
}
+
+void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
+ // ignore
+}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Nov 16 23:59:44 2009
@@ -1197,6 +1197,7 @@
LookupKind(LookupKind),
IDNS(0),
Redecl(Redecl != NotForRedeclaration),
+ HideTags(true),
Diagnose(Redecl == NotForRedeclaration)
{}
@@ -1212,6 +1213,7 @@
LookupKind(Other.LookupKind),
IDNS(Other.IDNS),
Redecl(Other.Redecl),
+ HideTags(Other.HideTags),
Diagnose(false)
{}
@@ -1235,6 +1237,12 @@
return Redecl;
}
+ /// Sets whether tag declarations should be hidden by non-tag
+ /// declarations during resolution. The default is true.
+ void setHideTags(bool Hide) {
+ HideTags = Hide;
+ }
+
/// The identifier namespace of this lookup. This information is
/// private to the lookup routines.
unsigned getIdentifierNamespace() const {
@@ -1441,6 +1449,10 @@
unsigned IDNS; // ill-defined until set by lookup
bool Redecl;
+ /// \brief True if tag declarations should be hidden if non-tags
+ /// are present
+ bool HideTags;
+
bool Diagnose;
};
@@ -2007,7 +2019,8 @@
SourceLocation IdentLoc,
IdentifierInfo *Ident);
- NamedDecl *BuildUsingDeclaration(SourceLocation UsingLoc,
+ NamedDecl *BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
+ SourceLocation UsingLoc,
const CXXScopeSpec &SS,
SourceLocation IdentLoc,
DeclarationName Name,
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Mon Nov 16 23:59:44 2009
@@ -198,7 +198,7 @@
return;
// Look through using declarations.
- if (UsingDecl *Using = dyn_cast<UsingDecl>(R.Declaration))
+ if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier),
CurContext);
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Nov 16 23:59:44 2009
@@ -2835,7 +2835,7 @@
}
DeclarationName TargetName = GetNameFromUnqualifiedId(Name);
- NamedDecl *UD = BuildUsingDeclaration(UsingLoc, SS,
+ NamedDecl *UD = BuildUsingDeclaration(S, AS, UsingLoc, SS,
Name.getSourceRange().getBegin(),
TargetName, AttrList, IsTypeName);
if (UD) {
@@ -2846,7 +2846,34 @@
return DeclPtrTy::make(UD);
}
-NamedDecl *Sema::BuildUsingDeclaration(SourceLocation UsingLoc,
+/// Builds a shadow declaration corresponding to a 'using' declaration.
+static UsingShadowDecl *BuildUsingShadowDecl(Sema &SemaRef, Scope *S,
+ AccessSpecifier AS,
+ UsingDecl *UD, NamedDecl *Orig) {
+ // FIXME: diagnose hiding, collisions
+
+ // If we resolved to another shadow declaration, just coalesce them.
+ if (isa<UsingShadowDecl>(Orig)) {
+ Orig = cast<UsingShadowDecl>(Orig)->getTargetDecl();
+ assert(!isa<UsingShadowDecl>(Orig) && "nested shadow declaration");
+ }
+
+ UsingShadowDecl *Shadow
+ = UsingShadowDecl::Create(SemaRef.Context, SemaRef.CurContext,
+ UD->getLocation(), UD, Orig);
+ UD->addShadowDecl(Shadow);
+
+ if (S)
+ SemaRef.PushOnScopeChains(Shadow, S);
+ else
+ SemaRef.CurContext->addDecl(Shadow);
+ Shadow->setAccess(AS);
+
+ return Shadow;
+}
+
+NamedDecl *Sema::BuildUsingDeclaration(Scope *S, AccessSpecifier AS,
+ SourceLocation UsingLoc,
const CXXScopeSpec &SS,
SourceLocation IdentLoc,
DeclarationName Name,
@@ -2880,7 +2907,7 @@
// anonymous union that is a member of a base class of the class being
// defined, or shall refer to an enumerator for an enumeration type that is
// a member of a base class of the class being defined.
-
+
CXXRecordDecl *LookupRD = dyn_cast<CXXRecordDecl>(LookupContext);
if (!LookupRD || !RD->isDerivedFrom(LookupRD)) {
Diag(SS.getRange().getBegin(),
@@ -2898,8 +2925,12 @@
}
}
- // Lookup target name.
+ // Look up the target name. Unlike most lookups, we do not want to
+ // 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);
+
LookupQualifiedName(R, LookupContext);
if (R.empty()) {
@@ -2908,24 +2939,33 @@
return 0;
}
- // FIXME: handle ambiguity?
- NamedDecl *ND = R.getAsSingleDecl(Context);
+ if (R.isAmbiguous())
+ return 0;
- if (IsTypeName && !isa<TypeDecl>(ND)) {
+ if (IsTypeName &&
+ (R.getResultKind() != LookupResult::Found
+ || !isa<TypeDecl>(R.getFoundDecl()))) {
Diag(IdentLoc, diag::err_using_typename_non_type);
return 0;
}
// C++0x N2914 [namespace.udecl]p6:
// A using-declaration shall not name a namespace.
- if (isa<NamespaceDecl>(ND)) {
+ if (R.getResultKind() == LookupResult::Found
+ && isa<NamespaceDecl>(R.getFoundDecl())) {
Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace)
<< SS.getRange();
return 0;
}
- return UsingDecl::Create(Context, CurContext, IdentLoc, SS.getRange(),
- ND->getLocation(), UsingLoc, ND, NNS, IsTypeName);
+ UsingDecl *UD = UsingDecl::Create(Context, CurContext, IdentLoc,
+ SS.getRange(), UsingLoc, NNS, Name,
+ IsTypeName);
+
+ for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I)
+ BuildUsingShadowDecl(*this, S, AS, UD, *I);
+
+ return UD;
}
/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Mon Nov 16 23:59:44 2009
@@ -297,7 +297,7 @@
// 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 (HasTag && !Ambiguous && (HasFunction || HasNonFunction))
+ if (HideTags && HasTag && !Ambiguous && (HasFunction || HasNonFunction))
Decls[UniqueTagIndex] = Decls[--N];
Decls.set_size(N);
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Nov 16 23:59:44 2009
@@ -788,10 +788,46 @@
if (!InstD)
return SemaRef.ExprError();
- // If we instantiated an UnresolvedUsingDecl and got back an UsingDecl,
- // we need to get the underlying decl.
- // FIXME: Is this correct? Maybe FindInstantiatedDecl should do this?
- InstD = InstD->getUnderlyingDecl();
+ // Flatten using declarations into their shadow declarations.
+ if (isa<UsingDecl>(InstD)) {
+ UsingDecl *UD = cast<UsingDecl>(InstD);
+
+ bool HasNonFunction = false;
+
+ llvm::SmallVector<NamedDecl*, 8> Decls;
+ for (UsingDecl::shadow_iterator I = UD->shadow_begin(),
+ E = UD->shadow_end(); I != E; ++I) {
+ NamedDecl *TD = (*I)->getTargetDecl();
+ if (!TD->isFunctionOrFunctionTemplate())
+ HasNonFunction = true;
+
+ Decls.push_back(TD);
+ }
+
+ if (Decls.empty())
+ return SemaRef.ExprError();
+
+ if (Decls.size() == 1)
+ InstD = Decls[0];
+ else if (!HasNonFunction) {
+ OverloadedFunctionDecl *OFD
+ = OverloadedFunctionDecl::Create(SemaRef.Context,
+ UD->getDeclContext(),
+ UD->getDeclName());
+ for (llvm::SmallVectorImpl<NamedDecl*>::iterator I = Decls.begin(),
+ E = Decls.end(); I != E; ++I)
+ if (isa<FunctionDecl>(*I))
+ OFD->addOverload(cast<FunctionDecl>(*I));
+ else
+ OFD->addOverload(cast<FunctionTemplateDecl>(*I));
+
+ InstD = OFD;
+ } else {
+ // FIXME
+ assert(false && "using declaration resolved to mixed set");
+ return SemaRef.ExprError();
+ }
+ }
CXXScopeSpec SS;
NestedNameSpecifier *Qualifier = 0;
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=89048&r1=89047&r2=89048&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Nov 16 23:59:44 2009
@@ -1019,9 +1019,9 @@
SS.setScopeRep(NNS);
NamedDecl *UD =
- SemaRef.BuildUsingDeclaration(D->getLocation(), SS,
- D->getTargetNameLocation(),
- D->getTargetName(), 0, D->isTypeName());
+ SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(),
+ D->getLocation(), SS, D->getTargetNameLocation(),
+ D->getDeclName(), 0, D->isTypeName());
if (UD)
SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD),
D);
More information about the cfe-commits
mailing list