[cfe-commits] r74027 - in /cfe/trunk: clang.xcodeproj/ clang.xcodeproj/project.pbxproj include/clang/AST/DeclCXX.h include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/SemaStmt.cpp test/CXX/class/class.local/p1.cpp test/CXX/class/class.local/p3.cpp

Ted Kremenek kremenek at apple.com
Tue Jun 23 17:44:54 PDT 2009


Hi Anders,

It would be really nice to drop clang.xcodeproj so that we aren't  
maintaining a separate Xcode project.  Is there a particular issue you  
have with the CMake generated Xcode project?

Ted

On Jun 23, 2009, at 5:10 PM, Anders Carlsson wrote:

> Author: andersca
> Date: Tue Jun 23 19:10:43 2009
> New Revision: 74027
>
> URL: http://llvm.org/viewvc/llvm-project?rev=74027&view=rev
> Log:
> [class.local] p1 and p3. Also, add back the xcodeproj file.
>
> Added:
>    cfe/trunk/clang.xcodeproj/   (props changed)
>      - copied from r73959, cfe/trunk/clang.xcodeproj/
>    cfe/trunk/clang.xcodeproj/project.pbxproj
>      - copied unchanged from r73959, cfe/trunk/clang.xcodeproj/ 
> project.pbxproj
>    cfe/trunk/test/CXX/class/class.local/p1.cpp
>    cfe/trunk/test/CXX/class/class.local/p3.cpp
> Modified:
>    cfe/trunk/include/clang/AST/DeclCXX.h
>    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>    cfe/trunk/lib/Sema/Sema.h
>    cfe/trunk/lib/Sema/SemaExpr.cpp
>    cfe/trunk/lib/Sema/SemaStmt.cpp
>
> Propchange: cfe/trunk/clang.xcodeproj/
>
> ------------------------------------------------------------------------------
> --- svn:ignore (added)
> +++ svn:ignore Tue Jun 23 19:10:43 2009
> @@ -0,0 +1,2 @@
> +*.mode1
> +*.pbxuser
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=74027&r1=74026&r2=74027&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Tue Jun 23 19:10:43 2009
> @@ -449,6 +449,15 @@
>   /// getDestructor - Returns the destructor decl for this class.
>   const CXXDestructorDecl *getDestructor(ASTContext &Context);
>
> +  /// isLocalClass - If the class is a local class [class.local],  
> returns
> +  /// the enclosing function declaration.
> +  const FunctionDecl *isLocalClass() const {
> +    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl> 
> (getDeclContext()))
> +      return RD->isLocalClass();
> +
> +    return dyn_cast<FunctionDecl>(getDeclContext());
> +  }
> +
>   /// viewInheritance - Renders and displays an inheritance diagram
>   /// for this C++ class and all of its base classes (transitively)  
> using
>   /// GraphViz.
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=74027&r1=74026&r2=74027&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Jun 23  
> 19:10:43 2009
> @@ -1603,6 +1603,12 @@
>   "anonymous %select{struct|union}0 cannot contain a "
>   "%select{private|protected}1 data member">;
>
> +// C++ local classes
> +def err_reference_to_local_var_in_enclosing_function : Error<
> +  "reference to local variable %0 declared in enclosed function %1">;
> +def note_local_variable_declared_here : Note<
> +  "%0 declared here">;
> +
> // C++ derived classes
> def err_base_clause_on_union : Error<"unions cannot have base  
> classes">;
> def err_base_must_be_class : Error<"base specifier must name a  
> class">;
>
> Modified: cfe/trunk/lib/Sema/Sema.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=74027&r1=74026&r2=74027&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/Sema.h (original)
> +++ cfe/trunk/lib/Sema/Sema.h Tue Jun 23 19:10:43 2009
> @@ -1377,9 +1377,10 @@
>                                                     bool  
> HasTrailingLParen,
>                                                     const  
> CXXScopeSpec &SS,
>                                                     bool  
> isAddressOfOperand);
> -  DeclRefExpr *BuildDeclRefExpr(NamedDecl *D, QualType Ty,  
> SourceLocation Loc,
> -                                bool TypeDependent, bool  
> ValueDependent,
> -                                const CXXScopeSpec *SS = 0);
> +  OwningExprResult BuildDeclRefExpr(NamedDecl *D, QualType Ty,
> +                                    SourceLocation Loc, bool  
> TypeDependent,
> +                                    bool ValueDependent,
> +                                    const CXXScopeSpec *SS = 0);
>   VarDecl *BuildAnonymousStructUnionMemberPath(FieldDecl *Field,
>                                     llvm::SmallVectorImpl<FieldDecl  
> *> &Path);
>   OwningExprResult
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=74027&r1=74026&r2=74027&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Jun 23 19:10:43 2009
> @@ -623,17 +623,36 @@
> /// BuildDeclRefExpr - Build either a DeclRefExpr or a
> /// QualifiedDeclRefExpr based on whether or not SS is a
> /// nested-name-specifier.
> -DeclRefExpr *
> +Sema::OwningExprResult
> Sema::BuildDeclRefExpr(NamedDecl *D, QualType Ty, SourceLocation Loc,
>                        bool TypeDependent, bool ValueDependent,
>                        const CXXScopeSpec *SS) {
> +
> +  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
> +    if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl> 
> (CurContext)) {
> +      if (const FunctionDecl *FD = MD->getParent()->isLocalClass()) {
> +        if (VD->hasLocalStorage() && VD->getDeclContext() !=  
> CurContext) {
> +          Diag(Loc,  
> diag::err_reference_to_local_var_in_enclosing_function)
> +            << D->getIdentifier() << FD->getDeclName();
> +          Diag(D->getLocation(),  
> diag::note_local_variable_declared_here)
> +            << D->getIdentifier();
> +          return ExprError();
> +        }
> +      }
> +    }
> +  }
> +
>   MarkDeclarationReferenced(Loc, D);
> +
> +  Expr *E;
>   if (SS && !SS->isEmpty()) {
> -    return new (Context) QualifiedDeclRefExpr(D, Ty, Loc,  
> TypeDependent,
> -                                              ValueDependent, SS- 
> >getRange(),
> +    E = new (Context) QualifiedDeclRefExpr(D, Ty, Loc, TypeDependent,
> +                                          ValueDependent, SS- 
> >getRange(),
>                   static_cast<NestedNameSpecifier *>(SS->getScopeRep 
> ()));
>   } else
> -    return new (Context) DeclRefExpr(D, Ty, Loc, TypeDependent,  
> ValueDependent);
> +    E = new (Context) DeclRefExpr(D, Ty, Loc, TypeDependent,  
> ValueDependent);
> +
> +  return Owned(E);
> }
>
> /// getObjectForAnonymousRecordDecl - Retrieve the (unnamed) field or
> @@ -968,7 +987,7 @@
>         // The pointer is type- and value-dependent if it points  
> into something
>         // dependent.
>         bool Dependent = DC->isDependentContext();
> -        return Owned(BuildDeclRefExpr(D, DType, Loc, Dependent,  
> Dependent, SS));
> +        return BuildDeclRefExpr(D, DType, Loc, Dependent,  
> Dependent, SS);
>       }
>     }
>   }
> @@ -1061,11 +1080,11 @@
>
>   // Make the DeclRefExpr or BlockDeclRefExpr for the decl.
>   if (OverloadedFunctionDecl *Ovl = dyn_cast<OverloadedFunctionDecl> 
> (D))
> -    return Owned(BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc,
> -                                  false, false, SS));
> +    return BuildDeclRefExpr(Ovl, Context.OverloadTy, Loc,
> +                           false, false, SS);
>   else if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
> -    return Owned(BuildDeclRefExpr(Template, Context.OverloadTy, Loc,
> -                                  false, false, SS));
> +    return BuildDeclRefExpr(Template, Context.OverloadTy, Loc,
> +                            false, false, SS);
>   ValueDecl *VD = cast<ValueDecl>(D);
>
>   // Check whether this declaration can be used. Note that we suppress
> @@ -1113,7 +1132,7 @@
>       QualType NoProtoType = T;
>       if (const FunctionProtoType *Proto = T->getAsFunctionProtoType 
> ())
>         NoProtoType = Context.getFunctionNoProtoType(Proto- 
> >getResultType());
> -      return Owned(BuildDeclRefExpr(VD, NoProtoType, Loc, false,  
> false, SS));
> +      return BuildDeclRefExpr(VD, NoProtoType, Loc, false, false,  
> SS);
>     }
>   }
>
> @@ -1194,8 +1213,8 @@
>     }
>   }
>
> -  return Owned(BuildDeclRefExpr(VD, VD->getType 
> ().getNonReferenceType(), Loc,
> -                                TypeDependent, ValueDependent, SS));
> +  return BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),  
> Loc,
> +                          TypeDependent, ValueDependent, SS);
> }
>
> Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc,
>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=74027&r1=74026&r2=74027&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Tue Jun 23 19:10:43 2009
> @@ -835,6 +835,7 @@
>
> Action::OwningStmtResult
> Sema::ActOnReturnStmt(SourceLocation ReturnLoc, FullExprArg rex) {
> +  bool RetValExprIsValid = !rex->isInvalid();
>   Expr *RetValExp = rex->takeAs<Expr>();
>   if (CurBlock)
>     return ActOnBlockReturnStmt(ReturnLoc, RetValExp);
>
> Added: cfe/trunk/test/CXX/class/class.local/p1.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.local/p1.cpp?rev=74027&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/CXX/class/class.local/p1.cpp (added)
> +++ cfe/trunk/test/CXX/class/class.local/p1.cpp Tue Jun 23 19:10:43  
> 2009
> @@ -0,0 +1,18 @@
> +// RUN: clang-cc -fsyntax-only -verify %s
> +
> +int x;
> +void f()
> +{
> +  static int s;
> +  int x; // expected-note{{'x' declared here}}
> +  extern int g();
> +
> +  struct local {
> +    int g() { return x; } // expected-error{{reference to local  
> variable 'x' declared in enclosed function 'f'}}
> +    int h() { return s; }
> +    int k() { return :: x; }
> +    int l() { return g(); }
> +  };
> +}
> +
> +local* p = 0; // expected-error{{unknown type name 'local'}}
>
> Added: cfe/trunk/test/CXX/class/class.local/p3.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/class/class.local/p3.cpp?rev=74027&view=auto
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- cfe/trunk/test/CXX/class/class.local/p3.cpp (added)
> +++ cfe/trunk/test/CXX/class/class.local/p3.cpp Tue Jun 23 19:10:43  
> 2009
> @@ -0,0 +1,30 @@
> +// RUN: clang-cc -fsyntax-only -verify %s
> +
> +void f1() {
> +  struct X {
> +    struct Y;
> +  };
> +
> +  struct X::Y {
> +    void f() {}
> +  };
> +}
> +
> +void f2() {
> +  struct X {
> +    struct Y;
> +
> +    struct Y {
> +      void f() {}
> +    };
> +  };
> +}
> +
> +// A class nested within a local class is a local class.
> +void f3(int a) { // expected-note{{'a' declared here}}
> +  struct X {
> +    struct Y {
> +      int f() { return a; } // expected-error{{reference to local  
> variable 'a' declared in enclosed function 'f3'}}
> +    };
> +  };
> +}
> \ No newline at end of file
>
>
> _______________________________________________
> 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