21#ifndef LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
22#define LLVM_CLANG_ANALYSIS_ANALYSES_THREADSAFETYCOMMON_H
33#include "llvm/ADT/DenseMap.h"
34#include "llvm/ADT/PointerIntPair.h"
35#include "llvm/ADT/PointerUnion.h"
36#include "llvm/ADT/SmallVector.h"
37#include "llvm/Support/Casting.h"
84 const auto *PE1 = dyn_cast_or_null<til::Project>(E1);
87 const auto *PE2 = dyn_cast_or_null<til::Project>(E2);
90 return PE1->clangDecl() == PE2->clangDecl();
109 void enterCFGBlock(
const CFGBlock *B) {}
112 bool visitPredecessors() {
return true; }
115 void handlePredecessor(
const CFGBlock *Pred) {}
118 void handlePredecessorBackEdge(
const CFGBlock *Pred) {}
121 void enterCFGBlockBody(
const CFGBlock *B) {}
124 void handleStatement(
const Stmt *S) {}
130 void exitCFGBlockBody(
const CFGBlock *B) {}
133 bool visitSuccessors() {
return true; }
136 void handleSuccessor(
const CFGBlock *Succ) {}
139 void handleSuccessorBackEdge(
const CFGBlock *Succ) {}
142 void exitCFGBlock(
const CFGBlock *B) {}
162 if (!isa_and_nonnull<NamedDecl>(AC.
getDecl()))
173 template <
class Visitor>
177 V.enterCFG(CFGraph,
getDecl(), &CFGraph->getEntry());
179 for (
const auto *CurrBlock : *SortedGraph) {
180 VisitedBlocks.
insert(CurrBlock);
182 V.enterCFGBlock(CurrBlock);
185 if (
V.visitPredecessors()) {
189 SE = CurrBlock->pred_end();
195 BackEdges.push_back(*SI);
198 V.handlePredecessor(*SI);
201 for (
auto *Blk : BackEdges)
202 V.handlePredecessorBackEdge(Blk);
205 V.enterCFGBlockBody(CurrBlock);
208 for (
const auto &BI : *CurrBlock) {
209 switch (BI.getKind()) {
219 V.handleDestructorCall(VD, DD);
227 V.exitCFGBlockBody(CurrBlock);
230 if (
V.visitSuccessors()) {
235 SE = CurrBlock->succ_end();
241 ForwardEdges.push_back(*SI);
244 V.handleSuccessorBackEdge(*SI);
247 for (
auto *Blk : ForwardEdges)
248 V.handleSuccessor(Blk);
251 V.exitCFGBlock(CurrBlock);
253 V.exitCFG(&CFGraph->getExit());
260 return dyn_cast<NamedDecl>(ACtx->getDecl());
266 CFG *CFGraph =
nullptr;
276 static constexpr unsigned FlagNegative = 1u << 0;
277 static constexpr unsigned FlagReentrant = 1u << 1;
280 llvm::PointerIntPair<const til::SExpr *, 2, unsigned> CapExpr;
288 : CapExpr(E, (Neg ? FlagNegative : 0) | (Reentrant ? FlagReentrant : 0)),
294 template <
typename T>
299 bool negative()
const {
return CapExpr.getInt() & FlagNegative; }
300 bool reentrant()
const {
return CapExpr.getInt() & FlagReentrant; }
329 if (
const auto *P = dyn_cast<til::Project>(
sexpr()))
330 return P->clangDecl();
331 if (
const auto *P = dyn_cast<til::LiteralPtr>(
sexpr()))
332 return P->clangDecl();
369 llvm::PointerUnion<const Expr *, til::SExpr *>
SelfArg =
nullptr;
375 llvm::PointerUnion<const Expr *const *, til::SExpr *>
FunArgs =
nullptr;
422 LookupLocalVarExpr = std::move(F);
436 const Expr *SelfE =
nullptr);
454 til::SExpr *translateAbstractConditionalOperator(
461 using StatementMap = llvm::DenseMap<const Stmt *, til::SExpr *>;
464 using LVarIndexMap = llvm::DenseMap<const ValueDecl *, unsigned>;
467 using NameVarPair = std::pair<const ValueDecl *, til::SExpr *>;
471 LVarDefinitionMap ExitMap;
472 bool HasBackEdges =
false;
475 unsigned UnprocessedSuccessors = 0;
478 unsigned ProcessedPredecessors = 0;
480 BlockInfo() =
default;
481 BlockInfo(BlockInfo &&) =
default;
482 BlockInfo &operator=(BlockInfo &&) =
default;
486 void enterCFGBlock(
const CFGBlock *B);
487 bool visitPredecessors() {
return true; }
488 void handlePredecessor(
const CFGBlock *Pred);
489 void handlePredecessorBackEdge(
const CFGBlock *Pred);
490 void enterCFGBlockBody(
const CFGBlock *B);
491 void handleStatement(
const Stmt *S);
493 void exitCFGBlockBody(
const CFGBlock *B);
494 bool visitSuccessors() {
return true; }
495 void handleSuccessor(
const CFGBlock *Succ);
496 void handleSuccessorBackEdge(
const CFGBlock *Succ);
497 void exitCFGBlock(
const CFGBlock *B);
498 void exitCFG(
const CFGBlock *
Last);
500 void insertStmt(
const Stmt *S, til::SExpr *E) {
501 SMap.insert(std::make_pair(S, E));
504 til::SExpr *addStatement(til::SExpr *E,
const Stmt *S,
505 const ValueDecl *VD =
nullptr);
506 til::SExpr *lookupVarDecl(
const ValueDecl *VD);
507 til::SExpr *addVarDecl(
const ValueDecl *VD, til::SExpr *E);
508 til::SExpr *updateVarDecl(
const ValueDecl *VD, til::SExpr *E);
510 void makePhiNodeVar(
unsigned i,
unsigned NPreds, til::SExpr *E);
511 void mergeEntryMap(LVarDefinitionMap Map);
512 void mergeEntryMapBackEdge();
513 void mergePhiNodesBackEdge(
const CFGBlock *Blk);
518 static const bool CapabilityExprMode =
true;
520 til::MemRegionRef Arena;
523 til::Variable *SelfVar =
nullptr;
525 til::SCFG *Scfg =
nullptr;
531 LVarIndexMap LVarIdxMap;
534 std::vector<til::BasicBlock *> BlockMap;
537 std::vector<BlockInfo> BBInfo;
539 LVarDefinitionMap CurrentLVarMap;
540 std::vector<til::Phi *> CurrentArguments;
541 std::vector<til::SExpr *> CurrentInstructions;
542 std::vector<til::Phi *> IncompleteArgs;
543 til::BasicBlock *CurrentBB =
nullptr;
544 BlockInfo *CurrentBlockInfo =
nullptr;
548 using LookupLocalVarExprClosure =
551 llvm::DenseSet<const ValueDecl *> VarsBeingTranslated;
553 LookupLocalVarExprClosure LookupLocalVarExpr;
This file defines AnalysisDeclContext, a class that manages the analysis context data for context sen...
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
SExprBuilder::CallingContext CallingContext
C Language Family Type Representation.
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
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.
A (possibly-)qualified type.
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
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 Reentrant)
CapabilityExpr(const til::SExpr *, T, bool, bool)=delete
bool matches(const CapabilityExpr &other) const
bool partiallyMatches(const CapabilityExpr &other) const
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.
void setLookupLocalVarExpr(std::function< const Expr *(const NamedDecl *)> F)
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
SExprBuilder(til::MemRegionRef A)
til::SExpr * lookupStmt(const Stmt *S)
til::LiteralPtr * createThisPlaceholder()
til::SCFG * buildCFG(CFGWalker &Walker)
til::SExpr * translateVariable(const VarDecl *VD, CallingContext *Ctx)
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.
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.
bool isa(CodeGen::Address addr)
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
const FunctionProtoType * T
int const char * function
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