[cfe-commits] r72015 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/AST/Decl.cpp lib/Sema/Sema.h lib/Sema/SemaTemplate.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-function-1.cpp test/SemaTemplate/temp_explicit.cpp
Douglas Gregor
dgregor at apple.com
Mon May 18 10:02:06 PDT 2009
Author: dgregor
Date: Mon May 18 12:01:57 2009
New Revision: 72015
URL: http://llvm.org/viewvc/llvm-project?rev=72015&view=rev
Log:
When instantiating the definition of a member function of a class
template, introduce that member function into the template
instantiation stack. Also, add diagnostics showing the member function
within the instantiation stack and clean up the qualified-name
printing so that we get something like:
note: in instantiation of member function 'Switch1<int, 2, 2>::f'
requested here
in the template instantiation backtrace.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/Decl.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp
cfe/trunk/test/SemaTemplate/temp_explicit.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon May 18 12:01:57 2009
@@ -745,6 +745,8 @@
"in instantiation of template class %0 requested here">;
def note_template_member_class_here : Note<
"in instantiation of member class %0 requested here">;
+def note_template_member_function_here : Note<
+ "in instantiation of member function %q0 requested here">;
def note_default_arg_instantiation_here : Note<
"in instantiation of default argument for '%0' required here">;
def err_field_instantiates_to_function : Error<
Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Mon May 18 12:01:57 2009
@@ -212,7 +212,15 @@
// scope class/struct/union. How do we handle this case?
break;
- if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
+ if (const ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
+ const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
+ std::string TemplateArgsStr
+ = TemplateSpecializationType::PrintTemplateArgumentList(
+ TemplateArgs.getFlatArgumentList(),
+ TemplateArgs.flat_size());
+ Names.push_back(Spec->getIdentifier()->getName() + TemplateArgsStr);
+ } else if (const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx))
Names.push_back(ND->getNameAsString());
else
break;
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon May 18 12:01:57 2009
@@ -2070,9 +2070,10 @@
/// Destruction of this object will pop the named instantiation off
/// the stack.
struct InstantiatingTemplate {
- /// \brief Note that we are instantiating a class template.
+ /// \brief Note that we are instantiating a class template,
+ /// function template, or a member thereof.
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- CXXRecordDecl *Entity,
+ Decl *Entity,
SourceRange InstantiationRange = SourceRange());
/// \brief Note that we are instantiating a default argument in a
@@ -2083,7 +2084,10 @@
unsigned NumTemplateArgs,
SourceRange InstantiationRange = SourceRange());
- ~InstantiatingTemplate();
+ /// \brief Note that we have finished instantiating this template.
+ void Clear();
+
+ ~InstantiatingTemplate() { Clear(); }
/// \brief Determines whether we have exceeded the maximum
/// recursive template instantiations.
@@ -2216,7 +2220,8 @@
InstantiateTemplateName(TemplateName Name, SourceLocation Loc,
const TemplateArgumentList &TemplateArgs);
- void InstantiateFunctionDefinition(FunctionDecl *Function);
+ void InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+ FunctionDecl *Function);
void InstantiateVariableDefinition(VarDecl *Var);
// Simple function for cloning expressions.
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Mon May 18 12:01:57 2009
@@ -2340,11 +2340,8 @@
// instantiation.
if (SpecializationRequiresInstantiation)
InstantiateClassTemplateSpecialization(Specialization, true);
- else {
- // Instantiate the members of this class template specialization.
- InstantiatingTemplate Inst(*this, TemplateLoc, Specialization);
+ else // Instantiate the members of this class template specialization.
InstantiateClassTemplateSpecializationMembers(TemplateLoc, Specialization);
- }
return DeclPtrTy::make(Specialization);
}
@@ -2405,12 +2402,9 @@
getTemplateInstantiationArgs(Record),
/*ExplicitInstantiation=*/true))
return true;
- } else {
- // Instantiate all of the members of class.
- InstantiatingTemplate Inst(*this, TemplateLoc, Record);
+ } else // Instantiate all of the members of class.
InstantiateClassMembers(TemplateLoc, Record,
getTemplateInstantiationArgs(Record));
- }
// FIXME: We don't have any representation for explicit instantiations of
// member classes. Such a representation is not needed for compilation, but it
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon May 18 12:01:57 2009
@@ -46,7 +46,7 @@
Sema::InstantiatingTemplate::
InstantiatingTemplate(Sema &SemaRef, SourceLocation PointOfInstantiation,
- CXXRecordDecl *Entity,
+ Decl *Entity,
SourceRange InstantiationRange)
: SemaRef(SemaRef) {
@@ -89,9 +89,11 @@
}
}
-Sema::InstantiatingTemplate::~InstantiatingTemplate() {
- if (!Invalid)
+void Sema::InstantiatingTemplate::Clear() {
+ if (!Invalid) {
SemaRef.ActiveTemplateInstantiations.pop_back();
+ Invalid = true;
+ }
}
bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
@@ -120,14 +122,24 @@
++Active) {
switch (Active->Kind) {
case ActiveTemplateInstantiation::TemplateInstantiation: {
- unsigned DiagID = diag::note_template_member_class_here;
- CXXRecordDecl *Record = (CXXRecordDecl *)Active->Entity;
- if (isa<ClassTemplateSpecializationDecl>(Record))
- DiagID = diag::note_template_class_instantiation_here;
- Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
- DiagID)
- << Context.getTypeDeclType(Record)
- << Active->InstantiationRange;
+ Decl *D = reinterpret_cast<Decl *>(Active->Entity);
+ if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
+ unsigned DiagID = diag::note_template_member_class_here;
+ if (isa<ClassTemplateSpecializationDecl>(Record))
+ DiagID = diag::note_template_class_instantiation_here;
+ Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+ DiagID)
+ << Context.getTypeDeclType(Record)
+ << Active->InstantiationRange;
+ } else {
+ FunctionDecl *Function = cast<FunctionDecl>(D);
+ unsigned DiagID = diag::note_template_member_function_here;
+ // FIXME: check for a function template
+ Diags.Report(FullSourceLoc(Active->PointOfInstantiation, SourceMgr),
+ DiagID)
+ << Function
+ << Active->InstantiationRange;
+ }
break;
}
@@ -768,8 +780,10 @@
CurContext = PreviousContext;
// If this is an explicit instantiation, instantiate our members, too.
- if (!Invalid && ExplicitInstantiation)
+ if (!Invalid && ExplicitInstantiation) {
+ Inst.Clear();
InstantiateClassMembers(PointOfInstantiation, Instantiation, TemplateArgs);
+ }
return Invalid;
}
@@ -820,7 +834,7 @@
D != DEnd; ++D) {
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(*D)) {
if (!Function->getBody(Context))
- InstantiateFunctionDefinition(Function);
+ InstantiateFunctionDefinition(PointOfInstantiation, Function);
} else if (VarDecl *Var = dyn_cast<VarDecl>(*D)) {
const VarDecl *Def = 0;
if (!Var->getDefinition(Def))
@@ -829,7 +843,7 @@
if (!Record->isInjectedClassName() && !Record->getDefinition(Context)) {
assert(Record->getInstantiatedFromMemberClass() &&
"Missing instantiated-from-template information");
- InstantiateClass(Record->getLocation(), Record,
+ InstantiateClass(PointOfInstantiation, Record,
Record->getInstantiatedFromMemberClass(),
TemplateArgs, true);
}
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon May 18 12:01:57 2009
@@ -574,7 +574,8 @@
///
/// \param Function the already-instantiated declaration of a
/// function.
-void Sema::InstantiateFunctionDefinition(FunctionDecl *Function) {
+void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
+ FunctionDecl *Function) {
// FIXME: make this work for function template specializations, too.
if (Function->isInvalidDecl())
@@ -590,7 +591,9 @@
if (!Pattern)
return;
- // FIXME: add to the instantiation stack.
+ InstantiatingTemplate Inst(*this, PointOfInstantiation, Function);
+ if (Inst)
+ return;
ActOnStartOfFunctionDef(0, DeclPtrTy::make(Function));
Modified: cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-function-1.cpp Mon May 18 12:01:57 2009
@@ -1,4 +1,4 @@
-// RUN: clang-cc -fsyntax-only -verify %s
+// RUN: clang-cc -fsyntax-only %s
template<typename T, typename U>
struct X0 {
void f(T x, U y) {
@@ -47,8 +47,8 @@
}
};
-template struct X4<void>; // expected-note{{in instantiation of template class 'X4<void>' requested here}}
-template struct X4<int>; // expected-note{{in instantiation of template class 'X4<int>' requested here}}
+template struct X4<void>; // expected-note{{in instantiation of}}
+template struct X4<int>; // expected-note{{in instantiation of}}
struct Incomplete; // expected-note{{forward declaration}}
Modified: cfe/trunk/test/SemaTemplate/temp_explicit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/temp_explicit.cpp?rev=72015&r1=72014&r2=72015&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/temp_explicit.cpp (original)
+++ cfe/trunk/test/SemaTemplate/temp_explicit.cpp Mon May 18 12:01:57 2009
@@ -49,7 +49,7 @@
// Check that explicit instantiations instantiate member classes.
template<typename T> struct X3 {
- struct Inner { // expected-note{{here}}
+ struct Inner {
void f(T*); // expected-error{{pointer to a reference}}
};
};
@@ -59,8 +59,8 @@
template struct X3<int&>; // expected-note{{instantiation}}
template<typename T> struct X4 {
- struct Inner { // expected-note 2{{here}}
- struct VeryInner { // expected-note 2{{here}}
+ struct Inner {
+ struct VeryInner {
void f(T*); // expected-error 2{{pointer to a reference}}
};
};
@@ -82,7 +82,7 @@
};
struct Inner2 {
- struct VeryInner { // expected-note 2{{instantiation}}
+ struct VeryInner {
void g(T*); // expected-error 2{{pointer to a reference}}
};
};
More information about the cfe-commits
mailing list