DeclBase.cpp revision a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0
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;
22709c4719788a5cea09897525e528fa00420f1677bSteve Naroff  case ObjCContainer:       break; // is abstract...no need to account for.
22856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCInterface:       nInterfaceDecls++; break;
22956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCClass:           nClassDecls++; break;
23056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCMethod:          nMethodDecls++; break;
23156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProtocol:        nProtocolDecls++; break;
23256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCForwardProtocol: nForwardProtocolDecls++; break;
23356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCategory:        nCategoryDecls++; break;
23456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCIvar:            nIvarDecls++; break;
23501e6779faca1e3a3164c697d6e2dfee0881a6981Ted Kremenek  case ObjCAtDefsField:     nAtDefsFieldDecls++; break;
23656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCImplementation:  nObjCImplementationDecls++; break;
23756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCategoryImpl:    nObjCCategoryImpl++; break;
23856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCCompatibleAlias: nObjCCompatibleAlias++; break;
23956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCProperty:        nObjCPropertyDecl++; break;
24056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case ObjCPropertyImpl:    nObjCPropertyImplDecl++; break;
24156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case LinkageSpec:         nLinkageSpecDecl++; break;
24256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case FileScopeAsm:        nFileScopeAsmDecl++; break;
24356ee6896f2efebffb4a2cce5a7610cdf1eddbbbeSteve Naroff  case Block:               nBlockDecls++; break;
2444111024be81e7c0525e42dadcc126d27e5bf2425Chris Lattner  case ImplicitParam:
24556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  case TranslationUnit:     break;
246d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis
24735bc0821c4f80041724cd4c5c4889b2581546a41Argyrios Kyrtzidis  case CXXRecord:           nCXXSUC++; break;
248d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  // FIXME: Statistics for C++ decls.
24972c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  case TemplateTypeParm:
25072c3f314d92d65c050ee1c07b7753623c044d6c7Douglas Gregor  case NonTypeTemplateParm:
251d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  case CXXMethod:
252b48fe3812047e84164925c8938ce82be0624c40cDouglas Gregor  case CXXConstructor:
25342a552f8200ba5948661aee0106fce0c04e39818Douglas Gregor  case CXXDestructor:
2542f1bc5285ccd40f411af5f5993f013e27e74ab78Douglas Gregor  case CXXConversion:
255d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis  case CXXClassVar:
256d3bb44f0f1a83cb208d3e61ee80afe6a4d20d2d8Argyrios Kyrtzidis    break;
25756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
25856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
25956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
26056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
26156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// Decl Implementation
26256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
26356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
26456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// Out-of-line virtual method providing a home for Decl.
26556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli FriedmanDecl::~Decl() {
26656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs)
26756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return;
26856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
26956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  DeclAttrMapTy::iterator it = DeclAttrs->find(this);
27056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  assert(it != DeclAttrs->end() && "No attrs found but HasAttrs is true!");
27156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
27256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // release attributes.
27356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  delete it->second;
27456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  invalidateAttrs();
27556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
27656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
27756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::addAttr(Attr *NewAttr) {
27856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!DeclAttrs)
27956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    DeclAttrs = new DeclAttrMapTy();
28056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  Attr *&ExistingAttr = (*DeclAttrs)[this];
28256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  NewAttr->setNext(ExistingAttr);
28456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  ExistingAttr = NewAttr;
28556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  HasAttrs = true;
28756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
28856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
28956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::invalidateAttrs() {
29056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs) return;
29156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
29256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  HasAttrs = false;
29356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs)[this] = 0;
29456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  DeclAttrs->erase(this);
29556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
29656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (DeclAttrs->empty()) {
29756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    delete DeclAttrs;
29856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    DeclAttrs = 0;
29956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
30056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
30156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
30256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanconst Attr *Decl::getAttrs() const {
30356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasAttrs)
30456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return 0;
30556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
30656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  return (*DeclAttrs)[this];
30756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
30856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
30956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::swapAttrs(Decl *RHS) {
31056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  bool HasLHSAttr = this->HasAttrs;
31156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  bool HasRHSAttr = RHS->HasAttrs;
31256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
31356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Usually, neither decl has attrs, nothing to do.
31456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasLHSAttr && !HasRHSAttr) return;
31556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
31656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // If 'this' has no attrs, swap the other way.
31756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (!HasLHSAttr)
31856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return RHS->swapAttrs(this);
31956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
32056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Handle the case when both decls have attrs.
32156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (HasRHSAttr) {
32256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    std::swap((*DeclAttrs)[this], (*DeclAttrs)[RHS]);
32356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return;
32456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
32556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
32656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  // Otherwise, LHS has an attr and RHS doesn't.
32756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs)[RHS] = (*DeclAttrs)[this];
32856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  (*DeclAttrs).erase(this);
32956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  this->HasAttrs = false;
33056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  RHS->HasAttrs = true;
33156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
33256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
33456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedmanvoid Decl::Destroy(ASTContext& C) {
335a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor#if 0
336a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor  // FIXME: This causes double-destroys in some cases, so it is
337a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor  // disabled at the moment.
33856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  if (ScopedDecl* SD = dyn_cast<ScopedDecl>(this)) {
33956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    // Observe the unrolled recursion.  By setting N->NextDeclarator = 0x0
34156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    // within the loop, only the Destroy method for the first ScopedDecl
34256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    // will deallocate all of the ScopedDecls in a chain.
34356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34456d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    ScopedDecl* N = SD->getNextDeclarator();
34556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
34656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    while (N) {
34756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      ScopedDecl* Tmp = N->getNextDeclarator();
34856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      N->NextDeclarator = 0x0;
34956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      N->Destroy(C);
35056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman      N = Tmp;
35156d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    }
35256d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  }
353a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor#endif
354a0fc55f3e9d7d7aa8761d0a9726033947d0d6bc0Douglas Gregor
35556d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  this->~Decl();
35656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  C.getAllocator().Deallocate((void *)this);
35756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
35856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
35942220c5432c141d47cc8ce786e472b49dc907378Argyrios KyrtzidisDecl *Decl::castFromDeclContext (const DeclContext *D) {
36042220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  return DeclContext::CastTo<Decl>(D);
36142220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis}
36242220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis
36342220c5432c141d47cc8ce786e472b49dc907378Argyrios KyrtzidisDeclContext *Decl::castToDeclContext(const Decl *D) {
36442220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis  return DeclContext::CastTo<DeclContext>(D);
36542220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis}
36642220c5432c141d47cc8ce786e472b49dc907378Argyrios Kyrtzidis
36756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
36856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman// DeclContext Implementation
36956d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman//===----------------------------------------------------------------------===//
37056d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman
37120bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidisconst DeclContext *DeclContext::getParent() const {
37220bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidis  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
37356d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return SD->getDeclContext();
37420bc6762282d192bd19be03094d4f311710e020cArgyrios Kyrtzidis  else if (const BlockDecl *BD = dyn_cast<BlockDecl>(this))
375090276f5e164d491a1bb3f541bafdb394f5e6f04Steve Naroff    return BD->getParentContext();
37656d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman  else
37756d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman    return NULL;
37856d29376459f88dcdbcbf6c9a83c2f77e433f1e2Eli Friedman}
37977407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis
38077407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidisconst DeclContext *DeclContext::getLexicalParent() const {
38177407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis  if (const ScopedDecl *SD = dyn_cast<ScopedDecl>(this))
38277407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis    return SD->getLexicalDeclContext();
383051c13a4a99c651e404b4a3160e1173b427eee17Argyrios Kyrtzidis  return getParent();
38477407b802130b1c44b1f63b855722a5376f57bcaArgyrios Kyrtzidis}
38544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
38644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// FIXME: We really want to use a DenseSet here to eliminate the
38744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// redundant storage of the declaration names, but (1) it doesn't give
38844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// us the ability to search based on DeclarationName, (2) we really
38944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor// need something more like a DenseMultiSet, and (3) it's
3903fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// implemented in terms of DenseMap anyway. However, this data
3913fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// structure is really space-inefficient, so we'll have to do
3923fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor// something.
3933fc749d899dfc194162128c1a88933148a39b68dDouglas Gregortypedef llvm::DenseMap<DeclarationName, std::vector<ScopedDecl*> >
3943fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  StoredDeclsMap;
39544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
39644b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::~DeclContext() {
39744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  unsigned Size = LookupPtr.getInt();
39844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (Size == LookupIsMap) {
39944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
40044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete Map;
40144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  } else {
4023fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
40344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete [] Array;
40444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
40544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
40644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
40744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregorvoid DeclContext::DestroyDecls(ASTContext &C) {
4086037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  for (decl_iterator D = decls_begin(); D != decls_end(); ++D) {
4096037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    // FIXME: assert that this condition holds.
41044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if ((*D)->getLexicalDeclContext() == this)
41144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      (*D)->Destroy(C);
41244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
41344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
41444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
415074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregorbool DeclContext::isTransparentContext() const {
416074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (DeclKind == Decl::Enum)
417074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return true; // FIXME: Check for C++0x scoped enums
418074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::LinkageSpec)
419074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return true;
420074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::Record || DeclKind == Decl::CXXRecord)
421bcbffc46f1ad3796c4582fa1e3a9113b5aa26061Douglas Gregor    return cast<RecordDecl>(this)->isAnonymousStructOrUnion();
422074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  else if (DeclKind == Decl::Namespace)
423074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return false; // FIXME: Check for C++0x inline namespaces
424074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
425074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  return false;
426074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor}
427074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
4280701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext *DeclContext::getPrimaryContext() {
42944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  switch (DeclKind) {
43044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::TranslationUnit:
431074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::LinkageSpec:
432074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::Block:
43344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // There is only one DeclContext for these entities.
43444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
43544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
43644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Namespace:
43744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The original namespace is our primary context.
43844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return static_cast<NamespaceDecl*>(this)->getOriginalNamespace();
43944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
44044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Enum:
441074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor#if 0
442074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    // FIXME: See the comment for CXXRecord, below.
44344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The declaration associated with the enumeration type is our
44444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // primary context.
44544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return Context.getTypeDeclType(static_cast<EnumDecl*>(this))
44644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor             ->getAsEnumType()->getDecl();
447074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor#else
448074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return this;
449074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor#endif
45044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
45144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Record:
45244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::CXXRecord: {
45344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The declaration associated with the type is be our primary
45444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // context.
45544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#if 0
45644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: This is what we expect to do. However, it doesn't work
45744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // because ASTContext::setTagDefinition changes the result of
45844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Context.getTypeDeclType, meaning that our "primary" declaration
45944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // of a RecordDecl/CXXRecordDecl will change, and we won't be able
46044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // to find any values inserted into the earlier "primary"
46144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // declaration. We need better tracking of redeclarations and
46244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // definitions.
46344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    QualType Type = Context.getTypeDeclType(static_cast<RecordDecl*>(this));
46444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return Type->getAsRecordType()->getDecl();
46544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#else
46644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: This hack will work for now, because the declaration we
46744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // create when we're defining the record is the one we'll use as
46844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // the definition later.
46944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
47044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor#endif
47144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
47244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
47344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCMethod:
47444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
47544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
47644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCInterface:
4770701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCProtocol:
4780701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategory:
47944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // FIXME: Can Objective-C interfaces be forward-declared?
48044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
48144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
4820701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCImplementation:
4830701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategoryImpl:
4840701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    return this;
4850701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff
48644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  default:
48744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
48844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor          "Unknown DeclContext kind");
48944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return this;
49044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
49144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
49244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
49344b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext *DeclContext::getNextContext() {
49444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  switch (DeclKind) {
49544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::TranslationUnit:
49644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Enum:
49744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Record:
49844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::CXXRecord:
49944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCMethod:
50044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::ObjCInterface:
5010701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategory:
5020701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCProtocol:
5030701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCImplementation:
5040701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  case Decl::ObjCCategoryImpl:
505074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::LinkageSpec:
506074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  case Decl::Block:
50744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // There is only one DeclContext for these entities.
50844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return 0;
50944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
51044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  case Decl::Namespace:
51144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Return the next namespace
51244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return static_cast<NamespaceDecl*>(this)->getNextNamespace();
51344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
51444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  default:
51544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    assert(DeclKind >= Decl::FunctionFirst && DeclKind <= Decl::FunctionLast &&
51644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor          "Unknown DeclContext kind");
51744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return 0;
51844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
51944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
52044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
521482b77d1cb4ca08391d1f749436f092a4cc24427Douglas Gregorvoid DeclContext::addDecl(ScopedDecl *D) {
522a8cc8ce044e5d2589128f0c1a84e586cce743b27Douglas Gregor  assert(D->getLexicalDeclContext() == this && "Decl inserted into wrong lexical context");
5236037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  assert(!D->NextDeclInScope && D != LastDecl &&
5246037fcba3431b47de1a994c9b286feac17894effDouglas Gregor         "Decl already inserted into a DeclContext");
5256037fcba3431b47de1a994c9b286feac17894effDouglas Gregor
5266037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  if (FirstDecl) {
5276037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    LastDecl->NextDeclInScope = D;
5286037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    LastDecl = D;
5296037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  } else {
5306037fcba3431b47de1a994c9b286feac17894effDouglas Gregor    FirstDecl = LastDecl = D;
5316037fcba3431b47de1a994c9b286feac17894effDouglas Gregor  }
532482b77d1cb4ca08391d1f749436f092a4cc24427Douglas Gregor  D->getDeclContext()->insert(D);
53344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
53444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
535074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// buildLookup - Build the lookup data structure with all of the
536074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// declarations in DCtx (and any other contexts linked to it or
537074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor/// transparent contexts nested within it).
5380701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroffvoid DeclContext::buildLookup(DeclContext *DCtx) {
539074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  for (; DCtx; DCtx = DCtx->getNextContext()) {
5404f3b8f8ac2f8c89028a2f8793df0a7887df809d4Douglas Gregor    for (decl_iterator D = DCtx->decls_begin(), DEnd = DCtx->decls_end();
5414f3b8f8ac2f8c89028a2f8793df0a7887df809d4Douglas Gregor         D != DEnd; ++D) {
542074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // Insert this declaration into the lookup structure
543074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      insertImpl(*D);
544074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
545074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // If this declaration is itself a transparent declaration context,
546074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      // add its members (recursively).
547074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor      if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D))
548074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor        if (InnerCtx->isTransparentContext())
5490701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff          buildLookup(InnerCtx->getPrimaryContext());
550074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    }
551074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  }
552074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor}
553074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
55444b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::lookup_result
5550701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext::lookup(DeclarationName Name) {
5560701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  DeclContext *PrimaryContext = getPrimaryContext();
55744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (PrimaryContext != this)
5580701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    return PrimaryContext->lookup(Name);
55944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5603fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  /// If there is no lookup data structure, build one now by walking
56144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// all of the linked DeclContexts (in declaration order!) and
56244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  /// inserting their values.
563074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (LookupPtr.getPointer() == 0)
5640701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff    buildLookup(this);
56544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
56644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (isLookupMap()) {
56744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
56844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap::iterator Pos = Map->find(Name);
5693fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (Pos != Map->end())
5703fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      return lookup_result(&Pos->second.front(),
5713fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor                           &Pos->second.front() + Pos->second.size());
5723fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    return lookup_result(0, 0);
57344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
57444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
57544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // We have a small array. Look into it.
57644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  unsigned Size = LookupPtr.getInt();
5773fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  ScopedDecl **Array = static_cast<ScopedDecl**>(LookupPtr.getPointer());
578e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor  for (unsigned Idx = 0; Idx != Size; ++Idx)
57944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Array[Idx]->getDeclName() == Name) {
5803fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      unsigned Last = Idx + 1;
5813fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      while (Last != Size && Array[Last]->getDeclName() == Name)
5823fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        ++Last;
5833fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      return lookup_result(&Array[Idx], &Array[Last]);
58444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
58544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
5863fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  return lookup_result(0, 0);
58744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
58844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
58944b4321feab46299d3f5cfd404680884752a0fcfDouglas GregorDeclContext::lookup_const_result
5900701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve NaroffDeclContext::lookup(DeclarationName Name) const {
5910701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  return const_cast<DeclContext*>(this)->lookup(Name);
59244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
59344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
59417a9b9e3ee75f5dbb4819cc8ebf40eec8015f84aDouglas Gregorconst DeclContext *DeclContext::getLookupContext() const {
59517a9b9e3ee75f5dbb4819cc8ebf40eec8015f84aDouglas Gregor  const DeclContext *Ctx = this;
59672de6676bd30f9081ee4166bbe07b4c270258ce6Douglas Gregor  // Skip through transparent contexts.
597ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor  while (Ctx->isTransparentContext())
598ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor    Ctx = Ctx->getParent();
599ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor  return Ctx;
600ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor}
601ce35607c282c845b3285d0f6e106489d8bbeba13Douglas Gregor
602482b77d1cb4ca08391d1f749436f092a4cc24427Douglas Gregorvoid DeclContext::insert(ScopedDecl *D) {
6030701bbb228dfd87e1fe82a0a4b7b9facfecb43daSteve Naroff  DeclContext *PrimaryContext = getPrimaryContext();
60444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (PrimaryContext != this) {
605482b77d1cb4ca08391d1f749436f092a4cc24427Douglas Gregor    PrimaryContext->insert(D);
60644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    return;
60744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
60844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
60944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // If we already have a lookup data structure, perform the insertion
61044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // into it. Otherwise, be lazy and don't build that structure until
61144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // someone asks for it.
61244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (LookupPtr.getPointer())
61344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    insertImpl(D);
614074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
615074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // If we are a transparent context, insert into our parent context,
616074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // too. This operation is recursive.
617074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (isTransparentContext())
618482b77d1cb4ca08391d1f749436f092a4cc24427Douglas Gregor    getParent()->insert(D);
61944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
62044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6213fc749d899dfc194162128c1a88933148a39b68dDouglas Gregorvoid DeclContext::insertImpl(ScopedDecl *D) {
622074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  // Skip unnamed declarations.
623074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor  if (!D->getDeclName())
624074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor    return;
625074149e11baf5f7db12f84efd5c34ba6e35d5cdfDouglas Gregor
6263fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  bool MayBeRedeclaration = true;
6273fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor
62844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  if (!isLookupMap()) {
62944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    unsigned Size = LookupPtr.getInt();
63044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
63144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // The lookup data is stored as an array. Search through the array
63244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // to find the insertion location.
6333fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    ScopedDecl **Array;
63444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Size == 0) {
6353fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array = new ScopedDecl*[LookupIsMap - 1];
63644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      LookupPtr.setPointer(Array);
63744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    } else {
6383fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array = static_cast<ScopedDecl **>(LookupPtr.getPointer());
63944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
64044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
64144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We always keep declarations of the same name next to each other
64244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // in the array, so that it is easy to return multiple results
6433fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    // from lookup().
6443fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    unsigned FirstMatch;
6453fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    for (FirstMatch = 0; FirstMatch != Size; ++FirstMatch)
6463fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      if (Array[FirstMatch]->getDeclName() == D->getDeclName())
647e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor        break;
64844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6493fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    unsigned InsertPos = FirstMatch;
6503fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (FirstMatch != Size) {
6513fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // We found another declaration with the same name. First
6523fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // determine whether this is a redeclaration of an existing
6533fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // declaration in this scope, in which case we will replace the
6543fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // existing declaration.
6553fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      unsigned LastMatch = FirstMatch;
6563fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      for (; LastMatch != Size; ++LastMatch) {
6573fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        if (Array[LastMatch]->getDeclName() != D->getDeclName())
6583fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          break;
6593fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor
6606ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        if (D->declarationReplaces(Array[LastMatch])) {
6613fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          // D is a redeclaration of an existing element in the
6623fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          // array. Replace that element with D.
6633fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          Array[LastMatch] = D;
6643fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor          return;
6653fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        }
66644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      }
66744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6683fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // [FirstMatch, LastMatch) contains the set of declarations that
6693fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // have the same name as this declaration. Determine where the
6703fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // declaration D will be inserted into this range.
6713fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      if (D->getIdentifierNamespace() == Decl::IDNS_Tag)
6723fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch;
6733fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      else if (Array[LastMatch-1]->getIdentifierNamespace() == Decl::IDNS_Tag)
6743fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch - 1;
6753fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      else
6763fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor        InsertPos = LastMatch;
67744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
67844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
67944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    if (Size < LookupIsMap - 1) {
68044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      // The new declaration will fit in the array. Insert the new
68144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      // declaration at the position Match in the array.
6823fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      for (unsigned Idx = Size; Idx > InsertPos; --Idx)
68344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor       Array[Idx] = Array[Idx-1];
68444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
6853fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Array[InsertPos] = D;
68644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      LookupPtr.setInt(Size + 1);
68744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      return;
68844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    }
68944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
69044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // We've reached capacity in this array. Create a map and copy in
69144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // all of the declarations that were stored in the array.
69244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    StoredDeclsMap *Map = new StoredDeclsMap(16);
69344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    LookupPtr.setPointer(Map);
69444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    LookupPtr.setInt(LookupIsMap);
695e267ff35b2f4e9d2b0d8bf24109d41cc7398b61bDouglas Gregor    for (unsigned Idx = 0; Idx != LookupIsMap - 1; ++Idx)
69644b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor      insertImpl(Array[Idx]);
69744b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    delete [] Array;
69844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
69944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Fall through to perform insertion into the map.
7003fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    MayBeRedeclaration = false;
7013fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  }
70244b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
70344b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  // Insert this declaration into the map.
70444b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  StoredDeclsMap *Map = static_cast<StoredDeclsMap*>(LookupPtr.getPointer());
70544b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  StoredDeclsMap::iterator Pos = Map->find(D->getDeclName());
7063fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor  if (Pos != Map->end()) {
7073fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (MayBeRedeclaration) {
7083fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      // Determine if this declaration is actually a redeclaration.
7096ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor      std::vector<ScopedDecl *>::iterator Redecl
7106ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        = std::find_if(Pos->second.begin(), Pos->second.end(),
7116ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor                     std::bind1st(std::mem_fun(&ScopedDecl::declarationReplaces),
7126ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor                                  D));
7136ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor      if (Redecl != Pos->second.end()) {
7146ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        *Redecl = D;
7156ed40e351a7c1fb3084434f1db19216b79623cf0Douglas Gregor        return;
7163fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      }
7173fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    }
71844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor
71944b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor    // Put this declaration into the appropriate slot.
7203fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    if (D->getIdentifierNamespace() == Decl::IDNS_Tag || Pos->second.empty())
7213fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(D);
7223fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    else if (Pos->second.back()->getIdentifierNamespace() == Decl::IDNS_Tag) {
7233fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      ScopedDecl *TagD = Pos->second.back();
7243fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.back() = D;
7253fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(TagD);
7263fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    } else
7273fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor      Pos->second.push_back(D);
72844b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  } else {
7293fc749d899dfc194162128c1a88933148a39b68dDouglas Gregor    (*Map)[D->getDeclName()].push_back(D);
73044b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor  }
73144b4321feab46299d3f5cfd404680884752a0fcfDouglas Gregor}
732