diff options
author | 2020-08-03 14:31:31 +0000 | |
---|---|---|
committer | 2020-08-03 14:31:31 +0000 | |
commit | e5dd70708596ae51455a0ffa086a00c5b29f8583 (patch) | |
tree | 5d676f27b570bacf71e786c3b5cff3e6f6679b59 /gnu/llvm/clang/tools/c-index-test/core_main.cpp | |
parent | Import LLVM 10.0.0 release including clang, lld and lldb. (diff) | |
download | wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.tar.xz wireguard-openbsd-e5dd70708596ae51455a0ffa086a00c5b29f8583.zip |
Import LLVM 10.0.0 release including clang, lld and lldb.
ok hackroom
tested by plenty
Diffstat (limited to 'gnu/llvm/clang/tools/c-index-test/core_main.cpp')
-rw-r--r-- | gnu/llvm/clang/tools/c-index-test/core_main.cpp | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/gnu/llvm/clang/tools/c-index-test/core_main.cpp b/gnu/llvm/clang/tools/c-index-test/core_main.cpp new file mode 100644 index 00000000000..c4025080124 --- /dev/null +++ b/gnu/llvm/clang/tools/c-index-test/core_main.cpp @@ -0,0 +1,362 @@ +//===-- core_main.cpp - Core Index Tool testbed ---------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/Mangle.h" +#include "clang/Basic/LangOptions.h" +#include "clang/CodeGen/ObjectFilePCHContainerOperations.h" +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Index/IndexingAction.h" +#include "clang/Index/IndexDataConsumer.h" +#include "clang/Index/USRGeneration.h" +#include "clang/Lex/Preprocessor.h" +#include "clang/Serialization/ASTReader.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/PrettyStackTrace.h" + +using namespace clang; +using namespace clang::index; +using namespace llvm; + +extern "C" int indextest_core_main(int argc, const char **argv); + +namespace { + +enum class ActionType { + None, + PrintSourceSymbols, +}; + +namespace options { + +static cl::OptionCategory IndexTestCoreCategory("index-test-core options"); + +static cl::opt<ActionType> +Action(cl::desc("Action:"), cl::init(ActionType::None), + cl::values( + clEnumValN(ActionType::PrintSourceSymbols, + "print-source-symbols", "Print symbols from source")), + cl::cat(IndexTestCoreCategory)); + +static cl::extrahelp MoreHelp( + "\nAdd \"-- <compiler arguments>\" at the end to setup the compiler " + "invocation\n" +); + +static cl::opt<bool> +DumpModuleImports("dump-imported-module-files", + cl::desc("Print symbols and input files from imported modules")); + +static cl::opt<bool> +IncludeLocals("include-locals", cl::desc("Print local symbols")); + +static cl::opt<std::string> +ModuleFilePath("module-file", + cl::desc("Path to module file to print symbols from")); +static cl::opt<std::string> + ModuleFormat("fmodule-format", cl::init("raw"), + cl::desc("Container format for clang modules and PCH, 'raw' or 'obj'")); + +} +} // anonymous namespace + +static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS); +static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, + raw_ostream &OS); +static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS); + +namespace { + +class PrintIndexDataConsumer : public IndexDataConsumer { + raw_ostream &OS; + std::unique_ptr<ASTNameGenerator> ASTNameGen; + std::shared_ptr<Preprocessor> PP; + +public: + PrintIndexDataConsumer(raw_ostream &OS) : OS(OS) { + } + + void initialize(ASTContext &Ctx) override { + ASTNameGen.reset(new ASTNameGenerator(Ctx)); + } + + void setPreprocessor(std::shared_ptr<Preprocessor> PP) override { + this->PP = std::move(PP); + } + + bool handleDeclOccurrence(const Decl *D, SymbolRoleSet Roles, + ArrayRef<SymbolRelation> Relations, + SourceLocation Loc, ASTNodeInfo ASTNode) override { + ASTContext &Ctx = D->getASTContext(); + SourceManager &SM = Ctx.getSourceManager(); + + Loc = SM.getFileLoc(Loc); + FileID FID = SM.getFileID(Loc); + unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc)); + unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc)); + OS << Line << ':' << Col << " | "; + + printSymbolInfo(getSymbolInfo(D), OS); + OS << " | "; + + printSymbolNameAndUSR(D, Ctx, OS); + OS << " | "; + + if (ASTNameGen->writeName(D, OS)) + OS << "<no-cgname>"; + OS << " | "; + + printSymbolRoles(Roles, OS); + OS << " | "; + + OS << "rel: " << Relations.size() << '\n'; + + for (auto &SymRel : Relations) { + OS << '\t'; + printSymbolRoles(SymRel.Roles, OS); + OS << " | "; + printSymbolNameAndUSR(SymRel.RelatedSymbol, Ctx, OS); + OS << '\n'; + } + + return true; + } + + bool handleModuleOccurrence(const ImportDecl *ImportD, + const clang::Module *Mod, SymbolRoleSet Roles, + SourceLocation Loc) override { + ASTContext &Ctx = ImportD->getASTContext(); + SourceManager &SM = Ctx.getSourceManager(); + + Loc = SM.getFileLoc(Loc); + FileID FID = SM.getFileID(Loc); + unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc)); + unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc)); + OS << Line << ':' << Col << " | "; + + printSymbolInfo(getSymbolInfo(ImportD), OS); + OS << " | "; + + printSymbolNameAndUSR(Mod, OS); + OS << " | "; + + printSymbolRoles(Roles, OS); + OS << " |\n"; + + return true; + } + + bool handleMacroOccurrence(const IdentifierInfo *Name, const MacroInfo *MI, + SymbolRoleSet Roles, SourceLocation Loc) override { + assert(PP); + SourceManager &SM = PP->getSourceManager(); + + Loc = SM.getFileLoc(Loc); + FileID FID = SM.getFileID(Loc); + unsigned Line = SM.getLineNumber(FID, SM.getFileOffset(Loc)); + unsigned Col = SM.getColumnNumber(FID, SM.getFileOffset(Loc)); + OS << Line << ':' << Col << " | "; + + printSymbolInfo(getSymbolInfoForMacro(*MI), OS); + OS << " | "; + + OS << Name->getName(); + OS << " | "; + + SmallString<256> USRBuf; + if (generateUSRForMacro(Name->getName(), MI->getDefinitionLoc(), SM, + USRBuf)) { + OS << "<no-usr>"; + } else { + OS << USRBuf; + } + OS << " | "; + + printSymbolRoles(Roles, OS); + OS << " |\n"; + return true; + } +}; + +} // anonymous namespace + +//===----------------------------------------------------------------------===// +// Print Source Symbols +//===----------------------------------------------------------------------===// + +static void dumpModuleFileInputs(serialization::ModuleFile &Mod, + ASTReader &Reader, + raw_ostream &OS) { + OS << "---- Module Inputs ----\n"; + Reader.visitInputFiles(Mod, /*IncludeSystem=*/true, /*Complain=*/false, + [&](const serialization::InputFile &IF, bool isSystem) { + OS << (isSystem ? "system" : "user") << " | "; + OS << IF.getFile()->getName() << '\n'; + }); +} + +static bool printSourceSymbols(const char *Executable, + ArrayRef<const char *> Args, + bool dumpModuleImports, bool indexLocals) { + SmallVector<const char *, 4> ArgsWithProgName; + ArgsWithProgName.push_back(Executable); + ArgsWithProgName.append(Args.begin(), Args.end()); + IntrusiveRefCntPtr<DiagnosticsEngine> + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); + auto CInvok = createInvocationFromCommandLine(ArgsWithProgName, Diags); + if (!CInvok) + return true; + + raw_ostream &OS = outs(); + auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(OS); + IndexingOptions IndexOpts; + IndexOpts.IndexFunctionLocals = indexLocals; + std::unique_ptr<FrontendAction> IndexAction = + createIndexingAction(DataConsumer, IndexOpts); + + auto PCHContainerOps = std::make_shared<PCHContainerOperations>(); + std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction( + std::move(CInvok), PCHContainerOps, Diags, IndexAction.get())); + + if (!Unit) + return true; + + if (dumpModuleImports) { + if (auto Reader = Unit->getASTReader()) { + Reader->getModuleManager().visit([&](serialization::ModuleFile &Mod) -> bool { + OS << "==== Module " << Mod.ModuleName << " ====\n"; + indexModuleFile(Mod, *Reader, *DataConsumer, IndexOpts); + dumpModuleFileInputs(Mod, *Reader, OS); + return true; // skip module dependencies. + }); + } + } + + return false; +} + +static bool printSourceSymbolsFromModule(StringRef modulePath, + StringRef format) { + FileSystemOptions FileSystemOpts; + auto pchContOps = std::make_shared<PCHContainerOperations>(); + // Register the support for object-file-wrapped Clang modules. + pchContOps->registerReader(std::make_unique<ObjectFilePCHContainerReader>()); + auto pchRdr = pchContOps->getReaderOrNull(format); + if (!pchRdr) { + errs() << "unknown module format: " << format << '\n'; + return true; + } + + IntrusiveRefCntPtr<DiagnosticsEngine> Diags = + CompilerInstance::createDiagnostics(new DiagnosticOptions()); + std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile( + modulePath, *pchRdr, ASTUnit::LoadASTOnly, Diags, + FileSystemOpts, /*UseDebugInfo=*/false, + /*OnlyLocalDecls=*/true, None, + CaptureDiagsKind::None, + /*AllowPCHWithCompilerErrors=*/true, + /*UserFilesAreVolatile=*/false); + if (!AU) { + errs() << "failed to create TU for: " << modulePath << '\n'; + return true; + } + + PrintIndexDataConsumer DataConsumer(outs()); + IndexingOptions IndexOpts; + indexASTUnit(*AU, DataConsumer, IndexOpts); + + return false; +} + +//===----------------------------------------------------------------------===// +// Helper Utils +//===----------------------------------------------------------------------===// + +static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) { + OS << getSymbolKindString(SymInfo.Kind); + if (SymInfo.SubKind != SymbolSubKind::None) + OS << '/' << getSymbolSubKindString(SymInfo.SubKind); + if (SymInfo.Properties) { + OS << '('; + printSymbolProperties(SymInfo.Properties, OS); + OS << ')'; + } + OS << '/' << getSymbolLanguageString(SymInfo.Lang); +} + +static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, + raw_ostream &OS) { + if (printSymbolName(D, Ctx.getLangOpts(), OS)) { + OS << "<no-name>"; + } + OS << " | "; + + SmallString<256> USRBuf; + if (generateUSRForDecl(D, USRBuf)) { + OS << "<no-usr>"; + } else { + OS << USRBuf; + } +} + +static void printSymbolNameAndUSR(const clang::Module *Mod, raw_ostream &OS) { + assert(Mod); + OS << Mod->getFullModuleName() << " | "; + generateFullUSRForModule(Mod, OS); +} + +//===----------------------------------------------------------------------===// +// Command line processing. +//===----------------------------------------------------------------------===// + +int indextest_core_main(int argc, const char **argv) { + sys::PrintStackTraceOnErrorSignal(argv[0]); + PrettyStackTraceProgram X(argc, argv); + void *MainAddr = (void*) (intptr_t) indextest_core_main; + std::string Executable = llvm::sys::fs::getMainExecutable(argv[0], MainAddr); + + assert(argv[1] == StringRef("core")); + ++argv; + --argc; + + std::vector<const char *> CompArgs; + const char **DoubleDash = std::find(argv, argv + argc, StringRef("--")); + if (DoubleDash != argv + argc) { + CompArgs = std::vector<const char *>(DoubleDash + 1, argv + argc); + argc = DoubleDash - argv; + } + + cl::HideUnrelatedOptions(options::IndexTestCoreCategory); + cl::ParseCommandLineOptions(argc, argv, "index-test-core"); + + if (options::Action == ActionType::None) { + errs() << "error: action required; pass '-help' for options\n"; + return 1; + } + + if (options::Action == ActionType::PrintSourceSymbols) { + if (!options::ModuleFilePath.empty()) { + return printSourceSymbolsFromModule(options::ModuleFilePath, + options::ModuleFormat); + } + if (CompArgs.empty()) { + errs() << "error: missing compiler args; pass '-- <compiler arguments>'\n"; + return 1; + } + return printSourceSymbols(Executable.c_str(), CompArgs, + options::DumpModuleImports, + options::IncludeLocals); + } + + return 0; +} |