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