[AMDGPU][True16][CodeGen] true16 codegen pattern for v_med3_u/i16 (#121850)
[llvm-project.git] / clang / tools / c-index-test / core_main.cpp
blob327a77a09408baa5a44cf9b8b0cd6ad2ed7f7c83
1 //===-- core_main.cpp - Core Index Tool testbed ---------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "clang/AST/Mangle.h"
10 #include "clang/Basic/LangOptions.h"
11 #include "clang/Frontend/ASTUnit.h"
12 #include "clang/Frontend/CompilerInstance.h"
13 #include "clang/Frontend/CompilerInvocation.h"
14 #include "clang/Frontend/FrontendAction.h"
15 #include "clang/Frontend/Utils.h"
16 #include "clang/Index/IndexDataConsumer.h"
17 #include "clang/Index/IndexingAction.h"
18 #include "clang/Index/USRGeneration.h"
19 #include "clang/Lex/Preprocessor.h"
20 #include "clang/Serialization/ASTReader.h"
21 #include "clang/Serialization/ObjectFilePCHContainerReader.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/PrettyStackTrace.h"
25 #include "llvm/Support/Program.h"
26 #include "llvm/Support/Signals.h"
27 #include "llvm/Support/StringSaver.h"
28 #include "llvm/Support/VirtualFileSystem.h"
29 #include "llvm/Support/raw_ostream.h"
31 using namespace clang;
32 using namespace clang::index;
33 using namespace llvm;
35 extern "C" int indextest_core_main(int argc, const char **argv);
36 extern "C" int indextest_perform_shell_execution(const char *command_line);
38 namespace {
40 enum class ActionType {
41 None,
42 PrintSourceSymbols,
45 namespace options {
47 static cl::OptionCategory IndexTestCoreCategory("index-test-core options");
49 static cl::opt<ActionType>
50 Action(cl::desc("Action:"), cl::init(ActionType::None),
51 cl::values(
52 clEnumValN(ActionType::PrintSourceSymbols,
53 "print-source-symbols", "Print symbols from source")),
54 cl::cat(IndexTestCoreCategory));
56 static cl::extrahelp MoreHelp(
57 "\nAdd \"-- <compiler arguments>\" at the end to setup the compiler "
58 "invocation\n"
61 static cl::opt<bool>
62 DumpModuleImports("dump-imported-module-files",
63 cl::desc("Print symbols and input files from imported modules"));
65 static cl::opt<bool>
66 IncludeLocals("include-locals", cl::desc("Print local symbols"));
68 static cl::opt<bool> IgnoreMacros("ignore-macros",
69 cl::desc("Skip indexing macros"));
71 static cl::opt<std::string>
72 ModuleFilePath("module-file",
73 cl::desc("Path to module file to print symbols from"));
74 static cl::opt<std::string>
75 ModuleFormat("fmodule-format", cl::init("raw"),
76 cl::desc("Container format for clang modules and PCH, 'raw' or 'obj'"));
79 } // anonymous namespace
81 static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS);
82 static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx,
83 raw_ostream &OS);
84 static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS);
86 namespace {
88 class PrintIndexDataConsumer : public IndexDataConsumer {
89 raw_ostream &OS;
90 std::unique_ptr<ASTNameGenerator> ASTNameGen;
91 std::shared_ptr<Preprocessor> PP;
93 public:
94 PrintIndexDataConsumer(raw_ostream &OS) : OS(OS) {
97 void initialize(ASTContext &Ctx) override {
98 ASTNameGen.reset(new ASTNameGenerator(Ctx));
101 void setPreprocessor(std::shared_ptr<Preprocessor> PP) override {
102 this->PP = std::move(PP);
105 bool handleDeclOccurrence(const Decl *D, SymbolRoleSet Roles,
106 ArrayRef<SymbolRelation> Relations,
107 SourceLocation Loc, ASTNodeInfo ASTNode) override {
108 ASTContext &Ctx = D->getASTContext();
109 SourceManager &SM = Ctx.getSourceManager();
111 Loc = SM.getFileLoc(Loc);
112 FileID FID = SM.getFileID(Loc);
113 unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc));
114 unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc));
115 OS << Line << ':' << Col << " | ";
117 printSymbolInfo(getSymbolInfo(D), OS);
118 OS << " | ";
120 printSymbolNameAndUSR(D, Ctx, OS);
121 OS << " | ";
123 if (ASTNameGen->writeName(D, OS))
124 OS << "<no-cgname>";
125 OS << " | ";
127 printSymbolRoles(Roles, OS);
128 OS << " | ";
130 OS << "rel: " << Relations.size() << '\n';
132 for (auto &SymRel : Relations) {
133 OS << '\t';
134 printSymbolRoles(SymRel.Roles, OS);
135 OS << " | ";
136 printSymbolNameAndUSR(SymRel.RelatedSymbol, Ctx, OS);
137 OS << '\n';
140 return true;
143 bool handleModuleOccurrence(const ImportDecl *ImportD,
144 const clang::Module *Mod, SymbolRoleSet Roles,
145 SourceLocation Loc) override {
146 ASTContext &Ctx = ImportD->getASTContext();
147 SourceManager &SM = Ctx.getSourceManager();
149 Loc = SM.getFileLoc(Loc);
150 FileID FID = SM.getFileID(Loc);
151 unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc));
152 unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc));
153 OS << Line << ':' << Col << " | ";
155 printSymbolInfo(getSymbolInfo(ImportD), OS);
156 OS << " | ";
158 printSymbolNameAndUSR(Mod, OS);
159 OS << " | ";
161 printSymbolRoles(Roles, OS);
162 OS << " |\n";
164 return true;
167 bool handleMacroOccurrence(const IdentifierInfo *Name, const MacroInfo *MI,
168 SymbolRoleSet Roles, SourceLocation Loc) override {
169 assert(PP);
170 SourceManager &SM = PP->getSourceManager();
172 Loc = SM.getFileLoc(Loc);
173 FileID FID = SM.getFileID(Loc);
174 unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc));
175 unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc));
176 OS << Line << ':' << Col << " | ";
178 printSymbolInfo(getSymbolInfoForMacro(*MI), OS);
179 OS << " | ";
181 OS << Name->getName();
182 OS << " | ";
184 SmallString<256> USRBuf;
185 if (generateUSRForMacro(Name->getName(), MI->getDefinitionLoc(), SM,
186 USRBuf)) {
187 OS << "<no-usr>";
188 } else {
189 OS << USRBuf;
191 OS << " | ";
193 printSymbolRoles(Roles, OS);
194 OS << " |\n";
195 return true;
199 } // anonymous namespace
201 //===----------------------------------------------------------------------===//
202 // Print Source Symbols
203 //===----------------------------------------------------------------------===//
205 static void dumpModuleFileInputs(serialization::ModuleFile &Mod,
206 ASTReader &Reader,
207 raw_ostream &OS) {
208 OS << "---- Module Inputs ----\n";
209 Reader.visitInputFiles(Mod, /*IncludeSystem=*/true, /*Complain=*/false,
210 [&](const serialization::InputFile &IF, bool isSystem) {
211 OS << (isSystem ? "system" : "user") << " | ";
212 OS << IF.getFile()->getName() << '\n';
216 static bool printSourceSymbols(const char *Executable,
217 ArrayRef<const char *> Args,
218 bool dumpModuleImports, bool indexLocals,
219 bool ignoreMacros) {
220 SmallVector<const char *, 4> ArgsWithProgName;
221 ArgsWithProgName.push_back(Executable);
222 ArgsWithProgName.append(Args.begin(), Args.end());
223 IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
224 CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
225 new DiagnosticOptions));
226 CreateInvocationOptions CIOpts;
227 CIOpts.Diags = Diags;
228 CIOpts.ProbePrecompiled = true; // FIXME: historical default. Needed?
229 auto CInvok = createInvocation(ArgsWithProgName, std::move(CIOpts));
230 if (!CInvok)
231 return true;
233 raw_ostream &OS = outs();
234 auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(OS);
235 IndexingOptions IndexOpts;
236 IndexOpts.IndexFunctionLocals = indexLocals;
237 IndexOpts.IndexMacros = !ignoreMacros;
238 IndexOpts.IndexMacrosInPreprocessor = !ignoreMacros;
239 std::unique_ptr<FrontendAction> IndexAction =
240 createIndexingAction(DataConsumer, IndexOpts);
242 auto PCHContainerOps = std::make_shared<PCHContainerOperations>();
243 std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
244 std::move(CInvok), PCHContainerOps, Diags, IndexAction.get()));
246 if (!Unit)
247 return true;
249 if (dumpModuleImports) {
250 if (auto Reader = Unit->getASTReader()) {
251 Reader->getModuleManager().visit([&](serialization::ModuleFile &Mod) -> bool {
252 OS << "==== Module " << Mod.ModuleName << " ====\n";
253 indexModuleFile(Mod, *Reader, *DataConsumer, IndexOpts);
254 dumpModuleFileInputs(Mod, *Reader, OS);
255 return true; // skip module dependencies.
260 return false;
263 static bool printSourceSymbolsFromModule(StringRef modulePath,
264 StringRef format) {
265 FileSystemOptions FileSystemOpts;
266 auto pchContOps = std::make_shared<PCHContainerOperations>();
267 // Register the support for object-file-wrapped Clang modules.
268 pchContOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>());
269 auto pchRdr = pchContOps->getReaderOrNull(format);
270 if (!pchRdr) {
271 errs() << "unknown module format: " << format << '\n';
272 return true;
275 auto HSOpts = std::make_shared<HeaderSearchOptions>();
277 IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
278 CompilerInstance::createDiagnostics(*llvm::vfs::getRealFileSystem(),
279 new DiagnosticOptions());
280 std::unique_ptr<ASTUnit> AU =
281 ASTUnit::LoadFromASTFile(modulePath, *pchRdr, ASTUnit::LoadASTOnly, Diags,
282 FileSystemOpts, HSOpts, /*LangOpts=*/nullptr,
283 /*OnlyLocalDecls=*/true, CaptureDiagsKind::None,
284 /*AllowASTWithCompilerErrors=*/true,
285 /*UserFilesAreVolatile=*/false);
286 if (!AU) {
287 errs() << "failed to create TU for: " << modulePath << '\n';
288 return true;
291 PrintIndexDataConsumer DataConsumer(outs());
292 IndexingOptions IndexOpts;
293 indexASTUnit(*AU, DataConsumer, IndexOpts);
295 return false;
298 //===----------------------------------------------------------------------===//
299 // Helper Utils
300 //===----------------------------------------------------------------------===//
302 static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) {
303 OS << getSymbolKindString(SymInfo.Kind);
304 if (SymInfo.SubKind != SymbolSubKind::None)
305 OS << '/' << getSymbolSubKindString(SymInfo.SubKind);
306 if (SymInfo.Properties) {
307 OS << '(';
308 printSymbolProperties(SymInfo.Properties, OS);
309 OS << ')';
311 OS << '/' << getSymbolLanguageString(SymInfo.Lang);
314 static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx,
315 raw_ostream &OS) {
316 if (printSymbolName(D, Ctx.getLangOpts(), OS)) {
317 OS << "<no-name>";
319 OS << " | ";
321 SmallString<256> USRBuf;
322 if (generateUSRForDecl(D, USRBuf)) {
323 OS << "<no-usr>";
324 } else {
325 OS << USRBuf;
329 static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS) {
330 assert(Mod);
331 OS << Mod->getFullModuleName() << " | ";
332 generateFullUSRForModule(Mod, OS);
335 //===----------------------------------------------------------------------===//
336 // Command line processing.
337 //===----------------------------------------------------------------------===//
339 int indextest_core_main(int argc, const char **argv) {
340 sys::PrintStackTraceOnErrorSignal(argv[0]);
341 PrettyStackTraceProgram X(argc, argv);
342 void *MainAddr = (void*) (intptr_t) indextest_core_main;
343 std::string Executable = llvm::sys::fs::getMainExecutable(argv[0], MainAddr);
345 assert(argv[1] == StringRef("core"));
346 ++argv;
347 --argc;
349 std::vector<const char *> CompArgs;
350 const char **DoubleDash = std::find(argv, argv + argc, StringRef("--"));
351 if (DoubleDash != argv + argc) {
352 CompArgs = std::vector<const char *>(DoubleDash + 1, argv + argc);
353 argc = DoubleDash - argv;
356 cl::HideUnrelatedOptions(options::IndexTestCoreCategory);
357 cl::ParseCommandLineOptions(argc, argv, "index-test-core");
359 if (options::Action == ActionType::None) {
360 errs() << "error: action required; pass '-help' for options\n";
361 return 1;
364 if (options::Action == ActionType::PrintSourceSymbols) {
365 if (!options::ModuleFilePath.empty()) {
366 return printSourceSymbolsFromModule(options::ModuleFilePath,
367 options::ModuleFormat);
369 if (CompArgs.empty()) {
370 errs() << "error: missing compiler args; pass '-- <compiler arguments>'\n";
371 return 1;
373 return printSourceSymbols(Executable.c_str(), CompArgs,
374 options::DumpModuleImports,
375 options::IncludeLocals, options::IgnoreMacros);
378 return 0;
381 //===----------------------------------------------------------------------===//
382 // Utility functions
383 //===----------------------------------------------------------------------===//
385 int indextest_perform_shell_execution(const char *command_line) {
386 BumpPtrAllocator Alloc;
387 llvm::StringSaver Saver(Alloc);
388 SmallVector<const char *, 4> Args;
389 llvm::cl::TokenizeGNUCommandLine(command_line, Saver, Args);
390 auto Program = llvm::sys::findProgramByName(Args[0]);
391 if (std::error_code ec = Program.getError()) {
392 llvm::errs() << "command not found: " << Args[0] << "\n";
393 return ec.value();
395 SmallVector<StringRef, 8> execArgs(Args.begin(), Args.end());
396 return llvm::sys::ExecuteAndWait(*Program, execArgs);