[cfe-commits] r80434 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-using-decl.cpp
Anders Carlsson
andersca at mac.com
Sat Aug 29 12:37:28 PDT 2009
Author: andersca
Date: Sat Aug 29 14:37:28 2009
New Revision: 80434
URL: http://llvm.org/viewvc/llvm-project?rev=80434&view=rev
Log:
Improve instantiation of UnresolvedUsingDecls.
Added:
cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=80434&r1=80433&r2=80434&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Aug 29 14:37:28 2009
@@ -44,16 +44,18 @@
class TargetInfo;
// Decls
class Decl;
+ class FieldDecl;
+ class ObjCIvarDecl;
+ class ObjCIvarRefExpr;
class ObjCPropertyDecl;
class RecordDecl;
class TagDecl;
+ class TemplateTypeParmDecl;
class TranslationUnitDecl;
class TypeDecl;
class TypedefDecl;
- class TemplateTypeParmDecl;
- class FieldDecl;
- class ObjCIvarRefExpr;
- class ObjCIvarDecl;
+ class UnresolvedUsingDecl;
+ class UsingDecl;
namespace Builtin { class Context; }
@@ -171,6 +173,29 @@
/// class template X).
llvm::DenseMap<VarDecl *, VarDecl *> InstantiatedFromStaticDataMember;
+ /// \brief Keeps track of the UnresolvedUsingDecls from which UsingDecls
+ /// where created during instantiation.
+ ///
+ /// For example:
+ /// \code
+ /// template<typename T>
+ /// struct A {
+ /// void f();
+ /// };
+ ///
+ /// template<typename T>
+ /// struct B : A<T> {
+ /// using A<T>::f;
+ /// };
+ ///
+ /// template struct B<int>;
+ /// \endcode
+ ///
+ /// This mapping will contain an entry that maps from the UsingDecl in
+ /// B<int> to the UnresolvedUsingDecl in B<T>.
+ llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>
+ InstantiatedFromUnresolvedUsingDecl;
+
TranslationUnitDecl *TUDecl;
/// SourceMgr - The associated SourceManager object.
@@ -242,6 +267,10 @@
/// the static data member template \p Tmpl of a class template.
void setInstantiatedFromStaticDataMember(VarDecl *Inst, VarDecl *Tmpl);
+ UnresolvedUsingDecl *getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD);
+ void setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
+ UnresolvedUsingDecl *UUD);
+
TranslationUnitDecl *getTranslationUnitDecl() const { return TUDecl; }
const char *getCommentForDecl(const Decl *D);
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=80434&r1=80433&r2=80434&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Sat Aug 29 14:37:28 2009
@@ -242,6 +242,24 @@
InstantiatedFromStaticDataMember[Inst] = Tmpl;
}
+UnresolvedUsingDecl *
+ASTContext::getInstantiatedFromUnresolvedUsingDecl(UsingDecl *UUD) {
+ llvm::DenseMap<UsingDecl *, UnresolvedUsingDecl *>::iterator Pos
+ = InstantiatedFromUnresolvedUsingDecl.find(UUD);
+ if (Pos == InstantiatedFromUnresolvedUsingDecl.end())
+ return 0;
+
+ return Pos->second;
+}
+
+void
+ASTContext::setInstantiatedFromUnresolvedUsingDecl(UsingDecl *UD,
+ UnresolvedUsingDecl *UUD) {
+ assert(!InstantiatedFromUnresolvedUsingDecl[UD] &&
+ "Already noted what using decl what instantiated from");
+ InstantiatedFromUnresolvedUsingDecl[UD] = UUD;
+}
+
namespace {
class BeforeInTranslationUnit
: std::binary_function<SourceRange, SourceRange, bool> {
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=80434&r1=80433&r2=80434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Aug 29 14:37:28 2009
@@ -477,6 +477,11 @@
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();
+
// FIXME: nested-name-specifier for QualifiedDeclRefExpr
return SemaRef.BuildDeclarationNameExpr(E->getLocation(), InstD,
/*FIXME:*/false,
@@ -685,6 +690,8 @@
Invalid = true;
else if (FieldDecl *Field = dyn_cast<FieldDecl>(NewMember))
Fields.push_back(DeclPtrTy::make(Field));
+ else if (UsingDecl *UD = dyn_cast<UsingDecl>(NewMember))
+ Instantiation->addDecl(UD);
} else {
// FIXME: Eventually, a NULL return will mean that one of the
// instantiations was a semantic disaster, and we'll want to set Invalid =
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=80434&r1=80433&r2=80434&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Aug 29 14:37:28 2009
@@ -757,9 +757,14 @@
SS.setRange(D->getTargetNestedNameRange());
SS.setScopeRep(NNS);
- return SemaRef.BuildUsingDeclaration(D->getLocation(), SS,
- D->getTargetNameLocation(),
- D->getTargetName(), 0, D->isTypeName());
+ NamedDecl *UD =
+ SemaRef.BuildUsingDeclaration(D->getLocation(), SS,
+ D->getTargetNameLocation(),
+ D->getTargetName(), 0, D->isTypeName());
+ if (UD)
+ SemaRef.Context.setInstantiatedFromUnresolvedUsingDecl(cast<UsingDecl>(UD),
+ D);
+ return UD;
}
Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner,
@@ -1220,6 +1225,12 @@
return false;
}
+static bool isInstantiationOf(UnresolvedUsingDecl *Pattern,
+ UsingDecl *Instance,
+ ASTContext &C) {
+ return C.getInstantiatedFromUnresolvedUsingDecl(Instance) == Pattern;
+}
+
static bool isInstantiationOfStaticDataMember(VarDecl *Pattern,
VarDecl *Instance) {
assert(Instance->isStaticDataMember());
@@ -1236,9 +1247,16 @@
}
static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) {
- if (D->getKind() != Other->getKind())
- return false;
+ if (D->getKind() != Other->getKind()) {
+ if (UnresolvedUsingDecl *UUD = dyn_cast<UnresolvedUsingDecl>(D)) {
+ if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) {
+ return isInstantiationOf(UUD, UD, Ctx);
+ }
+ }
+ return false;
+ }
+
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other))
return isInstantiationOf(cast<CXXRecordDecl>(D), Record);
Added: cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp?rev=80434&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-using-decl.cpp Sat Aug 29 14:37:28 2009
@@ -0,0 +1,17 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+template<typename T>
+struct A {
+ void f();
+};
+
+template<typename T>
+struct B : A<T> {
+ using A<T>::f;
+
+ void g() {
+ f();
+ }
+};
+
+template struct B<int>;
More information about the cfe-commits
mailing list