================ @@ -181,42 +160,105 @@ void ConfusableIdentifierCheck::check( if (!ND) return; - IdentifierInfo *NDII = ND->getIdentifier(); + addDeclToCheck(ND, cast<Decl>(ND->getDeclContext() + ->getNonTransparentContext())); + + // Associate template parameters with this declaration of this template. + if (const auto *TD = dyn_cast<TemplateDecl>(ND)) { + for (const NamedDecl *Param : *TD->getTemplateParameters()) + addDeclToCheck(Param, TD->getTemplatedDecl()); + } + + // Associate function parameters with this declaration of this function. + if (const auto *FD = dyn_cast<FunctionDecl>(ND)) { + for (const NamedDecl *Param : FD->parameters()) + addDeclToCheck(Param, ND); + } +} + +void ConfusableIdentifierCheck::addDeclToCheck(const NamedDecl *ND, + const Decl *Parent) { + const IdentifierInfo *NDII = ND->getIdentifier(); if (!NDII) return; StringRef NDName = NDII->getName(); if (NDName.empty()) return; - const ContextInfo *Info = getContextInfo(ND->getDeclContext()); + NameToDecls[NDII].push_back({ND, Parent}); +} + +void ConfusableIdentifierCheck::onEndOfTranslationUnit() { + llvm::StringMap<llvm::SmallVector<const IdentifierInfo *, 1>> SkeletonToNames; + // Compute the skeleton for each identifier. + for (auto &[Ident, Decls] : NameToDecls) { + SkeletonToNames[skeleton(Ident->getName())].push_back(Ident); + } - llvm::SmallVector<Entry> &Mapped = Mapper[skeleton(NDName)]; - for (const Entry &E : Mapped) { - if (!mayShadow(ND, Info, E.Declaration, E.Info)) + // Visit each skeleton with more than one identifier. + for (auto &[Skel, Idents] : SkeletonToNames) { + if (Idents.size() < 2) { continue; + } - const IdentifierInfo *ONDII = E.Declaration->getIdentifier(); - StringRef ONDName = ONDII->getName(); - if (ONDName == NDName) - continue; + // Find the declaration contexts that transitively contain each identifier. + DeclsWithinContextMap DeclsWithinContext; ---------------- 5chmidti wrote:
nit: speaking of performance, you could keep this map outside the `for (auto &[Skel, Idents] : SkeletonToNames) {` loop and clear the map so that there are not too many allocations. While this is almost a micro optimization at this level, the `for (auto &[Skel, Idents] : SkeletonToNames) {` will be executed quite a lot, so it might shave off the tiniest bit of additional time. If you do choose to look at this and compare the numbers and this does not really matter, then I'd keep it as-is for the smaller var scope. https://github.com/llvm/llvm-project/pull/130369 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits