llvm/clang/lib/Analysis/ThreadSafetyCommon.cpp

//===- ThreadSafetyCommon.cpp ---------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Implementation of the interfaces declared in ThreadSafetyCommon.h
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/Stmt.h"
#include "clang/AST/Type.h"
#include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
#include "clang/Analysis/CFG.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
#include <algorithm>
#include <cassert>
#include <string>
#include <utility>

usingnamespaceclang;
usingnamespacethreadSafety;

// From ThreadSafetyUtil.h
std::string threadSafety::getSourceLiteralString(const Expr *CE) {}

// Return true if E is a variable that points to an incomplete Phi node.
static bool isIncompletePhi(const til::SExpr *E) {}

CallingContext;

til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {}

til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) {}

static bool isCalleeArrow(const Expr *E) {}

static StringRef ClassifyDiagnostic(const CapabilityAttr *A) {}

static StringRef ClassifyDiagnostic(QualType VDT) {}

/// Translate a clang expression in an attribute to a til::SExpr.
/// Constructs the context from D, DeclExp, and SelfDecl.
///
/// \param AttrExp The expression to translate.
/// \param D       The declaration to which the attribute is attached.
/// \param DeclExp An expression involving the Decl to which the attribute
///                is attached.  E.g. the call to a function.
/// \param Self    S-expression to substitute for a \ref CXXThisExpr in a call,
///                or argument to a cleanup function.
CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
                                               const NamedDecl *D,
                                               const Expr *DeclExp,
                                               til::SExpr *Self) {}

/// Translate a clang expression in an attribute to a til::SExpr.
// This assumes a CallingContext has already been created.
CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
                                               CallingContext *Ctx) {}

til::LiteralPtr *SExprBuilder::createVariable(const VarDecl *VD) {}

std::pair<til::LiteralPtr *, StringRef>
SExprBuilder::createThisPlaceholder(const Expr *Exp) {}

// Translate a clang statement or expression to a TIL expression.
// Also performs substitution of variables; Ctx provides the context.
// Dispatches on the type of S.
til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
                                               CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE,
                                               CallingContext *Ctx) {}

static const ValueDecl *getValueDeclFromSExpr(const til::SExpr *E) {}

static bool hasAnyPointerType(const til::SExpr *E) {}

// Grab the very first declaration of virtual method D
static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) {}

til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME,
                                              CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateObjCIVarRefExpr(const ObjCIvarRefExpr *IVRE,
                                                   CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
                                            CallingContext *Ctx,
                                            const Expr *SelfE) {}

til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
    const CXXMemberCallExpr *ME, CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
    const CXXOperatorCallExpr *OCE, CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO,
                                                 CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateBinOp(til::TIL_BinaryOpcode Op,
                                         const BinaryOperator *BO,
                                         CallingContext *Ctx, bool Reverse) {}

til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op,
                                             const BinaryOperator *BO,
                                             CallingContext *Ctx,
                                             bool Assign) {}

til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO,
                                                  CallingContext *Ctx) {}

til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
                                            CallingContext *Ctx) {}

til::SExpr *
SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
                                          CallingContext *Ctx) {}

til::SExpr *
SExprBuilder::translateAbstractConditionalOperator(
    const AbstractConditionalOperator *CO, CallingContext *Ctx) {}

til::SExpr *
SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) {}

// If (E) is non-trivial, then add it to the current basic block, and
// update the statement map so that S refers to E.  Returns a new variable
// that refers to E.
// If E is trivial returns E.
til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S,
                                       const ValueDecl *VD) {}

// Returns the current value of VD, if known, and nullptr otherwise.
til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) {}

// if E is a til::Variable, update its clangDecl.
static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {}

// Adds a new variable declaration.
til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) {}

// Updates a current variable declaration.  (E.g. by assignment)
til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) {}

// Make a Phi node in the current block for the i^th variable in CurrentVarMap.
// If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E.
// If E == null, this is a backedge and will be set later.
void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {}

// Merge values from Map into the current variable map.
// This will construct Phi nodes in the current basic block as necessary.
void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {}

// Merge a back edge into the current variable map.
// This will create phi nodes for all variables in the variable map.
void SExprBuilder::mergeEntryMapBackEdge() {}

// Update the phi nodes that were initially created for a back edge
// once the variable definitions have been computed.
// I.e., merge the current variable map into the phi nodes for Blk.
void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {}

void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,
                            const CFGBlock *First) {}

void SExprBuilder::enterCFGBlock(const CFGBlock *B) {}

void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {}

void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {}

void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {}

void SExprBuilder::handleStatement(const Stmt *S) {}

void SExprBuilder::handleDestructorCall(const VarDecl *VD,
                                        const CXXDestructorDecl *DD) {}

void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {}

void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {}

void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {}

void SExprBuilder::exitCFGBlock(const CFGBlock *B) {}

void SExprBuilder::exitCFG(const CFGBlock *Last) {}

#ifndef NDEBUG
namespace {

class TILPrinter :
    public til::PrettyPrinter<TILPrinter, llvm::raw_ostream> {};

} // namespace

namespace clang {
namespace threadSafety {

void printSCFG(CFGWalker &Walker) {
  llvm::BumpPtrAllocator Bpa;
  til::MemRegionRef Arena(&Bpa);
  SExprBuilder SxBuilder(Arena);
  til::SCFG *Scfg = SxBuilder.buildCFG(Walker);
  TILPrinter::print(Scfg, llvm::errs());
}

} // namespace threadSafety
} // namespace clang
#endif // NDEBUG