1c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//===-- DeclContextInternals.h - DeclContext Representation -----*- C++ -*-===//
2c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//
3c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//                     The LLVM Compiler Infrastructure
4c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//
5c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor// This file is distributed under the University of Illinois Open Source
6c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor// License. See LICENSE.TXT for details.
7c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//
8c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//===----------------------------------------------------------------------===//
9c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//
10c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//  This file defines the data structures used in the implementation
11c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//  of DeclContext.
12c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//
13c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor//===----------------------------------------------------------------------===//
14c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor#ifndef LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
15c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor#define LLVM_CLANG_AST_DECLCONTEXTINTERNALS_H
16c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
17c0213f2691aed7c3f8f252e073b0b3913ee1c33cDouglas Gregor#include "clang/AST/Decl.h"
187745cab137b9d91205f13a7adaebe6ed801595f7Douglas Gregor#include "clang/AST/DeclCXX.h"
1930a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "clang/AST/DeclarationName.h"
207553ad2b7513fce1acd85658279da204fa99426fChandler Carruth#include "llvm/ADT/DenseMap.h"
2130a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/PointerUnion.h"
22c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor#include "llvm/ADT/SmallVector.h"
232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <algorithm>
24c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
25c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregornamespace clang {
26c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
270c01d18094100db92d38daa923c95661512db203John McCallclass DependentDiagnostic;
280c01d18094100db92d38daa923c95661512db203John McCall
29c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor/// StoredDeclsList - This is an array of decls optimized a common case of only
30c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor/// containing one entry.
31c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregorstruct StoredDeclsList {
32074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis
33074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  /// DeclsTy - When in vector form, this is what the Data pointer points to.
34686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<NamedDecl *, 4> DeclsTy;
35074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis
36074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  /// \brief The stored data, which will be either a pointer to a NamedDecl,
37074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  /// or a pointer to a vector.
38074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  llvm::PointerUnion<NamedDecl *, DeclsTy *> Data;
39c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
40c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregorpublic:
41074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  StoredDeclsList() {}
422cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
43c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  StoredDeclsList(const StoredDeclsList &RHS) : Data(RHS.Data) {
44074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    if (DeclsTy *RHSVec = RHS.getAsVector())
45074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Data = new DeclsTy(*RHSVec);
46c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
48c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  ~StoredDeclsList() {
49c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // If this is a vector-form, free the vector.
50074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    if (DeclsTy *Vector = getAsVector())
512cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      delete Vector;
52c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
54c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  StoredDeclsList &operator=(const StoredDeclsList &RHS) {
55074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    if (DeclsTy *Vector = getAsVector())
562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      delete Vector;
57c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    Data = RHS.Data;
58074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    if (DeclsTy *RHSVec = RHS.getAsVector())
59074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Data = new DeclsTy(*RHSVec);
60c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    return *this;
61c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  bool isNull() const { return Data.isNull(); }
641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
652cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  NamedDecl *getAsDecl() const {
66074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    return Data.dyn_cast<NamedDecl *>();
672cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
69074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  DeclsTy *getAsVector() const {
70074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    return Data.dyn_cast<DeclsTy *>();
712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
73c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  void setOnlyValue(NamedDecl *ND) {
742cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    assert(!getAsVector() && "Not inline");
75074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    Data = ND;
76074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    // Make sure that Data is a plain NamedDecl* so we can use its address
77074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    // at getLookupResult.
78074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    assert(*(NamedDecl **)&Data == ND &&
79074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis           "PointerUnion mangles the NamedDecl pointer!");
80c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
81c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
829f54ad4381370c6b771424b53d219e661d6d6706John McCall  void remove(NamedDecl *D) {
839f54ad4381370c6b771424b53d219e661d6d6706John McCall    assert(!isNull() && "removing from empty list");
849f54ad4381370c6b771424b53d219e661d6d6706John McCall    if (NamedDecl *Singleton = getAsDecl()) {
859f54ad4381370c6b771424b53d219e661d6d6706John McCall      assert(Singleton == D && "list is different singleton");
8660cfcecaf48e4310339dcfbdb0e3f0e6d2853855Chandler Carruth      (void)Singleton;
87074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Data = (NamedDecl *)0;
889f54ad4381370c6b771424b53d219e661d6d6706John McCall      return;
899f54ad4381370c6b771424b53d219e661d6d6706John McCall    }
909f54ad4381370c6b771424b53d219e661d6d6706John McCall
91074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vec = *getAsVector();
92074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
939f54ad4381370c6b771424b53d219e661d6d6706John McCall    assert(I != Vec.end() && "list does not contain decl");
949f54ad4381370c6b771424b53d219e661d6d6706John McCall    Vec.erase(I);
959f54ad4381370c6b771424b53d219e661d6d6706John McCall
96074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    assert(std::find(Vec.begin(), Vec.end(), D)
979f54ad4381370c6b771424b53d219e661d6d6706John McCall             == Vec.end() && "list still contains decl");
989f54ad4381370c6b771424b53d219e661d6d6706John McCall  }
999f54ad4381370c6b771424b53d219e661d6d6706John McCall
100bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  /// \brief Remove any declarations which were imported from an external
101bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  /// AST source.
102bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  void removeExternalDecls() {
103bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    if (isNull()) {
104bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      // Nothing to do.
105bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    } else if (NamedDecl *Singleton = getAsDecl()) {
106bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      if (Singleton->isFromASTFile())
107bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith        *this = StoredDeclsList();
108bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    } else {
109bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      DeclsTy &Vec = *getAsVector();
110bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
111bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith                               std::mem_fun(&Decl::isFromASTFile)),
112bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith                Vec.end());
113bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    }
114bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  }
115bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith
116c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// getLookupResult - Return an array of all the decls that this list
117c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// represents.
118074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  DeclContext::lookup_result getLookupResult() {
1192cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (isNull())
120a5fdd9ce694b1c2dbfd225cb6f55ef743d1ab562Douglas Gregor      return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
121a5fdd9ce694b1c2dbfd225cb6f55ef743d1ab562Douglas Gregor                                        DeclContext::lookup_iterator(0));
1221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1232cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    // If we have a single NamedDecl, return it.
1242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (getAsDecl()) {
125c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      assert(!isNull() && "Empty list isn't allowed");
1261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
127c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      // Data is a raw pointer to a NamedDecl*, return it.
128c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      void *Ptr = &Data;
129c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
130c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    }
1311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1322cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    assert(getAsVector() && "Must have a vector at this point");
133074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vector = *getAsVector();
1341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
135c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // Otherwise, we have a range result.
1366e48a2e2d677d9ba97b457e0af3494d6b6387380Argyrios Kyrtzidis    return DeclContext::lookup_result(Vector.begin(), Vector.end());
137c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
1381eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
139c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// HandleRedeclaration - If this is a redeclaration of an existing decl,
140c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// replace the old one with D and return true.  Otherwise return false.
141074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  bool HandleRedeclaration(NamedDecl *D) {
142c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // Most decls only have one entry in their list, special case it.
1432cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (NamedDecl *OldD = getAsDecl()) {
1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      if (!D->declarationReplaces(OldD))
145c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor        return false;
146c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      setOnlyValue(D);
147c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      return true;
148c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    }
1491eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
150c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // Determine if this declaration is actually a redeclaration.
151074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vec = *getAsVector();
152074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
1532cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor         OD != ODEnd; ++OD) {
154074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      NamedDecl *OldD = *OD;
1552cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      if (D->declarationReplaces(OldD)) {
156074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis        *OD = D;
1572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        return true;
1582cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      }
1592cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    }
1602cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
162c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
164c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// AddSubsequentDecl - This is called on the second and later decl when it is
165c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// not a redeclaration to merge it into the appropriate place in our list.
1661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///
167c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  void AddSubsequentDecl(NamedDecl *D) {
168c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // If this is the second decl added to the list, convert this to vector
169c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // form.
1702cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (NamedDecl *OldD = getAsDecl()) {
171074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      DeclsTy *VT = new DeclsTy();
172074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      VT->push_back(OldD);
173074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Data = VT;
174c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    }
1751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
176074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vec = *getAsVector();
177fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
178fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // Using directives end up in a special entry which contains only
179fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // other using directives, so all this logic is wasted for them.
180fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // But avoiding the logic wastes time in the far-more-common case
181fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // that we're *not* adding a new using directive.
182fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
183fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // Tag declarations always go at the end of the list so that an
184fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // iterator which points at the first tag will start a span of
185fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // decls that only contains tags.
1860d6b1640eb4d1a4a0203235cfdfcdaf3335af36dJohn McCall    if (D->hasTagIdentifierNamespace())
187074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.push_back(D);
188fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
189fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // Resolved using declarations go at the front of the list so that
190fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // they won't show up in other lookup results.  Unresolved using
191fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // declarations (which are always in IDNS_Using | IDNS_Ordinary)
192fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // follow that so that the using declarations will be contiguous.
193fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
194074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      DeclsTy::iterator I = Vec.begin();
195fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall      if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
196fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall        while (I != Vec.end() &&
197074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis               (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
198fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall          ++I;
199fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall      }
200074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.insert(I, D);
201fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
202fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // All other declarations go at the end of the list, but before any
203fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // tag declarations.  But we can be clever about tag declarations
204fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // because there can only ever be one in a scope.
205bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
206074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      NamedDecl *TagD = Vec.back();
207074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.back() = D;
208c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      Vec.push_back(TagD);
209c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    } else
210074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.push_back(D);
211c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
212c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor};
213c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
2140c01d18094100db92d38daa923c95661512db203John McCallclass StoredDeclsMap
2157553ad2b7513fce1acd85658279da204fa99426fChandler Carruth  : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
2160c01d18094100db92d38daa923c95661512db203John McCall
2170c01d18094100db92d38daa923c95661512db203John McCallpublic:
2180c01d18094100db92d38daa923c95661512db203John McCall  static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
2190c01d18094100db92d38daa923c95661512db203John McCall
2200c01d18094100db92d38daa923c95661512db203John McCallprivate:
2210c01d18094100db92d38daa923c95661512db203John McCall  friend class ASTContext; // walks the chain deleting these
2220c01d18094100db92d38daa923c95661512db203John McCall  friend class DeclContext;
2230c01d18094100db92d38daa923c95661512db203John McCall  llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
2240c01d18094100db92d38daa923c95661512db203John McCall};
225c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
2260c01d18094100db92d38daa923c95661512db203John McCallclass DependentStoredDeclsMap : public StoredDeclsMap {
2270c01d18094100db92d38daa923c95661512db203John McCallpublic:
2280c01d18094100db92d38daa923c95661512db203John McCall  DependentStoredDeclsMap() : FirstDiagnostic(0) {}
2290c01d18094100db92d38daa923c95661512db203John McCall
2300c01d18094100db92d38daa923c95661512db203John McCallprivate:
2310c01d18094100db92d38daa923c95661512db203John McCall  friend class DependentDiagnostic;
2320c01d18094100db92d38daa923c95661512db203John McCall  friend class DeclContext; // iterates over diagnostics
2330c01d18094100db92d38daa923c95661512db203John McCall
2340c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic *FirstDiagnostic;
2350c01d18094100db92d38daa923c95661512db203John McCall};
236c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
237c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor} // end namespace clang
238c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
2391eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#endif
240