[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