forked from OSchip/llvm-project
Remove elements from Sema.UndefinedInternals as functions are defined. Also
filter the elements before emitting them into a PCH. No user-visible functionality change, except that PCH files may be smaller? llvm-svn: 174034
This commit is contained in:
parent
60bd4be17a
commit
f0f5616457
|
@ -68,7 +68,7 @@ public:
|
|||
SmallVectorImpl<NamespaceDecl *> &Namespaces);
|
||||
|
||||
virtual void ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined);
|
||||
llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
|
||||
|
||||
/// \brief Do last resort, unqualified lookup on a LookupResult that
|
||||
/// Sema cannot find.
|
||||
|
|
|
@ -254,7 +254,7 @@ public:
|
|||
virtual void ReadKnownNamespaces(SmallVectorImpl<NamespaceDecl*> &Namespaces);
|
||||
|
||||
virtual void ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined);
|
||||
llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined);
|
||||
|
||||
/// \brief Do last resort, unqualified lookup on a LookupResult that
|
||||
/// Sema cannot find.
|
||||
|
|
|
@ -736,11 +736,15 @@ public:
|
|||
|
||||
// Contains the locations of the beginning of unparsed default
|
||||
// argument locations.
|
||||
llvm::DenseMap<ParmVarDecl *,SourceLocation> UnparsedDefaultArgLocs;
|
||||
llvm::DenseMap<ParmVarDecl *, SourceLocation> UnparsedDefaultArgLocs;
|
||||
|
||||
/// UndefinedInternals - all the used, undefined objects with
|
||||
/// internal linkage in this translation unit.
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> UndefinedInternals;
|
||||
llvm::DenseMap<NamedDecl *, SourceLocation> UndefinedInternals;
|
||||
|
||||
/// Obtain a sorted list of functions that are undefined but ODR-used.
|
||||
void getUndefinedInternals(
|
||||
llvm::SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined);
|
||||
|
||||
typedef std::pair<ObjCMethodList, ObjCMethodList> GlobalMethods;
|
||||
typedef llvm::DenseMap<Selector, GlobalMethods> GlobalMethodPool;
|
||||
|
|
|
@ -1521,7 +1521,7 @@ public:
|
|||
SmallVectorImpl<NamespaceDecl *> &Namespaces);
|
||||
|
||||
virtual void ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined);
|
||||
llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined);
|
||||
|
||||
virtual void ReadTentativeDefinitions(
|
||||
SmallVectorImpl<VarDecl *> &TentativeDefs);
|
||||
|
|
|
@ -202,7 +202,7 @@ void MultiplexExternalSemaSource::ReadKnownNamespaces(
|
|||
}
|
||||
|
||||
void MultiplexExternalSemaSource::ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined){
|
||||
llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined){
|
||||
for(size_t i = 0; i < Sources.size(); ++i)
|
||||
Sources[i]->ReadUndefinedInternals(Undefined);
|
||||
}
|
||||
|
|
|
@ -366,46 +366,70 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
|
|||
}
|
||||
|
||||
namespace {
|
||||
struct UndefinedInternal {
|
||||
NamedDecl *decl;
|
||||
FullSourceLoc useLoc;
|
||||
struct SortUndefinedInternal {
|
||||
const SourceManager &SM;
|
||||
explicit SortUndefinedInternal(SourceManager &SM) : SM(SM) {}
|
||||
|
||||
UndefinedInternal(NamedDecl *decl, FullSourceLoc useLoc)
|
||||
: decl(decl), useLoc(useLoc) {}
|
||||
bool operator()(const std::pair<NamedDecl *, SourceLocation> &l,
|
||||
const std::pair<NamedDecl *, SourceLocation> &r) const {
|
||||
if (l.second != r.second)
|
||||
return SM.isBeforeInTranslationUnit(l.second, r.second);
|
||||
return SM.isBeforeInTranslationUnit(l.first->getLocation(),
|
||||
r.first->getLocation());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Obtains a sorted list of functions that are undefined but ODR-used.
|
||||
void Sema::getUndefinedInternals(
|
||||
SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> > &Undefined) {
|
||||
for (llvm::DenseMap<NamedDecl *, SourceLocation>::iterator
|
||||
I = UndefinedInternals.begin(), E = UndefinedInternals.end();
|
||||
I != E; ++I) {
|
||||
NamedDecl *ND = I->first;
|
||||
|
||||
// Ignore attributes that have become invalid.
|
||||
if (ND->isInvalidDecl()) continue;
|
||||
|
||||
// If we found out that the decl is external, don't warn.
|
||||
if (ND->getLinkage() == ExternalLinkage) continue;
|
||||
|
||||
// __attribute__((weakref)) is basically a definition.
|
||||
if (ND->hasAttr<WeakRefAttr>()) continue;
|
||||
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
|
||||
if (FD->isDefined())
|
||||
continue;
|
||||
} else {
|
||||
if (cast<VarDecl>(ND)->hasDefinition() != VarDecl::DeclarationOnly)
|
||||
continue;
|
||||
}
|
||||
|
||||
Undefined.push_back(std::make_pair(ND, I->second));
|
||||
}
|
||||
|
||||
// Sort (in order of use site) so that we're not (as) dependent on
|
||||
// the iteration order through an llvm::DenseMap.
|
||||
std::sort(Undefined.begin(), Undefined.end(),
|
||||
SortUndefinedInternal(Context.getSourceManager()));
|
||||
}
|
||||
|
||||
/// checkUndefinedInternals - Check for undefined objects with internal linkage.
|
||||
static void checkUndefinedInternals(Sema &S) {
|
||||
if (S.UndefinedInternals.empty()) return;
|
||||
|
||||
// Collect all the still-undefined entities with internal linkage.
|
||||
SmallVector<UndefinedInternal, 16> undefined;
|
||||
for (llvm::MapVector<NamedDecl*,SourceLocation>::iterator
|
||||
i = S.UndefinedInternals.begin(), e = S.UndefinedInternals.end();
|
||||
i != e; ++i) {
|
||||
NamedDecl *decl = i->first;
|
||||
SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
|
||||
S.getUndefinedInternals(Undefined);
|
||||
if (Undefined.empty()) return;
|
||||
|
||||
// Ignore attributes that have become invalid.
|
||||
if (decl->isInvalidDecl()) continue;
|
||||
for (SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> >::iterator
|
||||
I = Undefined.begin(), E = Undefined.end(); I != E; ++I) {
|
||||
NamedDecl *ND = I->first;
|
||||
|
||||
// If we found out that the decl is external, don't warn.
|
||||
if (decl->getLinkage() == ExternalLinkage) continue;
|
||||
|
||||
// __attribute__((weakref)) is basically a definition.
|
||||
if (decl->hasAttr<WeakRefAttr>()) continue;
|
||||
|
||||
if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
|
||||
if (fn->isDefined())
|
||||
continue;
|
||||
} else {
|
||||
if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly)
|
||||
continue;
|
||||
}
|
||||
|
||||
S.Diag(decl->getLocation(), diag::warn_undefined_internal)
|
||||
<< isa<VarDecl>(decl) << decl;
|
||||
S.Diag(i->second, diag::note_used_here);
|
||||
S.Diag(ND->getLocation(), diag::warn_undefined_internal)
|
||||
<< isa<VarDecl>(ND) << ND;
|
||||
S.Diag(I->second, diag::note_used_here);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1065,7 +1089,7 @@ void ExternalSemaSource::ReadKnownNamespaces(
|
|||
}
|
||||
|
||||
void ExternalSemaSource::ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
|
||||
llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) {
|
||||
}
|
||||
|
||||
void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const {
|
||||
|
|
|
@ -8428,6 +8428,13 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
|
|||
if (FD) {
|
||||
FD->setBody(Body);
|
||||
|
||||
// The only way to be included in UndefinedInternals is if there is an
|
||||
// ODR-use before the definition. Avoid the expensive map lookup if this
|
||||
// is the first declaration.
|
||||
if (FD->getPreviousDecl() != 0 && FD->getPreviousDecl()->isUsed() &&
|
||||
FD->getLinkage() != ExternalLinkage)
|
||||
UndefinedInternals.erase(FD);
|
||||
|
||||
// If the function implicitly returns zero (like 'main') or is naked,
|
||||
// don't complain about missing return statements.
|
||||
if (FD->hasImplicitReturnZero() || FD->hasAttr<NakedAttr>())
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- ASTReader.cpp - AST File Reader ------------------------*- C++ -*-===//
|
||||
//===--- ASTReader.cpp - AST File Reader ----------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -5963,7 +5963,7 @@ void ASTReader::ReadKnownNamespaces(
|
|||
}
|
||||
|
||||
void ASTReader::ReadUndefinedInternals(
|
||||
llvm::MapVector<NamedDecl*, SourceLocation> &Undefined) {
|
||||
llvm::DenseMap<NamedDecl*, SourceLocation> &Undefined) {
|
||||
for (unsigned Idx = 0, N = UndefinedInternals.size(); Idx != N;) {
|
||||
NamedDecl *D = cast<NamedDecl>(GetDecl(UndefinedInternals[Idx++]));
|
||||
SourceLocation Loc =
|
||||
|
|
|
@ -3590,10 +3590,11 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
|
|||
|
||||
// Build a record of all used, undefined objects with internal linkage.
|
||||
RecordData UndefinedInternals;
|
||||
for (llvm::MapVector<NamedDecl*, SourceLocation>::iterator
|
||||
I = SemaRef.UndefinedInternals.begin(),
|
||||
IEnd = SemaRef.UndefinedInternals.end();
|
||||
I != IEnd; ++I) {
|
||||
|
||||
SmallVector<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
|
||||
SemaRef.getUndefinedInternals(Undefined);
|
||||
for (SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> >::iterator
|
||||
I = Undefined.begin(), E = Undefined.end(); I != E; ++I) {
|
||||
AddDeclRef(I->first, UndefinedInternals);
|
||||
AddSourceLocation(I->second, UndefinedInternals);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue