Exemplo n.º 1
0
    bool VisitCompoundStmt(CompoundStmt* CS) {
      for(CompoundStmt::body_iterator I = CS->body_begin(), E = CS->body_end();
          I != E; ++I) {
        if (!isa<BinaryOperator>(*I))
          continue;

        const BinaryOperator* BinOp = cast<BinaryOperator>(*I);
        if (isAutoCandidate(BinOp)) {
          ASTContext& C = m_Sema->getASTContext();
          VarDecl* VD 
            = cast<VarDecl>(cast<DeclRefExpr>(BinOp->getLHS())->getDecl());
          TypeSourceInfo* ResTSI = 0;
          TypeSourceInfo* TrivialTSI 
            = C.getTrivialTypeSourceInfo(VD->getType());
          Expr* RHS = BinOp->getRHS();
          m_Sema->DeduceAutoType(TrivialTSI, RHS, ResTSI);
          VD->setTypeSourceInfo(ResTSI);
          VD->setType(ResTSI->getType());
          VD->setInit(RHS);
          Sema::DeclGroupPtrTy VDPtrTy = m_Sema->ConvertDeclToDeclGroup(VD);
          // Transform the AST into a "sane" state. Replace the binary operator
          // with decl stmt, because the binop semantically is a decl with init.
          StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, BinOp->getLocStart(), 
                                                BinOp->getLocEnd());
          assert(!DS.isInvalid() && "Invalid DeclStmt.");
          *I = DS.take();
        }
      }
      return true; // returning false will abort the in-depth traversal.
    }
Exemplo n.º 2
0
 void Fix(CompoundStmt* CS) {
   if (!CS->size())
     return;
   typedef llvm::SmallVector<Stmt*, 32> Statements;
   Statements Stmts;
   Stmts.append(CS->body_begin(), CS->body_end());
   for (Statements::iterator I = Stmts.begin(); I != Stmts.end(); ++I) {
     if (!TraverseStmt(*I) && !m_HandledDecls.count(m_FoundDRE->getDecl())) {
       Sema::DeclGroupPtrTy VDPtrTy 
         = m_Sema->ConvertDeclToDeclGroup(m_FoundDRE->getDecl());
       StmtResult DS = m_Sema->ActOnDeclStmt(VDPtrTy, 
                                             m_FoundDRE->getLocStart(), 
                                             m_FoundDRE->getLocEnd());
       assert(!DS.isInvalid() && "Invalid DeclStmt.");
       I = Stmts.insert(I, DS.take());
       m_HandledDecls.insert(m_FoundDRE->getDecl());
     }
   }
   CS->setStmts(m_Sema->getASTContext(), Stmts.data(), Stmts.size());
 }
