[cfe-commits] r107675 - in /cfe/trunk: include/clang/AST/Stmt.h lib/AST/Stmt.cpp

Ted Kremenek kremenek at apple.com
Tue Jul 6 11:04:58 PDT 2010


Hi Tom,

Generally speaking we don't like to add these kind of specialized APIs to the main AST elements unless they have really widespread applicability.  If only one client is going to use it, it's usually better to keep these as static functions within a single .cpp source file and keep the core APIs svelt (which helps with conceptual clarity as well as compile times).  Once multiple clients have a common need for such functions, it's worth considering how they can be refactored into the global API (such as in the way you've done here).

On Jul 6, 2010, at 10:28 AM, Tom Care wrote:

> Author: tcare
> Date: Tue Jul  6 12:28:49 2010
> New Revision: 107675
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=107675&view=rev
> Log:
> Added several helper functions to Stmt to recursively check for different elements (macros, enum constants, etc).
> 
> Modified:
>    cfe/trunk/include/clang/AST/Stmt.h
>    cfe/trunk/lib/AST/Stmt.cpp
> 
> Modified: cfe/trunk/include/clang/AST/Stmt.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=107675&r1=107674&r2=107675&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/AST/Stmt.h (original)
> +++ cfe/trunk/include/clang/AST/Stmt.h Tue Jul  6 12:28:49 2010
> @@ -253,6 +253,25 @@
>   ///  within CFGs.
>   bool hasImplicitControlFlow() const;
> 
> +  /// contains* - Useful recursive methods to see if a statement contains an
> +  ///   element somewhere. Used in static analysis to reduce false positives.
> +  static bool containsMacro(const Stmt *S);
> +  static bool containsEnum(const Stmt *S);
> +  static bool containsZeroConstant(const Stmt *S);
> +  static bool containsOneConstant(const Stmt *S);
> +  template <class T> static bool containsStmt(const Stmt *S) {
> +    if (isa<T>(S))
> +        return true;
> +
> +    for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end(); ++I)
> +        if (const Stmt *child = *I)
> +          if (containsStmt<T>(child))
> +            return true;
> +
> +      return false;
> +  }
> +
> +
>   /// Child Iterators: All subclasses must implement child_begin and child_end
>   ///  to permit easy iteration over the substatements/subexpessions of an
>   ///  AST node.  This permits easy iteration over all nodes in the AST.
> 
> Modified: cfe/trunk/lib/AST/Stmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=107675&r1=107674&r2=107675&view=diff
> ==============================================================================
> --- cfe/trunk/lib/AST/Stmt.cpp (original)
> +++ cfe/trunk/lib/AST/Stmt.cpp Tue Jul  6 12:28:49 2010
> @@ -127,6 +127,72 @@
>   }
> }
> 
> +// Recursively find any substatements containing macros
> +bool Stmt::containsMacro(const Stmt *S) {
> +  if (S->getLocStart().isMacroID())
> +    return true;
> +
> +  if (S->getLocEnd().isMacroID())
> +    return true;
> +
> +  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end(); ++I)
> +    if (const Stmt *child = *I)
> +      if (containsMacro(child))
> +        return true;
> +
> +  return false;
> +}
> +
> +// Recursively find any substatements containing enum constants
> +bool Stmt::containsEnum(const Stmt *S) {
> +  const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(S);
> +
> +  if (DR && isa<EnumConstantDecl>(DR->getDecl()))
> +    return true;
> +
> +  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end(); ++I)
> +      if (const Stmt *child = *I)
> +        if (containsEnum(child))
> +          return true;
> +
> +  return false;
> +}
> +
> +bool Stmt::containsZeroConstant(const Stmt *S) {
> +  const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(S);
> +  if (IL && IL->getValue() == 0)
> +    return true;
> +
> +  const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(S);
> +  if (FL && FL->getValue().isZero())
> +    return true;
> +
> +  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end(); ++I)
> +    if (const Stmt *child = *I)
> +      if (containsZeroConstant(child))
> +        return true;
> +
> +  return false;
> +}
> +
> +bool Stmt::containsOneConstant(const Stmt *S) {
> +  const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(S);
> +  if (IL && IL->getValue() == 1)
> +    return true;
> +
> +  const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(S);
> +  const llvm::APFloat one(1.0);
> +  if (FL && FL->getValue().compare(one) == llvm::APFloat::cmpEqual)
> +    return true;
> +
> +  for (Stmt::const_child_iterator I = S->child_begin(); I != S->child_end(); ++I)
> +    if (const Stmt *child = *I)
> +      if (containsOneConstant(child))
> +        return true;
> +
> +  return false;
> +}
> +
> Expr *AsmStmt::getOutputExpr(unsigned i) {
>   return cast<Expr>(Exprs[i]);
> }
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits





More information about the cfe-commits mailing list