Esempio n. 1
0
//--------------------------------------------------------- 
void unrollRecordAssigns(StmtEditor& editor, Stmt* S)
{    
  const RecordType *RT;
  for (stmt_iterator<BinaryOperator> i = stmt_ibegin(S), 
       e = stmt_iend(S); i != e;)
  {
    BinaryOperator* BO = *i;
    if (BO->getOpcode() == BO_Assign && 
        (RT = BO->getType()->getAsStructureType()) != 0 && 
        editor.getStatementOfExpression(BO) == BO)  // ensures top level assign
    {
      CompoundStmt* CS = editor.ensureCompoundParent(BO);
      std::vector<Stmt*> compoundStmts(CS->child_begin(), CS->child_end());
      std::vector<Stmt*>::iterator insertPos = 
        std::find(compoundStmts.begin(), compoundStmts.end(), BO);
      assert(insertPos != compoundStmts.end());
      insertPos = compoundStmts.erase(insertPos);
      RecordAssignUnroller unroller(editor, RT->getDecl(), BO);
      compoundStmts.insert(insertPos, 
        unroller.compoundStmts.begin(), unroller.compoundStmts.end());
      editor.replaceStmts(CS, &compoundStmts[0], compoundStmts.size());
      i = stmt_ibegin(S);
    }
    else
    {
      ++i;
    }
  }
}
Esempio n. 2
0
void UnreachableCodeRule::apply(
  CXCursor& node, CXCursor& parentNode, ViolationSet& violationSet)
{
  Stmt *stmt = CursorHelper::getStmt(node);
  if (stmt)
  {
    CompoundStmt *compoundStmt = dyn_cast<CompoundStmt>(stmt);
    if (compoundStmt)
    {
      bool hasBreakPoint = false;
      for (CompoundStmt::body_iterator body = compoundStmt->body_begin(),
        bodyEnd = compoundStmt->body_end();
        body != bodyEnd;
        body++)
      {
        if (hasBreakPoint)
        {
          Violation violation(node, this);
          violationSet.addViolation(violation);
          return;
        }
        else
        {
          Stmt *bodyStmt = (Stmt *)*body;
          hasBreakPoint = isBreakPoint(bodyStmt, parentNode);
        }
      }
    }
  }
}
 bool shouldProceed(void *S, void *T) {
   using namespace clang;
   Sema *Sem = (Sema *)S;
   DiagnosticsEngine& Diag = Sem->getDiagnostics();
   cling::Transaction* Trans = (cling::Transaction*)T;
   // Here we will cheat a bit and assume that the warning came from the last
   // stmt, which will be in the 90% of the cases.
   CompoundStmt* CS = cast<CompoundStmt>(Trans->getWrapperFD()->getBody());
   // Skip the NullStmts.
   SourceLocation Loc = CS->getLocStart();
   for(CompoundStmt::const_reverse_body_iterator I = CS->body_rbegin(),
         E = CS->body_rend(); I != E; ++I)
     if (!isa<NullStmt>(*I)) {
       Loc = (*I)->getLocStart();
       break;
     }
   Diag.Report(Loc, diag::warn_null_ptr_deref);
   if (isatty(fileno(stdin))) {
     int input = getchar();
     getchar();
     if (input == 'y' || input == 'Y') 
       return false;
   }
   return true;
 }
    bool VisitSwitchStmt(SwitchStmt *switchStmt)
    {
        CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(switchStmt->getBody());
        if (compoundStmt)
        {
            bool breakFound = true;
            for (CompoundStmt::body_iterator body = compoundStmt->body_begin(),
                bodyEnd = compoundStmt->body_end(); body != bodyEnd; body++)
            {
                Stmt *bodyStmt = dyn_cast<Stmt>(*body);
                if (isBreakingPoint(bodyStmt))
                {
                    breakFound = true;
                    continue;
                }
                if (isSwitchCase(bodyStmt))
                {
                    if (!breakFound)
                    {
                        addViolation(switchStmt, this);
                        break;
                    }

                    FindingBreak findingBreak;
                    breakFound = findingBreak.findBreak(dyn_cast<SwitchCase>(bodyStmt));
                }
            }
            if (!breakFound)
            {
                addViolation(switchStmt, this);
            }
        }

        return true;
    }
