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) {
157 if (
const auto* SLit = dyn_cast<StringLiteral>(AttrExp)) {
158 if (SLit->getString() == StringRef(
"*"))
168 if (
const auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) {
169 if (OE->getOperator() == OO_Exclaim) {
171 AttrExp = OE->getArg(0);
174 else if (
const auto *UO = dyn_cast<UnaryOperator>(AttrExp)) {
175 if (UO->getOpcode() == UO_LNot) {
177 AttrExp = UO->getSubExpr();
185 if (!E || isa<til::Literal>(E))
189 if (
const auto *CE = dyn_cast_or_null<til::Cast>(E)) {
209 case Stmt::DeclRefExprClass:
210 return translateDeclRefExpr(cast<DeclRefExpr>(S), Ctx);
211 case Stmt::CXXThisExprClass:
212 return translateCXXThisExpr(cast<CXXThisExpr>(S), Ctx);
213 case Stmt::MemberExprClass:
214 return translateMemberExpr(cast<MemberExpr>(S), Ctx);
215 case Stmt::ObjCIvarRefExprClass:
216 return translateObjCIVarRefExpr(cast<ObjCIvarRefExpr>(S), Ctx);
217 case Stmt::CallExprClass:
218 return translateCallExpr(cast<CallExpr>(S), Ctx);
219 case Stmt::CXXMemberCallExprClass:
220 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
221 case Stmt::CXXOperatorCallExprClass:
222 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
223 case Stmt::UnaryOperatorClass:
224 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
225 case Stmt::BinaryOperatorClass:
226 case Stmt::CompoundAssignOperatorClass:
227 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
229 case Stmt::ArraySubscriptExprClass:
230 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
231 case Stmt::ConditionalOperatorClass:
232 return translateAbstractConditionalOperator(
233 cast<ConditionalOperator>(S), Ctx);
234 case Stmt::BinaryConditionalOperatorClass:
235 return translateAbstractConditionalOperator(
236 cast<BinaryConditionalOperator>(S), Ctx);
239 case Stmt::ConstantExprClass:
240 return translate(cast<ConstantExpr>(S)->getSubExpr(), 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);
247 case Stmt::MaterializeTemporaryExprClass:
248 return translate(cast<MaterializeTemporaryExpr>(S)->GetTemporaryExpr(),
252 case Stmt::CharacterLiteralClass:
253 case Stmt::CXXNullPtrLiteralExprClass:
254 case Stmt::GNUNullExprClass:
255 case Stmt::CXXBoolLiteralExprClass:
256 case Stmt::FloatingLiteralClass:
257 case Stmt::ImaginaryLiteralClass:
258 case Stmt::IntegerLiteralClass:
259 case Stmt::StringLiteralClass:
260 case Stmt::ObjCStringLiteralClass:
263 case Stmt::DeclStmtClass:
264 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
268 if (
const auto *CE = dyn_cast<CastExpr>(S))
269 return translateCastExpr(CE, Ctx);
279 if (
const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
282 unsigned I = PV->getFunctionScopeIndex();
286 assert(I < Ctx->NumArgs);
291 VD = FD->getParamDecl(I);
303 assert(SelfVar &&
"We have no variable for 'this'!");
308 if (
const auto *V = dyn_cast<til::Variable>(E))
309 return V->clangDecl();
310 if (
const auto *Ph = dyn_cast<til::Phi>(E))
311 return Ph->clangDecl();
312 if (
const auto *
P = dyn_cast<til::Project>(E))
313 return P->clangDecl();
314 if (
const auto *L = dyn_cast<til::LiteralPtr>(E))
315 return L->clangDecl();
321 if (VD && VD->getType()->isAnyPointerType())
323 if (
const auto *
C = dyn_cast<til::Cast>(E))
334 if (OverriddenMethods.begin() == OverriddenMethods.end())
337 D = *OverriddenMethods.begin();
348 if (
const auto *VD = dyn_cast<CXXMethodDecl>(D))
373 if (CapabilityExprMode) {
376 FD = FD->getMostRecentDecl();
377 if (LockReturnedAttr *At = FD->getAttr<LockReturnedAttr>()) {
390 for (
const auto *Arg : CE->
arguments()) {
397 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
399 if (CapabilityExprMode) {
408 return translateCallExpr(cast<CallExpr>(ME), Ctx,
412 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
414 if (CapabilityExprMode) {
417 if (k == OO_Star || k == OO_Arrow) {
423 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
436 if (CapabilityExprMode) {
438 if (
const auto *DRE = dyn_cast<DeclRefExpr>(UO->
getSubExpr())) {
497 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
499 CV = lookupVarDecl(VD);
505 E1 = addStatement(E1,
nullptr, VD);
508 return updateVarDecl(VD, E1);
519 case BO_Mul:
return translateBinOp(
til::BOP_Mul, BO, Ctx);
520 case BO_Div:
return translateBinOp(
til::BOP_Div, BO, Ctx);
521 case BO_Rem:
return translateBinOp(
til::BOP_Rem, BO, Ctx);
522 case BO_Add:
return translateBinOp(
til::BOP_Add, BO, Ctx);
523 case BO_Sub:
return translateBinOp(
til::BOP_Sub, BO, Ctx);
524 case BO_Shl:
return translateBinOp(
til::BOP_Shl, BO, Ctx);
525 case BO_Shr:
return translateBinOp(
til::BOP_Shr, BO, Ctx);
526 case BO_LT:
return translateBinOp(
til::BOP_Lt, BO, Ctx);
527 case BO_GT:
return translateBinOp(
til::BOP_Lt, BO, Ctx,
true);
528 case BO_LE:
return translateBinOp(
til::BOP_Leq, BO, Ctx);
529 case BO_GE:
return translateBinOp(
til::BOP_Leq, BO, Ctx,
true);
530 case BO_EQ:
return translateBinOp(
til::BOP_Eq, BO, Ctx);
531 case BO_NE:
return translateBinOp(
til::BOP_Neq, BO, Ctx);
532 case BO_Cmp:
return translateBinOp(
til::BOP_Cmp, BO, Ctx);
539 case BO_Assign:
return translateBinAssign(
til::BOP_Eq, BO, Ctx,
true);
540 case BO_MulAssign:
return translateBinAssign(
til::BOP_Mul, BO, Ctx);
541 case BO_DivAssign:
return translateBinAssign(
til::BOP_Div, BO, Ctx);
542 case BO_RemAssign:
return translateBinAssign(
til::BOP_Rem, BO, Ctx);
543 case BO_AddAssign:
return translateBinAssign(
til::BOP_Add, BO, Ctx);
544 case BO_SubAssign:
return translateBinAssign(
til::BOP_Sub, BO, Ctx);
545 case BO_ShlAssign:
return translateBinAssign(
til::BOP_Shl, BO, Ctx);
546 case BO_ShrAssign:
return translateBinAssign(
til::BOP_Shr, BO, Ctx);
547 case BO_AndAssign:
return translateBinAssign(
til::BOP_BitAnd, BO, Ctx);
548 case BO_XorAssign:
return translateBinAssign(
til::BOP_BitXor, BO, Ctx);
549 case BO_OrAssign:
return translateBinAssign(
til::BOP_BitOr, BO, Ctx);
562 case CK_LValueToRValue: {
563 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CE->
getSubExpr())) {
574 case CK_DerivedToBase:
575 case CK_UncheckedDerivedToBase:
576 case CK_ArrayToPointerDecay:
577 case CK_FunctionToPointerDecay: {
584 if (CapabilityExprMode)
600 SExprBuilder::translateAbstractConditionalOperator(
611 for (
auto I : DGrp) {
612 if (
auto *VD = dyn_cast_or_null<VarDecl>(I)) {
613 Expr *E = VD->getInit();
619 return addVarDecl(VD, SE);
638 CurrentInstructions.push_back(E);
646 auto It = LVarIdxMap.find(VD);
647 if (It != LVarIdxMap.end()) {
648 assert(CurrentLVarMap[It->second].first == VD);
649 return CurrentLVarMap[It->second].second;
658 if (
auto *V = dyn_cast<til::Variable>(E)) {
667 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.
size()));
669 CurrentLVarMap.
push_back(std::make_pair(VD, E));
676 auto It = LVarIdxMap.find(VD);
677 if (It == LVarIdxMap.end()) {
683 CurrentLVarMap.
elem(It->second).second = E;
690 void SExprBuilder::makePhiNodeVar(
unsigned i,
unsigned NPreds,
til::SExpr *E) {
691 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
692 assert(ArgIndex > 0 && ArgIndex < NPreds);
695 if (CurrE->
block() == CurrentBB) {
698 auto *Ph = dyn_cast<
til::Phi>(CurrE);
699 assert(Ph &&
"Expecting Phi node.");
701 Ph->values()[ArgIndex] = E;
709 for (
unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
710 Ph->
values()[PIdx] = CurrE;
712 Ph->
values()[ArgIndex] = E;
720 CurrentArguments.push_back(Ph);
722 IncompleteArgs.push_back(Ph);
725 CurrentLVarMap.
elem(i).second = Ph;
730 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
731 assert(CurrentBlockInfo &&
"Not processing a block!");
733 if (!CurrentLVarMap.
valid()) {
735 CurrentLVarMap = std::move(Map);
738 if (CurrentLVarMap.
sameAs(Map))
742 unsigned ESz = CurrentLVarMap.
size();
743 unsigned MSz = Map.size();
746 for (
unsigned i = 0; i < Sz; ++i) {
747 if (CurrentLVarMap[i].first != Map[i].first) {
753 if (CurrentLVarMap[i].second != Map[i].second)
754 makePhiNodeVar(i, NPreds, Map[i].second);
758 CurrentLVarMap.
downsize(Map.size());
764 void SExprBuilder::mergeEntryMapBackEdge() {
773 assert(CurrentBlockInfo &&
"Not processing a block!");
775 if (CurrentBlockInfo->HasBackEdges)
777 CurrentBlockInfo->HasBackEdges =
true;
780 unsigned Sz = CurrentLVarMap.
size();
783 for (
unsigned i = 0; i < Sz; ++i)
784 makePhiNodeVar(i, NPreds,
nullptr);
790 void SExprBuilder::mergePhiNodesBackEdge(
const CFGBlock *Blk) {
792 unsigned ArgIndex = BBInfo[Blk->
getBlockID()].ProcessedPredecessors;
793 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
796 auto *Ph = dyn_cast_or_null<til::Phi>(PE);
797 assert(Ph &&
"Expecting Phi Node.");
798 assert(Ph->values()[ArgIndex] ==
nullptr &&
"Wrong index for back edge.");
800 til::SExpr *E = lookupVarDecl(Ph->clangDecl());
801 assert(E &&
"Couldn't find local variable for Phi node.");
802 Ph->values()[ArgIndex] = E;
806 void SExprBuilder::enterCFG(
CFG *Cfg,
const NamedDecl *D,
810 Scfg =
new (Arena)
til::SCFG(Arena, NBlocks);
813 BBInfo.resize(NBlocks);
814 BlockMap.resize(NBlocks,
nullptr);
816 for (
auto *B : *Cfg) {
819 BlockMap[B->getBlockID()] = BB;
823 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
824 : cast<FunctionDecl>(D)->parameters();
825 for (
auto *Pm : Parms) {
834 til::SExpr *V = addStatement(Ld,
nullptr, Pm);
839 void SExprBuilder::enterCFGBlock(
const CFGBlock *B) {
843 Scfg->
add(CurrentBB);
852 void SExprBuilder::handlePredecessor(
const CFGBlock *Pred) {
856 BlockInfo *PredInfo = &BBInfo[Pred->
getBlockID()];
857 assert(PredInfo->UnprocessedSuccessors > 0);
859 if (--PredInfo->UnprocessedSuccessors == 0)
860 mergeEntryMap(std::move(PredInfo->ExitMap));
862 mergeEntryMap(PredInfo->ExitMap.clone());
864 ++CurrentBlockInfo->ProcessedPredecessors;
867 void SExprBuilder::handlePredecessorBackEdge(
const CFGBlock *Pred) {
868 mergeEntryMapBackEdge();
871 void SExprBuilder::enterCFGBlockBody(
const CFGBlock *B) {
875 static_cast<unsigned>(CurrentArguments.size()), Arena);
876 for (
auto *A : CurrentArguments)
880 void SExprBuilder::handleStatement(
const Stmt *S) {
885 void SExprBuilder::handleDestructorCall(
const VarDecl *VD,
891 addStatement(E,
nullptr);
894 void SExprBuilder::exitCFGBlockBody(
const CFGBlock *B) {
896 static_cast<unsigned>(CurrentInstructions.size()), Arena);
897 for (
auto *V : CurrentInstructions)
907 auto *Tm =
new (Arena)
til::Goto(BB, Idx);
921 void SExprBuilder::handleSuccessor(
const CFGBlock *Succ) {
922 ++CurrentBlockInfo->UnprocessedSuccessors;
925 void SExprBuilder::handleSuccessorBackEdge(
const CFGBlock *Succ) {
926 mergePhiNodesBackEdge(Succ);
927 ++BBInfo[Succ->
getBlockID()].ProcessedPredecessors;
930 void SExprBuilder::exitCFGBlock(
const CFGBlock *B) {
931 CurrentArguments.clear();
932 CurrentInstructions.clear();
933 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
935 CurrentBlockInfo =
nullptr;
939 for (
auto *Ph : IncompleteArgs) {
944 CurrentArguments.clear();
945 CurrentInstructions.clear();
946 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()
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)
static bool hasAnyPointerType(const til::SExpr *E)
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
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 ...
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.
overridden_method_range overridden_methods() const
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
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...
ASTContext & getASTContext() const LLVM_READONLY
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.
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.
const Expr * getBase() const
void setValues(unsigned Sz, const T &C)
ObjCIvarRefExpr - A reference to an ObjC instance variable.
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)
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.