[cfe-commits] r77664 - in /cfe/trunk: lib/AST/ASTContext.cpp lib/AST/StmtProfile.cpp test/SemaTemplate/canonical-expr-type.cpp
Douglas Gregor
dgregor at apple.com
Thu Jul 30 22:24:01 PDT 2009
Author: dgregor
Date: Fri Jul 31 00:24:01 2009
New Revision: 77664
URL: http://llvm.org/viewvc/llvm-project?rev=77664&view=rev
Log:
Canonicalization and profiling for overloaded function declarations,
for those extra-esoteric cases. Not that any two given C++ compilers
agree on this test case, but this change gives us a strong definition
of equivalent types.
Modified:
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/StmtProfile.cpp
cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=77664&r1=77663&r2=77664&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Jul 31 00:24:01 2009
@@ -2118,9 +2118,25 @@
// If this template name refers to a set of overloaded function templates,
/// the canonical template name merely stores the set of function templates.
- if (OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl())
- // FIXME: Can't really canonicalize a set of overloaded functions, can we?
- return TemplateName(Ovl);
+ if (OverloadedFunctionDecl *Ovl = Name.getAsOverloadedFunctionDecl()) {
+ OverloadedFunctionDecl *CanonOvl = 0;
+ for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
+ FEnd = Ovl->function_end();
+ F != FEnd; ++F) {
+ Decl *Canon = F->get()->getCanonicalDecl();
+ if (CanonOvl || Canon != F->get()) {
+ if (!CanonOvl)
+ CanonOvl = OverloadedFunctionDecl::Create(*this,
+ Ovl->getDeclContext(),
+ Ovl->getDeclName());
+
+ CanonOvl->addOverload(
+ AnyFunctionDecl::getFromNamedDecl(cast<NamedDecl>(Canon)));
+ }
+ }
+
+ return TemplateName(CanonOvl? CanonOvl : Ovl);
+ }
DependentTemplateName *DTN = Name.getAsDependentTemplateName();
assert(DTN && "Non-dependent template names must refer to template decls.");
Modified: cfe/trunk/lib/AST/StmtProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtProfile.cpp?rev=77664&r1=77663&r2=77664&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtProfile.cpp (original)
+++ cfe/trunk/lib/AST/StmtProfile.cpp Fri Jul 31 00:24:01 2009
@@ -603,8 +603,7 @@
void StmtProfiler::VisitDecl(Decl *D) {
if (Canonical && D) {
- if (NonTypeTemplateParmDecl *NTTP
- = dyn_cast<NonTypeTemplateParmDecl>(D)) {
+ if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) {
ID.AddInteger(NTTP->getDepth());
ID.AddInteger(NTTP->getIndex());
VisitType(NTTP->getType());
@@ -612,6 +611,29 @@
}
// FIXME: Template template parameters?
+
+ if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl>(D)) {
+ // Canonicalize all of the function declarations within the overload
+ // set.
+ llvm::SmallVector<Decl *, 4> Functions;
+ for (OverloadedFunctionDecl::function_iterator F = Ovl->function_begin(),
+ FEnd = Ovl->function_end();
+ F != FEnd; ++F)
+ Functions.push_back(F->get()->getCanonicalDecl());
+
+ // Sorting the functions based on the point means that the ID generated
+ // will be different from one execution of the compiler to another.
+ // Since these IDs don't persist over time, the change in ordering will
+ // not affect compilation.
+ std::sort(Functions.begin(), Functions.end());
+
+ for (llvm::SmallVector<Decl *, 4>::iterator F = Functions.begin(),
+ FEnd = Functions.end();
+ F != FEnd; ++F)
+ VisitDecl(*F);
+
+ return;
+ }
}
ID.AddPointer(D? D->getCanonicalDecl() : 0);
Modified: cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp?rev=77664&r1=77663&r2=77664&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp (original)
+++ cfe/trunk/test/SemaTemplate/canonical-expr-type.cpp Fri Jul 31 00:24:01 2009
@@ -15,6 +15,23 @@
template<typename U, U M>
void f0(U u, __typeof__(f(M))) { } // expected-error{{redefinition}}
+// Test insane typeof(expr) overload set canonicalization
+void f(int);
+void f(double);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-note{{previous}}
+
+void f(int);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}}
+
+void f(float);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { }
+
// Test dependently-sized array canonicalization
template<typename T, int N, int M>
void f1(T (&array)[N + M]) { } // expected-note{{previous}}
More information about the cfe-commits
mailing list