21#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
22#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
32#include "llvm/ADT/DenseMap.h"
33#include "llvm/ADT/PointerIntPair.h"
34#include "llvm/ADT/PointerUnion.h"
35#include "llvm/ADT/SmallVector.h"
36#include "llvm/Support/Casting.h"
44class AbstractConditionalOperator;
45class ArraySubscriptExpr;
49class CXXDestructorDecl;
50class CXXMemberCallExpr;
51class CXXOperatorCallExpr;
60namespace threadSafety {
73 if (isa<til::Wildcard>(E1))
74 return isa<til::Wildcard>(E2);
75 if (isa<til::Wildcard>(E2))
76 return isa<til::Wildcard>(E1);
82 const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
85 const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
88 return PE1->clangDecl() == PE2->clangDecl();
107 void enterCFGBlock(
const CFGBlock *B) {}
110 bool visitPredecessors() {
return true; }
113 void handlePredecessor(
const CFGBlock *Pred) {}
116 void handlePredecessorBackEdge(
const CFGBlock *Pred) {}
119 void enterCFGBlockBody(
const CFGBlock *B) {}
122 void handleStatement(
const Stmt *S) {}
128 void exitCFGBlockBody(
const CFGBlock *B) {}
131 bool visitSuccessors() {
return true; }
134 void handleSuccessor(
const CFGBlock *Succ) {}
137 void handleSuccessorBackEdge(
const CFGBlock *Succ) {}
140 void exitCFGBlock(
const CFGBlock *B) {}
155 CFGraph = AC.getCFG();
160 if (!isa_and_nonnull<NamedDecl>(AC.getDecl()))
171 template <
class Visitor>
177 for (
const auto *CurrBlock : *SortedGraph) {
178 VisitedBlocks.
insert(CurrBlock);
180 V.enterCFGBlock(CurrBlock);
183 if (
V.visitPredecessors()) {
187 SE = CurrBlock->pred_end();
193 BackEdges.push_back(*SI);
196 V.handlePredecessor(*SI);
199 for (
auto *Blk : BackEdges)
200 V.handlePredecessorBackEdge(Blk);
203 V.enterCFGBlockBody(CurrBlock);
206 for (
const auto &BI : *CurrBlock) {
207 switch (BI.getKind()) {
217 V.handleDestructorCall(VD, DD);
225 V.exitCFGBlockBody(CurrBlock);
228 if (
V.visitSuccessors()) {
233 SE = CurrBlock->succ_end();
239 ForwardEdges.push_back(*SI);
242 V.handleSuccessorBackEdge(*SI);
245 for (
auto *Blk : ForwardEdges)
246 V.handleSuccessor(Blk);
249 V.exitCFGBlock(CurrBlock);
258 return dyn_cast<NamedDecl>(ACtx->
getDecl());
264 CFG *CFGraph =
nullptr;
275 llvm::PointerIntPair<const til::SExpr *, 1, bool> CapExpr;
283 : CapExpr(
E, Neg), CapKind(
Kind) {}
293 return CapabilityExpr(CapExpr.getPointer(), CapKind, !CapExpr.getInt());
318 if (
const auto *
P = dyn_cast<til::Project>(
sexpr()))
319 return P->clangDecl();
320 if (
const auto *
P = dyn_cast<til::LiteralPtr>(
sexpr()))
321 return P->clangDecl();
358 llvm::PointerUnion<const Expr *, til::SExpr *>
SelfArg =
nullptr;
364 llvm::PointerUnion<const Expr *const *, til::SExpr *>
FunArgs =
nullptr;
391 std::pair<til::LiteralPtr *, StringRef>
420 const Expr *SelfE =
nullptr);
438 til::SExpr *translateAbstractConditionalOperator(
444 using StatementMap = llvm::DenseMap<const Stmt *, til::SExpr *>;
447 using LVarIndexMap = llvm::DenseMap<const ValueDecl *, unsigned>;
450 using NameVarPair = std::pair<const ValueDecl *, til::SExpr *>;
455 bool HasBackEdges =
false;
458 unsigned UnprocessedSuccessors = 0;
461 unsigned ProcessedPredecessors = 0;
463 BlockInfo() =
default;
464 BlockInfo(BlockInfo &&) =
default;
465 BlockInfo &operator=(BlockInfo &&) =
default;
469 void enterCFGBlock(
const CFGBlock *B);
470 bool visitPredecessors() {
return true; }
471 void handlePredecessor(
const CFGBlock *Pred);
472 void handlePredecessorBackEdge(
const CFGBlock *Pred);
473 void enterCFGBlockBody(
const CFGBlock *B);
474 void handleStatement(
const Stmt *S);
476 void exitCFGBlockBody(
const CFGBlock *B);
477 bool visitSuccessors() {
return true; }
478 void handleSuccessor(
const CFGBlock *Succ);
479 void handleSuccessorBackEdge(
const CFGBlock *Succ);
480 void exitCFGBlock(
const CFGBlock *B);
481 void exitCFG(
const CFGBlock *
Last);
483 void insertStmt(
const Stmt *S, til::SExpr *
E) {
484 SMap.insert(std::make_pair(S,
E));
487 til::SExpr *addStatement(til::SExpr *
E,
const Stmt *S,
488 const ValueDecl *VD =
nullptr);
489 til::SExpr *lookupVarDecl(
const ValueDecl *VD);
490 til::SExpr *addVarDecl(
const ValueDecl *VD, til::SExpr *
E);
491 til::SExpr *updateVarDecl(
const ValueDecl *VD, til::SExpr *
E);
493 void makePhiNodeVar(
unsigned i,
unsigned NPreds, til::SExpr *
E);
494 void mergeEntryMap(LVarDefinitionMap Map);
495 void mergeEntryMapBackEdge();
496 void mergePhiNodesBackEdge(
const CFGBlock *Blk);
501 static const bool CapabilityExprMode =
true;
503 til::MemRegionRef Arena;
506 til::Variable *SelfVar =
nullptr;
508 til::SCFG *Scfg =
nullptr;
514 LVarIndexMap LVarIdxMap;
517 std::vector<til::BasicBlock *> BlockMap;
520 std::vector<BlockInfo> BBInfo;
522 LVarDefinitionMap CurrentLVarMap;
523 std::vector<til::Phi *> CurrentArguments;
524 std::vector<til::SExpr *> CurrentInstructions;
525 std::vector<til::Phi *> IncompleteArgs;
526 til::BasicBlock *CurrentBB =
nullptr;
527 BlockInfo *CurrentBlockInfo =
nullptr;
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
enum clang::sema::@1653::IndirectLocalPathEntry::EntryKind Kind
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
SExprBuilder::CallingContext CallingContext
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
AnalysisDeclContext contains the context data for the function, method or block under analysis.
const Decl * getDecl() const
ASTContext & getASTContext() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
A builtin binary operation expression such as "x + y" or "x <= y".
Represents C++ object destructor implicitly generated for automatic object or temporary bound to cons...
const VarDecl * getVarDecl() const
Represents a single basic block in a source-level CFG.
AdjacentBlocks::const_iterator const_pred_iterator
unsigned getBlockID() const
AdjacentBlocks::const_iterator const_succ_iterator
T castAs() const
Convert to the specified CFGElement type, asserting that this CFGElement is of the desired type.
const CXXDestructorDecl * getDestructorDecl(ASTContext &astContext) const
const Stmt * getStmt() const
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Represents a C++ destructor within a class.
Represents a call to a member function that may be written either with member call syntax (e....
A call to an overloaded operator written using operator syntax.
Represents the this expression in C++.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
A reference to a declared variable, function, enum, etc.
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
This represents one expression.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Implements a set of CFGBlocks using a BitVector.
std::pair< std::nullopt_t, bool > insert(const CFGBlock *Block)
Set the bit associated with a particular CFGBlock.
bool alreadySet(const CFGBlock *Block)
Check if the bit for a CFGBlock has been already set.
Stmt - This represents one statement.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
const PostOrderCFGView * getSortedGraph() const
const NamedDecl * getDecl() const
bool init(AnalysisDeclContext &AC)
const CFG * getGraph() const
CapabilityExpr operator!() const
bool shouldIgnore() const
CapabilityExpr(const til::SExpr *E, StringRef Kind, bool Neg)
bool matches(const CapabilityExpr &other) const
bool partiallyMatches(const CapabilityExpr &other) const
CapabilityExpr(const til::SExpr *, T, bool)=delete
bool equals(const CapabilityExpr &other) const
const til::SExpr * sexpr() const
bool matchesUniv(const CapabilityExpr &CapE) const
std::string toString() const
const ValueDecl * valueDecl() const
StringRef getKind() const
const til::SCFG * getCFG() const
CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D, const Expr *DeclExp, til::SExpr *Self=nullptr)
Translate a clang expression in an attribute to a til::SExpr.
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
SExprBuilder(til::MemRegionRef A)
std::pair< til::LiteralPtr *, StringRef > createThisPlaceholder(const Expr *Exp)
til::SExpr * lookupStmt(const Stmt *S)
til::SCFG * buildCFG(CFGWalker &Walker)
til::LiteralPtr * createVariable(const VarDecl *VD)
til::BasicBlock * lookupBlock(const CFGBlock *B)
A basic block is part of an SCFG.
static bool compareExprs(const SExpr *E1, const SExpr *E2)
A Literal pointer to an object allocated in memory.
static bool compareExprs(const SExpr *E1, const SExpr *E2)
static void print(const SExpr *E, std::ostream &SS)
An SCFG is a control-flow graph.
Base class for AST nodes in the typed intermediate language.
@ VK_SFun
SFunction (self) parameter.
void setKind(VariableKind K)
bool matches(const til::SExpr *E1, const til::SExpr *E2)
bool equals(const til::SExpr *E1, const til::SExpr *E2)
std::string toString(const til::SExpr *E)
bool partiallyMatches(const til::SExpr *E1, const til::SExpr *E2)
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void printSCFG(CFGWalker &Walker)
The JSON file list parser is used to communicate input to InstallAPI.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
const FunctionProtoType * T
Encapsulates the lexical context of a function call.
llvm::PointerUnion< const Expr *const *, til::SExpr * > FunArgs
const NamedDecl * AttrDecl
CallingContext(CallingContext *P, const NamedDecl *D=nullptr)
llvm::PointerUnion< const Expr *, til::SExpr * > SelfArg