// 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;
}
namespace {
- struct UndefinedInternal {
- NamedDecl *decl;
- FullSourceLoc useLoc;
-
- UndefinedInternal(NamedDecl *decl, FullSourceLoc useLoc)
- : decl(decl), useLoc(useLoc) {}
+ struct SortUndefinedInternal {
+ const SourceManager &SM;
+ explicit SortUndefinedInternal(SourceManager &SM) : SM(SM) {}
+
+ 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());
+ }
};
}
-/// 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;
+/// 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 (decl->isInvalidDecl()) continue;
+ if (ND->isInvalidDecl()) continue;
// If we found out that the decl is external, don't warn.
- if (decl->getLinkage() == ExternalLinkage) continue;
+ if (ND->getLinkage() == ExternalLinkage) continue;
// __attribute__((weakref)) is basically a definition.
- if (decl->hasAttr<WeakRefAttr>()) continue;
+ if (ND->hasAttr<WeakRefAttr>()) continue;
- if (FunctionDecl *fn = dyn_cast<FunctionDecl>(decl)) {
- if (fn->isDefined())
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
+ if (FD->isDefined())
continue;
} else {
- if (cast<VarDecl>(decl)->hasDefinition() != VarDecl::DeclarationOnly)
+ if (cast<VarDecl>(ND)->hasDefinition() != VarDecl::DeclarationOnly)
continue;
}
- S.Diag(decl->getLocation(), diag::warn_undefined_internal)
- << isa<VarDecl>(decl) << decl;
- S.Diag(i->second, diag::note_used_here);
+ 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<std::pair<NamedDecl *, SourceLocation>, 16> Undefined;
+ S.getUndefinedInternals(Undefined);
+ if (Undefined.empty()) return;
+
+ for (SmallVectorImpl<std::pair<NamedDecl *, SourceLocation> >::iterator
+ I = Undefined.begin(), E = Undefined.end(); I != E; ++I) {
+ NamedDecl *ND = I->first;
+
+ S.Diag(ND->getLocation(), diag::warn_undefined_internal)
+ << isa<VarDecl>(ND) << ND;
+ S.Diag(I->second, diag::note_used_here);
}
}
}
void ExternalSemaSource::ReadUndefinedInternals(
- llvm::MapVector<NamedDecl *, SourceLocation> &Undefined) {
+ llvm::DenseMap<NamedDecl *, SourceLocation> &Undefined) {
}
void PrettyDeclStackTraceEntry::print(raw_ostream &OS) const {