Home | History | Annotate | Download | only in Analysis
      1 //===- ThreadSafetyCommon.cpp ----------------------------------*- C++ --*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Implementation of the interfaces declared in ThreadSafetyCommon.h
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/Analysis/Analyses/ThreadSafetyCommon.h"
     15 #include "clang/AST/Attr.h"
     16 #include "clang/AST/DeclCXX.h"
     17 #include "clang/AST/DeclObjC.h"
     18 #include "clang/AST/ExprCXX.h"
     19 #include "clang/AST/StmtCXX.h"
     20 #include "clang/Analysis/Analyses/PostOrderCFGView.h"
     21 #include "clang/Analysis/Analyses/ThreadSafetyTIL.h"
     22 #include "clang/Analysis/Analyses/ThreadSafetyTraverse.h"
     23 #include "clang/Analysis/AnalysisContext.h"
     24 #include "clang/Analysis/CFG.h"
     25 #include "clang/Basic/OperatorKinds.h"
     26 #include "clang/Basic/SourceLocation.h"
     27 #include "clang/Basic/SourceManager.h"
     28 #include "llvm/ADT/DenseMap.h"
     29 #include "llvm/ADT/SmallVector.h"
     30 #include "llvm/ADT/StringRef.h"
     31 #include <algorithm>
     32 #include <climits>
     33 #include <vector>
     34 using namespace clang;
     35 using namespace threadSafety;
     36 
     37 // From ThreadSafetyUtil.h
     38 std::string threadSafety::getSourceLiteralString(const clang::Expr *CE) {
     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();
     45       ret += "\"";
     46       return ret;
     47     }
     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:
     55     default:
     56       return "#lit";
     57   }
     58 }
     59 
     60 // Return true if E is a variable that points to an incomplete Phi node.
     61 static bool isIncompletePhi(const til::SExpr *E) {
     62   if (const auto *Ph = dyn_cast<til::Phi>(E))
     63     return Ph->status() == til::Phi::PH_Incomplete;
     64   return false;
     65 }
     66 
     67 typedef SExprBuilder::CallingContext CallingContext;
     68 
     69 
     70 til::SExpr *SExprBuilder::lookupStmt(const Stmt *S) {
     71   auto It = SMap.find(S);
     72   if (It != SMap.end())
     73     return It->second;
     74   return nullptr;
     75 }
     76 
     77 
     78 til::SCFG *SExprBuilder::buildCFG(CFGWalker &Walker) {
     79   Walker.walk(*this);
     80   return Scfg;
     81 }
     82 
     83 static bool isCalleeArrow(const Expr *E) {
     84   const MemberExpr *ME = dyn_cast<MemberExpr>(E->IgnoreParenCasts());
     85   return ME ? ME->isArrow() : false;
     86 }
     87 
     88 
     89 /// \brief Translate a clang expression in an attribute to a til::SExpr.
     90 /// Constructs the context from D, DeclExp, and SelfDecl.
     91 ///
     92 /// \param AttrExp The expression to translate.
     93 /// \param D       The declaration to which the attribute is attached.
     94 /// \param DeclExp An expression involving the Decl to which the attribute
     95 ///                is attached.  E.g. the call to a function.
     96 CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
     97                                                const NamedDecl *D,
     98                                                const Expr *DeclExp,
     99                                                VarDecl *SelfDecl) {
    100   // If we are processing a raw attribute expression, with no substitutions.
    101   if (!DeclExp)
    102     return translateAttrExpr(AttrExp, nullptr);
    103 
    104   CallingContext Ctx(nullptr, D);
    105 
    106   // Examine DeclExp to find SelfArg and FunArgs, which are used to substitute
    107   // for formal parameters when we call buildMutexID later.
    108   if (const MemberExpr *ME = dyn_cast<MemberExpr>(DeclExp)) {
    109     Ctx.SelfArg   = ME->getBase();
    110     Ctx.SelfArrow = ME->isArrow();
    111   } else if (const CXXMemberCallExpr *CE =
    112              dyn_cast<CXXMemberCallExpr>(DeclExp)) {
    113     Ctx.SelfArg   = CE->getImplicitObjectArgument();
    114     Ctx.SelfArrow = isCalleeArrow(CE->getCallee());
    115     Ctx.NumArgs   = CE->getNumArgs();
    116     Ctx.FunArgs   = CE->getArgs();
    117   } else if (const CallExpr *CE = dyn_cast<CallExpr>(DeclExp)) {
    118     Ctx.NumArgs = CE->getNumArgs();
    119     Ctx.FunArgs = CE->getArgs();
    120   } else if (const CXXConstructExpr *CE =
    121              dyn_cast<CXXConstructExpr>(DeclExp)) {
    122     Ctx.SelfArg = nullptr;  // Will be set below
    123     Ctx.NumArgs = CE->getNumArgs();
    124     Ctx.FunArgs = CE->getArgs();
    125   } else if (D && isa<CXXDestructorDecl>(D)) {
    126     // There's no such thing as a "destructor call" in the AST.
    127     Ctx.SelfArg = DeclExp;
    128   }
    129 
    130   // Hack to handle constructors, where self cannot be recovered from
    131   // the expression.
    132   if (SelfDecl && !Ctx.SelfArg) {
    133     DeclRefExpr SelfDRE(SelfDecl, false, SelfDecl->getType(), VK_LValue,
    134                         SelfDecl->getLocation());
    135     Ctx.SelfArg = &SelfDRE;
    136 
    137     // If the attribute has no arguments, then assume the argument is "this".
    138     if (!AttrExp)
    139       return translateAttrExpr(Ctx.SelfArg, nullptr);
    140     else  // For most attributes.
    141       return translateAttrExpr(AttrExp, &Ctx);
    142   }
    143 
    144   // If the attribute has no arguments, then assume the argument is "this".
    145   if (!AttrExp)
    146     return translateAttrExpr(Ctx.SelfArg, nullptr);
    147   else  // For most attributes.
    148     return translateAttrExpr(AttrExp, &Ctx);
    149 }
    150 
    151 
    152 /// \brief Translate a clang expression in an attribute to a til::SExpr.
    153 // This assumes a CallingContext has already been created.
    154 CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp,
    155                                                CallingContext *Ctx) {
    156   if (!AttrExp)
    157     return CapabilityExpr(nullptr, false);
    158 
    159   if (auto* SLit = dyn_cast<StringLiteral>(AttrExp)) {
    160     if (SLit->getString() == StringRef("*"))
    161       // The "*" expr is a universal lock, which essentially turns off
    162       // checks until it is removed from the lockset.
    163       return CapabilityExpr(new (Arena) til::Wildcard(), false);
    164     else
    165       // Ignore other string literals for now.
    166       return CapabilityExpr(nullptr, false);
    167   }
    168 
    169   bool Neg = false;
    170   if (auto *OE = dyn_cast<CXXOperatorCallExpr>(AttrExp)) {
    171     if (OE->getOperator() == OO_Exclaim) {
    172       Neg = true;
    173       AttrExp = OE->getArg(0);
    174     }
    175   }
    176   else if (auto *UO = dyn_cast<UnaryOperator>(AttrExp)) {
    177     if (UO->getOpcode() == UO_LNot) {
    178       Neg = true;
    179       AttrExp = UO->getSubExpr();
    180     }
    181   }
    182 
    183   til::SExpr *E = translate(AttrExp, Ctx);
    184 
    185   // Trap mutex expressions like nullptr, or 0.
    186   // Any literal value is nonsense.
    187   if (!E || isa<til::Literal>(E))
    188     return CapabilityExpr(nullptr, false);
    189 
    190   // Hack to deal with smart pointers -- strip off top-level pointer casts.
    191   if (auto *CE = dyn_cast_or_null<til::Cast>(E)) {
    192     if (CE->castOpcode() == til::CAST_objToPtr)
    193       return CapabilityExpr(CE->expr(), Neg);
    194   }
    195   return CapabilityExpr(E, Neg);
    196 }
    197 
    198 
    199 
    200 // Translate a clang statement or expression to a TIL expression.
    201 // Also performs substitution of variables; Ctx provides the context.
    202 // Dispatches on the type of S.
    203 til::SExpr *SExprBuilder::translate(const Stmt *S, CallingContext *Ctx) {
    204   if (!S)
    205     return nullptr;
    206 
    207   // Check if S has already been translated and cached.
    208   // This handles the lookup of SSA names for DeclRefExprs here.
    209   if (til::SExpr *E = lookupStmt(S))
    210     return E;
    211 
    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);
    230 
    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);
    239 
    240   // We treat these as no-ops
    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 
    248   // Collect all literals
    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:
    258     return new (Arena) til::Literal(cast<Expr>(S));
    259 
    260   case Stmt::DeclStmtClass:
    261     return translateDeclStmt(cast<DeclStmt>(S), Ctx);
    262   default:
    263     break;
    264   }
    265   if (const CastExpr *CE = dyn_cast<CastExpr>(S))
    266     return translateCastExpr(CE, Ctx);
    267 
    268   return new (Arena) til::Undefined(S);
    269 }
    270 
    271 
    272 
    273 til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE,
    274                                                CallingContext *Ctx) {
    275   const ValueDecl *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
    276 
    277   // Function parameters require substitution and/or renaming.
    278   if (const ParmVarDecl *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
    279     const FunctionDecl *FD =
    280         cast<FunctionDecl>(PV->getDeclContext())->getCanonicalDecl();
    281     unsigned I = PV->getFunctionScopeIndex();
    282 
    283     if (Ctx && Ctx->FunArgs && FD == Ctx->AttrDecl->getCanonicalDecl()) {
    284       // Substitute call arguments for references to function parameters
    285       assert(I < Ctx->NumArgs);
    286       return translate(Ctx->FunArgs[I], Ctx->Prev);
    287     }
    288     // Map the param back to the param of the original function declaration
    289     // for consistent comparisons.
    290     VD = FD->getParamDecl(I);
    291   }
    292 
    293   // For non-local variables, treat it as a referenced to a named object.
    294   return new (Arena) til::LiteralPtr(VD);
    295 }
    296 
    297 
    298 til::SExpr *SExprBuilder::translateCXXThisExpr(const CXXThisExpr *TE,
    299                                                CallingContext *Ctx) {
    300   // Substitute for 'this'
    301   if (Ctx && Ctx->SelfArg)
    302     return translate(Ctx->SelfArg, Ctx->Prev);
    303   assert(SelfVar && "We have no variable for 'this'!");
    304   return SelfVar;
    305 }
    306 
    307 static const ValueDecl *getValueDeclFromSExpr(const til::SExpr *E) {
    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();
    316   return 0;
    317 }
    318 
    319 static bool hasCppPointerType(const til::SExpr *E) {
    320   auto *VD = getValueDeclFromSExpr(E);
    321   if (VD && VD->getType()->isPointerType())
    322     return true;
    323   if (auto *C = dyn_cast<til::Cast>(E))
    324     return C->castOpcode() == til::CAST_objToPtr;
    325 
    326   return false;
    327 }
    328 
    329 // Grab the very first declaration of virtual method D
    330 static const CXXMethodDecl *getFirstVirtualDecl(const CXXMethodDecl *D) {
    331   while (true) {
    332     D = D->getCanonicalDecl();
    333     CXXMethodDecl::method_iterator I = D->begin_overridden_methods(),
    334                                    E = D->end_overridden_methods();
    335     if (I == E)
    336       return D;  // Method does not override anything
    337     D = *I;      // FIXME: this does not work with multiple inheritance.
    338   }
    339   return nullptr;
    340 }
    341 
    342 til::SExpr *SExprBuilder::translateMemberExpr(const MemberExpr *ME,
    343                                               CallingContext *Ctx) {
    344   til::SExpr *BE = translate(ME->getBase(), Ctx);
    345   til::SExpr *E  = new (Arena) til::SApply(BE);
    346 
    347   const ValueDecl *D = ME->getMemberDecl();
    348   if (auto *VD = dyn_cast<CXXMethodDecl>(D))
    349     D = getFirstVirtualDecl(VD);
    350 
    351   til::Project *P = new (Arena) til::Project(E, D);
    352   if (hasCppPointerType(BE))
    353     P->setArrow(true);
    354   return P;
    355 }
    356 
    357 
    358 til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
    359                                             CallingContext *Ctx,
    360                                             const Expr *SelfE) {
    361   if (CapabilityExprMode) {
    362     // Handle LOCK_RETURNED
    363     const FunctionDecl *FD = CE->getDirectCallee()->getMostRecentDecl();
    364     if (LockReturnedAttr* At = FD->getAttr<LockReturnedAttr>()) {
    365       CallingContext LRCallCtx(Ctx);
    366       LRCallCtx.AttrDecl = CE->getDirectCallee();
    367       LRCallCtx.SelfArg  = SelfE;
    368       LRCallCtx.NumArgs  = CE->getNumArgs();
    369       LRCallCtx.FunArgs  = CE->getArgs();
    370       return const_cast<til::SExpr*>(
    371           translateAttrExpr(At->getArg(), &LRCallCtx).sexpr());
    372     }
    373   }
    374 
    375   til::SExpr *E = translate(CE->getCallee(), Ctx);
    376   for (const auto *Arg : CE->arguments()) {
    377     til::SExpr *A = translate(Arg, Ctx);
    378     E = new (Arena) til::Apply(E, A);
    379   }
    380   return new (Arena) til::Call(E, CE);
    381 }
    382 
    383 
    384 til::SExpr *SExprBuilder::translateCXXMemberCallExpr(
    385     const CXXMemberCallExpr *ME, CallingContext *Ctx) {
    386   if (CapabilityExprMode) {
    387     // Ignore calls to get() on smart pointers.
    388     if (ME->getMethodDecl()->getNameAsString() == "get" &&
    389         ME->getNumArgs() == 0) {
    390       auto *E = translate(ME->getImplicitObjectArgument(), Ctx);
    391       return new (Arena) til::Cast(til::CAST_objToPtr, E);
    392       // return E;
    393     }
    394   }
    395   return translateCallExpr(cast<CallExpr>(ME), Ctx,
    396                            ME->getImplicitObjectArgument());
    397 }
    398 
    399 
    400 til::SExpr *SExprBuilder::translateCXXOperatorCallExpr(
    401     const CXXOperatorCallExpr *OCE, CallingContext *Ctx) {
    402   if (CapabilityExprMode) {
    403     // Ignore operator * and operator -> on smart pointers.
    404     OverloadedOperatorKind k = OCE->getOperator();
    405     if (k == OO_Star || k == OO_Arrow) {
    406       auto *E = translate(OCE->getArg(0), Ctx);
    407       return new (Arena) til::Cast(til::CAST_objToPtr, E);
    408       // return E;
    409     }
    410   }
    411   return translateCallExpr(cast<CallExpr>(OCE), Ctx);
    412 }
    413 
    414 
    415 til::SExpr *SExprBuilder::translateUnaryOperator(const UnaryOperator *UO,
    416                                                  CallingContext *Ctx) {
    417   switch (UO->getOpcode()) {
    418   case UO_PostInc:
    419   case UO_PostDec:
    420   case UO_PreInc:
    421   case UO_PreDec:
    422     return new (Arena) til::Undefined(UO);
    423 
    424   case UO_AddrOf: {
    425     if (CapabilityExprMode) {
    426       // interpret &Graph::mu_ as an existential.
    427       if (DeclRefExpr* DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr())) {
    428         if (DRE->getDecl()->isCXXInstanceMember()) {
    429           // This is a pointer-to-member expression, e.g. &MyClass::mu_.
    430           // We interpret this syntax specially, as a wildcard.
    431           auto *W = new (Arena) til::Wildcard();
    432           return new (Arena) til::Project(W, DRE->getDecl());
    433         }
    434       }
    435     }
    436     // otherwise, & is a no-op
    437     return translate(UO->getSubExpr(), Ctx);
    438   }
    439 
    440   // We treat these as no-ops
    441   case UO_Deref:
    442   case UO_Plus:
    443     return translate(UO->getSubExpr(), Ctx);
    444 
    445   case UO_Minus:
    446     return new (Arena)
    447       til::UnaryOp(til::UOP_Minus, translate(UO->getSubExpr(), Ctx));
    448   case UO_Not:
    449     return new (Arena)
    450       til::UnaryOp(til::UOP_BitNot, translate(UO->getSubExpr(), Ctx));
    451   case UO_LNot:
    452     return new (Arena)
    453       til::UnaryOp(til::UOP_LogicNot, translate(UO->getSubExpr(), Ctx));
    454 
    455   // Currently unsupported
    456   case UO_Real:
    457   case UO_Imag:
    458   case UO_Extension:
    459     return new (Arena) til::Undefined(UO);
    460   }
    461   return new (Arena) til::Undefined(UO);
    462 }
    463 
    464 
    465 til::SExpr *SExprBuilder::translateBinOp(til::TIL_BinaryOpcode Op,
    466                                          const BinaryOperator *BO,
    467                                          CallingContext *Ctx, bool Reverse) {
    468    til::SExpr *E0 = translate(BO->getLHS(), Ctx);
    469    til::SExpr *E1 = translate(BO->getRHS(), Ctx);
    470    if (Reverse)
    471      return new (Arena) til::BinaryOp(Op, E1, E0);
    472    else
    473      return new (Arena) til::BinaryOp(Op, E0, E1);
    474 }
    475 
    476 
    477 til::SExpr *SExprBuilder::translateBinAssign(til::TIL_BinaryOpcode Op,
    478                                              const BinaryOperator *BO,
    479                                              CallingContext *Ctx,
    480                                              bool Assign) {
    481   const Expr *LHS = BO->getLHS();
    482   const Expr *RHS = BO->getRHS();
    483   til::SExpr *E0 = translate(LHS, Ctx);
    484   til::SExpr *E1 = translate(RHS, Ctx);
    485 
    486   const ValueDecl *VD = nullptr;
    487   til::SExpr *CV = nullptr;
    488   if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(LHS)) {
    489     VD = DRE->getDecl();
    490     CV = lookupVarDecl(VD);
    491   }
    492 
    493   if (!Assign) {
    494     til::SExpr *Arg = CV ? CV : new (Arena) til::Load(E0);
    495     E1 = new (Arena) til::BinaryOp(Op, Arg, E1);
    496     E1 = addStatement(E1, nullptr, VD);
    497   }
    498   if (VD && CV)
    499     return updateVarDecl(VD, E1);
    500   return new (Arena) til::Store(E0, E1);
    501 }
    502 
    503 
    504 til::SExpr *SExprBuilder::translateBinaryOperator(const BinaryOperator *BO,
    505                                                   CallingContext *Ctx) {
    506   switch (BO->getOpcode()) {
    507   case BO_PtrMemD:
    508   case BO_PtrMemI:
    509     return new (Arena) til::Undefined(BO);
    510 
    511   case BO_Mul:  return translateBinOp(til::BOP_Mul, BO, Ctx);
    512   case BO_Div:  return translateBinOp(til::BOP_Div, BO, Ctx);
    513   case BO_Rem:  return translateBinOp(til::BOP_Rem, BO, Ctx);
    514   case BO_Add:  return translateBinOp(til::BOP_Add, BO, Ctx);
    515   case BO_Sub:  return translateBinOp(til::BOP_Sub, BO, Ctx);
    516   case BO_Shl:  return translateBinOp(til::BOP_Shl, BO, Ctx);
    517   case BO_Shr:  return translateBinOp(til::BOP_Shr, BO, Ctx);
    518   case BO_LT:   return translateBinOp(til::BOP_Lt,  BO, Ctx);
    519   case BO_GT:   return translateBinOp(til::BOP_Lt,  BO, Ctx, true);
    520   case BO_LE:   return translateBinOp(til::BOP_Leq, BO, Ctx);
    521   case BO_GE:   return translateBinOp(til::BOP_Leq, BO, Ctx, true);
    522   case BO_EQ:   return translateBinOp(til::BOP_Eq,  BO, Ctx);
    523   case BO_NE:   return translateBinOp(til::BOP_Neq, BO, Ctx);
    524   case BO_And:  return translateBinOp(til::BOP_BitAnd,   BO, Ctx);
    525   case BO_Xor:  return translateBinOp(til::BOP_BitXor,   BO, Ctx);
    526   case BO_Or:   return translateBinOp(til::BOP_BitOr,    BO, Ctx);
    527   case BO_LAnd: return translateBinOp(til::BOP_LogicAnd, BO, Ctx);
    528   case BO_LOr:  return translateBinOp(til::BOP_LogicOr,  BO, Ctx);
    529 
    530   case BO_Assign:    return translateBinAssign(til::BOP_Eq,  BO, Ctx, true);
    531   case BO_MulAssign: return translateBinAssign(til::BOP_Mul, BO, Ctx);
    532   case BO_DivAssign: return translateBinAssign(til::BOP_Div, BO, Ctx);
    533   case BO_RemAssign: return translateBinAssign(til::BOP_Rem, BO, Ctx);
    534   case BO_AddAssign: return translateBinAssign(til::BOP_Add, BO, Ctx);
    535   case BO_SubAssign: return translateBinAssign(til::BOP_Sub, BO, Ctx);
    536   case BO_ShlAssign: return translateBinAssign(til::BOP_Shl, BO, Ctx);
    537   case BO_ShrAssign: return translateBinAssign(til::BOP_Shr, BO, Ctx);
    538   case BO_AndAssign: return translateBinAssign(til::BOP_BitAnd, BO, Ctx);
    539   case BO_XorAssign: return translateBinAssign(til::BOP_BitXor, BO, Ctx);
    540   case BO_OrAssign:  return translateBinAssign(til::BOP_BitOr,  BO, Ctx);
    541 
    542   case BO_Comma:
    543     // The clang CFG should have already processed both sides.
    544     return translate(BO->getRHS(), Ctx);
    545   }
    546   return new (Arena) til::Undefined(BO);
    547 }
    548 
    549 
    550 til::SExpr *SExprBuilder::translateCastExpr(const CastExpr *CE,
    551                                             CallingContext *Ctx) {
    552   clang::CastKind K = CE->getCastKind();
    553   switch (K) {
    554   case CK_LValueToRValue: {
    555     if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
    556       til::SExpr *E0 = lookupVarDecl(DRE->getDecl());
    557       if (E0)
    558         return E0;
    559     }
    560     til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
    561     return E0;
    562     // FIXME!! -- get Load working properly
    563     // return new (Arena) til::Load(E0);
    564   }
    565   case CK_NoOp:
    566   case CK_DerivedToBase:
    567   case CK_UncheckedDerivedToBase:
    568   case CK_ArrayToPointerDecay:
    569   case CK_FunctionToPointerDecay: {
    570     til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
    571     return E0;
    572   }
    573   default: {
    574     // FIXME: handle different kinds of casts.
    575     til::SExpr *E0 = translate(CE->getSubExpr(), Ctx);
    576     if (CapabilityExprMode)
    577       return E0;
    578     return new (Arena) til::Cast(til::CAST_none, E0);
    579   }
    580   }
    581 }
    582 
    583 
    584 til::SExpr *
    585 SExprBuilder::translateArraySubscriptExpr(const ArraySubscriptExpr *E,
    586                                           CallingContext *Ctx) {
    587   til::SExpr *E0 = translate(E->getBase(), Ctx);
    588   til::SExpr *E1 = translate(E->getIdx(), Ctx);
    589   return new (Arena) til::ArrayIndex(E0, E1);
    590 }
    591 
    592 
    593 til::SExpr *
    594 SExprBuilder::translateAbstractConditionalOperator(
    595     const AbstractConditionalOperator *CO, CallingContext *Ctx) {
    596   auto *C = translate(CO->getCond(), Ctx);
    597   auto *T = translate(CO->getTrueExpr(), Ctx);
    598   auto *E = translate(CO->getFalseExpr(), Ctx);
    599   return new (Arena) til::IfThenElse(C, T, E);
    600 }
    601 
    602 
    603 til::SExpr *
    604 SExprBuilder::translateDeclStmt(const DeclStmt *S, CallingContext *Ctx) {
    605   DeclGroupRef DGrp = S->getDeclGroup();
    606   for (DeclGroupRef::iterator I = DGrp.begin(), E = DGrp.end(); I != E; ++I) {
    607     if (VarDecl *VD = dyn_cast_or_null<VarDecl>(*I)) {
    608       Expr *E = VD->getInit();
    609       til::SExpr* SE = translate(E, Ctx);
    610 
    611       // Add local variables with trivial type to the variable map
    612       QualType T = VD->getType();
    613       if (T.isTrivialType(VD->getASTContext())) {
    614         return addVarDecl(VD, SE);
    615       }
    616       else {
    617         // TODO: add alloca
    618       }
    619     }
    620   }
    621   return nullptr;
    622 }
    623 
    624 
    625 
    626 // If (E) is non-trivial, then add it to the current basic block, and
    627 // update the statement map so that S refers to E.  Returns a new variable
    628 // that refers to E.
    629 // If E is trivial returns E.
    630 til::SExpr *SExprBuilder::addStatement(til::SExpr* E, const Stmt *S,
    631                                        const ValueDecl *VD) {
    632   if (!E || !CurrentBB || E->block() || til::ThreadSafetyTIL::isTrivial(E))
    633     return E;
    634   if (VD)
    635     E = new (Arena) til::Variable(E, VD);
    636   CurrentInstructions.push_back(E);
    637   if (S)
    638     insertStmt(S, E);
    639   return E;
    640 }
    641 
    642 
    643 // Returns the current value of VD, if known, and nullptr otherwise.
    644 til::SExpr *SExprBuilder::lookupVarDecl(const ValueDecl *VD) {
    645   auto It = LVarIdxMap.find(VD);
    646   if (It != LVarIdxMap.end()) {
    647     assert(CurrentLVarMap[It->second].first == VD);
    648     return CurrentLVarMap[It->second].second;
    649   }
    650   return nullptr;
    651 }
    652 
    653 
    654 // if E is a til::Variable, update its clangDecl.
    655 static void maybeUpdateVD(til::SExpr *E, const ValueDecl *VD) {
    656   if (!E)
    657     return;
    658   if (til::Variable *V = dyn_cast<til::Variable>(E)) {
    659     if (!V->clangDecl())
    660       V->setClangDecl(VD);
    661   }
    662 }
    663 
    664 // Adds a new variable declaration.
    665 til::SExpr *SExprBuilder::addVarDecl(const ValueDecl *VD, til::SExpr *E) {
    666   maybeUpdateVD(E, VD);
    667   LVarIdxMap.insert(std::make_pair(VD, CurrentLVarMap.size()));
    668   CurrentLVarMap.makeWritable();
    669   CurrentLVarMap.push_back(std::make_pair(VD, E));
    670   return E;
    671 }
    672 
    673 
    674 // Updates a current variable declaration.  (E.g. by assignment)
    675 til::SExpr *SExprBuilder::updateVarDecl(const ValueDecl *VD, til::SExpr *E) {
    676   maybeUpdateVD(E, VD);
    677   auto It = LVarIdxMap.find(VD);
    678   if (It == LVarIdxMap.end()) {
    679     til::SExpr *Ptr = new (Arena) til::LiteralPtr(VD);
    680     til::SExpr *St  = new (Arena) til::Store(Ptr, E);
    681     return St;
    682   }
    683   CurrentLVarMap.makeWritable();
    684   CurrentLVarMap.elem(It->second).second = E;
    685   return E;
    686 }
    687 
    688 
    689 // Make a Phi node in the current block for the i^th variable in CurrentVarMap.
    690 // If E != null, sets Phi[CurrentBlockInfo->ArgIndex] = E.
    691 // If E == null, this is a backedge and will be set later.
    692 void SExprBuilder::makePhiNodeVar(unsigned i, unsigned NPreds, til::SExpr *E) {
    693   unsigned ArgIndex = CurrentBlockInfo->ProcessedPredecessors;
    694   assert(ArgIndex > 0 && ArgIndex < NPreds);
    695 
    696   til::SExpr *CurrE = CurrentLVarMap[i].second;
    697   if (CurrE->block() == CurrentBB) {
    698     // We already have a Phi node in the current block,
    699     // so just add the new variable to the Phi node.
    700     til::Phi *Ph = dyn_cast<til::Phi>(CurrE);
    701     assert(Ph && "Expecting Phi node.");
    702     if (E)
    703       Ph->values()[ArgIndex] = E;
    704     return;
    705   }
    706 
    707   // Make a new phi node: phi(..., E)
    708   // All phi args up to the current index are set to the current value.
    709   til::Phi *Ph = new (Arena) til::Phi(Arena, NPreds);
    710   Ph->values().setValues(NPreds, nullptr);
    711   for (unsigned PIdx = 0; PIdx < ArgIndex; ++PIdx)
    712     Ph->values()[PIdx] = CurrE;
    713   if (E)
    714     Ph->values()[ArgIndex] = E;
    715   Ph->setClangDecl(CurrentLVarMap[i].first);
    716   // If E is from a back-edge, or either E or CurrE are incomplete, then
    717   // mark this node as incomplete; we may need to remove it later.
    718   if (!E || isIncompletePhi(E) || isIncompletePhi(CurrE)) {
    719     Ph->setStatus(til::Phi::PH_Incomplete);
    720   }
    721 
    722   // Add Phi node to current block, and update CurrentLVarMap[i]
    723   CurrentArguments.push_back(Ph);
    724   if (Ph->status() == til::Phi::PH_Incomplete)
    725     IncompleteArgs.push_back(Ph);
    726 
    727   CurrentLVarMap.makeWritable();
    728   CurrentLVarMap.elem(i).second = Ph;
    729 }
    730 
    731 
    732 // Merge values from Map into the current variable map.
    733 // This will construct Phi nodes in the current basic block as necessary.
    734 void SExprBuilder::mergeEntryMap(LVarDefinitionMap Map) {
    735   assert(CurrentBlockInfo && "Not processing a block!");
    736 
    737   if (!CurrentLVarMap.valid()) {
    738     // Steal Map, using copy-on-write.
    739     CurrentLVarMap = std::move(Map);
    740     return;
    741   }
    742   if (CurrentLVarMap.sameAs(Map))
    743     return;  // Easy merge: maps from different predecessors are unchanged.
    744 
    745   unsigned NPreds = CurrentBB->numPredecessors();
    746   unsigned ESz = CurrentLVarMap.size();
    747   unsigned MSz = Map.size();
    748   unsigned Sz  = std::min(ESz, MSz);
    749 
    750   for (unsigned i=0; i<Sz; ++i) {
    751     if (CurrentLVarMap[i].first != Map[i].first) {
    752       // We've reached the end of variables in common.
    753       CurrentLVarMap.makeWritable();
    754       CurrentLVarMap.downsize(i);
    755       break;
    756     }
    757     if (CurrentLVarMap[i].second != Map[i].second)
    758       makePhiNodeVar(i, NPreds, Map[i].second);
    759   }
    760   if (ESz > MSz) {
    761     CurrentLVarMap.makeWritable();
    762     CurrentLVarMap.downsize(Map.size());
    763   }
    764 }
    765 
    766 
    767 // Merge a back edge into the current variable map.
    768 // This will create phi nodes for all variables in the variable map.
    769 void SExprBuilder::mergeEntryMapBackEdge() {
    770   // We don't have definitions for variables on the backedge, because we
    771   // haven't gotten that far in the CFG.  Thus, when encountering a back edge,
    772   // we conservatively create Phi nodes for all variables.  Unnecessary Phi
    773   // nodes will be marked as incomplete, and stripped out at the end.
    774   //
    775   // An Phi node is unnecessary if it only refers to itself and one other
    776   // variable, e.g. x = Phi(y, y, x)  can be reduced to x = y.
    777 
    778   assert(CurrentBlockInfo && "Not processing a block!");
    779 
    780   if (CurrentBlockInfo->HasBackEdges)
    781     return;
    782   CurrentBlockInfo->HasBackEdges = true;
    783 
    784   CurrentLVarMap.makeWritable();
    785   unsigned Sz = CurrentLVarMap.size();
    786   unsigned NPreds = CurrentBB->numPredecessors();
    787 
    788   for (unsigned i=0; i < Sz; ++i) {
    789     makePhiNodeVar(i, NPreds, nullptr);
    790   }
    791 }
    792 
    793 
    794 // Update the phi nodes that were initially created for a back edge
    795 // once the variable definitions have been computed.
    796 // I.e., merge the current variable map into the phi nodes for Blk.
    797 void SExprBuilder::mergePhiNodesBackEdge(const CFGBlock *Blk) {
    798   til::BasicBlock *BB = lookupBlock(Blk);
    799   unsigned ArgIndex = BBInfo[Blk->getBlockID()].ProcessedPredecessors;
    800   assert(ArgIndex > 0 && ArgIndex < BB->numPredecessors());
    801 
    802   for (til::SExpr *PE : BB->arguments()) {
    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.");
    806 
    807     til::SExpr *E = lookupVarDecl(Ph->clangDecl());
    808     assert(E && "Couldn't find local variable for Phi node.");
    809     Ph->values()[ArgIndex] = E;
    810   }
    811 }
    812 
    813 void SExprBuilder::enterCFG(CFG *Cfg, const NamedDecl *D,
    814                             const CFGBlock *First) {
    815   // Perform initial setup operations.
    816   unsigned NBlocks = Cfg->getNumBlockIDs();
    817   Scfg = new (Arena) til::SCFG(Arena, NBlocks);
    818 
    819   // allocate all basic blocks immediately, to handle forward references.
    820   BBInfo.resize(NBlocks);
    821   BlockMap.resize(NBlocks, nullptr);
    822   // create map from clang blockID to til::BasicBlocks
    823   for (auto *B : *Cfg) {
    824     auto *BB = new (Arena) til::BasicBlock(Arena);
    825     BB->reserveInstructions(B->size());
    826     BlockMap[B->getBlockID()] = BB;
    827   }
    828 
    829   CurrentBB = lookupBlock(&Cfg->getEntry());
    830   auto Parms = isa<ObjCMethodDecl>(D) ? cast<ObjCMethodDecl>(D)->parameters()
    831                                       : cast<FunctionDecl>(D)->parameters();
    832   for (auto *Pm : Parms) {
    833     QualType T = Pm->getType();
    834     if (!T.isTrivialType(Pm->getASTContext()))
    835       continue;
    836 
    837     // Add parameters to local variable map.
    838     // FIXME: right now we emulate params with loads; that should be fixed.
    839     til::SExpr *Lp = new (Arena) til::LiteralPtr(Pm);
    840     til::SExpr *Ld = new (Arena) til::Load(Lp);
    841     til::SExpr *V  = addStatement(Ld, nullptr, Pm);
    842     addVarDecl(Pm, V);
    843   }
    844 }
    845 
    846 
    847 void SExprBuilder::enterCFGBlock(const CFGBlock *B) {
    848   // Intialize TIL basic block and add it to the CFG.
    849   CurrentBB = lookupBlock(B);
    850   CurrentBB->reservePredecessors(B->pred_size());
    851   Scfg->add(CurrentBB);
    852 
    853   CurrentBlockInfo = &BBInfo[B->getBlockID()];
    854 
    855   // CurrentLVarMap is moved to ExitMap on block exit.
    856   // FIXME: the entry block will hold function parameters.
    857   // assert(!CurrentLVarMap.valid() && "CurrentLVarMap already initialized.");
    858 }
    859 
    860 
    861 void SExprBuilder::handlePredecessor(const CFGBlock *Pred) {
    862   // Compute CurrentLVarMap on entry from ExitMaps of predecessors
    863 
    864   CurrentBB->addPredecessor(BlockMap[Pred->getBlockID()]);
    865   BlockInfo *PredInfo = &BBInfo[Pred->getBlockID()];
    866   assert(PredInfo->UnprocessedSuccessors > 0);
    867 
    868   if (--PredInfo->UnprocessedSuccessors == 0)
    869     mergeEntryMap(std::move(PredInfo->ExitMap));
    870   else
    871     mergeEntryMap(PredInfo->ExitMap.clone());
    872 
    873   ++CurrentBlockInfo->ProcessedPredecessors;
    874 }
    875 
    876 
    877 void SExprBuilder::handlePredecessorBackEdge(const CFGBlock *Pred) {
    878   mergeEntryMapBackEdge();
    879 }
    880 
    881 
    882 void SExprBuilder::enterCFGBlockBody(const CFGBlock *B) {
    883   // The merge*() methods have created arguments.
    884   // Push those arguments onto the basic block.
    885   CurrentBB->arguments().reserve(
    886     static_cast<unsigned>(CurrentArguments.size()), Arena);
    887   for (auto *A : CurrentArguments)
    888     CurrentBB->addArgument(A);
    889 }
    890 
    891 
    892 void SExprBuilder::handleStatement(const Stmt *S) {
    893   til::SExpr *E = translate(S, nullptr);
    894   addStatement(E, S);
    895 }
    896 
    897 
    898 void SExprBuilder::handleDestructorCall(const VarDecl *VD,
    899                                         const CXXDestructorDecl *DD) {
    900   til::SExpr *Sf = new (Arena) til::LiteralPtr(VD);
    901   til::SExpr *Dr = new (Arena) til::LiteralPtr(DD);
    902   til::SExpr *Ap = new (Arena) til::Apply(Dr, Sf);
    903   til::SExpr *E = new (Arena) til::Call(Ap);
    904   addStatement(E, nullptr);
    905 }
    906 
    907 
    908 
    909 void SExprBuilder::exitCFGBlockBody(const CFGBlock *B) {
    910   CurrentBB->instructions().reserve(
    911     static_cast<unsigned>(CurrentInstructions.size()), Arena);
    912   for (auto *V : CurrentInstructions)
    913     CurrentBB->addInstruction(V);
    914 
    915   // Create an appropriate terminator
    916   unsigned N = B->succ_size();
    917   auto It = B->succ_begin();
    918   if (N == 1) {
    919     til::BasicBlock *BB = *It ? lookupBlock(*It) : nullptr;
    920     // TODO: set index
    921     unsigned Idx = BB ? BB->findPredecessorIndex(CurrentBB) : 0;
    922     auto *Tm = new (Arena) til::Goto(BB, Idx);
    923     CurrentBB->setTerminator(Tm);
    924   }
    925   else if (N == 2) {
    926     til::SExpr *C = translate(B->getTerminatorCondition(true), nullptr);
    927     til::BasicBlock *BB1 = *It ? lookupBlock(*It) : nullptr;
    928     ++It;
    929     til::BasicBlock *BB2 = *It ? lookupBlock(*It) : nullptr;
    930     // FIXME: make sure these arent' critical edges.
    931     auto *Tm = new (Arena) til::Branch(C, BB1, BB2);
    932     CurrentBB->setTerminator(Tm);
    933   }
    934 }
    935 
    936 
    937 void SExprBuilder::handleSuccessor(const CFGBlock *Succ) {
    938   ++CurrentBlockInfo->UnprocessedSuccessors;
    939 }
    940 
    941 
    942 void SExprBuilder::handleSuccessorBackEdge(const CFGBlock *Succ) {
    943   mergePhiNodesBackEdge(Succ);
    944   ++BBInfo[Succ->getBlockID()].ProcessedPredecessors;
    945 }
    946 
    947 
    948 void SExprBuilder::exitCFGBlock(const CFGBlock *B) {
    949   CurrentArguments.clear();
    950   CurrentInstructions.clear();
    951   CurrentBlockInfo->ExitMap = std::move(CurrentLVarMap);
    952   CurrentBB = nullptr;
    953   CurrentBlockInfo = nullptr;
    954 }
    955 
    956 
    957 void SExprBuilder::exitCFG(const CFGBlock *Last) {
    958   for (auto *Ph : IncompleteArgs) {
    959     if (Ph->status() == til::Phi::PH_Incomplete)
    960       simplifyIncompleteArg(Ph);
    961   }
    962 
    963   CurrentArguments.clear();
    964   CurrentInstructions.clear();
    965   IncompleteArgs.clear();
    966 }
    967 
    968 
    969 /*
    970 void printSCFG(CFGWalker &Walker) {
    971   llvm::BumpPtrAllocator Bpa;
    972   til::MemRegionRef Arena(&Bpa);
    973   SExprBuilder SxBuilder(Arena);
    974   til::SCFG *Scfg = SxBuilder.buildCFG(Walker);
    975   TILPrinter::print(Scfg, llvm::errs());
    976 }
    977 */
    978