blob: 0a25e75e016314bce7c88e45c07d4f63b5a10012 [file]
//===- ASTMapping.cpp - AST to SSAF Entity mapping --------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// This file implements utilities for mapping AST declarations to SSAF entities.
//
//===----------------------------------------------------------------------===//
#include "clang/Analysis/Scalable/ASTEntityMapping.h"
#include "clang/AST/Decl.h"
#include "clang/Analysis/Scalable/Model/BuildNamespace.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/SmallString.h"
namespace clang::ssaf {
std::optional<EntityName> getEntityName(const Decl *D) {
if (!D)
return std::nullopt;
if (D->isImplicit())
return std::nullopt;
if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->getBuiltinID())
return std::nullopt;
if (!isa<FunctionDecl, ParmVarDecl, VarDecl, FieldDecl, RecordDecl>(D))
return std::nullopt;
llvm::SmallString<16> Suffix;
const Decl *USRDecl = D;
// For parameters, use the parent function's USR with parameter index as
// suffix
if (const auto *PVD = dyn_cast<ParmVarDecl>(D)) {
const auto *FD =
dyn_cast_or_null<FunctionDecl>(PVD->getParentFunctionOrMethod());
if (!FD)
return std::nullopt;
USRDecl = FD;
const auto ParamIdx = PVD->getFunctionScopeIndex();
llvm::raw_svector_ostream OS(Suffix);
// Parameter uses function's USR with 1-based index as suffix
OS << (ParamIdx + 1);
}
llvm::SmallString<128> USRBuf;
if (clang::index::generateUSRForDecl(USRDecl, USRBuf))
return std::nullopt;
if (USRBuf.empty())
return std::nullopt;
return EntityName(USRBuf.str(), Suffix, {});
}
std::optional<EntityName> getEntityNameForReturn(const FunctionDecl *FD) {
if (!FD)
return std::nullopt;
if (FD->isImplicit())
return std::nullopt;
if (FD->getBuiltinID())
return std::nullopt;
llvm::SmallString<128> USRBuf;
if (clang::index::generateUSRForDecl(FD, USRBuf)) {
return std::nullopt;
}
if (USRBuf.empty())
return std::nullopt;
return EntityName(USRBuf.str(), /*Suffix=*/"0", /*Namespace=*/{});
}
} // namespace clang::ssaf