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