IdentifierTable.cpp revision 906c7f78ee9026c1dc40e062667341f1dd194959
11d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===// 21d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams// 31d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams// The LLVM Compiler Infrastructure 41d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams// 51d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams// This file is distributed under the University of Illinois Open Source 61d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams// License. See LICENSE.TXT for details. 7275b1e98bb949643d35546f10f8b1af009349526Jason Sams// 8275b1e98bb949643d35546f10f8b1af009349526Jason Sams//===----------------------------------------------------------------------===// 9275b1e98bb949643d35546f10f8b1af009349526Jason Sams// 107a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao// This file implements the IdentifierInfo, IdentifierVisitor, and 11f6a28c6a71d8929fb90ca83634a617d69531d87dStephen Hines// IdentifierTable interfaces. 1209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams// 1309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams//===----------------------------------------------------------------------===// 1409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 159bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao#include "clang/Basic/IdentifierTable.h" 169bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao#include "clang/Basic/LangOptions.h" 1709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#include "clang/Basic/CharInfo.h" 1809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#include "llvm/ADT/DenseMap.h" 1909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#include "llvm/ADT/FoldingSet.h" 209bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao#include "llvm/Support/ErrorHandling.h" 219bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao#include "llvm/Support/raw_ostream.h" 2209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#include <cstdio> 2309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 2409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Samsusing namespace clang; 259bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao 269bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao//===----------------------------------------------------------------------===// 2709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams// IdentifierInfo Implementation 2809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams//===----------------------------------------------------------------------===// 2909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 309bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei LiaoIdentifierInfo::IdentifierInfo() { 319bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao TokenID = tok::identifier; 3209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams ObjCOrBuiltinID = 0; 3309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams HasMacro = false; 3409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams HadMacro = false; 359bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao IsExtension = false; 36df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines IsCXX11CompatKeyword = false; 3709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams IsPoisoned = false; 3809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams IsCPPOperatorKeyword = false; 3909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams NeedsHandleIdentifier = false; 40df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines IsFromAST = false; 419bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao ChangedAfterLoad = false; 4209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams RevertedTokenID = false; 4309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams OutOfDate = false; 4409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams IsModulesImport = false; 459bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao FETokenInfo = 0; 469bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao Entry = 0; 4709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams} 4809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 4909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams//===----------------------------------------------------------------------===// 509bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao// IdentifierTable Implementation 519bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao//===----------------------------------------------------------------------===// 5209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 5309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason SamsIdentifierIterator::~IdentifierIterator() { } 5409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 559bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei LiaoIdentifierInfoLookup::~IdentifierInfoLookup() {} 569bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao 5709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Samsnamespace { 5809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams /// \brief A simple identifier lookup iterator that represents an 5909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams /// empty sequence of identifiers. 609bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao class EmptyLookupIterator : public IdentifierIterator 619bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao { 6209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams public: 6309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams virtual StringRef Next() { return StringRef(); } 6409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams }; 659bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao} 66df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines 6709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason SamsIdentifierIterator *IdentifierInfoLookup::getIdentifiers() { 6809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams return new EmptyLookupIterator(); 6909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams} 70df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines 71df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen HinesExternalIdentifierLookup::~ExternalIdentifierLookup() {} 7209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 7309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason SamsIdentifierTable::IdentifierTable(const LangOptions &LangOpts, 7409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams IdentifierInfoLookup* externalLookup) 75df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines : HashTable(8192), // Start with space for 8K identifiers. 76df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines ExternalLookup(externalLookup) { 7709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 7809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // Populate the identifier table with info about keywords for the current 7909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // language. 80df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines AddKeywords(LangOpts); 81df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines 8209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 8309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // Add the '_experimental_modules_import' contextual keyword. 8409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams get("import").setModulesImport(true); 85df09719cbeb426a4c8279f2ce226b5874ad7c2c9Stephen Hines} 869bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao 879bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao//===----------------------------------------------------------------------===// 889bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao// Language Keyword Implementation 899bb32e1fd75e864071f18ef10976e8ba9fc0e252Shih-wei Liao//===----------------------------------------------------------------------===// 9009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 9109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams// Constants for TokenKinds.def 9209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Samsnamespace { 9309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams enum { 947a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao KEYC99 = 0x1, 9509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYCXX = 0x2, 9609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYCXX11 = 0x4, 9709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYGNU = 0x8, 987a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao KEYMS = 0x10, 9909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams BOOLSUPPORT = 0x20, 10009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYALTIVEC = 0x40, 10109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYNOCXX = 0x80, 1027a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao KEYBORLAND = 0x100, 103275b1e98bb949643d35546f10f8b1af009349526Jason Sams KEYOPENCL = 0x200, 10409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYC11 = 0x400, 10509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYARC = 0x800, 10609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYNOMS = 0x01000, 10709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams WCHARSUPPORT = 0x02000, 10809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams KEYALL = (0xffff & ~KEYNOMS) // Because KEYNOMS is used to exclude. 10909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams }; 11009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams} 11109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 11209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// AddKeyword - This method is used to associate a token ID with specific 11309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// identifiers because they are language keywords. This causes the lexer to 11409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// automatically map matching identifiers to specialized token codes. 1157a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao/// 116275b1e98bb949643d35546f10f8b1af009349526Jason Sams/// The C90/C99/CPP/CPP0x flags are set to 3 if the token is a keyword in a 11709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// future language standard, set to 2 if the token should be enabled in the 11809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// specified language, set to 1 if it is an extension in the specified 11909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// language, and set to 0 if disabled in the specified language. 12009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Samsstatic void AddKeyword(StringRef Keyword, 12109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams tok::TokenKind TokenCode, unsigned Flags, 12209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams const LangOptions &LangOpts, IdentifierTable &Table) { 12309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams unsigned AddResult = 0; 12409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (Flags == KEYALL) AddResult = 2; 12509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.CPlusPlus && (Flags & KEYCXX)) AddResult = 2; 12609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.CPlusPlus11 && (Flags & KEYCXX11)) AddResult = 2; 1277a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao else if (LangOpts.C99 && (Flags & KEYC99)) AddResult = 2; 128275b1e98bb949643d35546f10f8b1af009349526Jason Sams else if (LangOpts.GNUKeywords && (Flags & KEYGNU)) AddResult = 1; 12909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.MicrosoftExt && (Flags & KEYMS)) AddResult = 1; 13009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.Borland && (Flags & KEYBORLAND)) AddResult = 1; 13109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.Bool && (Flags & BOOLSUPPORT)) AddResult = 2; 13209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.WChar && (Flags & WCHARSUPPORT)) AddResult = 2; 13309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.AltiVec && (Flags & KEYALTIVEC)) AddResult = 2; 13409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.OpenCL && (Flags & KEYOPENCL)) AddResult = 2; 13509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (!LangOpts.CPlusPlus && (Flags & KEYNOCXX)) AddResult = 2; 13609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.C11 && (Flags & KEYC11)) AddResult = 2; 1377a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao // We treat bridge casts as objective-C keywords so we can warn on them 138275b1e98bb949643d35546f10f8b1af009349526Jason Sams // in non-arc mode. 13909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.ObjC2 && (Flags & KEYARC)) AddResult = 2; 14009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams else if (LangOpts.CPlusPlus && (Flags & KEYCXX11)) AddResult = 3; 14109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 14209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // Don't add this keyword under MicrosoftMode. 14309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (LangOpts.MicrosoftMode && (Flags & KEYNOMS)) 14409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams return; 14509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // Don't add this keyword if disabled in this language. 1467a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (AddResult == 0) return; 147275b1e98bb949643d35546f10f8b1af009349526Jason Sams 14809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams IdentifierInfo &Info = 14909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams Table.get(Keyword, AddResult == 3 ? tok::identifier : TokenCode); 15009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams Info.setIsExtensionToken(AddResult == 1); 15109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams Info.setIsCXX11CompatKeyword(AddResult == 3); 15209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams} 15309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 15409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative 1557a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao/// representations. 156275b1e98bb949643d35546f10f8b1af009349526Jason Samsstatic void AddCXXOperatorKeyword(StringRef Keyword, 1572a63bf6c293d89c8e3725cfb7ee2add3dd3f0246Jason Sams tok::TokenKind TokenCode, 1587fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams IdentifierTable &Table) { 1597fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams IdentifierInfo &Info = Table.get(Keyword, TokenCode); 1607fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams Info.setIsCPlusPlusOperatorKeyword(); 1617fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 16209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 16309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector" 16409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// or "property". 16509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Samsstatic void AddObjCKeyword(StringRef Name, 16609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams tok::ObjCKeywordKind ObjCID, 16709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams IdentifierTable &Table) { 16809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams Table.get(Name).setObjCKeywordID(ObjCID); 16909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams} 17009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 17109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams/// AddKeywords - Add all keywords to the symbol table. 1727a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao/// 1737a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liaovoid IdentifierTable::AddKeywords(const LangOptions &LangOpts) { 1741d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // Add keywords and tokens for the current language. 1751d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams#define KEYWORD(NAME, FLAGS) \ 1761d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams AddKeyword(StringRef(#NAME), tok::kw_ ## NAME, \ 1777a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao FLAGS, LangOpts, *this); 1787a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao#define ALIAS(NAME, TOK, FLAGS) \ 1791d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams AddKeyword(StringRef(NAME), tok::kw_ ## TOK, \ 1801d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams FLAGS, LangOpts, *this); 1811d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams#define CXX_KEYWORD_OPERATOR(NAME, ALIAS) \ 1827a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (LangOpts.CXXOperatorNames) \ 1837a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this); 1847fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams#define OBJC1_AT_KEYWORD(NAME) \ 18509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (LangOpts.ObjC1) \ 18609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 18709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#define OBJC2_AT_KEYWORD(NAME) \ 18809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (LangOpts.ObjC2) \ 18909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this); 19009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#define TESTING_KEYWORD(NAME, FLAGS) 19109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#include "clang/Basic/TokenKinds.def" 19209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 19309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (LangOpts.ParseUnknownAnytype) 19409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL, 19509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams LangOpts, *this); 1961d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 1971d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 1981d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samstok::PPKeywordKind IdentifierInfo::getPPKeywordID() const { 19909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // We use a perfect hash function here involving the length of the keyword, 20009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // the first and third character. For preprocessor ID's there are no 2011d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // collisions (if there were, the switch below would complain about duplicate 2021d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // case values). Note that this depends on 'if' being null terminated. 2031d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2047a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao#define HASH(LEN, FIRST, THIRD) \ 2057a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao (LEN << 5) + (((FIRST-'a') + (THIRD-'a')) & 31) 2067fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams#define CASE(LEN, FIRST, THIRD, NAME) \ 20709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams case HASH(LEN, FIRST, THIRD): \ 20809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME 20909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 21009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams unsigned Len = getLength(); 21109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (Len < 2) return tok::pp_not_keyword; 212693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams const char *Name = getNameStart(); 2131d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams switch (HASH(Len, Name[0], Name[2])) { 2141d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams default: return tok::pp_not_keyword; 2151d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 2, 'i', '\0', if); 216693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams CASE( 4, 'e', 'i', elif); 2171d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 4, 'e', 's', else); 2181d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 4, 'l', 'n', line); 2191d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 4, 's', 'c', sccs); 220693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams CASE( 5, 'e', 'd', endif); 22109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams CASE( 5, 'e', 'r', error); 22209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams CASE( 5, 'i', 'e', ident); 22309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams CASE( 5, 'i', 'd', ifdef); 22409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams CASE( 5, 'u', 'd', undef); 22509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 22609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams CASE( 6, 'a', 's', assert); 227693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams CASE( 6, 'd', 'f', define); 2281d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 6, 'i', 'n', ifndef); 2291d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 6, 'i', 'p', import); 2301d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 6, 'p', 'a', pragma); 231693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 2321d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 7, 'd', 'f', defined); 2331d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 7, 'i', 'c', include); 2341d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 7, 'w', 'r', warning); 235693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 2361d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE( 8, 'u', 'a', unassert); 2371d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE(12, 'i', 'c', include_next); 2381d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2391d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE(14, '_', 'p', __public_macro); 2401d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2411d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE(15, '_', 'p', __private_macro); 2421d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2431d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams CASE(16, '_', 'i', __include_macros); 24409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#undef CASE 24509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams#undef HASH 24609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams } 24709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams} 24809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 24909aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams//===----------------------------------------------------------------------===// 250693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams// Stats Implementation 2511d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams//===----------------------------------------------------------------------===// 2521d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2531d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// PrintStats - Print statistics about how well the identifier table is doing 254693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams/// at hashing identifiers. 2551d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samsvoid IdentifierTable::PrintStats() const { 2561d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams unsigned NumBuckets = HashTable.getNumBuckets(); 2571d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams unsigned NumIdentifiers = HashTable.getNumItems(); 258693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers; 2597fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams unsigned AverageIdentifierSize = 0; 26009aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams unsigned MaxIdentifierLength = 0; 26109aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams 26209aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams // TODO: Figure out maximum times an identifier had to probe for -stats. 26309aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator 26409aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams I = HashTable.begin(), E = HashTable.end(); I != E; ++I) { 26509aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams unsigned IdLen = I->getKeyLength(); 26609aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams AverageIdentifierSize += IdLen; 26709aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams if (MaxIdentifierLength < IdLen) 26809aeb8ac1b0b976c2de40dd00da0c6841e4e882aJason Sams MaxIdentifierLength = IdLen; 269693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams } 270693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 2717fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams fprintf(stderr, "\n*** Identifier Table Stats:\n"); 2721d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams fprintf(stderr, "# Identifiers: %d\n", NumIdentifiers); 2731d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets); 2741d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams fprintf(stderr, "Hash density (#identifiers per bucket): %f\n", 2751d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams NumIdentifiers/(double)NumBuckets); 2761d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams fprintf(stderr, "Ave identifier length: %f\n", 2771d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams (AverageIdentifierSize/(double)NumIdentifiers)); 2781d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength); 2791d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 280693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams // Compute statistics about the memory allocated for identifiers. 281693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams HashTable.getAllocator().PrintStats(); 2827fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 2831d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2841d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams//===----------------------------------------------------------------------===// 2851d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams// SelectorTable Implementation 2861d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams//===----------------------------------------------------------------------===// 2871d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 2881d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samsunsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) { 2891d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr()); 2901d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 291693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 292693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsnamespace clang { 2937fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams/// MultiKeywordSelector - One of these variable length records is kept for each 2941d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// selector containing more than one keyword. We use a folding set 2951d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// to unique aggregate names (keyword selectors in ObjC parlance). Access to 2961d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// this class is provided strictly through Selector. 2971d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samsclass MultiKeywordSelector 2981d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams : public DeclarationNameExtra, public llvm::FoldingSetNode { 2991d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams MultiKeywordSelector(unsigned nKeys) { 3001d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; 301693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams } 302693080efdafbf49d675fe5f959f0286f83b30c81Jason Samspublic: 3031d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // Constructor for keyword selectors. 3041d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) { 3051d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams assert((nKeys > 1) && "not a multi-keyword selector"); 306693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; 307693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 3081d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // Fill in the trailing keyword array. 3091d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams IdentifierInfo **KeyInfo = reinterpret_cast<IdentifierInfo **>(this+1); 3101d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams for (unsigned i = 0; i != nKeys; ++i) 311693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams KeyInfo[i] = IIV[i]; 312693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams } 3137fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 3141d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // getName - Derive the full selector name and return it. 3151d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams std::string getName() const; 3161d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3171d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; } 3181d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3191d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams typedef IdentifierInfo *const *keyword_iterator; 3201d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams keyword_iterator keyword_begin() const { 3211d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return reinterpret_cast<keyword_iterator>(this+1); 3221d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3231d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams keyword_iterator keyword_end() const { 3241d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return keyword_begin()+getNumArgs(); 3251d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3261d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const { 3271d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index"); 3281d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return keyword_begin()[i]; 3291d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 330693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams static void Profile(llvm::FoldingSetNodeID &ID, 331693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams keyword_iterator ArgTys, unsigned NumArgs) { 3327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams ID.AddInteger(NumArgs); 3331d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams for (unsigned i = 0; i != NumArgs; ++i) 3341d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams ID.AddPointer(ArgTys[i]); 3351d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3361d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams void Profile(llvm::FoldingSetNodeID &ID) { 3371d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams Profile(ID, keyword_begin(), getNumArgs()); 3381d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3391d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams}; 3401d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} // end namespace clang. 3411d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 342693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsunsigned Selector::getNumArgs() const { 343693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams unsigned IIF = getIdentifierInfoFlag(); 3447fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams if (IIF <= ZeroArg) 3451d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return 0; 3461d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (IIF == OneArg) 3471d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return 1; 3481d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // We point to a MultiKeywordSelector. 3491d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams MultiKeywordSelector *SI = getMultiKeywordSelector(); 3501d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return SI->getNumArgs(); 3511d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 3521d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 353693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsIdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const { 354693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams if (getIdentifierInfoFlag() < MultiArg) { 3557fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams assert(argIndex == 0 && "illegal keyword index"); 3561d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return getAsIdentifierInfo(); 3571d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3581d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // We point to a MultiKeywordSelector. 3591d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams MultiKeywordSelector *SI = getMultiKeywordSelector(); 3601d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return SI->getIdentifierInfoForSlot(argIndex); 3611d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 3621d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3631d526a448325cd9678b12b7de9263a254ec8fdc8Jason SamsStringRef Selector::getNameForSlot(unsigned int argIndex) const { 364693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams IdentifierInfo *II = getIdentifierInfoForSlot(argIndex); 365693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams return II? II->getName() : StringRef(); 3667fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams} 3671d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3681d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samsstd::string MultiKeywordSelector::getName() const { 3691d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams SmallString<256> Str; 3701d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams llvm::raw_svector_ostream OS(Str); 3711d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) { 3721d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (*I) 3731d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams OS << (*I)->getName(); 3741d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams OS << ':'; 3751d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3761d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3771d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return OS.str(); 378693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams} 379693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 3807fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Samsstd::string Selector::getAsString() const { 3811d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (InfoPtr == 0) 3821d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return "<null selector>"; 3831d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3841d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (getIdentifierInfoFlag() < MultiArg) { 3851d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams IdentifierInfo *II = getAsIdentifierInfo(); 3861d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3871d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // If the number of arguments is 0 then II is guaranteed to not be null. 3881d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (getNumArgs() == 0) 3891d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return II->getName(); 3901d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3911d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (!II) 392693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams return ":"; 393693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 3947fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams return II->getName().str() + ":"; 3951d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 3961d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 3971d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // We have a multiple keyword selector. 3981d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return getMultiKeywordSelector()->getName(); 3991d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 4001d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 4011d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// Interpreting the given string using the normal CamelCase 4021d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// conventions, determine whether the given string starts with the 4031d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams/// given "word", which is assumed to end in a lowercase letter. 404693080efdafbf49d675fe5f959f0286f83b30c81Jason Samsstatic bool startsWithWord(StringRef name, StringRef word) { 405693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams if (name.size() < word.size()) return false; 406c8dc45cc95cd144038c153f3a4657527d5a7c0b6Alex Sakhartchouk return ((name.size() == word.size() || !isLowercase(name[word.size()])) && 407eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams name.startswith(word)); 4081d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 4091d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 4101d526a448325cd9678b12b7de9263a254ec8fdc8Jason SamsObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) { 4111d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams IdentifierInfo *first = sel.getIdentifierInfoForSlot(0); 4127a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (!first) return OMF_None; 4137a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao 4147fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams StringRef name = first->getName(); 4151d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (sel.isUnarySelector()) { 4161d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (name == "autorelease") return OMF_autorelease; 4171d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (name == "dealloc") return OMF_dealloc; 4187a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (name == "finalize") return OMF_finalize; 4197a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (name == "release") return OMF_release; 4207fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams if (name == "retain") return OMF_retain; 4211d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (name == "retainCount") return OMF_retainCount; 4221d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (name == "self") return OMF_self; 4231d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 4247a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao 4257a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (name == "performSelector") return OMF_performSelector; 4267fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 4271d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // The other method families may begin with a prefix of underscores. 4281d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams while (!name.empty() && name.front() == '_') 4291d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams name = name.substr(1); 4307a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao 4317a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (name.empty()) return OMF_None; 4327fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams switch (name.front()) { 4331d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams case 'a': 4341d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (startsWithWord(name, "alloc")) return OMF_alloc; 4351d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams break; 4367a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao case 'c': 4377a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (startsWithWord(name, "copy")) return OMF_copy; 4387fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams break; 4391d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams case 'i': 4401d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (startsWithWord(name, "init")) return OMF_init; 4411d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams break; 4427a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao case 'm': 4437a43031a3f3e06f0257b507d5f197afaa21e2a3aShih-wei Liao if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy; 444eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams break; 4451d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams case 'n': 4461d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (startsWithWord(name, "new")) return OMF_new; 4471d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams break; 4481d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams default: 449eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams break; 450eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams } 451eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams 4521d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return OMF_None; 4531d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 4541d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 455eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason SamsObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) { 456eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams IdentifierInfo *first = sel.getIdentifierInfoForSlot(0); 457eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams if (!first) return OIT_None; 4581d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 4591d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams StringRef name = first->getName(); 4601d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 461eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams if (name.empty()) return OIT_None; 462eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams switch (name.front()) { 463eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams case 'a': 4641d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (startsWithWord(name, "alloc")) return OIT_MemManage; 4651d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams else 4661d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (startsWithWord(name, "array")) return OIT_Array; 467eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams break; 468eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams case 'd': 469eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams if (startsWithWord(name, "dictionary")) return OIT_Dictionary; 4701d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams break; 4711d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams case 'i': 4721d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (startsWithWord(name, "init")) return OIT_MemManage; 473eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams break; 474eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams case 'r': 475eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams if (startsWithWord(name, "retain")) return OIT_MemManage; 4761d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams break; 4771d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams default: 4781d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams break; 479eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams } 480eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams return OIT_None; 481eb0dfedaf861049858a365d56d67cc85bfcad3c3Jason Sams} 4827fe6bce13c30b8d14dc833e06468666d28e56ee1Jason Sams 4831d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samsnamespace { 4841d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams struct SelectorTableImpl { 4851d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams llvm::FoldingSet<MultiKeywordSelector> Table; 4861d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams llvm::BumpPtrAllocator Allocator; 4871d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams }; 4881d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} // end anonymous namespace. 489693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams 4901d526a448325cd9678b12b7de9263a254ec8fdc8Jason Samsstatic SelectorTableImpl &getSelectorTableImpl(void *P) { 4911d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return *static_cast<SelectorTableImpl*>(P); 4921d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 4931d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 4941d526a448325cd9678b12b7de9263a254ec8fdc8Jason SamsSmallString<64> 4951d526a448325cd9678b12b7de9263a254ec8fdc8Jason SamsSelectorTable::constructSetterName(StringRef Name) { 496693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams SmallString<64> SetterName("set"); 4971d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams SetterName += Name; 4981d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams SetterName[3] = toUppercase(SetterName[3]); 4991d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return SetterName; 5001d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 5011d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 5021d526a448325cd9678b12b7de9263a254ec8fdc8Jason SamsSelector 503693080efdafbf49d675fe5f959f0286f83b30c81Jason SamsSelectorTable::constructSetterSelector(IdentifierTable &Idents, 5041d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams SelectorTable &SelTable, 5051d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams const IdentifierInfo *Name) { 5061d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams IdentifierInfo *SetterName = 507693080efdafbf49d675fe5f959f0286f83b30c81Jason Sams &Idents.get(constructSetterName(Name->getName())); 5081d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return SelTable.getUnarySelector(SetterName); 5091d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 5101d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 511693080efdafbf49d675fe5f959f0286f83b30c81Jason Samssize_t SelectorTable::getTotalMemory() const { 51220c6c1febce7cdf398c58287bf506b3a4a210285Alex Sakhartchouk SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); 51329858059ffff967607f7583ae9146dc4c720f92eAlex Sakhartchouk return SelTabImpl.Allocator.getTotalMemory(); 5147e90cb90349e7e5b0cef362781830d519c20200aJason Sams} 5157e90cb90349e7e5b0cef362781830d519c20200aJason Sams 5167e90cb90349e7e5b0cef362781830d519c20200aJason SamsSelector SelectorTable::getSelector(unsigned nKeys, IdentifierInfo **IIV) { 5171d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams if (nKeys < 2) 5181d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams return Selector(IIV[0], nKeys); 5191d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 5201d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl); 5211d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 5221d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // Unique selector, to guarantee there is one per name. 5231d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams llvm::FoldingSetNodeID ID; 5241cd2f783e4ad6d962c81aca59960fd8f2e774ad1Stephen Hines MultiKeywordSelector::Profile(ID, IIV, nKeys); 5257e90cb90349e7e5b0cef362781830d519c20200aJason Sams 5267e90cb90349e7e5b0cef362781830d519c20200aJason Sams void *InsertPos = 0; 5277e90cb90349e7e5b0cef362781830d519c20200aJason Sams if (MultiKeywordSelector *SI = 5287e90cb90349e7e5b0cef362781830d519c20200aJason Sams SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos)) 5297e90cb90349e7e5b0cef362781830d519c20200aJason Sams return Selector(SI); 5307e90cb90349e7e5b0cef362781830d519c20200aJason Sams 5317e90cb90349e7e5b0cef362781830d519c20200aJason Sams // MultiKeywordSelector objects are not allocated with new because they have a 5321d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams // variable size array (for parameter types) at the end of them. 5331d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *); 5341d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams MultiKeywordSelector *SI = 5351d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams (MultiKeywordSelector*)SelTabImpl.Allocator.Allocate(Size, 5361d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams llvm::alignOf<MultiKeywordSelector>()); 5371cd2f783e4ad6d962c81aca59960fd8f2e774ad1Stephen Hines new (SI) MultiKeywordSelector(nKeys, IIV); 5387e90cb90349e7e5b0cef362781830d519c20200aJason Sams SelTabImpl.Table.InsertNode(SI, InsertPos); 5397e90cb90349e7e5b0cef362781830d519c20200aJason Sams return Selector(SI); 5407e90cb90349e7e5b0cef362781830d519c20200aJason Sams} 5417e90cb90349e7e5b0cef362781830d519c20200aJason Sams 5427e90cb90349e7e5b0cef362781830d519c20200aJason SamsSelectorTable::SelectorTable() { 5437e90cb90349e7e5b0cef362781830d519c20200aJason Sams Impl = new SelectorTableImpl(); 5447e90cb90349e7e5b0cef362781830d519c20200aJason Sams} 5451d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 5461d526a448325cd9678b12b7de9263a254ec8fdc8Jason SamsSelectorTable::~SelectorTable() { 5471d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams delete &getSelectorTableImpl(Impl); 5481d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 5491d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 5501cd2f783e4ad6d962c81aca59960fd8f2e774ad1Stephen Hinesconst char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) { 5517e90cb90349e7e5b0cef362781830d519c20200aJason Sams switch (Operator) { 5527e90cb90349e7e5b0cef362781830d519c20200aJason Sams case OO_None: 5537e90cb90349e7e5b0cef362781830d519c20200aJason Sams case NUM_OVERLOADED_OPERATORS: 5547e90cb90349e7e5b0cef362781830d519c20200aJason Sams return 0; 5557e90cb90349e7e5b0cef362781830d519c20200aJason Sams 5567e90cb90349e7e5b0cef362781830d519c20200aJason Sams#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \ 5577e90cb90349e7e5b0cef362781830d519c20200aJason Sams case OO_##Name: return Spelling; 5581d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams#include "clang/Basic/OperatorKinds.def" 5591d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams } 5601d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams 5611d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams llvm_unreachable("Invalid OverloadedOperatorKind!"); 5621d526a448325cd9678b12b7de9263a254ec8fdc8Jason Sams} 5631cd2f783e4ad6d962c81aca59960fd8f2e774ad1Stephen Hines