DeclBase.cpp revision 72de6676bd30f9081ee4166bbe07b4c270258ce6
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";
9156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
9256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
9356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
9456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanbool Decl::CollectingStats(bool Enable) {
9556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (Enable)
9656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    StatSwitch = true;
9756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  return StatSwitch;
9856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
9956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
10056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::PrintStats() {
10156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "*** Decl Stats:\n");
10256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "  %d decls total.\n",
1034f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian          int(nFuncs+nVars+nParmVars+nOriginalParmVars+nFieldDecls+nSUC+nCXXSUC+
10456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+
10556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+
1068e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor              nAtDefsFieldDecls+nNamespaces+nOverFuncs));
10756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d namespace decls, %d each (%d bytes)\n",
10856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nNamespaces, (int)sizeof(NamespaceDecl),
10956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nNamespaces*sizeof(NamespaceDecl)));
1108e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  fprintf(stderr, "    %d overloaded function decls, %d each (%d bytes)\n",
1118e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor          nOverFuncs, (int)sizeof(OverloadedFunctionDecl),
1128e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor          int(nOverFuncs*sizeof(OverloadedFunctionDecl)));
11356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d function decls, %d each (%d bytes)\n",
11456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl)));
11556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d variable decls, %d each (%d bytes)\n",
11656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nVars, (int)sizeof(VarDecl),
11756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nVars*sizeof(VarDecl)));
11856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d parameter variable decls, %d each (%d bytes)\n",
11956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nParmVars, (int)sizeof(ParmVarDecl),
12056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nParmVars*sizeof(ParmVarDecl)));
1214f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian  fprintf(stderr, "    %d original parameter variable decls, %d each (%d bytes)\n",
1224f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian          nOriginalParmVars, (int)sizeof(ParmVarWithOriginalTypeDecl),
1234f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian          int(nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)));
12456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d field decls, %d each (%d bytes)\n",
12556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nFieldDecls, (int)sizeof(FieldDecl),
12656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nFieldDecls*sizeof(FieldDecl)));
12701e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  fprintf(stderr, "    %d @defs generated field decls, %d each (%d bytes)\n",
12801e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek          nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl),
12901e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek          int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl)));
13056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d struct/union/class decls, %d each (%d bytes)\n",
13156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nSUC, (int)sizeof(RecordDecl),
13256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nSUC*sizeof(RecordDecl)));
13355d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidis  fprintf(stderr, "    %d C++ struct/union/class decls, %d each (%d bytes)\n",
13455d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidis          nCXXSUC, (int)sizeof(CXXRecordDecl),
13555d71f9f4cf5f123db5d6dcfd20f3a8d5699c226Argyrios Kyrtzidis          int(nCXXSUC*sizeof(CXXRecordDecl)));
13656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d enum decls, %d each (%d bytes)\n",
13756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nEnumDecls, (int)sizeof(EnumDecl),
13856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nEnumDecls*sizeof(EnumDecl)));
13956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d enum constant decls, %d each (%d bytes)\n",
14056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nEnumConst, (int)sizeof(EnumConstantDecl),
14156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nEnumConst*sizeof(EnumConstantDecl)));
14256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d typedef decls, %d each (%d bytes)\n",
14356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl)));
14456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Objective-C decls...
14556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d interface decls, %d each (%d bytes)\n",
14656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl),
14756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nInterfaceDecls*sizeof(ObjCInterfaceDecl)));
14856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d instance variable decls, %d each (%d bytes)\n",
14956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nIvarDecls, (int)sizeof(ObjCIvarDecl),
15056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nIvarDecls*sizeof(ObjCIvarDecl)));
15156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d class decls, %d each (%d bytes)\n",
15256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nClassDecls, (int)sizeof(ObjCClassDecl),
15356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nClassDecls*sizeof(ObjCClassDecl)));
15456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d method decls, %d each (%d bytes)\n",
15556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nMethodDecls, (int)sizeof(ObjCMethodDecl),
15656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nMethodDecls*sizeof(ObjCMethodDecl)));
15756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d protocol decls, %d each (%d bytes)\n",
15856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nProtocolDecls, (int)sizeof(ObjCProtocolDecl),
15956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nProtocolDecls*sizeof(ObjCProtocolDecl)));
16056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d forward protocol decls, %d each (%d bytes)\n",
16156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl),
16256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)));
16356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d category decls, %d each (%d bytes)\n",
16456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nCategoryDecls, (int)sizeof(ObjCCategoryDecl),
16556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nCategoryDecls*sizeof(ObjCCategoryDecl)));
16656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
16756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
16856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl),
16956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl)));
17056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
17156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d class implementation decls, %d each (%d bytes)\n",
17256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl),
17356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)));
17456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
17556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d compatibility alias decls, %d each (%d bytes)\n",
17656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl),
17756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)));
17856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
17956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d property decls, %d each (%d bytes)\n",
18056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl),
18156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl)));
18256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
18356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "    %d property implementation decls, %d each (%d bytes)\n",
18456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl),
18556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)));
18656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
18756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  fprintf(stderr, "Total bytes = %d\n",
18856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman          int(nFuncs*sizeof(FunctionDecl)+
18956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+
1904f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian              nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)+
19156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+
19244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor              nCXXSUC*sizeof(CXXRecordDecl)+
19356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+
19456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nTypedef*sizeof(TypedefDecl)+
19556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nInterfaceDecls*sizeof(ObjCInterfaceDecl)+
19656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nIvarDecls*sizeof(ObjCIvarDecl)+
19756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nClassDecls*sizeof(ObjCClassDecl)+
19856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nMethodDecls*sizeof(ObjCMethodDecl)+
19956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nProtocolDecls*sizeof(ObjCProtocolDecl)+
20056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+
20156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nCategoryDecls*sizeof(ObjCCategoryDecl)+
20256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+
20356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+
20456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+
20556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+
20656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+
20756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nLinkageSpecDecl*sizeof(LinkageSpecDecl)+
20856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman              nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+
2098e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor              nNamespaces*sizeof(NamespaceDecl)+
2108e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor              nOverFuncs*sizeof(OverloadedFunctionDecl)));
21156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
21256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
21356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
21456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::addDeclKind(Kind k) {
21556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  switch (k) {
21656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Namespace:           nNamespaces++; break;
2178e9bebdea69c590dedfbf27374114cb76fe12fbdDouglas Gregor  case OverloadedFunction:  nOverFuncs++; break;
21856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Typedef:             nTypedef++; break;
21956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Function:            nFuncs++; break;
22056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Var:                 nVars++; break;
22156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ParmVar:             nParmVars++; break;
2224f5420d623831cceb567392067aa31ed2d3c37f6Fariborz Jahanian  case OriginalParmVar:     nOriginalParmVars++; break;
22356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case EnumConstant:        nEnumConst++; break;
22456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Field:               nFieldDecls++; break;
22535bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case Record:              nSUC++; break;
22656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case Enum:                nEnumDecls++; break;
22756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCInterface:       nInterfaceDecls++; break;
22856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCClass:           nClassDecls++; break;
22956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCMethod:          nMethodDecls++; break;
23056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProtocol:        nProtocolDecls++; break;
23156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCForwardProtocol: nForwardProtocolDecls++; break;
23256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCategory:        nCategoryDecls++; break;
23356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCIvar:            nIvarDecls++; break;
23401e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  case ObjCAtDefsField:     nAtDefsFieldDecls++; break;
23556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCImplementation:  nObjCImplementationDecls++; break;
23656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCategoryImpl:    nObjCCategoryImpl++; break;
23756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
23856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProperty:        nObjCPropertyDecl++; break;
23956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
24056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case LinkageSpec:         nLinkageSpecDecl++; break;
24156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case FileScopeAsm:        nFileScopeAsmDecl++; break;
24256ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff  case Block:               nBlockDecls++; break;
2434111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  case ImplicitParam:
24456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case TranslationUnit:     break;
245d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis
24635bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case CXXRecord:           nCXXSUC++; break;
247d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  // FIXME: Statistics for C++ decls.
24872c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  case TemplateTypeParm:
24972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  case NonTypeTemplateParm:
250d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  case CXXMethod:
251b48fe3812047e84164925c8938ce82be0624c40cDouglas Gregor  case CXXConstructor:
25242a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  case CXXDestructor:
2532f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor  case CXXConversion:
254d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  case CXXClassVar:
255d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis    break;
25656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
25756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
25856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
25956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
26056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// Decl Implementation
26156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
26256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
26356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// Out-of-line virtual method providing a home for Decl.
26456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli FriedmanDecl::~Decl() {
26556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs)
26656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return;
26756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
26856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  DeclAttrMapTy::iterator it = DeclAttrs->find(this);
26956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
27056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
27156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // release attributes.
27256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  delete it->second;
27356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  invalidateAttrs();
27456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
27556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
27656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::addAttr(Attr *NewAttr) {
27756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!DeclAttrs)
27856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    DeclAttrs = new DeclAttrMapTy();
27956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  Attr *&ExistingAttr = (*DeclAttrs)[this];
28156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  NewAttr->setNext(ExistingAttr);
28356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  ExistingAttr = NewAttr;
28456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  HasAttrs = true;
28656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
28756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::invalidateAttrs() {
28956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs) return;
29056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
29156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  HasAttrs = false;
29256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs)[this] = 0;
29356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  DeclAttrs->erase(this);
29456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
29556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (DeclAttrs->empty()) {
29656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    delete DeclAttrs;
29756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    DeclAttrs = 0;
29856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
29956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
30056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
30156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanconst Attr *Decl::getAttrs() const {
30256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs)
30356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return 0;
30456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
30556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  return (*DeclAttrs)[this];
30656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
30756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
30856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::swapAttrs(Decl *RHS) {
30956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  bool HasLHSAttr = this->HasAttrs;
31056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  bool HasRHSAttr = RHS->HasAttrs;
31156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
31256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Usually, neither decl has attrs, nothing to do.
31356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasLHSAttr && !HasRHSAttr) return;
31456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
31556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // If 'this' has no attrs, swap the other way.
31656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasLHSAttr)
31756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return RHS->swapAttrs(this);
31856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
31956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Handle the case when both decls have attrs.
32056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (HasRHSAttr) {
32156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
32256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return;
32356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
32456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
32556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Otherwise, LHS has an attr and RHS doesn't.
32656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
32756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs).erase(this);
32856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  this->HasAttrs = false;
32956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  RHS->HasAttrs = true;
33056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
33156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::Destroy(ASTContext& C) {
33456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
33556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    // Observe the unrolled recursion.  By setting N->NextDeclarator = 0x0
33756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    // within the loop, only the Destroy method for the first ScopedDecl
33856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    // will deallocate all of the ScopedDecls in a chain.
33956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    ScopedDecl* N = SD->getNextDeclarator();
34156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    while (N) {
34356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      ScopedDecl* Tmp = N->getNextDeclarator();
34456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      N->NextDeclarator = 0x0;
34556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      N->Destroy(C);
34656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      N = Tmp;
34756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    }
34856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
34956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
35056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  this->~Decl();
35156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  C.getAllocator().Deallocate((void *)this);
35256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
35356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
35442220c5432c141d47cc8ce786e472b49dc907378Argyrios KyrtzidisDecl *Decl::castFromDeclContext (const DeclContext *D) {
35542220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  return DeclContext::CastTo<Decl>(D);
35642220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis}
35742220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis
35842220c5432c141d47cc8ce786e472b49dc907378Argyrios KyrtzidisDeclContext *Decl::castToDeclContext(const Decl *D) {
35942220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  return DeclContext::CastTo<DeclContext>(D);
36042220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis}
36142220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis
36256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
36356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// DeclContext Implementation
36456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
36556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
36620bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidisconst DeclContext *DeclContext::getParent() const {
36720bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidis  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
36856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return SD->getDeclContext();
36920bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidis  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
370090276f5e164d491a1bb3f541bafdb394f5e6f04Steve Naroff    return BD->getParentContext();
37156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  else
37256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return NULL;
37356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
37477407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis
37577407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidisconst DeclContext *DeclContext::getLexicalParent() const {
37677407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
37777407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis    return SD->getLexicalDeclContext();
378051c13a4a99c651e404b4a3160e1173b427eee17Argyrios Kyrtzidis  return getParent();
37977407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis}
38044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
38144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// FIXME: We really want to use a DenseSet here to eliminate the
38244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// redundant storage of the declaration names, but (1) it doesn't give
38344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// us the ability to search based on DeclarationName, (2) we really
38444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// need something more like a DenseMultiSet, and (3) it's
3853fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// implemented in terms of DenseMap anyway. However, this data
3863fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// structure is really space-inefficient, so we'll have to do
3873fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// something.
3883fc749d899dfc194162128c1a88933148a39b68dDouglas Gregortypedef llvm::DenseMap<DeclarationName, std::vector<ScopedDecl*> >
3893fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  StoredDeclsMap;
39044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
39144b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::~DeclContext() {
39244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  unsigned Size = LookupPtr.getInt();
39344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (Size == LookupIsMap) {
39444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
39544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete Map;
39644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  } else {
3973fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
39844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete [] Array;
39944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
40044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
40144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
40244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregorvoid DeclContext::DestroyDecls(ASTContext &C) {
40344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  for (decl_iterator D = Decls.begin(); D != Decls.end(); ++D) {
40444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if ((*D)->getLexicalDeclContext() == this)
40544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      (*D)->Destroy(C);
40644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
40744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
40844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
409074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregorbool DeclContext::isTransparentContext() const {
410074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (DeclKind == Decl::Enum)
411074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return true; // FIXME: Check for C++0x scoped enums
412074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::LinkageSpec)
413074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return true;
414074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::Record || DeclKind == Decl::CXXRecord)
415bcbffc46f1ad3796c4582fa1e3a9113b5aa26061Douglas Gregor    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
416074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::Namespace)
417074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return false; // FIXME: Check for C++0x inline namespaces
418074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
419074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  return false;
420074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor}
421074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
4220701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext *DeclContext::getPrimaryContext() {
42344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  switch (DeclKind) {
42444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::TranslationUnit:
425074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::LinkageSpec:
426074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::Block:
42744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // There is only one DeclContext for these entities.
42844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
42944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
43044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Namespace:
43144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The original namespace is our primary context.
43244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
43344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
43444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Enum:
435074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor#if 0
436074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    // FIXME: See the comment for CXXRecord, below.
43744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The declaration associated with the enumeration type is our
43844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // primary context.
43944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return Context.getTypeDeclType(static_cast<EnumDecl*>(this))
44044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor             ->getAsEnumType()->getDecl();
441074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor#else
442074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return this;
443074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor#endif
44444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
44544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Record:
44644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::CXXRecord: {
44744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The declaration associated with the type is be our primary
44844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // context.
44944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#if 0
45044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: This is what we expect to do. However, it doesn't work
45144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // because ASTContext::setTagDefinition changes the result of
45244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Context.getTypeDeclType, meaning that our "primary" declaration
45344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // of a RecordDecl/CXXRecordDecl will change, and we won't be able
45444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // to find any values inserted into the earlier "primary"
45544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // declaration. We need better tracking of redeclarations and
45644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // definitions.
45744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    QualType Type = Context.getTypeDeclType(static_cast<RecordDecl*>(this));
45844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return Type->getAsRecordType()->getDecl();
45944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#else
46044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: This hack will work for now, because the declaration we
46144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // create when we're defining the record is the one we'll use as
46244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // the definition later.
46344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
46444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#endif
46544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
46644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
46744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCMethod:
46844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
46944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
47044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCInterface:
4710701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCProtocol:
4720701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategory:
47344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: Can Objective-C interfaces be forward-declared?
47444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
47544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
4760701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCImplementation:
4770701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategoryImpl:
4780701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    return this;
4790701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
48044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  default:
48144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
48244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor          "Unknown DeclContext kind");
48344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
48444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
48544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
48644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
48744b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext *DeclContext::getNextContext() {
48844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  switch (DeclKind) {
48944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::TranslationUnit:
49044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Enum:
49144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Record:
49244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::CXXRecord:
49344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCMethod:
49444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCInterface:
4950701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategory:
4960701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCProtocol:
4970701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCImplementation:
4980701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategoryImpl:
499074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::LinkageSpec:
500074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::Block:
50144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // There is only one DeclContext for these entities.
50244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return 0;
50344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
50444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Namespace:
50544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Return the next namespace
50644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
50744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
50844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  default:
50944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
51044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor          "Unknown DeclContext kind");
51144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return 0;
51244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
51344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
51444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
51544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregorvoid DeclContext::addDecl(ASTContext &Context, ScopedDecl *D, bool AllowLookup) {
51644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  Decls.push_back(D);
51744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (AllowLookup)
51844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    D->getDeclContext()->insert(Context, D);
51944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
52044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
521074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// buildLookup - Build the lookup data structure with all of the
522074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// declarations in DCtx (and any other contexts linked to it or
523074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// transparent contexts nested within it).
5240701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroffvoid DeclContext::buildLookup(DeclContext *DCtx) {
525074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  for (; DCtx; DCtx = DCtx->getNextContext()) {
5264f3b8f8ac2f8c89028a2f8793df0a7887df809d4Douglas Gregor    for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end();
5274f3b8f8ac2f8c89028a2f8793df0a7887df809d4Douglas Gregor         D != DEnd; ++D) {
528074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // Insert this declaration into the lookup structure
529074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      insertImpl(*D);
530074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
531074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // If this declaration is itself a transparent declaration context,
532074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // add its members (recursively).
533074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
534074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor        if (InnerCtx->isTransparentContext())
5350701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff          buildLookup(InnerCtx->getPrimaryContext());
536074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    }
537074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  }
538074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor}
539074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
54044b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::lookup_result
5410701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext::lookup(DeclarationName Name) {
5420701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  DeclContext *PrimaryContext = getPrimaryContext();
54344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (PrimaryContext != this)
5440701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    return PrimaryContext->lookup(Name);
54544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5463fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  /// If there is no lookup data structure, build one now by walking
54744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// all of the linked DeclContexts (in declaration order!) and
54844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// inserting their values.
549074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (LookupPtr.getPointer() == 0)
5500701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    buildLookup(this);
55144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
55244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (isLookupMap()) {
55344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
55444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap::iterator Pos = Map->find(Name);
5553fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (Pos != Map->end())
5563fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      return lookup_result(&Pos->second.front(),
5573fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor                           &Pos->second.front() + Pos->second.size());
5583fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    return lookup_result(0, 0);
55944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
56044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
56144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // We have a small array. Look into it.
56244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  unsigned Size = LookupPtr.getInt();
5633fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
564e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor  for (unsigned Idx = 0; Idx != Size; ++Idx)
56544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Array[Idx]->getDeclName() == Name) {
5663fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      unsigned Last = Idx + 1;
5673fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      while (Last != Size && Array[Last]->getDeclName() == Name)
5683fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        ++Last;
5693fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      return lookup_result(&Array[Idx], &Array[Last]);
57044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
57144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5723fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  return lookup_result(0, 0);
57344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
57444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
57544b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::lookup_const_result
5760701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext::lookup(DeclarationName Name) const {
5770701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  return const_cast<DeclContext*>(this)->lookup(Name);
57844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
57944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
58017a9b9e3ee75f5dbb4819cc8ebf40eec8015f84aDouglas Gregorconst DeclContext *DeclContext::getLookupContext() const {
58117a9b9e3ee75f5dbb4819cc8ebf40eec8015f84aDouglas Gregor  const DeclContext *Ctx = this;
58272de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor  // Skip through transparent contexts.
583ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor  while (Ctx->isTransparentContext())
584ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor    Ctx = Ctx->getParent();
585ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor  return Ctx;
586ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor}
587ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor
5883fc749d899dfc194162128c1a88933148a39b68dDouglas Gregorvoid DeclContext::insert(ASTContext &Context, ScopedDecl *D) {
5890701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  DeclContext *PrimaryContext = getPrimaryContext();
59044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (PrimaryContext != this) {
59144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    PrimaryContext->insert(Context, D);
59244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return;
59344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
59444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
59544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // If we already have a lookup data structure, perform the insertion
59644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // into it. Otherwise, be lazy and don't build that structure until
59744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // someone asks for it.
59844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (LookupPtr.getPointer())
59944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    insertImpl(D);
600074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
601074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
602074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // If we are a transparent context, insert into our parent context,
603074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // too. This operation is recursive.
604074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (isTransparentContext())
605074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    getParent()->insert(Context, D);
60644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
60744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6083fc749d899dfc194162128c1a88933148a39b68dDouglas Gregorvoid DeclContext::insertImpl(ScopedDecl *D) {
609074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // Skip unnamed declarations.
610074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (!D->getDeclName())
611074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return;
612074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
6133fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  bool MayBeRedeclaration = true;
6143fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor
61544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (!isLookupMap()) {
61644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    unsigned Size = LookupPtr.getInt();
61744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
61844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The lookup data is stored as an array. Search through the array
61944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // to find the insertion location.
6203fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    ScopedDecl **Array;
62144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Size == 0) {
6223fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array = new ScopedDecl*[LookupIsMap - 1];
62344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      LookupPtr.setPointer(Array);
62444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    } else {
6253fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array = static_cast<ScopedDecl **>(LookupPtr.getPointer());
62644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
62744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
62844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We always keep declarations of the same name next to each other
62944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // in the array, so that it is easy to return multiple results
6303fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    // from lookup().
6313fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    unsigned FirstMatch;
6323fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    for (FirstMatch = 0; FirstMatch != Size; ++FirstMatch)
6333fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      if (Array[FirstMatch]->getDeclName() == D->getDeclName())
634e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor        break;
63544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6363fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    unsigned InsertPos = FirstMatch;
6373fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (FirstMatch != Size) {
6383fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // We found another declaration with the same name. First
6393fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // determine whether this is a redeclaration of an existing
6403fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // declaration in this scope, in which case we will replace the
6413fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // existing declaration.
6423fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      unsigned LastMatch = FirstMatch;
6433fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      for (; LastMatch != Size; ++LastMatch) {
6443fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        if (Array[LastMatch]->getDeclName() != D->getDeclName())
6453fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          break;
6463fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor
6476ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        if (D->declarationReplaces(Array[LastMatch])) {
6483fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          // D is a redeclaration of an existing element in the
6493fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          // array. Replace that element with D.
6503fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          Array[LastMatch] = D;
6513fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          return;
6523fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        }
65344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      }
65444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6553fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // [FirstMatch, LastMatch) contains the set of declarations that
6563fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // have the same name as this declaration. Determine where the
6573fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // declaration D will be inserted into this range.
6583fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
6593fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch;
6603fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag)
6613fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch - 1;
6623fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      else
6633fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch;
66444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
66544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
66644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Size < LookupIsMap - 1) {
66744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      // The new declaration will fit in the array. Insert the new
66844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      // declaration at the position Match in the array.
6693fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      for (unsigned Idx = Size; Idx > InsertPos; --Idx)
67044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor       Array[Idx] = Array[Idx-1];
67144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6723fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array[InsertPos] = D;
67344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      LookupPtr.setInt(Size + 1);
67444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      return;
67544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
67644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
67744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We've reached capacity in this array. Create a map and copy in
67844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // all of the declarations that were stored in the array.
67944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = new StoredDeclsMap(16);
68044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    LookupPtr.setPointer(Map);
68144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    LookupPtr.setInt(LookupIsMap);
682e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor    for (unsigned Idx = 0; Idx != LookupIsMap - 1; ++Idx)
68344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      insertImpl(Array[Idx]);
68444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete [] Array;
68544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
68644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Fall through to perform insertion into the map.
6873fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    MayBeRedeclaration = false;
6883fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  }
68944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
69044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // Insert this declaration into the map.
69144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
69244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  StoredDeclsMap::iterator Pos = Map->find(D->getDeclName());
6933fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  if (Pos != Map->end()) {
6943fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (MayBeRedeclaration) {
6953fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // Determine if this declaration is actually a redeclaration.
6966ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor      std::vector<ScopedDecl *>::iterator Redecl
6976ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        = std::find_if(Pos->second.begin(), Pos->second.end(),
6986ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor                     std::bind1st(std::mem_fun(&ScopedDecl::declarationReplaces),
6996ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor                                  D));
7006ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor      if (Redecl != Pos->second.end()) {
7016ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        *Redecl = D;
7026ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        return;
7033fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      }
7043fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    }
70544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
70644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Put this declaration into the appropriate slot.
7073fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (D->getIdentifierNamespace() == Decl::IDNS_Tag || Pos->second.empty())
7083fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(D);
7093fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    else if (Pos->second.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
7103fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      ScopedDecl *TagD = Pos->second.back();
7113fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.back() = D;
7123fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(TagD);
7133fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    } else
7143fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(D);
71544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  } else {
7163fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    (*Map)[D->getDeclName()].push_back(D);
71744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
71844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
719