From: Bruno Ricci Date: Thu, 11 Jun 2020 10:53:47 +0000 (+0100) Subject: [clang][NFC] Various NFCs in CheckDefaultArgumentVisitor X-Git-Tag: llvmorg-12-init~3381 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0418005c0e2f280f0cdab9ad7b5a1a7bd03d9c10;p=platform%2Fupstream%2Fllvm.git [clang][NFC] Various NFCs in CheckDefaultArgumentVisitor Before the next patches do the following NFCs: - Make it a const visitor; CheckDefaultArgumentVisitor should really not modify the visited nodes. - clang-format - Take a reference to Sema instead of a pointer and pass it as the first argument to the constructor. This is for consistency with the other similar visitors. - Use range for loops when appropriate as per the style guide. - Use `const auto *" when appropriate as per the style guide. --- diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 26a5e12..e33df25 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -52,102 +52,100 @@ using namespace clang; //===----------------------------------------------------------------------===// namespace { - /// CheckDefaultArgumentVisitor - C++ [dcl.fct.default] Traverses - /// the default argument of a parameter to determine whether it - /// contains any ill-formed subexpressions. For example, this will - /// diagnose the use of local variables or parameters within the - /// default argument expression. - class CheckDefaultArgumentVisitor - : public StmtVisitor { - Expr *DefaultArg; - Sema *S; - - public: - CheckDefaultArgumentVisitor(Expr *defarg, Sema *s) - : DefaultArg(defarg), S(s) {} - - bool VisitExpr(Expr *Node); - bool VisitDeclRefExpr(DeclRefExpr *DRE); - bool VisitCXXThisExpr(CXXThisExpr *ThisE); - bool VisitLambdaExpr(LambdaExpr *Lambda); - bool VisitPseudoObjectExpr(PseudoObjectExpr *POE); - }; - - /// VisitExpr - Visit all of the children of this expression. - bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) { - bool IsInvalid = false; - for (Stmt *SubStmt : Node->children()) - IsInvalid |= Visit(SubStmt); - return IsInvalid; - } - - /// VisitDeclRefExpr - Visit a reference to a declaration, to - /// determine whether this declaration can be used in the default - /// argument expression. - bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(DeclRefExpr *DRE) { - NamedDecl *Decl = DRE->getDecl(); - if (ParmVarDecl *Param = dyn_cast(Decl)) { - // C++ [dcl.fct.default]p9 - // Default arguments are evaluated each time the function is - // called. The order of evaluation of function arguments is - // unspecified. Consequently, parameters of a function shall not - // be used in default argument expressions, even if they are not - // evaluated. Parameters of a function declared before a default - // argument expression are in scope and can hide namespace and - // class member names. - return S->Diag(DRE->getBeginLoc(), - diag::err_param_default_argument_references_param) - << Param->getDeclName() << DefaultArg->getSourceRange(); - } else if (VarDecl *VDecl = dyn_cast(Decl)) { - // C++ [dcl.fct.default]p7 - // Local variables shall not be used in default argument - // expressions. - if (VDecl->isLocalVarDecl()) - return S->Diag(DRE->getBeginLoc(), - diag::err_param_default_argument_references_local) - << VDecl->getDeclName() << DefaultArg->getSourceRange(); - } +/// CheckDefaultArgumentVisitor - C++ [dcl.fct.default] Traverses +/// the default argument of a parameter to determine whether it +/// contains any ill-formed subexpressions. For example, this will +/// diagnose the use of local variables or parameters within the +/// default argument expression. +class CheckDefaultArgumentVisitor + : public ConstStmtVisitor { + Sema &S; + const Expr *DefaultArg; - return false; - } +public: + CheckDefaultArgumentVisitor(Sema &S, const Expr *DefaultArg) + : S(S), DefaultArg(DefaultArg) {} + + bool VisitExpr(const Expr *Node); + bool VisitDeclRefExpr(const DeclRefExpr *DRE); + bool VisitCXXThisExpr(const CXXThisExpr *ThisE); + bool VisitLambdaExpr(const LambdaExpr *Lambda); + bool VisitPseudoObjectExpr(const PseudoObjectExpr *POE); +}; - /// VisitCXXThisExpr - Visit a C++ "this" expression. - bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(CXXThisExpr *ThisE) { - // C++ [dcl.fct.default]p8: - // The keyword this shall not be used in a default argument of a - // member function. - return S->Diag(ThisE->getBeginLoc(), - diag::err_param_default_argument_references_this) - << ThisE->getSourceRange(); +/// VisitExpr - Visit all of the children of this expression. +bool CheckDefaultArgumentVisitor::VisitExpr(const Expr *Node) { + bool IsInvalid = false; + for (const Stmt *SubStmt : Node->children()) + IsInvalid |= Visit(SubStmt); + return IsInvalid; +} + +/// VisitDeclRefExpr - Visit a reference to a declaration, to +/// determine whether this declaration can be used in the default +/// argument expression. +bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(const DeclRefExpr *DRE) { + const NamedDecl *Decl = DRE->getDecl(); + if (const auto *Param = dyn_cast(Decl)) { + // C++ [dcl.fct.default]p9 + // Default arguments are evaluated each time the function is + // called. The order of evaluation of function arguments is + // unspecified. Consequently, parameters of a function shall not + // be used in default argument expressions, even if they are not + // evaluated. Parameters of a function declared before a default + // argument expression are in scope and can hide namespace and + // class member names. + return S.Diag(DRE->getBeginLoc(), + diag::err_param_default_argument_references_param) + << Param->getDeclName() << DefaultArg->getSourceRange(); + } else if (const auto *VDecl = dyn_cast(Decl)) { + // C++ [dcl.fct.default]p7 + // Local variables shall not be used in default argument + // expressions. + if (VDecl->isLocalVarDecl()) + return S.Diag(DRE->getBeginLoc(), + diag::err_param_default_argument_references_local) + << VDecl->getDeclName() << DefaultArg->getSourceRange(); } - bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr(PseudoObjectExpr *POE) { - bool Invalid = false; - for (PseudoObjectExpr::semantics_iterator - i = POE->semantics_begin(), e = POE->semantics_end(); i != e; ++i) { - Expr *E = *i; + return false; +} - // Look through bindings. - if (OpaqueValueExpr *OVE = dyn_cast(E)) { - E = OVE->getSourceExpr(); - assert(E && "pseudo-object binding without source expression?"); - } +/// VisitCXXThisExpr - Visit a C++ "this" expression. +bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(const CXXThisExpr *ThisE) { + // C++ [dcl.fct.default]p8: + // The keyword this shall not be used in a default argument of a + // member function. + return S.Diag(ThisE->getBeginLoc(), + diag::err_param_default_argument_references_this) + << ThisE->getSourceRange(); +} - Invalid |= Visit(E); +bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr( + const PseudoObjectExpr *POE) { + bool Invalid = false; + for (const Expr *E : POE->semantics()) { + // Look through bindings. + if (const auto *OVE = dyn_cast(E)) { + E = OVE->getSourceExpr(); + assert(E && "pseudo-object binding without source expression?"); } - return Invalid; + + Invalid |= Visit(E); } + return Invalid; +} - bool CheckDefaultArgumentVisitor::VisitLambdaExpr(LambdaExpr *Lambda) { - // C++11 [expr.lambda.prim]p13: - // A lambda-expression appearing in a default argument shall not - // implicitly or explicitly capture any entity. - if (Lambda->capture_begin() == Lambda->capture_end()) - return false; +bool CheckDefaultArgumentVisitor::VisitLambdaExpr(const LambdaExpr *Lambda) { + // C++11 [expr.lambda.prim]p13: + // A lambda-expression appearing in a default argument shall not + // implicitly or explicitly capture any entity. + if (Lambda->capture_begin() == Lambda->capture_end()) + return false; - return S->Diag(Lambda->getBeginLoc(), diag::err_lambda_capture_default_arg); - } + return S.Diag(Lambda->getBeginLoc(), diag::err_lambda_capture_default_arg); } +} // namespace void Sema::ImplicitExceptionSpecification::CalledDecl(SourceLocation CallLoc, @@ -335,7 +333,7 @@ Sema::ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, } // Check that the default argument is well-formed - CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg, this); + CheckDefaultArgumentVisitor DefaultArgChecker(*this, DefaultArg); if (DefaultArgChecker.Visit(DefaultArg)) return Fail();