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)->GetTemporaryExpr(),
251 case Stmt::CharacterLiteralClass:
252 case Stmt::CXXNullPtrLiteralExprClass:
253 case Stmt::GNUNullExprClass:
254 case Stmt::CXXBoolLiteralExprClass:
255 case Stmt::FloatingLiteralClass:
256 case Stmt::ImaginaryLiteralClass:
257 case Stmt::IntegerLiteralClass:
258 case Stmt::StringLiteralClass:
259 case Stmt::ObjCStringLiteralClass:
262 case Stmt::DeclStmtClass:
263 return translateDeclStmt(cast<DeclStmt>(S), Ctx);
267 if (
const auto *CE = dyn_cast<CastExpr>(S))
268 return translateCastExpr(CE, Ctx);
278 if (
const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
279 unsigned I = PV->getFunctionScopeIndex();
283 if (isa<FunctionDecl>(D)
287 assert(I < Ctx->NumArgs);
293 VD = isa<FunctionDecl>(D)
294 ? cast<FunctionDecl>(D)->getCanonicalDecl()->getParamDecl(I)
307 assert(SelfVar &&
"We have no variable for 'this'!");
312 if (
const auto *
V = dyn_cast<til::Variable>(E))
313 return V->clangDecl();
314 if (
const auto *Ph = dyn_cast<til::Phi>(E))
315 return Ph->clangDecl();
316 if (
const auto *
P = dyn_cast<til::Project>(E))
317 return P->clangDecl();
318 if (
const auto *L = dyn_cast<til::LiteralPtr>(E))
319 return L->clangDecl();
325 if (VD && VD->getType()->isAnyPointerType())
327 if (
const auto *
C = dyn_cast<til::Cast>(E))
338 if (OverriddenMethods.begin() == OverriddenMethods.end())
341 D = *OverriddenMethods.begin();
352 if (
const auto *VD = dyn_cast<CXXMethodDecl>(D))
377 if (CapabilityExprMode) {
380 FD = FD->getMostRecentDecl();
381 if (LockReturnedAttr *At = FD->getAttr<LockReturnedAttr>()) {
394 for (
const auto *Arg : CE->
arguments()) {
401 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
403 if (CapabilityExprMode) {
412 return translateCallExpr(cast<CallExpr>(ME), Ctx,
416 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
418 if (CapabilityExprMode) {
421 if (k == OO_Star || k == OO_Arrow) {
427 return translateCallExpr(cast<CallExpr>(OCE), Ctx);
440 if (CapabilityExprMode) {
442 if (
const auto *DRE = dyn_cast<DeclRefExpr>(UO->
getSubExpr())) {
501 if (
const auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
503 CV = lookupVarDecl(VD);
509 E1 = addStatement(E1,
nullptr, VD);
512 return updateVarDecl(VD, E1);
523 case BO_Mul:
return translateBinOp(
til::BOP_Mul, BO, Ctx);
524 case BO_Div:
return translateBinOp(
til::BOP_Div, BO, Ctx);
525 case BO_Rem:
return translateBinOp(
til::BOP_Rem, BO, Ctx);
526 case BO_Add:
return translateBinOp(
til::BOP_Add, BO, Ctx);
527 case BO_Sub:
return translateBinOp(
til::BOP_Sub, BO, Ctx);
528 case BO_Shl:
return translateBinOp(
til::BOP_Shl, BO, Ctx);
529 case BO_Shr:
return translateBinOp(
til::BOP_Shr, BO, Ctx);
530 case BO_LT:
return translateBinOp(
til::BOP_Lt, BO, Ctx);
531 case BO_GT:
return translateBinOp(
til::BOP_Lt, BO, Ctx,
true);
532 case BO_LE:
return translateBinOp(
til::BOP_Leq, BO, Ctx);
533 case BO_GE:
return translateBinOp(
til::BOP_Leq, BO, Ctx,
true);
534 case BO_EQ:
return translateBinOp(
til::BOP_Eq, BO, Ctx);
535 case BO_NE:
return translateBinOp(
til::BOP_Neq, BO, Ctx);
536 case BO_Cmp:
return translateBinOp(
til::BOP_Cmp, BO, Ctx);
543 case BO_Assign:
return translateBinAssign(
til::BOP_Eq, BO, Ctx,
true);
544 case BO_MulAssign:
return translateBinAssign(
til::BOP_Mul, BO, Ctx);
545 case BO_DivAssign:
return translateBinAssign(
til::BOP_Div, BO, Ctx);
546 case BO_RemAssign:
return translateBinAssign(
til::BOP_Rem, BO, Ctx);
547 case BO_AddAssign:
return translateBinAssign(
til::BOP_Add, BO, Ctx);
548 case BO_SubAssign:
return translateBinAssign(
til::BOP_Sub, BO, Ctx);
549 case BO_ShlAssign:
return translateBinAssign(
til::BOP_Shl, BO, Ctx);
550 case BO_ShrAssign:
return translateBinAssign(
til::BOP_Shr, BO, Ctx);
551 case BO_AndAssign:
return translateBinAssign(
til::BOP_BitAnd, BO, Ctx);
552 case BO_XorAssign:
return translateBinAssign(
til::BOP_BitXor, BO, Ctx);
553 case BO_OrAssign:
return translateBinAssign(
til::BOP_BitOr, BO, Ctx);
566 case CK_LValueToRValue: {
567 if (
const auto *DRE = dyn_cast<DeclRefExpr>(CE->
getSubExpr())) {
578 case CK_DerivedToBase:
579 case CK_UncheckedDerivedToBase:
580 case CK_ArrayToPointerDecay:
581 case CK_FunctionToPointerDecay: {
588 if (CapabilityExprMode)
604 SExprBuilder::translateAbstractConditionalOperator(
615 for (
auto I : DGrp) {
616 if (
auto *VD = dyn_cast_or_null<VarDecl>(I)) {
617 Expr *E = VD->getInit();
623 return addVarDecl(VD, SE);
642 CurrentInstructions.push_back(E);
650 auto It = LVarIdxMap.find(VD);
651 if (It != LVarIdxMap.end()) {
652 assert(CurrentLVarMap[It->second].first == VD);
653 return CurrentLVarMap[It->second].second;
662 if (
auto *
V = dyn_cast<til::Variable>(E)) {
671 LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.
size()));
673 CurrentLVarMap.
push_back(std::make_pair(VD, E));
680 auto It = LVarIdxMap.find(VD);
681 if (It == LVarIdxMap.end()) {
687 CurrentLVarMap.
elem(It->second).second = E;
694 void SExprBuilder::makePhiNodeVar(
unsigned i,
unsigned NPreds,
til::SExpr *E) {
695 unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
696 assert(ArgIndex > 0 && ArgIndex < NPreds);
699 if (CurrE->
block() == CurrentBB) {
702 auto *Ph = dyn_cast<
til::Phi>(CurrE);
703 assert(Ph &&
"Expecting Phi node.");
705 Ph->values()[ArgIndex] = E;
713 for (
unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
714 Ph->
values()[PIdx] = CurrE;
716 Ph->
values()[ArgIndex] = E;
724 CurrentArguments.push_back(Ph);
726 IncompleteArgs.push_back(Ph);
729 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();
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());
768 void SExprBuilder::mergeEntryMapBackEdge() {
777 assert(CurrentBlockInfo &&
"Not processing a block!");
779 if (CurrentBlockInfo->HasBackEdges)
781 CurrentBlockInfo->HasBackEdges =
true;
784 unsigned Sz = CurrentLVarMap.
size();
787 for (
unsigned i = 0;
i < Sz; ++
i)
788 makePhiNodeVar(
i, NPreds,
nullptr);
794 void SExprBuilder::mergePhiNodesBackEdge(
const CFGBlock *Blk) {
796 unsigned ArgIndex = BBInfo[Blk->
getBlockID()].ProcessedPredecessors;
797 assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
800 auto *Ph = dyn_cast_or_null<til::Phi>(PE);
801 assert(Ph &&
"Expecting Phi Node.");
802 assert(Ph->values()[ArgIndex] ==
nullptr &&
"Wrong index for back edge.");
804 til::SExpr *E = lookupVarDecl(Ph->clangDecl());
805 assert(E &&
"Couldn't find local variable for Phi node.");
806 Ph->values()[ArgIndex] = E;
810 void SExprBuilder::enterCFG(
CFG *Cfg,
const NamedDecl *D,
814 Scfg =
new (Arena)
til::SCFG(Arena, NBlocks);
817 BBInfo.resize(NBlocks);
818 BlockMap.resize(NBlocks,
nullptr);
820 for (
auto *B : *Cfg) {
823 BlockMap[B->getBlockID()] = BB;
827 auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
828 : cast<FunctionDecl>(D)->parameters();
829 for (
auto *Pm : Parms) {
843 void SExprBuilder::enterCFGBlock(
const CFGBlock *B) {
847 Scfg->
add(CurrentBB);
856 void SExprBuilder::handlePredecessor(
const CFGBlock *Pred) {
860 BlockInfo *PredInfo = &BBInfo[Pred->
getBlockID()];
861 assert(PredInfo->UnprocessedSuccessors > 0);
863 if (--PredInfo->UnprocessedSuccessors == 0)
864 mergeEntryMap(std::move(PredInfo->ExitMap));
866 mergeEntryMap(PredInfo->ExitMap.clone());
868 ++CurrentBlockInfo->ProcessedPredecessors;
871 void SExprBuilder::handlePredecessorBackEdge(
const CFGBlock *Pred) {
872 mergeEntryMapBackEdge();
875 void SExprBuilder::enterCFGBlockBody(
const CFGBlock *B) {
879 static_cast<unsigned>(CurrentArguments.size()), Arena);
880 for (
auto *A : CurrentArguments)
884 void SExprBuilder::handleStatement(
const Stmt *S) {
889 void SExprBuilder::handleDestructorCall(
const VarDecl *VD,
895 addStatement(E,
nullptr);
898 void SExprBuilder::exitCFGBlockBody(
const CFGBlock *B) {
900 static_cast<unsigned>(CurrentInstructions.size()), Arena);
901 for (
auto *
V : CurrentInstructions)
911 auto *Tm =
new (Arena)
til::Goto(BB, Idx);
925 void SExprBuilder::handleSuccessor(
const CFGBlock *Succ) {
926 ++CurrentBlockInfo->UnprocessedSuccessors;
929 void SExprBuilder::handleSuccessorBackEdge(
const CFGBlock *Succ) {
930 mergePhiNodesBackEdge(Succ);
931 ++BBInfo[Succ->
getBlockID()].ProcessedPredecessors;
934 void SExprBuilder::exitCFGBlock(
const CFGBlock *B) {
935 CurrentArguments.clear();
936 CurrentInstructions.clear();
937 CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
939 CurrentBlockInfo =
nullptr;
943 for (
auto *Ph : IncompleteArgs) {
948 CurrentArguments.clear();
949 CurrentInstructions.clear();
950 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.