Esempio n. 5
0
Stmt *TransformWCR::MergeWCRsAndMakeCompoundStmt(StmtVector &Body) {
  StmtVector Stmts;
  UnwrapStmtList(Stmts, Body);

#if 1
  return NewCompoundStmt(Stmts);
#else
  StmtVector NewBody;
  for (unsigned i = 0, e = Stmts.size(); i < e; i++) {
    CompoundStmt *CS = dyn_cast<CompoundStmt>(Stmts[i]);
    if (CS && CS->isWCR() && !isLandPad(CS)) {
      // Check if the next stmt is a WCR.
      while (i + 1 < e) {
        CompoundStmt *nextCS = dyn_cast<CompoundStmt>(Stmts[i+1]);
        if (nextCS && nextCS->isWCR() && !isLandPad(CS)) {
          CS = MergeConsecutiveWCRs(CS, nextCS);
          i++;
        } else break;
      }
      NewBody.push_back(CS);
    } else {
      NewBody.push_back(Stmts[i]);
    }
  }

  return NewCompoundStmt(NewBody);
#endif
}
Esempio n. 6
0
//--------------------------------------------------------- 
void removeInnerAssigns(StmtEditor& editor, Stmt* S)
{    
  for (stmt_iterator<BinaryOperator> i = stmt_ibegin(S), 
       e = stmt_iend(S); i != e;)
  {
    if (i->getOpcode() == BO_Assign && 
        isa<Expr>(editor.getParent(*i)))
    {
      Stmt* exprStmt = editor.getStatementOfExpression(*i);
      CompoundStmt* CS = editor.ensureCompoundParent(exprStmt);
      std::vector<Stmt*> compoundStmts(CS->child_begin(), CS->child_end());
      std::vector<Stmt*>::iterator insertPos = 
        std::find(compoundStmts.begin(), compoundStmts.end(), exprStmt);
      assert(insertPos != compoundStmts.end());
      compoundStmts.insert(insertPos, *i);
      editor.replaceStatement(*i, selectInnerAssignResult(*i));
      editor.replaceStmts(CS, &compoundStmts[0], compoundStmts.size());
      i = stmt_ibegin(S);
    }
    else
    {
      ++i;
    }
  }
}
Esempio n. 7
0
Stmt *TransformVector::VisitDoStmt(DoStmt *Node) {
  // Body
  Stmt *Body = Node->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  if (!CS) {
    // Convert a single stmt Body into a compound stmt.
    SourceLocation loc;
    CS = new (ASTCtx) CompoundStmt(ASTCtx, &Body, 1, loc, loc);
  }
  Node->setBody(TransformStmt(CS));

  // Cond
  Expr *Cond = Node->getCond();
  if (Cond->getType()->isVectorType()) {
    DeclVector DeclVec;
    Node->setCond(ConvertVecLiteralInExpr(DeclVec, Cond));

    if (DeclVec.size() > 0) {
      CS = dyn_cast<CompoundStmt>(Node->getBody());

      StmtVector StmtVec;
      CompoundStmt::body_iterator I, E;
      for (I = CS->body_begin(), E = CS->body_end(); I != E; ++I) {
        StmtVec.push_back(*I);
      }
      PushBackDeclStmts(StmtVec, DeclVec);

      CS->setStmts(ASTCtx, StmtVec.data(), StmtVec.size());
    }
  } else {
    Node->setCond(TransformExpr(Cond));
  }

  return Node;
}
Esempio n. 8
0
  void ReturnSynthesizer::Transform() {
    if (!getTransaction()->getCompilationOpts().ResultEvaluation)
      return;

    FunctionDecl* FD = getTransaction()->getWrapperFD();

    int foundAtPos = -1;
    Expr* lastExpr = utils::Analyze::GetOrCreateLastExpr(FD, &foundAtPos, 
                                                         /*omitDS*/false,
                                                         m_Sema);
    if (lastExpr) {
      QualType RetTy = lastExpr->getType();
      if (!RetTy->isVoidType() && RetTy.isTriviallyCopyableType(*m_Context)) {
        // Change the void function's return type
        // We can't PushDeclContext, because we don't have scope.
        Sema::ContextRAII pushedDC(*m_Sema, FD);
        FunctionProtoType::ExtProtoInfo EPI;
        QualType FnTy
          = m_Context->getFunctionType(RetTy, llvm::ArrayRef<QualType>(), EPI);
        FD->setType(FnTy);
        CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
        assert(CS && "Missing body?");
        // Change it to a return stmt (Avoid dealloc/alloc of all el.)
        *(CS->body_begin() + foundAtPos)
          = m_Sema->ActOnReturnStmt(lastExpr->getExprLoc(), 
                                    lastExpr).take();
      }
    } else if (foundAtPos >= 0) {
      // check for non-void return statement
      CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
      Stmt* CSS = *(CS->body_begin() + foundAtPos);
      if (ReturnStmt* RS = dyn_cast<ReturnStmt>(CSS)) {
        if (Expr* RetV = RS->getRetValue()) {
          QualType RetTy = RetV->getType();
          // Any return statement will have been "healed" by Sema
          // to correspond to the original void return type of the
          // wrapper, using a ImplicitCastExpr 'void' <ToVoid>.
          // Remove that.
          if (RetTy->isVoidType()) {
            ImplicitCastExpr* VoidCast = dyn_cast<ImplicitCastExpr>(RetV);
            if (VoidCast) {
              RS->setRetValue(VoidCast->getSubExpr());
              RetTy = VoidCast->getSubExpr()->getType();
            }
          }

          if (!RetTy->isVoidType()
              && RetTy.isTriviallyCopyableType(*m_Context)) {
            Sema::ContextRAII pushedDC(*m_Sema, FD);
            FunctionProtoType::ExtProtoInfo EPI;
            QualType FnTy
              = m_Context->getFunctionType(RetTy, llvm::ArrayRef<QualType>(),
                                           EPI);
            FD->setType(FnTy);
          } // not returning void
        } // have return value
      } // is a return statement
    } // have a statement
  }
Esempio n. 9
0
CompoundStmt *TransformWCR::getWCR(int id) {
  for (WCRSetTy::iterator I = WCRs.begin(), E = WCRs.end(); I != E; ++I) {
    CompoundStmt *WCR = *I;
    if (WCR->getWCRID() == id) return WCR;
  }
  assert(0 && "Invalid WCR ID");
  return 0;
}
Esempio n. 10
0
bool EmptyIfStatementRule::isLexicalEmpty(Stmt *stmt)
{
  if (stmt)
  {
    CompoundStmt *compoundStmt = dyn_cast<CompoundStmt>(stmt);
    return isa<NullStmt>(stmt) || (compoundStmt && compoundStmt->body_empty());
  }
  return false;
}
Esempio n. 11
0
void TransformWCR::UnwrapStmtList(StmtVector &Stmts, StmtVector &Body) {
  for (unsigned i = 0, e = Body.size(); i < e; i++) {
    CompoundStmt *CS = dyn_cast<CompoundStmt>(Body[i]);
    if (CS && CS->isStmtList()) {
      SerializeStmtList(Stmts, CS);
    } else {
      Stmts.push_back(Body[i]);
    }
  }
}
Esempio n. 12
0
//---------------------------------------------------------------------------
void TransformWCR::SerializeStmtList(StmtVector &Stmts, CompoundStmt *SL) {
  for (CompoundStmt::body_iterator I = SL->body_begin(), E = SL->body_end();
       I != E; ++I) {
    CompoundStmt *CS = dyn_cast<CompoundStmt>(*I);
    if (CS && CS->isStmtList())
      SerializeStmtList(Stmts, CS);
    else
      Stmts.push_back(*I);
  }
  ASTCtx.Deallocate(SL);
}
NamedDecl* RedundantLocalVariableRule::extractFromDeclStmt(Stmt *stmt) {
  CompoundStmt *compoundStmt = dyn_cast<CompoundStmt>(stmt);
  if (compoundStmt && compoundStmt->size() >= 2) {
    Stmt *lastSecondStmt = (Stmt *)*(compoundStmt->body_end() - 2);
    DeclStmt *declStmt = dyn_cast<DeclStmt>(lastSecondStmt);
    if (declStmt && declStmt->isSingleDecl()) {
      return dyn_cast<NamedDecl>(declStmt->getSingleDecl());
    }
  }
  return NULL;
}
Esempio n. 14
0
////////////////////////////////////////////////////////////////////////////
/// Printing functions for debugging
////////////////////////////////////////////////////////////////////////////
void TransformWCR::printWCRs() {
  OS << "All WCRs(" << WCRs.size() << ") = { ";
  for (WCRSetTy::iterator I = WCRs.begin(), E = WCRs.end(); I != E; ++I) {
    if (I != WCRs.begin()) OS << ", ";
    CompoundStmt *WCR = *I;
    OS << "W" << WCR->getWCRID();
    if (isLandPad(WCR)) OS << "(LP)";
  }
  OS << " }\n";
  OS.flush();
}
Esempio n. 15
0
 void applyDecl(Decl *decl)
 {
     if (decl->hasBody() &&
         !isCppMethodDeclLocatedInCppRecordDecl(dyn_cast<CXXMethodDecl>(decl)))
     {
         CompoundStmt *compoundStmt = dyn_cast<CompoundStmt>(decl->getBody());
         int length = getLineCount(compoundStmt->getSourceRange(), _carrier->getSourceManager());
         int threshold = RuleConfiguration::intForKey("LONG_METHOD", 50);
         if (length > threshold)
         {
             string description = "Method with " +
                 toString<int>(length) + " lines exceeds limit of " + toString<int>(threshold);
             addViolation(decl, this, description);
         }
     }
 }
