DeclBase.cpp revision 3e9704981d7691fdd44913bf1786e8d760d8a627
156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===//
256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//
356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//                     The LLVM Compiler Infrastructure
456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//
556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// This file is distributed under the University of Illinois Open Source
656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// License. See LICENSE.TXT for details.
756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//
856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//
1056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// This file implements the Decl and DeclContext classes.
1156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//
1256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
1356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
1456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman#include "clang/AST/DeclBase.h"
15e91593ef084479340582b2ba177b44be50a717b7Daniel Dunbar#include "clang/AST/DeclObjC.h"
16d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis#include "clang/AST/DeclCXX.h"
1756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman#include "clang/AST/ASTContext.h"
1844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#include "clang/AST/Type.h"
1956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman#include "llvm/ADT/DenseMap.h"
206ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor#include <algorithm>
216ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor#include <functional>
223fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor#include <vector>
2356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanusing namespace clang;
2456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
2556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
2656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//  Statistics
2756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
2856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
2956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// temporary statistics gathering
3056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nFuncs = 0;
3156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nVars = 0;
3256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nParmVars = 0;
334f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanianstatic unsigned nOriginalParmVars = 0;
3456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nSUC = 0;
3555d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidisstatic unsigned nCXXSUC = 0;
3656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nEnumConst = 0;
3756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nEnumDecls = 0;
3856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nNamespaces = 0;
398e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregorstatic unsigned nOverFuncs = 0;
4056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nTypedef = 0;
4156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nFieldDecls = 0;
4256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nInterfaceDecls = 0;
4356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nClassDecls = 0;
4456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nMethodDecls = 0;
4556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nProtocolDecls = 0;
4656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nForwardProtocolDecls = 0;
4756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nCategoryDecls = 0;
4856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nIvarDecls = 0;
4901e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenekstatic unsigned nAtDefsFieldDecls = 0;
5056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nObjCImplementationDecls = 0;
5156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nObjCCategoryImpl = 0;
5256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nObjCCompatibleAlias = 0;
5356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nObjCPropertyDecl = 0;
5456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nObjCPropertyImplDecl = 0;
5556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nLinkageSpecDecl = 0;
5656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic unsigned nFileScopeAsmDecl = 0;
5756ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroffstatic unsigned nBlockDecls = 0;
5856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
5956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic bool StatSwitch = false;
6056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
6156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// This keeps track of all decl attributes. Since so few decls have attrs, we
6256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// keep them in a hash map instead of wasting space in the Decl class.
6356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmantypedef llvm::DenseMap<const Decl*, Attr*> DeclAttrMapTy;
6456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
6556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanstatic DeclAttrMapTy *DeclAttrs = 0;
6656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
6756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanconst char *Decl::getDeclKindName() const {
6856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  switch (DeclKind) {
6956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  default: assert(0 && "Unknown decl kind!");
7056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Namespace:           return "Namespace";
718e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  case OverloadedFunction:  return "OverloadedFunction";
7256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Typedef:             return "Typedef";
7356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Function:            return "Function";
7456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Var:                 return "Var";
7556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ParmVar:             return "ParmVar";
764f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian  case OriginalParmVar:     return "OriginalParmVar";
7756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case EnumConstant:        return "EnumConstant";
7856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCIvar:            return "ObjCIvar";
7956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCInterface:       return "ObjCInterface";
80d40910b581b09c937a8c1fdcde9b8ec724398fb9Steve Naroff  case ObjCImplementation:  return "ObjCImplementation";
8156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCClass:           return "ObjCClass";
8256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCMethod:          return "ObjCMethod";
8356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProtocol:        return "ObjCProtocol";
84d40910b581b09c937a8c1fdcde9b8ec724398fb9Steve Naroff  case ObjCProperty:        return "ObjCProperty";
85d40910b581b09c937a8c1fdcde9b8ec724398fb9Steve Naroff  case ObjCPropertyImpl:    return "ObjCPropertyImpl";
8656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCForwardProtocol: return "ObjCForwardProtocol";
8735bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case Record:              return "Record";
8835bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case CXXRecord:           return "CXXRecord";
8956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Enum:                return "Enum";
9056ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff  case Block:               return "Block";
914c92fea0c838e0df95f7aa53c0c592b659ea1b10Steve Naroff  case Field:               return "Field";
9256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
9356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
9456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
950a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroffconst char *DeclContext::getDeclKindName() const {
960a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  switch (DeclKind) {
970a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  default: assert(0 && "Unknown decl kind!");
980a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::TranslationUnit:     return "TranslationUnit";
990a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Namespace:           return "Namespace";
1000a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::OverloadedFunction:  return "OverloadedFunction";
1010a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Typedef:             return "Typedef";
1020a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Function:            return "Function";
1030a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Var:                 return "Var";
1040a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ParmVar:             return "ParmVar";
1050a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::OriginalParmVar:     return "OriginalParmVar";
1060a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::EnumConstant:        return "EnumConstant";
1070a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCIvar:            return "ObjCIvar";
1080a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCInterface:       return "ObjCInterface";
1090a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCImplementation:  return "ObjCImplementation";
1100a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCClass:           return "ObjCClass";
1110a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCMethod:          return "ObjCMethod";
1120a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCProtocol:        return "ObjCProtocol";
1130a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCProperty:        return "ObjCProperty";
1140a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCPropertyImpl:    return "ObjCPropertyImpl";
1150a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::ObjCForwardProtocol: return "ObjCForwardProtocol";
1160a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Record:              return "Record";
1170a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::CXXRecord:           return "CXXRecord";
1180a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Enum:                return "Enum";
1190a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Block:               return "Block";
1200a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  case Decl::Field:               return "Field";
1210a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff  }
1220a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff}
1230a4739305a984ef9b821cedad5f4fe235eb6ef7dSteve Naroff
12456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanbool Decl::CollectingStats(bool Enable) {
12556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (Enable)
12656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    StatSwitch = true;
12756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  return StatSwitch;
12856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
12956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
13056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::PrintStats() {
13156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "*** Decl Stats:\n");
13256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "  %d decls total.\n",
1334f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian          int(nFuncs+nVars+nParmVars+nOriginalParmVars+nFieldDecls+nSUC+nCXXSUC+
13456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
13556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
1368e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor              nAtDefsFieldDecls+nNamespaces+nOverFuncs));
13756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d namespace decls, %d each (%d bytes)\n",
13856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nNamespaces, (int)sizeof(NamespaceDecl),
13956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nNamespaces*sizeof(NamespaceDecl)));
1408e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  fprintf(stderr, "    %d overloaded function decls, %d each (%d bytes)\n",
1418e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor          nOverFuncs, (int)sizeof(OverloadedFunctionDecl),
1428e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor          int(nOverFuncs*sizeof(OverloadedFunctionDecl)));
14356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d function decls, %d each (%d bytes)\n",
14456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
14556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d variable decls, %d each (%d bytes)\n",
14656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nVars, (int)sizeof(VarDecl),
14756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nVars*sizeof(VarDecl)));
14856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d parameter variable decls, %d each (%d bytes)\n",
14956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nParmVars, (int)sizeof(ParmVarDecl),
15056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nParmVars*sizeof(ParmVarDecl)));
1514f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian  fprintf(stderr, "    %d original parameter variable decls, %d each (%d bytes)\n",
1524f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian          nOriginalParmVars, (int)sizeof(ParmVarWithOriginalTypeDecl),
1534f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian          int(nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)));
15456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d field decls, %d each (%d bytes)\n",
15556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nFieldDecls, (int)sizeof(FieldDecl),
15656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nFieldDecls*sizeof(FieldDecl)));
15701e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  fprintf(stderr, "    %d @defs generated field decls, %d each (%d bytes)\n",
15801e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek          nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl),
15901e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek          int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl)));
16056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n",
16156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nSUC, (int)sizeof(RecordDecl),
16256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nSUC*sizeof(RecordDecl)));
16355d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidis  fprintf(stderr, "    %d C++ struct/union/class decls, %d each (%d bytes)\n",
16455d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidis          nCXXSUC, (int)sizeof(CXXRecordDecl),
16555d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidis          int(nCXXSUC*sizeof(CXXRecordDecl)));
16656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d enum decls, %d each (%d bytes)\n",
16756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nEnumDecls, (int)sizeof(EnumDecl),
16856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nEnumDecls*sizeof(EnumDecl)));
16956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d enum constant decls, %d each (%d bytes)\n",
17056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nEnumConst, (int)sizeof(EnumConstantDecl),
17156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nEnumConst*sizeof(EnumConstantDecl)));
17256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n",
17356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
17456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Objective-C decls...
17556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d interface decls, %d each (%d bytes)\n",
17656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
17756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
17856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d instance variable decls, %d each (%d bytes)\n",
17956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nIvarDecls, (int)sizeof(ObjCIvarDecl),
18056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nIvarDecls*sizeof(ObjCIvarDecl)));
18156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d class decls, %d each (%d bytes)\n",
18256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nClassDecls, (int)sizeof(ObjCClassDecl),
18356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nClassDecls*sizeof(ObjCClassDecl)));
18456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d method decls, %d each (%d bytes)\n",
18556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nMethodDecls, (int)sizeof(ObjCMethodDecl),
18656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nMethodDecls*sizeof(ObjCMethodDecl)));
18756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d protocol decls, %d each (%d bytes)\n",
18856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
18956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
19056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d forward protocol decls, %d each (%d bytes)\n",
19156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
19256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
19356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d category decls, %d each (%d bytes)\n",
19456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
19556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
19656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
19756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
19856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
19956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
20056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
20156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
20256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
20356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
20456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
20556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d compatibility alias decls, %d each (%d bytes)\n",
20656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
20756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
20856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
20956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d property decls, %d each (%d bytes)\n",
21056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
21156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
21256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
21356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d property implementation decls, %d each (%d bytes)\n",
21456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
21556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
21656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
21756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "Total bytes = %d\n",
21856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nFuncs*sizeof(FunctionDecl)+
21956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
2204f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian              nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)+
22156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
22244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor              nCXXSUC*sizeof(CXXRecordDecl)+
22356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
22456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nTypedef*sizeof(TypedefDecl)+
22556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
22656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nIvarDecls*sizeof(ObjCIvarDecl)+
22756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nClassDecls*sizeof(ObjCClassDecl)+
22856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nMethodDecls*sizeof(ObjCMethodDecl)+
22956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nProtocolDecls*sizeof(ObjCProtocolDecl)+
23056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
23156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nCategoryDecls*sizeof(ObjCCategoryDecl)+
23256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
23356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
23456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
23556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
23656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
23756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
23856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
2398e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor              nNamespaces*sizeof(NamespaceDecl)+
2408e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor              nOverFuncs*sizeof(OverloadedFunctionDecl)));
24156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
24256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
24356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
24456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::addDeclKind(Kind k) {
24556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  switch (k) {
24656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Namespace:           nNamespaces++; break;
2478e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  case OverloadedFunction:  nOverFuncs++; break;
24856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Typedef:             nTypedef++; break;
24956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Function:            nFuncs++; break;
25056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Var:                 nVars++; break;
25156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ParmVar:             nParmVars++; break;
2524f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian  case OriginalParmVar:     nOriginalParmVars++; break;
25356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case EnumConstant:        nEnumConst++; break;
25456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Field:               nFieldDecls++; break;
25535bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case Record:              nSUC++; break;
25656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Enum:                nEnumDecls++; break;
25709c4719788a5cea09897525e528fa00420f1677bSteve Naroff  case ObjCContainer:       break; // is abstract...no need to account for.
25856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCInterface:       nInterfaceDecls++; break;
25956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCClass:           nClassDecls++; break;
26056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCMethod:          nMethodDecls++; break;
26156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProtocol:        nProtocolDecls++; break;
26256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCForwardProtocol: nForwardProtocolDecls++; break;
26356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCategory:        nCategoryDecls++; break;
26456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCIvar:            nIvarDecls++; break;
26501e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  case ObjCAtDefsField:     nAtDefsFieldDecls++; break;
26656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCImplementation:  nObjCImplementationDecls++; break;
26756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCategoryImpl:    nObjCCategoryImpl++; break;
26856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
26956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProperty:        nObjCPropertyDecl++; break;
27056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
27156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case LinkageSpec:         nLinkageSpecDecl++; break;
27256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case FileScopeAsm:        nFileScopeAsmDecl++; break;
27356ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff  case Block:               nBlockDecls++; break;
2744111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  case ImplicitParam:
27556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case TranslationUnit:     break;
276d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis
27735bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case CXXRecord:           nCXXSUC++; break;
278d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  // FIXME: Statistics for C++ decls.
27972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  case TemplateTypeParm:
28072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  case NonTypeTemplateParm:
281d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  case CXXMethod:
282b48fe3812047e84164925c8938ce82be0624c40cDouglas Gregor  case CXXConstructor:
28342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  case CXXDestructor:
2842f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor  case CXXConversion:
285d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  case CXXClassVar:
286d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis    break;
28756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
28856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
28956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
29056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
29156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// Decl Implementation
29256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
29356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
2944afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorvoid Decl::setDeclContext(DeclContext *DC) {
2954afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (isOutOfSemaDC())
2964afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    delete getMultipleDC();
2974afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
2984afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  DeclCtx = reinterpret_cast<uintptr_t>(DC);
2994afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor}
3004afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
3014afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorvoid Decl::setLexicalDeclContext(DeclContext *DC) {
3024afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (DC == getLexicalDeclContext())
3034afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    return;
3044afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
3054afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (isInSemaDC()) {
3064afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    MultipleDC *MDC = new MultipleDC();
3074afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    MDC->SemanticDC = getDeclContext();
3084afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    MDC->LexicalDC = DC;
3094afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    DeclCtx = reinterpret_cast<uintptr_t>(MDC) | 0x1;
3104afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  } else {
3114afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    getMultipleDC()->LexicalDC = DC;
3124afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  }
3134afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor}
3144afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
31556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// Out-of-line virtual method providing a home for Decl.
31656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli FriedmanDecl::~Decl() {
3174afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (isOutOfSemaDC())
3184afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    delete getMultipleDC();
3194afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
32056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs)
32156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return;
32256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
32356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  DeclAttrMapTy::iterator it = DeclAttrs->find(this);
32456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
32556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
32656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // release attributes.
32756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  delete it->second;
32856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  invalidateAttrs();
32956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
33056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::addAttr(Attr *NewAttr) {
33256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!DeclAttrs)
33356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    DeclAttrs = new DeclAttrMapTy();
33456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  Attr *&ExistingAttr = (*DeclAttrs)[this];
33656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  NewAttr->setNext(ExistingAttr);
33856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  ExistingAttr = NewAttr;
33956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  HasAttrs = true;
34156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
34256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::invalidateAttrs() {
34456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs) return;
34556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  HasAttrs = false;
34756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs)[this] = 0;
34856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  DeclAttrs->erase(this);
34956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
35056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (DeclAttrs->empty()) {
35156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    delete DeclAttrs;
35256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    DeclAttrs = 0;
35356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
35456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
35556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
35656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanconst Attr *Decl::getAttrs() const {
35756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs)
35856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return 0;
35956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
36056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  return (*DeclAttrs)[this];
36156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
36256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
36356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::swapAttrs(Decl *RHS) {
36456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  bool HasLHSAttr = this->HasAttrs;
36556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  bool HasRHSAttr = RHS->HasAttrs;
36656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
36756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Usually, neither decl has attrs, nothing to do.
36856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasLHSAttr && !HasRHSAttr) return;
36956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
37056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // If 'this' has no attrs, swap the other way.
37156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasLHSAttr)
37256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return RHS->swapAttrs(this);
37356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
37456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Handle the case when both decls have attrs.
37556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (HasRHSAttr) {
37656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
37756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return;
37856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
37956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
38056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Otherwise, LHS has an attr and RHS doesn't.
38156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
38256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs).erase(this);
38356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  this->HasAttrs = false;
38456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  RHS->HasAttrs = true;
38556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
38656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
38756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
38856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::Destroy(ASTContext& C) {
389a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor#if 0
39000ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor  // FIXME: Once ownership is fully understood, we can enable this code
39100ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor  if (DeclContext *DC = dyn_cast<DeclContext>(this))
39200ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor    DC->decls_begin()->Destroy(C);
39356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
39400ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor  // Observe the unrolled recursion.  By setting N->NextDeclInScope = 0x0
3954afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  // within the loop, only the Destroy method for the first Decl
3964afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  // will deallocate all of the Decls in a chain.
3974afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
39800ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor  Decl* N = NextDeclInScope;
3994afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
4004afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  while (N) {
40100ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor    Decl* Tmp = N->NextDeclInScope;
40200ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor    N->NextDeclInScope = 0;
4034afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    N->Destroy(C);
4044afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    N = Tmp;
40556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
406a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor
40756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  this->~Decl();
4083e9704981d7691fdd44913bf1786e8d760d8a627Steve Naroff  C.Deallocate((void *)this);
40900ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor#endif
41056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
41156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
41242220c5432c141d47cc8ce786e472b49dc907378Argyrios KyrtzidisDecl *Decl::castFromDeclContext (const DeclContext *D) {
41342220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  return DeclContext::CastTo<Decl>(D);
41442220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis}
41542220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis
41642220c5432c141d47cc8ce786e472b49dc907378Argyrios KyrtzidisDeclContext *Decl::castToDeclContext(const Decl *D) {
41742220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  return DeclContext::CastTo<DeclContext>(D);
41842220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis}
41942220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis
42056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
42156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// DeclContext Implementation
42256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
42356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
42420bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidisconst DeclContext *DeclContext::getParent() const {
4254afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (const Decl *D = dyn_cast<Decl>(this))
4264afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    return D->getDeclContext();
4274afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
4284afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  return NULL;
42956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
43077407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis
43177407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidisconst DeclContext *DeclContext::getLexicalParent() const {
4324afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (const Decl *D = dyn_cast<Decl>(this))
4334afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    return D->getLexicalDeclContext();
4344afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
435051c13a4a99c651e404b4a3160e1173b427eee17Argyrios Kyrtzidis  return getParent();
43677407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis}
43744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
43844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// FIXME: We really want to use a DenseSet here to eliminate the
43944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// redundant storage of the declaration names, but (1) it doesn't give
44044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// us the ability to search based on DeclarationName, (2) we really
44144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// need something more like a DenseMultiSet, and (3) it's
4423fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// implemented in terms of DenseMap anyway. However, this data
4433fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// structure is really space-inefficient, so we'll have to do
4443fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// something.
4454afa39deaa245592977136d367251ee2c173dd8dDouglas Gregortypedef llvm::DenseMap<DeclarationName, std::vector<NamedDecl*> >
4463fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  StoredDeclsMap;
44744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
44844b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::~DeclContext() {
44944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  unsigned Size = LookupPtr.getInt();
45044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (Size == LookupIsMap) {
45144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
45244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete Map;
45344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  } else {
4544afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
45544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete [] Array;
45644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
45744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
45844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
45944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregorvoid DeclContext::DestroyDecls(ASTContext &C) {
46000ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor  for (decl_iterator D = decls_begin(); D != decls_end(); )
46100ad0ef8369ee65337ff29c8db3c1841a01102c4Douglas Gregor    (*D++)->Destroy(C);
46244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
46344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
464074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregorbool DeclContext::isTransparentContext() const {
465074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (DeclKind == Decl::Enum)
466074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return true; // FIXME: Check for C++0x scoped enums
467074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::LinkageSpec)
468074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return true;
469074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::Record || DeclKind == Decl::CXXRecord)
470bcbffc46f1ad3796c4582fa1e3a9113b5aa26061Douglas Gregor    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
471074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::Namespace)
472074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return false; // FIXME: Check for C++0x inline namespaces
473074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
474074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  return false;
475074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor}
476074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
4770701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext *DeclContext::getPrimaryContext() {
47844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  switch (DeclKind) {
47944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::TranslationUnit:
480074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::LinkageSpec:
481074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::Block:
48244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // There is only one DeclContext for these entities.
48344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
48444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
48544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Namespace:
48644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The original namespace is our primary context.
48744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
48844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
48944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Enum:
49044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Record:
4910b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor  case Decl::CXXRecord:
4920b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor    // If this is a tag type that has a definition or is currently
4930b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor    // being defined, that definition is our primary context.
4940b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor    if (TagType *TagT = cast_or_null<TagType>(cast<TagDecl>(this)->TypeForDecl))
4950b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor      if (TagT->isBeingDefined() ||
4960b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor          (TagT->getDecl() && TagT->getDecl()->isDefinition()))
4970b7a158d120ac8d78c114a823e17eedfec6b6658Douglas Gregor        return TagT->getDecl();
49844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
49944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
50044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCMethod:
50144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
50244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
50344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCInterface:
5040701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCProtocol:
5050701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategory:
50644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: Can Objective-C interfaces be forward-declared?
50744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
50844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5090701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCImplementation:
5100701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategoryImpl:
5110701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    return this;
5120701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
51344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  default:
51444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
51544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor          "Unknown DeclContext kind");
51644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
51744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
51844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
51944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
52044b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext *DeclContext::getNextContext() {
52144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  switch (DeclKind) {
52244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::TranslationUnit:
52344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Enum:
52444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Record:
52544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::CXXRecord:
52644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCMethod:
52744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCInterface:
5280701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategory:
5290701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCProtocol:
5300701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCImplementation:
5310701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategoryImpl:
532074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::LinkageSpec:
533074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::Block:
53444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // There is only one DeclContext for these entities.
53544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return 0;
53644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
53744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Namespace:
53844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Return the next namespace
53944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
54044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
54144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  default:
54244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
54344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor          "Unknown DeclContext kind");
54444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return 0;
54544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
54644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
54744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5484afa39deaa245592977136d367251ee2c173dd8dDouglas Gregorvoid DeclContext::addDecl(Decl *D) {
549a8cc8ce044e5d2589128f0c1a84e586cce743b27Douglas Gregor  assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context");
5506037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  assert(!D->NextDeclInScope && D != LastDecl &&
5516037fcba3431b47de1a994c9b286feac17894effDouglas Gregor         "Decl already inserted into a DeclContext");
5526037fcba3431b47de1a994c9b286feac17894effDouglas Gregor
5536037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  if (FirstDecl) {
5546037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    LastDecl->NextDeclInScope = D;
5556037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    LastDecl = D;
5566037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  } else {
5576037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    FirstDecl = LastDecl = D;
5586037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  }
5594afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor
5604afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
56140f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregor    ND->getDeclContext()->makeDeclVisibleInContext(ND);
56244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
56344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
564074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// buildLookup - Build the lookup data structure with all of the
565074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// declarations in DCtx (and any other contexts linked to it or
566074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// transparent contexts nested within it).
5670701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroffvoid DeclContext::buildLookup(DeclContext *DCtx) {
568074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  for (; DCtx; DCtx = DCtx->getNextContext()) {
5694f3b8f8ac2f8c89028a2f8793df0a7887df809d4Douglas Gregor    for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end();
5704f3b8f8ac2f8c89028a2f8793df0a7887df809d4Douglas Gregor         D != DEnd; ++D) {
571074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // Insert this declaration into the lookup structure
5724afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor      if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
57340f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregor        makeDeclVisibleInContextImpl(ND);
574074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
575074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // If this declaration is itself a transparent declaration context,
576074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // add its members (recursively).
577074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
578074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor        if (InnerCtx->isTransparentContext())
5790701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff          buildLookup(InnerCtx->getPrimaryContext());
580074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    }
581074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  }
582074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor}
583074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
58444b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::lookup_result
5850701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext::lookup(DeclarationName Name) {
5860701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  DeclContext *PrimaryContext = getPrimaryContext();
58744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (PrimaryContext != this)
5880701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    return PrimaryContext->lookup(Name);
58944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5903fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  /// If there is no lookup data structure, build one now by walking
59144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// all of the linked DeclContexts (in declaration order!) and
59244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// inserting their values.
593074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (LookupPtr.getPointer() == 0)
5940701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    buildLookup(this);
59544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
59644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (isLookupMap()) {
59744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
59844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap::iterator Pos = Map->find(Name);
5993fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (Pos != Map->end())
6003fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      return lookup_result(&Pos->second.front(),
6013fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor                           &Pos->second.front() + Pos->second.size());
6023fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    return lookup_result(0, 0);
60344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
60444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
60544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // We have a small array. Look into it.
60644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  unsigned Size = LookupPtr.getInt();
6074afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor  NamedDecl **Array = static_cast<NamedDecl**>(LookupPtr.getPointer());
608e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor  for (unsigned Idx = 0; Idx != Size; ++Idx)
60944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Array[Idx]->getDeclName() == Name) {
6103fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      unsigned Last = Idx + 1;
6113fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      while (Last != Size && Array[Last]->getDeclName() == Name)
6123fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        ++Last;
6133fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      return lookup_result(&Array[Idx], &Array[Last]);
61444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
61544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6163fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  return lookup_result(0, 0);
61744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
61844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
61944b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::lookup_const_result
6200701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext::lookup(DeclarationName Name) const {
6210701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  return const_cast<DeclContext*>(this)->lookup(Name);
62244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
62344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
62417a9b9e3ee75f5dbb4819cc8ebf40eec8015f84aDouglas Gregorconst DeclContext *DeclContext::getLookupContext() const {
62517a9b9e3ee75f5dbb4819cc8ebf40eec8015f84aDouglas Gregor  const DeclContext *Ctx = this;
62672de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor  // Skip through transparent contexts.
627ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor  while (Ctx->isTransparentContext())
628ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor    Ctx = Ctx->getParent();
629ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor  return Ctx;
630ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor}
631ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor
63240f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregorvoid DeclContext::makeDeclVisibleInContext(NamedDecl *D) {
6330701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  DeclContext *PrimaryContext = getPrimaryContext();
63444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (PrimaryContext != this) {
63540f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregor    PrimaryContext->makeDeclVisibleInContext(D);
63644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return;
63744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
63844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
63944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // If we already have a lookup data structure, perform the insertion
64044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // into it. Otherwise, be lazy and don't build that structure until
64144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // someone asks for it.
64244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (LookupPtr.getPointer())
64340f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregor    makeDeclVisibleInContextImpl(D);
644074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
645074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // If we are a transparent context, insert into our parent context,
646074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // too. This operation is recursive.
647074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (isTransparentContext())
64840f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregor    getParent()->makeDeclVisibleInContext(D);
64944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
65044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
65140f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregorvoid DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
652074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // Skip unnamed declarations.
653074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (!D->getDeclName())
654074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return;
655074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
6563fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  bool MayBeRedeclaration = true;
6573fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor
65844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (!isLookupMap()) {
65944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    unsigned Size = LookupPtr.getInt();
66044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
66144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The lookup data is stored as an array. Search through the array
66244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // to find the insertion location.
6634afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor    NamedDecl **Array;
66444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Size == 0) {
6654afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor      Array = new NamedDecl*[LookupIsMap - 1];
66644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      LookupPtr.setPointer(Array);
66744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    } else {
6684afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor      Array = static_cast<NamedDecl **>(LookupPtr.getPointer());
66944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
67044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
67144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We always keep declarations of the same name next to each other
67244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // in the array, so that it is easy to return multiple results
6733fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    // from lookup().
6743fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    unsigned FirstMatch;
6753fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    for (FirstMatch = 0; FirstMatch != Size; ++FirstMatch)
6763fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      if (Array[FirstMatch]->getDeclName() == D->getDeclName())
677e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor        break;
67844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6793fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    unsigned InsertPos = FirstMatch;
6803fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (FirstMatch != Size) {
6813fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // We found another declaration with the same name. First
6823fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // determine whether this is a redeclaration of an existing
6833fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // declaration in this scope, in which case we will replace the
6843fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // existing declaration.
6853fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      unsigned LastMatch = FirstMatch;
6863fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      for (; LastMatch != Size; ++LastMatch) {
6873fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        if (Array[LastMatch]->getDeclName() != D->getDeclName())
6883fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          break;
6893fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor
6906ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        if (D->declarationReplaces(Array[LastMatch])) {
6913fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          // D is a redeclaration of an existing element in the
6923fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          // array. Replace that element with D.
6933fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          Array[LastMatch] = D;
6943fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          return;
6953fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        }
69644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      }
69744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6983fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // [FirstMatch, LastMatch) contains the set of declarations that
6993fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // have the same name as this declaration. Determine where the
7003fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // declaration D will be inserted into this range.
7013fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
7023fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch;
7033fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag)
7043fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch - 1;
7053fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      else
7063fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch;
70744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
70844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
70944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Size < LookupIsMap - 1) {
71044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      // The new declaration will fit in the array. Insert the new
71144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      // declaration at the position Match in the array.
7123fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      for (unsigned Idx = Size; Idx > InsertPos; --Idx)
71344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor       Array[Idx] = Array[Idx-1];
71444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
7153fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array[InsertPos] = D;
71644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      LookupPtr.setInt(Size + 1);
71744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      return;
71844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
71944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
72044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We've reached capacity in this array. Create a map and copy in
72144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // all of the declarations that were stored in the array.
72244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = new StoredDeclsMap(16);
72344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    LookupPtr.setPointer(Map);
72444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    LookupPtr.setInt(LookupIsMap);
725e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor    for (unsigned Idx = 0; Idx != LookupIsMap - 1; ++Idx)
72640f4e69002af9623a1f959bd57b99afda186a6a7Douglas Gregor      makeDeclVisibleInContextImpl(Array[Idx]);
72744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete [] Array;
72844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
72944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Fall through to perform insertion into the map.
7303fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    MayBeRedeclaration = false;
7313fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  }
73244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
73344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // Insert this declaration into the map.
73444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
73544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  StoredDeclsMap::iterator Pos = Map->find(D->getDeclName());
7363fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  if (Pos != Map->end()) {
7373fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (MayBeRedeclaration) {
7383fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // Determine if this declaration is actually a redeclaration.
7394afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor      std::vector<NamedDecl *>::iterator Redecl
7406ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        = std::find_if(Pos->second.begin(), Pos->second.end(),
7414afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor                     std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
7426ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor                                  D));
7436ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor      if (Redecl != Pos->second.end()) {
7446ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        *Redecl = D;
7456ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        return;
7463fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      }
7473fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    }
74844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
74944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Put this declaration into the appropriate slot.
7503fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (D->getIdentifierNamespace() == Decl::IDNS_Tag || Pos->second.empty())
7513fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(D);
7523fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    else if (Pos->second.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
7534afa39deaa245592977136d367251ee2c173dd8dDouglas Gregor      NamedDecl *TagD = Pos->second.back();
7543fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.back() = D;
7553fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(TagD);
7563fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    } else
7573fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(D);
75844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  } else {
7593fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    (*Map)[D->getDeclName()].push_back(D);
76044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
76144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
762