[cfe-commits] r49598 - in /cfe/trunk: include/clang/AST/Decl.h include/clang/AST/ExprCXX.h include/clang/Rewrite/RewriteRope.h lib/AST/Decl.cpp lib/Parse/ParseDecl.cpp lib/Sema/SemaDeclCXX.cpp test/Sema/default2.cpp

Chris Lattner sabre at nondot.org
Sat Apr 12 16:52:44 PDT 2008


Author: lattner
Date: Sat Apr 12 18:52:44 2008
New Revision: 49598

URL: http://llvm.org/viewvc/llvm-project?rev=49598&view=rev
Log:
Default argument cleanups and minor improvements, patch by
Doug Gregor!

Modified:
    cfe/trunk/include/clang/AST/Decl.h
    cfe/trunk/include/clang/AST/ExprCXX.h
    cfe/trunk/include/clang/Rewrite/RewriteRope.h
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/Sema/default2.cpp

Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Sat Apr 12 18:52:44 2008
@@ -352,6 +352,11 @@
     return ParamInfo[i];
   }
   void setParams(ParmVarDecl **NewParamInfo, unsigned NumParams);
+
+  /// getMinRequiredArguments - Returns the minimum number of arguments
+  /// needed to call this function. This may be fewer than the number of
+  /// function parameters, if some of the parameters have default
+  /// arguments (in C++).
   unsigned getMinRequiredArguments() const;
 
   QualType getResultType() const { 

Modified: cfe/trunk/include/clang/AST/ExprCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ExprCXX.h (original)
+++ cfe/trunk/include/clang/AST/ExprCXX.h Sat Apr 12 18:52:44 2008
@@ -149,7 +149,7 @@
     Expr *getExpr() { return Param->getDefaultArg(); }
 
     virtual SourceRange getSourceRange() const {
-      // Default argument expressions have no represntation in the
+      // Default argument expressions have no representation in the
       // source, so they have an empty source range.
       return SourceRange();
     }

Modified: cfe/trunk/include/clang/Rewrite/RewriteRope.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Rewrite/RewriteRope.h?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/include/clang/Rewrite/RewriteRope.h (original)
+++ cfe/trunk/include/clang/Rewrite/RewriteRope.h Sat Apr 12 18:52:44 2008
@@ -120,6 +120,7 @@
   RopeRefCountString *AllocBuffer;
   unsigned AllocOffs;
   enum { AllocChunkSize = 4080 };
+  
 public:
   RewriteRope() : CurSize(0), AllocBuffer(0), AllocOffs(AllocChunkSize) {}
   ~RewriteRope() { clear(); }

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Sat Apr 12 18:52:44 2008
@@ -425,7 +425,7 @@
 /// getMinRequiredArguments - Returns the minimum number of arguments
 /// needed to call this function. This may be fewer than the number of
 /// function parameters, if some of the parameters have default
-/// arguments.
+/// arguments (in C++).
 unsigned FunctionDecl::getMinRequiredArguments() const {
   unsigned NumRequiredArgs = getNumParams();
   while (NumRequiredArgs > 0

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Sat Apr 12 18:52:44 2008
@@ -1343,13 +1343,6 @@
         ConsumeToken();
         
         // Parse the default argument
-        // FIXME: For C++, name lookup from within the default argument 
-        // should be able to find parameter names, but we haven't put them
-        // in the scope. This means that we will accept ill-formed code
-        // such as:
-        //
-        //   int x;
-        //   void f(int x = x) { }
         ExprResult DefArgResult = ParseAssignmentExpression();
         if (DefArgResult.isInvalid) {
           SkipUntil(tok::comma, tok::r_paren, true, true);

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Sat Apr 12 18:52:44 2008
@@ -25,63 +25,68 @@
 // CheckDefaultArgumentVisitor
 //===----------------------------------------------------------------------===//
 
-/// CheckDefaultArgumentVisitor - 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 VISIBILITY_HIDDEN CheckDefaultArgumentVisitor 
-  : public StmtVisitor<CheckDefaultArgumentVisitor, bool>
-{
-  Sema *S;
-
-public:
-  explicit CheckDefaultArgumentVisitor(Sema *s) : S(s) {}
-
-  bool VisitExpr(Expr *Node);
-  bool VisitDeclRefExpr(DeclRefExpr *DRE);
-};
-
-/// VisitExpr - Visit all of the children of this expression.
-bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) {
-  bool IsInvalid = false;
-  for (Stmt::child_iterator first = Node->child_begin(), 
-                            last = Node->child_end();
-       first != last; ++first)
-    IsInvalid |= Visit(*first);
+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 VISIBILITY_HIDDEN CheckDefaultArgumentVisitor 
+    : public StmtVisitor<CheckDefaultArgumentVisitor, bool>
+  {
+    Expr *DefaultArg;
+    Sema *S;
+
+  public:
+    CheckDefaultArgumentVisitor(Expr *defarg, Sema *s) 
+      : DefaultArg(defarg), S(s) {}
+
+    bool VisitExpr(Expr *Node);
+    bool VisitDeclRefExpr(DeclRefExpr *DRE);
+  };
+
+  /// VisitExpr - Visit all of the children of this expression.
+  bool CheckDefaultArgumentVisitor::VisitExpr(Expr *Node) {
+    bool IsInvalid = false;
+    for (Stmt::child_iterator first = Node->child_begin(), 
+           last = Node->child_end();
+         first != last; ++first)
+      IsInvalid |= Visit(*first);
+
+    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) {
+    ValueDecl *Decl = DRE->getDecl();
+    if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(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->getSourceRange().getBegin(), 
+                     diag::err_param_default_argument_references_param,
+                     Param->getName(), DefaultArg->getSourceRange());
+    } else if (BlockVarDecl *BlockVar = dyn_cast<BlockVarDecl>(Decl)) {
+      // C++ [dcl.fct.default]p7
+      //   Local variables shall not be used in default argument
+      //   expressions.
+      return S->Diag(DRE->getSourceRange().getBegin(), 
+                     diag::err_param_default_argument_references_local,
+                     BlockVar->getName(), DefaultArg->getSourceRange());
+    }
 
-  return IsInvalid;
-}
+    // FIXME: when Clang has support for member functions, "this"
+    // will also need to be diagnosed.
 
-/// 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) {
-  ValueDecl *Decl = DRE->getDecl();
-  if (ParmVarDecl *Param = dyn_cast<ParmVarDecl>(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->getSourceRange().getBegin(), 
-                   diag::err_param_default_argument_references_param,
-                   Param->getName());
-  } else if (BlockVarDecl *BlockVar = dyn_cast<BlockVarDecl>(Decl)) {
-    // C++ [dcl.fct.default]p7
-    //   Local variables shall not be used in default argument
-    //   expressions.
-    return S->Diag(DRE->getSourceRange().getBegin(), 
-                   diag::err_param_default_argument_references_local,
-                   BlockVar->getName());
+    return false;
   }
-
-  // FIXME: when Clang has support for member functions, "this"
-  // will also need to be diagnosted.
-
-  return false;
 }
 
 /// ActOnParamDefaultArgument - Check whether the default argument
@@ -135,7 +140,7 @@
   //   declarator or abstract-declarator of a parameter-declaration.
 
   // Check that the default argument is well-formed
-  CheckDefaultArgumentVisitor DefaultArgChecker(this);
+  CheckDefaultArgumentVisitor DefaultArgChecker(DefaultArg.get(), this);
   if (DefaultArgChecker.Visit(DefaultArg.get()))
     return;
 

Modified: cfe/trunk/test/Sema/default2.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/default2.cpp?rev=49598&r1=49597&r2=49598&view=diff

==============================================================================
--- cfe/trunk/test/Sema/default2.cpp (original)
+++ cfe/trunk/test/Sema/default2.cpp Sat Apr 12 18:52:44 2008
@@ -25,3 +25,5 @@
    int i;
    extern void h2(int x = sizeof(i)); // expected-error {{default argument references local variable 'i' of enclosing function}}
 }
+
+void g2(int x, int y, int z = x + y); // expected-error {{default argument references parameter 'x'}} expected-error {{default argument references parameter 'y'}}





More information about the cfe-commits mailing list