15f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===// 25f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 35f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// The LLVM Compiler Infrastructure 45f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 50bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// This file is distributed under the University of Illinois Open Source 60bc735ffcfb223c0186419547abaa5c84482663eChris Lattner// License. See LICENSE.TXT for details. 75f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 85f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 95f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 105f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// This file implements the IdentifierInfo, IdentifierVisitor, and 115f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// IdentifierTable interfaces. 125f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// 135f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 145f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1580e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl#include "clang/Basic/CharInfo.h" 166bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/Basic/IdentifierTable.h" 17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#include "clang/Basic/LangOptions.h" 186bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "clang/Basic/OperatorKinds.h" 1985994260c41a54cab061a434ed378fc448333a4eChris Lattner#include "llvm/ADT/DenseMap.h" 2055fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/FoldingSet.h" 216bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines#include "llvm/ADT/SmallString.h" 227530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie#include "llvm/Support/ErrorHandling.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/Support/raw_ostream.h" 243daed52a57d03765223021f5f921bdc280c8f3ccChris Lattner#include <cstdio> 25c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek 265f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencerusing namespace clang; 275f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 285f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 295f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// IdentifierInfo Implementation 305f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 315f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 32ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted KremenekIdentifierInfo::IdentifierInfo() { 335f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer TokenID = tok::identifier; 345142af38ed0dd2f592cbfa00fa6e2e14dd6cc516Douglas Gregor ObjCOrBuiltinID = 0; 354365a7e46822700357a272d839ee2656d9603d5aChris Lattner HasMacro = false; 364d7e0ced7f16a04aabe2d8d91cbbb52fb1162810Alexander Kornienko HadMacro = false; 375f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsExtension = false; 3898d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith IsCXX11CompatKeyword = false; 395f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsPoisoned = false; 405f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IsCPPOperatorKeyword = false; 416a170eb3ea6d6319277becabef68eb1a26bf8766Chris Lattner NeedsHandleIdentifier = false; 423c7f4134603d04b44f997b43c0a9def270f25386Sebastian Redl IsFromAST = false; 43eee242ff426bf79149f221798966e58688383c1eDouglas Gregor ChangedAfterLoad = false; 44646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis RevertedTokenID = false; 45eee242ff426bf79149f221798966e58688383c1eDouglas Gregor OutOfDate = false; 4632ad2ee2618745ce3da51c2ae066ed5f21157c07Ted Kremenek IsModulesImport = false; 476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines FETokenInfo = nullptr; 486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines Entry = nullptr; 495f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 505f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 515f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// IdentifierTable Implementation 535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 5595f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas GregorIdentifierIterator::~IdentifierIterator() { } 5695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 5772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted KremenekIdentifierInfoLookup::~IdentifierInfoLookup() {} 5872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek 5995f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregornamespace { 6095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// \brief A simple identifier lookup iterator that represents an 6195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor /// empty sequence of identifiers. 6295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor class EmptyLookupIterator : public IdentifierIterator 6395f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor { 6495f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor public: 65651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines StringRef Next() override { return StringRef(); } 6695f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor }; 6795f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor} 6895f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 6987f9d81d0ab806dcf6ca50a0c068dcb2ba7f51b3Argyrios KyrtzidisIdentifierIterator *IdentifierInfoLookup::getIdentifiers() { 7095f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor return new EmptyLookupIterator(); 7195f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor} 7295f4292cc526c629fead321c7fcfd4fe0f3bc66eDouglas Gregor 738c5a760b82e73ed90b560090772db97e2ae27b09Douglas GregorExternalIdentifierLookup::~ExternalIdentifierLookup() {} 748c5a760b82e73ed90b560090772db97e2ae27b09Douglas Gregor 7572b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted KremenekIdentifierTable::IdentifierTable(const LangOptions &LangOpts, 7672b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek IdentifierInfoLookup* externalLookup) 7772b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek : HashTable(8192), // Start with space for 8K identifiers. 7872b1b15ee88aac0a63e2c1dc53fe22f5ab297b20Ted Kremenek ExternalLookup(externalLookup) { 795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Populate the identifier table with info about keywords for the current 815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // language. 825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer AddKeywords(LangOpts); 83f15e1143dcb39396a1b62e509e59cacaabbc4880Ted Kremenek 84f15e1143dcb39396a1b62e509e59cacaabbc4880Ted Kremenek 85f15e1143dcb39396a1b62e509e59cacaabbc4880Ted Kremenek // Add the '_experimental_modules_import' contextual keyword. 861b257afbae854c6817f26b7d61c4fed8ff7aebadDouglas Gregor get("import").setModulesImport(true); 875f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 905f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Language Keyword Implementation 915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 93eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman// Constants for TokenKinds.def 94eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedmannamespace { 95eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman enum { 9667922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYC99 = 0x1, 9767922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYCXX = 0x2, 984e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith KEYCXX11 = 0x4, 9967922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYGNU = 0x8, 10067922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYMS = 0x10, 10167922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith BOOLSUPPORT = 0x20, 10267922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYALTIVEC = 0x40, 10367922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYNOCXX = 0x80, 10467922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYBORLAND = 0x100, 10567922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith KEYOPENCL = 0x200, 106ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer KEYC11 = 0x400, 107f85e193739c953358c865005855253af4f68a497John McCall KEYARC = 0x800, 108a5a4cba88796cb1b8365ed523e8b6fdce9e512bdFrancois Pichet KEYNOMS = 0x01000, 1095b86ffd219bdee7720217d5755b772726668b242Abramo Bagnara WCHARSUPPORT = 0x02000, 110651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines HALFSUPPORT = 0x04000, 111a5a4cba88796cb1b8365ed523e8b6fdce9e512bdFrancois Pichet KEYALL = (0xffff & ~KEYNOMS) // Because KEYNOMS is used to exclude. 112eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman }; 113eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman} 114eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman 1155f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddKeyword - This method is used to associate a token ID with specific 1165f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// identifiers because they are language keywords. This causes the lexer to 1175f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// automatically map matching identifiers to specialized token codes. 1185f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 11998d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a 12098d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith/// future language standard, set to 2 if the token should be enabled in the 1210be8fb5bdfe7e07a57f07a740649ec8bfb690284Nick Lewycky/// specified language, set to 1 if it is an extension in the specified 12298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith/// language, and set to 0 if disabled in the specified language. 1235f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void AddKeyword(StringRef Keyword, 124eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman tok::TokenKind TokenCode, unsigned Flags, 1255f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer const LangOptions &LangOpts, IdentifierTable &Table) { 126eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman unsigned AddResult = 0; 12767922922cf3d9a2c5b4a02b1ee27e81da3850b53Dylan Noblesmith if (Flags == KEYALL) AddResult = 2; 128eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman else if (LangOpts.CPlusPlus && (Flags & KEYCXX)) AddResult = 2; 1294e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith else if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) AddResult = 2; 130eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2; 131eb5d7b752651283de5abfcc2f91df7227582a08dChandler Carruth else if (LangOpts.GNUKeywords && (Flags & KEYGNU)) AddResult = 1; 13262ec1f2fd7368542bb926c04797fb07023547694Francois Pichet else if (LangOpts.MicrosoftExt && (Flags & KEYMS)) AddResult = 1; 13352fc314e1b5e1baee6305067cf831763d02bd243Dawn Perchik else if (LangOpts.Borland && (Flags & KEYBORLAND)) AddResult = 1; 134e4f2142d00fa5fdb580c4e2413da91882d955381Chris Lattner else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2; 135651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines else if (LangOpts.Half && (Flags & HALFSUPPORT)) AddResult = 2; 1365b86ffd219bdee7720217d5755b772726668b242Abramo Bagnara else if (LangOpts.WChar && (Flags & WCHARSUPPORT)) AddResult = 2; 13782287d19ded35248c4ce6a425ce74116a13ce44eJohn Thompson else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2; 138f315fa81eef1977b3457fd7a7d4639e060fe7278Peter Collingbourne else if (LangOpts.OpenCL && (Flags & KEYOPENCL)) AddResult = 2; 1393a43d8df596a0af13379c3d2a78e2f7e7b156f30Douglas Gregor else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2; 140ffbe9b9c64ab2e94b9d48ec56e511f75826fc80aBenjamin Kramer else if (LangOpts.C11 && (Flags & KEYC11)) AddResult = 2; 14100852e41261f9860233d3b407fce0506346cdacbFariborz Jahanian // We treat bridge casts as objective-C keywords so we can warn on them 14200852e41261f9860233d3b407fce0506346cdacbFariborz Jahanian // in non-arc mode. 14300852e41261f9860233d3b407fce0506346cdacbFariborz Jahanian else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2; 1444e24f0f711e2c9fde79f19fa1c80deaab3f3b356Richard Smith else if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) AddResult = 3; 14598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith 146651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines // Don't add this keyword under MSVCCompat. 147651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines if (LangOpts.MSVCCompat && (Flags & KEYNOMS)) 148dfd110ce5e64077ec94df195233e7a39895bf15eFrancois Pichet return; 149eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman // Don't add this keyword if disabled in this language. 150eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman if (AddResult == 0) return; 151eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman 15298d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith IdentifierInfo &Info = 15398d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith Table.get(Keyword, AddResult == 3 ? tok::identifier : TokenCode); 154eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman Info.setIsExtensionToken(AddResult == 1); 15598d86b98b3fd0bd9c546123b16fd9995509aaae1Richard Smith Info.setIsCXX11CompatKeyword(AddResult == 3); 1565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative 1595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// representations. 1605f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void AddCXXOperatorKeyword(StringRef Keyword, 1615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer tok::TokenKind TokenCode, 1625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierTable &Table) { 163646395bbcaa849c94bc2a3246c71d809ca719f01Argyrios Kyrtzidis IdentifierInfo &Info = Table.get(Keyword, TokenCode); 164c637e6b7afeebc6b4f751e4373715b6a8ea77272Ted Kremenek Info.setIsCPlusPlusOperatorKeyword(); 1655f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1676557d1304c84233edd854288d4f80b987ad10ed9James Dennett/// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector" 1686557d1304c84233edd854288d4f80b987ad10ed9James Dennett/// or "property". 1695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void AddObjCKeyword(StringRef Name, 17050acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam tok::ObjCKeywordKind ObjCID, 1715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer IdentifierTable &Table) { 17250acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam Table.get(Name).setObjCKeywordID(ObjCID); 1735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 1745f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 1755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// AddKeywords - Add all keywords to the symbol table. 1765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// 1775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid IdentifierTable::AddKeywords(const LangOptions &LangOpts) { 1785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Add keywords and tokens for the current language. 1795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define KEYWORD(NAME, FLAGS) \ 1805f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \ 181eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman FLAGS, LangOpts, *this); 182eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman#define ALIAS(NAME, TOK, FLAGS) \ 1835f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \ 184eb32fde032a250091134db56a3aeaea6b09f6594Eli Friedman FLAGS, LangOpts, *this); 1855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ 1865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (LangOpts.CXXOperatorNames) \ 1875f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); 1885f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define OBJC1_AT_KEYWORD(NAME) \ 1895f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (LangOpts.ObjC1) \ 1905f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 1915f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#define OBJC2_AT_KEYWORD(NAME) \ 1925f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (LangOpts.ObjC2) \ 1935f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 194a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall#define TESTING_KEYWORD(NAME, FLAGS) 1955f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer#include "clang/Basic/TokenKinds.def" 196a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall 197a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall if (LangOpts.ParseUnknownAnytype) 198a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL, 199a5fc472b353b88be3b4981da946fb01f5a5cc0c6John McCall LangOpts, *this); 2005f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 2015f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 202387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattnertok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { 203387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner // We use a perfect hash function here involving the length of the keyword, 204387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner // the first and third character. For preprocessor ID's there are no 205387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner // collisions (if there were, the switch below would complain about duplicate 206387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner // case values). Note that this depends on 'if' being null terminated. 2071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 208387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#define HASH(LEN, FIRST, THIRD) \ 209387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31) 210387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#define CASE(LEN, FIRST, THIRD, NAME) \ 211387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner case HASH(LEN, FIRST, THIRD): \ 212387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME 2131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 214387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner unsigned Len = getLength(); 215a31f030d5c2bca6567ecfc7fa9367aeb19de7037Chris Lattner if (Len < 2) return tok::pp_not_keyword; 21676b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar const char *Name = getNameStart(); 217387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner switch (HASH(Len, Name[0], Name[2])) { 218387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner default: return tok::pp_not_keyword; 219387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 2, 'i', '\0', if); 220387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 4, 'e', 'i', elif); 221387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 4, 'e', 's', else); 222387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 4, 'l', 'n', line); 223387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 4, 's', 'c', sccs); 224387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 5, 'e', 'd', endif); 225387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 5, 'e', 'r', error); 226387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 5, 'i', 'e', ident); 227387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 5, 'i', 'd', ifdef); 228387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 5, 'u', 'd', undef); 229387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner 230387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 6, 'a', 's', assert); 231387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 6, 'd', 'f', define); 232387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 6, 'i', 'n', ifndef); 233387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 6, 'i', 'p', import); 234387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 6, 'p', 'a', pragma); 23594ad28b31433058445a27db722f60402ee820beaDouglas Gregor 236387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 7, 'd', 'f', defined); 237387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 7, 'i', 'c', include); 238387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 7, 'w', 'r', warning); 239387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner 240387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE( 8, 'u', 'a', unassert); 241387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner CASE(12, 'i', 'c', include_next); 2421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2431ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor CASE(14, '_', 'p', __public_macro); 2441ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor 2451ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor CASE(15, '_', 'p', __private_macro); 2461ac13c37d8af0145b7e03fea70b7b1476b8828c9Douglas Gregor 247b8e240ed8b8f58c7b7fe82776bd6147b437f5d53Chris Lattner CASE(16, '_', 'i', __include_macros); 248387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#undef CASE 249387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner#undef HASH 250387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner } 251387b98d37e08f7aa9ddf23e067e1d27e39ce16f3Chris Lattner} 2525f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2535f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 2545f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer// Stats Implementation 2555f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer//===----------------------------------------------------------------------===// 2565f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer 2575f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// PrintStats - Print statistics about how well the identifier table is doing 2585f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer/// at hashing identifiers. 2595f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencervoid IdentifierTable::PrintStats() const { 2605f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumBuckets = HashTable.getNumBuckets(); 2615f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumIdentifiers = HashTable.getNumItems(); 2625f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers; 2635f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned AverageIdentifierSize = 0; 2645f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned MaxIdentifierLength = 0; 2651eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2665f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // TODO: Figure out maximum times an identifier had to probe for -stats. 267ea9c26b3dbd74a1497f5609ae6e19a85f42b6073Ted Kremenek for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator 2685f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer I = HashTable.begin(), E = HashTable.end(); I != E; ++I) { 2695f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer unsigned IdLen = I->getKeyLength(); 2705f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer AverageIdentifierSize += IdLen; 2715f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer if (MaxIdentifierLength < IdLen) 2725f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer MaxIdentifierLength = IdLen; 2735f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer } 2741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2755f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "\n*** Identifier Table Stats:\n"); 2765f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers); 2775f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets); 2785f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "Hash density (#identifiers per bucket): %f\n", 2795f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer NumIdentifiers/(double)NumBuckets); 2805f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "Ave identifier length: %f\n", 2815f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer (AverageIdentifierSize/(double)NumIdentifiers)); 2825f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength); 2831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2845f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer // Compute statistics about the memory allocated for identifiers. 2855f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer HashTable.getAllocator().PrintStats(); 2865f016e2cb5d11daeb237544de1c5d59f20fe1a6eReid Spencer} 28768d331a78e655d97294e94fcfa63f92cc1f40578Steve Naroff 28829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff//===----------------------------------------------------------------------===// 28929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff// SelectorTable Implementation 29029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff//===----------------------------------------------------------------------===// 29129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 29285994260c41a54cab061a434ed378fc448333a4eChris Lattnerunsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) { 29385994260c41a54cab061a434ed378fc448333a4eChris Lattner return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr()); 29485994260c41a54cab061a434ed378fc448333a4eChris Lattner} 29585994260c41a54cab061a434ed378fc448333a4eChris Lattner 2962e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregornamespace clang { 29729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// MultiKeywordSelector - One of these variable length records is kept for each 29829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// selector containing more than one keyword. We use a folding set 2991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump/// to unique aggregate names (keyword selectors in ObjC parlance). Access to 30029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff/// this class is provided strictly through Selector. 3011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumpclass MultiKeywordSelector 3022e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor : public DeclarationNameExtra, public llvm::FoldingSetNode { 3032e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor MultiKeywordSelector(unsigned nKeys) { 3042e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; 3052e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor } 3061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stumppublic: 30729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff // Constructor for keyword selectors. 30829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) { 30929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff assert((nKeys > 1) && "not a multi-keyword selector"); 3102e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; 3111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 31229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff // Fill in the trailing keyword array. 31329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1); 31429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff for (unsigned i = 0; i != nKeys; ++i) 31529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff KeyInfo[i] = IIV[i]; 3161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump } 3171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 318f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner // getName - Derive the full selector name and return it. 319f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner std::string getName() const; 3201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 3212e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; } 3221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 32329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff typedef IdentifierInfo *const *keyword_iterator; 32429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff keyword_iterator keyword_begin() const { 32529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return reinterpret_cast<keyword_iterator>(this+1); 32629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 3271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump keyword_iterator keyword_end() const { 3281eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return keyword_begin()+getNumArgs(); 32929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 330f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const { 3312e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index"); 33229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return keyword_begin()[i]; 33329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 3341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump static void Profile(llvm::FoldingSetNodeID &ID, 33529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff keyword_iterator ArgTys, unsigned NumArgs) { 33629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff ID.AddInteger(NumArgs); 337f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner for (unsigned i = 0; i != NumArgs; ++i) 338f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner ID.AddPointer(ArgTys[i]); 33929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 34029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff void Profile(llvm::FoldingSetNodeID &ID) { 3412e1cd4264d363ca869bf37ef160902f211d21b8cDouglas Gregor Profile(ID, keyword_begin(), getNumArgs()); 34229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 34329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff}; 34485994260c41a54cab061a434ed378fc448333a4eChris Lattner} // end namespace clang. 34529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 34629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroffunsigned Selector::getNumArgs() const { 34729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff unsigned IIF = getIdentifierInfoFlag(); 34851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor if (IIF <= ZeroArg) 34929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return 0; 35029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff if (IIF == OneArg) 35129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return 1; 35251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor // We point to a MultiKeywordSelector. 35351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor MultiKeywordSelector *SI = getMultiKeywordSelector(); 3541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump return SI->getNumArgs(); 35529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 35629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 357f836e3fea2c77fdbb18170fb313ee0d45551320bChris LattnerIdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const { 35851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor if (getIdentifierInfoFlag() < MultiArg) { 359f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner assert(argIndex == 0 && "illegal keyword index"); 360405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor return getAsIdentifierInfo(); 36129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 36251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor // We point to a MultiKeywordSelector. 36351603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor MultiKeywordSelector *SI = getMultiKeywordSelector(); 36429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return SI->getIdentifierInfoForSlot(argIndex); 36529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 36629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 3675f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerStringRef Selector::getNameForSlot(unsigned int argIndex) const { 368813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor IdentifierInfo *II = getIdentifierInfoForSlot(argIndex); 3695f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner return II? II->getName() : StringRef(); 370813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor} 371813d8346529bf094eb2b249648906ba7fd226688Douglas Gregor 372f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattnerstd::string MultiKeywordSelector::getName() const { 373f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith SmallString<256> Str; 37476b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar llvm::raw_svector_ostream OS(Str); 375f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) { 376f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner if (*I) 37701eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar OS << (*I)->getName(); 37876b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar OS << ':'; 379f836e3fea2c77fdbb18170fb313ee0d45551320bChris Lattner } 3801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 38176b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar return OS.str(); 38229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 38329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 384077bf5e2f48acfa9e7d69429b6e4ba86ea14896dChris Lattnerstd::string Selector::getAsString() const { 385405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor if (InfoPtr == 0) 386405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor return "<null selector>"; 387405bad07391494d2eb025f8222c256c66b56e5f8Douglas Gregor 38851603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor if (getIdentifierInfoFlag() < MultiArg) { 389f5ed3961d21450c4fe98a00d7170da71b485328eTed Kremenek IdentifierInfo *II = getAsIdentifierInfo(); 3901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 391150ec292a6e7995a711cedbe7a10a25d664a6c6bTed Kremenek // If the number of arguments is 0 then II is guaranteed to not be null. 392f5ed3961d21450c4fe98a00d7170da71b485328eTed Kremenek if (getNumArgs() == 0) 39301eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar return II->getName(); 39476b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar 39576b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar if (!II) 39676b61ccc603fad1c631948bf1e49f31343de76e9Daniel Dunbar return ":"; 397f5ed3961d21450c4fe98a00d7170da71b485328eTed Kremenek 39801eb9b9683535d8a65c704ad2c545903409e2d36Daniel Dunbar return II->getName().str() + ":"; 39929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff } 4001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 40151603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor // We have a multiple keyword selector. 40251603be62ba78adeb64246b222583dcde4b20b2aDouglas Gregor return getMultiKeywordSelector()->getName(); 40329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 40429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 405651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Selector::print(llvm::raw_ostream &OS) const { 406651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines OS << getAsString(); 407651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines} 408651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 40985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// Interpreting the given string using the normal CamelCase 41085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// conventions, determine whether the given string starts with the 41185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall/// given "word", which is assumed to end in a lowercase letter. 4125f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic bool startsWithWord(StringRef name, StringRef word) { 41385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name.size() < word.size()) return false; 4143f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose return ((name.size() == word.size() || !isLowercase(name[word.size()])) && 4153f6f51e28231f65de9c2dd150a2d757b2162cfa3Jordan Rose name.startswith(word)); 41685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall} 41785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 41885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCallObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { 41985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall IdentifierInfo *first = sel.getIdentifierInfoForSlot(0); 42085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (!first) return OMF_None; 42185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 4225f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner StringRef name = first->getName(); 42385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (sel.isUnarySelector()) { 42485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name == "autorelease") return OMF_autorelease; 42585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name == "dealloc") return OMF_dealloc; 42680cb6e69d9e85231588ae604e4bc2bc9a07389afNico Weber if (name == "finalize") return OMF_finalize; 42785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name == "release") return OMF_release; 42885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name == "retain") return OMF_retain; 42985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name == "retainCount") return OMF_retainCount; 430926df6cfabf3eaa4afc990c097fa4619b76a9b57Douglas Gregor if (name == "self") return OMF_self; 43185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall } 4329670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian 4339670e179a67d868e171feac44fb8f9e2f108c5e8Fariborz Jahanian if (name == "performSelector") return OMF_performSelector; 43485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 43585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall // The other method families may begin with a prefix of underscores. 43685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall while (!name.empty() && name.front() == '_') 43785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall name = name.substr(1); 43885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 43985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (name.empty()) return OMF_None; 44085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall switch (name.front()) { 44185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall case 'a': 44285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (startsWithWord(name, "alloc")) return OMF_alloc; 44385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall break; 44485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall case 'c': 44585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (startsWithWord(name, "copy")) return OMF_copy; 44685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall break; 44785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall case 'i': 44885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (startsWithWord(name, "init")) return OMF_init; 44985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall break; 45085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall case 'm': 45185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy; 45285f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall break; 45385f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall case 'n': 45485f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall if (startsWithWord(name, "new")) return OMF_new; 45585f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall break; 45685f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall default: 45785f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall break; 45885f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall } 45985f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall 46085f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall return OMF_None; 46185f3d76c0ecfdefcf83ea44a57b7a16119c8a045John McCall} 46229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 46311638f7b922aa0182ab2028ec819001ed2fe8085Fariborz JahanianObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) { 4648d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian IdentifierInfo *first = sel.getIdentifierInfoForSlot(0); 4658d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian if (!first) return OIT_None; 4668d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian 4678d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian StringRef name = first->getName(); 4688d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian 4698d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian if (name.empty()) return OIT_None; 4708d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian switch (name.front()) { 4718d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian case 'a': 472d0f2921c3211299a80c043a3251e6b34dddba061Fariborz Jahanian if (startsWithWord(name, "array")) return OIT_Array; 4738d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian break; 4748d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian case 'd': 4759fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian if (startsWithWord(name, "default")) return OIT_ReturnsSelf; 4768d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian if (startsWithWord(name, "dictionary")) return OIT_Dictionary; 4778d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian break; 4788d3794e06a63578093bd71c3c2520bd01e6197a3Fariborz Jahanian case 's': 4799fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian if (startsWithWord(name, "shared")) return OIT_ReturnsSelf; 4809fcbd5e55a8029a0ca8a5d64457278ec716a8705Fariborz Jahanian if (startsWithWord(name, "standard")) return OIT_Singleton; 481a346eb1188419d3f1698092edfbd66890b74163cFariborz Jahanian case 'i': 482a346eb1188419d3f1698092edfbd66890b74163cFariborz Jahanian if (startsWithWord(name, "init")) return OIT_Init; 4838d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian default: 4848d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian break; 4858d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian } 4868d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian return OIT_None; 4878d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian} 4888d09216f13478b20f9d9088af22146e28c0cc4ceFariborz Jahanian 4895f7d2284c4b2f08d155732454002e68dc40c33efChris Lattnernamespace { 4905f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner struct SelectorTableImpl { 4915f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner llvm::FoldingSet<MultiKeywordSelector> Table; 4925f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner llvm::BumpPtrAllocator Allocator; 4935f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner }; 4945f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner} // end anonymous namespace. 4955f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner 4965f7d2284c4b2f08d155732454002e68dc40c33efChris Lattnerstatic SelectorTableImpl &getSelectorTableImpl(void *P) { 4975f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner return *static_cast<SelectorTableImpl*>(P); 4985f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner} 4995f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner 5007044668ecb518496e463ea2dacae100d4badfd19Adrian PrantlSmallString<64> 50180e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian PrantlSelectorTable::constructSetterName(StringRef Name) { 5027044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl SmallString<64> SetterName("set"); 5037044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl SetterName += Name; 5047044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl SetterName[3] = toUppercase(SetterName[3]); 5057044668ecb518496e463ea2dacae100d4badfd19Adrian Prantl return SetterName; 50680e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl} 50780e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl 5087044668ecb518496e463ea2dacae100d4badfd19Adrian PrantlSelector 50980e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian PrantlSelectorTable::constructSetterSelector(IdentifierTable &Idents, 51080e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl SelectorTable &SelTable, 51180e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl const IdentifierInfo *Name) { 51280e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl IdentifierInfo *SetterName = 51380e8ea92d6dcaa05165dcb4730485db82dcd4629Adrian Prantl &Idents.get(constructSetterName(Name->getName())); 5148fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer return SelTable.getUnarySelector(SetterName); 5158fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer} 5168fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer 51797f55d6ffd548d1777d790c84b358030682f9de2Ted Kremeneksize_t SelectorTable::getTotalMemory() const { 51897f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); 51997f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek return SelTabImpl.Allocator.getTotalMemory(); 52097f55d6ffd548d1777d790c84b358030682f9de2Ted Kremenek} 5215f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner 522ff38491c18b060526d754765b952f4a497a89416Chris LattnerSelector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) { 523ff38491c18b060526d754765b952f4a497a89416Chris Lattner if (nKeys < 2) 524ff38491c18b060526d754765b952f4a497a89416Chris Lattner return Selector(IIV[0], nKeys); 5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 5265f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); 5271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 52829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff // Unique selector, to guarantee there is one per name. 52929238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff llvm::FoldingSetNodeID ID; 53029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff MultiKeywordSelector::Profile(ID, IIV, nKeys); 53129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 5326bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines void *InsertPos = nullptr; 5335f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner if (MultiKeywordSelector *SI = 5345f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos)) 53529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return Selector(SI); 5361eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 53729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff // MultiKeywordSelector objects are not allocated with new because they have a 53829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff // variable size array (for parameter types) at the end of them. 5395f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *); 5405f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner MultiKeywordSelector *SI = 5411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size, 5423248854a5d16e1de17c58e05f726bdef9f042df2Chris Lattner llvm::alignOf<MultiKeywordSelector>()); 54329238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff new (SI) MultiKeywordSelector(nKeys, IIV); 5445f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner SelTabImpl.Table.InsertNode(SI, InsertPos); 54529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff return Selector(SI); 54629238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 54729238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 54829238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve NaroffSelectorTable::SelectorTable() { 5495f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner Impl = new SelectorTableImpl(); 55029238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 55129238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 55229238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve NaroffSelectorTable::~SelectorTable() { 5535f7d2284c4b2f08d155732454002e68dc40c33efChris Lattner delete &getSelectorTableImpl(Impl); 55429238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff} 55529238a0bf7cbf5b396efb451a0adb5fe4aa037caSteve Naroff 556ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregorconst char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) { 557ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor switch (Operator) { 558ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case OO_None: 559ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case NUM_OVERLOADED_OPERATORS: 5606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return nullptr; 56150acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam 562ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 563ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor case OO_##Name: return Spelling; 564ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor#include "clang/Basic/OperatorKinds.def" 565ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor } 56650acf24b717a05a509e340f0ad0556de68fa4d5dKovarththanan Rajaratnam 5677530c034c0c71a64c5a9173206d9742ae847af8bDavid Blaikie llvm_unreachable("Invalid OverloadedOperatorKind!"); 568ca1bdd7c269a2390d43c040a60511edd017ee130Douglas Gregor} 569