Esempio n. 16
0
bool RNFStatementVisitor::VisitStmtExpr(StmtExpr *SE)
{
  CompoundStmt *CS = SE->getSubStmt();
  if (ConsumerInstance->CallExprQueue.empty()) {
    TraverseStmt(CS);
    return false;
  }

  CallExpr *CallE = ConsumerInstance->CallExprQueue.back();
  CurrentStmt = CallE;

  for (clang::CompoundStmt::body_iterator I = CS->body_begin(),
       E = CS->body_end(); I != E; ++I) {
    TraverseStmt(*I);
  }
  return false;
}
Esempio n. 17
0
int NPathComplexityMetric::nPath(SwitchStmt *stmt)
{
    int internalNPath = 0, nPathSwitchStmt = nPath(stmt->getCond());
    CompoundStmt *body = (CompoundStmt *)stmt->getBody();
    for (CompoundStmt::body_iterator bodyStmt = body->body_begin(), bodyStmtEnd = body->body_end();
        bodyStmt != bodyStmtEnd; bodyStmt++)
    {
        if (isa<SwitchCase>(*bodyStmt))
        {
            SwitchCase *switchCase = dyn_cast<SwitchCase>(*bodyStmt);
            nPathSwitchStmt += internalNPath;
            internalNPath = nPath(switchCase->getSubStmt());
        }
        else
        {
            internalNPath *= nPath(*bodyStmt);
        }
    }
    return nPathSwitchStmt + internalNPath;
}
Esempio n. 18
0
    bool VisitForStmt(ForStmt *parentStmt)
    {
        Stmt *bodyStmt = parentStmt->getBody();
        ForStmt *forStmt = dyn_cast_or_null<ForStmt>(bodyStmt);
        CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(bodyStmt);
        if (!forStmt && compoundStmt && compoundStmt->size() == 1)
        {
            forStmt = dyn_cast_or_null<ForStmt>(compoundStmt->body_back());
        }
        if (forStmt)
        {
            Stmt *initStmt = parentStmt->getInit();
            Expr *incExpr = forStmt->getInc();
            if (isInnerIncMatchingOuterInit(incExpr, initStmt))
            {
                addViolation(incExpr, this);
            }
        }

        return true;
    }
