Author: dgregor Date: Mon Feb 2 18:34:39 2009 New Revision: 63581 URL: http://llvm.org/viewvc/llvm-project?rev=63581&view=rev Log: Simplify the way in which we inject the names of tag definitions and elaborated-type-specifier declarations into outer scopes while retaining their proper lexical scope. This way is simpler and more consistent with the way DeclContexts work, and also fixes
http://llvm.org/bugs/show_bug.cgi?id=3430 Modified: cfe/trunk/lib/Sema/SemaDecl.cpp cfe/trunk/test/Sema/struct-decl.c Modified: cfe/trunk/lib/Sema/SemaDecl.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=63581&r1=63580&r2=63581&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) +++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Feb 2 18:34:39 2009 @@ -839,6 +839,11 @@ } } else if ((*Mem)->isImplicit()) { // Any implicit members are fine. + } else if (isa<TagDecl>(*Mem) && (*Mem)->getDeclContext() != Record) { + // This is a type that showed up in an + // elaborated-type-specifier inside the anonymous struct or + // union, but which actually declares a type outside of the + // anonymous struct or union. It's okay. } else if (RecordDecl *MemRecord = dyn_cast<RecordDecl>(*Mem)) { if (!MemRecord->isAnonymousStructOrUnion() && MemRecord->getDeclName()) { @@ -2791,7 +2796,6 @@ DeclContext *SearchDC = CurContext; DeclContext *DC = CurContext; - DeclContext *LexicalContext = CurContext; Decl *PrevDecl = 0; bool Invalid = false; @@ -2806,6 +2810,7 @@ } DC = static_cast<DeclContext*>(SS.getScopeRep()); + SearchDC = DC; // Look-up name inside 'foo::'. PrevDecl = dyn_cast_or_null<TagDecl>( LookupQualifiedName(DC, Name, LookupTagName).getAsDecl()); @@ -2944,9 +2949,8 @@ // Find the context where we'll be declaring the tag. // FIXME: We would like to maintain the current DeclContext as the // lexical context, - while (DC->isRecord()) - DC = DC->getParent(); - LexicalContext = DC; + while (SearchDC->isRecord()) + SearchDC = SearchDC->getParent(); // Find the scope where we'll be declaring the tag. while (S->isClassScope() || @@ -2972,7 +2976,7 @@ if (Kind == TagDecl::TK_enum) { // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // enum X { A, B, C } D; D should chain to X. - New = EnumDecl::Create(Context, DC, Loc, Name, + New = EnumDecl::Create(Context, SearchDC, Loc, Name, cast_or_null<EnumDecl>(PrevDecl)); // If this is an undefined enum, warn. if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum); @@ -2983,10 +2987,10 @@ // struct X { int A; } D; D should chain to X. if (getLangOptions().CPlusPlus) // FIXME: Look for a way to use RecordDecl for simple structs. - New = CXXRecordDecl::Create(Context, Kind, DC, Loc, Name, + New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, cast_or_null<CXXRecordDecl>(PrevDecl)); else - New = RecordDecl::Create(Context, Kind, DC, Loc, Name, + New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, cast_or_null<RecordDecl>(PrevDecl)); } @@ -3041,7 +3045,7 @@ // Set the lexical context. If the tag has a C++ scope specifier, the // lexical context will be different from the semantic context. - New->setLexicalDeclContext(LexicalContext); + New->setLexicalDeclContext(CurContext); if (TK == TK_Definition) New->startDefinition(); @@ -3049,18 +3053,9 @@ // If this has an identifier, add it to the scope stack. if (Name) { S = getNonFieldDeclScope(S); - - // Add it to the decl chain. - if (LexicalContext != CurContext) { - // FIXME: PushOnScopeChains should not rely on CurContext! - DeclContext *OldContext = CurContext; - CurContext = LexicalContext; - PushOnScopeChains(New, S); - CurContext = OldContext; - } else - PushOnScopeChains(New, S); + PushOnScopeChains(New, S); } else { - LexicalContext->addDecl(New); + CurContext->addDecl(New); } return New; Modified: cfe/trunk/test/Sema/struct-decl.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/struct-decl.c?rev=63581&r1=63580&r2=63581&view=diff ============================================================================== --- cfe/trunk/test/Sema/struct-decl.c (original) +++ cfe/trunk/test/Sema/struct-decl.c Mon Feb 2 18:34:39 2009 @@ -1,5 +1,4 @@ // RUN: clang -fsyntax-only -verify %s - // PR3459 struct bar { char n[1]; @@ -9,3 +8,17 @@ char name[(int)&((struct bar *)0)->n]; char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{fields must have a constant size}} }; + +// PR3430 +struct s { + struct st { + int v; + } *ts; +}; + +struct st; + +int foo() { + struct st *f; + return f->v + f[0].v; +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
