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