Esempio n. 19
0
/// EmitCompoundStmt - Emit a compound statement {..} node.  If GetLast is true,
/// this captures the expression result of the last sub-statement and returns it
/// (for use by the statement expression extension).
RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
                                         llvm::Value *AggLoc, bool isAggVol) {
  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(),
                             "LLVM IR generation of compound statement ('{}')");
  
  CGDebugInfo *DI = getDebugInfo();
  if (DI) {
    EnsureInsertPoint();
    DI->setLocation(S.getLBracLoc());
    // FIXME: The llvm backend is currently not ready to deal with region_end
    // for block scoping.  In the presence of always_inline functions it gets so
    // confused that it doesn't emit any debug info.  Just disable this for now.
    //DI->EmitRegionStart(CurFn, Builder);
  }

  // Keep track of the current cleanup stack depth.
  size_t CleanupStackDepth = CleanupEntries.size();
  bool OldDidCallStackSave = DidCallStackSave;
  DidCallStackSave = false;
  
  for (CompoundStmt::const_body_iterator I = S.body_begin(),
       E = S.body_end()-GetLast; I != E; ++I)
    EmitStmt(*I);

  if (DI) {
    EnsureInsertPoint();
    DI->setLocation(S.getRBracLoc());
    
    // FIXME: The llvm backend is currently not ready to deal with region_end
    // for block scoping.  In the presence of always_inline functions it gets so
    // confused that it doesn't emit any debug info.  Just disable this for now.
    //DI->EmitRegionEnd(CurFn, Builder);
  }

  RValue RV;
  if (!GetLast) 
    RV = RValue::get(0);
  else {
    // We have to special case labels here.  They are statements, but when put 
    // at the end of a statement expression, they yield the value of their
    // subexpression.  Handle this by walking through all labels we encounter,
    // emitting them before we evaluate the subexpr.
    const Stmt *LastStmt = S.body_back();
    while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
      EmitLabel(*LS);
      LastStmt = LS->getSubStmt();
    }
  
    EnsureInsertPoint();
    
    RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
  }

  DidCallStackSave = OldDidCallStackSave;
  
  EmitCleanupBlocks(CleanupStackDepth);
  
  return RV;
}
Esempio n. 20
0
//--------------------------------------------------------- 
void removeGotosToNextLabel(StmtEditor& editor, Stmt* Node)
{
  RemoveGotosToNextLabel visitor(editor);
  visit_df(Node, visitor);
  for (RemoveGotosToNextLabel::tTouchedLabels::iterator i = visitor.m_TouchedLabels.begin(), 
       e = visitor.m_TouchedLabels.end(); i != e; ++i)
  {
    if (!i->second.m_Used)
    {
      LabelStmt* LS = i->second.LS;
      assert(LS);
      CompoundStmt* CS = dyn_cast<CompoundStmt>(editor.getParent(LS));
      if (CS && CS->size() > 1 && isa<NullStmt>(LS->getSubStmt()))
      {
        editor.removeStmt(CS, LS);
      }
      else
      {
        editor.replaceStatement(LS, LS->getSubStmt());
      }
    }
  }
}
Esempio n. 21
0
//--------------------------------------------------------- 
void expandOneUsedInitDeclsToUse(StmtEditor& editor, Stmt* Node)
{
  CountVarUses visitor(editor);
  CompileTimeComputedExprTester tester;
  visit_df(Node, visitor);
  for (CountVarUses::tVarRefCountMap::iterator i = visitor.m_VarUseCount.begin(), 
       e = visitor.m_VarUseCount.end(); i != e; ++i)
  {
    if (i->second.second < 2 || 
        (i->first->getInit() && tester.Visit(i->first->getInit())))
    {
      CompoundStmt* CS = dyn_cast<CompoundStmt>(editor.getParent(i->second.first));
      if (CS && CS->size() > 1)
      {
        if (i->second.second > 0)
        {
          visit_df(Node, ExpandVariableRefs(editor, i->first));
          i->first->setInit(0); // ownership was transferred, so don't confuse anyone after us
        }
        editor.removeStmt(CS, i->second.first);
      }
    }
  }
}
Esempio n. 22
0
ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, 
                                 Scope *CurScope, 
                                 llvm::Optional<unsigned> ManglingNumber,
                                 Decl *ContextDecl,
                                 bool IsInstantiation) {
  // Collect information from the lambda scope.
  llvm::SmallVector<LambdaExpr::Capture, 4> Captures;
  llvm::SmallVector<Expr *, 4> CaptureInits;
  LambdaCaptureDefault CaptureDefault;
  CXXRecordDecl *Class;
  CXXMethodDecl *CallOperator;
  SourceRange IntroducerRange;
  bool ExplicitParams;
  bool ExplicitResultType;
  bool LambdaExprNeedsCleanups;
  llvm::SmallVector<VarDecl *, 4> ArrayIndexVars;
  llvm::SmallVector<unsigned, 4> ArrayIndexStarts;
  {
    LambdaScopeInfo *LSI = getCurLambda();
    CallOperator = LSI->CallOperator;
    Class = LSI->Lambda;
    IntroducerRange = LSI->IntroducerRange;
    ExplicitParams = LSI->ExplicitParams;
    ExplicitResultType = !LSI->HasImplicitReturnType;
    LambdaExprNeedsCleanups = LSI->ExprNeedsCleanups;
    ArrayIndexVars.swap(LSI->ArrayIndexVars);
    ArrayIndexStarts.swap(LSI->ArrayIndexStarts);
    
    // Translate captures.
    for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
      LambdaScopeInfo::Capture From = LSI->Captures[I];
      assert(!From.isBlockCapture() && "Cannot capture __block variables");
      bool IsImplicit = I >= LSI->NumExplicitCaptures;

      // Handle 'this' capture.
      if (From.isThisCapture()) {
        Captures.push_back(LambdaExpr::Capture(From.getLocation(),
                                               IsImplicit,
                                               LCK_This));
        CaptureInits.push_back(new (Context) CXXThisExpr(From.getLocation(),
                                                         getCurrentThisType(),
                                                         /*isImplicit=*/true));
        continue;
      }

      VarDecl *Var = From.getVariable();
      LambdaCaptureKind Kind = From.isCopyCapture()? LCK_ByCopy : LCK_ByRef;
      Captures.push_back(LambdaExpr::Capture(From.getLocation(), IsImplicit, 
                                             Kind, Var, From.getEllipsisLoc()));
      CaptureInits.push_back(From.getCopyExpr());
    }

    switch (LSI->ImpCaptureStyle) {
    case CapturingScopeInfo::ImpCap_None:
      CaptureDefault = LCD_None;
      break;

    case CapturingScopeInfo::ImpCap_LambdaByval:
      CaptureDefault = LCD_ByCopy;
      break;

    case CapturingScopeInfo::ImpCap_LambdaByref:
      CaptureDefault = LCD_ByRef;
      break;

    case CapturingScopeInfo::ImpCap_Block:
      llvm_unreachable("block capture in lambda");
      break;
    }

    // C++11 [expr.prim.lambda]p4:
    //   If a lambda-expression does not include a
    //   trailing-return-type, it is as if the trailing-return-type
    //   denotes the following type:
    // FIXME: Assumes current resolution to core issue 975.
    if (LSI->HasImplicitReturnType) {
      //   - if there are no return statements in the
      //     compound-statement, or all return statements return
      //     either an expression of type void or no expression or
      //     braced-init-list, the type void;
      if (LSI->ReturnType.isNull()) {
        LSI->ReturnType = Context.VoidTy;
      } else {
        // C++11 [expr.prim.lambda]p4:
        //   - if the compound-statement is of the form
        //
        //       { attribute-specifier-seq[opt] return expression ; }
        //
        //     the type of the returned expression after
        //     lvalue-to-rvalue conversion (4.1), array-to-pointer
        //     conver- sion (4.2), and function-to-pointer conversion
        //     (4.3);
        //
        // Since we're accepting the resolution to a post-C++11 core
        // issue with a non-trivial extension, provide a warning (by
        // default).
        CompoundStmt *CompoundBody = cast<CompoundStmt>(Body);
        if (!(CompoundBody->size() == 1 &&
              isa<ReturnStmt>(*CompoundBody->body_begin())) &&
            !Context.hasSameType(LSI->ReturnType, Context.VoidTy))
          Diag(IntroducerRange.getBegin(), 
               diag::ext_lambda_implies_void_return);
      }

      // Create a function type with the inferred return type.
      const FunctionProtoType *Proto
        = CallOperator->getType()->getAs<FunctionProtoType>();
      QualType FunctionTy
        = Context.getFunctionType(LSI->ReturnType,
                                  Proto->arg_type_begin(),
                                  Proto->getNumArgs(),
                                  Proto->getExtProtoInfo());
      CallOperator->setType(FunctionTy);
    }

    // C++ [expr.prim.lambda]p7:
    //   The lambda-expression's compound-statement yields the
    //   function-body (8.4) of the function call operator [...].
    ActOnFinishFunctionBody(CallOperator, Body, IsInstantiation);
    CallOperator->setLexicalDeclContext(Class);
    Class->addDecl(CallOperator);
    PopExpressionEvaluationContext();

    // C++11 [expr.prim.lambda]p6:
    //   The closure type for a lambda-expression with no lambda-capture
    //   has a public non-virtual non-explicit const conversion function
    //   to pointer to function having the same parameter and return
    //   types as the closure type's function call operator.
    if (Captures.empty() && CaptureDefault == LCD_None)
      addFunctionPointerConversion(*this, IntroducerRange, Class,
                                   CallOperator);

    // Objective-C++:
    //   The closure type for a lambda-expression has a public non-virtual
    //   non-explicit const conversion function to a block pointer having the
    //   same parameter and return types as the closure type's function call
    //   operator.
    if (getLangOpts().Blocks && getLangOpts().ObjC1)
      addBlockPointerConversion(*this, IntroducerRange, Class, CallOperator);
    
    // Finalize the lambda class.
    SmallVector<Decl*, 4> Fields(Class->field_begin(), Class->field_end());
    ActOnFields(0, Class->getLocation(), Class, Fields, 
                SourceLocation(), SourceLocation(), 0);
    CheckCompletedCXXClass(Class);
  }

  if (LambdaExprNeedsCleanups)
    ExprNeedsCleanups = true;

  // If we don't already have a mangling number for this lambda expression,
  // allocate one now.
  if (!ManglingNumber) {
    ContextDecl = ExprEvalContexts.back().LambdaContextDecl;
    
    enum ContextKind {
      Normal,
      DefaultArgument,
      DataMember,
      StaticDataMember
    } Kind = Normal;

    // Default arguments of member function parameters that appear in a class
    // definition, as well as the initializers of data members, receive special
    // treatment. Identify them.
    if (ContextDecl) {
      if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(ContextDecl)) {
        if (const DeclContext *LexicalDC
              = Param->getDeclContext()->getLexicalParent())
          if (LexicalDC->isRecord())
            Kind = DefaultArgument;
      } else if (VarDecl *Var = dyn_cast<VarDecl>(ContextDecl)) {
        if (Var->getDeclContext()->isRecord())
          Kind = StaticDataMember;
      } else if (isa<FieldDecl>(ContextDecl)) {
        Kind = DataMember;
      }
    }        
    
    switch (Kind) {
    case Normal:
      if (CurContext->isDependentContext() || isInInlineFunction(CurContext))
        ManglingNumber = Context.getLambdaManglingNumber(CallOperator);
      else
        ManglingNumber = 0;
        
      // There is no special context for this lambda.
      ContextDecl = 0;        
      break;
      
    case StaticDataMember:
      if (!CurContext->isDependentContext()) {
        ManglingNumber = 0;
        ContextDecl = 0;
        break;
      }
      // Fall through to assign a mangling number.
        
    case DataMember:
    case DefaultArgument:
      ManglingNumber = ExprEvalContexts.back().getLambdaMangleContext()
                         .getManglingNumber(CallOperator);
      break;
    }
  }
  
  LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, 
                                          CaptureDefault, Captures, 
                                          ExplicitParams, ExplicitResultType,
                                          CaptureInits, ArrayIndexVars, 
                                          ArrayIndexStarts, Body->getLocEnd(),
                                          *ManglingNumber, ContextDecl);

  // C++11 [expr.prim.lambda]p2:
  //   A lambda-expression shall not appear in an unevaluated operand
  //   (Clause 5).
  if (!CurContext->isDependentContext()) {
    switch (ExprEvalContexts.back().Context) {
    case Unevaluated:
      // We don't actually diagnose this case immediately, because we
      // could be within a context where we might find out later that
      // the expression is potentially evaluated (e.g., for typeid).
      ExprEvalContexts.back().Lambdas.push_back(Lambda);
      break;

    case ConstantEvaluated:
    case PotentiallyEvaluated:
    case PotentiallyEvaluatedIfUsed:
      break;
    }
  }
  
  return MaybeBindToTemporary(Lambda);
}
Esempio n. 23
0
CompoundStmt *TransformWCR::NewStmtList(StmtVector &Stmts) {
  CompoundStmt *CS = NewCompoundStmt(Stmts);
  CS->setIsStmtList(true);
  return CS;
}
Esempio n. 24
0
Stmt *TransformVector::VisitSwitchStmt(SwitchStmt *Node) {
  DeclVector DeclVec;

  // Cond
  Expr *Cond = Node->getCond();
  if (Cond->getType()->isVectorType()) {
    Node->setCond(ConvertVecLiteralInExpr(DeclVec, Cond));
  } else {
    Node->setCond(TransformExpr(Cond));
  }

  // Body
  Stmt *Body = Node->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  if (!CS) {
    // Convert a single stmt body into a CompoundStmt.
    SourceLocation loc;
    CS = new (ASTCtx) CompoundStmt(ASTCtx, &Body, 1, loc, loc);
  }

  // Check all SwitchCase stmts themselves.
  SwitchCase *CurCase = Node->getSwitchCaseList();
  while (CurCase) {
    if (CaseStmt *CaseS = dyn_cast<CaseStmt>(CurCase)) {
      Expr *CaseLHS = CaseS->getLHS();
      if (CaseLHS->getType()->isVectorType()) {
        CaseS->setLHS(ConvertVecLiteralInExpr(DeclVec, CaseLHS));
      } else {
        CaseS->setLHS(TransformExpr(CaseLHS));
      }

      Expr *CaseRHS = CaseS->getRHS();
      if (CaseRHS && CaseRHS->getType()->isVectorType()) {
        CaseS->setRHS(ConvertVecLiteralInExpr(DeclVec, CaseRHS));
      } else {
        CaseS->setRHS(TransformExpr(CaseRHS));
      }
    }

    CurCase = CurCase->getNextSwitchCase();
  }

  // Check if there was a vector literal code motion.
  if (DeclVec.size() > 0) {
    PushBackDeclStmts(*CurStmtVec, DeclVec);
  }

  // If case stmts are not CompoundStmts, convert them into CompoundStmts
  StmtVector BodyStmts;
  CompoundStmt::body_iterator I, E;
  for (I = CS->body_begin(), E = CS->body_end(); I != E; ++I) {
    // Save the current stmt
    BodyStmts.push_back(*I);

    if (SwitchCase *SC = dyn_cast<SwitchCase>(*I)) {
      CompoundStmt::body_iterator NextI = I + 1; 
      if (NextI == E) break;

      if (isa<SwitchCase>(*NextI)) {
        // No stmt between current case stmt and next case stmt.
        if (Stmt *SubStmt = SC->getSubStmt()) {
          if (!isa<CompoundStmt>(SubStmt)) {
            SourceLocation loc;
            CompoundStmt *SubCS = new (ASTCtx) CompoundStmt(ASTCtx,
                &SubStmt, 1, loc, loc);

            if (CaseStmt *CaseS = dyn_cast<CaseStmt>(SC)) {
              CaseS->setSubStmt(SubCS);
            } else if (DefaultStmt *DefaultS = dyn_cast<DefaultStmt>(SC)) {
              DefaultS->setSubStmt(SubCS);
            } else {
              assert(0 && "What statement?");
            }
          }
        }
      } else {
        StmtVector StmtVec;

        // SubStmt
        if (Stmt *SubStmt = SC->getSubStmt()) {
          StmtVec.push_back(SubStmt);
        }

        // Following stmts
        do {
          I = NextI;
          StmtVec.push_back(*I);
        } while ((++NextI != E) && !isa<SwitchCase>(*NextI));

        // Convert all stmts into a CompoundStmt.
        SourceLocation loc;
        CompoundStmt *SubCS = new (ASTCtx) CompoundStmt(ASTCtx,
            StmtVec.data(), StmtVec.size(), loc, loc);

        if (CaseStmt *CaseS = dyn_cast<CaseStmt>(SC)) {
          CaseS->setSubStmt(SubCS);
        } else if (DefaultStmt *DefaultS = dyn_cast<DefaultStmt>(SC)) {
          DefaultS->setSubStmt(SubCS);
        } else {
          assert(0 && "What statement?");
        }
      }
    } //end if
  } //end for

  CS = new (ASTCtx) CompoundStmt(ASTCtx, BodyStmts.data(), BodyStmts.size(),
      SourceLocation(), SourceLocation());
  ASTCtx.Deallocate(Node->getBody());
  Node->setBody(TransformStmt(CS));

  return Node;
}
Esempio n. 25
0
  bool DeclExtractor::ExtractDecl(Decl* D) {
    FunctionDecl* FD = dyn_cast<FunctionDecl>(D);

    if (FD) {
      if (FD->getNameAsString().find("__cling_Un1Qu3"))
        return true;

      llvm::SmallVector<NamedDecl*, 4> TouchedDecls;
      CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody());
      assert(CS && "Function body not a CompoundStmt?");
      DeclContext* DC = FD->getTranslationUnitDecl();
      Scope* TUScope = m_Sema->TUScope;
      assert(TUScope == m_Sema->getScopeForContext(DC) && "TU scope from DC?");
      llvm::SmallVector<Stmt*, 4> Stmts;

      for (CompoundStmt::body_iterator I = CS->body_begin(), EI = CS->body_end();
           I != EI; ++I) {
        DeclStmt* DS = dyn_cast<DeclStmt>(*I);
        if (!DS) {
          Stmts.push_back(*I);
          continue;
        }

        for (DeclStmt::decl_iterator J = DS->decl_begin();
             J != DS->decl_end(); ++J) {
          NamedDecl* ND = dyn_cast<NamedDecl>(*J);
          if (ND) {
            DeclContext* OldDC = ND->getDeclContext();

            // Make sure the decl is not found at its old possition
            OldDC->removeDecl(ND);
            if (Scope* S = m_Sema->getScopeForContext(OldDC)) {
              S->RemoveDecl(ND);
              m_Sema->IdResolver.RemoveDecl(ND);
            }

            if (ND->getDeclContext() == ND->getLexicalDeclContext())
              ND->setLexicalDeclContext(DC);
            else 
              assert("Not implemented: Decl with different lexical context");
            ND->setDeclContext(DC);

            if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
              VD->setStorageClass(SC_None);
              VD->setStorageClassAsWritten(SC_None);

              // if we want to print the result of the initializer of int i = 5
              // or the default initializer int i
              if (I+1 == EI || !isa<NullStmt>(*(I+1))) {
                QualType VDTy = VD->getType().getNonReferenceType();
                Expr* DRE = m_Sema->BuildDeclRefExpr(VD, VDTy,VK_LValue,
                                                     SourceLocation()
                                                     ).take();
                Stmts.push_back(DRE);
              }
            }
            // force recalc of the linkage (to external)
            ND->ClearLinkageCache();

            TouchedDecls.push_back(ND);
          }
        }
      }
      bool hasNoErrors = !CheckForClashingNames(TouchedDecls, DC, TUScope);
      if (hasNoErrors) {
        for (size_t i = 0; i < TouchedDecls.size(); ++i) {
          m_Sema->PushOnScopeChains(TouchedDecls[i],
                                    m_Sema->getScopeForContext(DC),
                    /*AddCurContext*/!isa<UsingDirectiveDecl>(TouchedDecls[i]));

          // The transparent DeclContexts (eg. scopeless enum) doesn't have 
          // scopes. While extracting their contents we need to update the
          // lookup tables and telling them to pick up the new possitions
          //  in the AST.
          if (DeclContext* InnerDC = dyn_cast<DeclContext>(TouchedDecls[i])) {
            if (InnerDC->isTransparentContext()) {
              // We can't PushDeclContext, because we don't have scope.
              Sema::ContextRAII pushedDC(*m_Sema, InnerDC);

              for(DeclContext::decl_iterator DI = InnerDC->decls_begin(), 
                    DE = InnerDC->decls_end(); DI != DE ; ++DI) {
                if (NamedDecl* ND = dyn_cast<NamedDecl>(*DI))
                  InnerDC->makeDeclVisibleInContext(ND);
              }
            }
          }

          // Append the new top level decl to the current transaction.
          getTransaction()->appendUnique(DeclGroupRef(TouchedDecls[i]));
        }
      }

      CS->setStmts(*m_Context, Stmts.data(), Stmts.size());

      // Put the wrapper after its declarations. (Nice when AST dumping)
      DC->removeDecl(FD);
      DC->addDecl(FD);

      return hasNoErrors;
    }
    return true;
  }
