diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-03-14 21:19:51 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-03-14 21:19:51 +0000 |
commit | 7cbc558ffda5877ec4d2e432534e3d3d4ac10050 (patch) | |
tree | da94f5bf295b07b01b82017c6f96caf478ddb6f0 /lib/Sema/IdentifierResolver.cpp | |
parent | dc0f137295bc7ec5b231ff1842388f149f43c0c8 (diff) |
When synthesizing a label declaration based on a goto statement that
cannot yet be resolved, be sure to push the new label declaration into
the right place within the identifier chain. Otherwise, name lookup in
C++ gets confused when searching for names that are lexically closer
than the label. Fixes PR9463.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@127623 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/IdentifierResolver.cpp')
-rw-r--r-- | lib/Sema/IdentifierResolver.cpp | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/lib/Sema/IdentifierResolver.cpp b/lib/Sema/IdentifierResolver.cpp index 10856225ad..fcfc05380b 100644 --- a/lib/Sema/IdentifierResolver.cpp +++ b/lib/Sema/IdentifierResolver.cpp @@ -168,6 +168,39 @@ void IdentifierResolver::AddDecl(NamedDecl *D) { IDI->AddDecl(D); } +void IdentifierResolver::InsertDecl(iterator Pos, NamedDecl *D) { + if (Pos == iterator()) { + // Simple case: insert at the beginning of the list (which is the + // end of the stored vector). + AddDecl(D); + return; + } + + DeclarationName Name = D->getDeclName(); + void *Ptr = Name.getFETokenInfo<void>(); + + if (isDeclPtr(Ptr)) { + // There's only one element, and we want to insert before it in the list. + // Just create the storage for these identifiers and insert them in the + // opposite order we normally would. + assert(isDeclPtr(Ptr) && "Not a single declaration!"); + Name.setFETokenInfo(NULL); + IdDeclInfo *IDI = &(*IdDeclInfos)[Name]; + NamedDecl *PrevD = static_cast<NamedDecl*>(Ptr); + IDI->AddDecl(D); + IDI->AddDecl(PrevD); + return; + } + + // General case: insert the declaration at the appropriate point in the + // list, which already has at least two elements. + IdDeclInfo *IDI = toIdDeclInfo(Ptr); + if (Pos.isIterator()) + IDI->InsertDecl(Pos.getIterator(), D); + else + IDI->InsertDecl(IDI->decls_begin(), D); +} + /// RemoveDecl - Unlink the decl from its shadowed decl chain. /// The decl must already be part of the decl chain. void IdentifierResolver::RemoveDecl(NamedDecl *D) { |