Exemplo n.º 3
0
/// \brief Parsing of declarative or executable OpenMP directives.
///
///       threadprivate-directive:
///         annot_pragma_openmp 'threadprivate' simple-variable-list
///         annot_pragma_openmp_end
///
///       parallel-directive:
///         annot_pragma_openmp 'parallel' {clause} annot_pragma_openmp_end
///
StmtResult Parser::ParseOpenMPDeclarativeOrExecutableDirective() {
  assert(Tok.is(tok::annot_pragma_openmp) && "Not an OpenMP directive!");
  ParenBraceBracketBalancer BalancerRAIIObj(*this);
  SmallVector<Expr *, 5> Identifiers;
  SmallVector<OMPClause *, 5> Clauses;
  SmallVector<llvm::PointerIntPair<OMPClause *, 1, bool>, NUM_OPENMP_CLAUSES>
                                               FirstClauses(NUM_OPENMP_CLAUSES);
  const unsigned ScopeFlags = Scope::FnScope | Scope::DeclScope |
                              Scope::OpenMPDirectiveScope;
  SourceLocation Loc = ConsumeToken(), EndLoc;
  OpenMPDirectiveKind DKind = Tok.isAnnotation() ?
                                  OMPD_unknown :
                                  getOpenMPDirectiveKind(PP.getSpelling(Tok));
  // Name of critical directive.
  DeclarationNameInfo DirName;
  StmtResult Directive = StmtError();

  switch (DKind) {
  case OMPD_threadprivate:
    ConsumeToken();
    if (!ParseOpenMPSimpleVarList(OMPD_threadprivate, Identifiers, false)) {
      // The last seen token is annot_pragma_openmp_end - need to check for
      // extra tokens.
      if (Tok.isNot(tok::annot_pragma_openmp_end)) {
        Diag(Tok, diag::warn_omp_extra_tokens_at_eol)
          << getOpenMPDirectiveName(OMPD_threadprivate);
        SkipUntil(tok::annot_pragma_openmp_end, StopBeforeMatch);
      }
      DeclGroupPtrTy Res =
        Actions.ActOnOpenMPThreadprivateDirective(Loc,
                                                  Identifiers);
      Directive = Actions.ActOnDeclStmt(Res, Loc, Tok.getLocation());
    }
    SkipUntil(tok::annot_pragma_openmp_end);
    break;
  case OMPD_parallel: {
    ConsumeToken();

    Actions.StartOpenMPDSABlock(DKind, DirName, Actions.getCurScope());

    while (Tok.isNot(tok::annot_pragma_openmp_end)) {
      OpenMPClauseKind CKind = Tok.isAnnotation() ?
                                  OMPC_unknown :
                                  getOpenMPClauseKind(PP.getSpelling(Tok));
      OMPClause *Clause = ParseOpenMPClause(DKind, CKind,
                                            !FirstClauses[CKind].getInt());
      FirstClauses[CKind].setInt(true);
      if (Clause) {
        FirstClauses[CKind].setPointer(Clause);
        Clauses.push_back(Clause);
      }

      // Skip ',' if any.
      if (Tok.is(tok::comma))
        ConsumeToken();
    }
    // End location of the directive.
    EndLoc = Tok.getLocation();
    // Consume final annot_pragma_openmp_end.
    ConsumeToken();

    StmtResult AssociatedStmt;
    bool CreateDirective = true;
    ParseScope OMPDirectiveScope(this, ScopeFlags);
    {
      // The body is a block scope like in Lambdas and Blocks.
      Sema::CompoundScopeRAII CompoundScope(Actions);
      Actions.ActOnCapturedRegionStart(Loc, getCurScope(), CR_OpenMP, 1);
      Actions.ActOnStartOfCompoundStmt();
      // Parse statement
      AssociatedStmt = ParseStatement();
      Actions.ActOnFinishOfCompoundStmt();
      if (!AssociatedStmt.isUsable()) {
        Actions.ActOnCapturedRegionError();
        CreateDirective = false;
      } else {
        AssociatedStmt = Actions.ActOnCapturedRegionEnd(AssociatedStmt.take());
        CreateDirective = AssociatedStmt.isUsable();
      }
    }
    if (CreateDirective)
      Directive = Actions.ActOnOpenMPExecutableDirective(DKind, Clauses,
                                                         AssociatedStmt.take(),
                                                         Loc, EndLoc);

    // Exit scope.
    Actions.EndOpenMPDSABlock(Directive.get());
    OMPDirectiveScope.Exit();
    }
    break;
  case OMPD_unknown:
    Diag(Tok, diag::err_omp_unknown_directive);
    SkipUntil(tok::annot_pragma_openmp_end);
    break;
  case OMPD_task:
  case NUM_OPENMP_DIRECTIVES:
    Diag(Tok, diag::err_omp_unexpected_directive)
      << getOpenMPDirectiveName(DKind);
    SkipUntil(tok::annot_pragma_openmp_end);
    break;
  }
  return Directive;
}
    Stmt* SynthesizeCheck(SourceLocation Loc, Expr* Arg) {
      assert(Arg && "Cannot call with Arg=0");
      ASTContext& Context = m_Sema.getASTContext();
      //copied from DynamicLookup.cpp
      // Lookup Sema type
      CXXRecordDecl* SemaRD
        = dyn_cast<CXXRecordDecl>(utils::Lookup::Named(&m_Sema, "Sema",
                                   utils::Lookup::Namespace(&m_Sema, "clang")));

      QualType SemaRDTy = Context.getTypeDeclType(SemaRD);
      Expr* VoidSemaArg = utils::Synthesize::CStyleCastPtrExpr(&m_Sema,SemaRDTy,
                                                             (uint64_t)&m_Sema);

      // Lookup Expr type
      CXXRecordDecl* ExprRD
        = dyn_cast<CXXRecordDecl>(utils::Lookup::Named(&m_Sema, "Expr",
                                   utils::Lookup::Namespace(&m_Sema, "clang")));

      QualType ExprRDTy = Context.getTypeDeclType(ExprRD);
      Expr* VoidExprArg = utils::Synthesize::CStyleCastPtrExpr(&m_Sema,ExprRDTy,
                                                               (uint64_t)Arg);

      Expr *args[] = {VoidSemaArg, VoidExprArg};

      Scope* S = m_Sema.getScopeForContext(m_Sema.CurContext);
      DeclarationName Name
        = &Context.Idents.get("cling__runtime__internal__throwNullDerefException");

      SourceLocation noLoc;
      LookupResult R(m_Sema, Name, noLoc, Sema::LookupOrdinaryName,
                   Sema::ForRedeclaration);
      m_Sema.LookupQualifiedName(R, Context.getTranslationUnitDecl());
      assert(!R.empty() && "Cannot find valuePrinterInternal::Select(...)");

      CXXScopeSpec CSS;
      Expr* UnresolvedLookup
        = m_Sema.BuildDeclarationNameExpr(CSS, R, /*ADL*/ false).take();

      Expr* call = m_Sema.ActOnCallExpr(S, UnresolvedLookup, noLoc,
                                        args, noLoc).take();
      // Check whether we can get the argument'value. If the argument is
      // null, throw an exception direclty. If the argument is not null
      // then ignore this argument and continue to deal with the next
      // argument with the nonnull attribute.
      bool Result = false;
      if (Arg->EvaluateAsBooleanCondition(Result, Context)) {
        if(!Result) {
          return call;
        }
        return Arg;
      }
      // The argument's value cannot be decided, so we add a UnaryOp
      // operation to check its value at runtime.
      ExprResult ER = m_Sema.ActOnUnaryOp(S, Loc, tok::exclaim, Arg);

      Decl* varDecl = 0;
      Stmt* varStmt = 0;
      Sema::FullExprArg FullCond(m_Sema.MakeFullExpr(ER.take()));
      StmtResult IfStmt = m_Sema.ActOnIfStmt(Loc, FullCond, varDecl,
                                             call, Loc, varStmt);
      return IfStmt.take();
    }