Esempio n. 26
0
  bool ValuePrinterSynthesizer::tryAttachVP(FunctionDecl* FD) {
    // We have to be able to mark the expression for printout. There are
    // three scenarios:
    // 0: Expression printing disabled - don't do anything just exit.
    // 1: Expression printing enabled - print no matter what.
    // 2: Expression printing auto - analyze - rely on the omitted ';' to
    //    not produce the suppress marker.
    int indexOfLastExpr = -1;
    Expr* To = utils::Analyze::GetOrCreateLastExpr(FD, &indexOfLastExpr,
                                                   /*omitDS*/false,
                                                   m_Sema);
    if (To) {
      // Update the CompoundStmt body, avoiding alloc/dealloc of all the el.
      CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
      assert(CS && "Missing body?");

      switch (getCompilationOpts().ValuePrinting) {
      case CompilationOptions::VPDisabled:
        assert(0 && "Don't wait that long. Exit early!");
        break;
      case CompilationOptions::VPEnabled:
        break;
      case CompilationOptions::VPAuto: {
        // FIXME: Propagate the flag to the nested transactions also, they
        // must have the same CO as their parents.
        getCompilationOpts().ValuePrinting = CompilationOptions::VPEnabled;
        if ((int)CS->size() > indexOfLastExpr+1
            && (*(CS->body_begin() + indexOfLastExpr + 1))
            && isa<NullStmt>(*(CS->body_begin() + indexOfLastExpr + 1))) {
          // If next is NullStmt disable VP is disabled - exit. Signal this in
          // the CO of the transaction.
          getCompilationOpts().ValuePrinting = CompilationOptions::VPDisabled;
        }
        if (getCompilationOpts().ValuePrinting
            == CompilationOptions::VPDisabled)
          return true;
      }
        break;
      }

      // We can't PushDeclContext, because we don't have scope.
      Sema::ContextRAII pushedDC(*m_Sema, FD);

      if (To) {
        // Strip the parenthesis if any
        if (ParenExpr* PE = dyn_cast<ParenExpr>(To))
          To = PE->getSubExpr();

        Expr* Result = 0;
        // if (!m_Sema->getLangOpts().CPlusPlus)
        //   Result = SynthesizeVP(To);

        if (Result)
          *(CS->body_begin()+indexOfLastExpr) = Result;
      }
      // Clear the artificial NullStmt-s
      if (!ClearNullStmts(CS)) {
        // FIXME: Why it is here? Shouldn't it be in DeclExtractor?
        // if no body remove the wrapper
        DeclContext* DC = FD->getDeclContext();
        Scope* S = m_Sema->getScopeForContext(DC);
        if (S)
          S->RemoveDecl(FD);
        DC->removeDecl(FD);
      }
    }
    else // if nothing to attach to set the CO's ValuePrinting to disabled.
      getCompilationOpts().ValuePrinting = CompilationOptions::VPDisabled;
    return true;
  }
