Skip to content

Commit

Permalink
feat(cxx_indexer): prepare to eliminate simple aliases (#5535)
Browse files Browse the repository at this point in the history
  • Loading branch information
zrlk committed Mar 14, 2023
1 parent 54f7d31 commit 12de694
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 19 deletions.
26 changes: 26 additions & 0 deletions kythe/cxx/indexer/cxx/IndexerASTHooks.cc
Expand Up @@ -568,6 +568,32 @@ bool IndexerASTVisitor::declDominatesPrunableSubtree(const clang::Decl* Decl) {
return getAllParents()->DeclDominatesPrunableSubtree(Decl);
}

const clang::Decl* IndexerASTVisitor::GetInfluencedDeclFromLValueHead(
const clang::Stmt* head) {
if (head == nullptr) return nullptr;
head = SkipTrivialAliasing(head);
if (auto* expr = llvm::dyn_cast_or_null<clang::DeclRefExpr>(head);
expr != nullptr && expr->getFoundDecl() != nullptr &&
(expr->getFoundDecl()->getKind() == clang::Decl::Kind::Var ||
expr->getFoundDecl()->getKind() == clang::Decl::Kind::ParmVar)) {
return expr->getFoundDecl();
}
if (auto* expr = llvm::dyn_cast_or_null<clang::MemberExpr>(head);
expr != nullptr) {
if (auto* member = expr->getMemberDecl(); member != nullptr) {
return member;
}
}
return nullptr;
}

const clang::Stmt* IndexerASTVisitor::SkipTrivialAliasing(
const clang::Stmt* stmt) {
// TODO(zarko): the actual implementation.
if (stmt == nullptr) return nullptr;
return stmt;
}

bool IndexerASTVisitor::IsDefinition(const clang::VarDecl* VD) {
if (const auto* PVD = dyn_cast<clang::ParmVarDecl>(VD)) {
// For parameters, we want to report them as definitions iff they're
Expand Down
23 changes: 21 additions & 2 deletions kythe/cxx/indexer/cxx/IndexerASTHooks.h
Expand Up @@ -740,6 +740,22 @@ class IndexerASTVisitor : public RecursiveTypeVisitor<IndexerASTVisitor> {
GraphObserver& Observer;
clang::ASTContext& Context;

/// \return the `Decl` that is the target of influence by an lexpression with
/// head `head`, or null. For example, in `foo[x].bar(y).z`, the target of
/// influence is the member decl for `z`.
const clang::Decl* GetInfluencedDeclFromLValueHead(const clang::Stmt* head);

/// \brief Eliminates the trivial introduction of aliasing.
///
/// In some situations (and modulo undefined behavior), the expression
/// `*(&foo)` can be reduced to `foo`. `foo` may be a simple DeclRefExpr, but
/// it could also be a MemberExpr that has alias semantics tied to another
/// field or some piece of generated code.
///
/// \return the head of a trivial alias/dealias operation or `stmt` if the
/// operation failed to find one.
const clang::Stmt* SkipTrivialAliasing(const clang::Stmt* stmt);

/// \brief The result of calling into the lexer.
enum class LexerResult {
Failure, ///< The operation failed.
Expand Down Expand Up @@ -990,14 +1006,17 @@ class IndexerASTVisitor : public RecursiveTypeVisitor<IndexerASTVisitor> {
/// \brief Marks that `stmt` was used as a write target.
/// \return `stmt` as passed.
const clang::Stmt* UsedAsWrite(const clang::Stmt* stmt) {
if (stmt != nullptr) use_kinds_[stmt] = GraphObserver::UseKind::kWrite;
if (stmt != nullptr)
use_kinds_[SkipTrivialAliasing(stmt)] = GraphObserver::UseKind::kWrite;
return stmt;
}

/// \brief Marks that `stmt` was used as a read+write target.
/// \return `stmt` as passed.
const clang::Stmt* UsedAsReadWrite(const clang::Stmt* stmt) {
if (stmt != nullptr) use_kinds_[stmt] = GraphObserver::UseKind::kReadWrite;
if (stmt != nullptr)
use_kinds_[SkipTrivialAliasing(stmt)] =
GraphObserver::UseKind::kReadWrite;
return stmt;
}

Expand Down
17 changes: 0 additions & 17 deletions kythe/cxx/indexer/cxx/clang_utils.cc
Expand Up @@ -168,21 +168,4 @@ const clang::Stmt* FindLValueHead(const clang::Stmt* stmt) {
return nullptr;
}
}

const clang::Decl* GetInfluencedDeclFromLValueHead(const clang::Stmt* head) {
if (head == nullptr) return nullptr;
if (auto* expr = llvm::dyn_cast_or_null<clang::DeclRefExpr>(head);
expr != nullptr && expr->getFoundDecl() != nullptr &&
(expr->getFoundDecl()->getKind() == clang::Decl::Kind::Var ||
expr->getFoundDecl()->getKind() == clang::Decl::Kind::ParmVar)) {
return expr->getFoundDecl();
}
if (auto* expr = llvm::dyn_cast_or_null<clang::MemberExpr>(head);
expr != nullptr) {
if (auto* member = expr->getMemberDecl(); member != nullptr) {
return member;
}
}
return nullptr;
}
} // namespace kythe

0 comments on commit 12de694

Please sign in to comment.