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:
Rafael Espindola 2013-01-08 19:43:34 +00:00
parent 77aa25090a
commit 820fa707b1
3 changed files with 27 additions and 6 deletions

View File

@ -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)) {

View File

@ -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

View File

@ -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>();
}
}