Esempio n. 27
0
Stmt *TransformWCR::VisitForStmt(ForStmt *S) {
  StmtVector OuterBody;
  StmtVector BodyStmts;
  StmtVector WCRBody;

  // If Init of ForStmt has a DeclStmt, we make a CompoundStmt that encloses
  // an Init stmt and WhileStmt made from orginal ForStmt.
  bool HasDecl = false;

  // Init
  if (Stmt *Init = S->getInit()) {
    if (DeclStmt *DS = dyn_cast<DeclStmt>(Init)) {
      HasDecl = true;
      StmtVector tmpWCR;
      VisitRawDeclStmt(DS, OuterBody, tmpWCR);
      MergeBodyAndWCR(OuterBody, tmpWCR);
    } else {
      MergeBodyAndCond(OuterBody, Init);
    }
  }

  // Declaration of condition variable
  VarDecl *CondVD = NewCondVarDecl(ASTCtx.IntTy);
  CondDecls.push_back(NewDeclStmt(CondVD));

  // Computation of condition
  DeclRefExpr *LHS = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  Expr *Cond = S->getCond();
  if (!Cond) Cond = CLExprs.getExpr(CLExpressions::ONE);
  BinaryOperator *CondBinOp = new (ASTCtx) BinaryOperator(
      LHS, Cond, BO_Assign, LHS->getType(), 
      VK_RValue, OK_Ordinary, SourceLocation());

  // Cond WCR
  MergeBodyAndCond(BodyStmts, CondBinOp);

  // Exit condition
  DeclRefExpr *CondRef = new (ASTCtx) DeclRefExpr(CondVD,
      CondVD->getType(), VK_RValue, SourceLocation());
  UnaryOperator *NotCond = new (ASTCtx) UnaryOperator(
      CondRef, UO_LNot, CondVD->getType(), VK_RValue, OK_Ordinary,
      SourceLocation());
  BreakStmt *ThenStmt = new (ASTCtx) BreakStmt(SourceLocation());
  IfStmt *ExitStmt = new (ASTCtx) IfStmt(ASTCtx, SourceLocation(), 
                                         NULL, NotCond, ThenStmt);
  BodyStmts.push_back(ExitStmt);
  
  // Body
  Stmt *Body = S->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  assert(CS && "Not a CompoundStmt");

  // Identify each WCR
  VisitRawCompoundStmt(CS, BodyStmts, WCRBody);
  MergeBodyAndWCR(BodyStmts, WCRBody);

  // Inc
  if (Expr *Inc = S->getInc()) MergeBodyAndCond(BodyStmts, Inc);

  ASTCtx.Deallocate(S);
  ASTCtx.Deallocate(CS);

  // Outer WhileStmt 
  Cond = CLExprs.getExpr(CLExpressions::ONE);
  Body = MergeWCRsAndMakeCompoundStmt(BodyStmts);
  WhileStmt *WS = new (ASTCtx) WhileStmt(ASTCtx, NULL, Cond, Body,
                                         SourceLocation());
  OuterBody.push_back(WS);

  // Landing pad - empty WCR
  OuterBody.push_back(NewLandingPad(WS));

  CompoundStmt *Out = NewCompoundStmt(OuterBody);
  if (!HasDecl) Out->setIsStmtList(true);
  return Out;
}
  void ValueExtractionSynthesizer::Transform() {
    const CompilationOptions& CO = getTransaction()->getCompilationOpts();
    // If we do not evaluate the result, or printing out the result return.
    if (!(CO.ResultEvaluation || CO.ValuePrinting))
      return;

    FunctionDecl* FD = getTransaction()->getWrapperFD();

    int foundAtPos = -1;
    Expr* lastExpr = utils::Analyze::GetOrCreateLastExpr(FD, &foundAtPos,
                                                         /*omitDS*/false,
                                                         m_Sema);
    if (foundAtPos < 0)
      return;

    typedef llvm::SmallVector<Stmt**, 4> StmtIters;
    StmtIters returnStmts;
    ReturnStmtCollector collector(returnStmts);
    CompoundStmt* CS = cast<CompoundStmt>(FD->getBody());
    collector.VisitStmt(CS);

    if (isa<Expr>(*(CS->body_begin() + foundAtPos)))
      returnStmts.push_back(CS->body_begin() + foundAtPos);

    // We want to support cases such as:
    // gCling->evaluate("if() return 'A' else return 12", V), that puts in V,
    // either A or 12.
    // In this case the void wrapper is compiled with the stmts returning
    // values. Sema would cast them to void, but the code will still be
    // executed. For example:
    // int g(); void f () { return g(); } will still call g().
    //
    for (StmtIters::iterator I = returnStmts.begin(), E = returnStmts.end();
         I != E; ++I) {
      ReturnStmt* RS = dyn_cast<ReturnStmt>(**I);
      if (RS) {
        // When we are handling a return stmt, the last expression must be the
        // return stmt value. Ignore the calculation of the lastStmt because it
        // might be wrong, in cases where the return is not in the end of the 
        // function.
        lastExpr = RS->getRetValue();
        if (lastExpr) {
          assert (lastExpr->getType()->isVoidType() && "Must be void type.");
          // Any return statement will have been "healed" by Sema
          // to correspond to the original void return type of the
          // wrapper, using a ImplicitCastExpr 'void' <ToVoid>.
          // Remove that.
          if (ImplicitCastExpr* VoidCast
              = dyn_cast<ImplicitCastExpr>(lastExpr)) {
            lastExpr = VoidCast->getSubExpr();
          }
        }
        // if no value assume void
        else {
          // We can't PushDeclContext, because we don't have scope.
          Sema::ContextRAII pushedDC(*m_Sema, FD);
          RS->setRetValue(SynthesizeSVRInit(0));
        }

      }
      else
        lastExpr = cast<Expr>(**I);

      if (lastExpr) {
        QualType lastExprTy = lastExpr->getType();
        // May happen on auto types which resolve to dependent.
        if (lastExprTy->isDependentType())
          continue;
        // Set up lastExpr properly.
        // Change the void function's return type
        // We can't PushDeclContext, because we don't have scope.
        Sema::ContextRAII pushedDC(*m_Sema, FD);

        if (lastExprTy->isFunctionType()) {
          // A return type of function needs to be converted to
          // pointer to function.
          lastExprTy = m_Context->getPointerType(lastExprTy);
          lastExpr = m_Sema->ImpCastExprToType(lastExpr, lastExprTy,
                                               CK_FunctionToPointerDecay,
                                               VK_RValue).take();
        }

        //
        // Here we don't want to depend on the JIT runFunction, because of its
        // limitations, when it comes to return value handling. There it is
        // not clear who provides the storage and who cleans it up in a
        // platform independent way.
        //
        // Depending on the type we need to synthesize a call to cling:
        // 0) void : set the value's type to void;
        // 1) enum, integral, float, double, referece, pointer types :
        //      call to cling::internal::setValueNoAlloc(...);
        // 2) object type (alloc on the stack) :
        //      cling::internal::setValueWithAlloc
        //   2.1) constant arrays:
        //          call to cling::runtime::internal::copyArray(...)
        //
        // We need to synthesize later:
        // Wrapper has signature: void w(cling::Value SVR)
        // case 1):
        //   setValueNoAlloc(gCling, &SVR, lastExprTy, lastExpr())
        // case 2):
        //   new (setValueWithAlloc(gCling, &SVR, lastExprTy)) (lastExpr)
        // case 2.1):
        //   copyArray(src, placement, size)

        Expr* SVRInit = SynthesizeSVRInit(lastExpr);
        // if we had return stmt update to execute the SVR init, even if the
        // wrapper returns void.
        if (RS) {
          if (ImplicitCastExpr* VoidCast
              = dyn_cast<ImplicitCastExpr>(RS->getRetValue()))
            VoidCast->setSubExpr(SVRInit);
        }
        else
          **I = SVRInit;
      }
    }
  }
