forked from OSchip/llvm-project
Mark all subsequent decls used.
In the source static void f(); static void f(); template<typename T> static void g() { f(); } static void f() { } void h() { g<int>(); } the call to f refers to the second decl, but it is only marked used at the end of the translation unit during instantiation, after the third f decl has been linked in. With this patch we mark all subsequent decls used, so that it is easy to check if a symbol is used or not. llvm-svn: 171888
This commit is contained in:
parent
77aa25090a
commit
820fa707b1
|
@ -328,11 +328,7 @@ CastKind Sema::ScalarTypeToBooleanCastKind(QualType ScalarTy) {
|
|||
|
||||
/// \brief Used to prune the decls of Sema's UnusedFileScopedDecls vector.
|
||||
static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
|
||||
// Template instantiation can happen at the end of the translation unit
|
||||
// and it sets the canonical (first) decl to used. Normal uses set the last
|
||||
// decl at the time to used and subsequent decl inherit the flag. The net
|
||||
// result is that we need to check both ends of the decl chain.
|
||||
if (D->isUsed() || D->getMostRecentDecl()->isUsed())
|
||||
if (D->getMostRecentDecl()->isUsed())
|
||||
return true;
|
||||
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
|
|
|
@ -10495,7 +10495,18 @@ void Sema::MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func) {
|
|||
if (old.isInvalid()) old = Loc;
|
||||
}
|
||||
|
||||
Func->setUsed(true);
|
||||
// Normally the must current decl is marked used while processing the use and
|
||||
// any subsequent decls are marked used by decl merging. This fails with
|
||||
// template instantiation since marking can happen at the end of the file
|
||||
// and, because of the two phase lookup, this function is called with at
|
||||
// decl in the middle of a decl chain. We loop to maintain the invariant
|
||||
// that once a decl is used, all decls after it are also used.
|
||||
for (FunctionDecl *F = Func->getMostRecentDecl();;) {
|
||||
F->setUsed(true);
|
||||
if (F == Func)
|
||||
break;
|
||||
F = F->getPreviousDecl();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -28,3 +28,17 @@ namespace test3 {
|
|||
g<int>();
|
||||
}
|
||||
}
|
||||
|
||||
namespace test4 {
|
||||
static void f();
|
||||
static void f();
|
||||
template<typename T>
|
||||
static void g() {
|
||||
f();
|
||||
}
|
||||
static void f() {
|
||||
}
|
||||
void h() {
|
||||
g<int>();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue