28 #include "llvm/ADT/DenseMap.h"
29 #include "llvm/ADT/SmallVector.h"
30 #include "llvm/ADT/StringRef.h"
34 using namespace clang;
35 using namespace threadSafety;
39 switch (CE->getStmtClass()) {
40 case Stmt::IntegerLiteralClass:
41 return cast<IntegerLiteral>(CE)->
getValue().toString(10,
true);
42 case Stmt::StringLiteralClass: {
43 std::string ret(
"\"");
44 ret += cast<StringLiteral>(CE)->getString();
48 case Stmt::CharacterLiteralClass:
49 case Stmt::CXXNullPtrLiteralExprClass:
50 case Stmt::GNUNullExprClass:
51 case Stmt::CXXBoolLiteralExprClass:
52 case Stmt::FloatingLiteralClass:
53 case Stmt::ImaginaryLiteralClass:
54 case Stmt::ObjCStringLiteralClass:
62 if (
const auto *Ph = dyn_cast<til::Phi>(E))
71 auto It =
SMap.find(S);
85 return ME ? ME->
isArrow() :
false;
108 if (
const MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
112 dyn_cast<CXXMemberCallExpr>(DeclExp)) {
113 Ctx.
SelfArg = CE->getImplicitObjectArgument();
115 Ctx.
NumArgs = CE->getNumArgs();
117 }
else if (
const CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
118 Ctx.
NumArgs = CE->getNumArgs();
121 dyn_cast<CXXConstructExpr>(DeclExp)) {
123 Ctx.
NumArgs = CE->getNumArgs();
125 }
else if (D && isa<CXXDestructorDecl>(D)) {
132 if (SelfDecl && !Ctx.
SelfArg) {
159 if (
auto* SLit = dyn_cast<StringLiteral>(AttrExp)) {
160 if (SLit->getString() == StringRef(
"*"))
170 if (
auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) {
171 if (OE->getOperator() == OO_Exclaim) {
173 AttrExp = OE->getArg(0);
176 else if (
auto *UO = dyn_cast<UnaryOperator>(AttrExp)) {
177 if (UO->getOpcode() ==
UO_LNot) {
179 AttrExp = UO->getSubExpr();
187 if (!E || isa<til::Literal>(E))
191 if (
auto *CE = dyn_cast_or_null<til::Cast>(E)) {
212 switch (S->getStmtClass()) {
213 case Stmt::DeclRefExprClass:
214 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
215 case Stmt::CXXThisExprClass:
216 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
217 case Stmt::MemberExprClass:
218 return translateMemberExpr(cast<MemberExpr>(S), Ctx);
219 case Stmt::CallExprClass:
220 return translateCallExpr(cast<CallExpr>(S), Ctx);
221 case Stmt::CXXMemberCallExprClass:
222 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
223 case Stmt::CXXOperatorCallExprClass:
224 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
225 case Stmt::UnaryOperatorClass:
226 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
227 case Stmt::BinaryOperatorClass:
228 case Stmt::CompoundAssignOperatorClass:
229 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
231 case Stmt::ArraySubscriptExprClass:
232 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
233 case Stmt::ConditionalOperatorClass:
234 return translateAbstractConditionalOperator(
235 cast<ConditionalOperator>(S), Ctx);
236 case Stmt::BinaryConditionalOperatorClass:
237 return translateAbstractConditionalOperator(
238 cast<BinaryConditionalOperator>(S), Ctx);
241 case Stmt::ParenExprClass:
242 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
243 case Stmt::ExprWithCleanupsClass:
244 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
245 case Stmt::CXXBindTemporaryExprClass:
246 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
249 case Stmt::CharacterLiteralClass:
250 case Stmt::CXXNullPtrLiteralExprClass:
251 case Stmt::GNUNullExprClass:
252 case Stmt::CXXBoolLiteralExprClass:
253 case Stmt::FloatingLiteralClass:
254 case Stmt::ImaginaryLiteralClass:
255 case Stmt::IntegerLiteralClass:
256 case Stmt::StringLiteralClass:
257 case Stmt::ObjCStringLiteralClass:
260 case Stmt::DeclStmtClass:
261 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
265 if (
const CastExpr *CE = dyn_cast<CastExpr>(S))
266 return translateCastExpr(CE, Ctx);
278 if (
const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
280 cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
281 unsigned I = PV->getFunctionScopeIndex();
285 assert(I < Ctx->NumArgs);
303 assert(SelfVar &&
"We have no variable for 'this'!");
308 if (
auto *V = dyn_cast<til::Variable>(E))
309 return V->clangDecl();
310 if (
auto *Ph = dyn_cast<til::Phi>(E))
311 return Ph->clangDecl();
312 if (
auto *
P = dyn_cast<til::Project>(E))
313 return P->clangDecl();
314 if (
auto *L = dyn_cast<til::LiteralPtr>(E))
315 return L->clangDecl();
323 if (
auto *
C = dyn_cast<til::Cast>(E))
348 if (
auto *VD = dyn_cast<CXXMethodDecl>(D))
361 if (CapabilityExprMode) {
364 if (LockReturnedAttr* At = FD->
getAttr<LockReturnedAttr>()) {
367 LRCallCtx.SelfArg = SelfE;
369 LRCallCtx.FunArgs = CE->
getArgs();
376 for (
const auto *Arg : CE->
arguments()) {
384 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
386 if (CapabilityExprMode) {
395 return translateCallExpr(cast<CallExpr>(ME), Ctx,
400 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
402 if (CapabilityExprMode) {
405 if (k == OO_Star || k == OO_Arrow) {
411 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
425 if (CapabilityExprMode) {
488 if (
const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) {
490 CV = lookupVarDecl(VD);
496 E1 = addStatement(E1,
nullptr, VD);
499 return updateVarDecl(VD, E1);
576 if (CapabilityExprMode)
594 SExprBuilder::translateAbstractConditionalOperator(
607 if (
VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
608 Expr *E = VD->getInit();
614 return addVarDecl(VD, SE);
636 CurrentInstructions.push_back(E);
645 auto It = LVarIdxMap.find(VD);
646 if (It != LVarIdxMap.end()) {
647 assert(CurrentLVarMap[It->second].first == VD);
648 return CurrentLVarMap[It->second].second;
667 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.
size()));
669 CurrentLVarMap.
push_back(std::make_pair(VD, E));
677 auto It = LVarIdxMap.find(VD);
678 if (It == LVarIdxMap.end()) {
684 CurrentLVarMap.
elem(It->second).second = E;
692 void SExprBuilder::makePhiNodeVar(
unsigned i,
unsigned NPreds,
til::SExpr *E) {
693 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
694 assert(ArgIndex > 0 && ArgIndex < NPreds);
697 if (CurrE->
block() == CurrentBB) {
701 assert(Ph &&
"Expecting Phi node.");
703 Ph->
values()[ArgIndex] = E;
711 for (
unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
712 Ph->
values()[PIdx] = CurrE;
714 Ph->
values()[ArgIndex] = E;
723 CurrentArguments.push_back(Ph);
725 IncompleteArgs.push_back(Ph);
728 CurrentLVarMap.
elem(i).second = Ph;
734 void SExprBuilder::mergeEntryMap(LVarDefinitionMap
Map) {
735 assert(CurrentBlockInfo &&
"Not processing a block!");
737 if (!CurrentLVarMap.
valid()) {
739 CurrentLVarMap = std::move(Map);
742 if (CurrentLVarMap.
sameAs(Map))
746 unsigned ESz = CurrentLVarMap.
size();
747 unsigned MSz = Map.size();
748 unsigned Sz = std::min(ESz, MSz);
750 for (
unsigned i=0; i<Sz; ++i) {
751 if (CurrentLVarMap[i].first != Map[i].first) {
757 if (CurrentLVarMap[i].second != Map[i].second)
758 makePhiNodeVar(i, NPreds, Map[i].second);
762 CurrentLVarMap.
downsize(Map.size());
769 void SExprBuilder::mergeEntryMapBackEdge() {
778 assert(CurrentBlockInfo &&
"Not processing a block!");
780 if (CurrentBlockInfo->HasBackEdges)
782 CurrentBlockInfo->HasBackEdges =
true;
785 unsigned Sz = CurrentLVarMap.
size();
788 for (
unsigned i=0; i < Sz; ++i) {
789 makePhiNodeVar(i, NPreds,
nullptr);
797 void SExprBuilder::mergePhiNodesBackEdge(
const CFGBlock *Blk) {
799 unsigned ArgIndex = BBInfo[Blk->
getBlockID()].ProcessedPredecessors;
800 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
803 til::Phi *Ph = dyn_cast_or_null<til::Phi>(PE);
804 assert(Ph &&
"Expecting Phi Node.");
805 assert(Ph->
values()[ArgIndex] ==
nullptr &&
"Wrong index for back edge.");
808 assert(E &&
"Couldn't find local variable for Phi node.");
809 Ph->
values()[ArgIndex] = E;
813 void SExprBuilder::enterCFG(
CFG *Cfg,
const NamedDecl *D,
817 Scfg =
new (Arena)
til::SCFG(Arena, NBlocks);
820 BBInfo.resize(NBlocks);
821 BlockMap.resize(NBlocks,
nullptr);
823 for (
auto *B : *Cfg) {
826 BlockMap[B->getBlockID()] = BB;
830 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
831 : cast<FunctionDecl>(D)->parameters();
832 for (
auto *Pm : Parms) {
841 til::SExpr *V = addStatement(Ld,
nullptr, Pm);
847 void SExprBuilder::enterCFGBlock(
const CFGBlock *B) {
851 Scfg->
add(CurrentBB);
861 void SExprBuilder::handlePredecessor(
const CFGBlock *Pred) {
865 BlockInfo *PredInfo = &BBInfo[Pred->
getBlockID()];
866 assert(PredInfo->UnprocessedSuccessors > 0);
868 if (--PredInfo->UnprocessedSuccessors == 0)
869 mergeEntryMap(std::move(PredInfo->ExitMap));
871 mergeEntryMap(PredInfo->ExitMap.clone());
873 ++CurrentBlockInfo->ProcessedPredecessors;
877 void SExprBuilder::handlePredecessorBackEdge(
const CFGBlock *Pred) {
878 mergeEntryMapBackEdge();
882 void SExprBuilder::enterCFGBlockBody(
const CFGBlock *B) {
886 static_cast<unsigned>(CurrentArguments.size()), Arena);
887 for (
auto *A : CurrentArguments)
892 void SExprBuilder::handleStatement(
const Stmt *S) {
898 void SExprBuilder::handleDestructorCall(
const VarDecl *VD,
904 addStatement(E,
nullptr);
909 void SExprBuilder::exitCFGBlockBody(
const CFGBlock *B) {
911 static_cast<unsigned>(CurrentInstructions.size()), Arena);
912 for (
auto *V : CurrentInstructions)
922 auto *Tm =
new (Arena)
til::Goto(BB, Idx);
937 void SExprBuilder::handleSuccessor(
const CFGBlock *Succ) {
938 ++CurrentBlockInfo->UnprocessedSuccessors;
942 void SExprBuilder::handleSuccessorBackEdge(
const CFGBlock *Succ) {
943 mergePhiNodesBackEdge(Succ);
944 ++BBInfo[Succ->
getBlockID()].ProcessedPredecessors;
948 void SExprBuilder::exitCFGBlock(
const CFGBlock *B) {
949 CurrentArguments.clear();
950 CurrentInstructions.clear();
951 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
953 CurrentBlockInfo =
nullptr;
958 for (
auto *Ph : IncompleteArgs) {
963 CurrentArguments.clear();
964 CurrentInstructions.clear();
965 IncompleteArgs.clear();
A call to an overloaded operator written using operator syntax.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
CastKind getCastKind() const
Apply a self-argument to a self-applicable function.
Expr ** getArgs()
Retrieve the call arguments.
til::SExpr * lookupStmt(const Stmt *S)
const DeclGroupRef getDeclGroup() const
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
succ_iterator succ_begin()
static bool hasCppPointerType(const til::SExpr *E)
Defines the SourceManager interface.
const ValArray & values() const
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
static const ValueDecl * getValueDeclFromSExpr(const til::SExpr *E)
Represents a call to a C++ constructor.
void push_back(const T &Elem)
const Expr * getCallee() const
static bool isCalleeArrow(const Expr *E)
unsigned succ_size() const
bool isTrivialType(ASTContext &Context) const
unsigned addPredecessor(BasicBlock *Pred)
static const CXXMethodDecl * getFirstVirtualDecl(const CXXMethodDecl *D)
ParmVarDecl - Represents a parameter to a function.
Defines the clang::Expr interface and subclasses for C++ expressions.
til::SCFG * buildCFG(CFGWalker &Walker)
method_iterator end_overridden_methods() const
InstrArray & instructions()
Project a named slot from a C++ struct or class.
Expr * getImplicitObjectArgument() const
Retrieves the implicit object argument for the member call.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
void reserveInstructions(unsigned Nins)
static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD)
Expr * getTrueExpr() const
void downsize(unsigned i)
unsigned pred_size() const
A builtin binary operation expression such as "x + y" or "x <= y".
std::string getNameAsString() const
Expr * IgnoreParenCasts() LLVM_READONLY
unsigned findPredecessorIndex(const BasicBlock *BB) const
Return the index of BB, or Predecessors.size if BB is not a predecessor.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Placeholder for expressions that cannot be represented in the TIL.
Represents the this expression in C++.
void addInstruction(SExpr *V)
Add a new instruction.
CXXMethodDecl * getMethodDecl() const
Retrieves the declaration of the called method.
CastKind
CastKind - The kind of operation required for a conversion.
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.
void addArgument(Phi *V)
Add a new argument.
const CXXMethodDecl *const * method_iterator
void setTerminator(Terminator *E)
Stmt * getTerminatorCondition(bool StripParens=true)
const InstrArray & arguments() const
Represents a C++ destructor within a class.
Defines an enumeration for C++ overloaded operators.
const ParmVarDecl * getParamDecl(unsigned i) const
static SVal getValue(SVal val, SValBuilder &svalBuilder)
Expr * getSubExpr() const
unsigned getBlockID() const
BasicBlock * block() const
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void reservePredecessors(unsigned NumPreds)
method_iterator begin_overridden_methods() const
ASTContext & getASTContext() const LLVM_READONLY
Represents a static or instance method of a struct/union/class.
bool sameAs(const CopyOnWriteVector &V) const
size_t numPredecessors() const
Returns the number of predecessors.
std::string getSourceLiteralString(const clang::Expr *CE)
SExprBuilder::CallingContext CallingContext
Placeholder for a wildcard that matches any other expression.
Encapsulates the lexical context of a function call. The lexical context includes the arguments to th...
Load a value from memory.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
void setClangDecl(const clang::ValueDecl *Cvd)
Set the clang variable associated with this Phi node.
const Expr *const * FunArgs
unsigned getNumArgs() const
til::BasicBlock * lookupBlock(const CFGBlock *B)
const clang::ValueDecl * clangDecl() const
Return the clang declaration of the variable for this Phi node, if any.
Expr * getFalseExpr() const
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
void setValues(unsigned Sz, const T &C)
CapabilityExpr translateAttrExpr(const Expr *AttrExp, const NamedDecl *D, const Expr *DeclExp, VarDecl *SelfD=nullptr)
Translate a clang expression in an attribute to a til::SExpr. Constructs the context from D...
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
void reserve(size_t Ncp, MemRegionRef A)
Defines the clang::SourceLocation class and associated facilities.
bool isTrivial(const SExpr *E)
void simplifyIncompleteArg(til::Phi *Ph)
static bool isIncompletePhi(const til::SExpr *E)
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
const NamedDecl * AttrDecl
Base class for AST nodes in the typed intermediate language.
An l-value expression is a reference to an object with independent storage.
Call a function (after all arguments have been applied).
SourceLocation getLocation() const
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
unsigned getNumBlockIDs() const
bool isPointerType() const