void WebCLPreprocessorAction::ExecuteAction() { clang::CompilerInstance &instance = getCompilerInstance(); if (!initialize(instance)) return; clang::PreprocessorOutputOptions& options = instance.getPreprocessorOutputOpts(); options.ShowComments = 1; options.ShowLineMarkers = 0; clang::DoPrintPreprocessedInput( instance.getPreprocessor(), out_, options); out_->flush(); // Iterate over all identifier tokens found in the source, to collect // identifiers which might be calls to builtin functions, and then // forward-declare the builtin functions with that name, if any WebCLBuiltins builtins; llvm::raw_string_ostream builtinOut(builtinDecls_); clang::IdentifierTable& identifiers = instance.getPreprocessor().getIdentifierTable(); for (clang::IdentifierTable::const_iterator i = identifiers.begin(); i != identifiers.end(); ++i) { // Ignore identifiers that start with __ (no OpenCL builtin is like that, but a lot of Clang // internal misc are), and also identifiers the preprocessor has to handle in some way, // e.g. macros to expand, trigraph sequences to normalize and so on. // (The preprocessor has already done its magic and inserted the expansions to the // identifier table at this point so we get them that way) if (!i->first().startswith("__") && !i->second->isHandleIdentifierCase()) { builtins.emitDeclarations(builtinOut, i->first().str()); } } builtinOut.flush(); }
bool WebCLMatcher1Action::checkIdentifiers() { clang::CompilerInstance &instance = getCompilerInstance(); clang::ASTContext &context = instance.getASTContext(); clang::IdentifierTable &table = context.Idents; const int numPrefixes = 3; const char *prefixes[numPrefixes] = { cfg_.typePrefix_.c_str(), cfg_.variablePrefix_.c_str(), cfg_.macroPrefix_.c_str() }; const size_t lengths[numPrefixes] = { cfg_.typePrefix_.size(), cfg_.variablePrefix_.size(), cfg_.macroPrefix_.size() }; bool status = true; for (clang::IdentifierTable::iterator i = table.begin(); i != table.end(); ++i) { clang::IdentifierInfo *identifier = i->getValue(); const char *name = identifier->getNameStart(); static const unsigned int maxLength = 255; if (identifier->getLength() > maxLength) { reporter_->error("Identifier '%0' exceeds maximum length of %1 characters.") << name << maxLength; status = false; } for (int p = 0; p < numPrefixes ; ++p) { const char *prefix = prefixes[p]; if (!strncmp(prefix, name, lengths[p])) { reporter_->error("Identifier '%0' uses reserved prefix '%1'.") << name << prefix; status = false; } } } return status; }
void WebCLMatcher2Action::ExecuteAction() { clang::CompilerInstance &instance = getCompilerInstance(); WebCLRenamedStructRelocator renamedStructRelocator(instance, *rewriter_); renamedStructRelocator.prepare(finder_); ParseAST(instance.getPreprocessor(), consumer_, instance.getASTContext()); clang::tooling::Replacements &renamedStructRelocations = renamedStructRelocator.complete(); if (!clang::tooling::applyAllReplacements(renamedStructRelocations, *rewriter_)) { reporter_->fatal("Can't relocate renamed structures."); return; } if (!printer_->print(*out_, "// WebCL Validator: matching stage 2.\n")) { reporter_->fatal("Can't print second matcher stage output."); return; } }
void WebCLMatcher1Action::ExecuteAction() { clang::CompilerInstance &instance = getCompilerInstance(); WebCLNamelessStructRenamer namelessStructRenamer(instance, cfg_); namelessStructRenamer.prepare(finder_); ParseAST(instance.getPreprocessor(), consumer_, instance.getASTContext()); clang::tooling::Replacements &namelessStructRenamings = namelessStructRenamer.complete(); if (!checkIdentifiers()) return; if (!clang::tooling::applyAllReplacements(namelessStructRenamings, *rewriter_)) { reporter_->fatal("Can't apply rename nameless structures."); return; } if (!printer_->print(*out_, "// WebCL Validator: matching stage 1.\n")) { reporter_->fatal("Can't print first matcher stage output."); return; } }
void WebCLFindUsedExtensionsAction::ExecuteAction() { clang::CompilerInstance &instance = getCompilerInstance(); ParseAST(instance.getPreprocessor(), consumer_, instance.getASTContext()); }