29 #include "llvm/ADT/StringRef.h" 30 #include "llvm/Support/Casting.h" 36 using namespace clang;
37 using namespace threadSafety;
42 case Stmt::IntegerLiteralClass:
43 return cast<IntegerLiteral>(CE)->
getValue().toString(10,
true);
44 case Stmt::StringLiteralClass: {
45 std::string ret(
"\"");
46 ret += cast<StringLiteral>(CE)->getString();
50 case Stmt::CharacterLiteralClass:
51 case Stmt::CXXNullPtrLiteralExprClass:
52 case Stmt::GNUNullExprClass:
53 case Stmt::CXXBoolLiteralExprClass:
54 case Stmt::FloatingLiteralClass:
55 case Stmt::ImaginaryLiteralClass:
56 case Stmt::ObjCStringLiteralClass:
64 if (
const auto *Ph = dyn_cast<til::Phi>(E))
72 auto It =
SMap.find(S);
85 return ME ? ME->
isArrow() :
false;
107 if (
const auto *ME = dyn_cast<MemberExpr>(DeclExp)) {
110 }
else if (
const auto *CE = dyn_cast<CXXMemberCallExpr>(DeclExp)) {
111 Ctx.
SelfArg = CE->getImplicitObjectArgument();
113 Ctx.
NumArgs = CE->getNumArgs();
115 }
else if (
const auto *CE = dyn_cast<CallExpr>(DeclExp)) {
116 Ctx.
NumArgs = CE->getNumArgs();
118 }
else if (
const auto *CE = dyn_cast<CXXConstructExpr>(DeclExp)) {
120 Ctx.
NumArgs = CE->getNumArgs();
122 }
else if (D && isa<CXXDestructorDecl>(D)) {
129 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::ObjCIvarRefExprClass:
215 return translateObjCIVarRefExpr(cast<ObjCIvarRefExpr>(S), Ctx);
216 case Stmt::CallExprClass:
217 return translateCallExpr(cast<CallExpr>(S), Ctx);
218 case Stmt::CXXMemberCallExprClass:
219 return translateCXXMemberCallExpr(cast<CXXMemberCallExpr>(S), Ctx);
220 case Stmt::CXXOperatorCallExprClass:
221 return translateCXXOperatorCallExpr(cast<CXXOperatorCallExpr>(S), Ctx);
222 case Stmt::UnaryOperatorClass:
223 return translateUnaryOperator(cast<UnaryOperator>(S), Ctx);
224 case Stmt::BinaryOperatorClass:
225 case Stmt::CompoundAssignOperatorClass:
226 return translateBinaryOperator(cast<BinaryOperator>(S), Ctx);
228 case Stmt::ArraySubscriptExprClass:
229 return translateArraySubscriptExpr(cast<ArraySubscriptExpr>(S), Ctx);
230 case Stmt::ConditionalOperatorClass:
231 return translateAbstractConditionalOperator(
232 cast<ConditionalOperator>(S), Ctx);
233 case Stmt::BinaryConditionalOperatorClass:
234 return translateAbstractConditionalOperator(
235 cast<BinaryConditionalOperator>(S), Ctx);
238 case Stmt::ConstantExprClass:
239 return translate(cast<ConstantExpr>(S)->getSubExpr(), Ctx);
240 case Stmt::ParenExprClass:
241 return translate(cast<ParenExpr>(S)->getSubExpr(), Ctx);
242 case Stmt::ExprWithCleanupsClass:
243 return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
244 case Stmt::CXXBindTemporaryExprClass:
245 return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
246 case Stmt::MaterializeTemporaryExprClass:
247 return translate(cast<MaterializeTemporaryExpr>(S)->getSubExpr(), Ctx);
250 case Stmt::CharacterLiteralClass:
251 case Stmt::CXXNullPtrLiteralExprClass:
252 case Stmt::GNUNullExprClass:
253 case Stmt::CXXBoolLiteralExprClass:
254 case Stmt::FloatingLiteralClass:
255 case Stmt::ImaginaryLiteralClass:
256 case Stmt::IntegerLiteralClass:
257 case Stmt::StringLiteralClass:
258 case Stmt::ObjCStringLiteralClass:
261 case Stmt::DeclStmtClass:
262 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
266 if (
const auto *CE = dyn_cast<CastExpr>(S))
267 return translateCastExpr(CE, Ctx);
277 if (
const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
278 unsigned I = PV->getFunctionScopeIndex();
282 if (isa<FunctionDecl>(D)
286 assert(I < Ctx->NumArgs);
292 VD = isa<FunctionDecl>(D)
293 ? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I)
306 assert(SelfVar &&
"We have no variable for 'this'!");
311 if (
const auto *
V = dyn_cast<til::Variable>(E))
312 return V->clangDecl();
313 if (
const auto *Ph = dyn_cast<til::Phi>(E))
314 return Ph->clangDecl();
315 if (
const auto *
P = dyn_cast<til::Project>(E))
316 return P->clangDecl();
317 if (
const auto *L = dyn_cast<til::LiteralPtr>(E))
318 return L->clangDecl();
324 if (VD && VD->getType()->isAnyPointerType())
326 if (
const auto *
C = dyn_cast<til::Cast>(E))
337 if (OverriddenMethods.begin() == OverriddenMethods.end())
340 D = *OverriddenMethods.begin();
351 if (
const auto *VD = dyn_cast<CXXMethodDecl>(D))
376 if (CapabilityExprMode) {
379 FD = FD->getMostRecentDecl();
380 if (LockReturnedAttr *At = FD->getAttr<LockReturnedAttr>()) {
393 for (
const auto *Arg : CE->
arguments()) {
400 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
402 if (CapabilityExprMode) {
411 return translateCallExpr(cast<CallExpr>(ME), Ctx,
415 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
417 if (CapabilityExprMode) {
420 if (k == OO_Star || k == OO_Arrow) {
426 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
439 if (CapabilityExprMode) {
441 if (
const auto *DRE = dyn_cast<DeclRefExpr>(UO->
getSubExpr())) {
500 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
502 CV = lookupVarDecl(VD);
508 E1 = addStatement(E1,
nullptr, VD);
511 return updateVarDecl(VD, E1);
522 case BO_Mul:
return translateBinOp(
til::BOP_Mul, BO, Ctx);
523 case BO_Div:
return translateBinOp(
til::BOP_Div, BO, Ctx);
524 case BO_Rem:
return translateBinOp(
til::BOP_Rem, BO, Ctx);
525 case BO_Add:
return translateBinOp(
til::BOP_Add, BO, Ctx);
526 case BO_Sub:
return translateBinOp(
til::BOP_Sub, BO, Ctx);
527 case BO_Shl:
return translateBinOp(
til::BOP_Shl, BO, Ctx);
528 case BO_Shr:
return translateBinOp(
til::BOP_Shr, BO, Ctx);
529 case BO_LT:
return translateBinOp(
til::BOP_Lt, BO, Ctx);
530 case BO_GT:
return translateBinOp(
til::BOP_Lt, BO, Ctx,
true);
531 case BO_LE:
return translateBinOp(
til::BOP_Leq, BO, Ctx);
532 case BO_GE:
return translateBinOp(
til::BOP_Leq, BO, Ctx,
true);
533 case BO_EQ:
return translateBinOp(
til::BOP_Eq, BO, Ctx);
534 case BO_NE:
return translateBinOp(
til::BOP_Neq, BO, Ctx);
535 case BO_Cmp:
return translateBinOp(
til::BOP_Cmp, BO, Ctx);
542 case BO_Assign:
return translateBinAssign(
til::BOP_Eq, BO, Ctx,
true);
543 case BO_MulAssign:
return translateBinAssign(
til::BOP_Mul, BO, Ctx);
544 case BO_DivAssign:
return translateBinAssign(
til::BOP_Div, BO, Ctx);
545 case BO_RemAssign:
return translateBinAssign(
til::BOP_Rem, BO, Ctx);
546 case BO_AddAssign:
return translateBinAssign(
til::BOP_Add, BO, Ctx);
547 case BO_SubAssign:
return translateBinAssign(
til::BOP_Sub, BO, Ctx);
548 case BO_ShlAssign:
return translateBinAssign(
til::BOP_Shl, BO, Ctx);
549 case BO_ShrAssign:
return translateBinAssign(
til::BOP_Shr, BO, Ctx);
550 case BO_AndAssign:
return translateBinAssign(
til::BOP_BitAnd, BO, Ctx);
551 case BO_XorAssign:
return translateBinAssign(
til::BOP_BitXor, BO, Ctx);
552 case BO_OrAssign:
return translateBinAssign(
til::BOP_BitOr, BO, Ctx);
565 case CK_LValueToRValue: {
566 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CE->
getSubExpr())) {
577 case CK_DerivedToBase:
578 case CK_UncheckedDerivedToBase:
579 case CK_ArrayToPointerDecay:
580 case CK_FunctionToPointerDecay: {
587 if (CapabilityExprMode)
603 SExprBuilder::translateAbstractConditionalOperator(
614 for (
auto I : DGrp) {
615 if (
auto *VD = dyn_cast_or_null<VarDecl>(I)) {
616 Expr *E = VD->getInit();
622 return addVarDecl(VD, SE);
641 CurrentInstructions.push_back(E);
649 auto It = LVarIdxMap.find(VD);
650 if (It != LVarIdxMap.end()) {
651 assert(CurrentLVarMap[It->second].first == VD);
652 return CurrentLVarMap[It->second].second;
661 if (
auto *
V = dyn_cast<til::Variable>(E)) {
670 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.
size()));
672 CurrentLVarMap.
push_back(std::make_pair(VD, E));
679 auto It = LVarIdxMap.find(VD);
680 if (It == LVarIdxMap.end()) {
686 CurrentLVarMap.
elem(It->second).second = E;
693 void SExprBuilder::makePhiNodeVar(
unsigned i,
unsigned NPreds,
til::SExpr *E) {
694 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
695 assert(ArgIndex > 0 && ArgIndex < NPreds);
698 if (CurrE->
block() == CurrentBB) {
701 auto *Ph = dyn_cast<
til::Phi>(CurrE);
702 assert(Ph &&
"Expecting Phi node.");
704 Ph->values()[ArgIndex] = E;
712 for (
unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
713 Ph->
values()[PIdx] = CurrE;
715 Ph->
values()[ArgIndex] = E;
723 CurrentArguments.push_back(Ph);
725 IncompleteArgs.push_back(Ph);
728 CurrentLVarMap.
elem(i).second = Ph;
733 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
734 assert(CurrentBlockInfo &&
"Not processing a block!");
736 if (!CurrentLVarMap.
valid()) {
738 CurrentLVarMap = std::move(Map);
741 if (CurrentLVarMap.
sameAs(Map))
745 unsigned ESz = CurrentLVarMap.
size();
746 unsigned MSz = Map.size();
749 for (
unsigned i = 0; i < Sz; ++i) {
750 if (CurrentLVarMap[i].first != Map[i].first) {
756 if (CurrentLVarMap[i].second != Map[i].second)
757 makePhiNodeVar(i, NPreds, Map[i].second);
761 CurrentLVarMap.
downsize(Map.size());
767 void SExprBuilder::mergeEntryMapBackEdge() {
776 assert(CurrentBlockInfo &&
"Not processing a block!");
778 if (CurrentBlockInfo->HasBackEdges)
780 CurrentBlockInfo->HasBackEdges =
true;
783 unsigned Sz = CurrentLVarMap.
size();
786 for (
unsigned i = 0; i < Sz; ++i)
787 makePhiNodeVar(i, NPreds,
nullptr);
793 void SExprBuilder::mergePhiNodesBackEdge(
const CFGBlock *Blk) {
795 unsigned ArgIndex = BBInfo[Blk->
getBlockID()].ProcessedPredecessors;
796 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
799 auto *Ph = dyn_cast_or_null<til::Phi>(PE);
800 assert(Ph &&
"Expecting Phi Node.");
801 assert(Ph->values()[ArgIndex] ==
nullptr &&
"Wrong index for back edge.");
803 til::SExpr *E = lookupVarDecl(Ph->clangDecl());
804 assert(E &&
"Couldn't find local variable for Phi node.");
805 Ph->values()[ArgIndex] = E;
809 void SExprBuilder::enterCFG(
CFG *Cfg,
const NamedDecl *D,
813 Scfg =
new (Arena)
til::SCFG(Arena, NBlocks);
816 BBInfo.resize(NBlocks);
817 BlockMap.resize(NBlocks,
nullptr);
819 for (
auto *B : *Cfg) {
822 BlockMap[B->getBlockID()] = BB;
826 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
827 : cast<FunctionDecl>(D)->parameters();
828 for (
auto *Pm : Parms) {
842 void SExprBuilder::enterCFGBlock(
const CFGBlock *B) {
846 Scfg->
add(CurrentBB);
855 void SExprBuilder::handlePredecessor(
const CFGBlock *Pred) {
859 BlockInfo *PredInfo = &BBInfo[Pred->
getBlockID()];
860 assert(PredInfo->UnprocessedSuccessors > 0);
862 if (--PredInfo->UnprocessedSuccessors == 0)
863 mergeEntryMap(std::move(PredInfo->ExitMap));
865 mergeEntryMap(PredInfo->ExitMap.clone());
867 ++CurrentBlockInfo->ProcessedPredecessors;
870 void SExprBuilder::handlePredecessorBackEdge(
const CFGBlock *Pred) {
871 mergeEntryMapBackEdge();
874 void SExprBuilder::enterCFGBlockBody(
const CFGBlock *B) {
878 static_cast<unsigned>(CurrentArguments.size()), Arena);
879 for (
auto *A : CurrentArguments)
883 void SExprBuilder::handleStatement(
const Stmt *S) {
888 void SExprBuilder::handleDestructorCall(
const VarDecl *VD,
894 addStatement(E,
nullptr);
897 void SExprBuilder::exitCFGBlockBody(
const CFGBlock *B) {
899 static_cast<unsigned>(CurrentInstructions.size()), Arena);
900 for (
auto *
V : CurrentInstructions)
910 auto *Tm =
new (Arena)
til::Goto(BB, Idx);
924 void SExprBuilder::handleSuccessor(
const CFGBlock *Succ) {
925 ++CurrentBlockInfo->UnprocessedSuccessors;
928 void SExprBuilder::handleSuccessorBackEdge(
const CFGBlock *Succ) {
929 mergePhiNodesBackEdge(Succ);
930 ++BBInfo[Succ->
getBlockID()].ProcessedPredecessors;
933 void SExprBuilder::exitCFGBlock(
const CFGBlock *B) {
934 CurrentArguments.clear();
935 CurrentInstructions.clear();
936 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
938 CurrentBlockInfo =
nullptr;
942 for (
auto *Ph : IncompleteArgs) {
947 CurrentArguments.clear();
948 CurrentInstructions.clear();
949 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
Decl - This represents one declaration (or definition), e.g.
Expr * getImplicitObjectArgument() const
Retrieve 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
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
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
Retrieve 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.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
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)
__DEVICE__ int min(int __a, int __b)
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
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.