head	1.1;
branch	1.1.1;
access;
symbols
	netbsd-11-0-RC4:1.1.1.2
	netbsd-11-0-RC3:1.1.1.2
	netbsd-11-0-RC2:1.1.1.2
	netbsd-11-0-RC1:1.1.1.2
	perseant-exfatfs-base-20250801:1.1.1.2
	netbsd-11:1.1.1.2.0.8
	netbsd-11-base:1.1.1.2
	netbsd-10-1-RELEASE:1.1.1.2
	perseant-exfatfs-base-20240630:1.1.1.2
	perseant-exfatfs:1.1.1.2.0.6
	perseant-exfatfs-base:1.1.1.2
	netbsd-10-0-RELEASE:1.1.1.2
	netbsd-10-0-RC6:1.1.1.2
	netbsd-10-0-RC5:1.1.1.2
	netbsd-10-0-RC4:1.1.1.2
	netbsd-10-0-RC3:1.1.1.2
	netbsd-10-0-RC2:1.1.1.2
	netbsd-10-0-RC1:1.1.1.2
	netbsd-10:1.1.1.2.0.4
	netbsd-10-base:1.1.1.2
	cjep_sun2x-base1:1.1.1.2
	cjep_sun2x:1.1.1.2.0.2
	cjep_sun2x-base:1.1.1.2
	cjep_staticlib_x-base1:1.1.1.2
	LLVM-249b40b558955afe5ac2b549edcf2d7f859c8cc9:1.1.1.2
	cjep_staticlib_x:1.1.1.1.0.4
	cjep_staticlib_x-base:1.1.1.1
	phil-wifi-20200421:1.1.1.1
	phil-wifi-20200411:1.1.1.1
	is-mlppp:1.1.1.1.0.2
	is-mlppp-base:1.1.1.1
	phil-wifi-20200406:1.1.1.1
	phil-wifi-20191119:1.1.1.1
	LLVM-01f3a59fb3e2542fce74c768718f594d0debd0da:1.1.1.1
	LLVM:1.1.1;
locks; strict;
comment	@// @;


1.1
date	2019.11.08.14.29.42;	author joerg;	state Exp;
branches
	1.1.1.1;
next	;
commitid	lIv69tfiG0KHw3KB;

1.1.1.1
date	2019.11.08.14.29.42;	author joerg;	state Exp;
branches
	1.1.1.1.4.1;
next	1.1.1.2;
commitid	lIv69tfiG0KHw3KB;

1.1.1.2
date	2021.05.30.01.25.57;	author joerg;	state Exp;
branches;
next	;
commitid	uhgdinROdC6tU6VC;

1.1.1.1.4.1
date	2021.05.31.22.07.21;	author cjep;	state Exp;
branches;
next	;
commitid	eWz9SBW0XqKjJlVC;


desc
@@


1.1
log
@Initial revision
@
text
@//===--- USRFinder.cpp - Clang refactoring library ------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file Implements a recursive AST visitor that finds the USR of a symbol at a
/// point.
///
//===----------------------------------------------------------------------===//

#include "clang/Tooling/Refactoring/Rename/USRFinder.h"
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
#include "llvm/ADT/SmallVector.h"

using namespace llvm;

namespace clang {
namespace tooling {

namespace {

/// Recursively visits each AST node to find the symbol underneath the cursor.
class NamedDeclOccurrenceFindingVisitor
    : public RecursiveSymbolVisitor<NamedDeclOccurrenceFindingVisitor> {
public:
  // Finds the NamedDecl at a point in the source.
  // \param Point the location in the source to search for the NamedDecl.
  explicit NamedDeclOccurrenceFindingVisitor(const SourceLocation Point,
                                             const ASTContext &Context)
      : RecursiveSymbolVisitor(Context.getSourceManager(),
                               Context.getLangOpts()),
        Point(Point), Context(Context) {}

  bool visitSymbolOccurrence(const NamedDecl *ND,
                             ArrayRef<SourceRange> NameRanges) {
    if (!ND)
      return true;
    for (const auto &Range : NameRanges) {
      SourceLocation Start = Range.getBegin();
      SourceLocation End = Range.getEnd();
      if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
          !End.isFileID() || !isPointWithin(Start, End))
        return true;
    }
    Result = ND;
    return false;
  }

