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"
21b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith#include "llvm/ADT/PointerIntPair.h"
2230a2e16f6c27f888dd11eba6bbbae1e980078fcbChandler Carruth#include "llvm/ADT/PointerUnion.h"
23c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor#include "llvm/ADT/SmallVector.h"
242cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor#include <algorithm>
25c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
26c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregornamespace clang {
27c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
280c01d18094100db92d38daa923c95661512db203John McCallclass DependentDiagnostic;
290c01d18094100db92d38daa923c95661512db203John McCall
30b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith/// \brief An array of decls optimized for the common case of only containing
31b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith/// one entry.
32c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregorstruct StoredDeclsList {
33074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis
34b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  /// \brief When in vector form, this is what the Data pointer points to.
35686775deca8b8685eb90801495880e3abdd844c2Chris Lattner  typedef SmallVector<NamedDecl *, 4> DeclsTy;
36074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis
37b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  /// \brief A collection of declarations, with a flag to indicate if we have
38b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  /// further external declarations.
39b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  typedef llvm::PointerIntPair<DeclsTy *, 1, bool> DeclsAndHasExternalTy;
40b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith
41074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  /// \brief The stored data, which will be either a pointer to a NamedDecl,
42b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  /// or a pointer to a vector with a flag to indicate if there are further
43b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  /// external declarations.
44b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  llvm::PointerUnion<NamedDecl*, DeclsAndHasExternalTy> Data;
45c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
46c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregorpublic:
47074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  StoredDeclsList() {}
482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StoredDeclsList(StoredDeclsList &&RHS) : Data(RHS.Data) {
506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    RHS.Data = (NamedDecl *)nullptr;
51c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
53c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  ~StoredDeclsList() {
54c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // If this is a vector-form, free the vector.
55074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    if (DeclsTy *Vector = getAsVector())
562cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      delete Vector;
57c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
59651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  StoredDeclsList &operator=(StoredDeclsList &&RHS) {
60074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    if (DeclsTy *Vector = getAsVector())
612cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      delete Vector;
62c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    Data = RHS.Data;
636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines    RHS.Data = (NamedDecl *)nullptr;
64c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    return *this;
65c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  bool isNull() const { return Data.isNull(); }
681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  NamedDecl *getAsDecl() const {
70074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    return Data.dyn_cast<NamedDecl *>();
712cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
722cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
73b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  DeclsAndHasExternalTy getAsVectorAndHasExternal() const {
74b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    return Data.dyn_cast<DeclsAndHasExternalTy>();
75b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  }
76b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith
77074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  DeclsTy *getAsVector() const {
78b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    return getAsVectorAndHasExternal().getPointer();
79b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  }
80b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith
81b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  bool hasExternalDecls() const {
82b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    return getAsVectorAndHasExternal().getInt();
83b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  }
84b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith
85b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith  void setHasExternalDecls() {
86b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    if (DeclsTy *Vec = getAsVector())
87b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      Data = DeclsAndHasExternalTy(Vec, true);
88b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    else {
89b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      DeclsTy *VT = new DeclsTy();
90b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      if (NamedDecl *OldD = getAsDecl())
91b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith        VT->push_back(OldD);
92b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      Data = DeclsAndHasExternalTy(VT, true);
93b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    }
942cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor  }
952cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
96c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  void setOnlyValue(NamedDecl *ND) {
972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    assert(!getAsVector() && "Not inline");
98074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    Data = ND;
99074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    // Make sure that Data is a plain NamedDecl* so we can use its address
100074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    // at getLookupResult.
101074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    assert(*(NamedDecl **)&Data == ND &&
102074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis           "PointerUnion mangles the NamedDecl pointer!");
103c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
104c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
1059f54ad4381370c6b771424b53d219e661d6d6706John McCall  void remove(NamedDecl *D) {
1069f54ad4381370c6b771424b53d219e661d6d6706John McCall    assert(!isNull() && "removing from empty list");
1079f54ad4381370c6b771424b53d219e661d6d6706John McCall    if (NamedDecl *Singleton = getAsDecl()) {
1089f54ad4381370c6b771424b53d219e661d6d6706John McCall      assert(Singleton == D && "list is different singleton");
10960cfcecaf48e4310339dcfbdb0e3f0e6d2853855Chandler Carruth      (void)Singleton;
1106bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      Data = (NamedDecl *)nullptr;
1119f54ad4381370c6b771424b53d219e661d6d6706John McCall      return;
1129f54ad4381370c6b771424b53d219e661d6d6706John McCall    }
1139f54ad4381370c6b771424b53d219e661d6d6706John McCall
114074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vec = *getAsVector();
115074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy::iterator I = std::find(Vec.begin(), Vec.end(), D);
1169f54ad4381370c6b771424b53d219e661d6d6706John McCall    assert(I != Vec.end() && "list does not contain decl");
1179f54ad4381370c6b771424b53d219e661d6d6706John McCall    Vec.erase(I);
1189f54ad4381370c6b771424b53d219e661d6d6706John McCall
119074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    assert(std::find(Vec.begin(), Vec.end(), D)
1209f54ad4381370c6b771424b53d219e661d6d6706John McCall             == Vec.end() && "list still contains decl");
1219f54ad4381370c6b771424b53d219e661d6d6706John McCall  }
1229f54ad4381370c6b771424b53d219e661d6d6706John McCall
123bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  /// \brief Remove any declarations which were imported from an external
124bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  /// AST source.
125bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  void removeExternalDecls() {
126bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    if (isNull()) {
127bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      // Nothing to do.
128bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    } else if (NamedDecl *Singleton = getAsDecl()) {
129bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      if (Singleton->isFromASTFile())
130bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith        *this = StoredDeclsList();
131bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    } else {
132bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      DeclsTy &Vec = *getAsVector();
133bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith      Vec.erase(std::remove_if(Vec.begin(), Vec.end(),
134bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith                               std::mem_fun(&Decl::isFromASTFile)),
135bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith                Vec.end());
136b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      // Don't have any external decls any more.
137b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      Data = DeclsAndHasExternalTy(&Vec, false);
138bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    }
139bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith  }
140bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith
141c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// getLookupResult - Return an array of all the decls that this list
142c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// represents.
143074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  DeclContext::lookup_result getLookupResult() {
1442cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (isNull())
1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines      return DeclContext::lookup_result(DeclContext::lookup_iterator(nullptr),
1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines                                        DeclContext::lookup_iterator(nullptr));
1471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1482cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    // If we have a single NamedDecl, return it.
1492cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (getAsDecl()) {
150c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      assert(!isNull() && "Empty list isn't allowed");
1511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
152c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      // Data is a raw pointer to a NamedDecl*, return it.
153c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      void *Ptr = &Data;
154c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      return DeclContext::lookup_result((NamedDecl**)Ptr, (NamedDecl**)Ptr+1);
155c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    }
1561eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
1572cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    assert(getAsVector() && "Must have a vector at this point");
158074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vector = *getAsVector();
1591eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
160c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // Otherwise, we have a range result.
1616e48a2e2d677d9ba97b457e0af3494d6b6387380Argyrios Kyrtzidis    return DeclContext::lookup_result(Vector.begin(), Vector.end());
162c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
1631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
164c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// HandleRedeclaration - If this is a redeclaration of an existing decl,
165c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// replace the old one with D and return true.  Otherwise return false.
166074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis  bool HandleRedeclaration(NamedDecl *D) {
167c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // Most decls only have one entry in their list, special case it.
1682cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (NamedDecl *OldD = getAsDecl()) {
1692cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      if (!D->declarationReplaces(OldD))
170c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor        return false;
171c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      setOnlyValue(D);
172c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      return true;
173c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    }
1741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
175c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // Determine if this declaration is actually a redeclaration.
176074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vec = *getAsVector();
177074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    for (DeclsTy::iterator OD = Vec.begin(), ODEnd = Vec.end();
1782cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor         OD != ODEnd; ++OD) {
179074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      NamedDecl *OldD = *OD;
1802cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      if (D->declarationReplaces(OldD)) {
181074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis        *OD = D;
1822cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor        return true;
1832cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor      }
1842cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    }
1852cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor
1862cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    return false;
187c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
1881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
189c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// AddSubsequentDecl - This is called on the second and later decl when it is
190c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  /// not a redeclaration to merge it into the appropriate place in our list.
1911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  ///
192c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  void AddSubsequentDecl(NamedDecl *D) {
193b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith    assert(!isNull() && "don't AddSubsequentDecl when we have no decls");
194b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith
195c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // If this is the second decl added to the list, convert this to vector
196c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    // form.
1972cf2634ffdb4f7c8d46cef3f8e60a55993f1c57aDouglas Gregor    if (NamedDecl *OldD = getAsDecl()) {
198074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      DeclsTy *VT = new DeclsTy();
199074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      VT->push_back(OldD);
200b7165589b2eafc4b48d09a5914e21604ae580256Richard Smith      Data = DeclsAndHasExternalTy(VT, false);
201c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    }
2021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
203074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis    DeclsTy &Vec = *getAsVector();
204fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
205fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // Using directives end up in a special entry which contains only
206fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // other using directives, so all this logic is wasted for them.
207fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // But avoiding the logic wastes time in the far-more-common case
208fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // that we're *not* adding a new using directive.
209fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
210fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // Tag declarations always go at the end of the list so that an
211fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // iterator which points at the first tag will start a span of
212fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // decls that only contains tags.
2130d6b1640eb4d1a4a0203235cfdfcdaf3335af36dJohn McCall    if (D->hasTagIdentifierNamespace())
214074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.push_back(D);
215fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
216fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // Resolved using declarations go at the front of the list so that
217fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // they won't show up in other lookup results.  Unresolved using
218fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // declarations (which are always in IDNS_Using | IDNS_Ordinary)
219fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // follow that so that the using declarations will be contiguous.
220fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    else if (D->getIdentifierNamespace() & Decl::IDNS_Using) {
221074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      DeclsTy::iterator I = Vec.begin();
222fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall      if (D->getIdentifierNamespace() != Decl::IDNS_Using) {
223fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall        while (I != Vec.end() &&
224074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis               (*I)->getIdentifierNamespace() == Decl::IDNS_Using)
225fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall          ++I;
226fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall      }
227074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.insert(I, D);
228fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall
229fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // All other declarations go at the end of the list, but before any
230fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // tag declarations.  But we can be clever about tag declarations
231fda8e12774921e3cac3ebcba1148bcf4479ddd7aJohn McCall    // because there can only ever be one in a scope.
232bbcd0f3ba215d5a8857b224e32b0330586a00dc6Richard Smith    } else if (!Vec.empty() && Vec.back()->hasTagIdentifierNamespace()) {
233074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      NamedDecl *TagD = Vec.back();
234074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.back() = D;
235c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor      Vec.push_back(TagD);
236c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor    } else
237074dcc8ef8c5df7a155c85648e8eae786bee6cabArgyrios Kyrtzidis      Vec.push_back(D);
238c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor  }
239c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor};
240c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
2410c01d18094100db92d38daa923c95661512db203John McCallclass StoredDeclsMap
2427553ad2b7513fce1acd85658279da204fa99426fChandler Carruth  : public llvm::SmallDenseMap<DeclarationName, StoredDeclsList, 4> {
2430c01d18094100db92d38daa923c95661512db203John McCall
2440c01d18094100db92d38daa923c95661512db203John McCallpublic:
2450c01d18094100db92d38daa923c95661512db203John McCall  static void DestroyAll(StoredDeclsMap *Map, bool Dependent);
2460c01d18094100db92d38daa923c95661512db203John McCall
2470c01d18094100db92d38daa923c95661512db203John McCallprivate:
2480c01d18094100db92d38daa923c95661512db203John McCall  friend class ASTContext; // walks the chain deleting these
2490c01d18094100db92d38daa923c95661512db203John McCall  friend class DeclContext;
2500c01d18094100db92d38daa923c95661512db203John McCall  llvm::PointerIntPair<StoredDeclsMap*, 1> Previous;
2510c01d18094100db92d38daa923c95661512db203John McCall};
252c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
2530c01d18094100db92d38daa923c95661512db203John McCallclass DependentStoredDeclsMap : public StoredDeclsMap {
2540c01d18094100db92d38daa923c95661512db203John McCallpublic:
2556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  DependentStoredDeclsMap() : FirstDiagnostic(nullptr) {}
2560c01d18094100db92d38daa923c95661512db203John McCall
2570c01d18094100db92d38daa923c95661512db203John McCallprivate:
2580c01d18094100db92d38daa923c95661512db203John McCall  friend class DependentDiagnostic;
2590c01d18094100db92d38daa923c95661512db203John McCall  friend class DeclContext; // iterates over diagnostics
2600c01d18094100db92d38daa923c95661512db203John McCall
2610c01d18094100db92d38daa923c95661512db203John McCall  DependentDiagnostic *FirstDiagnostic;
2620c01d18094100db92d38daa923c95661512db203John McCall};
263c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
264c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor} // end namespace clang
265c2ee10d79f70036af652a395ac1f8273f3d04e12Douglas Gregor
2661eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump#endif
267