void HTMLIdentifier::addNames(QualifiedName** names, unsigned namesCount, unsigned indexOffset) { IdentifierTable& table = identifierTable(); for (unsigned i = 0; i < namesCount; ++i) { StringImpl* name = names[i]->localName().impl(); unsigned hash = name->hash(); unsigned index = i + indexOffset; IdentifierEntry entry(index, name); IdentifierTable::AddResult addResult = table.add(hash, entry); maxNameLength = std::max(maxNameLength, name->length()); // Ensure we're using the same hashing algorithm to get and set. ASSERT_UNUSED(addResult, !addResult.isNewEntry || HTMLIdentifier::findIndex(name->characters(), name->length()) == index); // We expect some hash collisions, but only for identical strings. // Since all of these names are AtomicStrings pointers should be equal. // Note: If you hit this ASSERT, then we had a hash collision among // HTMLNames strings, and we need to re-design how we use this hash! ASSERT_UNUSED(addResult, !addResult.isNewEntry || name == addResult.iterator->value.second); } }
unsigned HTMLIdentifier::findIndex(const UChar* characters, unsigned length) { // We don't need to try hashing if we know the string is too long. if (length > maxNameLength) return invalidIndex; // computeHashAndMaskTop8Bits is the function StringImpl::hash() uses. unsigned hash = StringHasher::computeHashAndMaskTop8Bits(characters, length); const IdentifierTable& table = identifierTable(); ASSERT(!table.isEmpty()); IdentifierTable::const_iterator it = table.find(hash); if (it == table.end()) return invalidIndex; // It's possible to have hash collisions between arbitrary strings and // known identifiers (e.g. "bvvfg" collides with "script"). // However ASSERTs in addNames() guard against there ever being collisions // between known identifiers. if (!equal(it->value.second, characters, length)) return invalidIndex; return it->value.first; }
int main() { clang::DiagnosticOptions diagnosticOptions; clang::TextDiagnosticPrinter *pTextDiagnosticPrinter = new clang::TextDiagnosticPrinter( llvm::outs(), diagnosticOptions); llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> pDiagIDs; clang::DiagnosticsEngine *pDiagnosticsEngine = new clang::DiagnosticsEngine(pDiagIDs, pTextDiagnosticPrinter); clang::LangOptions languageOptions; clang::FileSystemOptions fileSystemOptions; clang::FileManager fileManager(fileSystemOptions); clang::SourceManager sourceManager( *pDiagnosticsEngine, fileManager); clang::HeaderSearchOptions headerSearchOptions; // <Warning!!> -- Platform Specific Code lives here // This depends on A) that you're running linux and // B) that you have the same GCC LIBs installed that // I do. // Search through Clang itself for something like this, // go on, you won't find it. The reason why is Clang // has its own versions of std* which are installed under // /usr/local/lib/clang/<version>/include/ // See somewhere around Driver.cpp:77 to see Clang adding // its version of the headers to its include path. headerSearchOptions.AddPath("/usr/include/linux", clang::frontend::Angled, false, false, false); headerSearchOptions.AddPath("/usr/include/c++/4.4/tr1", clang::frontend::Angled, false, false, false); headerSearchOptions.AddPath("/usr/include/c++/4.4", clang::frontend::Angled, false, false, false); // </Warning!!> -- End of Platform Specific Code clang::TargetOptions targetOptions; targetOptions.Triple = llvm::sys::getDefaultTargetTriple(); clang::TargetInfo *pTargetInfo = clang::TargetInfo::CreateTargetInfo( *pDiagnosticsEngine, targetOptions); clang::HeaderSearch headerSearch(fileManager, *pDiagnosticsEngine, languageOptions, pTargetInfo); clang::CompilerInstance compInst; clang::Preprocessor preprocessor( *pDiagnosticsEngine, languageOptions, pTargetInfo, sourceManager, headerSearch, compInst); clang::PreprocessorOptions preprocessorOptions; clang::FrontendOptions frontendOptions; clang::InitializePreprocessor( preprocessor, preprocessorOptions, headerSearchOptions, frontendOptions); const clang::FileEntry *pFile = fileManager.getFile( "input04.c"); sourceManager.createMainFileID(pFile); const clang::TargetInfo &targetInfo = *pTargetInfo; clang::IdentifierTable identifierTable(languageOptions); clang::SelectorTable selectorTable; clang::Builtin::Context builtinContext; builtinContext.InitializeTarget(targetInfo); clang::ASTContext astContext( languageOptions, sourceManager, pTargetInfo, identifierTable, selectorTable, builtinContext, 0 /* size_reserve*/); MyASTConsumer astConsumer; clang::Sema sema( preprocessor, astContext, astConsumer); pTextDiagnosticPrinter->BeginSourceFile(languageOptions, &preprocessor); clang::ParseAST(preprocessor, &astConsumer, astContext); pTextDiagnosticPrinter->EndSourceFile(); return 0; }
int main(int argc, const char **argv, char * const *envp) { // Path void *MainAddr = (void*) (intptr_t) GetExecutablePath; llvm::sys::Path Path = GetExecutablePath(argv[0]); // DiagnosticOptions DiagnosticOptions diagnosticOptions; // DiagnosticClient TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::outs(), diagnosticOptions); // Diagnostic llvm::IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); Diagnostic diagnostic(DiagID, DiagClient); //DiagnosticOptions DiagOpts; //llvm::IntrusiveRefCntPtr<Diagnostic> diagnostic = CompilerInstance::createDiagnostics(DiagOpts, argc, argv); // LangOptions LangOptions langOptions; langOptions.CPlusPlus = 1; langOptions.CPlusPlus0x = 1; langOptions.Microsoft = 1; langOptions.Bool = 1; langOptions.Exceptions = 1; langOptions.CXXExceptions = 1; langOptions.EmitAllDecls = 1; // FileManager FileSystemOptions fileSystemOptions; FileManager fileManager(fileSystemOptions); // SourceManager SourceManager sourceManager(diagnostic, fileManager); // HeadderSearch HeaderSearch headerSearch(fileManager); // TargetOptions TargetOptions targetOptions; targetOptions.Triple = llvm::sys::getHostTriple(); // TargetInfo TargetInfo *pTargetInfo = TargetInfo::CreateTargetInfo( diagnostic, targetOptions); // HeaderSearchOptions HeaderSearchOptions headerSearchOptions; ApplyHeaderSearchOptions( headerSearch, headerSearchOptions, langOptions, pTargetInfo->getTriple()); // Preprocessor Preprocessor preprocessor( diagnostic, langOptions, *pTargetInfo, sourceManager, headerSearch); // PreprocessorOptions PreprocessorOptions preprocessorOptions; preprocessorOptions.DetailedRecord = true; preprocessor.createPreprocessingRecord(); // FrontendOptions FrontendOptions frontendOptions; // InitializePreprocessor InitializePreprocessor( preprocessor, preprocessorOptions, headerSearchOptions, frontendOptions); //preprocessor.SetCommentRetentionState(true, true); // Tutorial const FileEntry *pFile = fileManager.getFile( "test.cpp", true); sourceManager.createMainFileID(pFile); /*preprocessor.EnterMainSourceFile(); Token Tok; do { preprocessor.Lex(Tok); // read one token //if (context.diags.hasErrorOccurred()) // stop lexing/pp on error // break; preprocessor.DumpToken(Tok); // outputs to cerr std::cerr << std::endl; } while (Tok.isNot(tok::eof));*/ const TargetInfo &targetInfo = *pTargetInfo; IdentifierTable identifierTable(langOptions); SelectorTable selectorTable; Builtin::Context builtinContext(targetInfo); ASTContext astContext( langOptions, sourceManager, targetInfo, identifierTable, selectorTable, builtinContext, 0 /* size_reserve*/); // ASTConsumer astConsumer; MyASTConsumer astConsumer; astConsumer.sourceManager = &sourceManager; astConsumer.html = new ClangDocHTML; astConsumer.html->astConsumer = &astConsumer; preprocessor.addPPCallbacks(astConsumer.html); preprocessor.AddCommentHandler(astConsumer.html); Sema sema( preprocessor, astContext, astConsumer); sema.Initialize(); //MySemanticAnalisys mySema( preprocessor, astContext, astConsumer); //Parser parser( preprocessor, sema); //parser.ParseTranslationUnit(); astConsumer.preprocessor = &sema.PP; ParseAST(preprocessor, &astConsumer, astContext); return 0; }
bool HTMLIdentifier::hasIndex(const StringImpl* string) { const IdentifierTable& table = identifierTable(); return table.contains(string->hash()); }