[cfe-commits] r103323 - in /cfe/trunk: include/clang/AST/RecursiveASTVisitor.h lib/Frontend/BoostConAction.cpp lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp test/SemaTemplate/instantiate-non-dependent-types.cpp
Douglas Gregor
dgregor at apple.com
Fri May 7 16:12:07 PDT 2010
Author: dgregor
Date: Fri May 7 18:12:07 2010
New Revision: 103323
URL: http://llvm.org/viewvc/llvm-project?rev=103323&view=rev
Log:
When we encounter a non-dependent type during template instantiation,
mark any declarations we see inside of that type as
"referenced". Fixes PR7079.
Added:
cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp
Modified:
cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
cfe/trunk/lib/Frontend/BoostConAction.cpp
cfe/trunk/lib/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
+++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Fri May 7 18:12:07 2010
@@ -257,6 +257,8 @@
case Type::Class: DISPATCH(Class##Type, Class##Type, T.getTypePtr());
#include "clang/AST/TypeNodes.def"
}
+
+ return false;
}
template<typename Derived>
@@ -291,6 +293,8 @@
case NestedNameSpecifier::TypeSpecWithTemplate:
return Visit(QualType(NNS->getAsType(), 0));
}
+
+ return false;
}
template<typename Derived>
@@ -327,6 +331,8 @@
return getDerived().VisitTemplateArguments(Arg.pack_begin(),
Arg.pack_size());
}
+
+ return false;
}
template<typename Derived>
@@ -614,7 +620,8 @@
return true;
if (T->getTemplateId() &&
- getDerived().VisitTemplateSpecializationType(T->getTemplateId()))
+ getDerived().VisitTemplateSpecializationType(
+ const_cast<TemplateSpecializationType *>(T->getTemplateId())))
return true;
return getDerived().VisitType(T);
Modified: cfe/trunk/lib/Frontend/BoostConAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/BoostConAction.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/BoostConAction.cpp (original)
+++ cfe/trunk/lib/Frontend/BoostConAction.cpp Fri May 7 18:12:07 2010
@@ -10,6 +10,7 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include <cstdio>
+#include <iostream>
using namespace clang;
namespace {
@@ -19,6 +20,11 @@
/// HandleTranslationUnit - This method is called when the ASTs for entire
/// translation unit have been parsed.
virtual void HandleTranslationUnit(ASTContext &Ctx);
+
+ bool VisitCXXRecordDecl(CXXRecordDecl *D) {
+ std::cout << D->getNameAsString() << std::endl;
+ return false;
+ }
};
}
Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri May 7 18:12:07 2010
@@ -1784,6 +1784,7 @@
virtual void PopExpressionEvaluationContext();
void MarkDeclarationReferenced(SourceLocation Loc, Decl *D);
+ void MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T);
bool DiagRuntimeBehavior(SourceLocation Loc, const PartialDiagnostic &PD);
// Primary Expressions.
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri May 7 18:12:07 2010
@@ -22,6 +22,7 @@
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
+#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/TypeLoc.h"
#include "clang/Basic/PartialDiagnostic.h"
#include "clang/Basic/SourceManager.h"
@@ -7572,6 +7573,48 @@
}
}
+namespace {
+ // Mark all of the declarations referenced
+ // FIXME: Not fully implemented yet! We need to have a better understanding
+ // of when we're entering
+ class MarkReferencedDecls : public RecursiveASTVisitor<MarkReferencedDecls> {
+ Sema &S;
+ SourceLocation Loc;
+
+ public:
+ typedef RecursiveASTVisitor<MarkReferencedDecls> Inherited;
+
+ MarkReferencedDecls(Sema &S, SourceLocation Loc) : S(S), Loc(Loc) { }
+
+ bool VisitTemplateArgument(const TemplateArgument &Arg);
+ bool VisitRecordType(RecordType *T);
+ };
+}
+
+bool MarkReferencedDecls::VisitTemplateArgument(const TemplateArgument &Arg) {
+ if (Arg.getKind() == TemplateArgument::Declaration) {
+ S.MarkDeclarationReferenced(Loc, Arg.getAsDecl());
+ }
+
+ return Inherited::VisitTemplateArgument(Arg);
+}
+
+bool MarkReferencedDecls::VisitRecordType(RecordType *T) {
+ if (ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
+ const TemplateArgumentList &Args = Spec->getTemplateArgs();
+ return VisitTemplateArguments(Args.getFlatArgumentList(),
+ Args.flat_size());
+ }
+
+ return false;
+}
+
+void Sema::MarkDeclarationsReferencedInType(SourceLocation Loc, QualType T) {
+ MarkReferencedDecls Marker(*this, Loc);
+ Marker.Visit(Context.getCanonicalType(T));
+}
+
/// \brief Emit a diagnostic that describes an effect on the run-time behavior
/// of the program being compiled.
///
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Fri May 7 18:12:07 2010
@@ -560,9 +560,7 @@
///
/// For the purposes of template instantiation, a type has already been
/// transformed if it is NULL or if it is not dependent.
- bool AlreadyTransformed(QualType T) {
- return T.isNull() || !T->isDependentType();
- }
+ bool AlreadyTransformed(QualType T);
/// \brief Returns the location of the entity being instantiated, if known.
SourceLocation getBaseLocation() { return Loc; }
@@ -624,6 +622,17 @@
};
}
+bool TemplateInstantiator::AlreadyTransformed(QualType T) {
+ if (T.isNull())
+ return true;
+
+ if (T->isDependentType())
+ return false;
+
+ getSema().MarkDeclarationsReferencedInType(Loc, T);
+ return true;
+}
+
Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
if (!D)
return 0;
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=103323&r1=103322&r2=103323&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri May 7 18:12:07 2010
@@ -191,6 +191,8 @@
Invalid = true;
DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy);
}
+ } else {
+ SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
}
// Create the new typedef
@@ -440,6 +442,8 @@
<< DI->getType();
Invalid = true;
}
+ } else {
+ SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType());
}
Expr *BitWidth = D->getBitWidth();
Added: cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp?rev=103323&view=auto
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp (added)
+++ cfe/trunk/test/SemaTemplate/instantiate-non-dependent-types.cpp Fri May 7 18:12:07 2010
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X1 {
+ static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+};
+
+template<void(*)()> struct instantiate { };
+
+template<typename T>
+struct X2 {
+ typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}}
+};
+
+X2<int> x;
More information about the cfe-commits
mailing list