[cfe-commits] r141954 - in /cfe/trunk: include/clang/Sema/Sema.h lib/Sema/SemaDecl.cpp lib/Sema/SemaTemplate.cpp test/SemaTemplate/current-instantiation.cpp
Douglas Gregor
dgregor at apple.com
Fri Oct 14 08:31:12 PDT 2011
Author: dgregor
Date: Fri Oct 14 10:31:12 2011
New Revision: 141954
URL: http://llvm.org/viewvc/llvm-project?rev=141954&view=rev
Log:
When declaring an out-of-line template, attempt to rebuild any types
within the template parameter list that may have changed now that we
know the current instantiation. Fixes <rdar://problem/10194295>.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/test/SemaTemplate/current-instantiation.cpp
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=141954&r1=141953&r2=141954&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Oct 14 10:31:12 2011
@@ -4134,7 +4134,9 @@
bool RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS);
ExprResult RebuildExprInCurrentInstantiation(Expr *E);
-
+ bool RebuildTemplateParamsInCurrentInstantiation(
+ TemplateParameterList *Params);
+
std::string
getTemplateArgumentBindingsText(const TemplateParameterList *Params,
const TemplateArgumentList &Args);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=141954&r1=141953&r2=141954&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Oct 14 10:31:12 2011
@@ -4789,6 +4789,16 @@
Diag(NewFD->getLocation(), diag::err_destructor_template);
return 0;
}
+
+ // If we're adding a template to a dependent context, we may need to
+ // rebuilding some of the types used within the template parameter list,
+ // now that we know what the current instantiation is.
+ if (DC->isDependentContext()) {
+ ContextRAII SavedContext(*this, DC);
+ if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams))
+ Invalid = true;
+ }
+
FunctionTemplate = FunctionTemplateDecl::Create(Context, DC,
NewFD->getLocation(),
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=141954&r1=141953&r2=141954&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Fri Oct 14 10:31:12 2011
@@ -846,6 +846,15 @@
if (RequireCompleteDeclContext(SS, SemanticContext))
return true;
+ // If we're adding a template to a dependent context, we may need to
+ // rebuilding some of the types used within the template parameter list,
+ // now that we know what the current instantiation is.
+ if (SemanticContext->isDependentContext()) {
+ ContextRAII SavedContext(*this, SemanticContext);
+ if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams))
+ Invalid = true;
+ }
+
LookupQualifiedName(Previous, SemanticContext);
} else {
SemanticContext = CurContext;
@@ -6699,6 +6708,45 @@
return false;
}
+/// \brief Rebuild the template parameters now that we know we're in a current
+/// instantiation.
+bool Sema::RebuildTemplateParamsInCurrentInstantiation(
+ TemplateParameterList *Params) {
+ for (unsigned I = 0, N = Params->size(); I != N; ++I) {
+ Decl *Param = Params->getParam(I);
+
+ // There is nothing to rebuild in a type parameter.
+ if (isa<TemplateTypeParmDecl>(Param))
+ continue;
+
+ // Rebuild the template parameter list of a template template parameter.
+ if (TemplateTemplateParmDecl *TTP
+ = dyn_cast<TemplateTemplateParmDecl>(Param)) {
+ if (RebuildTemplateParamsInCurrentInstantiation(
+ TTP->getTemplateParameters()))
+ return true;
+
+ continue;
+ }
+
+ // Rebuild the type of a non-type template parameter.
+ NonTypeTemplateParmDecl *NTTP = cast<NonTypeTemplateParmDecl>(Param);
+ TypeSourceInfo *NewTSI
+ = RebuildTypeInCurrentInstantiation(NTTP->getTypeSourceInfo(),
+ NTTP->getLocation(),
+ NTTP->getDeclName());
+ if (!NewTSI)
+ return true;
+
+ if (NewTSI != NTTP->getTypeSourceInfo()) {
+ NTTP->setTypeSourceInfo(NewTSI);
+ NTTP->setType(NewTSI->getType());
+ }
+ }
+
+ return false;
+}
+
/// \brief Produces a formatted string that describes the binding of
/// template parameters to template arguments.
std::string
Modified: cfe/trunk/test/SemaTemplate/current-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/current-instantiation.cpp?rev=141954&r1=141953&r2=141954&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/current-instantiation.cpp (original)
+++ cfe/trunk/test/SemaTemplate/current-instantiation.cpp Fri Oct 14 10:31:12 2011
@@ -215,3 +215,23 @@
};
};
}
+
+namespace rdar10194295 {
+ template<typename XT>
+ class X {
+ public:
+ enum Enum { Yes, No };
+ template<Enum> void foo();
+ template<Enum> class Inner;
+ };
+
+ template<typename XT>
+ template<typename X<XT>::Enum>
+ void X<XT>::foo()
+ {
+ }
+
+ template<typename XT>
+ template<typename X<XT>::Enum>
+ class X<XT>::Inner { };
+}
More information about the cfe-commits
mailing list