25#include "llvm/ADT/DenseSet.h" 
   26#include "llvm/ADT/STLExtras.h" 
   31#define DEBUG_TYPE "dataflow" 
   36  const Expr *Current = &E;
 
   38  while (Current != 
Last) {
 
   40    if (
auto *EWC = dyn_cast<ExprWithCleanups>(Current)) {
 
   41      Current = EWC->getSubExpr();
 
   42      assert(Current != 
nullptr);
 
   44    if (
auto *CE = dyn_cast<ConstantExpr>(Current)) {
 
   45      Current = CE->getSubExpr();
 
   46      assert(Current != 
nullptr);
 
   49    assert(Current != 
nullptr);
 
 
   55  if (
auto *E = dyn_cast<Expr>(&S))
 
 
   82  if (Fields.size() != FieldLocs.size())
 
   84  for ([[maybe_unused]] 
auto [Field, Loc] : FieldLocs)
 
   85    if (!Fields.contains(cast_or_null<FieldDecl>(Field)))
 
 
   94template <
class InitListT>
 
   95static std::vector<const FieldDecl *>
 
   97  const RecordDecl *RD = InitList->getType()->getAsRecordDecl();
 
   98  assert(RD != 
nullptr);
 
  100  std::vector<const FieldDecl *> Fields;
 
  102  if (InitList->getType()->isUnionType()) {
 
  103    if (
const FieldDecl *Field = InitList->getInitializedFieldInUnion())
 
  104      Fields.push_back(Field);
 
  113      RD->
fields(), std::back_inserter(Fields),
 
  114      [](
const FieldDecl *Field) { return !Field->isUnnamedBitField(); });
 
 
  121                           InitList->inits()) {}
 
 
  127                           ParenInitList->getInitExprs()) {}
 
 
  130    QualType Ty, std::vector<const FieldDecl *> Fields,
 
  133  assert(RD != 
nullptr);
 
  141    assert(Fields.size() <= 1);
 
  142    if (!Fields.empty()) {
 
  143      ImplicitValueInitForUnion.emplace(Fields.front()->getType());
 
  144      InitsForUnion.push_back(&*ImplicitValueInitForUnion);
 
  146    Inits = InitsForUnion;
 
  151  assert(Fields.size() + RD->getNumBases() == Inits.size());
 
  152  for (
const CXXBaseSpecifier &
Base : RD->bases()) {
 
  153    assert(InitIdx < Inits.size());
 
  154    Expr *Init = Inits[InitIdx++];
 
  155    BaseInits.emplace_back(&
Base, Init);
 
  158  assert(Fields.size() == Inits.size() - InitIdx);
 
  159  for (
const FieldDecl *Field : Fields) {
 
  160    assert(InitIdx < Inits.size());
 
  161    Expr *
Init = Inits[InitIdx++];
 
  162    FieldInits.emplace_back(Field, 
Init);
 
  167                           llvm::DenseSet<const VarDecl *> &Globals) {
 
  168  if (
auto *
V = dyn_cast<VarDecl>(&D))
 
  169    if (
V->hasGlobalStorage())
 
 
  174                          llvm::DenseSet<const VarDecl *> &Locals) {
 
  175  if (
auto *
V = dyn_cast<VarDecl>(&D))
 
 
  181                             llvm::DenseSet<const FunctionDecl *> &Funcs) {
 
  182  if (
auto *FD = dyn_cast<FunctionDecl>(&D))
 
 
  189  const auto *MethodDecl = dyn_cast_or_null<CXXMethodDecl>(
C.getCalleeDecl());
 
  192  auto *Body = dyn_cast_or_null<CompoundStmt>(MethodDecl->getBody());
 
  193  if (!Body || Body->size() != 1)
 
  195  if (
auto *RS = dyn_cast<ReturnStmt>(*Body->body_begin()))
 
  196    if (
auto *Return = RS->getRetValue())
 
  197      return dyn_cast<MemberExpr>(Return->IgnoreParenImpCasts());
 
 
  204      : Referenced(Referenced) {}
 
 
  208      if (
Init->isMemberInitializer()) {
 
  209        Referenced.Fields.insert(
Init->getMember());
 
  210      } 
else if (
Init->isIndirectMemberInitializer()) {
 
  211        for (
const auto *I : 
Init->getIndirectMember()->chain())
 
  222      if (
auto *DefaultInit = dyn_cast<CXXDefaultInitExpr>(InitExpr))
 
 
  245      if (
const auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()))
 
  246        Referenced.Fields.insert(FD);
 
 
  255    if (
const auto *FD = dyn_cast<FieldDecl>(VD))
 
  256      Referenced.Fields.insert(FD);
 
 
 
  280  if (
const auto *CtorDecl = dyn_cast<CXXConstructorDecl>(&FD))
 
  293  if (
const auto *
Method = dyn_cast<CXXMethodDecl>(&FD);
 
  295    for (
const auto &
Capture : 
Method->getParent()->captures()) {
 
  296      if (
Capture.capturesVariable()) {
 
  297        if (
const auto *Param =
 
  298                dyn_cast<ParmVarDecl>(
Capture.getCapturedVar())) {
 
  299          Result.LambdaCapturedParams.insert(Param);
 
 
This file provides some common utility functions for processing Lambda related AST Constructs.
 
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
 
Defines the clang::Expr interface and subclasses for C++ expressions.
 
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
 
C Language Family Type Representation.
 
Represents a base class of a C++ class.
 
Represents a C++ constructor within a class.
 
Represents a C++ base or member initializer.
 
Represents a call to a member function that may be written either with member call syntax (e....
 
Represents a list-initialization with parenthesis.
 
A reference to a declared variable, function, enum, etc.
 
Decl - This represents one declaration (or definition), e.g.
 
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
 
This represents one expression.
 
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
 
Represents a member of a struct/union/class.
 
Represents a function declaration or definition.
 
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
 
Describes an C or C++ initializer list.
 
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
 
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
 
A (possibly-)qualified type.
 
Represents a struct/union/class.
 
field_range fields() const
 
Stmt - This represents one statement.
 
The base class of the type hierarchy.
 
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
 
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
 
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
 
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
 
bool isRecordType() const
 
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
 
RecordInitListHelper(const InitListExpr *InitList)
 
llvm::DenseMap< const ValueDecl *, StorageLocation * > FieldToLoc
 
bool VisitCXXParenListInitExpr(CXXParenListInitExpr *ParenInitList) override
 
bool VisitInitListExpr(InitListExpr *InitList) override
 
bool VisitMemberExpr(MemberExpr *E) override
 
bool VisitDeclRefExpr(DeclRefExpr *E) override
 
void traverseConstructorInits(const CXXConstructorDecl *Ctor)
 
bool VisitCXXMemberCallExpr(CXXMemberCallExpr *C) override
 
ReferencedDeclsVisitor(ReferencedDecls &Referenced)
 
bool VisitDecl(Decl *D) override
 
Dataflow Directional Tag Classes.
 
static void getFieldsFromClassHierarchy(QualType Type, FieldSet &Fields)
 
static void insertIfFunction(const Decl &D, llvm::DenseSet< const FunctionDecl * > &Funcs)
 
static MemberExpr * getMemberForAccessor(const CXXMemberCallExpr &C)
 
ReferencedDecls getReferencedDecls(const FunctionDecl &FD)
Returns declarations that are declared in or referenced from FD.
 
static std::vector< const FieldDecl * > getFieldsForInitListExpr(const InitListT *InitList)
Returns the fields of a RecordDecl that are initialized by an InitListExpr or CXXParenListInitExpr,...
 
const Expr & ignoreCFGOmittedNodes(const Expr &E)
Skip past nodes that the CFG does not emit.
 
FieldSet getObjectFields(QualType Type)
Returns the set of all fields in the type.
 
static void insertIfGlobal(const Decl &D, llvm::DenseSet< const VarDecl * > &Globals)
 
static void insertIfLocal(const Decl &D, llvm::DenseSet< const VarDecl * > &Locals)
 
bool containsSameFields(const FieldSet &Fields, const RecordStorageLocation::FieldToLoc &FieldLocs)
Returns whether Fields and FieldLocs contain the same fields.
 
llvm::SmallSetVector< const FieldDecl *, 4 > FieldSet
A set of FieldDecl *.
 
bool isa(CodeGen::Address addr)
 
bool isLambdaCallOperator(const CXXMethodDecl *MD)
 
@ Result
The result type of a method or function.
 
U cast(CodeGen::Address addr)
 
A collection of several types of declarations, all referenced from the same function.