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. }
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()); }
/// \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(); }