Esempio n. 29
0
  bool DeclExtractor::ExtractDecl(FunctionDecl* FD) {
    llvm::SmallVector<NamedDecl*, 4> TouchedDecls;
    CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody());
    assert(CS && "Function body not a CompoundStmt?");
    DeclContext* DC = FD->getTranslationUnitDecl();
    Scope* TUScope = m_Sema->TUScope;
    assert(TUScope == m_Sema->getScopeForContext(DC) && "TU scope from DC?");
    llvm::SmallVector<Stmt*, 4> Stmts;

    for (CompoundStmt::body_iterator I = CS->body_begin(), EI = CS->body_end();
         I != EI; ++I) {
      DeclStmt* DS = dyn_cast<DeclStmt>(*I);
      if (!DS) {
        Stmts.push_back(*I);
        continue;
      }
      
      for (DeclStmt::decl_iterator J = DS->decl_begin();
           J != DS->decl_end(); ++J) {
        NamedDecl* ND = dyn_cast<NamedDecl>(*J);
        if (isa<UsingDirectiveDecl>(*J))
          continue; // FIXME: Here we should be more elegant.
        if (ND) {
          if (Stmts.size()) {
            // We need to emit a new custom wrapper wrapping the stmts
            EnforceInitOrder(Stmts);
            assert(!Stmts.size() && "Stmt list must be flushed.");
          }

          // We know the transaction is closed, but it is safe.
          getTransaction()->forceAppend(ND);

          DeclContext* OldDC = ND->getDeclContext();

          // Make sure the decl is not found at its old possition
          ND->getLexicalDeclContext()->removeDecl(ND);
          if (Scope* S = m_Sema->getScopeForContext(OldDC)) {
            S->RemoveDecl(ND);
            if (utils::Analyze::isOnScopeChains(ND, *m_Sema))
              m_Sema->IdResolver.RemoveDecl(ND);
          }

          // For variable definitions causing var/function ambiguity such as:
          // MyClass my();, C++ standard says it shall be resolved as a function
          //
          // In the particular context this definition is inside a function
          // already, but clang thinks it as a lambda, so we need to ignore the
          // check decl context vs lexical decl context.
          if (ND->getDeclContext() == ND->getLexicalDeclContext()
              || isa<FunctionDecl>(ND))
            ND->setLexicalDeclContext(DC);
          else 
            assert(0 && "Not implemented: Decl with different lexical context");
          ND->setDeclContext(DC);

          if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
            VD->setStorageClass(SC_None);
          }

          clearLinkage(ND);

          TouchedDecls.push_back(ND);
        }
      }
    }
    bool hasNoErrors = !CheckForClashingNames(TouchedDecls, DC, TUScope);
    if (hasNoErrors) {
      for (size_t i = 0; i < TouchedDecls.size(); ++i) {
        // We should skip the checks for annonymous decls and we should not
        // register them in the lookup.
        if (!TouchedDecls[i]->getDeclName())
          continue;

        m_Sema->PushOnScopeChains(TouchedDecls[i],
                                  m_Sema->getScopeForContext(DC),
                    /*AddCurContext*/!isa<UsingDirectiveDecl>(TouchedDecls[i]));

        // The transparent DeclContexts (eg. scopeless enum) doesn't have 
        // scopes. While extracting their contents we need to update the
        // lookup tables and telling them to pick up the new possitions
        // in the AST.
        if (DeclContext* InnerDC = dyn_cast<DeclContext>(TouchedDecls[i])) {
          if (InnerDC->isTransparentContext()) {
            // We can't PushDeclContext, because we don't have scope.
            Sema::ContextRAII pushedDC(*m_Sema, InnerDC);

            for(DeclContext::decl_iterator DI = InnerDC->decls_begin(), 
                  DE = InnerDC->decls_end(); DI != DE ; ++DI) {
              if (NamedDecl* ND = dyn_cast<NamedDecl>(*DI))
                InnerDC->makeDeclVisibleInContext(ND);
            }
          }
        }
      }
    }

    CS->setStmts(*m_Context, Stmts.data(), Stmts.size());

    // The order matters, because when we extract decls from the wrapper we
    // append them to the transaction. If the transaction gets unloaded it will
    // introduce a fake dependency, so put the move last.
    Transaction* T = getTransaction();
    for (Transaction::iterator I = T->decls_begin(), E = T->decls_end();
         I != E; ++I)
      if (!I->m_DGR.isNull() && I->m_DGR.isSingleDecl()
          && I->m_DGR.getSingleDecl() == T->getWrapperFD()) {
        T->erase(I);
        break;
      }
    T->forceAppend(FD);

    // Put the wrapper after its declarations. (Nice when AST dumping)
    DC->removeDecl(FD);
    DC->addDecl(FD);

    return hasNoErrors;
  }