  const NamedDecl *getNamedDecl() const { return Result; }

private:
  // Determines if the Point is within Start and End.
  bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
    // FIXME: Add tests for Point == End.
    return Point == Start || Point == End ||
           (Context.getSourceManager().isBeforeInTranslationUnit(Start,
                                                                 Point) &&
            Context.getSourceManager().isBeforeInTranslationUnit(Point, End));
  }

  const NamedDecl *Result = nullptr;
  const SourceLocation Point; // The location to find the NamedDecl.
  const ASTContext &Context;
};

} // end anonymous namespace

const NamedDecl *getNamedDeclAt(const ASTContext &Context,
                                const SourceLocation Point) {
  const SourceManager &SM = Context.getSourceManager();
  NamedDeclOccurrenceFindingVisitor Visitor(Point, Context);

  // Try to be clever about pruning down the number of top-level declarations we
  // see. If both start and end is either before or after the point we're
  // looking for the point cannot be inside of this decl. Don't even look at it.
  for (auto *CurrDecl : Context.getTranslationUnitDecl()->decls()) {
    SourceLocation StartLoc = CurrDecl->getBeginLoc();
    SourceLocation EndLoc = CurrDecl->getEndLoc();
    if (StartLoc.isValid() && EndLoc.isValid() &&
        SM.isBeforeInTranslationUnit(StartLoc, Point) !=
            SM.isBeforeInTranslationUnit(EndLoc, Point))
      Visitor.TraverseDecl(CurrDecl);
  }

  return Visitor.getNamedDecl();
}

namespace {

/// Recursively visits each NamedDecl node to find the declaration with a
/// specific name.
class NamedDeclFindingVisitor
    : public RecursiveASTVisitor<NamedDeclFindingVisitor> {
public:
  explicit NamedDeclFindingVisitor(StringRef Name) : Name(Name) {}

  // We don't have to traverse the uses to find some declaration with a
  // specific name, so just visit the named declarations.
  bool VisitNamedDecl(const NamedDecl *ND) {
    if (!ND)
      return true;
    // Fully qualified name is used to find the declaration.
    if (Name != ND->getQualifiedNameAsString() &&
        Name != "::" + ND->getQualifiedNameAsString())
      return true;
    Result = ND;
    return false;
  }

  const NamedDecl *getNamedDecl() const { return Result; }

private:
  const NamedDecl *Result = nullptr;
  StringRef Name;
};

} // end anonymous namespace

const NamedDecl *getNamedDeclFor(const ASTContext &Context,
                                 const std::string &Name) {
  NamedDeclFindingVisitor Visitor(Name);
  Visitor.TraverseDecl(Context.getTranslationUnitDecl());
  return Visitor.getNamedDecl();
}

std::string getUSRForDecl(const Decl *Decl) {
  llvm::SmallVector<char, 128> Buff;

  // FIXME: Add test for the nullptr case.
  if (Decl == nullptr || index::generateUSRForDecl(Decl, Buff))
    return "";

  return std::string(Buff.data(), Buff.size());
}

} // end namespace tooling
} // end namespace clang
@


1.1.1.1
log
@Import 01f3a59fb3e2542fce74c768718f594d0debd0da from the LLVM mono-repo:
clang (without test/, unittests/, www/)
llvm (without test/, unittests/)
@
text
@@


1.1.1.1.4.1
log
@sync with head
@
text
@a17 1
#include "clang/Basic/SourceManager.h"
d135 1
a135 1
  llvm::SmallString<128> Buff;
d141 1
a141 1
  return std::string(Buff);
@


1.1.1.2
log
@Import clang 249b40b558955afe5ac2b549edcf2d7f859c8cc9.
@
text
@a17 1
#include "clang/Basic/SourceManager.h"
d135 1
a135 1
  llvm::SmallString<128> Buff;
d141 1
a141 1
  return std::string(Buff);
@

