30 #include "llvm/ADT/StringRef.h" 31 #include "llvm/Support/Casting.h" 37 using namespace clang;
38 using namespace threadSafety;
43 case Stmt::IntegerLiteralClass:
44 return cast<IntegerLiteral>(CE)->
getValue().toString(10,
true);
45 case Stmt::StringLiteralClass: {
46 std::string ret(
"\"");
47 ret += cast<StringLiteral>(CE)->getString();
51 case Stmt::CharacterLiteralClass:
52 case Stmt::CXXNullPtrLiteralExprClass:
53 case Stmt::GNUNullExprClass:
54 case Stmt::CXXBoolLiteralExprClass:
55 case Stmt::FloatingLiteralClass:
56 case Stmt::ImaginaryLiteralClass:
57 case Stmt::ObjCStringLiteralClass:
65 if (
const auto *Ph = dyn_cast<til::Phi>(E))
73 auto It =
SMap.find(S);
86 return ME ? ME->
isArrow() :
false;
108 if (
const auto *ME = dyn_cast<MemberExpr>(DeclExp)) {
111 }
else if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
112 Ctx.
SelfArg = CE->getImplicitObjectArgument();
114 Ctx.
NumArgs = CE->getNumArgs();
116 }
else if (
const auto *CE = dyn_cast<CallExpr>(DeclExp)) {
117 Ctx.
NumArgs = CE->getNumArgs();
119 }
else if (
const auto *CE = dyn_cast<CXXConstructExpr>(DeclExp)) {
121 Ctx.
NumArgs = CE->getNumArgs();
123 }
else if (D && isa<CXXDestructorDecl>(D)) {
130 if (SelfDecl && !Ctx.
SelfArg) {
156 if (
const auto* SLit = dyn_cast<StringLiteral>(AttrExp)) {
157 if (SLit->getString() == StringRef(
"*"))
167 if (
const auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) {
168 if (OE->getOperator() == OO_Exclaim) {
170 AttrExp = OE->getArg(0);
173 else if (
const auto *UO = dyn_cast<UnaryOperator>(AttrExp)) {
174 if (UO->getOpcode() == UO_LNot) {
176 AttrExp = UO->getSubExpr();
184 if (!E || isa<til::Literal>(E))
188 if (
const auto *CE = dyn_cast_or_null<til::Cast>(E)) {
208 case Stmt::DeclRefExprClass:
209 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
210 case Stmt::CXXThisExprClass:
211 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
212 case Stmt::MemberExprClass:
213 return translateMemberExpr(cast<MemberExpr>(S), Ctx);
214 case Stmt::CallExprClass:
215 return translateCallExpr(cast<CallExpr>(S), Ctx);
216 case Stmt::CXXMemberCallExprClass:
217 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
218 case Stmt::CXXOperatorCallExprClass:
219 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
220 case Stmt::UnaryOperatorClass:
221 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
222 case Stmt::BinaryOperatorClass:
223 case Stmt::CompoundAssignOperatorClass:
224 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
226 case Stmt::ArraySubscriptExprClass:
227 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
228 case Stmt::ConditionalOperatorClass:
229 return translateAbstractConditionalOperator(
230 cast<ConditionalOperator>(S), Ctx);
231 case Stmt::BinaryConditionalOperatorClass:
232 return translateAbstractConditionalOperator(
233 cast<BinaryConditionalOperator>(S), Ctx);
236 case Stmt::ParenExprClass:
237 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
238 case Stmt::ExprWithCleanupsClass:
239 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
240 case Stmt::CXXBindTemporaryExprClass:
241 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
242 case Stmt::MaterializeTemporaryExprClass:
243 return translate(cast<MaterializeTemporaryExpr>(S)->GetTemporaryExpr(),
247 case Stmt::CharacterLiteralClass:
248 case Stmt::CXXNullPtrLiteralExprClass:
249 case Stmt::GNUNullExprClass:
250 case Stmt::CXXBoolLiteralExprClass:
251 case Stmt::FloatingLiteralClass:
252 case Stmt::ImaginaryLiteralClass:
253 case Stmt::IntegerLiteralClass:
254 case Stmt::StringLiteralClass:
255 case Stmt::ObjCStringLiteralClass:
258 case Stmt::DeclStmtClass:
259 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
263 if (
const auto *CE = dyn_cast<CastExpr>(S))
264 return translateCastExpr(CE, Ctx);
274 if (
const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
277 unsigned I = PV->getFunctionScopeIndex();
281 assert(I < Ctx->NumArgs);
286 VD = FD->getParamDecl(I);
298 assert(SelfVar &&
"We have no variable for 'this'!");
303 if (
const auto *V = dyn_cast<til::Variable>(E))
304 return V->clangDecl();
305 if (
const auto *Ph = dyn_cast<til::Phi>(E))
306 return Ph->clangDecl();
307 if (
const auto *
P = dyn_cast<til::Project>(E))
308 return P->clangDecl();
309 if (
const auto *L = dyn_cast<til::LiteralPtr>(E))
310 return L->clangDecl();
316 if (VD && VD->getType()->isPointerType())
318 if (
const auto *
C = dyn_cast<til::Cast>(E))
329 if (OverriddenMethods.begin() == OverriddenMethods.end())
332 D = *OverriddenMethods.begin();
343 if (
const auto *VD = dyn_cast<CXXMethodDecl>(D))
355 if (CapabilityExprMode) {
358 if (LockReturnedAttr* At = FD->
getAttr<LockReturnedAttr>()) {
370 for (
const auto *Arg : CE->
arguments()) {
377 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
379 if (CapabilityExprMode) {
388 return translateCallExpr(cast<CallExpr>(ME), Ctx,
392 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
394 if (CapabilityExprMode) {
397 if (k == OO_Star || k == OO_Arrow) {
403 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
416 if (CapabilityExprMode) {
418 if (
const auto *DRE = dyn_cast<DeclRefExpr>(UO->
getSubExpr())) {
477 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
479 CV = lookupVarDecl(VD);
485 E1 = addStatement(E1,
nullptr, VD);
488 return updateVarDecl(VD, E1);
499 case BO_Mul:
return translateBinOp(
til::BOP_Mul, BO, Ctx);
500 case BO_Div:
return translateBinOp(
til::BOP_Div, BO, Ctx);
501 case BO_Rem:
return translateBinOp(
til::BOP_Rem, BO, Ctx);
502 case BO_Add:
return translateBinOp(
til::BOP_Add, BO, Ctx);
503 case BO_Sub:
return translateBinOp(
til::BOP_Sub, BO, Ctx);
504 case BO_Shl:
return translateBinOp(
til::BOP_Shl, BO, Ctx);
505 case BO_Shr:
return translateBinOp(
til::BOP_Shr, BO, Ctx);
506 case BO_LT:
return translateBinOp(
til::BOP_Lt, BO, Ctx);
507 case BO_GT:
return translateBinOp(
til::BOP_Lt, BO, Ctx,
true);
508 case BO_LE:
return translateBinOp(
til::BOP_Leq, BO, Ctx);
509 case BO_GE:
return translateBinOp(
til::BOP_Leq, BO, Ctx,
true);
510 case BO_EQ:
return translateBinOp(
til::BOP_Eq, BO, Ctx);
511 case BO_NE:
return translateBinOp(
til::BOP_Neq, BO, Ctx);
512 case BO_Cmp:
return translateBinOp(
til::BOP_Cmp, BO, Ctx);
519 case BO_Assign:
return translateBinAssign(
til::BOP_Eq, BO, Ctx,
true);
520 case BO_MulAssign:
return translateBinAssign(
til::BOP_Mul, BO, Ctx);
521 case BO_DivAssign:
return translateBinAssign(
til::BOP_Div, BO, Ctx);
522 case BO_RemAssign:
return translateBinAssign(
til::BOP_Rem, BO, Ctx);
523 case BO_AddAssign:
return translateBinAssign(
til::BOP_Add, BO, Ctx);
524 case BO_SubAssign:
return translateBinAssign(
til::BOP_Sub, BO, Ctx);
525 case BO_ShlAssign:
return translateBinAssign(
til::BOP_Shl, BO, Ctx);
526 case BO_ShrAssign:
return translateBinAssign(
til::BOP_Shr, BO, Ctx);
527 case BO_AndAssign:
return translateBinAssign(
til::BOP_BitAnd, BO, Ctx);
528 case BO_XorAssign:
return translateBinAssign(
til::BOP_BitXor, BO, Ctx);
529 case BO_OrAssign:
return translateBinAssign(
til::BOP_BitOr, BO, Ctx);
542 case CK_LValueToRValue: {
543 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CE->
getSubExpr())) {
554 case CK_DerivedToBase:
555 case CK_UncheckedDerivedToBase:
556 case CK_ArrayToPointerDecay:
557 case CK_FunctionToPointerDecay: {
564 if (CapabilityExprMode)
580 SExprBuilder::translateAbstractConditionalOperator(
591 for (
auto I : DGrp) {
592 if (
auto *VD = dyn_cast_or_null<VarDecl>(I)) {
593 Expr *E = VD->getInit();
599 return addVarDecl(VD, SE);
618 CurrentInstructions.push_back(E);
626 auto It = LVarIdxMap.find(VD);
627 if (It != LVarIdxMap.end()) {
628 assert(CurrentLVarMap[It->second].first == VD);
629 return CurrentLVarMap[It->second].second;
638 if (
auto *V = dyn_cast<til::Variable>(E)) {
647 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.
size()));
649 CurrentLVarMap.
push_back(std::make_pair(VD, E));
656 auto It = LVarIdxMap.find(VD);
657 if (It == LVarIdxMap.end()) {
663 CurrentLVarMap.
elem(It->second).second = E;
670 void SExprBuilder::makePhiNodeVar(
unsigned i,
unsigned NPreds,
til::SExpr *E) {
671 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
672 assert(ArgIndex > 0 && ArgIndex < NPreds);
675 if (CurrE->
block() == CurrentBB) {
678 auto *Ph = dyn_cast<
til::Phi>(CurrE);
679 assert(Ph &&
"Expecting Phi node.");
681 Ph->values()[ArgIndex] = E;
689 for (
unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
690 Ph->
values()[PIdx] = CurrE;
692 Ph->
values()[ArgIndex] = E;
700 CurrentArguments.push_back(Ph);
702 IncompleteArgs.push_back(Ph);
705 CurrentLVarMap.
elem(i).second = Ph;
710 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
711 assert(CurrentBlockInfo &&
"Not processing a block!");
713 if (!CurrentLVarMap.
valid()) {
715 CurrentLVarMap = std::move(Map);
718 if (CurrentLVarMap.
sameAs(Map))
722 unsigned ESz = CurrentLVarMap.
size();
723 unsigned MSz = Map.size();
726 for (
unsigned i = 0; i < Sz; ++i) {
727 if (CurrentLVarMap[i].first != Map[i].first) {
733 if (CurrentLVarMap[i].second != Map[i].second)
734 makePhiNodeVar(i, NPreds, Map[i].second);
738 CurrentLVarMap.
downsize(Map.size());
744 void SExprBuilder::mergeEntryMapBackEdge() {
753 assert(CurrentBlockInfo &&
"Not processing a block!");
755 if (CurrentBlockInfo->HasBackEdges)
757 CurrentBlockInfo->HasBackEdges =
true;
760 unsigned Sz = CurrentLVarMap.
size();
763 for (
unsigned i = 0; i < Sz; ++i)
764 makePhiNodeVar(i, NPreds,
nullptr);
770 void SExprBuilder::mergePhiNodesBackEdge(
const CFGBlock *Blk) {
772 unsigned ArgIndex = BBInfo[Blk->
getBlockID()].ProcessedPredecessors;
773 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
776 auto *Ph = dyn_cast_or_null<til::Phi>(PE);
777 assert(Ph &&
"Expecting Phi Node.");
778 assert(Ph->values()[ArgIndex] ==
nullptr &&
"Wrong index for back edge.");
780 til::SExpr *E = lookupVarDecl(Ph->clangDecl());
781 assert(E &&
"Couldn't find local variable for Phi node.");
782 Ph->values()[ArgIndex] = E;
786 void SExprBuilder::enterCFG(
CFG *Cfg,
const NamedDecl *D,
790 Scfg =
new (Arena)
til::SCFG(Arena, NBlocks);
793 BBInfo.resize(NBlocks);
794 BlockMap.resize(NBlocks,
nullptr);
796 for (
auto *B : *Cfg) {
799 BlockMap[B->getBlockID()] = BB;
803 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
804 : cast<FunctionDecl>(D)->parameters();
805 for (
auto *Pm : Parms) {
814 til::SExpr *V = addStatement(Ld,
nullptr, Pm);
819 void SExprBuilder::enterCFGBlock(
const CFGBlock *B) {
823 Scfg->
add(CurrentBB);
832 void SExprBuilder::handlePredecessor(
const CFGBlock *Pred) {
836 BlockInfo *PredInfo = &BBInfo[Pred->
getBlockID()];
837 assert(PredInfo->UnprocessedSuccessors > 0);
839 if (--PredInfo->UnprocessedSuccessors == 0)
840 mergeEntryMap(std::move(PredInfo->ExitMap));
842 mergeEntryMap(PredInfo->ExitMap.clone());
844 ++CurrentBlockInfo->ProcessedPredecessors;
847 void SExprBuilder::handlePredecessorBackEdge(
const CFGBlock *Pred) {
848 mergeEntryMapBackEdge();
851 void SExprBuilder::enterCFGBlockBody(
const CFGBlock *B) {
855 static_cast<unsigned>(CurrentArguments.size()), Arena);
856 for (
auto *A : CurrentArguments)
860 void SExprBuilder::handleStatement(
const Stmt *S) {
865 void SExprBuilder::handleDestructorCall(
const VarDecl *VD,
871 addStatement(E,
nullptr);
874 void SExprBuilder::exitCFGBlockBody(
const CFGBlock *B) {
876 static_cast<unsigned>(CurrentInstructions.size()), Arena);
877 for (
auto *V : CurrentInstructions)
887 auto *Tm =
new (Arena)
til::Goto(BB, Idx);
901 void SExprBuilder::handleSuccessor(
const CFGBlock *Succ) {
902 ++CurrentBlockInfo->UnprocessedSuccessors;
905 void SExprBuilder::handleSuccessorBackEdge(
const CFGBlock *Succ) {
906 mergePhiNodesBackEdge(Succ);
907 ++BBInfo[Succ->
getBlockID()].ProcessedPredecessors;
910 void SExprBuilder::exitCFGBlock(
const CFGBlock *B) {
911 CurrentArguments.clear();
912 CurrentInstructions.clear();
913 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
915 CurrentBlockInfo =
nullptr;
919 for (
auto *Ph : IncompleteArgs) {
924 CurrentArguments.clear();
925 CurrentInstructions.clear();
926 IncompleteArgs.clear();
A call to an overloaded operator written using operator syntax.
Simple arithmetic unary operations, e.g.
static const Decl * getCanonicalDecl(const Decl *D)
Represents a function declaration or definition.
Apply a self-argument to a self-applicable function.
Expr ** getArgs()
Retrieve the call arguments.
til::SExpr * lookupStmt(const Stmt *S)
A (possibly-)qualified type.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A conditional branch to two other blocks.
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
succ_iterator succ_begin()
static bool hasCppPointerType(const til::SExpr *E)
Stmt - This represents one statement.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
C Language Family Type Representation.
unsigned getBlockID() const
Expr * getImplicitObjectArgument() const
Retrieves the implicit object argument for the member call.
til::SExpr * translate(const Stmt *S, CallingContext *Ctx)
Expr * getFalseExpr() const
static const ValueDecl * getValueDeclFromSExpr(const til::SExpr *E)
void push_back(const T &Elem)
unsigned succ_size() const
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
Represents a variable declaration or definition.
std::string getSourceLiteralString(const Expr *CE)
static bool isCalleeArrow(const Expr *E)
unsigned addPredecessor(BasicBlock *Pred)
static const CXXMethodDecl * getFirstVirtualDecl(const CXXMethodDecl *D)
size_t numPredecessors() const
Returns the number of predecessors.
Defines the clang::Expr interface and subclasses for C++ expressions.
If p is a reference to an array, then p[i] is a reference to the i'th element of the array...
til::SCFG * buildCFG(CFGWalker &Walker)
InstrArray & instructions()
Project a named slot from a C++ struct or class.
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
const DeclGroupRef getDeclGroup() const
void reserveInstructions(unsigned Nins)
unsigned findPredecessorIndex(const BasicBlock *BB) const
Return the index of BB, or Predecessors.size if BB is not a predecessor.
static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD)
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
void downsize(unsigned i)
A builtin binary operation expression such as "x + y" or "x <= y".
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
A basic block is part of an SCFG.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
void setClangDecl(const ValueDecl *Cvd)
Set the clang variable associated with this Phi node.
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.
An SCFG is a control-flow graph.
CastKind
CastKind - The kind of operation required for a conversion.
Represents a single basic block in a source-level CFG.
void addArgument(Phi *V)
Add a new argument.
Apply an argument to a function.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Expr - This represents one expression.
void setTerminator(Terminator *E)
Stmt * getTerminatorCondition(bool StripParens=true)
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt...
Represents a C++ destructor within a class.
Defines an enumeration for C++ overloaded operators.
const Expr * getCallee() const
overridden_method_range overridden_methods() const
static SVal getValue(SVal val, SValBuilder &svalBuilder)
Jump to another basic block.
SExprBuilder::CallingContext CallingContext
UnaryOperator - This represents the unary-expression's (except sizeof and alignof), the postinc/postdec operators from postfix-expression, and various extensions.
CXXMethodDecl * getMethodDecl() const
Retrieves the declaration of the called method.
Expr * getTrueExpr() const
TIL_BinaryOpcode
Opcode for binary arithmetic operations.
void reservePredecessors(unsigned NumPreds)
Expr * getSubExpr() const
CastKind getCastKind() const
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
const ValArray & values() const
Represents a call to a member function that may be written either with member call syntax (e...
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Represents a static or instance method of a struct/union/class.
unsigned getNumBlockIDs() const
Returns the total number of BlockIDs allocated (which start at 0).
Placeholder for a wildcard that matches any other expression.
bool sameAs(const CopyOnWriteVector &V) const
Encapsulates the lexical context of a function call.
const InstrArray & arguments() const
Defines various enumerations that describe declaration and type specifiers.
Load a value from memory.
Dataflow Directional Tag Classes.
OverloadedOperatorKind getOperator() const
Returns the kind of overloaded operator that this expression refers to.
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return 0.
unsigned pred_size() const
An if-then-else expression.
StmtClass getStmtClass() const
const Expr *const * FunArgs
BasicBlock * block() const
Returns the block, if this is an instruction in a basic block, otherwise returns null.
til::BasicBlock * lookupBlock(const CFGBlock *B)
Phi Node, for code in SSA form.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
AbstractConditionalOperator - An abstract base class for ConditionalOperator and BinaryConditionalOpe...
Simple arithmetic binary operations, e.g.
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.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
void reserve(size_t Ncp, MemRegionRef A)
bool isTrivial(const SExpr *E)
void simplifyIncompleteArg(til::Phi *Ph)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
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.
const NamedDecl * AttrDecl
__DEVICE__ int min(int __a, int __b)
Base class for AST nodes in the typed intermediate language.
A Literal pointer to an object allocated in memory.
An l-value expression is a reference to an object with independent storage.
Call a function (after all arguments have been applied).
This represents a decl that may have a name.
llvm::DenseMap< const Stmt *, CFGBlock * > SMap
SourceLocation getLocation() const
bool isCXXInstanceMember() const
Determine whether the given declaration is an instance member of a C++ class.