From e0f70a8a979f5b843e90a0a20442ca79e2507208 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Sun, 14 Mar 2021 17:04:34 +0100 Subject: [PATCH] Revert "[AST] Add generator for source location introspection" Breaks the build ... somehow: https://llvm-compile-time-tracker.com/show_error.php?commit=77f7d2be214a1de29d583c75739f563593991fc3 FAILED: tools/clang/include/clang/Tooling/NodeIntrospection.inc cd /root/llvm-compile-time-tracker/llvm-project-build/tools/clang/lib/Tooling && /usr/bin/cmake -E make_directory /root/llvm-compile-time-tracker/llvm-project-build/tools/clang/lib/Tooling/generated/ && /root/llvm-compile-time-tracker/llvm-project/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py --json-input-path /root/llvm-compile-time-tracker/llvm-project-build/ASTNodeAPI.json --output-file generated/NodeIntrospection.inc --empty-implementation 0 && /usr/bin/cmake -E copy_if_different /root/llvm-compile-time-tracker/llvm-project-build/tools/clang/lib/Tooling/generated/NodeIntrospection.inc /root/llvm-compile-time-tracker/llvm-project-build/tools/clang/include/clang/Tooling/NodeIntrospection.inc /bin/sh: 1: /root/llvm-compile-time-tracker/llvm-project/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py: not found This reverts commit cefe711135c40b6fb9670cf92118f94f88964b23. This reverts commit f72f122feebe7f980c22ed4a7e04fc274ce2c976. This reverts commit 970c21e345548a967c1bc000462198330982ed7e. This reverts commit 77f7d2be214a1de29d583c75739f563593991fc3. --- .../include/clang/Tooling/NodeIntrospection.h | 85 -------- clang/lib/Tooling/CMakeLists.txt | 75 ------- clang/lib/Tooling/DumpTool/APIData.h | 32 --- .../Tooling/DumpTool/ASTSrcLocProcessor.cpp | 170 --------------- .../lib/Tooling/DumpTool/ASTSrcLocProcessor.h | 48 ----- clang/lib/Tooling/DumpTool/CMakeLists.txt | 16 -- .../lib/Tooling/DumpTool/ClangSrcLocDump.cpp | 139 ------------ .../Tooling/DumpTool/generate_cxx_src_locs.py | 201 ------------------ clang/lib/Tooling/NodeIntrospection.cpp | 61 ------ clang/unittests/CMakeLists.txt | 1 - clang/unittests/Introspection/CMakeLists.txt | 25 --- .../Introspection/IntrospectionTest.cpp | 100 --------- 12 files changed, 953 deletions(-) delete mode 100644 clang/include/clang/Tooling/NodeIntrospection.h delete mode 100644 clang/lib/Tooling/DumpTool/APIData.h delete mode 100644 clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp delete mode 100644 clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h delete mode 100644 clang/lib/Tooling/DumpTool/CMakeLists.txt delete mode 100644 clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp delete mode 100755 clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py delete mode 100644 clang/lib/Tooling/NodeIntrospection.cpp delete mode 100644 clang/unittests/Introspection/CMakeLists.txt delete mode 100644 clang/unittests/Introspection/IntrospectionTest.cpp diff --git a/clang/include/clang/Tooling/NodeIntrospection.h b/clang/include/clang/Tooling/NodeIntrospection.h deleted file mode 100644 index abaa58b674a1..000000000000 --- a/clang/include/clang/Tooling/NodeIntrospection.h +++ /dev/null @@ -1,85 +0,0 @@ -//===- NodeIntrospection.h ------------------------------------*- C++ -*---===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains the implementation of the NodeIntrospection. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLING_NODEINTROSPECTION_H -#define LLVM_CLANG_TOOLING_NODEINTROSPECTION_H - -#include "clang/AST/ASTTypeTraits.h" -#include "clang/AST/DeclarationName.h" - -#include -#include - -namespace clang { - -class Stmt; - -namespace tooling { - -class LocationCall { -public: - enum LocationCallFlags { NoFlags, ReturnsPointer, IsCast }; - LocationCall(std::shared_ptr on, std::string name, - LocationCallFlags flags = NoFlags) - : m_on(on), m_name(name), m_flags(flags) {} - LocationCall(std::shared_ptr on, std::string name, - std::vector const &args, - LocationCallFlags flags = NoFlags) - : m_on(on), m_name(name), m_flags(flags) {} - - LocationCall *on() const { return m_on.get(); } - StringRef name() const { return m_name; } - std::vector const &args() const { return m_args; } - bool returnsPointer() const { return m_flags & ReturnsPointer; } - bool isCast() const { return m_flags & IsCast; } - -private: - std::shared_ptr m_on; - std::string m_name; - std::vector m_args; - LocationCallFlags m_flags; -}; - -class LocationCallFormatterCpp { -public: - static std::string format(LocationCall *Call); -}; - -namespace internal { -struct RangeLessThan { - bool operator()( - std::pair> const &LHS, - std::pair> const &RHS) const; -}; -} // namespace internal - -template >> -using UniqueMultiMap = std::set, Comp>; - -using SourceLocationMap = - UniqueMultiMap>; -using SourceRangeMap = - UniqueMultiMap, - internal::RangeLessThan>; - -struct NodeLocationAccessors { - SourceLocationMap LocationAccessors; - SourceRangeMap RangeAccessors; -}; - -namespace NodeIntrospection { -NodeLocationAccessors GetLocations(clang::Stmt const *Object); -NodeLocationAccessors GetLocations(clang::DynTypedNode const &Node); -} // namespace NodeIntrospection -} // namespace tooling -} // namespace clang -#endif diff --git a/clang/lib/Tooling/CMakeLists.txt b/clang/lib/Tooling/CMakeLists.txt index 9572ad09df0a..7a58af59dad1 100644 --- a/clang/lib/Tooling/CMakeLists.txt +++ b/clang/lib/Tooling/CMakeLists.txt @@ -8,83 +8,10 @@ add_subdirectory(Core) add_subdirectory(Inclusions) add_subdirectory(Refactoring) add_subdirectory(ASTDiff) -add_subdirectory(DumpTool) add_subdirectory(Syntax) add_subdirectory(DependencyScanning) add_subdirectory(Transformer) -find_package(Python3 COMPONENTS Interpreter) - -# The generation of ASTNodeAPI.json takes a long time in a -# Debug build due to parsing AST.h. Disable the processing -# but setting CLANG_TOOLING_BUILD_AST_INTROSPECTION as an -# internal hidden setting to override. -# When the processing is disabled, a trivial/empty JSON -# file is generated by clang-ast-dump and generate_cxx_src_locs.py -# generates the same API, but with a trivial implementation. - -option(CLANG_TOOLING_BUILD_AST_INTROSPECTION "Enable AST introspection" TRUE) -set(skip_expensive_processing $,$>>) - -file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ASTTU.cpp - CONTENT " -#include -") - -add_custom_command( - COMMENT Generate ASTNodeAPI.json - OUTPUT ${CMAKE_BINARY_DIR}/ASTNodeAPI.json - DEPENDS clang-ast-dump clang-resource-headers - COMMAND - $ - # Skip this in debug mode because parsing AST.h is too slow - --skip-processing=${skip_expensive_processing} - --astheader=${CMAKE_CURRENT_BINARY_DIR}/ASTTU.cpp - -I ${CMAKE_BINARY_DIR}/lib/clang/${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}/include - -I ${CMAKE_SOURCE_DIR}/../clang/include - -I ${CMAKE_BINARY_DIR}/tools/clang/include/ - -I ${CMAKE_BINARY_DIR}/include - -I ${CMAKE_SOURCE_DIR}/include - --json-output-path ${CMAKE_BINARY_DIR}/ASTNodeAPI.json -) - -add_custom_target(run-ast-api-dump-tool - DEPENDS ${CMAKE_BINARY_DIR}/ASTNodeAPI.json -) - -# Replace the last lib component of the current binary directory with include -string(FIND ${CMAKE_CURRENT_BINARY_DIR} "/lib/" PATH_LIB_START REVERSE) -if(PATH_LIB_START EQUAL -1) - message(FATAL_ERROR "Couldn't find lib component in binary directory") -endif() -math(EXPR PATH_LIB_END "${PATH_LIB_START}+5") -string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) -string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} ${PATH_LIB_END} -1 PATH_TAIL) -string(CONCAT BINARY_INCLUDE_DIR ${PATH_HEAD} "/include/clang/" ${PATH_TAIL}) - -add_custom_command( - COMMENT Generate NodeIntrospection.inc - OUTPUT ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc - DEPENDS ${CMAKE_BINARY_DIR}/ASTNodeAPI.json ${CMAKE_CURRENT_SOURCE_DIR}/DumpTool/generate_cxx_src_locs.py - COMMAND - ${CMAKE_COMMAND} -E make_directory - ${CMAKE_CURRENT_BINARY_DIR}/generated/ - COMMAND - ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DumpTool/generate_cxx_src_locs.py - --json-input-path ${CMAKE_BINARY_DIR}/ASTNodeAPI.json - --output-file generated/NodeIntrospection.inc - --empty-implementation ${skip_expensive_processing} - COMMAND - ${CMAKE_COMMAND} -E copy_if_different - ${CMAKE_CURRENT_BINARY_DIR}/generated/NodeIntrospection.inc - ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc -) - -add_custom_target(run-ast-api-generate-tool - DEPENDS - ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc -) - add_clang_library(clangTooling AllTUsExecution.cpp ArgumentsAdjusters.cpp @@ -100,8 +27,6 @@ add_clang_library(clangTooling Refactoring.cpp RefactoringCallbacks.cpp StandaloneExecution.cpp - NodeIntrospection.cpp - ${BINARY_INCLUDE_DIR}/NodeIntrospection.inc Tooling.cpp DEPENDS diff --git a/clang/lib/Tooling/DumpTool/APIData.h b/clang/lib/Tooling/DumpTool/APIData.h deleted file mode 100644 index 0ec53f6e7dc3..000000000000 --- a/clang/lib/Tooling/DumpTool/APIData.h +++ /dev/null @@ -1,32 +0,0 @@ -//===- APIData.h ---------------------------------------------*- C++ -*----===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_TOOLING_DUMPTOOL_APIDATA_H -#define LLVM_CLANG_LIB_TOOLING_DUMPTOOL_APIDATA_H - -#include -#include - -namespace clang { -namespace tooling { - -struct ClassData { - - bool isEmpty() const { - return ASTClassLocations.empty() && ASTClassRanges.empty(); - } - - std::vector ASTClassLocations; - std::vector ASTClassRanges; - // TODO: Extend this with locations available via typelocs etc. -}; - -} // namespace tooling -} // namespace clang - -#endif diff --git a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp deleted file mode 100644 index ff279d9425d8..000000000000 --- a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.cpp +++ /dev/null @@ -1,170 +0,0 @@ -//===- ASTSrcLocProcessor.cpp --------------------------------*- C++ -*----===// -// -// 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 "ASTSrcLocProcessor.h" - -#include "clang/Frontend/CompilerInstance.h" -#include "llvm/Support/JSON.h" - -using namespace clang::tooling; -using namespace llvm; -using namespace clang::ast_matchers; - -ASTSrcLocProcessor::ASTSrcLocProcessor(StringRef JsonPath) - : JsonPath(JsonPath) { - - MatchFinder::MatchFinderOptions FinderOptions; - - Finder = std::make_unique(std::move(FinderOptions)); - Finder->addMatcher( - cxxRecordDecl( - isDefinition(), - isSameOrDerivedFrom( - // TODO: Extend this with other clades - namedDecl(hasName("clang::Stmt")).bind("nodeClade")), - optionally(isDerivedFrom(cxxRecordDecl().bind("derivedFrom")))) - .bind("className"), - this); -} - -std::unique_ptr -ASTSrcLocProcessor::createASTConsumer(clang::CompilerInstance &Compiler, - StringRef File) { - return Finder->newASTConsumer(); -} - -llvm::json::Object toJSON(llvm::StringMap> const &Obj) { - using llvm::json::toJSON; - - llvm::json::Object JsonObj; - for (const auto &Item : Obj) { - JsonObj[Item.first()] = Item.second; - } - return JsonObj; -} - -llvm::json::Object toJSON(llvm::StringMap const &Obj) { - using llvm::json::toJSON; - - llvm::json::Object JsonObj; - for (const auto &Item : Obj) { - JsonObj[Item.first()] = Item.second; - } - return JsonObj; -} - -llvm::json::Object toJSON(ClassData const &Obj) { - llvm::json::Object JsonObj; - - if (!Obj.ASTClassLocations.empty()) - JsonObj["sourceLocations"] = Obj.ASTClassLocations; - if (!Obj.ASTClassRanges.empty()) - JsonObj["sourceRanges"] = Obj.ASTClassRanges; - return JsonObj; -} - -llvm::json::Object toJSON(llvm::StringMap const &Obj) { - using llvm::json::toJSON; - - llvm::json::Object JsonObj; - for (const auto &Item : Obj) { - if (!Item.second.isEmpty()) - JsonObj[Item.first()] = ::toJSON(Item.second); - } - return JsonObj; -} - -void WriteJSON(std::string JsonPath, - llvm::StringMap const &ClassInheritance, - llvm::StringMap> const &ClassesInClade, - llvm::StringMap const &ClassEntries) { - llvm::json::Object JsonObj; - - using llvm::json::toJSON; - - JsonObj["classInheritance"] = ::toJSON(ClassInheritance); - JsonObj["classesInClade"] = ::toJSON(ClassesInClade); - JsonObj["classEntries"] = ::toJSON(ClassEntries); - - std::error_code EC; - llvm::raw_fd_ostream JsonOut(JsonPath, EC, llvm::sys::fs::F_Text); - if (EC) - return; - - llvm::json::Value JsonVal(std::move(JsonObj)); - JsonOut << formatv("{0:2}", JsonVal); -} - -void ASTSrcLocProcessor::generate() { - WriteJSON(JsonPath, ClassInheritance, ClassesInClade, ClassEntries); -} - -std::vector -CaptureMethods(std::string TypeString, const clang::CXXRecordDecl *ASTClass, - const MatchFinder::MatchResult &Result) { - - auto publicAccessor = [](auto... InnerMatcher) { - return cxxMethodDecl(isPublic(), parameterCountIs(0), isConst(), - InnerMatcher...); - }; - - auto BoundNodesVec = - match(findAll(publicAccessor(ofClass(equalsNode(ASTClass)), - returns(asString(TypeString))) - .bind("classMethod")), - *ASTClass, *Result.Context); - - std::vector Methods; - for (const auto &BN : BoundNodesVec) { - if (const auto *Node = BN.getNodeAs("classMethod")) { - // Only record the getBeginLoc etc on Stmt etc, because it will call - // more-derived implementations pseudo-virtually. - if ((ASTClass->getName() != "Stmt" && ASTClass->getName() != "Decl") && - (Node->getName() == "getBeginLoc" || Node->getName() == "getEndLoc" || - Node->getName() == "getSourceRange")) { - continue; - } - // Only record the getExprLoc on Expr, because it will call - // more-derived implementations pseudo-virtually. - if (ASTClass->getName() != "Expr" && Node->getName() == "getExprLoc") { - continue; - } - Methods.push_back(Node->getName().str()); - } - } - return Methods; -} - -void ASTSrcLocProcessor::run(const MatchFinder::MatchResult &Result) { - - if (const auto *ASTClass = - Result.Nodes.getNodeAs("className")) { - - StringRef ClassName = ASTClass->getName(); - - ClassData CD; - - const auto *NodeClade = - Result.Nodes.getNodeAs("nodeClade"); - StringRef CladeName = NodeClade->getName(); - - if (const auto *DerivedFrom = - Result.Nodes.getNodeAs("derivedFrom")) - ClassInheritance[ClassName] = DerivedFrom->getName(); - - CD.ASTClassLocations = - CaptureMethods("class clang::SourceLocation", ASTClass, Result); - CD.ASTClassRanges = - CaptureMethods("class clang::SourceRange", ASTClass, Result); - - if (!CD.isEmpty()) { - ClassEntries[ClassName] = CD; - ClassesInClade[CladeName].push_back(ClassName); - } - } -} diff --git a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h b/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h deleted file mode 100644 index 00994758e03c..000000000000 --- a/clang/lib/Tooling/DumpTool/ASTSrcLocProcessor.h +++ /dev/null @@ -1,48 +0,0 @@ -//===- ASTSrcLocProcessor.h ---------------------------------*- C++ -*-----===// -// -// 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 -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_TOOLING_DUMPTOOL_ASTSRCLOCPROCESSOR_H -#define LLVM_CLANG_TOOLING_DUMPTOOL_ASTSRCLOCPROCESSOR_H - -#include "APIData.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "llvm/ADT/StringRef.h" -#include -#include -#include - -namespace clang { - -class CompilerInstance; - -namespace tooling { - -class ASTSrcLocProcessor : public ast_matchers::MatchFinder::MatchCallback { -public: - explicit ASTSrcLocProcessor(StringRef JsonPath); - - std::unique_ptr createASTConsumer(CompilerInstance &Compiler, - StringRef File); - - void generate(); - -private: - void run(const ast_matchers::MatchFinder::MatchResult &Result) override; - - llvm::StringMap ClassInheritance; - llvm::StringMap> ClassesInClade; - llvm::StringMap ClassEntries; - - std::string JsonPath; - std::unique_ptr Finder; -}; - -} // namespace tooling -} // namespace clang - -#endif diff --git a/clang/lib/Tooling/DumpTool/CMakeLists.txt b/clang/lib/Tooling/DumpTool/CMakeLists.txt deleted file mode 100644 index 712985bf7e2b..000000000000 --- a/clang/lib/Tooling/DumpTool/CMakeLists.txt +++ /dev/null @@ -1,16 +0,0 @@ - -add_clang_executable(clang-ast-dump - ASTSrcLocProcessor.cpp - ClangSrcLocDump.cpp -) - -target_link_libraries(clang-ast-dump - PRIVATE - clangAST - clangASTMatchers - clangBasic - clangDriver - clangFrontend - clangSerialization - clangToolingCore -) diff --git a/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp b/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp deleted file mode 100644 index 28337eae9e85..000000000000 --- a/clang/lib/Tooling/DumpTool/ClangSrcLocDump.cpp +++ /dev/null @@ -1,139 +0,0 @@ -//===- ClangSrcLocDump.cpp ------------------------------------*- C++ -*---===// -// -// 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/Basic/Diagnostic.h" -#include "clang/Driver/Compilation.h" -#include "clang/Driver/Driver.h" -#include "clang/Driver/Job.h" -#include "clang/Driver/Options.h" -#include "clang/Driver/Tool.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/Option/ArgList.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/JSON.h" - -#include "ASTSrcLocProcessor.h" - -using namespace clang::tooling; -using namespace clang; -using namespace llvm; - -static cl::list IncludeDirectories( - "I", cl::desc("Include directories to use while compiling"), - cl::value_desc("directory"), cl::Required, cl::OneOrMore, cl::Prefix); - -static cl::opt - AstHeaderFile("astheader", cl::desc("AST header to parse API from"), - cl::Required, cl::value_desc("AST header file")); - -static cl::opt - SkipProcessing("skip-processing", - cl::desc("Avoid processing the AST header file"), - cl::Required, cl::value_desc("bool")); - -static cl::opt JsonOutputPath("json-output-path", - cl::desc("json output path"), - cl::Required, - cl::value_desc("path")); - -class ASTSrcLocGenerationAction : public clang::ASTFrontendAction { -public: - ASTSrcLocGenerationAction() : Processor(JsonOutputPath) {} - - ~ASTSrcLocGenerationAction() { Processor.generate(); } - - std::unique_ptr - CreateASTConsumer(clang::CompilerInstance &Compiler, - llvm::StringRef File) override { - return Processor.createASTConsumer(Compiler, File); - } - -private: - ASTSrcLocProcessor Processor; -}; - -int main(int argc, const char **argv) { - - cl::ParseCommandLineOptions(argc, argv); - - if (SkipProcessing) { - std::error_code EC; - llvm::raw_fd_ostream JsonOut(JsonOutputPath, EC, llvm::sys::fs::F_Text); - if (EC) - return 1; - JsonOut << formatv("{0:2}", llvm::json::Value(llvm::json::Object())); - return 0; - } - - std::vector Args; - Args.push_back("-cc1"); - - llvm::transform(IncludeDirectories, std::back_inserter(Args), - [](const std::string &IncDir) { return "-I" + IncDir; }); - - Args.push_back("-fsyntax-only"); - Args.push_back(AstHeaderFile); - - std::vector Argv(Args.size(), nullptr); - llvm::transform(Args, Argv.begin(), - [](const std::string &Arg) { return Arg.c_str(); }); - - IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); - unsigned MissingArgIndex, MissingArgCount; - auto Opts = driver::getDriverOptTable(); - auto ParsedArgs = Opts.ParseArgs(llvm::makeArrayRef(Argv).slice(1), - MissingArgIndex, MissingArgCount); - ParseDiagnosticArgs(*DiagOpts, ParsedArgs); - TextDiagnosticPrinter DiagnosticPrinter(llvm::errs(), &*DiagOpts); - DiagnosticsEngine Diagnostics( - IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, - &DiagnosticPrinter, false); - - FileManager Files(FileSystemOptions(), vfs::getRealFileSystem()); - - auto Driver = std::make_unique( - "clang", llvm::sys::getDefaultTargetTriple(), Diagnostics, - "ast-api-dump-tool", &Files.getVirtualFileSystem()); - - auto Comp = Driver->BuildCompilation(llvm::makeArrayRef(Argv)); - if (!Comp) - return 1; - - const auto &Jobs = Comp->getJobs(); - if (Jobs.size() != 1 || !isa(*Jobs.begin())) { - SmallString<256> error_msg; - llvm::raw_svector_ostream error_stream(error_msg); - Jobs.Print(error_stream, "; ", true); - return 1; - } - - const auto &Cmd = cast(*Jobs.begin()); - const llvm::opt::ArgStringList &CC1Args = Cmd.getArguments(); - - auto Invocation = std::make_unique(); - CompilerInvocation::CreateFromArgs(*Invocation, CC1Args, Diagnostics); - - CompilerInstance Compiler(std::make_shared()); - Compiler.setInvocation(std::move(Invocation)); - - Compiler.createDiagnostics(&DiagnosticPrinter, false); - if (!Compiler.hasDiagnostics()) - return 1; - - Compiler.createSourceManager(Files); - - ASTSrcLocGenerationAction ScopedToolAction; - Compiler.ExecuteAction(ScopedToolAction); - - Files.clearStatCache(); - - return 0; -} diff --git a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py b/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py deleted file mode 100755 index 0740db0c7629..000000000000 --- a/clang/lib/Tooling/DumpTool/generate_cxx_src_locs.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/python -# -*- coding: utf-8 -*- - -import os -import sys -import json - -import argparse - -class Generator(object): - - implementationContent = '' - - def GeneratePrologue(self): - - self.implementationContent += \ - """ -/*===- Generated file -------------------------------------------*- C++ -*-===*\ -|* *| -|* Introspection of available AST node SourceLocations *| -|* *| -|* Automatically generated file, do not edit! *| -|* *| -\*===----------------------------------------------------------------------===*/ - -namespace clang { -namespace tooling { - -using LocationAndString = SourceLocationMap::value_type; -using RangeAndString = SourceRangeMap::value_type; -""" - - def GenerateBaseGetLocationsDeclaration(self, CladeName): - self.implementationContent += \ - """ -void GetLocationsImpl(std::shared_ptr const& Prefix, - clang::{0} const *Object, SourceLocationMap &Locs, - SourceRangeMap &Rngs); -""".format(CladeName) - - def GenerateSrcLocMethod(self, ClassName, ClassData): - - self.implementationContent += \ - """ -static void GetLocations{0}(std::shared_ptr const& Prefix, - clang::{0} const &Object, - SourceLocationMap &Locs, SourceRangeMap &Rngs) -{{ -""".format(ClassName) - - if 'sourceLocations' in ClassData: - for locName in ClassData['sourceLocations']: - self.implementationContent += \ - """ - Locs.insert(LocationAndString(Object.{0}(), - std::make_shared(Prefix, "{0}"))); -""".format(locName) - - self.implementationContent += '\n' - - if 'sourceRanges' in ClassData: - for rngName in ClassData['sourceRanges']: - self.implementationContent += \ - """ - Rngs.insert(RangeAndString(Object.{0}(), - std::make_shared(Prefix, "{0}"))); -""".format(rngName) - - self.implementationContent += '\n' - - self.implementationContent += '}\n' - - def GenerateFiles(self, OutputFile): - with open(os.path.join(os.getcwd(), - OutputFile), 'w') as f: - f.write(self.implementationContent) - - def GenerateBaseGetLocationsFunction(self, ASTClassNames, CladeName): - - MethodReturnType = 'NodeLocationAccessors' - - Signature = \ - 'GetLocations(clang::{0} const *Object)'.format(CladeName) - ImplSignature = \ - """ -GetLocationsImpl(std::shared_ptr const& Prefix, - clang::{0} const *Object, SourceLocationMap &Locs, - SourceRangeMap &Rngs) -""".format(CladeName) - - self.implementationContent += \ - 'void {0} {{ GetLocations{1}(Prefix, *Object, Locs, Rngs);'.format( - ImplSignature, - CladeName) - - for ASTClassName in ASTClassNames: - if ASTClassName != CladeName: - self.implementationContent += \ - """ -if (auto Derived = llvm::dyn_cast(Object)) {{ - GetLocations{0}(Prefix, *Derived, Locs, Rngs); -}} -""".format(ASTClassName) - - self.implementationContent += '}' - - self.implementationContent += \ - """ -{0} NodeIntrospection::{1} {{ - NodeLocationAccessors Result; - std::shared_ptr Prefix; - - GetLocationsImpl(Prefix, Object, Result.LocationAccessors, - Result.RangeAccessors); -""".format(MethodReturnType, - Signature) - - self.implementationContent += 'return Result; }' - - def GenerateDynNodeVisitor(self, CladeNames): - MethodReturnType = 'NodeLocationAccessors' - - Signature = \ - 'GetLocations(clang::DynTypedNode const &Node)' - - self.implementationContent += MethodReturnType \ - + ' NodeIntrospection::' + Signature + '{' - - for CladeName in CladeNames: - self.implementationContent += \ - """ - if (const auto *N = Node.get<{0}>()) - return GetLocations(const_cast<{0} *>(N));""".format(CladeName) - - self.implementationContent += '\nreturn {}; }' - - def GenerateEpilogue(self): - - self.implementationContent += ''' - } -} -''' - -def main(): - - parser = argparse.ArgumentParser() - parser.add_argument('--json-input-path', - help='Read API description from FILE', metavar='FILE') - parser.add_argument('--output-file', help='Generate output in FILEPATH', - metavar='FILEPATH') - parser.add_argument('--empty-implementation', - help='Generate empty implementation', - action="store", type=int) - - options = parser.parse_args() - - if options.empty_implementation: - with open(os.path.join(os.getcwd(), - options.output_file), 'w') as f: - f.write(""" -namespace clang { -namespace tooling { - -NodeLocationAccessors NodeIntrospection::GetLocations(clang::Stmt const *) { - return {}; -} -NodeLocationAccessors -NodeIntrospection::GetLocations(clang::DynTypedNode const &) { - return {}; -} -} // namespace tooling -} // namespace clang - """) - sys.exit(0) - - with open(options.json_input_path) as f: - jsonData = json.load(f) - - g = Generator() - - g.GeneratePrologue() - - if 'classesInClade' in jsonData: - for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): - g.GenerateBaseGetLocationsDeclaration(CladeName) - - for (ClassName, ClassAccessors) in jsonData['classEntries'].items(): - if ClassAccessors: - g.GenerateSrcLocMethod(ClassName, ClassAccessors) - - for (CladeName, ClassNameData) in jsonData['classesInClade'].items(): - g.GenerateBaseGetLocationsFunction(ClassNameData, CladeName) - - g.GenerateDynNodeVisitor(jsonData['classesInClade'].keys()) - - g.GenerateEpilogue() - - g.GenerateFiles(options.output_file) - -if __name__ == '__main__': - main() diff --git a/clang/lib/Tooling/NodeIntrospection.cpp b/clang/lib/Tooling/NodeIntrospection.cpp deleted file mode 100644 index 89e8c19c6ba8..000000000000 --- a/clang/lib/Tooling/NodeIntrospection.cpp +++ /dev/null @@ -1,61 +0,0 @@ -//===- NodeIntrospection.h -----------------------------------*- C++ -*----===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// This file contains the implementation of the NodeIntrospection. -// -//===----------------------------------------------------------------------===// - -#include "clang/Tooling/NodeIntrospection.h" - -#include "clang/AST/AST.h" - -namespace clang { - -namespace tooling { - -std::string LocationCallFormatterCpp::format(LocationCall *Call) { - SmallVector vec; - while (Call) { - vec.push_back(Call); - Call = Call->on(); - } - std::string result; - for (auto *VecCall : llvm::reverse(llvm::makeArrayRef(vec).drop_front())) { - result += - (VecCall->name() + "()" + (VecCall->returnsPointer() ? "->" : ".")) - .str(); - } - result += (vec.back()->name() + "()").str(); - return result; -} - -namespace internal { -bool RangeLessThan::operator()( - std::pair> const &LHS, - std::pair> const &RHS) const { - if (!LHS.first.isValid() || !RHS.first.isValid()) - return false; - - if (LHS.first.getBegin() < RHS.first.getBegin()) - return true; - else if (LHS.first.getBegin() != RHS.first.getBegin()) - return false; - - if (LHS.first.getEnd() < RHS.first.getEnd()) - return true; - else if (LHS.first.getEnd() != RHS.first.getEnd()) - return false; - - return LHS.second->name() < RHS.second->name(); -} -} // namespace internal - -} // namespace tooling -} // namespace clang - -#include "clang/Tooling/NodeIntrospection.inc" diff --git a/clang/unittests/CMakeLists.txt b/clang/unittests/CMakeLists.txt index 4e0873955700..bb635dfff991 100644 --- a/clang/unittests/CMakeLists.txt +++ b/clang/unittests/CMakeLists.txt @@ -29,7 +29,6 @@ add_subdirectory(ASTMatchers) add_subdirectory(AST) add_subdirectory(CrossTU) add_subdirectory(Tooling) -add_subdirectory(Introspection) add_subdirectory(Format) add_subdirectory(Frontend) add_subdirectory(Rewrite) diff --git a/clang/unittests/Introspection/CMakeLists.txt b/clang/unittests/Introspection/CMakeLists.txt deleted file mode 100644 index 3dd8aec56b76..000000000000 --- a/clang/unittests/Introspection/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -set(LLVM_LINK_COMPONENTS - FrontendOpenMP - Support - ) - -add_clang_unittest(IntrospectionTests - IntrospectionTest.cpp - ) - -clang_target_link_libraries(IntrospectionTests - PRIVATE - clangAST - clangASTMatchers - clangTooling - clangBasic - clangSerialization - clangFrontend - ) -target_compile_definitions(IntrospectionTests PRIVATE - SKIP_INTROSPECTION_GENERATION=$,$>> -) -target_link_libraries(IntrospectionTests - PRIVATE - LLVMTestingSupport -) diff --git a/clang/unittests/Introspection/IntrospectionTest.cpp b/clang/unittests/Introspection/IntrospectionTest.cpp deleted file mode 100644 index 25fc17a76761..000000000000 --- a/clang/unittests/Introspection/IntrospectionTest.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//===- unittest/Introspection/IntrospectionTest.cpp ----------*- C++ -*---===// -// -// 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 -// -//===----------------------------------------------------------------------===// -// -// Tests for AST location API introspection. -// -//===----------------------------------------------------------------------===// - -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/ASTMatchers/ASTMatchers.h" -#include "clang/Tooling/NodeIntrospection.h" -#include "clang/Tooling/Tooling.h" -#include "gmock/gmock-matchers.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using namespace clang; -using namespace clang::ast_matchers; -using namespace clang::tooling; - -using ::testing::UnorderedElementsAre; -using ::testing::Pair; - -#if SKIP_INTROSPECTION_GENERATION - -TEST(Introspection, NonFatalAPI) { - auto AST = buildASTFromCode("void foo() {} void bar() { foo(); }", "foo.cpp", - std::make_shared()); - auto &Ctx = AST->getASTContext(); - auto &TU = *Ctx.getTranslationUnitDecl(); - - auto BoundNodes = ast_matchers::match( - decl(hasDescendant( - callExpr(callee(functionDecl(hasName("foo")))).bind("fooCall"))), - TU, Ctx); - - EXPECT_EQ(BoundNodes.size(), 1u); - - auto *FooCall = BoundNodes[0].getNodeAs("fooCall"); - - auto result = NodeIntrospection::GetLocations(FooCall); - - EXPECT_EQ(result.LocationAccessors.size(), 0u); - EXPECT_EQ(result.RangeAccessors.size(), 0u); -} - -#else - -TEST(Introspection, SourceLocations) { - auto AST = buildASTFromCode("void foo() {} void bar() { foo(); }", "foo.cpp", - std::make_shared()); - auto &Ctx = AST->getASTContext(); - auto &TU = *Ctx.getTranslationUnitDecl(); - - auto BoundNodes = ast_matchers::match( - decl(hasDescendant( - callExpr(callee(functionDecl(hasName("foo")))).bind("fooCall"))), - TU, Ctx); - - EXPECT_EQ(BoundNodes.size(), 1u); - - auto *FooCall = BoundNodes[0].getNodeAs("fooCall"); - - auto result = NodeIntrospection::GetLocations(FooCall); - - std::map ExpectedLocations; - llvm::transform(result.LocationAccessors, - std::inserter(ExpectedLocations, ExpectedLocations.end()), - [](const auto &Accessor) { - return std::make_pair( - LocationCallFormatterCpp::format(Accessor.second.get()), - Accessor.first); - }); - - EXPECT_THAT(ExpectedLocations, - UnorderedElementsAre( - Pair("getBeginLoc()", FooCall->getBeginLoc()), - Pair("getEndLoc()", FooCall->getEndLoc()), - Pair("getExprLoc()", FooCall->getExprLoc()), - Pair("getRParenLoc()", FooCall->getRParenLoc()))); - - std::map ExpectedRanges; - llvm::transform(result.RangeAccessors, - std::inserter(ExpectedRanges, ExpectedRanges.end()), - [](const auto &Accessor) { - return std::make_pair( - LocationCallFormatterCpp::format(Accessor.second.get()), - Accessor.first); - }); - - EXPECT_THAT(ExpectedRanges, - UnorderedElementsAre( - Pair("getSourceRange()", FooCall->getSourceRange()))); -} -#endif