From 6b0f04067f2a1269c0d0bb2d73ed11ac43099c47 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 16 Jan 2019 10:57:02 +0000 Subject: Bump the trunk version to 9.0.0svn git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351320 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/ReleaseNotes.rst | 246 ++------------------------------------------------ docs/conf.py | 4 +- 2 files changed, 8 insertions(+), 242 deletions(-) diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 8731dc73..ce8e0842 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,5 +1,5 @@ =================================================== -Extra Clang Tools 8.0.0 (In-Progress) Release Notes +Extra Clang Tools 9.0.0 (In-Progress) Release Notes =================================================== .. contents:: @@ -10,7 +10,7 @@ Written by the `LLVM Team `_ .. warning:: - These are in-progress notes for the upcoming Extra Clang Tools 8 release. + These are in-progress notes for the upcoming Extra Clang Tools 9 release. Release notes for previous releases can be found on `the Download Page `_. @@ -18,7 +18,7 @@ Introduction ============ This document contains the release notes for the Extra Clang Tools, part of the -Clang release 8.0.0. Here we describe the status of the Extra Clang Tools in +Clang release 9.0.0. Here we describe the status of the Extra Clang Tools in some detail, including major improvements from the previous release and new feature work. All LLVM releases may be downloaded from the `LLVM releases web site `_. @@ -32,7 +32,7 @@ main Clang web page, this document applies to the *next* release, not the current one. To see the release notes for a specific release, please see the `releases page `_. -What's New in Extra Clang Tools 8.0.0? +What's New in Extra Clang Tools 9.0.0? ====================================== Some of the major new features and improvements to Extra Clang Tools are listed @@ -57,47 +57,7 @@ The improvements are... Improvements to clang-query --------------------------- -- A new command line parameter ``--preload`` was added to - run commands from a file and then start the interactive interpreter. - -- The command ``q`` can was added as an alias for ``quit`` to exit the - ``clang-query`` interpreter. - -- It is now possible to bind to named values (the result of ``let`` - expressions). For example: - - .. code-block:: none - - let fn functionDecl() - match fn.bind("foo") - -- It is now possible to write comments in ``clang-query`` code. This - is primarily useful when using script-mode. Comments are all content - following the ``#`` character on a line: - - .. code-block:: none - - # This is a comment - match fn.bind("foo") # This is a trailing comment - -- The new ``set print-matcher true`` command now causes ``clang-query`` to - print the evaluated matcher together with the resulting bindings. - -- A new output mode ``detailed-ast`` was added to ``clang-query``. The - existing ``dump`` output mode is now a deprecated alias - for ``detailed-ast`` - -- Output modes can now be enabled or disabled non-exclusively. For example, - - .. code-block:: none - - # Enable detailed-ast without disabling other output, such as diag - enable output detailed-ast - m functionDecl() - - # Disable detailed-ast only - disable output detailed-ast - m functionDecl() +- ... Improvements to clang-rename ---------------------------- @@ -107,201 +67,7 @@ The improvements are... Improvements to clang-tidy -------------------------- -- New :doc:`abseil-duration-comparison - ` check. - - Checks for comparisons which should be done in the ``absl::Duration`` domain - instead of the float of integer domains. - -- New :doc:`abseil-duration-division - ` check. - - Checks for uses of ``absl::Duration`` division that is done in a - floating-point context, and recommends the use of a function that - returns a floating-point value. - -- New :doc:`abseil-duration-factory-float - ` check. - - Checks for cases where the floating-point overloads of various - ``absl::Duration`` factory functions are called when the more-efficient - integer versions could be used instead. - -- New :doc:`abseil-duration-factory-scale - ` check. - - Checks for cases where arguments to ``absl::Duration`` factory functions are - scaled internally and could be changed to a different factory function. - -- New :doc:`abseil-duration-subtraction - ` check. - - Checks for cases where subtraction should be performed in the - ``absl::Duration`` domain. - -- New :doc:`abseil-faster-strsplit-delimiter - ` check. - - Finds instances of ``absl::StrSplit()`` or ``absl::MaxSplits()`` where the - delimiter is a single character string literal and replaces with a character. - -- New :doc:`abseil-no-internal-dependencies - ` check. - - Gives a warning if code using Abseil depends on internal details. - -- New :doc:`abseil-no-namespace - ` check. - - Ensures code does not open ``namespace absl`` as that violates Abseil's - compatibility guidelines. - -- New :doc:`abseil-redundant-strcat-calls - ` check. - - Suggests removal of unnecessary calls to ``absl::StrCat`` when the result is - being passed to another ``absl::StrCat`` or ``absl::StrAppend``. - -- New :doc:`abseil-str-cat-append - ` check. - - Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests - ``absl::StrAppend()`` should be used instead. - -- New :doc:`abseil-upgrade-duration-conversions - ` check. - - Finds calls to ``absl::Duration`` arithmetic operators and factories whose - argument needs an explicit cast to continue compiling after upcoming API - changes. - -- New :doc:`bugprone-too-small-loop-variable - ` check. - - Detects those ``for`` loops that have a loop variable with a "too small" type - which means this type can't represent all values which are part of the - iteration range. - -- New :doc:`cppcoreguidelines-macro-usage - ` check. - - Finds macro usage that is considered problematic because better language - constructs exist for the task. - -- New :doc:`google-objc-function-naming - ` check. - - Checks that function names in function declarations comply with the naming - conventions described in the Google Objective-C Style Guide. - -- New :doc:`misc-non-private-member-variables-in-classes - ` check. - - Finds classes that not only contain the data (non-static member variables), - but also have logic (non-static member functions), and diagnoses all member - variables that have any other scope other than ``private``. - -- New :doc:`modernize-avoid-c-arrays - ` check. - - Finds C-style array types and recommend to use ``std::array<>`` / - ``std::vector<>``. - -- New :doc:`modernize-concat-nested-namespaces - ` check. - - Checks for uses of nested namespaces in the form of - ``namespace a { namespace b { ... }}`` and offers change to - syntax introduced in C++17 standard: ``namespace a::b { ... }``. - -- New :doc:`modernize-deprecated-ios-base-aliases - ` check. - - Detects usage of the deprecated member types of ``std::ios_base`` and replaces - those that have a non-deprecated equivalent. - -- New :doc:`modernize-use-nodiscard - ` check. - - Adds ``[[nodiscard]]`` attributes (introduced in C++17) to member functions - to highlight at compile time which return values should not be ignored. - -- New :doc:`readability-isolate-decl - ` check. - - Detects local variable declarations declaring more than one variable and - tries to refactor the code to one statement per declaration. - -- New :doc:`readability-const-return-type - ` check. - - Checks for functions with a ``const``-qualified return type and recommends - removal of the ``const`` keyword. - -- New :doc:`readability-magic-numbers - ` check. - - Detects usage of magic numbers, numbers that are used as literals instead of - introduced via constants or symbols. - -- New :doc:`readability-redundant-preprocessor - ` check. - - Finds potentially redundant preprocessor directives. - -- New :doc:`readability-uppercase-literal-suffix - ` check. - - Detects when the integral literal or floating point literal has non-uppercase - suffix, and suggests to make the suffix uppercase. The list of destination - suffixes can be optionally provided. - -- New alias :doc:`cert-dcl16-c - ` to :doc:`readability-uppercase-literal-suffix - ` - added. - -- New alias :doc:`cppcoreguidelines-avoid-c-arrays - ` - to :doc:`modernize-avoid-c-arrays - ` added. - -- New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes - ` - to :doc:`misc-non-private-member-variables-in-classes - ` - added. - -- New alias :doc:`hicpp-avoid-c-arrays - ` - to :doc:`modernize-avoid-c-arrays - ` added. - -- New alias :doc:`hicpp-uppercase-literal-suffix - ` to - :doc:`readability-uppercase-literal-suffix - ` - added. - -- The :doc:`cppcoreguidelines-narrowing-conversions - ` check now - detects more narrowing conversions: - - integer to narrower signed integer (this is compiler implementation defined), - - integer - floating point narrowing conversions, - - floating point - integer narrowing conversions, - - constants with narrowing conversions (even in ternary operator). - -- The :doc:`objc-property-declaration - ` check now ignores the - `Acronyms` and `IncludeDefaultAcronyms` options. - -- The :doc:`readability-redundant-smartptr-get - ` check does not warn - about calls inside macros anymore by default. - -- The :doc:`readability-uppercase-literal-suffix - ` check does not warn - about literal suffixes inside macros anymore by default. +- ... Improvements to include-fixer ----------------------------- diff --git a/docs/conf.py b/docs/conf.py index 1b07e8ef..a79558f0 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -49,9 +49,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year # built documents. # # The short version. -version = '8' +version = '9' # The full version, including alpha/beta/rc tags. -release = '8' +release = '9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. -- cgit v1.2.3 From 99bed98d0db094fb277783ce229552c480dc0b6d Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Wed, 16 Jan 2019 14:49:32 +0000 Subject: [clang-tidy] Move the macro helper function to a common location; NFC This is useful for multiple checks. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351348 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/DurationComparisonCheck.cpp | 24 ++---------------------- clang-tidy/abseil/DurationRewriter.cpp | 17 +++++++++++++++++ clang-tidy/abseil/DurationRewriter.h | 5 +++++ 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tidy/abseil/DurationComparisonCheck.cpp index 963da3f3..adf0f6d8 100644 --- a/clang-tidy/abseil/DurationComparisonCheck.cpp +++ b/clang-tidy/abseil/DurationComparisonCheck.cpp @@ -19,26 +19,6 @@ namespace clang { namespace tidy { namespace abseil { -/// Return `true` if `E` is a either: not a macro at all; or an argument to -/// one. In the latter case, we should still transform it. -static bool IsValidMacro(const MatchFinder::MatchResult &Result, - const Expr *E) { - if (!E->getBeginLoc().isMacroID()) - return true; - - SourceLocation Loc = E->getBeginLoc(); - // We want to get closer towards the initial macro typed into the source only - // if the location is being expanded as a macro argument. - while (Result.SourceManager->isMacroArgExpansion(Loc)) { - // We are calling getImmediateMacroCallerLoc, but note it is essentially - // equivalent to calling getImmediateSpellingLoc in this context according - // to Clang implementation. We are not calling getImmediateSpellingLoc - // because Clang comment says it "should not generally be used by clients." - Loc = Result.SourceManager->getImmediateMacroCallerLoc(Loc); - } - return !Loc.isMacroID(); -} - void DurationComparisonCheck::registerMatchers(MatchFinder *Finder) { auto Matcher = binaryOperator(anyOf(hasOperatorName(">"), hasOperatorName(">="), @@ -64,8 +44,8 @@ void DurationComparisonCheck::check(const MatchFinder::MatchResult &Result) { // want to handle the case of rewriting both sides. This is much simpler if // we unconditionally try and rewrite both, and let the rewriter determine // if nothing needs to be done. - if (!IsValidMacro(Result, Binop->getLHS()) || - !IsValidMacro(Result, Binop->getRHS())) + if (!isNotInMacro(Result, Binop->getLHS()) || + !isNotInMacro(Result, Binop->getRHS())) return; std::string LhsReplacement = rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS()); diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index ed648897..ca44ab5b 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -216,6 +216,23 @@ std::string rewriteExprFromNumberToDuration( .str(); } +bool isNotInMacro(const MatchFinder::MatchResult &Result, const Expr *E) { + if (!E->getBeginLoc().isMacroID()) + return true; + + SourceLocation Loc = E->getBeginLoc(); + // We want to get closer towards the initial macro typed into the source only + // if the location is being expanded as a macro argument. + while (Result.SourceManager->isMacroArgExpansion(Loc)) { + // We are calling getImmediateMacroCallerLoc, but note it is essentially + // equivalent to calling getImmediateSpellingLoc in this context according + // to Clang implementation. We are not calling getImmediateSpellingLoc + // because Clang comment says it "should not generally be used by clients." + Loc = Result.SourceManager->getImmediateMacroCallerLoc(Loc); + } + return !Loc.isMacroID(); +} + } // namespace abseil } // namespace tidy } // namespace clang diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index d0004d1c..e4204131 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -75,6 +75,11 @@ std::string rewriteExprFromNumberToDuration( const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, const Expr *Node); +/// Return `true` if `E` is a either: not a macro at all; or an argument to +/// one. In the both cases, we often want to do the transformation. +bool isNotInMacro(const ast_matchers::MatchFinder::MatchResult &Result, + const Expr *E); + AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, DurationConversionFunction) { using namespace clang::ast_matchers; -- cgit v1.2.3 From 128300ffd21cd1a2fabbd88859ee4cf6604bcc0d Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Thu, 17 Jan 2019 18:31:34 +0000 Subject: [Documentation] Add a chapter about Clang-tidy integrations. Patch by Marina Kalashina. Differential Revision: https://reviews.llvm.org/D54945 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351463 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/Contributing.rst | 507 ++++++++++++++++++++++++++++++++++++++ docs/clang-tidy/Integrations.rst | 117 +++++++++ docs/clang-tidy/index.rst | 510 +-------------------------------------- 3 files changed, 626 insertions(+), 508 deletions(-) create mode 100644 docs/clang-tidy/Contributing.rst create mode 100644 docs/clang-tidy/Integrations.rst diff --git a/docs/clang-tidy/Contributing.rst b/docs/clang-tidy/Contributing.rst new file mode 100644 index 00000000..ab64b39b --- /dev/null +++ b/docs/clang-tidy/Contributing.rst @@ -0,0 +1,507 @@ +================ +Getting Involved +================ + +:program:`clang-tidy` has several own checks and can run Clang static analyzer +checks, but its power is in the ability to easily write custom checks. + +Checks are organized in modules, which can be linked into :program:`clang-tidy` +with minimal or no code changes in :program:`clang-tidy`. + +Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_ +or on the AST level using `AST Matchers`_. When an error is found, checks can +report them in a way similar to how Clang diagnostics work. A fix-it hint can be +attached to a diagnostic message. + +The interface provided by :program:`clang-tidy` makes it easy to write useful +and precise checks in just a few lines of code. If you have an idea for a good +check, the rest of this document explains how to do this. + +There are a few tools particularly useful when developing clang-tidy checks: + * ``add_new_check.py`` is a script to automate the process of adding a new + check, it will create the check, update the CMake file and create a test; + * ``rename_check.py`` does what the script name suggests, renames an existing + check; + * :program:`clang-query` is invaluable for interactive prototyping of AST + matchers and exploration of the Clang AST; + * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``) + provides a convenient way to dump AST of a C++ program. + +If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, +:program:`clang-tidy` will not be built with support for the +``clang-analyzer-*`` checks or the ``mpi-*`` checks. + + +.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html +.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html +.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html + + +Choosing the Right Place for your Check +--------------------------------------- + +If you have an idea of a check, you should decide whether it should be +implemented as a: + ++ *Clang diagnostic*: if the check is generic enough, targets code patterns that + most probably are bugs (rather than style or readability issues), can be + implemented effectively and with extremely low false positive rate, it may + make a good Clang diagnostic. + ++ *Clang static analyzer check*: if the check requires some sort of control flow + analysis, it should probably be implemented as a static analyzer check. + ++ *clang-tidy check* is a good choice for linter-style checks, checks that are + related to a certain coding style, checks that address code readability, etc. + + +Preparing your Workspace +------------------------ + +If you are new to LLVM development, you should read the `Getting Started with +the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_ +documents to check out and build LLVM, Clang and Clang Extra Tools with CMake. + +Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and +let's start! + +.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html +.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html + + +The Directory Structure +----------------------- + +:program:`clang-tidy` source code resides in the +``llvm/tools/clang/tools/extra`` directory and is structured as follows: + +:: + + clang-tidy/ # Clang-tidy core. + |-- ClangTidy.h # Interfaces for users and checks. + |-- ClangTidyModule.h # Interface for clang-tidy modules. + |-- ClangTidyModuleRegistry.h # Interface for registering of modules. + ... + |-- google/ # Google clang-tidy module. + |-+ + |-- GoogleTidyModule.cpp + |-- GoogleTidyModule.h + ... + |-- llvm/ # LLVM clang-tidy module. + |-+ + |-- LLVMTidyModule.cpp + |-- LLVMTidyModule.h + ... + |-- objc/ # Objective-C clang-tidy module. + |-+ + |-- ObjCTidyModule.cpp + |-- ObjCTidyModule.h + ... + |-- tool/ # Sources of the clang-tidy binary. + ... + test/clang-tidy/ # Integration tests. + ... + unittests/clang-tidy/ # Unit tests. + |-- ClangTidyTest.h + |-- GoogleModuleTest.cpp + |-- LLVMModuleTest.cpp + |-- ObjCModuleTest.cpp + ... + + +Writing a clang-tidy Check +-------------------------- + +So you have an idea of a useful check for :program:`clang-tidy`. + +First, if you're not familiar with LLVM development, read through the `Getting +Started with LLVM`_ document for instructions on setting up your workflow and +the `LLVM Coding Standards`_ document to familiarize yourself with the coding +style used in the project. For code reviews we mostly use `LLVM Phabricator`_. + +.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html +.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html +.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html + +Next, you need to decide which module the check belongs to. Modules +are located in subdirectories of `clang-tidy/ +`_ +and contain checks targeting a certain aspect of code quality (performance, +readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.) +or a widely used API (e.g. MPI). Their names are same as user-facing check +groups names described :ref:`above `. + +After choosing the module and the name for the check, run the +``clang-tidy/add_new_check.py`` script to create the skeleton of the check and +plug it to :program:`clang-tidy`. It's the recommended way of adding new checks. + +If we want to create a `readability-awesome-function-names`, we would run: + +.. code-block:: console + + $ clang-tidy/add_new_check.py readability awesome-function-names + + +The ``add_new_check.py`` script will: + * create the class for your check inside the specified module's directory and + register it in the module and in the build system; + * create a lit test file in the ``test/clang-tidy/`` directory; + * create a documentation file and include it into the + ``docs/clang-tidy/checks/list.rst``. + +Let's see in more detail at the check class definition: + +.. code-block:: c++ + + ... + + #include "../ClangTidy.h" + + namespace clang { + namespace tidy { + namespace readability { + + ... + class AwesomeFunctionNamesCheck : public ClangTidyCheck { + public: + AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + }; + + } // namespace readability + } // namespace tidy + } // namespace clang + + ... + +Constructor of the check receives the ``Name`` and ``Context`` parameters, and +must forward them to the ``ClangTidyCheck`` constructor. + +In our case the check needs to operate on the AST level and it overrides the +``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the +preprocessor level, we'd need instead to override the ``registerPPCallbacks`` +method. + +In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_ +for more information) that will find the pattern in the AST that we want to +inspect. The results of the matching are passed to the ``check`` method, which +can further inspect them and report diagnostics. + +.. code-block:: c++ + + using namespace ast_matchers; + + void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher(functionDecl().bind("x"), this); + } + + void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) { + const auto *MatchedDecl = Result.Nodes.getNodeAs("x"); + if (MatchedDecl->getName().startswith("awesome_")) + return; + diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome") + << MatchedDecl + << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_"); + } + +(If you want to see an example of a useful check, look at +`clang-tidy/google/ExplicitConstructorCheck.h +`_ +and `clang-tidy/google/ExplicitConstructorCheck.cpp +`_). + + +Registering your Check +---------------------- + +(The ``add_new_check.py`` takes care of registering the check in an existing +module. If you want to create a new module or know the details, read on.) + +The check should be registered in the corresponding module with a distinct name: + +.. code-block:: c++ + + class MyModule : public ClangTidyModule { + public: + void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "my-explicit-constructor"); + } + }; + +Now we need to register the module in the ``ClangTidyModuleRegistry`` using a +statically initialized variable: + +.. code-block:: c++ + + static ClangTidyModuleRegistry::Add X("my-module", + "Adds my lint checks."); + + +When using LLVM build system, we need to use the following hack to ensure the +module is linked into the :program:`clang-tidy` binary: + +Add this near the ``ClangTidyModuleRegistry::Add`` variable: + +.. code-block:: c++ + + // This anchor is used to force the linker to link in the generated object file + // and thus register the MyModule. + volatile int MyModuleAnchorSource = 0; + +And this to the main translation unit of the :program:`clang-tidy` binary (or +the binary you link the ``clang-tidy`` library in) +``clang-tidy/tool/ClangTidyMain.cpp``: + +.. code-block:: c++ + + // This anchor is used to force the linker to link the MyModule. + extern volatile int MyModuleAnchorSource; + static int MyModuleAnchorDestination = MyModuleAnchorSource; + + +Configuring Checks +------------------ + +If a check needs configuration options, it can access check-specific options +using the ``Options.get("SomeOption", DefaultValue)`` call in the check +constructor. In this case the check should also override the +``ClangTidyCheck::storeOptions`` method to make the options provided by the +check discoverable. This method lets :program:`clang-tidy` know which options +the check implements and what the current values are (e.g. for the +``-dump-config`` command line option). + +.. code-block:: c++ + + class MyCheck : public ClangTidyCheck { + const unsigned SomeOption1; + const std::string SomeOption2; + + public: + MyCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + SomeOption(Options.get("SomeOption1", -1U)), + SomeOption(Options.get("SomeOption2", "some default")) {} + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override { + Options.store(Opts, "SomeOption1", SomeOption1); + Options.store(Opts, "SomeOption2", SomeOption2); + } + ... + +Assuming the check is registered with the name "my-check", the option can then +be set in a ``.clang-tidy`` file in the following way: + +.. code-block:: yaml + + CheckOptions: + - key: my-check.SomeOption1 + value: 123 + - key: my-check.SomeOption2 + value: 'some other value' + +If you need to specify check options on a command line, you can use the inline +YAML format: + +.. code-block:: console + + $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ... + + +Testing Checks +-------------- + +To run tests for :program:`clang-tidy` use the command: + +.. code-block:: console + + $ ninja check-clang-tools + +:program:`clang-tidy` checks can be tested using either unit tests or +`lit`_ tests. Unit tests may be more convenient to test complex replacements +with strict checks. `Lit`_ tests allow using partial text matching and regular +expressions which makes them more suitable for writing compact tests for +diagnostic messages. + +The ``check_clang_tidy.py`` script provides an easy way to test both +diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test +file, runs :program:`clang-tidy` and verifies messages and fixes with two +separate `FileCheck`_ invocations: once with FileCheck's directive +prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages, +and once with the directive prefix set to ``CHECK-FIXES``, running +against the fixed code (i.e., the code after generated fix-its are +applied). In particular, ``CHECK-FIXES:`` can be used to check +that code was not modified by fix-its, by checking that it is present +unchanged in the fixed code. The full set of `FileCheck`_ directives +is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though +typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``) +are sufficient for clang-tidy tests. Note that the `FileCheck`_ +documentation mostly assumes the default prefix (``CHECK``), and hence +describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc. +Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for +clang-tidy tests. + +An additional check enabled by ``check_clang_tidy.py`` ensures that +if `CHECK-MESSAGES:` is used in a file then every warning or error +must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` +instead, if you want to **also** ensure that all the notes are checked. + +To use the ``check_clang_tidy.py`` script, put a .cpp file with the +appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use +``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against +diagnostic messages and fixed code. + +It's advised to make the checks as specific as possible to avoid checks matching +to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]`` +substitutions and distinct function and variable names in the test code. + +Here's an example of a test using the ``check_clang_tidy.py`` script (the full +source code is at `test/clang-tidy/google-readability-casting.cpp`_): + +.. code-block:: c++ + + // RUN: %check_clang_tidy %s google-readability-casting %t + + void f(int a) { + int b = (int)a; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting] + // CHECK-FIXES: int b = a; + } + +To check more than one scenario in the same test file use +``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or +``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``. +With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*`` +directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``. + +Here's an example: + +.. code-block:: c++ + + // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A + // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B + // RUN: %check_clang_tidy %s misc-unused-using-decls %t + ... + // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}} + // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}} + // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}} + // CHECK-FIXES-USING-A-NOT: using a::A;$ + // CHECK-FIXES-USING-B-NOT: using a::B;$ + // CHECK-FIXES-NOT: using a::C;$ + + +There are many dark corners in the C++ language, and it may be difficult to make +your check work perfectly in all cases, especially if it issues fix-it hints. The +most frequent pitfalls are macros and templates: + +1. code written in a macro body/template definition may have a different meaning + depending on the macro expansion/template instantiation; +2. multiple macro expansions/template instantiations may result in the same code + being inspected by the check multiple times (possibly, with different + meanings, see 1), and the same warning (or a slightly different one) may be + issued by the check multiple times; :program:`clang-tidy` will deduplicate + _identical_ warnings, but if the warnings are slightly different, all of them + will be shown to the user (and used for applying fixes, if any); +3. making replacements to a macro body/template definition may be fine for some + macro expansions/template instantiations, but easily break some other + expansions/instantiations. + +.. _lit: http://llvm.org/docs/CommandGuide/lit.html +.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html +.. _test/clang-tidy/google-readability-casting.cpp: http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp + + +Running clang-tidy on LLVM +-------------------------- + +To test a check it's best to try it out on a larger code base. LLVM and Clang +are the natural targets as you already have the source code around. The most +convenient way to run :program:`clang-tidy` is with a compile command database; +CMake can automatically generate one, for a description of how to enable it see +`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place and +a working version of :program:`clang-tidy` is in ``PATH`` the entire code base +can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script executes +:program:`clang-tidy` with the default set of checks on every translation unit +in the compile command database and displays the resulting warnings and errors. +The script provides multiple configuration flags. + +* The default set of checks can be overridden using the ``-checks`` argument, + taking the identical format as :program:`clang-tidy` does. For example + ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override`` + check only. + +* To restrict the files examined you can provide one or more regex arguments + that the file names are matched against. + ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy + checks. It may also be necessary to restrict the header files warnings are + displayed from using the ``-header-filter`` flag. It has the same behavior + as the corresponding :program:`clang-tidy` flag. + +* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers + all changes in a temporary directory and applies them. Passing ``-format`` + will run clang-format over changed lines. + + +On checks profiling +------------------- + +:program:`clang-tidy` can collect per-check profiling info, and output it +for each processed source file (translation unit). + +To enable profiling info collection, use the ``-enable-check-profile`` argument. +The timings will be output to ``stderr`` as a table. Example output: + +.. code-block:: console + + $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp + ===-------------------------------------------------------------------------=== + clang-tidy checks profiling + ===-------------------------------------------------------------------------=== + Total Execution Time: 1.0282 seconds (1.0258 wall clock) + + ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- + 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) readability-function-size + 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) Total + +It can also store that data as JSON files for further processing. Example output: + +.. code-block:: console + + $ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp + $ # Note that there won't be timings table printed to the console. + $ ls /tmp/out/ + 20180516161318717446360-source.cpp.json + $ cat 20180516161318717446360-source.cpp.json + { + "file": "/path/to/source.cpp", + "timestamp": "2018-05-16 16:13:18.717446360", + "profile": { + "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00, + "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01, + "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01 + } + } + +There is only one argument that controls profile storage: + +* ``-store-check-profile=`` + + By default reports are printed in tabulated format to stderr. When this option + is passed, these per-TU profiles are instead stored as JSON. + If the prefix is not an absolute path, it is considered to be relative to the + directory from where you have run :program:`clang-tidy`. All ``.`` and ``..`` + patterns in the path are collapsed, and symlinks are resolved. + + Example: + Let's suppose you have a source file named ``example.cpp``, located in the + ``/source`` directory. Only the input filename is used, not the full path + to the source file. Additionally, it is prefixed with the current timestamp. + + * If you specify ``-store-check-profile=/tmp``, then the profile will be saved + to ``/tmp/-example.cpp.json`` + + * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify + ``-store-check-profile=.``, then the profile will still be saved to + ``/foo/-example.cpp.json`` diff --git a/docs/clang-tidy/Integrations.rst b/docs/clang-tidy/Integrations.rst new file mode 100644 index 00000000..2d1e1956 --- /dev/null +++ b/docs/clang-tidy/Integrations.rst @@ -0,0 +1,117 @@ +================================== +Clang-tidy IDE/Editor Integrations +================================== + +.. _Clangd: https://clang.llvm.org/extra/clangd.html + +Apart from being a standalone tool, :program:`clang-tidy` is integrated into +various IDEs, code analyzers, and editors. Besides, it is currently being +integrated into Clangd_. The following table shows the most +well-known :program:`clang-tidy` integrations in detail. + ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +| | Feature | ++======================================+========================+=================================+==========================+=========================================+==========================+ +| **Tool** | On-the-fly inspection | Check list configuration (GUI) | Options to checks (GUI) | Configuration via ``.clang-tidy`` files | Custom clang-tidy binary | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|A.L.E. for Vim | \+\ | \-\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Clang Power Tools for Visual Studio | \-\ | \+\ | \-\ | \+\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Clangd | \+\ | \-\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CLion IDE | \+\ | \+\ | \+\ | \+\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CodeChecker | \-\ | \-\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CPPCheck | \-\ | \-\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|CPPDepend | \-\ | \-\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Flycheck for Emacs | \+\ | \-\ | \-\ | \+\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|KDevelop IDE | \-\ | \+\ | \+\ | \+\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Qt Creator IDE | \+\ | \+\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|ReSharper C++ for Visual Studio | \+\ | \+\ | \-\ | \+\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Syntastic for Vim | \+\ | \-\ | \-\ | \-\ | \+\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ +|Visual Assist for Visual Studio | \+\ | \+\ | \-\ | \-\ | \-\ | ++--------------------------------------+------------------------+---------------------------------+--------------------------+-----------------------------------------+--------------------------+ + +**IDEs** + +.. _CLion: https://www.jetbrains.com/clion/ +.. _integrates clang-tidy: https://www.jetbrains.com/help/clion/clang-tidy-checks-support.html + +CLion_ 2017.2 and later `integrates clang-tidy`_ as an extension to the +built-in code analyzer. Starting from 2018.2 EAP, CLion allows using +:program:`clang-tidy` via Clangd. Inspections and applicable quick-fixes are +performed on the fly, and checks can be configured in standard command line +format. In this integration, you can switch to the :program:`clang-tidy` +binary different from the bundled one, pass the configuration in +``.clang-tidy`` files instead of using the IDE settings, and configure +options for particular checks. + +.. _KDevelop: https://www.kdevelop.org/ +.. _kdev-clang-tidy: https://github.com/KDE/kdev-clang-tidy/ + +KDevelop_ with the kdev-clang-tidy_ plugin, starting from version 5.1, performs +static analysis using :program:`clang-tidy`. The plugin launches the +:program:`clang-tidy` binary from the specified location and parses its +output to provide a list of issues. + +.. _QtCreator: https://www.qt.io/ +.. _Clang Code Model: http://doc.qt.io/qtcreator/creator-clang-codemodel.html + +QtCreator_ 4.6 integrates :program:`clang-tidy` warnings into the editor +diagnostics under the `Clang Code Model`_. To employ :program:`clang-tidy` +inspection in QtCreator, you need to create a copy of one of the presets and +choose the checks to be performed in the Clang Code Model Warnings menu. + +.. _MS Visual Studio: https://visualstudio.microsoft.com/ +.. _ReSharper C++: https://www.jetbrains.com/help/resharper/Clang_Tidy_Integration.html +.. _Visual Assist: https://docs.wholetomato.com/default.asp?W761 +.. _Clang Power Tools: https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools +.. _clang-tidy-vs: https://github.com/llvm-mirror/clang-tools-extra/tree/master/clang-tidy-vs + +`MS Visual Studio`_ has a native clang-tidy-vs_ plugin and also can integrate +:program:`clang-tidy` by means of three other tools. The `ReSharper C++`_ +extension, version 2017.3 and later, provides seamless :program:`clang-tidy` +integration: checks and quick-fixes run alongside native inspections. Apart +from that, ReSharper C++ incorporates :program:`clang-tidy` as a separate +step of its code clean-up process. `Visual Assist`_ build 2210 includes a +subset of :program:`clang-tidy` checklist to inspect the code as you edit. +Another way to bring :program:`clang-tidy` functionality to Visual Studio is +the `Clang Power Tools`_ plugin, which includes most of the +:program:`clang-tidy` checks and runs them during compilation or as a separate +step of code analysis. + +**Editors** + +.. _Flycheck: https://github.com/ch1bo/flycheck-clang-tidy +.. _Syntastic: https://github.com/vim-syntastic/syntastic +.. _A.L.E.: https://github.com/w0rp/ale +.. _Emacs24: https://www.gnu.org/s/emacs/ +.. _Vim: https://www.vim.org/ + +Emacs24_, when expanded with the Flycheck_ plugin, incorporates the +:program:`clang-tidy` inspection into the syntax analyzer. For Vim_, you can +use Syntastic_, which includes :program:`clang-tidy`, or `A.L.E.`_, +a lint engine that applies :program:`clang-tidy` along with other linters. + +**Analyzers** + +.. _CPPDepend: https://www.cppdepend.com/cppdependv2018 +.. _CPPCheck: https://sourceforge.net/p/cppcheck/news/ +.. _CodeChecker: https://github.com/Ericsson/codechecker +.. _plugin: https://github.com/Ericsson/CodeCheckerEclipsePlugin + +:program:`clang-tidy` is integrated in CPPDepend_ starting from version 2018.1 +and CPPCheck_ 1.82. CPPCheck integration lets you import Visual Studio +solutions and run the :program:`clang-tidy` inspection on them. The +CodeChecker_ application of version 5.3 or later, which also comes as a plugin_ +for Eclipse, supports :program:`clang-tidy` as a static analysis instrument and +allows to use a custom :program:`clang-tidy` binary. diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst index 20b18b4b..4172d134 100644 --- a/docs/clang-tidy/index.rst +++ b/docs/clang-tidy/index.rst @@ -10,6 +10,8 @@ See also: :maxdepth: 1 The list of clang-tidy checks + Clang-tidy IDE/Editor Integrations + Getting Involved :program:`clang-tidy` is a clang-based C++ "linter" tool. Its purpose is to provide an extensible framework for diagnosing and fixing typical programming @@ -310,511 +312,3 @@ the parenthesis) whitespaces can be used and will be ignored. .. _LibTooling: http://clang.llvm.org/docs/LibTooling.html .. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html - - -Getting Involved -================ - -:program:`clang-tidy` has several own checks and can run Clang static analyzer -checks, but its power is in the ability to easily write custom checks. - -Checks are organized in modules, which can be linked into :program:`clang-tidy` -with minimal or no code changes in :program:`clang-tidy`. - -Checks can plug into the analysis on the preprocessor level using `PPCallbacks`_ -or on the AST level using `AST Matchers`_. When an error is found, checks can -report them in a way similar to how Clang diagnostics work. A fix-it hint can be -attached to a diagnostic message. - -The interface provided by :program:`clang-tidy` makes it easy to write useful -and precise checks in just a few lines of code. If you have an idea for a good -check, the rest of this document explains how to do this. - -There are a few tools particularly useful when developing clang-tidy checks: - * ``add_new_check.py`` is a script to automate the process of adding a new - check, it will create the check, update the CMake file and create a test; - * ``rename_check.py`` does what the script name suggests, renames an existing - check; - * :program:`clang-query` is invaluable for interactive prototyping of AST - matchers and exploration of the Clang AST; - * `clang-check`_ with the ``-ast-dump`` (and optionally ``-ast-dump-filter``) - provides a convenient way to dump AST of a C++ program. - -If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, -:program:`clang-tidy` will not be built with support for the -``clang-analyzer-*`` checks or the ``mpi-*`` checks. - - -.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html -.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html -.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html - - -Choosing the Right Place for your Check ---------------------------------------- - -If you have an idea of a check, you should decide whether it should be -implemented as a: - -+ *Clang diagnostic*: if the check is generic enough, targets code patterns that - most probably are bugs (rather than style or readability issues), can be - implemented effectively and with extremely low false positive rate, it may - make a good Clang diagnostic. - -+ *Clang static analyzer check*: if the check requires some sort of control flow - analysis, it should probably be implemented as a static analyzer check. - -+ *clang-tidy check* is a good choice for linter-style checks, checks that are - related to a certain coding style, checks that address code readability, etc. - - -Preparing your Workspace ------------------------- - -If you are new to LLVM development, you should read the `Getting Started with -the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_ -documents to check out and build LLVM, Clang and Clang Extra Tools with CMake. - -Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and -let's start! - -.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html -.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html - - -The Directory Structure ------------------------ - -:program:`clang-tidy` source code resides in the -``llvm/tools/clang/tools/extra`` directory and is structured as follows: - -:: - - clang-tidy/ # Clang-tidy core. - |-- ClangTidy.h # Interfaces for users and checks. - |-- ClangTidyModule.h # Interface for clang-tidy modules. - |-- ClangTidyModuleRegistry.h # Interface for registering of modules. - ... - |-- google/ # Google clang-tidy module. - |-+ - |-- GoogleTidyModule.cpp - |-- GoogleTidyModule.h - ... - |-- llvm/ # LLVM clang-tidy module. - |-+ - |-- LLVMTidyModule.cpp - |-- LLVMTidyModule.h - ... - |-- objc/ # Objective-C clang-tidy module. - |-+ - |-- ObjCTidyModule.cpp - |-- ObjCTidyModule.h - ... - |-- tool/ # Sources of the clang-tidy binary. - ... - test/clang-tidy/ # Integration tests. - ... - unittests/clang-tidy/ # Unit tests. - |-- ClangTidyTest.h - |-- GoogleModuleTest.cpp - |-- LLVMModuleTest.cpp - |-- ObjCModuleTest.cpp - ... - - -Writing a clang-tidy Check --------------------------- - -So you have an idea of a useful check for :program:`clang-tidy`. - -First, if you're not familiar with LLVM development, read through the `Getting -Started with LLVM`_ document for instructions on setting up your workflow and -the `LLVM Coding Standards`_ document to familiarize yourself with the coding -style used in the project. For code reviews we mostly use `LLVM Phabricator`_. - -.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html -.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html -.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html - -Next, you need to decide which module the check belongs to. Modules -are located in subdirectories of `clang-tidy/ -`_ -and contain checks targeting a certain aspect of code quality (performance, -readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.) -or a widely used API (e.g. MPI). Their names are same as user-facing check -groups names described :ref:`above `. - -After choosing the module and the name for the check, run the -``clang-tidy/add_new_check.py`` script to create the skeleton of the check and -plug it to :program:`clang-tidy`. It's the recommended way of adding new checks. - -If we want to create a `readability-awesome-function-names`, we would run: - -.. code-block:: console - - $ clang-tidy/add_new_check.py readability awesome-function-names - - -The ``add_new_check.py`` script will: - * create the class for your check inside the specified module's directory and - register it in the module and in the build system; - * create a lit test file in the ``test/clang-tidy/`` directory; - * create a documentation file and include it into the - ``docs/clang-tidy/checks/list.rst``. - -Let's see in more detail at the check class definition: - -.. code-block:: c++ - - ... - - #include "../ClangTidy.h" - - namespace clang { - namespace tidy { - namespace readability { - - ... - class AwesomeFunctionNamesCheck : public ClangTidyCheck { - public: - AwesomeFunctionNamesCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} - void registerMatchers(ast_matchers::MatchFinder *Finder) override; - void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - }; - - } // namespace readability - } // namespace tidy - } // namespace clang - - ... - -Constructor of the check receives the ``Name`` and ``Context`` parameters, and -must forward them to the ``ClangTidyCheck`` constructor. - -In our case the check needs to operate on the AST level and it overrides the -``registerMatchers`` and ``check`` methods. If we wanted to analyze code on the -preprocessor level, we'd need instead to override the ``registerPPCallbacks`` -method. - -In the ``registerMatchers`` method we create an AST Matcher (see `AST Matchers`_ -for more information) that will find the pattern in the AST that we want to -inspect. The results of the matching are passed to the ``check`` method, which -can further inspect them and report diagnostics. - -.. code-block:: c++ - - using namespace ast_matchers; - - void AwesomeFunctionNamesCheck::registerMatchers(MatchFinder *Finder) { - Finder->addMatcher(functionDecl().bind("x"), this); - } - - void AwesomeFunctionNamesCheck::check(const MatchFinder::MatchResult &Result) { - const auto *MatchedDecl = Result.Nodes.getNodeAs("x"); - if (MatchedDecl->getName().startswith("awesome_")) - return; - diag(MatchedDecl->getLocation(), "function %0 is insufficiently awesome") - << MatchedDecl - << FixItHint::CreateInsertion(MatchedDecl->getLocation(), "awesome_"); - } - -(If you want to see an example of a useful check, look at -`clang-tidy/google/ExplicitConstructorCheck.h -`_ -and `clang-tidy/google/ExplicitConstructorCheck.cpp -`_). - - -Registering your Check ----------------------- - -(The ``add_new_check.py`` takes care of registering the check in an existing -module. If you want to create a new module or know the details, read on.) - -The check should be registered in the corresponding module with a distinct name: - -.. code-block:: c++ - - class MyModule : public ClangTidyModule { - public: - void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { - CheckFactories.registerCheck( - "my-explicit-constructor"); - } - }; - -Now we need to register the module in the ``ClangTidyModuleRegistry`` using a -statically initialized variable: - -.. code-block:: c++ - - static ClangTidyModuleRegistry::Add X("my-module", - "Adds my lint checks."); - - -When using LLVM build system, we need to use the following hack to ensure the -module is linked into the :program:`clang-tidy` binary: - -Add this near the ``ClangTidyModuleRegistry::Add`` variable: - -.. code-block:: c++ - - // This anchor is used to force the linker to link in the generated object file - // and thus register the MyModule. - volatile int MyModuleAnchorSource = 0; - -And this to the main translation unit of the :program:`clang-tidy` binary (or -the binary you link the ``clang-tidy`` library in) -``clang-tidy/tool/ClangTidyMain.cpp``: - -.. code-block:: c++ - - // This anchor is used to force the linker to link the MyModule. - extern volatile int MyModuleAnchorSource; - static int MyModuleAnchorDestination = MyModuleAnchorSource; - - -Configuring Checks ------------------- - -If a check needs configuration options, it can access check-specific options -using the ``Options.get("SomeOption", DefaultValue)`` call in the check -constructor. In this case the check should also override the -``ClangTidyCheck::storeOptions`` method to make the options provided by the -check discoverable. This method lets :program:`clang-tidy` know which options -the check implements and what the current values are (e.g. for the -``-dump-config`` command line option). - -.. code-block:: c++ - - class MyCheck : public ClangTidyCheck { - const unsigned SomeOption1; - const std::string SomeOption2; - - public: - MyCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - SomeOption(Options.get("SomeOption1", -1U)), - SomeOption(Options.get("SomeOption2", "some default")) {} - - void storeOptions(ClangTidyOptions::OptionMap &Opts) override { - Options.store(Opts, "SomeOption1", SomeOption1); - Options.store(Opts, "SomeOption2", SomeOption2); - } - ... - -Assuming the check is registered with the name "my-check", the option can then -be set in a ``.clang-tidy`` file in the following way: - -.. code-block:: yaml - - CheckOptions: - - key: my-check.SomeOption1 - value: 123 - - key: my-check.SomeOption2 - value: 'some other value' - -If you need to specify check options on a command line, you can use the inline -YAML format: - -.. code-block:: console - - $ clang-tidy -config="{CheckOptions: [{key: a, value: b}, {key: x, value: y}]}" ... - - -Testing Checks --------------- - -To run tests for :program:`clang-tidy` use the command: - -.. code-block:: console - - $ ninja check-clang-tools - -:program:`clang-tidy` checks can be tested using either unit tests or -`lit`_ tests. Unit tests may be more convenient to test complex replacements -with strict checks. `Lit`_ tests allow using partial text matching and regular -expressions which makes them more suitable for writing compact tests for -diagnostic messages. - -The ``check_clang_tidy.py`` script provides an easy way to test both -diagnostic messages and fix-its. It filters out ``CHECK`` lines from the test -file, runs :program:`clang-tidy` and verifies messages and fixes with two -separate `FileCheck`_ invocations: once with FileCheck's directive -prefix set to ``CHECK-MESSAGES``, validating the diagnostic messages, -and once with the directive prefix set to ``CHECK-FIXES``, running -against the fixed code (i.e., the code after generated fix-its are -applied). In particular, ``CHECK-FIXES:`` can be used to check -that code was not modified by fix-its, by checking that it is present -unchanged in the fixed code. The full set of `FileCheck`_ directives -is available (e.g., ``CHECK-MESSAGES-SAME:``, ``CHECK-MESSAGES-NOT:``), though -typically the basic ``CHECK`` forms (``CHECK-MESSAGES`` and ``CHECK-FIXES``) -are sufficient for clang-tidy tests. Note that the `FileCheck`_ -documentation mostly assumes the default prefix (``CHECK``), and hence -describes the directive as ``CHECK:``, ``CHECK-SAME:``, ``CHECK-NOT:``, etc. -Replace ``CHECK`` by either ``CHECK-FIXES`` or ``CHECK-MESSAGES`` for -clang-tidy tests. - -An additional check enabled by ``check_clang_tidy.py`` ensures that -if `CHECK-MESSAGES:` is used in a file then every warning or error -must have an associated CHECK in that file. Or, you can use ``CHECK-NOTES:`` -instead, if you want to **also** ensure that all the notes are checked. - -To use the ``check_clang_tidy.py`` script, put a .cpp file with the -appropriate ``RUN`` line in the ``test/clang-tidy`` directory. Use -``CHECK-MESSAGES:`` and ``CHECK-FIXES:`` lines to write checks against -diagnostic messages and fixed code. - -It's advised to make the checks as specific as possible to avoid checks matching -to incorrect parts of the input. Use ``[[@LINE+X]]``/``[[@LINE-X]]`` -substitutions and distinct function and variable names in the test code. - -Here's an example of a test using the ``check_clang_tidy.py`` script (the full -source code is at `test/clang-tidy/google-readability-casting.cpp`_): - -.. code-block:: c++ - - // RUN: %check_clang_tidy %s google-readability-casting %t - - void f(int a) { - int b = (int)a; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type [google-readability-casting] - // CHECK-FIXES: int b = a; - } - -To check more than one scenario in the same test file use -``-check-suffix=SUFFIX-NAME`` on ``check_clang_tidy.py`` command line or -``-check-suffixes=SUFFIX-NAME-1,SUFFIX-NAME-2,...``. -With ``-check-suffix[es]=SUFFIX-NAME`` you need to replace your ``CHECK-*`` -directives with ``CHECK-MESSAGES-SUFFIX-NAME`` and ``CHECK-FIXES-SUFFIX-NAME``. - -Here's an example: - -.. code-block:: c++ - - // RUN: %check_clang_tidy -check-suffix=USING-A %s misc-unused-using-decls %t -- -- -DUSING_A - // RUN: %check_clang_tidy -check-suffix=USING-B %s misc-unused-using-decls %t -- -- -DUSING_B - // RUN: %check_clang_tidy %s misc-unused-using-decls %t - ... - // CHECK-MESSAGES-USING-A: :[[@LINE-8]]:10: warning: using decl 'A' {{.*}} - // CHECK-MESSAGES-USING-B: :[[@LINE-7]]:10: warning: using decl 'B' {{.*}} - // CHECK-MESSAGES: :[[@LINE-6]]:10: warning: using decl 'C' {{.*}} - // CHECK-FIXES-USING-A-NOT: using a::A;$ - // CHECK-FIXES-USING-B-NOT: using a::B;$ - // CHECK-FIXES-NOT: using a::C;$ - - -There are many dark corners in the C++ language, and it may be difficult to make -your check work perfectly in all cases, especially if it issues fix-it hints. The -most frequent pitfalls are macros and templates: - -1. code written in a macro body/template definition may have a different meaning - depending on the macro expansion/template instantiation; -2. multiple macro expansions/template instantiations may result in the same code - being inspected by the check multiple times (possibly, with different - meanings, see 1), and the same warning (or a slightly different one) may be - issued by the check multiple times; :program:`clang-tidy` will deduplicate - _identical_ warnings, but if the warnings are slightly different, all of them - will be shown to the user (and used for applying fixes, if any); -3. making replacements to a macro body/template definition may be fine for some - macro expansions/template instantiations, but easily break some other - expansions/instantiations. - -.. _lit: http://llvm.org/docs/CommandGuide/lit.html -.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html -.. _test/clang-tidy/google-readability-casting.cpp: http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp - - -Running clang-tidy on LLVM --------------------------- - -To test a check it's best to try it out on a larger code base. LLVM and Clang -are the natural targets as you already have the source code around. The most -convenient way to run :program:`clang-tidy` is with a compile command database; -CMake can automatically generate one, for a description of how to enable it see -`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place and -a working version of :program:`clang-tidy` is in ``PATH`` the entire code base -can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script executes -:program:`clang-tidy` with the default set of checks on every translation unit -in the compile command database and displays the resulting warnings and errors. -The script provides multiple configuration flags. - -* The default set of checks can be overridden using the ``-checks`` argument, - taking the identical format as :program:`clang-tidy` does. For example - ``-checks=-*,modernize-use-override`` will run the ``modernize-use-override`` - check only. - -* To restrict the files examined you can provide one or more regex arguments - that the file names are matched against. - ``run-clang-tidy.py clang-tidy/.*Check\.cpp`` will only analyze clang-tidy - checks. It may also be necessary to restrict the header files warnings are - displayed from using the ``-header-filter`` flag. It has the same behavior - as the corresponding :program:`clang-tidy` flag. - -* To apply suggested fixes ``-fix`` can be passed as an argument. This gathers - all changes in a temporary directory and applies them. Passing ``-format`` - will run clang-format over changed lines. - - -On checks profiling -------------------- - -:program:`clang-tidy` can collect per-check profiling info, and output it -for each processed source file (translation unit). - -To enable profiling info collection, use the ``-enable-check-profile`` argument. -The timings will be output to ``stderr`` as a table. Example output: - -.. code-block:: console - - $ clang-tidy -enable-check-profile -checks=-*,readability-function-size source.cpp - ===-------------------------------------------------------------------------=== - clang-tidy checks profiling - ===-------------------------------------------------------------------------=== - Total Execution Time: 1.0282 seconds (1.0258 wall clock) - - ---User Time--- --System Time-- --User+System-- ---Wall Time--- --- Name --- - 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) readability-function-size - 0.9136 (100.0%) 0.1146 (100.0%) 1.0282 (100.0%) 1.0258 (100.0%) Total - -It can also store that data as JSON files for further processing. Example output: - -.. code-block:: console - - $ clang-tidy -enable-check-profile -store-check-profile=. -checks=-*,readability-function-size source.cpp - $ # Note that there won't be timings table printed to the console. - $ ls /tmp/out/ - 20180516161318717446360-source.cpp.json - $ cat 20180516161318717446360-source.cpp.json - { - "file": "/path/to/source.cpp", - "timestamp": "2018-05-16 16:13:18.717446360", - "profile": { - "time.clang-tidy.readability-function-size.wall": 1.0421266555786133e+00, - "time.clang-tidy.readability-function-size.user": 9.2088400000005421e-01, - "time.clang-tidy.readability-function-size.sys": 1.2418899999999974e-01 - } - } - -There is only one argument that controls profile storage: - -* ``-store-check-profile=`` - - By default reports are printed in tabulated format to stderr. When this option - is passed, these per-TU profiles are instead stored as JSON. - If the prefix is not an absolute path, it is considered to be relative to the - directory from where you have run :program:`clang-tidy`. All ``.`` and ``..`` - patterns in the path are collapsed, and symlinks are resolved. - - Example: - Let's suppose you have a source file named ``example.cpp``, located in the - ``/source`` directory. Only the input filename is used, not the full path - to the source file. Additionally, it is prefixed with the current timestamp. - - * If you specify ``-store-check-profile=/tmp``, then the profile will be saved - to ``/tmp/-example.cpp.json`` - - * If you run :program:`clang-tidy` from within ``/foo`` directory, and specify - ``-store-check-profile=.``, then the profile will still be saved to - ``/foo/-example.cpp.json`` -- cgit v1.2.3 From c90decf8bee460edd288daf256e9b4241d04adad Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Thu, 17 Jan 2019 19:35:39 +0000 Subject: [Documentation] Fix link in docs/clang-tidy/Contributing.rst. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351466 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/Contributing.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/clang-tidy/Contributing.rst b/docs/clang-tidy/Contributing.rst index ab64b39b..56b2ae02 100644 --- a/docs/clang-tidy/Contributing.rst +++ b/docs/clang-tidy/Contributing.rst @@ -59,8 +59,9 @@ Preparing your Workspace ------------------------ If you are new to LLVM development, you should read the `Getting Started with -the LLVM System`_, `Using Clang Tools`_ and `How To Setup Tooling For LLVM`_ -documents to check out and build LLVM, Clang and Clang Extra Tools with CMake. +the LLVM System`_, `Using Clang Tools`_ and `How To Setup Clang Tooling For +LLVM`_ documents to check out and build LLVM, Clang and Clang Extra Tools with +CMake. Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and let's start! -- cgit v1.2.3 From deca4c90b4e8f116e4992238f0d51e289fd5ef10 Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Thu, 17 Jan 2019 19:47:44 +0000 Subject: [Documentation] Another attempt to fix link in docs/clang-tidy/Contributing.rst. Use HTTPS for links. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351467 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/Contributing.rst | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/docs/clang-tidy/Contributing.rst b/docs/clang-tidy/Contributing.rst index 56b2ae02..c0554e9a 100644 --- a/docs/clang-tidy/Contributing.rst +++ b/docs/clang-tidy/Contributing.rst @@ -32,9 +32,9 @@ If CMake is configured with ``CLANG_ENABLE_STATIC_ANALYZER``, ``clang-analyzer-*`` checks or the ``mpi-*`` checks. -.. _AST Matchers: http://clang.llvm.org/docs/LibASTMatchers.html -.. _PPCallbacks: http://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html -.. _clang-check: http://clang.llvm.org/docs/ClangCheck.html +.. _AST Matchers: https://clang.llvm.org/docs/LibASTMatchers.html +.. _PPCallbacks: https://clang.llvm.org/doxygen/classclang_1_1PPCallbacks.html +.. _clang-check: https://clang.llvm.org/docs/ClangCheck.html Choosing the Right Place for your Check @@ -66,8 +66,9 @@ CMake. Once you are done, change to the ``llvm/tools/clang/tools/extra`` directory, and let's start! -.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html -.. _Using Clang Tools: http://clang.llvm.org/docs/ClangTools.html +.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html +.. _Using Clang Tools: https://clang.llvm.org/docs/ClangTools.html +.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html The Directory Structure @@ -120,13 +121,13 @@ Started with LLVM`_ document for instructions on setting up your workflow and the `LLVM Coding Standards`_ document to familiarize yourself with the coding style used in the project. For code reviews we mostly use `LLVM Phabricator`_. -.. _Getting Started with LLVM: http://llvm.org/docs/GettingStarted.html -.. _LLVM Coding Standards: http://llvm.org/docs/CodingStandards.html -.. _LLVM Phabricator: http://llvm.org/docs/Phabricator.html +.. _Getting Started with LLVM: https://llvm.org/docs/GettingStarted.html +.. _LLVM Coding Standards: https://llvm.org/docs/CodingStandards.html +.. _LLVM Phabricator: https://llvm.org/docs/Phabricator.html Next, you need to decide which module the check belongs to. Modules are located in subdirectories of `clang-tidy/ -`_ +`_ and contain checks targeting a certain aspect of code quality (performance, readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.) or a widely used API (e.g. MPI). Their names are same as user-facing check @@ -209,9 +210,9 @@ can further inspect them and report diagnostics. (If you want to see an example of a useful check, look at `clang-tidy/google/ExplicitConstructorCheck.h -`_ +`_ and `clang-tidy/google/ExplicitConstructorCheck.cpp -`_). +`_). Registering your Check @@ -409,9 +410,9 @@ most frequent pitfalls are macros and templates: macro expansions/template instantiations, but easily break some other expansions/instantiations. -.. _lit: http://llvm.org/docs/CommandGuide/lit.html -.. _FileCheck: http://llvm.org/docs/CommandGuide/FileCheck.html -.. _test/clang-tidy/google-readability-casting.cpp: http://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp +.. _lit: https://llvm.org/docs/CommandGuide/lit.html +.. _FileCheck: https://llvm.org/docs/CommandGuide/FileCheck.html +.. _test/clang-tidy/google-readability-casting.cpp: https://reviews.llvm.org/diffusion/L/browse/clang-tools-extra/trunk/test/clang-tidy/google-readability-casting.cpp Running clang-tidy on LLVM -- cgit v1.2.3 From 563ffd667318c498f08a6f4810d21ef338610100 Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Thu, 17 Jan 2019 20:00:23 +0000 Subject: [Documentation] Fix another link in docs/clang-tidy/Contributing.rst. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351468 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/Contributing.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/clang-tidy/Contributing.rst b/docs/clang-tidy/Contributing.rst index c0554e9a..6d61809e 100644 --- a/docs/clang-tidy/Contributing.rst +++ b/docs/clang-tidy/Contributing.rst @@ -422,12 +422,15 @@ To test a check it's best to try it out on a larger code base. LLVM and Clang are the natural targets as you already have the source code around. The most convenient way to run :program:`clang-tidy` is with a compile command database; CMake can automatically generate one, for a description of how to enable it see -`How To Setup Tooling For LLVM`_. Once ``compile_commands.json`` is in place and -a working version of :program:`clang-tidy` is in ``PATH`` the entire code base -can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script executes -:program:`clang-tidy` with the default set of checks on every translation unit -in the compile command database and displays the resulting warnings and errors. -The script provides multiple configuration flags. +`How To Setup Clang Tooling For LLVM`_. Once ``compile_commands.json`` is in +place and a working version of :program:`clang-tidy` is in ``PATH`` the entire +code base can be analyzed with ``clang-tidy/tool/run-clang-tidy.py``. The script +executes :program:`clang-tidy` with the default set of checks on every +translation unit in the compile command database and displays the resulting +warnings and errors. The script provides multiple configuration flags. + +.. _How To Setup Clang Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html + * The default set of checks can be overridden using the ``-checks`` argument, taking the identical format as :program:`clang-tidy` does. For example -- cgit v1.2.3 From 0d35b5e1955c89d64a43e14bb61df50a91008bd1 Mon Sep 17 00:00:00 2001 From: Aaron Ballman Date: Thu, 17 Jan 2019 20:21:44 +0000 Subject: Revert r351208 (which was a revert of r350892). This corresponds to the fix to Clang in r351470. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351471 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/modularize/ProblemsInconsistent.modularize | 10 ------ test/pp-trace/pp-trace-conditional.cpp | 48 ++++++++++++------------- test/pp-trace/pp-trace-macro.cpp | 4 +-- 3 files changed, 26 insertions(+), 36 deletions(-) diff --git a/test/modularize/ProblemsInconsistent.modularize b/test/modularize/ProblemsInconsistent.modularize index 04d0b013..713bfe90 100644 --- a/test/modularize/ProblemsInconsistent.modularize +++ b/test/modularize/ProblemsInconsistent.modularize @@ -60,16 +60,6 @@ Inputs/InconsistentHeader2.h # CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h # CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h # CHECK-NEXT: (no macro definition) -# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:11:2 -# CHECK-NEXT: #if SYMBOL == 1 -# CHECK-NEXT: ^ -# CHECK-NEXT: error: Conditional expression instance 'SYMBOL == 1' has different values in this header, depending on how it was included. -# CHECK-NEXT: 'SYMBOL == 1' expanded to: 'true' with respect to these inclusion paths: -# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader1.h -# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h -# CHECK-NEXT: 'SYMBOL == 1' expanded to: 'false' with respect to these inclusion paths: -# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentHeader2.h -# CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h # CHECK-NEXT: {{.*}}{{[/\\]}}Inputs{{[/\\]}}InconsistentSubHeader.h:2:2 # CHECK-NEXT: #ifdef SYMBOL1 # CHECK-NEXT: ^ diff --git a/test/pp-trace/pp-trace-conditional.cpp b/test/pp-trace/pp-trace-conditional.cpp index ac5d3b37..8e7ce887 100644 --- a/test/pp-trace/pp-trace-conditional.cpp +++ b/test/pp-trace/pp-trace-conditional.cpp @@ -79,14 +79,14 @@ // CHECK-NEXT: MacroDirective: MD_Define // CHECK: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:4:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Endif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:4:2" // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:3:2" // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:5"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Endif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:2" @@ -95,7 +95,7 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:6:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:7:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:9:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Else // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:2" @@ -107,7 +107,7 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:10:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:11:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:5"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Else // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:14:2" @@ -119,11 +119,11 @@ // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:13:2" // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:8"] // CHECK-NEXT: ConditionValue: CVK_NotEvaluated // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:17:2" // CHECK-NEXT: - Callback: Endif @@ -133,11 +133,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:18:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:19:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:8"] // CHECK-NEXT: ConditionValue: CVK_NotEvaluated // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:20:2" // CHECK-NEXT: - Callback: Endif @@ -147,11 +147,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:21:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:22:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:5"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:26:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:25:7"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2" // CHECK-NEXT: - Callback: SourceRangeSkipped @@ -161,11 +161,11 @@ // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:24:2" // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:5"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:28:7"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:2" // CHECK-NEXT: - Callback: Endif @@ -175,11 +175,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:27:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:29:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:8"] // CHECK-NEXT: ConditionValue: CVK_NotEvaluated // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:30:2" // CHECK-NEXT: - Callback: Endif @@ -189,11 +189,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:31:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:32:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:8"] // CHECK-NEXT: ConditionValue: CVK_NotEvaluated // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:33:2" // CHECK-NEXT: - Callback: Endif @@ -203,11 +203,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:34:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:35:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:5"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:38:7"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:37:2" // CHECK-NEXT: - Callback: SourceRangeSkipped @@ -222,11 +222,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:39:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:40:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:5"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:43:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:42:7"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2" // CHECK-NEXT: - Callback: Else @@ -239,11 +239,11 @@ // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:41:2" // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:47:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:8"] // CHECK-NEXT: ConditionValue: CVK_NotEvaluated // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:45:2" // CHECK-NEXT: - Callback: Endif @@ -253,11 +253,11 @@ // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:46:1", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:48:2"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:4", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:5", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:5"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Elif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:6", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:51:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:7", "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:50:8"] // CHECK-NEXT: ConditionValue: CVK_NotEvaluated // CHECK-NEXT: IfLoc: "{{.*}}{{[/\\]}}pp-trace-conditional.cpp:49:2" // CHECK-NEXT: - Callback: Endif diff --git a/test/pp-trace/pp-trace-macro.cpp b/test/pp-trace/pp-trace-macro.cpp index e6ba761d..1202aa20 100644 --- a/test/pp-trace/pp-trace-macro.cpp +++ b/test/pp-trace/pp-trace-macro.cpp @@ -44,7 +44,7 @@ X // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:19"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:4", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:6:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:5:19"] // CHECK-NEXT: ConditionValue: CVK_True // CHECK-NEXT: - Callback: Endif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:6:2" @@ -58,7 +58,7 @@ X // CHECK-NEXT: Range: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:19"] // CHECK-NEXT: - Callback: If // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:2" -// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:4", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:1"] +// CHECK-NEXT: ConditionRange: ["{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:5", "{{.*}}{{[/\\]}}pp-trace-macro.cpp:8:19"] // CHECK-NEXT: ConditionValue: CVK_False // CHECK-NEXT: - Callback: Endif // CHECK-NEXT: Loc: "{{.*}}{{[/\\]}}pp-trace-macro.cpp:9:2" -- cgit v1.2.3 From 317bf2b7a4369ad40c59604b32459eed2a4bb044 Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Thu, 17 Jan 2019 20:37:35 +0000 Subject: [clang-tidy] Add abseil-duration-conversion-cast check Differential Revision: https://reviews.llvm.org/D56532 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351473 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/AbseilTidyModule.cpp | 3 + clang-tidy/abseil/CMakeLists.txt | 1 + clang-tidy/abseil/DurationConversionCastCheck.cpp | 85 +++++++++++++++++++ clang-tidy/abseil/DurationConversionCastCheck.h | 36 ++++++++ docs/ReleaseNotes.rst | 6 +- .../checks/abseil-duration-conversion-cast.rst | 31 +++++++ docs/clang-tidy/checks/list.rst | 1 + .../clang-tidy/abseil-duration-conversion-cast.cpp | 95 ++++++++++++++++++++++ 8 files changed, 257 insertions(+), 1 deletion(-) create mode 100644 clang-tidy/abseil/DurationConversionCastCheck.cpp create mode 100644 clang-tidy/abseil/DurationConversionCastCheck.h create mode 100644 docs/clang-tidy/checks/abseil-duration-conversion-cast.rst create mode 100644 test/clang-tidy/abseil-duration-conversion-cast.cpp diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp index 18140015..da702c71 100644 --- a/clang-tidy/abseil/AbseilTidyModule.cpp +++ b/clang-tidy/abseil/AbseilTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" #include "DurationComparisonCheck.h" +#include "DurationConversionCastCheck.h" #include "DurationDivisionCheck.h" #include "DurationFactoryFloatCheck.h" #include "DurationFactoryScaleCheck.h" @@ -32,6 +33,8 @@ public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { CheckFactories.registerCheck( "abseil-duration-comparison"); + CheckFactories.registerCheck( + "abseil-duration-conversion-cast"); CheckFactories.registerCheck( "abseil-duration-division"); CheckFactories.registerCheck( diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt index bf9d9e84..6a37bab5 100644 --- a/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tidy/abseil/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyAbseilModule AbseilTidyModule.cpp DurationComparisonCheck.cpp + DurationConversionCastCheck.cpp DurationDivisionCheck.cpp DurationFactoryFloatCheck.cpp DurationFactoryScaleCheck.cpp diff --git a/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tidy/abseil/DurationConversionCastCheck.cpp new file mode 100644 index 00000000..830d61ef --- /dev/null +++ b/clang-tidy/abseil/DurationConversionCastCheck.cpp @@ -0,0 +1,85 @@ +//===--- DurationConversionCastCheck.cpp - clang-tidy ---------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "DurationConversionCastCheck.h" +#include "DurationRewriter.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace abseil { + +void DurationConversionCastCheck::registerMatchers(MatchFinder *Finder) { + auto CallMatcher = ignoringImpCasts(callExpr( + callee(functionDecl(DurationConversionFunction()).bind("func_decl")), + hasArgument(0, expr().bind("arg")))); + + Finder->addMatcher( + expr(anyOf( + cxxStaticCastExpr(hasSourceExpression(CallMatcher)).bind("cast_expr"), + cStyleCastExpr(hasSourceExpression(CallMatcher)).bind("cast_expr"), + cxxFunctionalCastExpr(hasSourceExpression(CallMatcher)) + .bind("cast_expr"))), + this); +} + +void DurationConversionCastCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *MatchedCast = + Result.Nodes.getNodeAs("cast_expr"); + + if (!isNotInMacro(Result, MatchedCast)) + return; + + const auto *FuncDecl = Result.Nodes.getNodeAs("func_decl"); + const auto *Arg = Result.Nodes.getNodeAs("arg"); + StringRef ConversionFuncName = FuncDecl->getName(); + + llvm::Optional Scale = getScaleForInverse(ConversionFuncName); + if (!Scale) + return; + + // Casting a double to an integer. + if (MatchedCast->getTypeAsWritten()->isIntegerType() && + ConversionFuncName.contains("Double")) { + llvm::StringRef NewFuncName = getInverseForScale(*Scale).second; + + diag(MatchedCast->getBeginLoc(), + "duration should be converted directly to an integer rather than " + "through a type cast") + << FixItHint::CreateReplacement( + MatchedCast->getSourceRange(), + (llvm::Twine(NewFuncName.substr(2)) + "(" + + tooling::fixit::getText(*Arg, *Result.Context) + ")") + .str()); + } + + // Casting an integer to a double. + if (MatchedCast->getTypeAsWritten()->isRealFloatingType() && + ConversionFuncName.contains("Int64")) { + llvm::StringRef NewFuncName = getInverseForScale(*Scale).first; + + diag(MatchedCast->getBeginLoc(), "duration should be converted directly to " + "a floating-piont number rather than " + "through a type cast") + << FixItHint::CreateReplacement( + MatchedCast->getSourceRange(), + (llvm::Twine(NewFuncName.substr(2)) + "(" + + tooling::fixit::getText(*Arg, *Result.Context) + ")") + .str()); + } +} + +} // namespace abseil +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/abseil/DurationConversionCastCheck.h b/clang-tidy/abseil/DurationConversionCastCheck.h new file mode 100644 index 00000000..bc5cbd86 --- /dev/null +++ b/clang-tidy/abseil/DurationConversionCastCheck.h @@ -0,0 +1,36 @@ +//===--- DurationConversionCastCheck.h - clang-tidy -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace abseil { + +/// Checks for casts of ``absl::Duration`` conversion functions, and recommends +/// the right conversion function instead. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-duration-conversion-cast.html +class DurationConversionCastCheck : public ClangTidyCheck { +public: + DurationConversionCastCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace abseil +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_DURATIONCONVERSIONCASTCHECK_H diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index ce8e0842..bb699349 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -67,7 +67,11 @@ The improvements are... Improvements to clang-tidy -------------------------- -- ... +- New :doc:`abseil-duration-conversion-cast + ` check. + + Checks for casts of ``absl::Duration`` conversion functions, and recommends + the right conversion function instead. Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/abseil-duration-conversion-cast.rst b/docs/clang-tidy/checks/abseil-duration-conversion-cast.rst new file mode 100644 index 00000000..3c1a152b --- /dev/null +++ b/docs/clang-tidy/checks/abseil-duration-conversion-cast.rst @@ -0,0 +1,31 @@ +.. title:: clang-tidy - abseil-duration-conversion-cast + +abseil-duration-conversion-cast +=============================== + +Checks for casts of ``absl::Duration`` conversion functions, and recommends +the right conversion function instead. + +Examples: + +.. code-block:: c++ + + // Original - Cast from a double to an integer + absl::Duration d; + int i = static_cast(absl::ToDoubleSeconds(d)); + + // Suggested - Use the integer conversion function directly. + int i = absl::ToInt64Seconds(d); + + + // Original - Cast from a double to an integer + absl::Duration d; + double x = static_cast(absl::ToInt64Seconds(d)); + + // Suggested - Use the integer conversion function directly. + double x = absl::ToDoubleSeconds(d); + + +Note: In the second example, the suggested fix could yield a different result, +as the conversion to integer could truncate. In practice, this is very rare, +and you should use ``absl::Trunc`` to perform this operation explicitly instead. diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 080e747b..509b1406 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -5,6 +5,7 @@ Clang-Tidy Checks .. toctree:: abseil-duration-comparison + abseil-duration-conversion-cast abseil-duration-division abseil-duration-factory-float abseil-duration-factory-scale diff --git a/test/clang-tidy/abseil-duration-conversion-cast.cpp b/test/clang-tidy/abseil-duration-conversion-cast.cpp new file mode 100644 index 00000000..260aa327 --- /dev/null +++ b/test/clang-tidy/abseil-duration-conversion-cast.cpp @@ -0,0 +1,95 @@ +// RUN: %check_clang_tidy %s abseil-duration-conversion-cast %t -- -- -I%S/Inputs + +#include "absl/time/time.h" + +void f() { + absl::Duration d1; + double x; + int i; + + i = static_cast(absl::ToDoubleHours(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Hours(d1); + x = static_cast(absl::ToInt64Hours(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleHours(d1); + i = static_cast(absl::ToDoubleMinutes(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Minutes(d1); + x = static_cast(absl::ToInt64Minutes(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleMinutes(d1); + i = static_cast(absl::ToDoubleSeconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Seconds(d1); + x = static_cast(absl::ToInt64Seconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleSeconds(d1); + i = static_cast(absl::ToDoubleMilliseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Milliseconds(d1); + x = static_cast(absl::ToInt64Milliseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleMilliseconds(d1); + i = static_cast(absl::ToDoubleMicroseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Microseconds(d1); + x = static_cast(absl::ToInt64Microseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + i = static_cast(absl::ToDoubleNanoseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Nanoseconds(d1); + x = static_cast(absl::ToInt64Nanoseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleNanoseconds(d1); + + // Functional-style casts + i = int(absl::ToDoubleHours(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Hours(d1); + x = float(absl::ToInt64Microseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + + // C-style casts + i = (int) absl::ToDoubleHours(d1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Hours(d1); + x = (float) absl::ToInt64Microseconds(d1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + + // Type aliasing + typedef int FancyInt; + typedef float FancyFloat; + + FancyInt j = static_cast(absl::ToDoubleHours(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToInt64Hours(d1); + FancyFloat k = static_cast(absl::ToInt64Microseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:18: warning: duration should be converted directly to a floating-piont number rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: absl::ToDoubleMicroseconds(d1); + + // Macro handling + // We want to transform things in macro arguments +#define EXTERNAL(x) (x) + 5 + i = EXTERNAL(static_cast(absl::ToDoubleSeconds(d1))); + // CHECK-MESSAGES: [[@LINE-1]]:16: warning: duration should be converted directly to an integer rather than through a type cast [abseil-duration-conversion-cast] + // CHECK-FIXES: EXTERNAL(absl::ToInt64Seconds(d1)); +#undef EXTERNAL + + // We don't want to transform this which get split across macro boundaries +#define SPLIT(x) static_cast((x)) + 5 + i = SPLIT(absl::ToDoubleSeconds(d1)); +#undef SPLIT + + // We also don't want to transform things inside of a macro definition +#define INTERNAL(x) static_cast(absl::ToDoubleSeconds((x))) + 5 + i = INTERNAL(d1); +#undef INTERNAL + + // These shouldn't be converted + i = static_cast(absl::ToInt64Seconds(d1)); + i = static_cast(absl::ToDoubleSeconds(d1)); +} -- cgit v1.2.3 From 92da8ca2a951b036cf7632a98117d7a0f1232ac4 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Fri, 18 Jan 2019 17:04:26 +0000 Subject: [clangd] Make background index less chatty Summary: It is producing too much input in non-verbose mode, i.e. a message per indexed file Reviewers: sammccall, kadircet Reviewed By: sammccall Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D56915 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351563 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Background.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp index b9b945c5..fc3bd253 100644 --- a/clangd/index/Background.cpp +++ b/clangd/index/Background.cpp @@ -398,7 +398,7 @@ llvm::Error BackgroundIndex::index(tooling::CompileCommand Cmd, DigestsSnapshot = IndexedFileDigests; } - log("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash)); + vlog("Indexing {0} (digest:={1})", Cmd.Filename, llvm::toHex(Hash)); ParseInputs Inputs; Inputs.FS = std::move(FS); Inputs.FS->setCurrentWorkingDirectory(Cmd.Directory); -- cgit v1.2.3 From 9e454c861c254debad1a0cbac9a56f8d6f84d058 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Fri, 18 Jan 2019 18:03:11 +0000 Subject: [clang-tidy] add reproducer for PR39949 into test-suite Summary: The underlying issue is fixed in https://reviews.llvm.org/D56444 and this test ensures the issue does not creep back into our code-base. Reviewers: alexfh, aaron.ballman, hokein, hwright Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D56918 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351569 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../abseil-upgrade-duration-conversions.cpp | 33 ++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/clang-tidy/abseil-upgrade-duration-conversions.cpp b/test/clang-tidy/abseil-upgrade-duration-conversions.cpp index 7d8ad43e..fed0f8bd 100644 --- a/test/clang-tidy/abseil-upgrade-duration-conversions.cpp +++ b/test/clang-tidy/abseil-upgrade-duration-conversions.cpp @@ -430,3 +430,36 @@ void factoryInMacros() { factoryTemplateAndMacro>(); TemplateFactoryInMacro(ConvertibleTo()); } + +// This is a reduced test-case for PR39949 and manifested in this check. +namespace std { +template +_Tp declval(); + +template +struct __res { + template + static decltype(declval<_Functor>()(_Args()...)) _S_test(int); + + template + static void _S_test(...); + + typedef decltype(_S_test<_ArgTypes...>(0)) type; +}; + +template +struct function; + +template +struct function { + template ::type> + function(_Functor) {} +}; +} // namespace std + +typedef std::function F; + +F foo() { + return F([] {}); +} -- cgit v1.2.3 From 4fbd349bcaec8e628af2d2a24946a91d6557c79f Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 19 Jan 2019 06:14:24 +0000 Subject: Install new LLVM license structure and new developer policy. This installs the new developer policy and moves all of the license files across all LLVM projects in the monorepo to the new license structure. The remaining projects will be moved independently. Note that I've left odd formatting and other idiosyncracies of the legacy license structure text alone to make the diff easier to read. Critically, note that we do not in any case *remove* the old license notice or terms, as that remains necessary until we finish the relicensing process. I've updated a few license files that refer to the LLVM license to instead simply refer generically to whatever license the LLVM project is under, basically trying to minimize confusion. This is really the culmination of so many people. Chris led the community discussions, drafted the policy update and organized the multi-year string of meeting between lawyers across the community to figure out the strategy. Numerous lawyers at companies in the community spent their time figuring out initial answers, and then the Foundation's lawyer Heather Meeker has done *so* much to help refine and get us ready here. I could keep going on, but I just want to make sure everyone realizes what a huge community effort this has been from the begining. Differential Revision: https://reviews.llvm.org/D56897 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351631 91177308-0d34-0410-b5e6-96231b3b80d8 --- LICENSE.TXT | 257 +++++++++++++++++++++++++++++++++--- clang-tidy-vs/ClangTidy/license.txt | 257 +++++++++++++++++++++++++++++++++--- clang-tidy/cert/LICENSE.TXT | 4 +- clang-tidy/hicpp/LICENSE.TXT | 4 +- 4 files changed, 476 insertions(+), 46 deletions(-) diff --git a/LICENSE.TXT b/LICENSE.TXT index 44864d4d..27f66f00 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -1,5 +1,240 @@ ============================================================================== -LLVM Release License +The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: +============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +============================================================================== +Software from third parties included in the LLVM Project: +============================================================================== +The LLVM Project contains third party software which is under different license +terms. All such code will be identified clearly using at least one of two +mechanisms: +1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or +2) It will contain specific license and restriction terms at the top of every + file. + +============================================================================== +Legacy LLVM License (ttps://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License @@ -41,23 +276,3 @@ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. - -============================================================================== -The LLVM software contains code written by third parties. Such software will -have its own individual LICENSE.TXT file in the directory in which it appears. -This file will describe the copyrights, license, and restrictions which apply -to that code. - -The disclaimer of warranty in the University of Illinois Open Source License -applies to all code in the LLVM Distribution, and nothing in any of the -other licenses gives permission to use the names of the LLVM Team or the -University of Illinois to endorse or promote products derived from this -Software. - -The following pieces of software have additional or alternate copyrights, -licenses, and/or restrictions: - -Program Directory -------- --------- -clang-tidy clang-tidy/cert -clang-tidy clang-tidy/hicpp diff --git a/clang-tidy-vs/ClangTidy/license.txt b/clang-tidy-vs/ClangTidy/license.txt index 547f6a48..92392772 100644 --- a/clang-tidy-vs/ClangTidy/license.txt +++ b/clang-tidy-vs/ClangTidy/license.txt @@ -1,5 +1,240 @@ ============================================================================== -LLVM Release License +The LLVM Project is under the Apache License v2.0 with LLVM Exceptions: +============================================================================== + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + +---- LLVM Exceptions to the Apache 2.0 License ---- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into an Object form of such source code, you +may redistribute such embedded portions in such Object form without complying +with the conditions of Sections 4(a), 4(b) and 4(d) of the License. + +In addition, if you combine or link compiled forms of this Software with +software that is licensed under the GPLv2 ("Combined Software") and if a +court of competent jurisdiction determines that the patent provision (Section +3), the indemnity provision (Section 9) or other Section of the License +conflicts with the conditions of the GPLv2, you may retroactively and +prospectively choose to deem waived or otherwise exclude such Section(s) of +the License, but only in their entirety and only with respect to the Combined +Software. + +============================================================================== +Software from third parties included in the LLVM Project: +============================================================================== +The LLVM Project contains third party software which is under different license +terms. All such code will be identified clearly using at least one of two +mechanisms: +1) It will be in a separate directory tree with its own `LICENSE.txt` or + `LICENSE` file at the top containing the specific license and restrictions + which apply to that software, or +2) It will contain specific license and restriction terms at the top of every + file. + +============================================================================== +Legacy LLVM License (ttps://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License @@ -41,23 +276,3 @@ CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE. - -============================================================================== -The LLVM software contains code written by third parties. Such software will -have its own individual LICENSE.TXT file in the directory in which it appears. -This file will describe the copyrights, license, and restrictions which apply -to that code. - -The disclaimer of warranty in the University of Illinois Open Source License -applies to all code in the LLVM Distribution, and nothing in any of the -other licenses gives permission to use the names of the LLVM Team or the -University of Illinois to endorse or promote products derived from this -Software. - -The following pieces of software have additional or alternate copyrights, -licenses, and/or restrictions: - -Program Directory -------- --------- - - diff --git a/clang-tidy/cert/LICENSE.TXT b/clang-tidy/cert/LICENSE.TXT index d8395ccc..769cc46f 100644 --- a/clang-tidy/cert/LICENSE.TXT +++ b/clang-tidy/cert/LICENSE.TXT @@ -1,8 +1,8 @@ ------------------------------------------------------------------------------ clang-tidy CERT Files ------------------------------------------------------------------------------ -All clang-tidy files are licensed under the LLVM license with the following -additions: +All clang-tidy files are licensed under the same terms as the rest of the LLVM +project with the following additions: Any file referencing a CERT Secure Coding guideline: Please allow this letter to serve as confirmation that open source projects on diff --git a/clang-tidy/hicpp/LICENSE.TXT b/clang-tidy/hicpp/LICENSE.TXT index fb8f513e..b432d4ea 100644 --- a/clang-tidy/hicpp/LICENSE.TXT +++ b/clang-tidy/hicpp/LICENSE.TXT @@ -1,8 +1,8 @@ ------------------------------------------------------------------------------ clang-tidy High-Integrity C++ Files ------------------------------------------------------------------------------ -All clang-tidy files are licensed under the LLVM license with the following -additions: +All clang-tidy files are licensed under the same terms as the rest of the LLVM +project with the following additions: Any file referencing a High-Integrity C++ Coding guideline: -- cgit v1.2.3 From d6c035da2e8d1e437cb044ce8d967ff42d737f8f Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 19 Jan 2019 06:29:07 +0000 Subject: Update some code used in our visual studio plugins to use linux file endings. We already used them in some cases, and this makes things consistent. This will also simplify updating the licenses in these files. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351632 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy-vs/ClangTidy/ClangTidyPackage.cs | 112 +++--- clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs | 416 +++++++++++------------ clang-tidy-vs/ClangTidy/PkgCmdID.cs | 2 +- 3 files changed, 265 insertions(+), 265 deletions(-) diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs index 9a0c9b67..c5164e72 100644 --- a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs +++ b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs @@ -1,56 +1,56 @@ -//===-- ClangTidyPackages.cs - VSPackage for clang-tidy ----------*- C# -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class contains a VS extension package that runs clang-tidy over a -// file in a VS text editor. -// -//===----------------------------------------------------------------------===// - -using Microsoft.VisualStudio.Editor; -using Microsoft.VisualStudio.Shell; -using Microsoft.VisualStudio.Shell.Interop; -using Microsoft.VisualStudio.TextManager.Interop; -using System; -using System.Collections; -using System.ComponentModel; -using System.ComponentModel.Design; -using System.IO; -using System.Runtime.InteropServices; -using System.Windows.Forms; -using System.Xml.Linq; - -namespace LLVM.ClangTidy -{ - [PackageRegistration(UseManagedResourcesOnly = true)] - [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] - [ProvideMenuResource("Menus.ctmenu", 1)] - [Guid(GuidList.guidClangTidyPkgString)] - [ProvideOptionPage(typeof(ClangTidyConfigurationPage), "LLVM/Clang", "ClangTidy", 0, 0, true)] - public sealed class ClangTidyPackage : Package - { - #region Package Members - protected override void Initialize() - { - base.Initialize(); - - var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; - if (commandService != null) - { - var menuCommandID = new CommandID(GuidList.guidClangTidyCmdSet, (int)PkgCmdIDList.cmdidClangTidy); - var menuItem = new MenuCommand(MenuItemCallback, menuCommandID); - commandService.AddCommand(menuItem); - } - } - #endregion - - private void MenuItemCallback(object sender, EventArgs args) - { - } - } -} +//===-- ClangTidyPackages.cs - VSPackage for clang-tidy ----------*- C# -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class contains a VS extension package that runs clang-tidy over a +// file in a VS text editor. +// +//===----------------------------------------------------------------------===// + +using Microsoft.VisualStudio.Editor; +using Microsoft.VisualStudio.Shell; +using Microsoft.VisualStudio.Shell.Interop; +using Microsoft.VisualStudio.TextManager.Interop; +using System; +using System.Collections; +using System.ComponentModel; +using System.ComponentModel.Design; +using System.IO; +using System.Runtime.InteropServices; +using System.Windows.Forms; +using System.Xml.Linq; + +namespace LLVM.ClangTidy +{ + [PackageRegistration(UseManagedResourcesOnly = true)] + [InstalledProductRegistration("#110", "#112", "1.0", IconResourceID = 400)] + [ProvideMenuResource("Menus.ctmenu", 1)] + [Guid(GuidList.guidClangTidyPkgString)] + [ProvideOptionPage(typeof(ClangTidyConfigurationPage), "LLVM/Clang", "ClangTidy", 0, 0, true)] + public sealed class ClangTidyPackage : Package + { + #region Package Members + protected override void Initialize() + { + base.Initialize(); + + var commandService = GetService(typeof(IMenuCommandService)) as OleMenuCommandService; + if (commandService != null) + { + var menuCommandID = new CommandID(GuidList.guidClangTidyCmdSet, (int)PkgCmdIDList.cmdidClangTidy); + var menuItem = new MenuCommand(MenuItemCallback, menuCommandID); + commandService.AddCommand(menuItem); + } + } + #endregion + + private void MenuItemCallback(object sender, EventArgs args) + { + } + } +} diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs index 20c8a8ff..9b49e669 100644 --- a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs +++ b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs @@ -1,208 +1,208 @@ -//===-- ClangTidyPropertyGrid.cs - UI for configuring clang-tidy -*- C# -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This class contains a UserControl consisting of a .NET PropertyGrid control -// allowing configuration of checks and check options for ClangTidy. -// -//===----------------------------------------------------------------------===// -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Drawing; -using System.Data; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows.Forms; -using System.IO; -using Microsoft.VisualStudio.Shell; - -namespace LLVM.ClangTidy -{ - /// - /// A UserControl displaying a PropertyGrid allowing configuration of clang-tidy - /// checks and check options, as well as serialization and deserialization of - /// clang-tidy configuration files. When a configuration file is loaded, the - /// entire chain of configuration files is analyzed based on the file path, - /// and quick access is provided to edit or view any of the files in the - /// configuration chain, allowing easy visualization of where values come from - /// (similar in spirit to the -explain-config option of clang-tidy). - /// - public partial class ClangTidyPropertyGrid : UserControl - { - /// - /// The sequence of .clang-tidy configuration files, starting from the root - /// of the filesystem, down to the selected file. - /// - List> PropertyChain_ = null; - - public ClangTidyPropertyGrid() - { - InitializeComponent(); - InitializeSettings(); - } - - private enum ShouldCancel - { - Yes, - No, - } - - public void SaveSettingsToStorage() - { - PersistUnsavedChanges(false); - } - - private ShouldCancel PersistUnsavedChanges(bool PromptFirst) - { - var UnsavedResults = PropertyChain_.Where(x => x.Key != null && x.Value.GetHasUnsavedChanges()); - if (UnsavedResults.Count() == 0) - return ShouldCancel.No; - - bool ShouldSave = false; - if (PromptFirst) - { - var Response = MessageBox.Show( - "You have unsaved changes! Do you want to save before loading a new file?", - "clang-tidy", - MessageBoxButtons.YesNoCancel); - - ShouldSave = (Response == DialogResult.Yes); - if (Response == DialogResult.Cancel) - return ShouldCancel.Yes; - } - else - ShouldSave = true; - - if (ShouldSave) - { - foreach (var Result in UnsavedResults) - { - ClangTidyConfigParser.SerializeClangTidyFile(Result.Value, Result.Key); - Result.Value.SetHasUnsavedChanges(false); - } - } - return ShouldCancel.No; - } - - public void InitializeSettings() - { - PropertyChain_ = new List>(); - PropertyChain_.Add(new KeyValuePair(null, ClangTidyProperties.RootProperties)); - reloadPropertyChain(); - } - - private void button1_Click(object sender, EventArgs e) - { - ShouldCancel Cancel = PersistUnsavedChanges(true); - if (Cancel == ShouldCancel.Yes) - return; - - using (OpenFileDialog D = new OpenFileDialog()) - { - D.Filter = "Clang Tidy files|.clang-tidy"; - D.CheckPathExists = true; - D.CheckFileExists = true; - - if (D.ShowDialog() == DialogResult.OK) - { - PropertyChain_.Clear(); - PropertyChain_ = ClangTidyConfigParser.ParseConfigurationChain(D.FileName); - textBox1.Text = D.FileName; - reloadPropertyChain(); - } - } - } - - private static readonly string DefaultText = "(Default)"; - private static readonly string BrowseText = "Browse for a file to edit its properties"; - - /// - /// After a new configuration file is chosen, analyzes the directory hierarchy - /// and finds all .clang-tidy files in the path, parses them and updates the - /// PropertyGrid and quick-access LinkLabel control to reflect the new property - /// chain. - /// - private void reloadPropertyChain() - { - StringBuilder LinkBuilder = new StringBuilder(); - LinkBuilder.Append(DefaultText); - LinkBuilder.Append(" > "); - int PrefixLength = LinkBuilder.Length; - - if (PropertyChain_.Count == 1) - LinkBuilder.Append(BrowseText); - else - LinkBuilder.Append(PropertyChain_[PropertyChain_.Count - 1].Key); - - linkLabelPath.Text = LinkBuilder.ToString(); - - // Given a path like D:\Foo\Bar\Baz, construct a LinkLabel where individual - // components of the path are clickable iff they contain a .clang-tidy file. - // Clicking one of the links then updates the PropertyGrid to display the - // selected .clang-tidy file. - ClangTidyProperties LastProps = ClangTidyProperties.RootProperties; - linkLabelPath.Links.Clear(); - linkLabelPath.Links.Add(0, DefaultText.Length, LastProps); - foreach (var Prop in PropertyChain_.Skip(1)) - { - LastProps = Prop.Value; - string ClangTidyFolder = Path.GetFileName(Prop.Key); - int ClangTidyFolderOffset = Prop.Key.Length - ClangTidyFolder.Length; - linkLabelPath.Links.Add(PrefixLength + ClangTidyFolderOffset, ClangTidyFolder.Length, LastProps); - } - propertyGrid1.SelectedObject = LastProps; - } - - private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) - { - ClangTidyProperties Props = (ClangTidyProperties)propertyGrid1.SelectedObject; - Props.SetHasUnsavedChanges(true); - - // When a CategoryVerb is selected, perform the corresponding action. - PropertyDescriptor Property = e.ChangedItem.PropertyDescriptor; - if (!(e.ChangedItem.Value is CategoryVerb)) - return; - - CategoryVerb Action = (CategoryVerb)e.ChangedItem.Value; - if (Action == CategoryVerb.None) - return; - - var Category = Property.Attributes.OfType().FirstOrDefault(); - if (Category == null) - return; - var SameCategoryProps = Props.GetProperties(new Attribute[] { Category }); - foreach (PropertyDescriptor P in SameCategoryProps) - { - if (P == Property) - continue; - switch (Action) - { - case CategoryVerb.Disable: - P.SetValue(propertyGrid1.SelectedObject, false); - break; - case CategoryVerb.Enable: - P.SetValue(propertyGrid1.SelectedObject, true); - break; - case CategoryVerb.Inherit: - P.ResetValue(propertyGrid1.SelectedObject); - break; - } - } - Property.ResetValue(propertyGrid1.SelectedObject); - propertyGrid1.Invalidate(); - } - - private void linkLabelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) - { - ClangTidyProperties Props = (ClangTidyProperties)e.Link.LinkData; - propertyGrid1.SelectedObject = Props; - } - } -} +//===-- ClangTidyPropertyGrid.cs - UI for configuring clang-tidy -*- C# -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This class contains a UserControl consisting of a .NET PropertyGrid control +// allowing configuration of checks and check options for ClangTidy. +// +//===----------------------------------------------------------------------===// +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Drawing; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using System.IO; +using Microsoft.VisualStudio.Shell; + +namespace LLVM.ClangTidy +{ + /// + /// A UserControl displaying a PropertyGrid allowing configuration of clang-tidy + /// checks and check options, as well as serialization and deserialization of + /// clang-tidy configuration files. When a configuration file is loaded, the + /// entire chain of configuration files is analyzed based on the file path, + /// and quick access is provided to edit or view any of the files in the + /// configuration chain, allowing easy visualization of where values come from + /// (similar in spirit to the -explain-config option of clang-tidy). + /// + public partial class ClangTidyPropertyGrid : UserControl + { + /// + /// The sequence of .clang-tidy configuration files, starting from the root + /// of the filesystem, down to the selected file. + /// + List> PropertyChain_ = null; + + public ClangTidyPropertyGrid() + { + InitializeComponent(); + InitializeSettings(); + } + + private enum ShouldCancel + { + Yes, + No, + } + + public void SaveSettingsToStorage() + { + PersistUnsavedChanges(false); + } + + private ShouldCancel PersistUnsavedChanges(bool PromptFirst) + { + var UnsavedResults = PropertyChain_.Where(x => x.Key != null && x.Value.GetHasUnsavedChanges()); + if (UnsavedResults.Count() == 0) + return ShouldCancel.No; + + bool ShouldSave = false; + if (PromptFirst) + { + var Response = MessageBox.Show( + "You have unsaved changes! Do you want to save before loading a new file?", + "clang-tidy", + MessageBoxButtons.YesNoCancel); + + ShouldSave = (Response == DialogResult.Yes); + if (Response == DialogResult.Cancel) + return ShouldCancel.Yes; + } + else + ShouldSave = true; + + if (ShouldSave) + { + foreach (var Result in UnsavedResults) + { + ClangTidyConfigParser.SerializeClangTidyFile(Result.Value, Result.Key); + Result.Value.SetHasUnsavedChanges(false); + } + } + return ShouldCancel.No; + } + + public void InitializeSettings() + { + PropertyChain_ = new List>(); + PropertyChain_.Add(new KeyValuePair(null, ClangTidyProperties.RootProperties)); + reloadPropertyChain(); + } + + private void button1_Click(object sender, EventArgs e) + { + ShouldCancel Cancel = PersistUnsavedChanges(true); + if (Cancel == ShouldCancel.Yes) + return; + + using (OpenFileDialog D = new OpenFileDialog()) + { + D.Filter = "Clang Tidy files|.clang-tidy"; + D.CheckPathExists = true; + D.CheckFileExists = true; + + if (D.ShowDialog() == DialogResult.OK) + { + PropertyChain_.Clear(); + PropertyChain_ = ClangTidyConfigParser.ParseConfigurationChain(D.FileName); + textBox1.Text = D.FileName; + reloadPropertyChain(); + } + } + } + + private static readonly string DefaultText = "(Default)"; + private static readonly string BrowseText = "Browse for a file to edit its properties"; + + /// + /// After a new configuration file is chosen, analyzes the directory hierarchy + /// and finds all .clang-tidy files in the path, parses them and updates the + /// PropertyGrid and quick-access LinkLabel control to reflect the new property + /// chain. + /// + private void reloadPropertyChain() + { + StringBuilder LinkBuilder = new StringBuilder(); + LinkBuilder.Append(DefaultText); + LinkBuilder.Append(" > "); + int PrefixLength = LinkBuilder.Length; + + if (PropertyChain_.Count == 1) + LinkBuilder.Append(BrowseText); + else + LinkBuilder.Append(PropertyChain_[PropertyChain_.Count - 1].Key); + + linkLabelPath.Text = LinkBuilder.ToString(); + + // Given a path like D:\Foo\Bar\Baz, construct a LinkLabel where individual + // components of the path are clickable iff they contain a .clang-tidy file. + // Clicking one of the links then updates the PropertyGrid to display the + // selected .clang-tidy file. + ClangTidyProperties LastProps = ClangTidyProperties.RootProperties; + linkLabelPath.Links.Clear(); + linkLabelPath.Links.Add(0, DefaultText.Length, LastProps); + foreach (var Prop in PropertyChain_.Skip(1)) + { + LastProps = Prop.Value; + string ClangTidyFolder = Path.GetFileName(Prop.Key); + int ClangTidyFolderOffset = Prop.Key.Length - ClangTidyFolder.Length; + linkLabelPath.Links.Add(PrefixLength + ClangTidyFolderOffset, ClangTidyFolder.Length, LastProps); + } + propertyGrid1.SelectedObject = LastProps; + } + + private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e) + { + ClangTidyProperties Props = (ClangTidyProperties)propertyGrid1.SelectedObject; + Props.SetHasUnsavedChanges(true); + + // When a CategoryVerb is selected, perform the corresponding action. + PropertyDescriptor Property = e.ChangedItem.PropertyDescriptor; + if (!(e.ChangedItem.Value is CategoryVerb)) + return; + + CategoryVerb Action = (CategoryVerb)e.ChangedItem.Value; + if (Action == CategoryVerb.None) + return; + + var Category = Property.Attributes.OfType().FirstOrDefault(); + if (Category == null) + return; + var SameCategoryProps = Props.GetProperties(new Attribute[] { Category }); + foreach (PropertyDescriptor P in SameCategoryProps) + { + if (P == Property) + continue; + switch (Action) + { + case CategoryVerb.Disable: + P.SetValue(propertyGrid1.SelectedObject, false); + break; + case CategoryVerb.Enable: + P.SetValue(propertyGrid1.SelectedObject, true); + break; + case CategoryVerb.Inherit: + P.ResetValue(propertyGrid1.SelectedObject); + break; + } + } + Property.ResetValue(propertyGrid1.SelectedObject); + propertyGrid1.Invalidate(); + } + + private void linkLabelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e) + { + ClangTidyProperties Props = (ClangTidyProperties)e.Link.LinkData; + propertyGrid1.SelectedObject = Props; + } + } +} diff --git a/clang-tidy-vs/ClangTidy/PkgCmdID.cs b/clang-tidy-vs/ClangTidy/PkgCmdID.cs index 3faf403a..beabbce5 100644 --- a/clang-tidy-vs/ClangTidy/PkgCmdID.cs +++ b/clang-tidy-vs/ClangTidy/PkgCmdID.cs @@ -4,4 +4,4 @@ { public const uint cmdidClangTidy = 0x100; }; -} \ No newline at end of file +} -- cgit v1.2.3 From 07982502f33e317d8d3027d4d4ebd7d17ab72b63 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 19 Jan 2019 06:36:08 +0000 Subject: Convert two more files that were using Windows line endings and remove a stray single '\r' from one file. These are the last line ending issues I can find in the files containing parts of LLVM's file headers. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351634 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/readability/ElseAfterReturnCheck.cpp | 116 ++++++++++++------------ 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tidy/readability/ElseAfterReturnCheck.cpp index be8de252..55669b2a 100644 --- a/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ b/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -1,58 +1,58 @@ -//===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "ElseAfterReturnCheck.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Tooling/FixIt.h" - -using namespace clang::ast_matchers; - -namespace clang { -namespace tidy { -namespace readability { - -void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { - const auto ControlFlowInterruptorMatcher = - stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"), - breakStmt().bind("break"), - expr(ignoringImplicit(cxxThrowExpr().bind("throw"))))); - Finder->addMatcher( - compoundStmt(forEach( - ifStmt(unless(isConstexpr()), - hasThen(stmt( - anyOf(ControlFlowInterruptorMatcher, - compoundStmt(has(ControlFlowInterruptorMatcher))))), - hasElse(stmt().bind("else"))) - .bind("if"))), - this); -} - -void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { - const auto *If = Result.Nodes.getNodeAs("if"); - SourceLocation ElseLoc = If->getElseLoc(); - std::string ControlFlowInterruptor; - for (const auto *BindingName : {"return", "continue", "break", "throw"}) - if (Result.Nodes.getNodeAs(BindingName)) - ControlFlowInterruptor = BindingName; - - DiagnosticBuilder Diag = diag(ElseLoc, "do not use 'else' after '%0'") - << ControlFlowInterruptor; - Diag << tooling::fixit::createRemoval(ElseLoc); - - // FIXME: Removing the braces isn't always safe. Do a more careful analysis. - // FIXME: Change clang-format to correctly un-indent the code. - if (const auto *CS = Result.Nodes.getNodeAs("else")) - Diag << tooling::fixit::createRemoval(CS->getLBracLoc()) - << tooling::fixit::createRemoval(CS->getRBracLoc()); -} - -} // namespace readability -} // namespace tidy -} // namespace clang +//===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ElseAfterReturnCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace readability { + +void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { + const auto ControlFlowInterruptorMatcher = + stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"), + breakStmt().bind("break"), + expr(ignoringImplicit(cxxThrowExpr().bind("throw"))))); + Finder->addMatcher( + compoundStmt(forEach( + ifStmt(unless(isConstexpr()), + hasThen(stmt( + anyOf(ControlFlowInterruptorMatcher, + compoundStmt(has(ControlFlowInterruptorMatcher))))), + hasElse(stmt().bind("else"))) + .bind("if"))), + this); +} + +void ElseAfterReturnCheck::check(const MatchFinder::MatchResult &Result) { + const auto *If = Result.Nodes.getNodeAs("if"); + SourceLocation ElseLoc = If->getElseLoc(); + std::string ControlFlowInterruptor; + for (const auto *BindingName : {"return", "continue", "break", "throw"}) + if (Result.Nodes.getNodeAs(BindingName)) + ControlFlowInterruptor = BindingName; + + DiagnosticBuilder Diag = diag(ElseLoc, "do not use 'else' after '%0'") + << ControlFlowInterruptor; + Diag << tooling::fixit::createRemoval(ElseLoc); + + // FIXME: Removing the braces isn't always safe. Do a more careful analysis. + // FIXME: Change clang-format to correctly un-indent the code. + if (const auto *CS = Result.Nodes.getNodeAs("else")) + Diag << tooling::fixit::createRemoval(CS->getLBracLoc()) + << tooling::fixit::createRemoval(CS->getRBracLoc()); +} + +} // namespace readability +} // namespace tidy +} // namespace clang -- cgit v1.2.3 From b1ace237b8a4c7246d6a3cd7b1d34118074d9af3 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 19 Jan 2019 08:50:56 +0000 Subject: Update the file headers across all of the LLVM projects in the monorepo to reflect the new license. We understand that people may be surprised that we're moving the header entirely to discuss the new license. We checked this carefully with the Foundation's lawyer and we believe this is the correct approach. Essentially, all code in the project is now made available by the LLVM project under our new license, so you will see that the license headers include that license only. Some of our contributors have contributed code under our old license, and accordingly, we have retained a copy of our old license notice in the top-level files in each project and repository. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351636 91177308-0d34-0410-b5e6-96231b3b80d8 --- change-namespace/ChangeNamespace.cpp | 7 +++---- change-namespace/ChangeNamespace.h | 7 +++---- change-namespace/tool/ClangChangeNamespace.cpp | 7 +++---- .../Tooling/ApplyReplacements.h | 7 +++---- .../lib/Tooling/ApplyReplacements.cpp | 7 +++---- .../tool/ClangApplyReplacementsMain.cpp | 7 +++---- clang-doc/BitcodeReader.cpp | 7 +++---- clang-doc/BitcodeReader.h | 7 +++---- clang-doc/BitcodeWriter.cpp | 7 +++---- clang-doc/BitcodeWriter.h | 7 +++---- clang-doc/ClangDoc.cpp | 7 +++---- clang-doc/ClangDoc.h | 7 +++---- clang-doc/Generators.cpp | 7 +++---- clang-doc/Generators.h | 7 +++---- clang-doc/MDGenerator.cpp | 7 +++---- clang-doc/Mapper.cpp | 7 +++---- clang-doc/Mapper.h | 7 +++---- clang-doc/Representation.cpp | 7 +++---- clang-doc/Representation.h | 7 +++---- clang-doc/Serialize.cpp | 7 +++---- clang-doc/Serialize.h | 7 +++---- clang-doc/YAMLGenerator.cpp | 7 +++---- clang-doc/tool/ClangDocMain.cpp | 7 +++---- clang-move/ClangMove.cpp | 7 +++---- clang-move/ClangMove.h | 7 +++---- clang-move/HelperDeclRefGraph.cpp | 7 +++---- clang-move/HelperDeclRefGraph.h | 7 +++---- clang-move/tool/ClangMoveMain.cpp | 7 +++---- clang-query/Query.cpp | 7 +++---- clang-query/Query.h | 7 +++---- clang-query/QueryParser.cpp | 7 +++---- clang-query/QueryParser.h | 7 +++---- clang-query/QuerySession.h | 7 +++---- clang-query/tool/ClangQuery.cpp | 7 +++---- clang-reorder-fields/ReorderFieldsAction.cpp | 7 +++---- clang-reorder-fields/ReorderFieldsAction.h | 7 +++---- clang-reorder-fields/tool/ClangReorderFields.cpp | 7 +++---- clang-tidy-vs/ClangTidy/ClangTidyPackage.cs | 7 +++---- clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs | 7 +++---- clang-tidy/ClangTidy.cpp | 7 +++---- clang-tidy/ClangTidy.h | 7 +++---- clang-tidy/ClangTidyDiagnosticConsumer.cpp | 7 +++---- clang-tidy/ClangTidyDiagnosticConsumer.h | 7 +++---- clang-tidy/ClangTidyForceLinker.h | 7 +++---- clang-tidy/ClangTidyModule.cpp | 7 +++---- clang-tidy/ClangTidyModule.h | 7 +++---- clang-tidy/ClangTidyModuleRegistry.h | 7 +++---- clang-tidy/ClangTidyOptions.cpp | 7 +++---- clang-tidy/ClangTidyOptions.h | 7 +++---- clang-tidy/ClangTidyProfiling.cpp | 7 +++---- clang-tidy/ClangTidyProfiling.h | 7 +++---- clang-tidy/abseil/AbseilMatcher.h | 7 +++---- clang-tidy/abseil/AbseilTidyModule.cpp | 7 +++---- clang-tidy/abseil/DurationComparisonCheck.cpp | 7 +++---- clang-tidy/abseil/DurationComparisonCheck.h | 7 +++---- clang-tidy/abseil/DurationConversionCastCheck.cpp | 7 +++---- clang-tidy/abseil/DurationConversionCastCheck.h | 7 +++---- clang-tidy/abseil/DurationDivisionCheck.cpp | 7 +++---- clang-tidy/abseil/DurationDivisionCheck.h | 7 +++---- clang-tidy/abseil/DurationFactoryFloatCheck.cpp | 7 +++---- clang-tidy/abseil/DurationFactoryFloatCheck.h | 7 +++---- clang-tidy/abseil/DurationFactoryScaleCheck.cpp | 7 +++---- clang-tidy/abseil/DurationFactoryScaleCheck.h | 7 +++---- clang-tidy/abseil/DurationRewriter.cpp | 7 +++---- clang-tidy/abseil/DurationRewriter.h | 7 +++---- clang-tidy/abseil/DurationSubtractionCheck.cpp | 7 +++---- clang-tidy/abseil/DurationSubtractionCheck.h | 7 +++---- clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp | 7 +++---- clang-tidy/abseil/FasterStrsplitDelimiterCheck.h | 7 +++---- clang-tidy/abseil/NoInternalDependenciesCheck.cpp | 7 +++---- clang-tidy/abseil/NoInternalDependenciesCheck.h | 7 +++---- clang-tidy/abseil/NoNamespaceCheck.cpp | 7 +++---- clang-tidy/abseil/NoNamespaceCheck.h | 7 +++---- clang-tidy/abseil/RedundantStrcatCallsCheck.cpp | 7 +++---- clang-tidy/abseil/RedundantStrcatCallsCheck.h | 7 +++---- clang-tidy/abseil/StrCatAppendCheck.cpp | 7 +++---- clang-tidy/abseil/StrCatAppendCheck.h | 7 +++---- clang-tidy/abseil/StringFindStartswithCheck.cpp | 7 +++---- clang-tidy/abseil/StringFindStartswithCheck.h | 7 +++---- .../abseil/UpgradeDurationConversionsCheck.cpp | 7 +++---- clang-tidy/abseil/UpgradeDurationConversionsCheck.h | 7 +++---- clang-tidy/add_new_check.py | 21 +++++++++------------ clang-tidy/android/AndroidTidyModule.cpp | 7 +++---- clang-tidy/android/CloexecAccept4Check.cpp | 7 +++---- clang-tidy/android/CloexecAccept4Check.h | 7 +++---- clang-tidy/android/CloexecAcceptCheck.cpp | 7 +++---- clang-tidy/android/CloexecAcceptCheck.h | 7 +++---- clang-tidy/android/CloexecCheck.cpp | 7 +++---- clang-tidy/android/CloexecCheck.h | 7 +++---- clang-tidy/android/CloexecCreatCheck.cpp | 7 +++---- clang-tidy/android/CloexecCreatCheck.h | 7 +++---- clang-tidy/android/CloexecDupCheck.cpp | 7 +++---- clang-tidy/android/CloexecDupCheck.h | 7 +++---- clang-tidy/android/CloexecEpollCreate1Check.cpp | 7 +++---- clang-tidy/android/CloexecEpollCreate1Check.h | 7 +++---- clang-tidy/android/CloexecEpollCreateCheck.cpp | 7 +++---- clang-tidy/android/CloexecEpollCreateCheck.h | 7 +++---- clang-tidy/android/CloexecFopenCheck.cpp | 6 +++--- clang-tidy/android/CloexecFopenCheck.h | 7 +++---- clang-tidy/android/CloexecInotifyInit1Check.cpp | 7 +++---- clang-tidy/android/CloexecInotifyInit1Check.h | 7 +++---- clang-tidy/android/CloexecInotifyInitCheck.cpp | 7 +++---- clang-tidy/android/CloexecInotifyInitCheck.h | 7 +++---- clang-tidy/android/CloexecMemfdCreateCheck.cpp | 7 +++---- clang-tidy/android/CloexecMemfdCreateCheck.h | 7 +++---- clang-tidy/android/CloexecOpenCheck.cpp | 7 +++---- clang-tidy/android/CloexecOpenCheck.h | 7 +++---- clang-tidy/android/CloexecSocketCheck.cpp | 7 +++---- clang-tidy/android/CloexecSocketCheck.h | 7 +++---- .../android/ComparisonInTempFailureRetryCheck.cpp | 7 +++---- .../android/ComparisonInTempFailureRetryCheck.h | 7 +++---- clang-tidy/boost/BoostTidyModule.cpp | 7 +++---- clang-tidy/boost/UseToStringCheck.cpp | 7 +++---- clang-tidy/boost/UseToStringCheck.h | 7 +++---- clang-tidy/bugprone/ArgumentCommentCheck.cpp | 7 +++---- clang-tidy/bugprone/ArgumentCommentCheck.h | 7 +++---- clang-tidy/bugprone/AssertSideEffectCheck.cpp | 7 +++---- clang-tidy/bugprone/AssertSideEffectCheck.h | 7 +++---- .../bugprone/BoolPointerImplicitConversionCheck.cpp | 7 +++---- .../bugprone/BoolPointerImplicitConversionCheck.h | 7 +++---- clang-tidy/bugprone/BugproneTidyModule.cpp | 7 +++---- clang-tidy/bugprone/CopyConstructorInitCheck.cpp | 7 +++---- clang-tidy/bugprone/CopyConstructorInitCheck.h | 7 +++---- clang-tidy/bugprone/DanglingHandleCheck.cpp | 7 +++---- clang-tidy/bugprone/DanglingHandleCheck.h | 7 +++---- clang-tidy/bugprone/ExceptionEscapeCheck.cpp | 7 +++---- clang-tidy/bugprone/ExceptionEscapeCheck.h | 7 +++---- clang-tidy/bugprone/FoldInitTypeCheck.cpp | 7 +++---- clang-tidy/bugprone/FoldInitTypeCheck.h | 7 +++---- .../bugprone/ForwardDeclarationNamespaceCheck.cpp | 7 +++---- .../bugprone/ForwardDeclarationNamespaceCheck.h | 7 +++---- .../bugprone/ForwardingReferenceOverloadCheck.cpp | 7 +++---- .../bugprone/ForwardingReferenceOverloadCheck.h | 7 +++---- clang-tidy/bugprone/InaccurateEraseCheck.cpp | 7 +++---- clang-tidy/bugprone/InaccurateEraseCheck.h | 7 +++---- clang-tidy/bugprone/IncorrectRoundingsCheck.cpp | 7 +++---- clang-tidy/bugprone/IncorrectRoundingsCheck.h | 7 +++---- clang-tidy/bugprone/IntegerDivisionCheck.cpp | 7 +++---- clang-tidy/bugprone/IntegerDivisionCheck.h | 7 +++---- clang-tidy/bugprone/LambdaFunctionNameCheck.cpp | 7 +++---- clang-tidy/bugprone/LambdaFunctionNameCheck.h | 7 +++---- clang-tidy/bugprone/MacroParenthesesCheck.cpp | 7 +++---- clang-tidy/bugprone/MacroParenthesesCheck.h | 7 +++---- .../bugprone/MacroRepeatedSideEffectsCheck.cpp | 7 +++---- clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h | 7 +++---- .../MisplacedOperatorInStrlenInAllocCheck.cpp | 7 +++---- .../MisplacedOperatorInStrlenInAllocCheck.h | 7 +++---- clang-tidy/bugprone/MisplacedWideningCastCheck.cpp | 7 +++---- clang-tidy/bugprone/MisplacedWideningCastCheck.h | 7 +++---- .../bugprone/MoveForwardingReferenceCheck.cpp | 7 +++---- clang-tidy/bugprone/MoveForwardingReferenceCheck.h | 7 +++---- clang-tidy/bugprone/MultipleStatementMacroCheck.cpp | 7 +++---- clang-tidy/bugprone/MultipleStatementMacroCheck.h | 7 +++---- clang-tidy/bugprone/ParentVirtualCallCheck.cpp | 7 +++---- clang-tidy/bugprone/ParentVirtualCallCheck.h | 7 +++---- clang-tidy/bugprone/SizeofContainerCheck.cpp | 7 +++---- clang-tidy/bugprone/SizeofContainerCheck.h | 7 +++---- clang-tidy/bugprone/SizeofExpressionCheck.cpp | 7 +++---- clang-tidy/bugprone/SizeofExpressionCheck.h | 7 +++---- clang-tidy/bugprone/StringConstructorCheck.cpp | 7 +++---- clang-tidy/bugprone/StringConstructorCheck.h | 7 +++---- .../bugprone/StringIntegerAssignmentCheck.cpp | 7 +++---- clang-tidy/bugprone/StringIntegerAssignmentCheck.h | 7 +++---- .../bugprone/StringLiteralWithEmbeddedNulCheck.cpp | 7 +++---- .../bugprone/StringLiteralWithEmbeddedNulCheck.h | 7 +++---- clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp | 7 +++---- clang-tidy/bugprone/SuspiciousEnumUsageCheck.h | 7 +++---- clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp | 7 +++---- clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h | 7 +++---- clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp | 7 +++---- clang-tidy/bugprone/SuspiciousMissingCommaCheck.h | 7 +++---- clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp | 7 +++---- clang-tidy/bugprone/SuspiciousSemicolonCheck.h | 7 +++---- .../bugprone/SuspiciousStringCompareCheck.cpp | 7 +++---- clang-tidy/bugprone/SuspiciousStringCompareCheck.h | 7 +++---- clang-tidy/bugprone/SwappedArgumentsCheck.cpp | 7 +++---- clang-tidy/bugprone/SwappedArgumentsCheck.h | 7 +++---- clang-tidy/bugprone/TerminatingContinueCheck.cpp | 7 +++---- clang-tidy/bugprone/TerminatingContinueCheck.h | 7 +++---- clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp | 7 +++---- clang-tidy/bugprone/ThrowKeywordMissingCheck.h | 7 +++---- clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp | 7 +++---- clang-tidy/bugprone/TooSmallLoopVariableCheck.h | 7 +++---- .../bugprone/UndefinedMemoryManipulationCheck.cpp | 7 +++---- .../bugprone/UndefinedMemoryManipulationCheck.h | 7 +++---- clang-tidy/bugprone/UndelegatedConstructorCheck.cpp | 7 +++---- clang-tidy/bugprone/UndelegatedConstructorCheck.h | 7 +++---- clang-tidy/bugprone/UnusedRaiiCheck.cpp | 7 +++---- clang-tidy/bugprone/UnusedRaiiCheck.h | 7 +++---- clang-tidy/bugprone/UnusedReturnValueCheck.cpp | 7 +++---- clang-tidy/bugprone/UnusedReturnValueCheck.h | 7 +++---- clang-tidy/bugprone/UseAfterMoveCheck.cpp | 7 +++---- clang-tidy/bugprone/UseAfterMoveCheck.h | 7 +++---- clang-tidy/bugprone/VirtualNearMissCheck.cpp | 7 +++---- clang-tidy/bugprone/VirtualNearMissCheck.h | 7 +++---- clang-tidy/cert/CERTTidyModule.cpp | 7 +++---- clang-tidy/cert/CommandProcessorCheck.cpp | 7 +++---- clang-tidy/cert/CommandProcessorCheck.h | 7 +++---- clang-tidy/cert/DontModifyStdNamespaceCheck.cpp | 7 +++---- clang-tidy/cert/DontModifyStdNamespaceCheck.h | 7 +++---- clang-tidy/cert/FloatLoopCounter.cpp | 7 +++---- clang-tidy/cert/FloatLoopCounter.h | 7 +++---- clang-tidy/cert/LimitedRandomnessCheck.cpp | 7 +++---- clang-tidy/cert/LimitedRandomnessCheck.h | 7 +++---- clang-tidy/cert/PostfixOperatorCheck.cpp | 7 +++---- clang-tidy/cert/PostfixOperatorCheck.h | 7 +++---- .../cert/ProperlySeededRandomGeneratorCheck.cpp | 7 +++---- .../cert/ProperlySeededRandomGeneratorCheck.h | 7 +++---- clang-tidy/cert/SetLongJmpCheck.cpp | 7 +++---- clang-tidy/cert/SetLongJmpCheck.h | 7 +++---- clang-tidy/cert/StaticObjectExceptionCheck.cpp | 7 +++---- clang-tidy/cert/StaticObjectExceptionCheck.h | 7 +++---- clang-tidy/cert/StrToNumCheck.cpp | 7 +++---- clang-tidy/cert/StrToNumCheck.h | 7 +++---- clang-tidy/cert/ThrownExceptionTypeCheck.cpp | 7 +++---- clang-tidy/cert/ThrownExceptionTypeCheck.h | 7 +++---- clang-tidy/cert/VariadicFunctionDefCheck.cpp | 7 +++---- clang-tidy/cert/VariadicFunctionDefCheck.h | 7 +++---- clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp | 7 +++---- clang-tidy/cppcoreguidelines/AvoidGotoCheck.h | 7 +++---- .../CppCoreGuidelinesTidyModule.cpp | 7 +++---- .../cppcoreguidelines/InterfacesGlobalInitCheck.cpp | 7 +++---- .../cppcoreguidelines/InterfacesGlobalInitCheck.h | 7 +++---- clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp | 7 +++---- clang-tidy/cppcoreguidelines/MacroUsageCheck.h | 7 +++---- .../cppcoreguidelines/NarrowingConversionsCheck.cpp | 7 +++---- .../cppcoreguidelines/NarrowingConversionsCheck.h | 7 +++---- clang-tidy/cppcoreguidelines/NoMallocCheck.cpp | 7 +++---- clang-tidy/cppcoreguidelines/NoMallocCheck.h | 7 +++---- clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp | 7 +++---- clang-tidy/cppcoreguidelines/OwningMemoryCheck.h | 7 +++---- .../ProBoundsArrayToPointerDecayCheck.cpp | 7 +++---- .../ProBoundsArrayToPointerDecayCheck.h | 7 +++---- .../ProBoundsConstantArrayIndexCheck.cpp | 7 +++---- .../ProBoundsConstantArrayIndexCheck.h | 7 +++---- .../ProBoundsPointerArithmeticCheck.cpp | 7 +++---- .../ProBoundsPointerArithmeticCheck.h | 7 +++---- .../cppcoreguidelines/ProTypeConstCastCheck.cpp | 7 +++---- .../cppcoreguidelines/ProTypeConstCastCheck.h | 7 +++---- .../cppcoreguidelines/ProTypeCstyleCastCheck.cpp | 7 +++---- .../cppcoreguidelines/ProTypeCstyleCastCheck.h | 7 +++---- .../cppcoreguidelines/ProTypeMemberInitCheck.cpp | 7 +++---- .../cppcoreguidelines/ProTypeMemberInitCheck.h | 7 +++---- .../ProTypeReinterpretCastCheck.cpp | 7 +++---- .../cppcoreguidelines/ProTypeReinterpretCastCheck.h | 7 +++---- .../ProTypeStaticCastDowncastCheck.cpp | 7 +++---- .../ProTypeStaticCastDowncastCheck.h | 7 +++---- .../cppcoreguidelines/ProTypeUnionAccessCheck.cpp | 7 +++---- .../cppcoreguidelines/ProTypeUnionAccessCheck.h | 7 +++---- clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp | 7 +++---- clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h | 7 +++---- clang-tidy/cppcoreguidelines/SlicingCheck.cpp | 7 +++---- clang-tidy/cppcoreguidelines/SlicingCheck.h | 7 +++---- .../SpecialMemberFunctionsCheck.cpp | 7 +++---- .../cppcoreguidelines/SpecialMemberFunctionsCheck.h | 7 +++---- clang-tidy/fuchsia/DefaultArgumentsCheck.cpp | 7 +++---- clang-tidy/fuchsia/DefaultArgumentsCheck.h | 7 +++---- clang-tidy/fuchsia/FuchsiaTidyModule.cpp | 7 +++---- clang-tidy/fuchsia/MultipleInheritanceCheck.cpp | 7 +++---- clang-tidy/fuchsia/MultipleInheritanceCheck.h | 7 +++---- clang-tidy/fuchsia/OverloadedOperatorCheck.cpp | 7 +++---- clang-tidy/fuchsia/OverloadedOperatorCheck.h | 7 +++---- clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp | 7 +++---- clang-tidy/fuchsia/RestrictSystemIncludesCheck.h | 7 +++---- .../fuchsia/StaticallyConstructedObjectsCheck.cpp | 7 +++---- .../fuchsia/StaticallyConstructedObjectsCheck.h | 7 +++---- clang-tidy/fuchsia/TrailingReturnCheck.cpp | 7 +++---- clang-tidy/fuchsia/TrailingReturnCheck.h | 7 +++---- clang-tidy/fuchsia/VirtualInheritanceCheck.cpp | 7 +++---- clang-tidy/fuchsia/VirtualInheritanceCheck.h | 7 +++---- clang-tidy/google/AvoidCStyleCastsCheck.cpp | 7 +++---- clang-tidy/google/AvoidCStyleCastsCheck.h | 7 +++---- .../google/AvoidThrowingObjCExceptionCheck.cpp | 7 +++---- clang-tidy/google/AvoidThrowingObjCExceptionCheck.h | 7 +++---- clang-tidy/google/DefaultArgumentsCheck.cpp | 7 +++---- clang-tidy/google/DefaultArgumentsCheck.h | 7 +++---- clang-tidy/google/ExplicitConstructorCheck.cpp | 7 +++---- clang-tidy/google/ExplicitConstructorCheck.h | 7 +++---- clang-tidy/google/ExplicitMakePairCheck.cpp | 7 +++---- clang-tidy/google/ExplicitMakePairCheck.h | 7 +++---- clang-tidy/google/FunctionNamingCheck.cpp | 7 +++---- clang-tidy/google/FunctionNamingCheck.h | 7 +++---- clang-tidy/google/GlobalNamesInHeadersCheck.cpp | 7 +++---- clang-tidy/google/GlobalNamesInHeadersCheck.h | 7 +++---- .../google/GlobalVariableDeclarationCheck.cpp | 7 +++---- clang-tidy/google/GlobalVariableDeclarationCheck.h | 7 +++---- clang-tidy/google/GoogleTidyModule.cpp | 7 +++---- clang-tidy/google/IntegerTypesCheck.cpp | 7 +++---- clang-tidy/google/IntegerTypesCheck.h | 7 +++---- clang-tidy/google/NonConstReferences.cpp | 7 +++---- clang-tidy/google/NonConstReferences.h | 7 +++---- clang-tidy/google/OverloadedUnaryAndCheck.cpp | 7 +++---- clang-tidy/google/OverloadedUnaryAndCheck.h | 7 +++---- clang-tidy/google/TodoCommentCheck.cpp | 7 +++---- clang-tidy/google/TodoCommentCheck.h | 7 +++---- clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp | 7 +++---- clang-tidy/google/UnnamedNamespaceInHeaderCheck.h | 7 +++---- clang-tidy/google/UsingNamespaceDirectiveCheck.cpp | 7 +++---- clang-tidy/google/UsingNamespaceDirectiveCheck.h | 7 +++---- clang-tidy/hicpp/ExceptionBaseclassCheck.cpp | 7 +++---- clang-tidy/hicpp/ExceptionBaseclassCheck.h | 7 +++---- clang-tidy/hicpp/HICPPTidyModule.cpp | 7 +++---- clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp | 7 +++---- clang-tidy/hicpp/MultiwayPathsCoveredCheck.h | 7 +++---- clang-tidy/hicpp/NoAssemblerCheck.cpp | 7 +++---- clang-tidy/hicpp/NoAssemblerCheck.h | 7 +++---- clang-tidy/hicpp/SignedBitwiseCheck.cpp | 7 +++---- clang-tidy/hicpp/SignedBitwiseCheck.h | 7 +++---- clang-tidy/llvm/HeaderGuardCheck.cpp | 7 +++---- clang-tidy/llvm/HeaderGuardCheck.h | 7 +++---- clang-tidy/llvm/IncludeOrderCheck.cpp | 7 +++---- clang-tidy/llvm/IncludeOrderCheck.h | 7 +++---- clang-tidy/llvm/LLVMTidyModule.cpp | 7 +++---- clang-tidy/llvm/TwineLocalCheck.cpp | 7 +++---- clang-tidy/llvm/TwineLocalCheck.h | 7 +++---- clang-tidy/misc/DefinitionsInHeadersCheck.cpp | 7 +++---- clang-tidy/misc/DefinitionsInHeadersCheck.h | 7 +++---- clang-tidy/misc/MiscTidyModule.cpp | 7 +++---- clang-tidy/misc/MisplacedConstCheck.cpp | 7 +++---- clang-tidy/misc/MisplacedConstCheck.h | 7 +++---- clang-tidy/misc/NewDeleteOverloadsCheck.cpp | 7 +++---- clang-tidy/misc/NewDeleteOverloadsCheck.h | 7 +++---- clang-tidy/misc/NonCopyableObjects.cpp | 7 +++---- clang-tidy/misc/NonCopyableObjects.h | 7 +++---- .../NonPrivateMemberVariablesInClassesCheck.cpp | 7 +++---- .../misc/NonPrivateMemberVariablesInClassesCheck.h | 7 +++---- clang-tidy/misc/RedundantExpressionCheck.cpp | 7 +++---- clang-tidy/misc/RedundantExpressionCheck.h | 7 +++---- clang-tidy/misc/StaticAssertCheck.cpp | 7 +++---- clang-tidy/misc/StaticAssertCheck.h | 7 +++---- .../misc/ThrowByValueCatchByReferenceCheck.cpp | 7 +++---- clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h | 7 +++---- .../misc/UnconventionalAssignOperatorCheck.cpp | 7 +++---- clang-tidy/misc/UnconventionalAssignOperatorCheck.h | 7 +++---- clang-tidy/misc/UniqueptrResetReleaseCheck.cpp | 7 +++---- clang-tidy/misc/UniqueptrResetReleaseCheck.h | 7 +++---- clang-tidy/misc/UnusedAliasDeclsCheck.cpp | 7 +++---- clang-tidy/misc/UnusedAliasDeclsCheck.h | 7 +++---- clang-tidy/misc/UnusedParametersCheck.cpp | 7 +++---- clang-tidy/misc/UnusedParametersCheck.h | 7 +++---- clang-tidy/misc/UnusedUsingDeclsCheck.cpp | 7 +++---- clang-tidy/misc/UnusedUsingDeclsCheck.h | 7 +++---- clang-tidy/modernize/AvoidBindCheck.cpp | 7 +++---- clang-tidy/modernize/AvoidBindCheck.h | 7 +++---- clang-tidy/modernize/AvoidCArraysCheck.cpp | 7 +++---- clang-tidy/modernize/AvoidCArraysCheck.h | 7 +++---- .../modernize/ConcatNestedNamespacesCheck.cpp | 7 +++---- clang-tidy/modernize/ConcatNestedNamespacesCheck.h | 7 +++---- clang-tidy/modernize/DeprecatedHeadersCheck.cpp | 7 +++---- clang-tidy/modernize/DeprecatedHeadersCheck.h | 7 +++---- .../modernize/DeprecatedIosBaseAliasesCheck.cpp | 7 +++---- .../modernize/DeprecatedIosBaseAliasesCheck.h | 7 +++---- clang-tidy/modernize/LoopConvertCheck.cpp | 7 +++---- clang-tidy/modernize/LoopConvertCheck.h | 7 +++---- clang-tidy/modernize/LoopConvertUtils.cpp | 7 +++---- clang-tidy/modernize/LoopConvertUtils.h | 7 +++---- clang-tidy/modernize/MakeSharedCheck.cpp | 7 +++---- clang-tidy/modernize/MakeSharedCheck.h | 7 +++---- clang-tidy/modernize/MakeSmartPtrCheck.cpp | 7 +++---- clang-tidy/modernize/MakeSmartPtrCheck.h | 7 +++---- clang-tidy/modernize/MakeUniqueCheck.cpp | 7 +++---- clang-tidy/modernize/MakeUniqueCheck.h | 7 +++---- clang-tidy/modernize/ModernizeTidyModule.cpp | 7 +++---- clang-tidy/modernize/PassByValueCheck.cpp | 7 +++---- clang-tidy/modernize/PassByValueCheck.h | 7 +++---- clang-tidy/modernize/RawStringLiteralCheck.cpp | 7 +++---- clang-tidy/modernize/RawStringLiteralCheck.h | 7 +++---- clang-tidy/modernize/RedundantVoidArgCheck.cpp | 7 +++---- clang-tidy/modernize/RedundantVoidArgCheck.h | 7 +++---- clang-tidy/modernize/ReplaceAutoPtrCheck.cpp | 7 +++---- clang-tidy/modernize/ReplaceAutoPtrCheck.h | 7 +++---- clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp | 7 +++---- clang-tidy/modernize/ReplaceRandomShuffleCheck.h | 7 +++---- clang-tidy/modernize/ReturnBracedInitListCheck.cpp | 7 +++---- clang-tidy/modernize/ReturnBracedInitListCheck.h | 7 +++---- clang-tidy/modernize/ShrinkToFitCheck.cpp | 7 +++---- clang-tidy/modernize/ShrinkToFitCheck.h | 7 +++---- clang-tidy/modernize/UnaryStaticAssertCheck.cpp | 7 +++---- clang-tidy/modernize/UnaryStaticAssertCheck.h | 7 +++---- clang-tidy/modernize/UseAutoCheck.cpp | 7 +++---- clang-tidy/modernize/UseAutoCheck.h | 7 +++---- clang-tidy/modernize/UseBoolLiteralsCheck.cpp | 7 +++---- clang-tidy/modernize/UseBoolLiteralsCheck.h | 7 +++---- clang-tidy/modernize/UseDefaultMemberInitCheck.cpp | 7 +++---- clang-tidy/modernize/UseDefaultMemberInitCheck.h | 7 +++---- clang-tidy/modernize/UseEmplaceCheck.cpp | 7 +++---- clang-tidy/modernize/UseEmplaceCheck.h | 7 +++---- clang-tidy/modernize/UseEqualsDefaultCheck.cpp | 7 +++---- clang-tidy/modernize/UseEqualsDefaultCheck.h | 7 +++---- clang-tidy/modernize/UseEqualsDeleteCheck.cpp | 7 +++---- clang-tidy/modernize/UseEqualsDeleteCheck.h | 7 +++---- clang-tidy/modernize/UseNodiscardCheck.cpp | 7 +++---- clang-tidy/modernize/UseNodiscardCheck.h | 7 +++---- clang-tidy/modernize/UseNoexceptCheck.cpp | 7 +++---- clang-tidy/modernize/UseNoexceptCheck.h | 7 +++---- clang-tidy/modernize/UseNullptrCheck.cpp | 7 +++---- clang-tidy/modernize/UseNullptrCheck.h | 7 +++---- clang-tidy/modernize/UseOverrideCheck.cpp | 7 +++---- clang-tidy/modernize/UseOverrideCheck.h | 7 +++---- .../modernize/UseTransparentFunctorsCheck.cpp | 7 +++---- clang-tidy/modernize/UseTransparentFunctorsCheck.h | 7 +++---- clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp | 7 +++---- clang-tidy/modernize/UseUncaughtExceptionsCheck.h | 7 +++---- clang-tidy/modernize/UseUsingCheck.cpp | 7 +++---- clang-tidy/modernize/UseUsingCheck.h | 7 +++---- clang-tidy/mpi/BufferDerefCheck.cpp | 7 +++---- clang-tidy/mpi/BufferDerefCheck.h | 7 +++---- clang-tidy/mpi/MPITidyModule.cpp | 7 +++---- clang-tidy/mpi/TypeMismatchCheck.cpp | 7 +++---- clang-tidy/mpi/TypeMismatchCheck.h | 7 +++---- clang-tidy/objc/AvoidNSErrorInitCheck.cpp | 7 +++---- clang-tidy/objc/AvoidNSErrorInitCheck.h | 7 +++---- clang-tidy/objc/AvoidSpinlockCheck.cpp | 7 +++---- clang-tidy/objc/AvoidSpinlockCheck.h | 7 +++---- clang-tidy/objc/ForbiddenSubclassingCheck.cpp | 7 +++---- clang-tidy/objc/ForbiddenSubclassingCheck.h | 7 +++---- clang-tidy/objc/ObjCTidyModule.cpp | 7 +++---- clang-tidy/objc/PropertyDeclarationCheck.cpp | 7 +++---- clang-tidy/objc/PropertyDeclarationCheck.h | 7 +++---- clang-tidy/performance/FasterStringFindCheck.cpp | 7 +++---- clang-tidy/performance/FasterStringFindCheck.h | 7 +++---- clang-tidy/performance/ForRangeCopyCheck.cpp | 7 +++---- clang-tidy/performance/ForRangeCopyCheck.h | 7 +++---- .../performance/ImplicitConversionInLoopCheck.cpp | 7 +++---- .../performance/ImplicitConversionInLoopCheck.h | 7 +++---- .../performance/InefficientAlgorithmCheck.cpp | 7 +++---- clang-tidy/performance/InefficientAlgorithmCheck.h | 7 +++---- .../InefficientStringConcatenationCheck.cpp | 7 +++---- .../InefficientStringConcatenationCheck.h | 7 +++---- .../performance/InefficientVectorOperationCheck.cpp | 7 +++---- .../performance/InefficientVectorOperationCheck.h | 7 +++---- clang-tidy/performance/MoveConstArgCheck.cpp | 7 +++---- clang-tidy/performance/MoveConstArgCheck.h | 7 +++---- clang-tidy/performance/MoveConstructorInitCheck.cpp | 7 +++---- clang-tidy/performance/MoveConstructorInitCheck.h | 7 +++---- .../performance/NoexceptMoveConstructorCheck.cpp | 7 +++---- .../performance/NoexceptMoveConstructorCheck.h | 7 +++---- clang-tidy/performance/PerformanceTidyModule.cpp | 7 +++---- .../performance/TypePromotionInMathFnCheck.cpp | 7 +++---- clang-tidy/performance/TypePromotionInMathFnCheck.h | 7 +++---- .../performance/UnnecessaryCopyInitialization.cpp | 7 +++---- .../performance/UnnecessaryCopyInitialization.h | 7 +++---- .../performance/UnnecessaryValueParamCheck.cpp | 7 +++---- clang-tidy/performance/UnnecessaryValueParamCheck.h | 7 +++---- clang-tidy/plugin/ClangTidyPlugin.cpp | 7 +++---- clang-tidy/portability/PortabilityTidyModule.cpp | 7 +++---- clang-tidy/portability/SIMDIntrinsicsCheck.cpp | 7 +++---- clang-tidy/portability/SIMDIntrinsicsCheck.h | 7 +++---- clang-tidy/readability/AvoidConstParamsInDecls.cpp | 7 +++---- clang-tidy/readability/AvoidConstParamsInDecls.h | 7 +++---- .../readability/BracesAroundStatementsCheck.cpp | 7 +++---- .../readability/BracesAroundStatementsCheck.h | 7 +++---- clang-tidy/readability/ConstReturnTypeCheck.cpp | 7 +++---- clang-tidy/readability/ConstReturnTypeCheck.h | 7 +++---- clang-tidy/readability/ContainerSizeEmptyCheck.cpp | 7 +++---- clang-tidy/readability/ContainerSizeEmptyCheck.h | 7 +++---- clang-tidy/readability/DeleteNullPointerCheck.cpp | 7 +++---- clang-tidy/readability/DeleteNullPointerCheck.h | 7 +++---- clang-tidy/readability/DeletedDefaultCheck.cpp | 7 +++---- clang-tidy/readability/DeletedDefaultCheck.h | 7 +++---- clang-tidy/readability/ElseAfterReturnCheck.cpp | 7 +++---- clang-tidy/readability/ElseAfterReturnCheck.h | 7 +++---- clang-tidy/readability/FunctionSizeCheck.cpp | 7 +++---- clang-tidy/readability/FunctionSizeCheck.h | 7 +++---- clang-tidy/readability/IdentifierNamingCheck.cpp | 7 +++---- clang-tidy/readability/IdentifierNamingCheck.h | 7 +++---- .../readability/ImplicitBoolConversionCheck.cpp | 7 +++---- .../readability/ImplicitBoolConversionCheck.h | 7 +++---- .../InconsistentDeclarationParameterNameCheck.cpp | 7 +++---- .../InconsistentDeclarationParameterNameCheck.h | 7 +++---- clang-tidy/readability/IsolateDeclarationCheck.cpp | 7 +++---- clang-tidy/readability/IsolateDeclarationCheck.h | 7 +++---- clang-tidy/readability/MagicNumbersCheck.cpp | 7 +++---- clang-tidy/readability/MagicNumbersCheck.h | 7 +++---- .../readability/MisleadingIndentationCheck.cpp | 7 +++---- clang-tidy/readability/MisleadingIndentationCheck.h | 7 +++---- clang-tidy/readability/MisplacedArrayIndexCheck.cpp | 7 +++---- clang-tidy/readability/MisplacedArrayIndexCheck.h | 7 +++---- clang-tidy/readability/NamedParameterCheck.cpp | 7 +++---- clang-tidy/readability/NamedParameterCheck.h | 7 +++---- clang-tidy/readability/NamespaceCommentCheck.cpp | 7 +++---- clang-tidy/readability/NamespaceCommentCheck.h | 7 +++---- clang-tidy/readability/NonConstParameterCheck.cpp | 7 +++---- clang-tidy/readability/NonConstParameterCheck.h | 7 +++---- clang-tidy/readability/ReadabilityTidyModule.cpp | 7 +++---- .../readability/RedundantControlFlowCheck.cpp | 7 +++---- clang-tidy/readability/RedundantControlFlowCheck.h | 7 +++---- .../readability/RedundantDeclarationCheck.cpp | 7 +++---- clang-tidy/readability/RedundantDeclarationCheck.h | 7 +++---- .../RedundantFunctionPtrDereferenceCheck.cpp | 7 +++---- .../RedundantFunctionPtrDereferenceCheck.h | 7 +++---- clang-tidy/readability/RedundantMemberInitCheck.cpp | 7 +++---- clang-tidy/readability/RedundantMemberInitCheck.h | 7 +++---- .../readability/RedundantPreprocessorCheck.cpp | 7 +++---- clang-tidy/readability/RedundantPreprocessorCheck.h | 7 +++---- .../readability/RedundantSmartptrGetCheck.cpp | 7 +++---- clang-tidy/readability/RedundantSmartptrGetCheck.h | 7 +++---- clang-tidy/readability/RedundantStringCStrCheck.cpp | 7 +++---- clang-tidy/readability/RedundantStringCStrCheck.h | 7 +++---- clang-tidy/readability/RedundantStringInitCheck.cpp | 7 +++---- clang-tidy/readability/RedundantStringInitCheck.h | 7 +++---- clang-tidy/readability/SimplifyBooleanExprCheck.cpp | 7 +++---- clang-tidy/readability/SimplifyBooleanExprCheck.h | 7 +++---- .../readability/SimplifySubscriptExprCheck.cpp | 7 +++---- clang-tidy/readability/SimplifySubscriptExprCheck.h | 7 +++---- .../StaticAccessedThroughInstanceCheck.cpp | 7 +++---- .../StaticAccessedThroughInstanceCheck.h | 7 +++---- .../StaticDefinitionInAnonymousNamespaceCheck.cpp | 7 +++---- .../StaticDefinitionInAnonymousNamespaceCheck.h | 7 +++---- clang-tidy/readability/StringCompareCheck.cpp | 7 +++---- clang-tidy/readability/StringCompareCheck.h | 7 +++---- .../readability/UniqueptrDeleteReleaseCheck.cpp | 7 +++---- .../readability/UniqueptrDeleteReleaseCheck.h | 7 +++---- .../readability/UppercaseLiteralSuffixCheck.cpp | 7 +++---- .../readability/UppercaseLiteralSuffixCheck.h | 7 +++---- clang-tidy/rename_check.py | 7 +++---- clang-tidy/tool/ClangTidyMain.cpp | 7 +++---- clang-tidy/tool/clang-tidy-diff.py | 7 +++---- clang-tidy/tool/run-clang-tidy.py | 7 +++---- clang-tidy/utils/ASTUtils.cpp | 7 +++---- clang-tidy/utils/ASTUtils.h | 7 +++---- clang-tidy/utils/DeclRefExprUtils.cpp | 7 +++---- clang-tidy/utils/DeclRefExprUtils.h | 7 +++---- clang-tidy/utils/ExprSequence.cpp | 7 +++---- clang-tidy/utils/ExprSequence.h | 7 +++---- clang-tidy/utils/FixItHintUtils.cpp | 7 +++---- clang-tidy/utils/FixItHintUtils.h | 7 +++---- clang-tidy/utils/HeaderFileExtensionsUtils.cpp | 7 +++---- clang-tidy/utils/HeaderFileExtensionsUtils.h | 7 +++---- clang-tidy/utils/HeaderGuard.cpp | 7 +++---- clang-tidy/utils/HeaderGuard.h | 7 +++---- clang-tidy/utils/IncludeInserter.cpp | 7 +++---- clang-tidy/utils/IncludeInserter.h | 7 +++---- clang-tidy/utils/IncludeSorter.cpp | 7 +++---- clang-tidy/utils/IncludeSorter.h | 7 +++---- clang-tidy/utils/LexerUtils.cpp | 7 +++---- clang-tidy/utils/LexerUtils.h | 7 +++---- clang-tidy/utils/Matchers.h | 7 +++---- clang-tidy/utils/NamespaceAliaser.cpp | 7 +++---- clang-tidy/utils/NamespaceAliaser.h | 7 +++---- clang-tidy/utils/OptionsUtils.cpp | 7 +++---- clang-tidy/utils/OptionsUtils.h | 7 +++---- clang-tidy/utils/TypeTraits.cpp | 7 +++---- clang-tidy/utils/TypeTraits.h | 7 +++---- clang-tidy/utils/UsingInserter.cpp | 7 +++---- clang-tidy/utils/UsingInserter.h | 7 +++---- clang-tidy/zircon/TemporaryObjectsCheck.cpp | 7 +++---- clang-tidy/zircon/TemporaryObjectsCheck.h | 7 +++---- clang-tidy/zircon/ZirconTidyModule.cpp | 7 +++---- clangd/AST.cpp | 7 +++---- clangd/AST.h | 7 +++---- clangd/Cancellation.cpp | 7 +++---- clangd/Cancellation.h | 7 +++---- clangd/ClangdLSPServer.cpp | 7 +++---- clangd/ClangdLSPServer.h | 7 +++---- clangd/ClangdServer.cpp | 7 +++---- clangd/ClangdServer.h | 7 +++---- clangd/ClangdUnit.cpp | 7 +++---- clangd/ClangdUnit.h | 7 +++---- clangd/CodeComplete.cpp | 7 +++---- clangd/CodeComplete.h | 7 +++---- clangd/CodeCompletionStrings.cpp | 7 +++---- clangd/CodeCompletionStrings.h | 7 +++---- clangd/Compiler.cpp | 7 +++---- clangd/Compiler.h | 7 +++---- clangd/Context.cpp | 7 +++---- clangd/Context.h | 7 +++---- clangd/Diagnostics.cpp | 7 +++---- clangd/Diagnostics.h | 7 +++---- clangd/DraftStore.cpp | 7 +++---- clangd/DraftStore.h | 7 +++---- clangd/ExpectedTypes.h | 7 +++---- clangd/FS.cpp | 7 +++---- clangd/FS.h | 7 +++---- clangd/FSProvider.cpp | 7 +++---- clangd/FSProvider.h | 7 +++---- clangd/FileDistance.cpp | 7 +++---- clangd/FileDistance.h | 7 +++---- clangd/FindSymbols.cpp | 7 +++---- clangd/FindSymbols.h | 7 +++---- clangd/Function.h | 7 +++---- clangd/FuzzyMatch.cpp | 7 +++---- clangd/FuzzyMatch.h | 7 +++---- clangd/GlobalCompilationDatabase.cpp | 7 +++---- clangd/GlobalCompilationDatabase.h | 7 +++---- clangd/Headers.cpp | 7 +++---- clangd/Headers.h | 7 +++---- clangd/JSONTransport.cpp | 7 +++---- clangd/Logger.cpp | 7 +++---- clangd/Logger.h | 7 +++---- clangd/Path.h | 7 +++---- clangd/Protocol.cpp | 7 +++---- clangd/Protocol.h | 7 +++---- clangd/Quality.cpp | 7 +++---- clangd/Quality.h | 7 +++---- clangd/RIFF.cpp | 7 +++---- clangd/RIFF.h | 7 +++---- clangd/SourceCode.cpp | 7 +++---- clangd/SourceCode.h | 7 +++---- clangd/TUScheduler.cpp | 7 +++---- clangd/TUScheduler.h | 7 +++---- clangd/Threading.h | 7 +++---- clangd/Trace.cpp | 7 +++---- clangd/Trace.h | 7 +++---- clangd/Transport.h | 7 +++---- clangd/URI.cpp | 7 +++---- clangd/URI.h | 7 +++---- clangd/XRefs.cpp | 7 +++---- clangd/XRefs.h | 7 +++---- clangd/benchmarks/IndexBenchmark.cpp | 7 +++---- clangd/fuzzer/ClangdFuzzer.cpp | 7 +++---- clangd/index/Background.cpp | 7 +++---- clangd/index/Background.h | 7 +++---- clangd/index/BackgroundIndexStorage.cpp | 7 +++---- clangd/index/CanonicalIncludes.cpp | 7 +++---- clangd/index/CanonicalIncludes.h | 7 +++---- clangd/index/FileIndex.cpp | 7 +++---- clangd/index/FileIndex.h | 7 +++---- clangd/index/Index.cpp | 7 +++---- clangd/index/Index.h | 7 +++---- clangd/index/IndexAction.h | 7 +++---- clangd/index/MemIndex.cpp | 7 +++---- clangd/index/MemIndex.h | 7 +++---- clangd/index/Merge.cpp | 7 +++---- clangd/index/Merge.h | 7 +++---- clangd/index/Serialization.cpp | 7 +++---- clangd/index/Serialization.h | 7 +++---- clangd/index/SymbolCollector.cpp | 7 +++---- clangd/index/SymbolCollector.h | 7 +++---- clangd/index/SymbolID.cpp | 7 +++---- clangd/index/SymbolID.h | 7 +++---- clangd/index/YAMLSerialization.cpp | 7 +++---- clangd/index/dex/Dex.cpp | 7 +++---- clangd/index/dex/Dex.h | 7 +++---- clangd/index/dex/Iterator.cpp | 7 +++---- clangd/index/dex/Iterator.h | 7 +++---- clangd/index/dex/PostingList.cpp | 7 +++---- clangd/index/dex/PostingList.h | 7 +++---- clangd/index/dex/Token.h | 7 +++---- clangd/index/dex/Trigram.cpp | 7 +++---- clangd/index/dex/Trigram.h | 7 +++---- clangd/index/dex/dexp/Dexp.cpp | 7 +++---- clangd/indexer/IndexerMain.cpp | 7 +++---- clangd/tool/ClangdMain.cpp | 7 +++---- clangd/xpc/Conversion.cpp | 7 +++---- clangd/xpc/Conversion.h | 7 +++---- clangd/xpc/XPCTransport.cpp | 7 +++---- include-fixer/FuzzySymbolIndex.cpp | 7 +++---- include-fixer/FuzzySymbolIndex.h | 7 +++---- include-fixer/InMemorySymbolIndex.cpp | 7 +++---- include-fixer/InMemorySymbolIndex.h | 7 +++---- include-fixer/IncludeFixer.cpp | 7 +++---- include-fixer/IncludeFixer.h | 7 +++---- include-fixer/IncludeFixerContext.cpp | 7 +++---- include-fixer/IncludeFixerContext.h | 7 +++---- include-fixer/SymbolIndex.h | 7 +++---- include-fixer/SymbolIndexManager.cpp | 7 +++---- include-fixer/SymbolIndexManager.h | 7 +++---- include-fixer/YamlSymbolIndex.cpp | 7 +++---- include-fixer/YamlSymbolIndex.h | 7 +++---- include-fixer/find-all-symbols/FindAllMacros.cpp | 7 +++---- include-fixer/find-all-symbols/FindAllMacros.h | 7 +++---- include-fixer/find-all-symbols/FindAllSymbols.cpp | 7 +++---- include-fixer/find-all-symbols/FindAllSymbols.h | 7 +++---- .../find-all-symbols/FindAllSymbolsAction.cpp | 7 +++---- .../find-all-symbols/FindAllSymbolsAction.h | 7 +++---- .../find-all-symbols/HeaderMapCollector.cpp | 7 +++---- include-fixer/find-all-symbols/HeaderMapCollector.h | 7 +++---- include-fixer/find-all-symbols/PathConfig.cpp | 7 +++---- include-fixer/find-all-symbols/PathConfig.h | 7 +++---- .../find-all-symbols/PragmaCommentHandler.cpp | 7 +++---- .../find-all-symbols/PragmaCommentHandler.h | 7 +++---- .../find-all-symbols/STLPostfixHeaderMap.cpp | 7 +++---- .../find-all-symbols/STLPostfixHeaderMap.h | 7 +++---- include-fixer/find-all-symbols/SymbolInfo.cpp | 7 +++---- include-fixer/find-all-symbols/SymbolInfo.h | 7 +++---- include-fixer/find-all-symbols/SymbolReporter.h | 7 +++---- .../find-all-symbols/tool/FindAllSymbolsMain.cpp | 7 +++---- .../find-all-symbols/tool/run-find-all-symbols.py | 7 +++---- include-fixer/plugin/IncludeFixerPlugin.cpp | 7 +++---- include-fixer/tool/ClangIncludeFixer.cpp | 7 +++---- modularize/CoverageChecker.cpp | 7 +++---- modularize/CoverageChecker.h | 7 +++---- modularize/Modularize.cpp | 7 +++---- modularize/Modularize.h | 7 +++---- modularize/ModularizeUtilities.cpp | 7 +++---- modularize/ModularizeUtilities.h | 7 +++---- modularize/ModuleAssistant.cpp | 7 +++---- modularize/PreprocessorTracker.cpp | 7 +++---- modularize/PreprocessorTracker.h | 7 +++---- pp-trace/PPCallbacksTracker.cpp | 7 +++---- pp-trace/PPCallbacksTracker.h | 7 +++---- pp-trace/PPTrace.cpp | 7 +++---- test/clang-tidy/check_clang_tidy.py | 7 +++---- tool-template/ToolTemplate.cpp | 7 +++---- unittests/change-namespace/ChangeNamespaceTests.cpp | 7 +++---- .../ApplyReplacementsTest.cpp | 7 +++---- unittests/clang-doc/BitcodeTest.cpp | 7 +++---- unittests/clang-doc/ClangDocTest.cpp | 7 +++---- unittests/clang-doc/ClangDocTest.h | 7 +++---- unittests/clang-doc/MDGeneratorTest.cpp | 7 +++---- unittests/clang-doc/MergeTest.cpp | 7 +++---- unittests/clang-doc/SerializeTest.cpp | 7 +++---- unittests/clang-doc/YAMLGeneratorTest.cpp | 7 +++---- unittests/clang-move/ClangMoveTests.cpp | 7 +++---- unittests/clang-query/QueryEngineTest.cpp | 7 +++---- unittests/clang-query/QueryParserTest.cpp | 7 +++---- unittests/clang-tidy/ClangTidyTest.h | 7 +++---- unittests/clang-tidy/IncludeInserterTest.cpp | 7 +++---- unittests/clang-tidy/NamespaceAliaserTest.cpp | 7 +++---- unittests/clang-tidy/ObjCModuleTest.cpp | 7 +++---- .../clang-tidy/OverlappingReplacementsTest.cpp | 7 +++---- unittests/clang-tidy/UsingInserterTest.cpp | 7 +++---- unittests/clangd/Annotations.cpp | 7 +++---- unittests/clangd/Annotations.h | 7 +++---- unittests/clangd/ClangdTests.cpp | 7 +++---- unittests/clangd/ClangdUnitTests.cpp | 7 +++---- unittests/clangd/CodeCompleteTests.cpp | 7 +++---- unittests/clangd/CodeCompletionStringsTests.cpp | 7 +++---- unittests/clangd/ContextTests.cpp | 7 +++---- unittests/clangd/DexTests.cpp | 7 +++---- unittests/clangd/DraftStoreTests.cpp | 7 +++---- unittests/clangd/ExpectedTypeTest.cpp | 7 +++---- unittests/clangd/FSTests.cpp | 7 +++---- unittests/clangd/FileDistanceTests.cpp | 7 +++---- unittests/clangd/FileIndexTests.cpp | 7 +++---- unittests/clangd/FindSymbolsTests.cpp | 7 +++---- unittests/clangd/FunctionTests.cpp | 7 +++---- unittests/clangd/FuzzyMatchTests.cpp | 7 +++---- unittests/clangd/GlobalCompilationDatabaseTests.cpp | 7 +++---- unittests/clangd/HeadersTests.cpp | 7 +++---- unittests/clangd/IndexActionTests.cpp | 7 +++---- unittests/clangd/IndexTests.cpp | 7 +++---- unittests/clangd/JSONTransportTests.cpp | 7 +++---- unittests/clangd/Matchers.h | 7 +++---- unittests/clangd/QualityTests.cpp | 7 +++---- unittests/clangd/RIFFTests.cpp | 7 +++---- unittests/clangd/SerializationTests.cpp | 7 +++---- unittests/clangd/SourceCodeTests.cpp | 7 +++---- unittests/clangd/SymbolCollectorTests.cpp | 7 +++---- unittests/clangd/SymbolInfoTests.cpp | 7 +++---- unittests/clangd/SyncAPI.cpp | 7 +++---- unittests/clangd/SyncAPI.h | 7 +++---- unittests/clangd/TUSchedulerTests.cpp | 7 +++---- unittests/clangd/TestFS.cpp | 7 +++---- unittests/clangd/TestFS.h | 7 +++---- unittests/clangd/TestIndex.cpp | 7 +++---- unittests/clangd/TestIndex.h | 7 +++---- unittests/clangd/TestTU.cpp | 7 +++---- unittests/clangd/TestTU.h | 7 +++---- unittests/clangd/ThreadingTests.cpp | 7 +++---- unittests/clangd/TraceTests.cpp | 7 +++---- unittests/clangd/URITests.cpp | 7 +++---- unittests/clangd/XRefsTests.cpp | 7 +++---- unittests/clangd/xpc/ConversionTests.cpp | 7 +++---- unittests/include-fixer/FuzzySymbolIndexTests.cpp | 7 +++---- unittests/include-fixer/IncludeFixerTest.cpp | 7 +++---- .../find-all-symbols/FindAllSymbolsTests.cpp | 7 +++---- unittests/include/common/VirtualFileHelper.h | 7 +++---- 759 files changed, 2283 insertions(+), 3043 deletions(-) diff --git a/change-namespace/ChangeNamespace.cpp b/change-namespace/ChangeNamespace.cpp index 7a710318..eb732639 100644 --- a/change-namespace/ChangeNamespace.cpp +++ b/change-namespace/ChangeNamespace.cpp @@ -1,9 +1,8 @@ //===-- ChangeNamespace.cpp - Change namespace implementation -------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "ChangeNamespace.h" diff --git a/change-namespace/ChangeNamespace.h b/change-namespace/ChangeNamespace.h index cfe3cbc7..293d5ce8 100644 --- a/change-namespace/ChangeNamespace.h +++ b/change-namespace/ChangeNamespace.h @@ -1,9 +1,8 @@ //===-- ChangeNamespace.h -- Change namespace ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/change-namespace/tool/ClangChangeNamespace.cpp b/change-namespace/tool/ClangChangeNamespace.cpp index 180e8c38..0d515029 100644 --- a/change-namespace/tool/ClangChangeNamespace.cpp +++ b/change-namespace/tool/ClangChangeNamespace.cpp @@ -1,9 +1,8 @@ //===-- ClangIncludeFixer.cpp - Standalone change namespace ---------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 tool can be used to change the surrounding namespaces of class/function diff --git a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h index da9ae0c9..34f5c75d 100644 --- a/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h +++ b/clang-apply-replacements/include/clang-apply-replacements/Tooling/ApplyReplacements.h @@ -1,9 +1,8 @@ //===-- ApplyReplacements.h - Deduplicate and apply replacements -- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp index b4799225..7a656a66 100644 --- a/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp +++ b/clang-apply-replacements/lib/Tooling/ApplyReplacements.cpp @@ -1,9 +1,8 @@ //===-- ApplyReplacements.cpp - Apply and deduplicate replacements --------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp index 8977b131..ffd1e65c 100644 --- a/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp +++ b/clang-apply-replacements/tool/ClangApplyReplacementsMain.cpp @@ -1,9 +1,8 @@ //===-- ClangApplyReplacementsMain.cpp - Main file for the tool -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-doc/BitcodeReader.cpp b/clang-doc/BitcodeReader.cpp index 20cdc508..04e5d7d2 100644 --- a/clang-doc/BitcodeReader.cpp +++ b/clang-doc/BitcodeReader.cpp @@ -1,9 +1,8 @@ //===-- BitcodeReader.cpp - ClangDoc Bitcode Reader ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-doc/BitcodeReader.h b/clang-doc/BitcodeReader.h index ec3f6b0f..2642a2c7 100644 --- a/clang-doc/BitcodeReader.h +++ b/clang-doc/BitcodeReader.h @@ -1,9 +1,8 @@ //===-- BitcodeReader.h - ClangDoc Bitcode Reader --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/BitcodeWriter.cpp b/clang-doc/BitcodeWriter.cpp index bc990fa7..232c3f13 100644 --- a/clang-doc/BitcodeWriter.cpp +++ b/clang-doc/BitcodeWriter.cpp @@ -1,9 +1,8 @@ //===-- BitcodeWriter.cpp - ClangDoc Bitcode Writer ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-doc/BitcodeWriter.h b/clang-doc/BitcodeWriter.h index 12a31ea5..9deba830 100644 --- a/clang-doc/BitcodeWriter.h +++ b/clang-doc/BitcodeWriter.h @@ -1,9 +1,8 @@ //===-- BitcodeWriter.h - ClangDoc Bitcode Writer --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/ClangDoc.cpp b/clang-doc/ClangDoc.cpp index a11c5840..ec32f012 100644 --- a/clang-doc/ClangDoc.cpp +++ b/clang-doc/ClangDoc.cpp @@ -1,9 +1,8 @@ //===-- ClangDoc.cpp - ClangDoc ---------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/ClangDoc.h b/clang-doc/ClangDoc.h index 59e9a92b..f3820d2c 100644 --- a/clang-doc/ClangDoc.h +++ b/clang-doc/ClangDoc.h @@ -1,9 +1,8 @@ //===-- ClangDoc.h - ClangDoc -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/Generators.cpp b/clang-doc/Generators.cpp index 5a0d0c5c..e57a2617 100644 --- a/clang-doc/Generators.cpp +++ b/clang-doc/Generators.cpp @@ -1,9 +1,8 @@ //===---- Generator.cpp - Generator Registry ---------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-doc/Generators.h b/clang-doc/Generators.h index 90a81e82..25e5e0b4 100644 --- a/clang-doc/Generators.h +++ b/clang-doc/Generators.h @@ -1,9 +1,8 @@ //===-- Generators.h - ClangDoc Generator ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Generator classes for converting declaration information into documentation diff --git a/clang-doc/MDGenerator.cpp b/clang-doc/MDGenerator.cpp index 5deb510e..d7784200 100644 --- a/clang-doc/MDGenerator.cpp +++ b/clang-doc/MDGenerator.cpp @@ -1,9 +1,8 @@ //===-- MDGenerator.cpp - Markdown Generator --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-doc/Mapper.cpp b/clang-doc/Mapper.cpp index 0b00bd1f..654096d8 100644 --- a/clang-doc/Mapper.cpp +++ b/clang-doc/Mapper.cpp @@ -1,9 +1,8 @@ //===-- Mapper.cpp - ClangDoc Mapper ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-doc/Mapper.h b/clang-doc/Mapper.h index a0b1ac22..fe2a8e2b 100644 --- a/clang-doc/Mapper.h +++ b/clang-doc/Mapper.h @@ -1,9 +1,8 @@ //===-- Mapper.h - ClangDoc Mapper ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/Representation.cpp b/clang-doc/Representation.cpp index eacf11a8..398d1025 100644 --- a/clang-doc/Representation.cpp +++ b/clang-doc/Representation.cpp @@ -1,9 +1,8 @@ ///===-- Representation.cpp - ClangDoc Representation -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/Representation.h b/clang-doc/Representation.h index 48f8f3d8..ad12ec4d 100644 --- a/clang-doc/Representation.h +++ b/clang-doc/Representation.h @@ -1,9 +1,8 @@ ///===-- Representation.h - ClangDoc Representation -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/Serialize.cpp b/clang-doc/Serialize.cpp index eb72c19c..897fed56 100644 --- a/clang-doc/Serialize.cpp +++ b/clang-doc/Serialize.cpp @@ -1,9 +1,8 @@ //===-- Serializer.cpp - ClangDoc Serializer --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-doc/Serialize.h b/clang-doc/Serialize.h index d89dac80..3a2c93df 100644 --- a/clang-doc/Serialize.h +++ b/clang-doc/Serialize.h @@ -1,9 +1,8 @@ //===-- Serializer.h - ClangDoc Serializer ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-doc/YAMLGenerator.cpp b/clang-doc/YAMLGenerator.cpp index e0939019..ceb42153 100644 --- a/clang-doc/YAMLGenerator.cpp +++ b/clang-doc/YAMLGenerator.cpp @@ -1,9 +1,8 @@ //===-- ClangDocYAML.cpp - ClangDoc YAML -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Implementation of the YAML generator, converting decl info into YAML output. diff --git a/clang-doc/tool/ClangDocMain.cpp b/clang-doc/tool/ClangDocMain.cpp index 71ca2d91..2b44869d 100644 --- a/clang-doc/tool/ClangDocMain.cpp +++ b/clang-doc/tool/ClangDocMain.cpp @@ -1,9 +1,8 @@ //===-- ClangDocMain.cpp - ClangDoc -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-move/ClangMove.cpp b/clang-move/ClangMove.cpp index 3ab3d4eb..9fd3e960 100644 --- a/clang-move/ClangMove.cpp +++ b/clang-move/ClangMove.cpp @@ -1,9 +1,8 @@ //===-- ClangMove.cpp - Implement ClangMove functationalities ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-move/ClangMove.h b/clang-move/ClangMove.h index 94172181..8dfccf7a 100644 --- a/clang-move/ClangMove.h +++ b/clang-move/ClangMove.h @@ -1,9 +1,8 @@ //===-- ClangMove.h - Clang move -----------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-move/HelperDeclRefGraph.cpp b/clang-move/HelperDeclRefGraph.cpp index 28200e0b..93a0f879 100644 --- a/clang-move/HelperDeclRefGraph.cpp +++ b/clang-move/HelperDeclRefGraph.cpp @@ -1,9 +1,8 @@ //===-- UsedHelperDeclFinder.cpp - AST-based call graph for helper decls --===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-move/HelperDeclRefGraph.h b/clang-move/HelperDeclRefGraph.h index 11b3c9c1..a9cc22df 100644 --- a/clang-move/HelperDeclRefGraph.h +++ b/clang-move/HelperDeclRefGraph.h @@ -1,9 +1,8 @@ //===-- UsedHelperDeclFinder.h - AST-based call graph for helper decls ----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-move/tool/ClangMoveMain.cpp b/clang-move/tool/ClangMoveMain.cpp index f50e973a..a73dd6e3 100644 --- a/clang-move/tool/ClangMoveMain.cpp +++ b/clang-move/tool/ClangMoveMain.cpp @@ -1,9 +1,8 @@ //===-- ClangMoveMain.cpp - move defintion to new file ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-query/Query.cpp b/clang-query/Query.cpp index ffa3b456..eea0e776 100644 --- a/clang-query/Query.cpp +++ b/clang-query/Query.cpp @@ -1,9 +1,8 @@ //===---- Query.cpp - clang-query query -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-query/Query.h b/clang-query/Query.h index b4ff1d0f..56af4869 100644 --- a/clang-query/Query.h +++ b/clang-query/Query.h @@ -1,9 +1,8 @@ //===--- Query.h - clang-query ----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-query/QueryParser.cpp b/clang-query/QueryParser.cpp index 54eb5a03..4da2f5da 100644 --- a/clang-query/QueryParser.cpp +++ b/clang-query/QueryParser.cpp @@ -1,9 +1,8 @@ //===---- QueryParser.cpp - clang-query command parser --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-query/QueryParser.h b/clang-query/QueryParser.h index 56eb5a9a..f5d4393d 100644 --- a/clang-query/QueryParser.h +++ b/clang-query/QueryParser.h @@ -1,9 +1,8 @@ //===--- QueryParser.h - clang-query ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-query/QuerySession.h b/clang-query/QuerySession.h index 70a4ede8..0f3bc1aa 100644 --- a/clang-query/QuerySession.h +++ b/clang-query/QuerySession.h @@ -1,9 +1,8 @@ //===--- QuerySession.h - clang-query ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-query/tool/ClangQuery.cpp b/clang-query/tool/ClangQuery.cpp index 59c49baa..80e1c602 100644 --- a/clang-query/tool/ClangQuery.cpp +++ b/clang-query/tool/ClangQuery.cpp @@ -1,9 +1,8 @@ //===---- ClangQuery.cpp - clang-query tool -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-reorder-fields/ReorderFieldsAction.cpp b/clang-reorder-fields/ReorderFieldsAction.cpp index 7cb8abe5..c11234a0 100644 --- a/clang-reorder-fields/ReorderFieldsAction.cpp +++ b/clang-reorder-fields/ReorderFieldsAction.cpp @@ -1,9 +1,8 @@ //===-- tools/extra/clang-reorder-fields/ReorderFieldsAction.cpp -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-reorder-fields/ReorderFieldsAction.h b/clang-reorder-fields/ReorderFieldsAction.h index f08c632a..cc450ed7 100644 --- a/clang-reorder-fields/ReorderFieldsAction.h +++ b/clang-reorder-fields/ReorderFieldsAction.h @@ -1,9 +1,8 @@ //===-- tools/extra/clang-reorder-fields/ReorderFieldsAction.h -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-reorder-fields/tool/ClangReorderFields.cpp b/clang-reorder-fields/tool/ClangReorderFields.cpp index 077e55e8..bae3f4c6 100644 --- a/clang-reorder-fields/tool/ClangReorderFields.cpp +++ b/clang-reorder-fields/tool/ClangReorderFields.cpp @@ -1,9 +1,8 @@ //===-- tools/extra/clang-reorder-fields/tool/ClangReorderFields.cpp -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs index c5164e72..fb8a1511 100644 --- a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs +++ b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs @@ -1,9 +1,8 @@ //===-- ClangTidyPackages.cs - VSPackage for clang-tidy ----------*- C# -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs index 9b49e669..c9945b27 100644 --- a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs +++ b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs @@ -1,9 +1,8 @@ //===-- ClangTidyPropertyGrid.cs - UI for configuring clang-tidy -*- C# -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-tidy/ClangTidy.cpp b/clang-tidy/ClangTidy.cpp index 0feda605..974c7d59 100644 --- a/clang-tidy/ClangTidy.cpp +++ b/clang-tidy/ClangTidy.cpp @@ -1,9 +1,8 @@ //===--- tools/extra/clang-tidy/ClangTidy.cpp - Clang tidy tool -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-tidy/ClangTidy.h b/clang-tidy/ClangTidy.h index dc11200d..29857320 100644 --- a/clang-tidy/ClangTidy.h +++ b/clang-tidy/ClangTidy.h @@ -1,9 +1,8 @@ //===--- ClangTidy.h - clang-tidy -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 7e04d71f..637addf2 100644 --- a/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -1,9 +1,8 @@ //===--- tools/extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp ----------=== // // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tidy/ClangTidyDiagnosticConsumer.h index a868203f..63dbd526 100644 --- a/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -1,9 +1,8 @@ //===--- ClangTidyDiagnosticConsumer.h - clang-tidy -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyForceLinker.h b/clang-tidy/ClangTidyForceLinker.h index 2e8e8a83..966aeb28 100644 --- a/clang-tidy/ClangTidyForceLinker.h +++ b/clang-tidy/ClangTidyForceLinker.h @@ -1,9 +1,8 @@ //===- ClangTidyForceLinker.h - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyModule.cpp b/clang-tidy/ClangTidyModule.cpp index 9dbf0161..7d6de87a 100644 --- a/clang-tidy/ClangTidyModule.cpp +++ b/clang-tidy/ClangTidyModule.cpp @@ -1,9 +1,8 @@ //===--- tools/extra/clang-tidy/ClangTidyModule.cpp - Clang tidy tool -----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-tidy/ClangTidyModule.h b/clang-tidy/ClangTidyModule.h index 47216368..378f1093 100644 --- a/clang-tidy/ClangTidyModule.h +++ b/clang-tidy/ClangTidyModule.h @@ -1,9 +1,8 @@ //===--- ClangTidyModule.h - clang-tidy -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyModuleRegistry.h b/clang-tidy/ClangTidyModuleRegistry.h index dc44d14e..891671a7 100644 --- a/clang-tidy/ClangTidyModuleRegistry.h +++ b/clang-tidy/ClangTidyModuleRegistry.h @@ -1,9 +1,8 @@ //===--- ClangTidyModuleRegistry.h - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyOptions.cpp b/clang-tidy/ClangTidyOptions.cpp index c40e97c5..e6a60ee6 100644 --- a/clang-tidy/ClangTidyOptions.cpp +++ b/clang-tidy/ClangTidyOptions.cpp @@ -1,9 +1,8 @@ //===--- ClangTidyOptions.cpp - clang-tidy ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyOptions.h b/clang-tidy/ClangTidyOptions.h index 1a753544..87c7cf59 100644 --- a/clang-tidy/ClangTidyOptions.h +++ b/clang-tidy/ClangTidyOptions.h @@ -1,9 +1,8 @@ //===--- ClangTidyOptions.h - clang-tidy ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyProfiling.cpp b/clang-tidy/ClangTidyProfiling.cpp index fc0a9697..63eed227 100644 --- a/clang-tidy/ClangTidyProfiling.cpp +++ b/clang-tidy/ClangTidyProfiling.cpp @@ -1,9 +1,8 @@ //===--- ClangTidyProfiling.cpp - clang-tidy --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/ClangTidyProfiling.h b/clang-tidy/ClangTidyProfiling.h index 9d86b8e9..a266e388 100644 --- a/clang-tidy/ClangTidyProfiling.h +++ b/clang-tidy/ClangTidyProfiling.h @@ -1,9 +1,8 @@ //===--- ClangTidyProfiling.h - clang-tidy ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/AbseilMatcher.h b/clang-tidy/abseil/AbseilMatcher.h index 116aa953..3f7529d1 100644 --- a/clang-tidy/abseil/AbseilMatcher.h +++ b/clang-tidy/abseil/AbseilMatcher.h @@ -1,9 +1,8 @@ //===- AbseilMatcher.h - clang-tidy ---------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp index da702c71..6c92166b 100644 --- a/clang-tidy/abseil/AbseilTidyModule.cpp +++ b/clang-tidy/abseil/AbseilTidyModule.cpp @@ -1,9 +1,8 @@ //===------- AbseilTidyModule.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tidy/abseil/DurationComparisonCheck.cpp index adf0f6d8..b724622d 100644 --- a/clang-tidy/abseil/DurationComparisonCheck.cpp +++ b/clang-tidy/abseil/DurationComparisonCheck.cpp @@ -1,9 +1,8 @@ //===--- DurationComparisonCheck.cpp - clang-tidy -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationComparisonCheck.h b/clang-tidy/abseil/DurationComparisonCheck.h index 2d82f8ee..4c7085fc 100644 --- a/clang-tidy/abseil/DurationComparisonCheck.h +++ b/clang-tidy/abseil/DurationComparisonCheck.h @@ -1,9 +1,8 @@ //===--- DurationComparisonCheck.h - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tidy/abseil/DurationConversionCastCheck.cpp index 830d61ef..827ab56a 100644 --- a/clang-tidy/abseil/DurationConversionCastCheck.cpp +++ b/clang-tidy/abseil/DurationConversionCastCheck.cpp @@ -1,9 +1,8 @@ //===--- DurationConversionCastCheck.cpp - clang-tidy ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationConversionCastCheck.h b/clang-tidy/abseil/DurationConversionCastCheck.h index bc5cbd86..bc1d6203 100644 --- a/clang-tidy/abseil/DurationConversionCastCheck.h +++ b/clang-tidy/abseil/DurationConversionCastCheck.h @@ -1,9 +1,8 @@ //===--- DurationConversionCastCheck.h - clang-tidy -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationDivisionCheck.cpp b/clang-tidy/abseil/DurationDivisionCheck.cpp index 5edc1587..82c405f9 100644 --- a/clang-tidy/abseil/DurationDivisionCheck.cpp +++ b/clang-tidy/abseil/DurationDivisionCheck.cpp @@ -1,9 +1,8 @@ //===--- DurationDivisionCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationDivisionCheck.h b/clang-tidy/abseil/DurationDivisionCheck.h index 932d0296..ac81e059 100644 --- a/clang-tidy/abseil/DurationDivisionCheck.h +++ b/clang-tidy/abseil/DurationDivisionCheck.h @@ -1,9 +1,8 @@ //===--- DurationDivisionCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationFactoryFloatCheck.cpp b/clang-tidy/abseil/DurationFactoryFloatCheck.cpp index 06765144..d46265d1 100644 --- a/clang-tidy/abseil/DurationFactoryFloatCheck.cpp +++ b/clang-tidy/abseil/DurationFactoryFloatCheck.cpp @@ -1,9 +1,8 @@ //===--- DurationFactoryFloatCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationFactoryFloatCheck.h b/clang-tidy/abseil/DurationFactoryFloatCheck.h index 8d215e44..cc773153 100644 --- a/clang-tidy/abseil/DurationFactoryFloatCheck.h +++ b/clang-tidy/abseil/DurationFactoryFloatCheck.h @@ -1,9 +1,8 @@ //===--- DurationFactoryFloatCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationFactoryScaleCheck.cpp b/clang-tidy/abseil/DurationFactoryScaleCheck.cpp index e56ed819..0884a1db 100644 --- a/clang-tidy/abseil/DurationFactoryScaleCheck.cpp +++ b/clang-tidy/abseil/DurationFactoryScaleCheck.cpp @@ -1,9 +1,8 @@ //===--- DurationFactoryScaleCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationFactoryScaleCheck.h b/clang-tidy/abseil/DurationFactoryScaleCheck.h index 606724e6..3b79b91d 100644 --- a/clang-tidy/abseil/DurationFactoryScaleCheck.h +++ b/clang-tidy/abseil/DurationFactoryScaleCheck.h @@ -1,9 +1,8 @@ //===--- DurationFactoryScaleCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index ca44ab5b..eac7df66 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -1,9 +1,8 @@ //===--- DurationRewriter.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index e4204131..ac8fe19f 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -1,9 +1,8 @@ //===--- DurationRewriter.h - clang-tidy ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationSubtractionCheck.cpp b/clang-tidy/abseil/DurationSubtractionCheck.cpp index db9d407b..17f610ae 100644 --- a/clang-tidy/abseil/DurationSubtractionCheck.cpp +++ b/clang-tidy/abseil/DurationSubtractionCheck.cpp @@ -1,9 +1,8 @@ //===--- DurationSubtractionCheck.cpp - clang-tidy ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/DurationSubtractionCheck.h b/clang-tidy/abseil/DurationSubtractionCheck.h index 227dcdb5..89deb375 100644 --- a/clang-tidy/abseil/DurationSubtractionCheck.h +++ b/clang-tidy/abseil/DurationSubtractionCheck.h @@ -1,9 +1,8 @@ //===--- DurationSubtractionCheck.h - clang-tidy ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp index 35d99ac1..57f822ec 100644 --- a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp +++ b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.cpp @@ -1,9 +1,8 @@ //===--- FasterStrsplitDelimiterCheck.cpp - clang-tidy---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h index 17e231cb..7dc77e7d 100644 --- a/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h +++ b/clang-tidy/abseil/FasterStrsplitDelimiterCheck.h @@ -1,9 +1,8 @@ //===--- FasterStrsplitDelimiterCheck.h - clang-tidy-------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/NoInternalDependenciesCheck.cpp b/clang-tidy/abseil/NoInternalDependenciesCheck.cpp index cb77e95f..dcb8585d 100644 --- a/clang-tidy/abseil/NoInternalDependenciesCheck.cpp +++ b/clang-tidy/abseil/NoInternalDependenciesCheck.cpp @@ -1,9 +1,8 @@ //===--- NoInternalDependenciesCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/NoInternalDependenciesCheck.h b/clang-tidy/abseil/NoInternalDependenciesCheck.h index 7e659df5..301c89d6 100644 --- a/clang-tidy/abseil/NoInternalDependenciesCheck.h +++ b/clang-tidy/abseil/NoInternalDependenciesCheck.h @@ -1,9 +1,8 @@ //===--- NoInternalDependenciesCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/NoNamespaceCheck.cpp b/clang-tidy/abseil/NoNamespaceCheck.cpp index fc9e6980..5db50de0 100644 --- a/clang-tidy/abseil/NoNamespaceCheck.cpp +++ b/clang-tidy/abseil/NoNamespaceCheck.cpp @@ -1,9 +1,8 @@ //===--- NoNamespaceCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/NoNamespaceCheck.h b/clang-tidy/abseil/NoNamespaceCheck.h index 00686d16..058d1101 100644 --- a/clang-tidy/abseil/NoNamespaceCheck.h +++ b/clang-tidy/abseil/NoNamespaceCheck.h @@ -1,9 +1,8 @@ //===--- NoNamespaceCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp b/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp index 19806685..f8e6e7a5 100644 --- a/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp +++ b/clang-tidy/abseil/RedundantStrcatCallsCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantStrcatCallsCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/RedundantStrcatCallsCheck.h b/clang-tidy/abseil/RedundantStrcatCallsCheck.h index ede03547..71f3ff64 100644 --- a/clang-tidy/abseil/RedundantStrcatCallsCheck.h +++ b/clang-tidy/abseil/RedundantStrcatCallsCheck.h @@ -1,9 +1,8 @@ //===--- RedundantStrcatCallsCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/StrCatAppendCheck.cpp b/clang-tidy/abseil/StrCatAppendCheck.cpp index 49072371..a249b121 100644 --- a/clang-tidy/abseil/StrCatAppendCheck.cpp +++ b/clang-tidy/abseil/StrCatAppendCheck.cpp @@ -1,9 +1,8 @@ //===--- StrCatAppendCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/StrCatAppendCheck.h b/clang-tidy/abseil/StrCatAppendCheck.h index eaa750da..72203fdd 100644 --- a/clang-tidy/abseil/StrCatAppendCheck.h +++ b/clang-tidy/abseil/StrCatAppendCheck.h @@ -1,9 +1,8 @@ //===--- StrCatAppendCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/StringFindStartswithCheck.cpp b/clang-tidy/abseil/StringFindStartswithCheck.cpp index 2701c24b..9009647a 100644 --- a/clang-tidy/abseil/StringFindStartswithCheck.cpp +++ b/clang-tidy/abseil/StringFindStartswithCheck.cpp @@ -1,9 +1,8 @@ //===--- StringFindStartswithCheck.cc - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/StringFindStartswithCheck.h b/clang-tidy/abseil/StringFindStartswithCheck.h index 1c04e805..68bae50a 100644 --- a/clang-tidy/abseil/StringFindStartswithCheck.h +++ b/clang-tidy/abseil/StringFindStartswithCheck.h @@ -1,9 +1,8 @@ //===--- StringFindStartswithCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp b/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp index 1925f48c..9c709d25 100644 --- a/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp +++ b/clang-tidy/abseil/UpgradeDurationConversionsCheck.cpp @@ -1,9 +1,8 @@ //===--- UpgradeDurationConversionsCheck.cpp - clang-tidy -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/abseil/UpgradeDurationConversionsCheck.h b/clang-tidy/abseil/UpgradeDurationConversionsCheck.h index 63712e2c..b1096a67 100644 --- a/clang-tidy/abseil/UpgradeDurationConversionsCheck.h +++ b/clang-tidy/abseil/UpgradeDurationConversionsCheck.h @@ -1,9 +1,8 @@ //===--- UpgradeDurationConversionsCheck.h - clang-tidy ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/add_new_check.py b/clang-tidy/add_new_check.py index f4c518d0..898392b1 100755 --- a/clang-tidy/add_new_check.py +++ b/clang-tidy/add_new_check.py @@ -2,10 +2,9 @@ # #===- add_new_check.py - clang-tidy check generator ----------*- python -*--===# # -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# 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 # #===------------------------------------------------------------------------===# @@ -61,10 +60,9 @@ def write_header(module_path, module, check_name, check_name_camel): f.write('*- C++ -*-===//') f.write(""" // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// @@ -112,10 +110,9 @@ def write_implementation(module_path, module, check_name_camel): f.write('-===//') f.write(""" // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/AndroidTidyModule.cpp b/clang-tidy/android/AndroidTidyModule.cpp index bbb4b715..2baa3fba 100644 --- a/clang-tidy/android/AndroidTidyModule.cpp +++ b/clang-tidy/android/AndroidTidyModule.cpp @@ -1,9 +1,8 @@ //===--- AndroidTidyModule.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecAccept4Check.cpp b/clang-tidy/android/CloexecAccept4Check.cpp index 3d172ef3..fe1f341f 100644 --- a/clang-tidy/android/CloexecAccept4Check.cpp +++ b/clang-tidy/android/CloexecAccept4Check.cpp @@ -1,9 +1,8 @@ //===--- CloexecAccept4Check.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecAccept4Check.h b/clang-tidy/android/CloexecAccept4Check.h index 0cf32152..21196de3 100644 --- a/clang-tidy/android/CloexecAccept4Check.h +++ b/clang-tidy/android/CloexecAccept4Check.h @@ -1,9 +1,8 @@ //===--- CloexecAccept4Check.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecAcceptCheck.cpp b/clang-tidy/android/CloexecAcceptCheck.cpp index f583bd0c..b26ad75d 100644 --- a/clang-tidy/android/CloexecAcceptCheck.cpp +++ b/clang-tidy/android/CloexecAcceptCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecAcceptCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecAcceptCheck.h b/clang-tidy/android/CloexecAcceptCheck.h index cba1c098..304ac51f 100644 --- a/clang-tidy/android/CloexecAcceptCheck.h +++ b/clang-tidy/android/CloexecAcceptCheck.h @@ -1,9 +1,8 @@ //===--- CloexecAcceptCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecCheck.cpp b/clang-tidy/android/CloexecCheck.cpp index 4cc0f614..148839a6 100644 --- a/clang-tidy/android/CloexecCheck.cpp +++ b/clang-tidy/android/CloexecCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecCheck.cpp - clang-tidy-------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecCheck.h b/clang-tidy/android/CloexecCheck.h index 1c58a313..da6c6692 100644 --- a/clang-tidy/android/CloexecCheck.h +++ b/clang-tidy/android/CloexecCheck.h @@ -1,9 +1,8 @@ //===--- CloexecCheck.h - clang-tidy-----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-tidy/android/CloexecCreatCheck.cpp b/clang-tidy/android/CloexecCreatCheck.cpp index 83ca49a3..f096884d 100644 --- a/clang-tidy/android/CloexecCreatCheck.cpp +++ b/clang-tidy/android/CloexecCreatCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecCreatCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecCreatCheck.h b/clang-tidy/android/CloexecCreatCheck.h index 335990cc..cb60e258 100644 --- a/clang-tidy/android/CloexecCreatCheck.h +++ b/clang-tidy/android/CloexecCreatCheck.h @@ -1,9 +1,8 @@ //===--- CloexecCreatCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecDupCheck.cpp b/clang-tidy/android/CloexecDupCheck.cpp index ec4ff0ac..9a676d14 100644 --- a/clang-tidy/android/CloexecDupCheck.cpp +++ b/clang-tidy/android/CloexecDupCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecDupCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecDupCheck.h b/clang-tidy/android/CloexecDupCheck.h index c040b380..e87c0abb 100644 --- a/clang-tidy/android/CloexecDupCheck.h +++ b/clang-tidy/android/CloexecDupCheck.h @@ -1,9 +1,8 @@ //===--- CloexecDupCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecEpollCreate1Check.cpp b/clang-tidy/android/CloexecEpollCreate1Check.cpp index d94b4a06..8fb175ee 100644 --- a/clang-tidy/android/CloexecEpollCreate1Check.cpp +++ b/clang-tidy/android/CloexecEpollCreate1Check.cpp @@ -1,9 +1,8 @@ //===--- CloexecEpollCreate1Check.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecEpollCreate1Check.h b/clang-tidy/android/CloexecEpollCreate1Check.h index 9890d5f0..cac2581b 100644 --- a/clang-tidy/android/CloexecEpollCreate1Check.h +++ b/clang-tidy/android/CloexecEpollCreate1Check.h @@ -1,9 +1,8 @@ //===--- CloexecEpollCreate1Check.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecEpollCreateCheck.cpp b/clang-tidy/android/CloexecEpollCreateCheck.cpp index 7165d24f..f1d7edfd 100644 --- a/clang-tidy/android/CloexecEpollCreateCheck.cpp +++ b/clang-tidy/android/CloexecEpollCreateCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecEpollCreateCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecEpollCreateCheck.h b/clang-tidy/android/CloexecEpollCreateCheck.h index 21d2b2ab..8db80c84 100644 --- a/clang-tidy/android/CloexecEpollCreateCheck.h +++ b/clang-tidy/android/CloexecEpollCreateCheck.h @@ -1,9 +1,8 @@ //===--- CloexecEpollCreateCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecFopenCheck.cpp b/clang-tidy/android/CloexecFopenCheck.cpp index 33058d6e..dc9908b6 100644 --- a/clang-tidy/android/CloexecFopenCheck.cpp +++ b/clang-tidy/android/CloexecFopenCheck.cpp @@ -1,9 +1,9 @@ //===--- CloexecFopenCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure +// 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 is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// #include "CloexecFopenCheck.h" diff --git a/clang-tidy/android/CloexecFopenCheck.h b/clang-tidy/android/CloexecFopenCheck.h index 1c82b8bd..0b617ffd 100644 --- a/clang-tidy/android/CloexecFopenCheck.h +++ b/clang-tidy/android/CloexecFopenCheck.h @@ -1,9 +1,8 @@ //===--- CloexecFopenCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source // -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecInotifyInit1Check.cpp b/clang-tidy/android/CloexecInotifyInit1Check.cpp index ca0aeb87..f0a0b982 100644 --- a/clang-tidy/android/CloexecInotifyInit1Check.cpp +++ b/clang-tidy/android/CloexecInotifyInit1Check.cpp @@ -1,9 +1,8 @@ //===--- CloexecInotifyInit1Check.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecInotifyInit1Check.h b/clang-tidy/android/CloexecInotifyInit1Check.h index deb04f2a..d4a392d3 100644 --- a/clang-tidy/android/CloexecInotifyInit1Check.h +++ b/clang-tidy/android/CloexecInotifyInit1Check.h @@ -1,9 +1,8 @@ //===--- CloexecInotifyInit1Check.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecInotifyInitCheck.cpp b/clang-tidy/android/CloexecInotifyInitCheck.cpp index 0d5a56da..e11cbb8b 100644 --- a/clang-tidy/android/CloexecInotifyInitCheck.cpp +++ b/clang-tidy/android/CloexecInotifyInitCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecInotifyInitCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecInotifyInitCheck.h b/clang-tidy/android/CloexecInotifyInitCheck.h index ceeecbea..3b6e0574 100644 --- a/clang-tidy/android/CloexecInotifyInitCheck.h +++ b/clang-tidy/android/CloexecInotifyInitCheck.h @@ -1,9 +1,8 @@ //===--- CloexecInotifyInitCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecMemfdCreateCheck.cpp b/clang-tidy/android/CloexecMemfdCreateCheck.cpp index 4820e2bd..6fa606b8 100644 --- a/clang-tidy/android/CloexecMemfdCreateCheck.cpp +++ b/clang-tidy/android/CloexecMemfdCreateCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecMemfdCreateCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecMemfdCreateCheck.h b/clang-tidy/android/CloexecMemfdCreateCheck.h index 0fe96f46..f429ee5f 100644 --- a/clang-tidy/android/CloexecMemfdCreateCheck.h +++ b/clang-tidy/android/CloexecMemfdCreateCheck.h @@ -1,9 +1,8 @@ //===--- CloexecMemfdCreateCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecOpenCheck.cpp b/clang-tidy/android/CloexecOpenCheck.cpp index a4d3bc68..d0617a33 100644 --- a/clang-tidy/android/CloexecOpenCheck.cpp +++ b/clang-tidy/android/CloexecOpenCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecOpenCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecOpenCheck.h b/clang-tidy/android/CloexecOpenCheck.h index c221087f..eb3319c7 100644 --- a/clang-tidy/android/CloexecOpenCheck.h +++ b/clang-tidy/android/CloexecOpenCheck.h @@ -1,9 +1,8 @@ //===--- CloexecOpenCheck.h - clang-tidy-----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecSocketCheck.cpp b/clang-tidy/android/CloexecSocketCheck.cpp index b223918f..dd0f6244 100644 --- a/clang-tidy/android/CloexecSocketCheck.cpp +++ b/clang-tidy/android/CloexecSocketCheck.cpp @@ -1,9 +1,8 @@ //===--- CloexecSocketCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/CloexecSocketCheck.h b/clang-tidy/android/CloexecSocketCheck.h index c1fd01f1..acbfceab 100644 --- a/clang-tidy/android/CloexecSocketCheck.h +++ b/clang-tidy/android/CloexecSocketCheck.h @@ -1,9 +1,8 @@ //===--- CloexecSocketCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp b/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp index a98eb8ca..f43d9496 100644 --- a/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp +++ b/clang-tidy/android/ComparisonInTempFailureRetryCheck.cpp @@ -1,9 +1,8 @@ //===--- ComparisonInTempFailureRetryCheck.cpp - clang-tidy----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/android/ComparisonInTempFailureRetryCheck.h b/clang-tidy/android/ComparisonInTempFailureRetryCheck.h index de812323..53e8b8e7 100644 --- a/clang-tidy/android/ComparisonInTempFailureRetryCheck.h +++ b/clang-tidy/android/ComparisonInTempFailureRetryCheck.h @@ -1,9 +1,8 @@ //===--- ComparisonInTempFailureRetryCheck.h - clang-tidy--------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/boost/BoostTidyModule.cpp b/clang-tidy/boost/BoostTidyModule.cpp index 28eb1d65..4ab22ade 100644 --- a/clang-tidy/boost/BoostTidyModule.cpp +++ b/clang-tidy/boost/BoostTidyModule.cpp @@ -1,9 +1,8 @@ //===------- BoostTidyModule.cpp - clang-tidy -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/boost/UseToStringCheck.cpp b/clang-tidy/boost/UseToStringCheck.cpp index 259f3dfd..29bedcf5 100644 --- a/clang-tidy/boost/UseToStringCheck.cpp +++ b/clang-tidy/boost/UseToStringCheck.cpp @@ -1,9 +1,8 @@ //===--- UseToStringCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/boost/UseToStringCheck.h b/clang-tidy/boost/UseToStringCheck.h index 76e7823b..e1666153 100644 --- a/clang-tidy/boost/UseToStringCheck.h +++ b/clang-tidy/boost/UseToStringCheck.h @@ -1,9 +1,8 @@ //===--- UseToStringCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.cpp b/clang-tidy/bugprone/ArgumentCommentCheck.cpp index 62f30f79..f939aa0e 100644 --- a/clang-tidy/bugprone/ArgumentCommentCheck.cpp +++ b/clang-tidy/bugprone/ArgumentCommentCheck.cpp @@ -1,9 +1,8 @@ //===--- ArgumentCommentCheck.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.h b/clang-tidy/bugprone/ArgumentCommentCheck.h index 2f5a751b..2eee74d6 100644 --- a/clang-tidy/bugprone/ArgumentCommentCheck.h +++ b/clang-tidy/bugprone/ArgumentCommentCheck.h @@ -1,9 +1,8 @@ //===--- ArgumentCommentCheck.h - clang-tidy --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/AssertSideEffectCheck.cpp b/clang-tidy/bugprone/AssertSideEffectCheck.cpp index c747980b..a28ef113 100644 --- a/clang-tidy/bugprone/AssertSideEffectCheck.cpp +++ b/clang-tidy/bugprone/AssertSideEffectCheck.cpp @@ -1,9 +1,8 @@ //===--- AssertSideEffectCheck.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/AssertSideEffectCheck.h b/clang-tidy/bugprone/AssertSideEffectCheck.h index 0f386c9d..ffc8000d 100644 --- a/clang-tidy/bugprone/AssertSideEffectCheck.h +++ b/clang-tidy/bugprone/AssertSideEffectCheck.h @@ -1,9 +1,8 @@ //===--- AssertSideEffectCheck.h - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp index 675322dd..b7f5b0d6 100644 --- a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp +++ b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.cpp @@ -1,9 +1,8 @@ //===--- BoolPointerImplicitConversionCheck.cpp - clang-tidy --------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h index b3416a92..7ddaab2f 100644 --- a/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h +++ b/clang-tidy/bugprone/BoolPointerImplicitConversionCheck.h @@ -1,9 +1,8 @@ //===--- BoolPointerImplicitConversionCheck.h - clang-tidy ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/BugproneTidyModule.cpp b/clang-tidy/bugprone/BugproneTidyModule.cpp index beb58f5d..01bc0e54 100644 --- a/clang-tidy/bugprone/BugproneTidyModule.cpp +++ b/clang-tidy/bugprone/BugproneTidyModule.cpp @@ -1,9 +1,8 @@ //===--- BugproneTidyModule.cpp - clang-tidy ------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/CopyConstructorInitCheck.cpp b/clang-tidy/bugprone/CopyConstructorInitCheck.cpp index f0488254..5ae7999c 100644 --- a/clang-tidy/bugprone/CopyConstructorInitCheck.cpp +++ b/clang-tidy/bugprone/CopyConstructorInitCheck.cpp @@ -1,9 +1,8 @@ //===--- CopyConstructorInitCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/CopyConstructorInitCheck.h b/clang-tidy/bugprone/CopyConstructorInitCheck.h index 4d13da4a..16e4678a 100644 --- a/clang-tidy/bugprone/CopyConstructorInitCheck.h +++ b/clang-tidy/bugprone/CopyConstructorInitCheck.h @@ -1,9 +1,8 @@ //===--- CopyConstructorInitCheck.h - clang-tidy--------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tidy/bugprone/DanglingHandleCheck.cpp index 81b799ed..9cefc20f 100644 --- a/clang-tidy/bugprone/DanglingHandleCheck.cpp +++ b/clang-tidy/bugprone/DanglingHandleCheck.cpp @@ -1,9 +1,8 @@ //===--- DanglingHandleCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/DanglingHandleCheck.h b/clang-tidy/bugprone/DanglingHandleCheck.h index add8d427..801240fa 100644 --- a/clang-tidy/bugprone/DanglingHandleCheck.h +++ b/clang-tidy/bugprone/DanglingHandleCheck.h @@ -1,9 +1,8 @@ //===--- DanglingHandleCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index 3c8a6c5d..bd57da99 100644 --- a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -1,9 +1,8 @@ //===--- ExceptionEscapeCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.h b/clang-tidy/bugprone/ExceptionEscapeCheck.h index d690022a..5f4ddf2b 100644 --- a/clang-tidy/bugprone/ExceptionEscapeCheck.h +++ b/clang-tidy/bugprone/ExceptionEscapeCheck.h @@ -1,9 +1,8 @@ //===--- ExceptionEscapeCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/FoldInitTypeCheck.cpp b/clang-tidy/bugprone/FoldInitTypeCheck.cpp index 6d7fd285..e77c981c 100644 --- a/clang-tidy/bugprone/FoldInitTypeCheck.cpp +++ b/clang-tidy/bugprone/FoldInitTypeCheck.cpp @@ -1,9 +1,8 @@ //===--- FoldInitTypeCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/FoldInitTypeCheck.h b/clang-tidy/bugprone/FoldInitTypeCheck.h index e6170de0..dce71ac0 100644 --- a/clang-tidy/bugprone/FoldInitTypeCheck.h +++ b/clang-tidy/bugprone/FoldInitTypeCheck.h @@ -1,9 +1,8 @@ //===--- FoldInitTypeCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp index 9ea5b553..a03f8609 100644 --- a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp +++ b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp @@ -1,9 +1,8 @@ //===--- ForwardDeclarationNamespaceCheck.cpp - clang-tidy ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h index c3d30186..dfecddc9 100644 --- a/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h +++ b/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.h @@ -1,9 +1,8 @@ //===--- ForwardDeclarationNamespaceCheck.h - clang-tidy --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp index 17bdc76c..57055ff2 100644 --- a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp +++ b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp @@ -1,9 +1,8 @@ //===--- ForwardingReferenceOverloadCheck.cpp - clang-tidy-----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h index 4b00ab29..7f3a4222 100644 --- a/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h +++ b/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.h @@ -1,9 +1,8 @@ //===--- ForwardingReferenceOverloadCheck.h - clang-tidy---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/InaccurateEraseCheck.cpp b/clang-tidy/bugprone/InaccurateEraseCheck.cpp index c1e65b58..b236e992 100644 --- a/clang-tidy/bugprone/InaccurateEraseCheck.cpp +++ b/clang-tidy/bugprone/InaccurateEraseCheck.cpp @@ -1,9 +1,8 @@ //===--- InaccurateEraseCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/InaccurateEraseCheck.h b/clang-tidy/bugprone/InaccurateEraseCheck.h index d6b37290..7a8b3aa0 100644 --- a/clang-tidy/bugprone/InaccurateEraseCheck.h +++ b/clang-tidy/bugprone/InaccurateEraseCheck.h @@ -1,9 +1,8 @@ //===--- InaccurateEraseCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp b/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp index 549799f1..bc58e8e6 100644 --- a/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp +++ b/clang-tidy/bugprone/IncorrectRoundingsCheck.cpp @@ -1,9 +1,8 @@ //===--- IncorrectRoundingsCheck.cpp - clang-tidy ------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/IncorrectRoundingsCheck.h b/clang-tidy/bugprone/IncorrectRoundingsCheck.h index b1886fd8..1c84316d 100644 --- a/clang-tidy/bugprone/IncorrectRoundingsCheck.h +++ b/clang-tidy/bugprone/IncorrectRoundingsCheck.h @@ -1,9 +1,8 @@ //===--- IncorrectRoundingsCheck.h - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/IntegerDivisionCheck.cpp b/clang-tidy/bugprone/IntegerDivisionCheck.cpp index 094d9913..670efe2a 100644 --- a/clang-tidy/bugprone/IntegerDivisionCheck.cpp +++ b/clang-tidy/bugprone/IntegerDivisionCheck.cpp @@ -1,9 +1,8 @@ //===--- IntegerDivisionCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/IntegerDivisionCheck.h b/clang-tidy/bugprone/IntegerDivisionCheck.h index 307e4938..20776688 100644 --- a/clang-tidy/bugprone/IntegerDivisionCheck.h +++ b/clang-tidy/bugprone/IntegerDivisionCheck.h @@ -1,9 +1,8 @@ //===--- IntegerDivisionCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp b/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp index bdb769dc..bcd1ab8a 100644 --- a/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp +++ b/clang-tidy/bugprone/LambdaFunctionNameCheck.cpp @@ -1,9 +1,8 @@ //===--- LambdaFunctionNameCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/LambdaFunctionNameCheck.h b/clang-tidy/bugprone/LambdaFunctionNameCheck.h index b7b1b441..b00df533 100644 --- a/clang-tidy/bugprone/LambdaFunctionNameCheck.h +++ b/clang-tidy/bugprone/LambdaFunctionNameCheck.h @@ -1,9 +1,8 @@ //===--- LambdaFunctionNameCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MacroParenthesesCheck.cpp b/clang-tidy/bugprone/MacroParenthesesCheck.cpp index 6846bc2f..2bebf4ad 100644 --- a/clang-tidy/bugprone/MacroParenthesesCheck.cpp +++ b/clang-tidy/bugprone/MacroParenthesesCheck.cpp @@ -1,9 +1,8 @@ //===--- MacroParenthesesCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MacroParenthesesCheck.h b/clang-tidy/bugprone/MacroParenthesesCheck.h index 383a6cce..4b9e1819 100644 --- a/clang-tidy/bugprone/MacroParenthesesCheck.h +++ b/clang-tidy/bugprone/MacroParenthesesCheck.h @@ -1,9 +1,8 @@ //===--- MacroParenthesesCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp index 30c770e3..91ec0944 100644 --- a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp +++ b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.cpp @@ -1,9 +1,8 @@ //===--- MacroRepeatedSideEffectsCheck.cpp - clang-tidy--------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h index a2a31341..6917c5b2 100644 --- a/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h +++ b/clang-tidy/bugprone/MacroRepeatedSideEffectsCheck.h @@ -1,9 +1,8 @@ //===--- MacroRepeatedSideEffectsCheck.h - clang-tidy -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp index 83ddbcfb..3e6f9fde 100644 --- a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp +++ b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp @@ -1,9 +1,8 @@ //===--- MisplacedOperatorInStrlenInAllocCheck.cpp - clang-tidy------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h index 99cfcfbb..aede5ff9 100644 --- a/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h +++ b/clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.h @@ -1,9 +1,8 @@ //===--- MisplacedOperatorInStrlenInAllocCheck.h - clang-tidy----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp b/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp index 46fbd2b4..98a1a0c3 100644 --- a/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp +++ b/clang-tidy/bugprone/MisplacedWideningCastCheck.cpp @@ -1,9 +1,8 @@ //===--- MisplacedWideningCastCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MisplacedWideningCastCheck.h b/clang-tidy/bugprone/MisplacedWideningCastCheck.h index b61556fd..ccf4cf75 100644 --- a/clang-tidy/bugprone/MisplacedWideningCastCheck.h +++ b/clang-tidy/bugprone/MisplacedWideningCastCheck.h @@ -1,9 +1,8 @@ //===--- MisplacedWideningCastCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp index f75a194f..bf6f2f6e 100644 --- a/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp +++ b/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp @@ -1,9 +1,8 @@ //===--- MoveForwardingReferenceCheck.cpp - clang-tidy --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MoveForwardingReferenceCheck.h b/clang-tidy/bugprone/MoveForwardingReferenceCheck.h index c61de757..2565dcda 100644 --- a/clang-tidy/bugprone/MoveForwardingReferenceCheck.h +++ b/clang-tidy/bugprone/MoveForwardingReferenceCheck.h @@ -1,9 +1,8 @@ //===--- MoveForwardingReferenceCheck.h - clang-tidy ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp b/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp index 5c498213..5cc7febc 100644 --- a/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp +++ b/clang-tidy/bugprone/MultipleStatementMacroCheck.cpp @@ -1,9 +1,8 @@ //===--- MultipleStatementMacroCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/MultipleStatementMacroCheck.h b/clang-tidy/bugprone/MultipleStatementMacroCheck.h index efc65991..0fd91eb3 100644 --- a/clang-tidy/bugprone/MultipleStatementMacroCheck.h +++ b/clang-tidy/bugprone/MultipleStatementMacroCheck.h @@ -1,9 +1,8 @@ //===--- MultipleStatementMacroCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ParentVirtualCallCheck.cpp b/clang-tidy/bugprone/ParentVirtualCallCheck.cpp index a5293b15..b2f51426 100755 --- a/clang-tidy/bugprone/ParentVirtualCallCheck.cpp +++ b/clang-tidy/bugprone/ParentVirtualCallCheck.cpp @@ -1,9 +1,8 @@ //===--- ParentVirtualCallCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ParentVirtualCallCheck.h b/clang-tidy/bugprone/ParentVirtualCallCheck.h index 08c3aefb..a1753cde 100755 --- a/clang-tidy/bugprone/ParentVirtualCallCheck.h +++ b/clang-tidy/bugprone/ParentVirtualCallCheck.h @@ -1,9 +1,8 @@ //===--- ParentVirtualCallCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SizeofContainerCheck.cpp b/clang-tidy/bugprone/SizeofContainerCheck.cpp index f7d63b1a..411fe8de 100644 --- a/clang-tidy/bugprone/SizeofContainerCheck.cpp +++ b/clang-tidy/bugprone/SizeofContainerCheck.cpp @@ -1,9 +1,8 @@ //===--- SizeofContainerCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SizeofContainerCheck.h b/clang-tidy/bugprone/SizeofContainerCheck.h index 76b82b00..e358279f 100644 --- a/clang-tidy/bugprone/SizeofContainerCheck.h +++ b/clang-tidy/bugprone/SizeofContainerCheck.h @@ -1,9 +1,8 @@ //===--- SizeofContainerCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tidy/bugprone/SizeofExpressionCheck.cpp index d662657a..959e0ae3 100644 --- a/clang-tidy/bugprone/SizeofExpressionCheck.cpp +++ b/clang-tidy/bugprone/SizeofExpressionCheck.cpp @@ -1,9 +1,8 @@ //===--- SizeofExpressionCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SizeofExpressionCheck.h b/clang-tidy/bugprone/SizeofExpressionCheck.h index 8e14c315..b06551a4 100644 --- a/clang-tidy/bugprone/SizeofExpressionCheck.h +++ b/clang-tidy/bugprone/SizeofExpressionCheck.h @@ -1,9 +1,8 @@ //===--- SizeofExpressionCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tidy/bugprone/StringConstructorCheck.cpp index cc6e2973..3a4e75bc 100644 --- a/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -1,9 +1,8 @@ //===--- StringConstructorCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/StringConstructorCheck.h b/clang-tidy/bugprone/StringConstructorCheck.h index 52e9791f..22740156 100644 --- a/clang-tidy/bugprone/StringConstructorCheck.h +++ b/clang-tidy/bugprone/StringConstructorCheck.h @@ -1,9 +1,8 @@ //===--- StringConstructorCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index f49a5709..cce0de9f 100644 --- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -1,9 +1,8 @@ //===--- StringIntegerAssignmentCheck.cpp - clang-tidy---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.h b/clang-tidy/bugprone/StringIntegerAssignmentCheck.h index 42fa53e9..66da587a 100644 --- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.h +++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.h @@ -1,9 +1,8 @@ //===--- StringIntegerAssignmentCheck.h - clang-tidy-------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp index b440b616..0fbd93e8 100644 --- a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp +++ b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.cpp @@ -1,9 +1,8 @@ //===--- StringLiteralWithEmbeddedNulCheck.cpp - clang-tidy----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h index f5341c31..68885106 100644 --- a/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h +++ b/clang-tidy/bugprone/StringLiteralWithEmbeddedNulCheck.h @@ -1,9 +1,8 @@ //===--- StringLiteralWithEmbeddedNulCheck.h - clang-tidy--------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp index 53537005..42965a6d 100644 --- a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp +++ b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.cpp @@ -1,9 +1,8 @@ //===--- SuspiciousEnumUsageCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h index 9c1b53d7..32c4a0b7 100644 --- a/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h +++ b/clang-tidy/bugprone/SuspiciousEnumUsageCheck.h @@ -1,9 +1,8 @@ //===--- SuspiciousEnumUsageCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp index ca3c1263..9f983169 100644 --- a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp +++ b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.cpp @@ -1,9 +1,8 @@ //===--- SuspiciousMemsetUsageCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h index 1c0d1bcf..98872e64 100644 --- a/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h +++ b/clang-tidy/bugprone/SuspiciousMemsetUsageCheck.h @@ -1,9 +1,8 @@ //===--- SuspiciousMemsetUsageCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp index a66cf431..09409d87 100644 --- a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp +++ b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.cpp @@ -1,9 +1,8 @@ //===--- SuspiciousMissingCommaCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h index 4ae3ecf0..d1f58a48 100644 --- a/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h +++ b/clang-tidy/bugprone/SuspiciousMissingCommaCheck.h @@ -1,9 +1,8 @@ //===--- SuspiciousMissingCommaCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp b/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp index f92fc37f..576fba51 100644 --- a/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp +++ b/clang-tidy/bugprone/SuspiciousSemicolonCheck.cpp @@ -1,9 +1,8 @@ //===--- SuspiciousSemicolonCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousSemicolonCheck.h b/clang-tidy/bugprone/SuspiciousSemicolonCheck.h index adfced1a..12829b1a 100644 --- a/clang-tidy/bugprone/SuspiciousSemicolonCheck.h +++ b/clang-tidy/bugprone/SuspiciousSemicolonCheck.h @@ -1,9 +1,8 @@ //===--- SuspiciousSemicolonCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp b/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp index a16da4af..8de64608 100644 --- a/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp +++ b/clang-tidy/bugprone/SuspiciousStringCompareCheck.cpp @@ -1,9 +1,8 @@ //===--- SuspiciousStringCompareCheck.cpp - clang-tidy---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SuspiciousStringCompareCheck.h b/clang-tidy/bugprone/SuspiciousStringCompareCheck.h index 38a9d9cd..409d79bc 100644 --- a/clang-tidy/bugprone/SuspiciousStringCompareCheck.h +++ b/clang-tidy/bugprone/SuspiciousStringCompareCheck.h @@ -1,9 +1,8 @@ //===--- SuspiciousStringCompareCheck.h - clang-tidy-------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SwappedArgumentsCheck.cpp b/clang-tidy/bugprone/SwappedArgumentsCheck.cpp index c1550f6d..9f055306 100644 --- a/clang-tidy/bugprone/SwappedArgumentsCheck.cpp +++ b/clang-tidy/bugprone/SwappedArgumentsCheck.cpp @@ -1,9 +1,8 @@ //===--- SwappedArgumentsCheck.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/SwappedArgumentsCheck.h b/clang-tidy/bugprone/SwappedArgumentsCheck.h index 59ec3add..a1e10df6 100644 --- a/clang-tidy/bugprone/SwappedArgumentsCheck.h +++ b/clang-tidy/bugprone/SwappedArgumentsCheck.h @@ -1,9 +1,8 @@ //===--- SwappedArgumentsCheck.h - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/TerminatingContinueCheck.cpp b/clang-tidy/bugprone/TerminatingContinueCheck.cpp index e41fc1fa..beeeb2c8 100644 --- a/clang-tidy/bugprone/TerminatingContinueCheck.cpp +++ b/clang-tidy/bugprone/TerminatingContinueCheck.cpp @@ -1,9 +1,8 @@ //===--- TerminatingContinueCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/TerminatingContinueCheck.h b/clang-tidy/bugprone/TerminatingContinueCheck.h index 5985693c..6d589491 100644 --- a/clang-tidy/bugprone/TerminatingContinueCheck.h +++ b/clang-tidy/bugprone/TerminatingContinueCheck.h @@ -1,9 +1,8 @@ //===--- TerminatingContinueCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp b/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp index 695d9c5f..767f9a4a 100644 --- a/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp +++ b/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp @@ -1,9 +1,8 @@ //===--- ThrowKeywordMissingCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/ThrowKeywordMissingCheck.h b/clang-tidy/bugprone/ThrowKeywordMissingCheck.h index cc57083c..76b4dc15 100644 --- a/clang-tidy/bugprone/ThrowKeywordMissingCheck.h +++ b/clang-tidy/bugprone/ThrowKeywordMissingCheck.h @@ -1,9 +1,8 @@ //===--- ThrowKeywordMissingCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp index 59cc185e..395885e9 100644 --- a/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp +++ b/clang-tidy/bugprone/TooSmallLoopVariableCheck.cpp @@ -1,9 +1,8 @@ //===--- TooSmallLoopVariableCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/TooSmallLoopVariableCheck.h b/clang-tidy/bugprone/TooSmallLoopVariableCheck.h index 0819fcf1..54589ac5 100644 --- a/clang-tidy/bugprone/TooSmallLoopVariableCheck.h +++ b/clang-tidy/bugprone/TooSmallLoopVariableCheck.h @@ -1,9 +1,8 @@ //===--- TooSmallLoopVariableCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp index 0665e080..514ee5ab 100644 --- a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp +++ b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.cpp @@ -1,9 +1,8 @@ //===--- UndefinedMemoryManipulationCheck.cpp - clang-tidy-----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h index 64d6c56b..01903df4 100644 --- a/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h +++ b/clang-tidy/bugprone/UndefinedMemoryManipulationCheck.h @@ -1,9 +1,8 @@ //===--- UndefinedMemoryManipulationCheck.h - clang-tidy---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp b/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp index 90c07b9a..32a023fc 100644 --- a/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp +++ b/clang-tidy/bugprone/UndelegatedConstructorCheck.cpp @@ -1,9 +1,8 @@ //===--- UndelegatedConstructorCheck.cpp - clang-tidy --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UndelegatedConstructorCheck.h b/clang-tidy/bugprone/UndelegatedConstructorCheck.h index ed881e15..9eda29c7 100644 --- a/clang-tidy/bugprone/UndelegatedConstructorCheck.h +++ b/clang-tidy/bugprone/UndelegatedConstructorCheck.h @@ -1,9 +1,8 @@ //===--- UndelegatedConstructorCheck.h - clang-tidy -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UnusedRaiiCheck.cpp b/clang-tidy/bugprone/UnusedRaiiCheck.cpp index e9089b77..e89cbe19 100644 --- a/clang-tidy/bugprone/UnusedRaiiCheck.cpp +++ b/clang-tidy/bugprone/UnusedRaiiCheck.cpp @@ -1,9 +1,8 @@ //===--- UnusedRaiiCheck.cpp - clang-tidy ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UnusedRaiiCheck.h b/clang-tidy/bugprone/UnusedRaiiCheck.h index 34190ece..7a4a6efa 100644 --- a/clang-tidy/bugprone/UnusedRaiiCheck.h +++ b/clang-tidy/bugprone/UnusedRaiiCheck.h @@ -1,9 +1,8 @@ //===--- UnusedRaiiCheck.h - clang-tidy -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UnusedReturnValueCheck.cpp b/clang-tidy/bugprone/UnusedReturnValueCheck.cpp index b8de045e..c3efb08d 100644 --- a/clang-tidy/bugprone/UnusedReturnValueCheck.cpp +++ b/clang-tidy/bugprone/UnusedReturnValueCheck.cpp @@ -1,9 +1,8 @@ //===--- UnusedReturnValueCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UnusedReturnValueCheck.h b/clang-tidy/bugprone/UnusedReturnValueCheck.h index 9475f56b..35678edd 100644 --- a/clang-tidy/bugprone/UnusedReturnValueCheck.h +++ b/clang-tidy/bugprone/UnusedReturnValueCheck.h @@ -1,9 +1,8 @@ //===--- UnusedReturnValueCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UseAfterMoveCheck.cpp b/clang-tidy/bugprone/UseAfterMoveCheck.cpp index 99c847eb..8e316ebc 100644 --- a/clang-tidy/bugprone/UseAfterMoveCheck.cpp +++ b/clang-tidy/bugprone/UseAfterMoveCheck.cpp @@ -1,9 +1,8 @@ //===--- UseAfterMoveCheck.cpp - clang-tidy -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/UseAfterMoveCheck.h b/clang-tidy/bugprone/UseAfterMoveCheck.h index f6dea68d..c0984b45 100644 --- a/clang-tidy/bugprone/UseAfterMoveCheck.h +++ b/clang-tidy/bugprone/UseAfterMoveCheck.h @@ -1,9 +1,8 @@ //===--- UseAfterMoveCheck.h - clang-tidy ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/VirtualNearMissCheck.cpp b/clang-tidy/bugprone/VirtualNearMissCheck.cpp index ede1bf33..32ca1b48 100644 --- a/clang-tidy/bugprone/VirtualNearMissCheck.cpp +++ b/clang-tidy/bugprone/VirtualNearMissCheck.cpp @@ -1,9 +1,8 @@ //===--- VirtualNearMissCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/bugprone/VirtualNearMissCheck.h b/clang-tidy/bugprone/VirtualNearMissCheck.h index ea1e2566..38314ee0 100644 --- a/clang-tidy/bugprone/VirtualNearMissCheck.h +++ b/clang-tidy/bugprone/VirtualNearMissCheck.h @@ -1,9 +1,8 @@ //===--- VirtualNearMissCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/CERTTidyModule.cpp b/clang-tidy/cert/CERTTidyModule.cpp index b6a0e7b6..cd8da0c6 100644 --- a/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tidy/cert/CERTTidyModule.cpp @@ -1,9 +1,8 @@ //===--- CERTTidyModule.cpp - clang-tidy ----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/CommandProcessorCheck.cpp b/clang-tidy/cert/CommandProcessorCheck.cpp index e2dbeca2..cfc2f373 100644 --- a/clang-tidy/cert/CommandProcessorCheck.cpp +++ b/clang-tidy/cert/CommandProcessorCheck.cpp @@ -1,9 +1,8 @@ //===--- Env33CCheck.cpp - clang-tidy--------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/CommandProcessorCheck.h b/clang-tidy/cert/CommandProcessorCheck.h index a85a7eda..1f172e45 100644 --- a/clang-tidy/cert/CommandProcessorCheck.h +++ b/clang-tidy/cert/CommandProcessorCheck.h @@ -1,9 +1,8 @@ //===--- CommandInterpreterCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp b/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp index e5759a52..7b2c7597 100644 --- a/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp +++ b/clang-tidy/cert/DontModifyStdNamespaceCheck.cpp @@ -1,9 +1,8 @@ //===--- DontModifyStdNamespaceCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/DontModifyStdNamespaceCheck.h b/clang-tidy/cert/DontModifyStdNamespaceCheck.h index 0cc23f79..06de157f 100644 --- a/clang-tidy/cert/DontModifyStdNamespaceCheck.h +++ b/clang-tidy/cert/DontModifyStdNamespaceCheck.h @@ -1,9 +1,8 @@ //===--- DontModifyStdNamespaceCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/FloatLoopCounter.cpp b/clang-tidy/cert/FloatLoopCounter.cpp index e92552ed..b6b3b194 100644 --- a/clang-tidy/cert/FloatLoopCounter.cpp +++ b/clang-tidy/cert/FloatLoopCounter.cpp @@ -1,9 +1,8 @@ //===--- FloatLoopCounter.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/FloatLoopCounter.h b/clang-tidy/cert/FloatLoopCounter.h index c66e44ae..7752c6e7 100644 --- a/clang-tidy/cert/FloatLoopCounter.h +++ b/clang-tidy/cert/FloatLoopCounter.h @@ -1,9 +1,8 @@ //===--- FloatLoopCounter.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/LimitedRandomnessCheck.cpp b/clang-tidy/cert/LimitedRandomnessCheck.cpp index 3f6f948d..847f05e7 100644 --- a/clang-tidy/cert/LimitedRandomnessCheck.cpp +++ b/clang-tidy/cert/LimitedRandomnessCheck.cpp @@ -1,9 +1,8 @@ //===--- LimitedRandomnessCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/LimitedRandomnessCheck.h b/clang-tidy/cert/LimitedRandomnessCheck.h index 59d511cb..b88145e5 100644 --- a/clang-tidy/cert/LimitedRandomnessCheck.h +++ b/clang-tidy/cert/LimitedRandomnessCheck.h @@ -1,9 +1,8 @@ //===--- LimitedRandomnessCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/PostfixOperatorCheck.cpp b/clang-tidy/cert/PostfixOperatorCheck.cpp index b8e84df9..45c74814 100644 --- a/clang-tidy/cert/PostfixOperatorCheck.cpp +++ b/clang-tidy/cert/PostfixOperatorCheck.cpp @@ -1,9 +1,8 @@ //===--- PostfixOperatorCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/PostfixOperatorCheck.h b/clang-tidy/cert/PostfixOperatorCheck.h index 29c2306d..6b7eda2b 100644 --- a/clang-tidy/cert/PostfixOperatorCheck.h +++ b/clang-tidy/cert/PostfixOperatorCheck.h @@ -1,9 +1,8 @@ //===--- PostfixOperatorCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp index 6ae9bd29..3be83cf4 100644 --- a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp +++ b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.cpp @@ -1,9 +1,8 @@ //===--- ProperlySeededRandomGeneratorCheck.cpp - clang-tidy---------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h index ac5507c9..4fbca8fd 100644 --- a/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h +++ b/clang-tidy/cert/ProperlySeededRandomGeneratorCheck.h @@ -1,9 +1,8 @@ //===--- ProperlySeededRandomGeneratorCheck.h - clang-tidy-------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/SetLongJmpCheck.cpp b/clang-tidy/cert/SetLongJmpCheck.cpp index 89ba5e77..6b418d49 100644 --- a/clang-tidy/cert/SetLongJmpCheck.cpp +++ b/clang-tidy/cert/SetLongJmpCheck.cpp @@ -1,9 +1,8 @@ //===--- SetLongJmpCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/SetLongJmpCheck.h b/clang-tidy/cert/SetLongJmpCheck.h index 1d6c0981..ea20ba7f 100644 --- a/clang-tidy/cert/SetLongJmpCheck.h +++ b/clang-tidy/cert/SetLongJmpCheck.h @@ -1,9 +1,8 @@ //===--- SetLongJmpCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/StaticObjectExceptionCheck.cpp b/clang-tidy/cert/StaticObjectExceptionCheck.cpp index 30f86aa9..363c96a2 100644 --- a/clang-tidy/cert/StaticObjectExceptionCheck.cpp +++ b/clang-tidy/cert/StaticObjectExceptionCheck.cpp @@ -1,9 +1,8 @@ //===--- StaticObjectExceptionCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/StaticObjectExceptionCheck.h b/clang-tidy/cert/StaticObjectExceptionCheck.h index 463f4336..6b59b859 100644 --- a/clang-tidy/cert/StaticObjectExceptionCheck.h +++ b/clang-tidy/cert/StaticObjectExceptionCheck.h @@ -1,9 +1,8 @@ //===--- StaticObjectExceptionCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/StrToNumCheck.cpp b/clang-tidy/cert/StrToNumCheck.cpp index 0b3ea43b..38e2dc00 100644 --- a/clang-tidy/cert/StrToNumCheck.cpp +++ b/clang-tidy/cert/StrToNumCheck.cpp @@ -1,9 +1,8 @@ //===--- Err34CCheck.cpp - clang-tidy--------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/StrToNumCheck.h b/clang-tidy/cert/StrToNumCheck.h index 55f13bea..423a9059 100644 --- a/clang-tidy/cert/StrToNumCheck.h +++ b/clang-tidy/cert/StrToNumCheck.h @@ -1,9 +1,8 @@ //===--- StrToNumCheck.h - clang-tidy----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/ThrownExceptionTypeCheck.cpp b/clang-tidy/cert/ThrownExceptionTypeCheck.cpp index 37fb355f..94784055 100644 --- a/clang-tidy/cert/ThrownExceptionTypeCheck.cpp +++ b/clang-tidy/cert/ThrownExceptionTypeCheck.cpp @@ -1,9 +1,8 @@ //===--- ThrownExceptionTypeCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/ThrownExceptionTypeCheck.h b/clang-tidy/cert/ThrownExceptionTypeCheck.h index 2f9d887f..042b98c1 100644 --- a/clang-tidy/cert/ThrownExceptionTypeCheck.h +++ b/clang-tidy/cert/ThrownExceptionTypeCheck.h @@ -1,9 +1,8 @@ //===--- ThrownExceptionTypeCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/VariadicFunctionDefCheck.cpp b/clang-tidy/cert/VariadicFunctionDefCheck.cpp index ea6112a6..4fe6b7af 100644 --- a/clang-tidy/cert/VariadicFunctionDefCheck.cpp +++ b/clang-tidy/cert/VariadicFunctionDefCheck.cpp @@ -1,9 +1,8 @@ //===--- VariadicfunctiondefCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cert/VariadicFunctionDefCheck.h b/clang-tidy/cert/VariadicFunctionDefCheck.h index e215e8df..7f8d479d 100644 --- a/clang-tidy/cert/VariadicFunctionDefCheck.h +++ b/clang-tidy/cert/VariadicFunctionDefCheck.h @@ -1,9 +1,8 @@ //===--- VariadicFunctionDefCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp index eaed15f9..9e7bf636 100644 --- a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp +++ b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidGotoCheck.cpp - clang-tidy-----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h index cf7dd76f..f27e22c7 100644 --- a/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h +++ b/clang-tidy/cppcoreguidelines/AvoidGotoCheck.h @@ -1,9 +1,8 @@ //===--- AvoidGotoCheck.h - clang-tidy---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index 0870f1ee..fdf2880b 100644 --- a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -1,9 +1,8 @@ //===--- CppCoreGuidelinesModule.cpp - clang-tidy -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp index 59993cba..d9c91b23 100644 --- a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp +++ b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.cpp @@ -1,9 +1,8 @@ //===--- InterfacesGlobalInitCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h index 13712d11..ecaaaa33 100644 --- a/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h +++ b/clang-tidy/cppcoreguidelines/InterfacesGlobalInitCheck.h @@ -1,9 +1,8 @@ //===--- InterfacesGlobalInitCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp b/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp index 8b893c7c..07351b86 100644 --- a/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp +++ b/clang-tidy/cppcoreguidelines/MacroUsageCheck.cpp @@ -1,9 +1,8 @@ //===--- MacroUsageCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/MacroUsageCheck.h b/clang-tidy/cppcoreguidelines/MacroUsageCheck.h index a39d55a2..fc96e338 100644 --- a/clang-tidy/cppcoreguidelines/MacroUsageCheck.h +++ b/clang-tidy/cppcoreguidelines/MacroUsageCheck.h @@ -1,9 +1,8 @@ //===--- MacroUsageCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp index 132d84ad..57311166 100644 --- a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp +++ b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.cpp @@ -1,9 +1,8 @@ //===--- NarrowingConversionsCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h index 3e72248f..cc598edd 100644 --- a/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h +++ b/clang-tidy/cppcoreguidelines/NarrowingConversionsCheck.h @@ -1,9 +1,8 @@ //===--- NarrowingConversionsCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp b/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp index f9cec51e..b78e7d17 100644 --- a/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp +++ b/clang-tidy/cppcoreguidelines/NoMallocCheck.cpp @@ -1,9 +1,8 @@ //===--- NoMallocCheck.cpp - clang-tidy------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/NoMallocCheck.h b/clang-tidy/cppcoreguidelines/NoMallocCheck.h index 4cec8a83..023202ae 100644 --- a/clang-tidy/cppcoreguidelines/NoMallocCheck.h +++ b/clang-tidy/cppcoreguidelines/NoMallocCheck.h @@ -1,9 +1,8 @@ //===--- NoMallocCheck.h - clang-tidy----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp index 0b7e0a3d..11d1e3eb 100644 --- a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp +++ b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.cpp @@ -1,9 +1,8 @@ //===--- OwningMemoryCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h index e68e4c09..0498eea9 100644 --- a/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h +++ b/clang-tidy/cppcoreguidelines/OwningMemoryCheck.h @@ -1,9 +1,8 @@ //===--- OwningMemoryCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp index af41386d..6939ec9b 100644 --- a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.cpp @@ -1,9 +1,8 @@ //===--- ProBoundsArrayToPointerDecayCheck.cpp - clang-tidy----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h index 0afffb64..28099654 100644 --- a/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h +++ b/clang-tidy/cppcoreguidelines/ProBoundsArrayToPointerDecayCheck.h @@ -1,9 +1,8 @@ //===--- ProBoundsArrayToPointerDecayCheck.h - clang-tidy--------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp index 9fbb1219..32e3fb54 100644 --- a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.cpp @@ -1,9 +1,8 @@ //===--- ProBoundsConstantArrayIndexCheck.cpp - clang-tidy-----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h index 28b24a6b..c056926c 100644 --- a/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h +++ b/clang-tidy/cppcoreguidelines/ProBoundsConstantArrayIndexCheck.h @@ -1,9 +1,8 @@ //===--- ProBoundsConstantArrayIndexCheck.h - clang-tidy---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp index dfbb51be..384c8be9 100644 --- a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.cpp @@ -1,9 +1,8 @@ //===--- ProBoundsPointerArithmeticCheck.cpp - clang-tidy------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h index 5ecf93cc..ab43c789 100644 --- a/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h +++ b/clang-tidy/cppcoreguidelines/ProBoundsPointerArithmeticCheck.h @@ -1,9 +1,8 @@ //===--- ProBoundsPointerArithmeticCheck.h - clang-tidy----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp index 4b6fb420..419c6765 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeConstCastCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h index 92a3a1b5..2fbfdd3b 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeConstCastCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeConstCastCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp index bc2418d6..18fad579 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeCstyleCastCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h index c08b883c..aebc57ec 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeCstyleCastCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeCstyleCastCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index 82f50a1a..c6cfe5ec 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeMemberInitCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h index 20d3f60f..807acfe3 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeMemberInitCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp index e56e6388..4c4c6ce1 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeReinterpretCastCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h index 9610546f..5afd461f 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeReinterpretCastCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeReinterpretCast.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp index f43e4fa1..59503ba6 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeStaticCastDowncastCheck.cpp - clang-tidy-------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h index b6d76a69..e7c45aec 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeStaticCastDowncastCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeStaticCastDowncastCheck.h - clang-tidy-----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp index 09752f69..e50dd4e6 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeUnionAccessCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h index fc7dd671..70080f43 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeUnionAccessCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeUnionAccessCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp index 56227b23..650e668d 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp +++ b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp @@ -1,9 +1,8 @@ //===--- ProTypeVarargCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h index 558c8568..98acc5ad 100644 --- a/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h +++ b/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.h @@ -1,9 +1,8 @@ //===--- ProTypeVarargCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tidy/cppcoreguidelines/SlicingCheck.cpp index 53b2f728..8ad47505 100644 --- a/clang-tidy/cppcoreguidelines/SlicingCheck.cpp +++ b/clang-tidy/cppcoreguidelines/SlicingCheck.cpp @@ -1,9 +1,8 @@ //===--- SlicingCheck.cpp - clang-tidy-------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/SlicingCheck.h b/clang-tidy/cppcoreguidelines/SlicingCheck.h index 9ee91bcd..a2322a9f 100644 --- a/clang-tidy/cppcoreguidelines/SlicingCheck.h +++ b/clang-tidy/cppcoreguidelines/SlicingCheck.h @@ -1,9 +1,8 @@ //===--- SlicingCheck.h - clang-tidy-----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp index df3c2796..8f95e501 100644 --- a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp +++ b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.cpp @@ -1,9 +1,8 @@ //===--- SpecialMemberFunctionsCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h index 8ab0c92b..71caa4da 100644 --- a/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h +++ b/clang-tidy/cppcoreguidelines/SpecialMemberFunctionsCheck.h @@ -1,9 +1,8 @@ //===--- SpecialMemberFunctionsCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp b/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp index e6a67e0a..7f83ac67 100644 --- a/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp +++ b/clang-tidy/fuchsia/DefaultArgumentsCheck.cpp @@ -1,9 +1,8 @@ //===--- DefaultArgumentsCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/DefaultArgumentsCheck.h b/clang-tidy/fuchsia/DefaultArgumentsCheck.h index f54fd964..b31145ca 100644 --- a/clang-tidy/fuchsia/DefaultArgumentsCheck.h +++ b/clang-tidy/fuchsia/DefaultArgumentsCheck.h @@ -1,9 +1,8 @@ //===--- DefaultArgumentsCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/FuchsiaTidyModule.cpp b/clang-tidy/fuchsia/FuchsiaTidyModule.cpp index 0d3bbfe7..034a30ea 100644 --- a/clang-tidy/fuchsia/FuchsiaTidyModule.cpp +++ b/clang-tidy/fuchsia/FuchsiaTidyModule.cpp @@ -1,9 +1,8 @@ //===--- FuchsiaTidyModule.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp index a49c952f..a5f9d6ed 100644 --- a/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp +++ b/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp @@ -1,9 +1,8 @@ //===--- MultipleInheritanceCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tidy/fuchsia/MultipleInheritanceCheck.h index 6250e3ec..02d4cff6 100644 --- a/clang-tidy/fuchsia/MultipleInheritanceCheck.h +++ b/clang-tidy/fuchsia/MultipleInheritanceCheck.h @@ -1,9 +1,8 @@ //===--- MultipleInheritanceCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp b/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp index 4aab1e01..fb77efc3 100644 --- a/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp +++ b/clang-tidy/fuchsia/OverloadedOperatorCheck.cpp @@ -1,9 +1,8 @@ //===--- OverloadedOperatorCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/OverloadedOperatorCheck.h b/clang-tidy/fuchsia/OverloadedOperatorCheck.h index a22e5ae5..6d99e8bf 100644 --- a/clang-tidy/fuchsia/OverloadedOperatorCheck.h +++ b/clang-tidy/fuchsia/OverloadedOperatorCheck.h @@ -1,9 +1,8 @@ //===--- OverloadedOperatorCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp index 4817e904..e42e32cd 100644 --- a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp +++ b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.cpp @@ -1,9 +1,8 @@ //===--- RestrictSystemIncludesCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h index d4e5ac1e..64da2e76 100644 --- a/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h +++ b/clang-tidy/fuchsia/RestrictSystemIncludesCheck.h @@ -1,9 +1,8 @@ //===--- RestrictSystemIncludesCheck.h - clang-tidy---------- ----*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp index c8ffd2e5..cd6de922 100644 --- a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp +++ b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.cpp @@ -1,9 +1,8 @@ //===--- StaticallyConstructedObjectsCheck.cpp - clang-tidy----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h index 6df9b1c2..5e16d0ae 100644 --- a/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h +++ b/clang-tidy/fuchsia/StaticallyConstructedObjectsCheck.h @@ -1,9 +1,8 @@ //===--- StaticallyConstructedObjectsCheck.h - clang-tidy--------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/TrailingReturnCheck.cpp b/clang-tidy/fuchsia/TrailingReturnCheck.cpp index 71dc4724..a1da0db6 100644 --- a/clang-tidy/fuchsia/TrailingReturnCheck.cpp +++ b/clang-tidy/fuchsia/TrailingReturnCheck.cpp @@ -1,9 +1,8 @@ //===--- TrailingReturnCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/TrailingReturnCheck.h b/clang-tidy/fuchsia/TrailingReturnCheck.h index 4a16c4e4..181d1422 100644 --- a/clang-tidy/fuchsia/TrailingReturnCheck.h +++ b/clang-tidy/fuchsia/TrailingReturnCheck.h @@ -1,9 +1,8 @@ //===--- TrailingReturnCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp b/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp index 82f44103..54a4d73c 100644 --- a/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp +++ b/clang-tidy/fuchsia/VirtualInheritanceCheck.cpp @@ -1,9 +1,8 @@ //===--- VirtualInheritanceCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/fuchsia/VirtualInheritanceCheck.h b/clang-tidy/fuchsia/VirtualInheritanceCheck.h index b2c84c41..8e39d816 100644 --- a/clang-tidy/fuchsia/VirtualInheritanceCheck.h +++ b/clang-tidy/fuchsia/VirtualInheritanceCheck.h @@ -1,9 +1,8 @@ //===--- VirtualInheritanceCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/AvoidCStyleCastsCheck.cpp b/clang-tidy/google/AvoidCStyleCastsCheck.cpp index d6ea7e00..6a16d884 100644 --- a/clang-tidy/google/AvoidCStyleCastsCheck.cpp +++ b/clang-tidy/google/AvoidCStyleCastsCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidCStyleCastsCheck.cpp - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/AvoidCStyleCastsCheck.h b/clang-tidy/google/AvoidCStyleCastsCheck.h index ea7e34ca..0f6ec2e0 100644 --- a/clang-tidy/google/AvoidCStyleCastsCheck.h +++ b/clang-tidy/google/AvoidCStyleCastsCheck.h @@ -1,9 +1,8 @@ //===--- AvoidCStyleCastsCheck.h - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp index ad74181b..bfc34672 100644 --- a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp +++ b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidThrowingObjCExceptionCheck.cpp - clang-tidy------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h index 9498226d..bc50bc27 100644 --- a/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h +++ b/clang-tidy/google/AvoidThrowingObjCExceptionCheck.h @@ -1,9 +1,8 @@ //===--- AvoidThrowingObjCExceptionCheck.h - clang-tidy----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/DefaultArgumentsCheck.cpp b/clang-tidy/google/DefaultArgumentsCheck.cpp index ccbd870a..1ec2924d 100644 --- a/clang-tidy/google/DefaultArgumentsCheck.cpp +++ b/clang-tidy/google/DefaultArgumentsCheck.cpp @@ -1,9 +1,8 @@ //===--- DefaultArgumentsCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/DefaultArgumentsCheck.h b/clang-tidy/google/DefaultArgumentsCheck.h index 1457a093..cbaa0a6f 100644 --- a/clang-tidy/google/DefaultArgumentsCheck.h +++ b/clang-tidy/google/DefaultArgumentsCheck.h @@ -1,9 +1,8 @@ //===--- DefaultArgumentsCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/ExplicitConstructorCheck.cpp b/clang-tidy/google/ExplicitConstructorCheck.cpp index 778ce890..69731c26 100644 --- a/clang-tidy/google/ExplicitConstructorCheck.cpp +++ b/clang-tidy/google/ExplicitConstructorCheck.cpp @@ -1,9 +1,8 @@ //===--- ExplicitConstructorCheck.cpp - clang-tidy ------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/ExplicitConstructorCheck.h b/clang-tidy/google/ExplicitConstructorCheck.h index 81e66790..7efc104b 100644 --- a/clang-tidy/google/ExplicitConstructorCheck.h +++ b/clang-tidy/google/ExplicitConstructorCheck.h @@ -1,9 +1,8 @@ //===--- ExplicitConstructorCheck.h - clang-tidy ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/ExplicitMakePairCheck.cpp b/clang-tidy/google/ExplicitMakePairCheck.cpp index 7e827514..51df3a8f 100644 --- a/clang-tidy/google/ExplicitMakePairCheck.cpp +++ b/clang-tidy/google/ExplicitMakePairCheck.cpp @@ -1,9 +1,8 @@ //===--- ExplicitMakePairCheck.cpp - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/ExplicitMakePairCheck.h b/clang-tidy/google/ExplicitMakePairCheck.h index a29825f3..1eb55282 100644 --- a/clang-tidy/google/ExplicitMakePairCheck.h +++ b/clang-tidy/google/ExplicitMakePairCheck.h @@ -1,9 +1,8 @@ //===--- ExplicitMakePairCheck.h - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tidy/google/FunctionNamingCheck.cpp index f7064708..3eeb6fa6 100644 --- a/clang-tidy/google/FunctionNamingCheck.cpp +++ b/clang-tidy/google/FunctionNamingCheck.cpp @@ -1,9 +1,8 @@ //===--- FunctionNamingCheck.cpp - clang-tidy -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/FunctionNamingCheck.h b/clang-tidy/google/FunctionNamingCheck.h index 46499e90..6efea261 100644 --- a/clang-tidy/google/FunctionNamingCheck.h +++ b/clang-tidy/google/FunctionNamingCheck.h @@ -1,9 +1,8 @@ //===--- FunctionNamingCheck.h - clang-tidy ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/GlobalNamesInHeadersCheck.cpp b/clang-tidy/google/GlobalNamesInHeadersCheck.cpp index 9f03f7d5..a83e636a 100644 --- a/clang-tidy/google/GlobalNamesInHeadersCheck.cpp +++ b/clang-tidy/google/GlobalNamesInHeadersCheck.cpp @@ -1,9 +1,8 @@ //===--- GlobalNamesInHeadersCheck.cpp - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/GlobalNamesInHeadersCheck.h b/clang-tidy/google/GlobalNamesInHeadersCheck.h index 79a6e285..80247bc3 100644 --- a/clang-tidy/google/GlobalNamesInHeadersCheck.h +++ b/clang-tidy/google/GlobalNamesInHeadersCheck.h @@ -1,9 +1,8 @@ //===--- GlobalNamesInHeadersCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp index 63885237..b2ad2764 100644 --- a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp +++ b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp @@ -1,9 +1,8 @@ //===--- GlobalVariableDeclarationCheck.cpp - clang-tidy-------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.h b/clang-tidy/google/GlobalVariableDeclarationCheck.h index ed0352bb..7213bebd 100644 --- a/clang-tidy/google/GlobalVariableDeclarationCheck.h +++ b/clang-tidy/google/GlobalVariableDeclarationCheck.h @@ -1,9 +1,8 @@ //===--- GlobalVariableDeclarationCheck.h - clang-tidy-----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/GoogleTidyModule.cpp b/clang-tidy/google/GoogleTidyModule.cpp index 7996cfc8..e6236ec2 100644 --- a/clang-tidy/google/GoogleTidyModule.cpp +++ b/clang-tidy/google/GoogleTidyModule.cpp @@ -1,9 +1,8 @@ //===--- GoogleTidyModule.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/IntegerTypesCheck.cpp b/clang-tidy/google/IntegerTypesCheck.cpp index 07ee081a..c9a1f3be 100644 --- a/clang-tidy/google/IntegerTypesCheck.cpp +++ b/clang-tidy/google/IntegerTypesCheck.cpp @@ -1,9 +1,8 @@ //===--- IntegerTypesCheck.cpp - clang-tidy -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/IntegerTypesCheck.h b/clang-tidy/google/IntegerTypesCheck.h index 8d8f9038..d8a846d9 100644 --- a/clang-tidy/google/IntegerTypesCheck.h +++ b/clang-tidy/google/IntegerTypesCheck.h @@ -1,9 +1,8 @@ //===--- IntegerTypesCheck.h - clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/NonConstReferences.cpp b/clang-tidy/google/NonConstReferences.cpp index 856bc5bc..6e0fcfe5 100644 --- a/clang-tidy/google/NonConstReferences.cpp +++ b/clang-tidy/google/NonConstReferences.cpp @@ -1,9 +1,8 @@ //===--- NonConstReferences.cpp - clang-tidy --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/NonConstReferences.h b/clang-tidy/google/NonConstReferences.h index a665813f..2b7ea8fe 100644 --- a/clang-tidy/google/NonConstReferences.h +++ b/clang-tidy/google/NonConstReferences.h @@ -1,9 +1,8 @@ //===--- NonConstReferences.h - clang-tidy ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/OverloadedUnaryAndCheck.cpp b/clang-tidy/google/OverloadedUnaryAndCheck.cpp index 57702c76..1d4d1049 100644 --- a/clang-tidy/google/OverloadedUnaryAndCheck.cpp +++ b/clang-tidy/google/OverloadedUnaryAndCheck.cpp @@ -1,9 +1,8 @@ //===--- OverloadedUnaryAndCheck.cpp - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/OverloadedUnaryAndCheck.h b/clang-tidy/google/OverloadedUnaryAndCheck.h index 5492eba2..2208b37a 100644 --- a/clang-tidy/google/OverloadedUnaryAndCheck.h +++ b/clang-tidy/google/OverloadedUnaryAndCheck.h @@ -1,9 +1,8 @@ //===--- OverloadedUnaryAndCheck.h - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/TodoCommentCheck.cpp b/clang-tidy/google/TodoCommentCheck.cpp index f1c79ce6..c46f07df 100644 --- a/clang-tidy/google/TodoCommentCheck.cpp +++ b/clang-tidy/google/TodoCommentCheck.cpp @@ -1,9 +1,8 @@ //===--- TodoCommentCheck.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/TodoCommentCheck.h b/clang-tidy/google/TodoCommentCheck.h index dbdc3668..eb89dd03 100644 --- a/clang-tidy/google/TodoCommentCheck.h +++ b/clang-tidy/google/TodoCommentCheck.h @@ -1,9 +1,8 @@ //===--- TodoCommentCheck.h - clang-tidy ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp index 94e1729b..cdb6149c 100644 --- a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp +++ b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.cpp @@ -1,9 +1,8 @@ //===--- UnnamedNamespaceInHeaderCheck.cpp - clang-tidy ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h index 4d310f57..92cece2b 100644 --- a/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h +++ b/clang-tidy/google/UnnamedNamespaceInHeaderCheck.h @@ -1,9 +1,8 @@ //===--- UnnamedNamespaceInHeaderCheck.h - clang-tidy -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp b/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp index 7490f022..f11a7d1c 100644 --- a/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp +++ b/clang-tidy/google/UsingNamespaceDirectiveCheck.cpp @@ -1,9 +1,8 @@ //===--- UsingNamespaceDirectiveCheck.cpp - clang-tidy ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/google/UsingNamespaceDirectiveCheck.h b/clang-tidy/google/UsingNamespaceDirectiveCheck.h index 2be65c16..eb636ea2 100644 --- a/clang-tidy/google/UsingNamespaceDirectiveCheck.h +++ b/clang-tidy/google/UsingNamespaceDirectiveCheck.h @@ -1,9 +1,8 @@ //===--- UsingNamespaceDirectiveCheck.h - clang-tidy ------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp index 890a56f7..a5884286 100644 --- a/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp +++ b/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp @@ -1,9 +1,8 @@ //===--- ExceptionBaseclassCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/ExceptionBaseclassCheck.h b/clang-tidy/hicpp/ExceptionBaseclassCheck.h index 778979dd..10220139 100644 --- a/clang-tidy/hicpp/ExceptionBaseclassCheck.h +++ b/clang-tidy/hicpp/ExceptionBaseclassCheck.h @@ -1,9 +1,8 @@ //===--- ExceptionBaseclassCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/HICPPTidyModule.cpp b/clang-tidy/hicpp/HICPPTidyModule.cpp index 5b5f4518..ad367dcf 100644 --- a/clang-tidy/hicpp/HICPPTidyModule.cpp +++ b/clang-tidy/hicpp/HICPPTidyModule.cpp @@ -1,9 +1,8 @@ //===------- HICPPTidyModule.cpp - clang-tidy -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp index 03f4edba..e30b4f12 100644 --- a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp +++ b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.cpp @@ -1,9 +1,8 @@ //===--- MultiwayPathsCoveredCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h index 498dad65..d21afbb5 100644 --- a/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h +++ b/clang-tidy/hicpp/MultiwayPathsCoveredCheck.h @@ -1,9 +1,8 @@ //===--- MultiwayPathsCoveredCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/NoAssemblerCheck.cpp b/clang-tidy/hicpp/NoAssemblerCheck.cpp index 06969a87..af5a1cb0 100644 --- a/clang-tidy/hicpp/NoAssemblerCheck.cpp +++ b/clang-tidy/hicpp/NoAssemblerCheck.cpp @@ -1,9 +1,8 @@ //===--- NoAssemblerCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/NoAssemblerCheck.h b/clang-tidy/hicpp/NoAssemblerCheck.h index 416ccb06..d91c5de2 100644 --- a/clang-tidy/hicpp/NoAssemblerCheck.h +++ b/clang-tidy/hicpp/NoAssemblerCheck.h @@ -1,9 +1,8 @@ //===--- NoAssemblerCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/SignedBitwiseCheck.cpp b/clang-tidy/hicpp/SignedBitwiseCheck.cpp index 97383693..781a4430 100644 --- a/clang-tidy/hicpp/SignedBitwiseCheck.cpp +++ b/clang-tidy/hicpp/SignedBitwiseCheck.cpp @@ -1,9 +1,8 @@ //===--- SignedBitwiseCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/hicpp/SignedBitwiseCheck.h b/clang-tidy/hicpp/SignedBitwiseCheck.h index 24338ad9..34d5f096 100644 --- a/clang-tidy/hicpp/SignedBitwiseCheck.h +++ b/clang-tidy/hicpp/SignedBitwiseCheck.h @@ -1,9 +1,8 @@ //===--- SignedBitwiseCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/HeaderGuardCheck.cpp b/clang-tidy/llvm/HeaderGuardCheck.cpp index c0e449ed..bde460ca 100644 --- a/clang-tidy/llvm/HeaderGuardCheck.cpp +++ b/clang-tidy/llvm/HeaderGuardCheck.cpp @@ -1,9 +1,8 @@ //===--- HeaderGuardCheck.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/HeaderGuardCheck.h b/clang-tidy/llvm/HeaderGuardCheck.h index ca2d7efd..46021e28 100644 --- a/clang-tidy/llvm/HeaderGuardCheck.h +++ b/clang-tidy/llvm/HeaderGuardCheck.h @@ -1,9 +1,8 @@ //===--- HeaderGuardCheck.h - clang-tidy ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/IncludeOrderCheck.cpp b/clang-tidy/llvm/IncludeOrderCheck.cpp index f1fdb39c..3d23644e 100644 --- a/clang-tidy/llvm/IncludeOrderCheck.cpp +++ b/clang-tidy/llvm/IncludeOrderCheck.cpp @@ -1,9 +1,8 @@ //===--- IncludeOrderCheck.cpp - clang-tidy -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/IncludeOrderCheck.h b/clang-tidy/llvm/IncludeOrderCheck.h index ad876b95..b10496e0 100644 --- a/clang-tidy/llvm/IncludeOrderCheck.h +++ b/clang-tidy/llvm/IncludeOrderCheck.h @@ -1,9 +1,8 @@ //===--- IncludeOrderCheck.h - clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/LLVMTidyModule.cpp b/clang-tidy/llvm/LLVMTidyModule.cpp index ea46ca93..f5242685 100644 --- a/clang-tidy/llvm/LLVMTidyModule.cpp +++ b/clang-tidy/llvm/LLVMTidyModule.cpp @@ -1,9 +1,8 @@ //===--- LLVMTidyModule.cpp - clang-tidy ----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/TwineLocalCheck.cpp b/clang-tidy/llvm/TwineLocalCheck.cpp index 744ddd9d..2fddf6d2 100644 --- a/clang-tidy/llvm/TwineLocalCheck.cpp +++ b/clang-tidy/llvm/TwineLocalCheck.cpp @@ -1,9 +1,8 @@ //===--- TwineLocalCheck.cpp - clang-tidy ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/llvm/TwineLocalCheck.h b/clang-tidy/llvm/TwineLocalCheck.h index 9f7979b4..c2b03e81 100644 --- a/clang-tidy/llvm/TwineLocalCheck.h +++ b/clang-tidy/llvm/TwineLocalCheck.h @@ -1,9 +1,8 @@ //===--- TwineLocalCheck.h - clang-tidy -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/DefinitionsInHeadersCheck.cpp b/clang-tidy/misc/DefinitionsInHeadersCheck.cpp index f4dab397..a36f307b 100644 --- a/clang-tidy/misc/DefinitionsInHeadersCheck.cpp +++ b/clang-tidy/misc/DefinitionsInHeadersCheck.cpp @@ -1,9 +1,8 @@ //===--- DefinitionsInHeadersCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/DefinitionsInHeadersCheck.h b/clang-tidy/misc/DefinitionsInHeadersCheck.h index 428b05cd..8e5eb7c8 100644 --- a/clang-tidy/misc/DefinitionsInHeadersCheck.h +++ b/clang-tidy/misc/DefinitionsInHeadersCheck.h @@ -1,9 +1,8 @@ //===--- DefinitionsInHeadersCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/MiscTidyModule.cpp b/clang-tidy/misc/MiscTidyModule.cpp index dd9061a4..ba160d1d 100644 --- a/clang-tidy/misc/MiscTidyModule.cpp +++ b/clang-tidy/misc/MiscTidyModule.cpp @@ -1,9 +1,8 @@ //===--- MiscTidyModule.cpp - clang-tidy ----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/MisplacedConstCheck.cpp b/clang-tidy/misc/MisplacedConstCheck.cpp index 515b22c0..1e1b2b0d 100644 --- a/clang-tidy/misc/MisplacedConstCheck.cpp +++ b/clang-tidy/misc/MisplacedConstCheck.cpp @@ -1,9 +1,8 @@ //===--- MisplacedConstCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/MisplacedConstCheck.h b/clang-tidy/misc/MisplacedConstCheck.h index 410edf7b..a156e3e3 100644 --- a/clang-tidy/misc/MisplacedConstCheck.h +++ b/clang-tidy/misc/MisplacedConstCheck.h @@ -1,9 +1,8 @@ //===--- MisplacedConstCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/NewDeleteOverloadsCheck.cpp b/clang-tidy/misc/NewDeleteOverloadsCheck.cpp index 5e291195..a96d1904 100644 --- a/clang-tidy/misc/NewDeleteOverloadsCheck.cpp +++ b/clang-tidy/misc/NewDeleteOverloadsCheck.cpp @@ -1,9 +1,8 @@ //===--- NewDeleteOverloadsCheck.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/NewDeleteOverloadsCheck.h b/clang-tidy/misc/NewDeleteOverloadsCheck.h index 3e99892b..46a3bb72 100644 --- a/clang-tidy/misc/NewDeleteOverloadsCheck.h +++ b/clang-tidy/misc/NewDeleteOverloadsCheck.h @@ -1,9 +1,8 @@ //===--- NewDeleteOverloadsCheck.h - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/NonCopyableObjects.cpp b/clang-tidy/misc/NonCopyableObjects.cpp index de152754..53cc2734 100644 --- a/clang-tidy/misc/NonCopyableObjects.cpp +++ b/clang-tidy/misc/NonCopyableObjects.cpp @@ -1,9 +1,8 @@ //===--- NonCopyableObjects.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/NonCopyableObjects.h b/clang-tidy/misc/NonCopyableObjects.h index 38a45fd5..5ebaba83 100644 --- a/clang-tidy/misc/NonCopyableObjects.h +++ b/clang-tidy/misc/NonCopyableObjects.h @@ -1,9 +1,8 @@ //===--- NonCopyableObjects.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp index c0bdbfbf..549647ff 100644 --- a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp +++ b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp @@ -1,9 +1,8 @@ //===--- NonPrivateMemberVariablesInClassesCheck.cpp - clang-tidy ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h index c39e356c..6072eae8 100644 --- a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h +++ b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h @@ -1,9 +1,8 @@ //===--- NonPrivateMemberVariablesInClassesCheck.h - clang-tidy -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tidy/misc/RedundantExpressionCheck.cpp index e9b0f4d0..33a8b9a4 100644 --- a/clang-tidy/misc/RedundantExpressionCheck.cpp +++ b/clang-tidy/misc/RedundantExpressionCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantExpressionCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/RedundantExpressionCheck.h b/clang-tidy/misc/RedundantExpressionCheck.h index c0f8bf5e..02d37e16 100644 --- a/clang-tidy/misc/RedundantExpressionCheck.h +++ b/clang-tidy/misc/RedundantExpressionCheck.h @@ -1,9 +1,8 @@ //===--- RedundantExpressionCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/StaticAssertCheck.cpp b/clang-tidy/misc/StaticAssertCheck.cpp index 583ed7ad..18d94128 100644 --- a/clang-tidy/misc/StaticAssertCheck.cpp +++ b/clang-tidy/misc/StaticAssertCheck.cpp @@ -1,9 +1,8 @@ //===--- StaticAssertCheck.cpp - clang-tidy -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/StaticAssertCheck.h b/clang-tidy/misc/StaticAssertCheck.h index faefce17..f3d3586e 100644 --- a/clang-tidy/misc/StaticAssertCheck.h +++ b/clang-tidy/misc/StaticAssertCheck.h @@ -1,9 +1,8 @@ //===--- StaticAssertCheck.h - clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp index 759c3f0e..b7077a12 100644 --- a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp +++ b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp @@ -1,9 +1,8 @@ //===--- ThrowByValueCatchByReferenceCheck.cpp - clang-tidy----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h index a2e7df73..6b79c20f 100644 --- a/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h +++ b/clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h @@ -1,9 +1,8 @@ //===--- ThrowByValueCatchByReferenceCheck.h - clang-tidy--------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp b/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp index 84dd410d..8c87dae9 100644 --- a/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp +++ b/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp @@ -1,9 +1,8 @@ //===--- UnconventionalAssignOperatorCheck.cpp - clang-tidy -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnconventionalAssignOperatorCheck.h b/clang-tidy/misc/UnconventionalAssignOperatorCheck.h index ee91dcaa..761701df 100644 --- a/clang-tidy/misc/UnconventionalAssignOperatorCheck.h +++ b/clang-tidy/misc/UnconventionalAssignOperatorCheck.h @@ -1,9 +1,8 @@ //===--- UnconventionalAssignOperatorCheck.h - clang-tidy -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp b/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp index 99758d33..9363fa90 100644 --- a/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp +++ b/clang-tidy/misc/UniqueptrResetReleaseCheck.cpp @@ -1,9 +1,8 @@ //===--- UniqueptrResetReleaseCheck.cpp - clang-tidy ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UniqueptrResetReleaseCheck.h b/clang-tidy/misc/UniqueptrResetReleaseCheck.h index cf18a5a5..d013f32c 100644 --- a/clang-tidy/misc/UniqueptrResetReleaseCheck.h +++ b/clang-tidy/misc/UniqueptrResetReleaseCheck.h @@ -1,9 +1,8 @@ //===--- UniqueptrResetReleaseCheck.h - clang-tidy --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnusedAliasDeclsCheck.cpp b/clang-tidy/misc/UnusedAliasDeclsCheck.cpp index 4beb4320..c301aeab 100644 --- a/clang-tidy/misc/UnusedAliasDeclsCheck.cpp +++ b/clang-tidy/misc/UnusedAliasDeclsCheck.cpp @@ -1,9 +1,8 @@ //===--- UnusedAliasDeclsCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnusedAliasDeclsCheck.h b/clang-tidy/misc/UnusedAliasDeclsCheck.h index 8cce3756..af27ef0f 100644 --- a/clang-tidy/misc/UnusedAliasDeclsCheck.h +++ b/clang-tidy/misc/UnusedAliasDeclsCheck.h @@ -1,9 +1,8 @@ //===--- UnusedAliasDeclsCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnusedParametersCheck.cpp b/clang-tidy/misc/UnusedParametersCheck.cpp index cee09150..01dce8fa 100644 --- a/clang-tidy/misc/UnusedParametersCheck.cpp +++ b/clang-tidy/misc/UnusedParametersCheck.cpp @@ -1,9 +1,8 @@ //===--- UnusedParametersCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnusedParametersCheck.h b/clang-tidy/misc/UnusedParametersCheck.h index b9bae26f..f4e07083 100644 --- a/clang-tidy/misc/UnusedParametersCheck.h +++ b/clang-tidy/misc/UnusedParametersCheck.h @@ -1,9 +1,8 @@ //===--- UnusedParametersCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tidy/misc/UnusedUsingDeclsCheck.cpp index 48009b5a..532dbfd4 100644 --- a/clang-tidy/misc/UnusedUsingDeclsCheck.cpp +++ b/clang-tidy/misc/UnusedUsingDeclsCheck.cpp @@ -1,9 +1,8 @@ //===--- UnusedUsingDeclsCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/misc/UnusedUsingDeclsCheck.h b/clang-tidy/misc/UnusedUsingDeclsCheck.h index 2a41a8f6..acc6a44e 100644 --- a/clang-tidy/misc/UnusedUsingDeclsCheck.h +++ b/clang-tidy/misc/UnusedUsingDeclsCheck.h @@ -1,9 +1,8 @@ //===--- UnusedUsingDeclsCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tidy/modernize/AvoidBindCheck.cpp index bd477026..44174243 100644 --- a/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tidy/modernize/AvoidBindCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidBindCheck.cpp - clang-tidy-----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/AvoidBindCheck.h b/clang-tidy/modernize/AvoidBindCheck.h index 5ae0241f..c1042d52 100644 --- a/clang-tidy/modernize/AvoidBindCheck.h +++ b/clang-tidy/modernize/AvoidBindCheck.h @@ -1,9 +1,8 @@ //===--- AvoidBindCheck.h - clang-tidy---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tidy/modernize/AvoidCArraysCheck.cpp index dd194832..bceda5c2 100644 --- a/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidCArraysCheck.cpp - clang-tidy -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/AvoidCArraysCheck.h b/clang-tidy/modernize/AvoidCArraysCheck.h index afef8848..ef638e9b 100644 --- a/clang-tidy/modernize/AvoidCArraysCheck.h +++ b/clang-tidy/modernize/AvoidCArraysCheck.h @@ -1,9 +1,8 @@ //===--- AvoidCArraysCheck.h - clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp b/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp index bef85f7b..33ac8561 100644 --- a/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp +++ b/clang-tidy/modernize/ConcatNestedNamespacesCheck.cpp @@ -1,9 +1,8 @@ //===--- ConcatNestedNamespacesCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ConcatNestedNamespacesCheck.h b/clang-tidy/modernize/ConcatNestedNamespacesCheck.h index 547690d2..7f3c6934 100644 --- a/clang-tidy/modernize/ConcatNestedNamespacesCheck.h +++ b/clang-tidy/modernize/ConcatNestedNamespacesCheck.h @@ -1,9 +1,8 @@ //===--- ConcatNestedNamespacesCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/DeprecatedHeadersCheck.cpp b/clang-tidy/modernize/DeprecatedHeadersCheck.cpp index 1ff3f898..ffc041b4 100644 --- a/clang-tidy/modernize/DeprecatedHeadersCheck.cpp +++ b/clang-tidy/modernize/DeprecatedHeadersCheck.cpp @@ -1,9 +1,8 @@ //===--- DeprecatedHeadersCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/DeprecatedHeadersCheck.h b/clang-tidy/modernize/DeprecatedHeadersCheck.h index ee7254e3..4be4ad90 100644 --- a/clang-tidy/modernize/DeprecatedHeadersCheck.h +++ b/clang-tidy/modernize/DeprecatedHeadersCheck.h @@ -1,9 +1,8 @@ //===--- DeprecatedHeadersCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp index c9f0649a..cd094219 100644 --- a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp +++ b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp @@ -1,9 +1,8 @@ //===--- DeprecatedIosBaseAliasesCheck.cpp - clang-tidy--------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h index bbccd413..bbb5ff74 100644 --- a/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h +++ b/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.h @@ -1,9 +1,8 @@ //===--- DeprecatedIosBaseAliasesCheck.h - clang-tidy------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/LoopConvertCheck.cpp b/clang-tidy/modernize/LoopConvertCheck.cpp index aa11b71a..f9e941c2 100644 --- a/clang-tidy/modernize/LoopConvertCheck.cpp +++ b/clang-tidy/modernize/LoopConvertCheck.cpp @@ -1,9 +1,8 @@ //===--- LoopConvertCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/LoopConvertCheck.h b/clang-tidy/modernize/LoopConvertCheck.h index 75ab25aa..f98a1dc4 100644 --- a/clang-tidy/modernize/LoopConvertCheck.h +++ b/clang-tidy/modernize/LoopConvertCheck.h @@ -1,9 +1,8 @@ //===--- LoopConvertCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/LoopConvertUtils.cpp b/clang-tidy/modernize/LoopConvertUtils.cpp index f65f7a16..80d80a79 100644 --- a/clang-tidy/modernize/LoopConvertUtils.cpp +++ b/clang-tidy/modernize/LoopConvertUtils.cpp @@ -1,9 +1,8 @@ //===--- LoopConvertUtils.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/LoopConvertUtils.h b/clang-tidy/modernize/LoopConvertUtils.h index f0fa11a8..3cead294 100644 --- a/clang-tidy/modernize/LoopConvertUtils.h +++ b/clang-tidy/modernize/LoopConvertUtils.h @@ -1,9 +1,8 @@ //===--- LoopConvertUtils.h - clang-tidy ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/MakeSharedCheck.cpp b/clang-tidy/modernize/MakeSharedCheck.cpp index 541c2cb5..11d24432 100644 --- a/clang-tidy/modernize/MakeSharedCheck.cpp +++ b/clang-tidy/modernize/MakeSharedCheck.cpp @@ -1,9 +1,8 @@ //===--- MakeSharedCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/MakeSharedCheck.h b/clang-tidy/modernize/MakeSharedCheck.h index cf014462..95bf6b7c 100644 --- a/clang-tidy/modernize/MakeSharedCheck.h +++ b/clang-tidy/modernize/MakeSharedCheck.h @@ -1,9 +1,8 @@ //===--- MakeSharedCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/MakeSmartPtrCheck.cpp b/clang-tidy/modernize/MakeSmartPtrCheck.cpp index 15b88b8b..9b0c5d82 100644 --- a/clang-tidy/modernize/MakeSmartPtrCheck.cpp +++ b/clang-tidy/modernize/MakeSmartPtrCheck.cpp @@ -1,9 +1,8 @@ //===--- MakeSmartPtrCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/MakeSmartPtrCheck.h b/clang-tidy/modernize/MakeSmartPtrCheck.h index 02428d7a..82855e24 100644 --- a/clang-tidy/modernize/MakeSmartPtrCheck.h +++ b/clang-tidy/modernize/MakeSmartPtrCheck.h @@ -1,9 +1,8 @@ //===--- MakeSmartPtrCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/MakeUniqueCheck.cpp b/clang-tidy/modernize/MakeUniqueCheck.cpp index 3ebbb071..1ee4fd70 100644 --- a/clang-tidy/modernize/MakeUniqueCheck.cpp +++ b/clang-tidy/modernize/MakeUniqueCheck.cpp @@ -1,9 +1,8 @@ //===--- MakeUniqueCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/MakeUniqueCheck.h b/clang-tidy/modernize/MakeUniqueCheck.h index 587b41e0..113c3294 100644 --- a/clang-tidy/modernize/MakeUniqueCheck.h +++ b/clang-tidy/modernize/MakeUniqueCheck.h @@ -1,9 +1,8 @@ //===--- MakeUniqueCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tidy/modernize/ModernizeTidyModule.cpp index fcf535b7..45ecdf93 100644 --- a/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -1,9 +1,8 @@ //===--- ModernizeTidyModule.cpp - clang-tidy -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tidy/modernize/PassByValueCheck.cpp index f54c5754..15c37253 100644 --- a/clang-tidy/modernize/PassByValueCheck.cpp +++ b/clang-tidy/modernize/PassByValueCheck.cpp @@ -1,9 +1,8 @@ //===--- PassByValueCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/PassByValueCheck.h b/clang-tidy/modernize/PassByValueCheck.h index 37deb3f7..fde65174 100644 --- a/clang-tidy/modernize/PassByValueCheck.h +++ b/clang-tidy/modernize/PassByValueCheck.h @@ -1,9 +1,8 @@ //===--- PassByValueCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/RawStringLiteralCheck.cpp b/clang-tidy/modernize/RawStringLiteralCheck.cpp index a4aef41f..415010bc 100644 --- a/clang-tidy/modernize/RawStringLiteralCheck.cpp +++ b/clang-tidy/modernize/RawStringLiteralCheck.cpp @@ -1,9 +1,8 @@ //===--- RawStringLiteralCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/RawStringLiteralCheck.h b/clang-tidy/modernize/RawStringLiteralCheck.h index f7721f6a..370400cc 100644 --- a/clang-tidy/modernize/RawStringLiteralCheck.h +++ b/clang-tidy/modernize/RawStringLiteralCheck.h @@ -1,9 +1,8 @@ //===--- RawStringLiteralCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/RedundantVoidArgCheck.cpp b/clang-tidy/modernize/RedundantVoidArgCheck.cpp index ea49ab7b..96eb7a2b 100644 --- a/clang-tidy/modernize/RedundantVoidArgCheck.cpp +++ b/clang-tidy/modernize/RedundantVoidArgCheck.cpp @@ -1,9 +1,8 @@ //===- RedundantVoidArgCheck.cpp - clang-tidy -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/RedundantVoidArgCheck.h b/clang-tidy/modernize/RedundantVoidArgCheck.h index c990ef46..6c90fa3c 100644 --- a/clang-tidy/modernize/RedundantVoidArgCheck.h +++ b/clang-tidy/modernize/RedundantVoidArgCheck.h @@ -1,9 +1,8 @@ //===--- RedundantVoidArgCheck.h - clang-tidy --------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp index 3281ef66..0de835e0 100644 --- a/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp +++ b/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp @@ -1,9 +1,8 @@ //===--- ReplaceAutoPtrCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ReplaceAutoPtrCheck.h b/clang-tidy/modernize/ReplaceAutoPtrCheck.h index 5b73d51b..174676e1 100644 --- a/clang-tidy/modernize/ReplaceAutoPtrCheck.h +++ b/clang-tidy/modernize/ReplaceAutoPtrCheck.h @@ -1,9 +1,8 @@ //===--- ReplaceAutoPtrCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp b/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp index 9a715693..73afec7a 100644 --- a/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp +++ b/clang-tidy/modernize/ReplaceRandomShuffleCheck.cpp @@ -1,9 +1,8 @@ //===--- ReplaceRandomShuffleCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ReplaceRandomShuffleCheck.h b/clang-tidy/modernize/ReplaceRandomShuffleCheck.h index 050d7401..65367080 100644 --- a/clang-tidy/modernize/ReplaceRandomShuffleCheck.h +++ b/clang-tidy/modernize/ReplaceRandomShuffleCheck.h @@ -1,9 +1,8 @@ //===--- ReplaceRandomShuffleCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ReturnBracedInitListCheck.cpp b/clang-tidy/modernize/ReturnBracedInitListCheck.cpp index e5857f76..f7e27172 100644 --- a/clang-tidy/modernize/ReturnBracedInitListCheck.cpp +++ b/clang-tidy/modernize/ReturnBracedInitListCheck.cpp @@ -1,9 +1,8 @@ //===--- ReturnBracedInitListCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ReturnBracedInitListCheck.h b/clang-tidy/modernize/ReturnBracedInitListCheck.h index eda982a8..2c60a4e3 100644 --- a/clang-tidy/modernize/ReturnBracedInitListCheck.h +++ b/clang-tidy/modernize/ReturnBracedInitListCheck.h @@ -1,9 +1,8 @@ //===--- ReturnBracedInitListCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ShrinkToFitCheck.cpp b/clang-tidy/modernize/ShrinkToFitCheck.cpp index bc0749b9..607dc5fa 100644 --- a/clang-tidy/modernize/ShrinkToFitCheck.cpp +++ b/clang-tidy/modernize/ShrinkToFitCheck.cpp @@ -1,9 +1,8 @@ //===--- ShrinkToFitCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/ShrinkToFitCheck.h b/clang-tidy/modernize/ShrinkToFitCheck.h index 1e3745cd..2f873744 100644 --- a/clang-tidy/modernize/ShrinkToFitCheck.h +++ b/clang-tidy/modernize/ShrinkToFitCheck.h @@ -1,9 +1,8 @@ //===--- ShrinkToFitCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UnaryStaticAssertCheck.cpp b/clang-tidy/modernize/UnaryStaticAssertCheck.cpp index 5ddbb933..d93a0248 100644 --- a/clang-tidy/modernize/UnaryStaticAssertCheck.cpp +++ b/clang-tidy/modernize/UnaryStaticAssertCheck.cpp @@ -1,9 +1,8 @@ //===--- UnaryStaticAssertCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UnaryStaticAssertCheck.h b/clang-tidy/modernize/UnaryStaticAssertCheck.h index b83c2c43..e1e95881 100644 --- a/clang-tidy/modernize/UnaryStaticAssertCheck.h +++ b/clang-tidy/modernize/UnaryStaticAssertCheck.h @@ -1,9 +1,8 @@ //===--- UnaryStaticAssertCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tidy/modernize/UseAutoCheck.cpp index 0fecd24a..e9f54f81 100644 --- a/clang-tidy/modernize/UseAutoCheck.cpp +++ b/clang-tidy/modernize/UseAutoCheck.cpp @@ -1,9 +1,8 @@ //===--- UseAutoCheck.cpp - clang-tidy-------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseAutoCheck.h b/clang-tidy/modernize/UseAutoCheck.h index a061c5ff..f10cd08c 100644 --- a/clang-tidy/modernize/UseAutoCheck.h +++ b/clang-tidy/modernize/UseAutoCheck.h @@ -1,9 +1,8 @@ //===--- UseAutoCheck.h - clang-tidy-----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseBoolLiteralsCheck.cpp b/clang-tidy/modernize/UseBoolLiteralsCheck.cpp index 13afbb43..011837e0 100644 --- a/clang-tidy/modernize/UseBoolLiteralsCheck.cpp +++ b/clang-tidy/modernize/UseBoolLiteralsCheck.cpp @@ -1,9 +1,8 @@ //===--- UseBoolLiteralsCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseBoolLiteralsCheck.h b/clang-tidy/modernize/UseBoolLiteralsCheck.h index c9c73634..898d9f38 100644 --- a/clang-tidy/modernize/UseBoolLiteralsCheck.h +++ b/clang-tidy/modernize/UseBoolLiteralsCheck.h @@ -1,9 +1,8 @@ //===--- UseBoolLiteralsCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp index 23a3e1fa..e2ab13b8 100644 --- a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -1,9 +1,8 @@ //===--- UseDefaultMemberInitCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseDefaultMemberInitCheck.h b/clang-tidy/modernize/UseDefaultMemberInitCheck.h index d8887a02..77f0e73a 100644 --- a/clang-tidy/modernize/UseDefaultMemberInitCheck.h +++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.h @@ -1,9 +1,8 @@ //===--- UseDefaultMemberInitCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tidy/modernize/UseEmplaceCheck.cpp index b6c142d1..786bb5a9 100644 --- a/clang-tidy/modernize/UseEmplaceCheck.cpp +++ b/clang-tidy/modernize/UseEmplaceCheck.cpp @@ -1,9 +1,8 @@ //===--- UseEmplaceCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseEmplaceCheck.h b/clang-tidy/modernize/UseEmplaceCheck.h index 2efb2129..6a55ffb9 100644 --- a/clang-tidy/modernize/UseEmplaceCheck.h +++ b/clang-tidy/modernize/UseEmplaceCheck.h @@ -1,9 +1,8 @@ //===--- UseEmplaceCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tidy/modernize/UseEqualsDefaultCheck.cpp index 4245bfea..ae6f91c8 100644 --- a/clang-tidy/modernize/UseEqualsDefaultCheck.cpp +++ b/clang-tidy/modernize/UseEqualsDefaultCheck.cpp @@ -1,9 +1,8 @@ //===--- UseEqualsDefaultCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseEqualsDefaultCheck.h b/clang-tidy/modernize/UseEqualsDefaultCheck.h index a55c222d..486ccb20 100644 --- a/clang-tidy/modernize/UseEqualsDefaultCheck.h +++ b/clang-tidy/modernize/UseEqualsDefaultCheck.h @@ -1,9 +1,8 @@ //===--- UseEqualsDefaultCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseEqualsDeleteCheck.cpp b/clang-tidy/modernize/UseEqualsDeleteCheck.cpp index fc8425d9..4c366b4c 100644 --- a/clang-tidy/modernize/UseEqualsDeleteCheck.cpp +++ b/clang-tidy/modernize/UseEqualsDeleteCheck.cpp @@ -1,9 +1,8 @@ //===--- UseEqualsDeleteCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseEqualsDeleteCheck.h b/clang-tidy/modernize/UseEqualsDeleteCheck.h index 716f045d..7d1c74d3 100644 --- a/clang-tidy/modernize/UseEqualsDeleteCheck.h +++ b/clang-tidy/modernize/UseEqualsDeleteCheck.h @@ -1,9 +1,8 @@ //===--- UseEqualsDeleteCheck.h - clang-tidy---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseNodiscardCheck.cpp b/clang-tidy/modernize/UseNodiscardCheck.cpp index f655515b..d2ac7d52 100644 --- a/clang-tidy/modernize/UseNodiscardCheck.cpp +++ b/clang-tidy/modernize/UseNodiscardCheck.cpp @@ -1,9 +1,8 @@ //===--- UseNodiscardCheck.cpp - clang-tidy -------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseNodiscardCheck.h b/clang-tidy/modernize/UseNodiscardCheck.h index 00563e7f..004ef58c 100644 --- a/clang-tidy/modernize/UseNodiscardCheck.h +++ b/clang-tidy/modernize/UseNodiscardCheck.h @@ -1,9 +1,8 @@ //===--- UseNodiscardCheck.h - clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseNoexceptCheck.cpp b/clang-tidy/modernize/UseNoexceptCheck.cpp index 869381ab..4b9c4984 100644 --- a/clang-tidy/modernize/UseNoexceptCheck.cpp +++ b/clang-tidy/modernize/UseNoexceptCheck.cpp @@ -1,9 +1,8 @@ //===--- UseNoexceptCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseNoexceptCheck.h b/clang-tidy/modernize/UseNoexceptCheck.h index a15867bd..f947d5db 100644 --- a/clang-tidy/modernize/UseNoexceptCheck.h +++ b/clang-tidy/modernize/UseNoexceptCheck.h @@ -1,9 +1,8 @@ //===--- UseNoexceptCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseNullptrCheck.cpp b/clang-tidy/modernize/UseNullptrCheck.cpp index 3bf09c1f..45e59c3e 100644 --- a/clang-tidy/modernize/UseNullptrCheck.cpp +++ b/clang-tidy/modernize/UseNullptrCheck.cpp @@ -1,9 +1,8 @@ //===--- UseNullptrCheck.cpp - clang-tidy----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseNullptrCheck.h b/clang-tidy/modernize/UseNullptrCheck.h index 4b33f1ee..7fa8b4f1 100644 --- a/clang-tidy/modernize/UseNullptrCheck.h +++ b/clang-tidy/modernize/UseNullptrCheck.h @@ -1,9 +1,8 @@ //===--- UseNullptrCheck.h - clang-tidy--------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tidy/modernize/UseOverrideCheck.cpp index 9429eb2c..6b065955 100644 --- a/clang-tidy/modernize/UseOverrideCheck.cpp +++ b/clang-tidy/modernize/UseOverrideCheck.cpp @@ -1,9 +1,8 @@ //===--- UseOverrideCheck.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseOverrideCheck.h b/clang-tidy/modernize/UseOverrideCheck.h index 83ce7da7..0f316095 100644 --- a/clang-tidy/modernize/UseOverrideCheck.h +++ b/clang-tidy/modernize/UseOverrideCheck.h @@ -1,9 +1,8 @@ //===--- UseOverrideCheck.h - clang-tidy ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp index 74f050ba..6490f027 100644 --- a/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp +++ b/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp @@ -1,9 +1,8 @@ //===--- UseTransparentFunctorsCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseTransparentFunctorsCheck.h b/clang-tidy/modernize/UseTransparentFunctorsCheck.h index 4bdce766..effc754c 100644 --- a/clang-tidy/modernize/UseTransparentFunctorsCheck.h +++ b/clang-tidy/modernize/UseTransparentFunctorsCheck.h @@ -1,9 +1,8 @@ //===--- UseTransparentFunctorsCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp b/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp index 05b2dd82..cb3f5513 100644 --- a/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp +++ b/clang-tidy/modernize/UseUncaughtExceptionsCheck.cpp @@ -1,9 +1,8 @@ //===--- UseUncaughtExceptionsCheck.cpp - clang-tidy--------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseUncaughtExceptionsCheck.h b/clang-tidy/modernize/UseUncaughtExceptionsCheck.h index 2b9660c7..80db6a61 100644 --- a/clang-tidy/modernize/UseUncaughtExceptionsCheck.h +++ b/clang-tidy/modernize/UseUncaughtExceptionsCheck.h @@ -1,9 +1,8 @@ //===--- UseUncaughtExceptionsCheck.h - clang-tidy------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseUsingCheck.cpp b/clang-tidy/modernize/UseUsingCheck.cpp index a690e447..bd234623 100644 --- a/clang-tidy/modernize/UseUsingCheck.cpp +++ b/clang-tidy/modernize/UseUsingCheck.cpp @@ -1,9 +1,8 @@ //===--- UseUsingCheck.cpp - clang-tidy------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/modernize/UseUsingCheck.h b/clang-tidy/modernize/UseUsingCheck.h index 022eef08..0975751f 100644 --- a/clang-tidy/modernize/UseUsingCheck.h +++ b/clang-tidy/modernize/UseUsingCheck.h @@ -1,9 +1,8 @@ //===--- UseUsingCheck.h - clang-tidy----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/mpi/BufferDerefCheck.cpp b/clang-tidy/mpi/BufferDerefCheck.cpp index 8e2c0e34..8ababfe4 100644 --- a/clang-tidy/mpi/BufferDerefCheck.cpp +++ b/clang-tidy/mpi/BufferDerefCheck.cpp @@ -1,9 +1,8 @@ //===--- BufferDerefCheck.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/mpi/BufferDerefCheck.h b/clang-tidy/mpi/BufferDerefCheck.h index 8490fa1c..833608bd 100644 --- a/clang-tidy/mpi/BufferDerefCheck.h +++ b/clang-tidy/mpi/BufferDerefCheck.h @@ -1,9 +1,8 @@ //===--- BufferDerefCheck.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/mpi/MPITidyModule.cpp b/clang-tidy/mpi/MPITidyModule.cpp index 55e187db..b295d5ff 100644 --- a/clang-tidy/mpi/MPITidyModule.cpp +++ b/clang-tidy/mpi/MPITidyModule.cpp @@ -1,9 +1,8 @@ //===--- MPITidyModule.cpp - clang-tidy -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/mpi/TypeMismatchCheck.cpp b/clang-tidy/mpi/TypeMismatchCheck.cpp index a1f92b8f..a9661e0e 100644 --- a/clang-tidy/mpi/TypeMismatchCheck.cpp +++ b/clang-tidy/mpi/TypeMismatchCheck.cpp @@ -1,9 +1,8 @@ //===--- TypeMismatchCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/mpi/TypeMismatchCheck.h b/clang-tidy/mpi/TypeMismatchCheck.h index dd56c465..28ff6056 100644 --- a/clang-tidy/mpi/TypeMismatchCheck.h +++ b/clang-tidy/mpi/TypeMismatchCheck.h @@ -1,9 +1,8 @@ //===--- TypeMismatchCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp index d5e2027a..eb18dcd2 100644 --- a/clang-tidy/objc/AvoidNSErrorInitCheck.cpp +++ b/clang-tidy/objc/AvoidNSErrorInitCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidNSErrorInitCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/AvoidNSErrorInitCheck.h b/clang-tidy/objc/AvoidNSErrorInitCheck.h index 379b8a2a..33deaba9 100644 --- a/clang-tidy/objc/AvoidNSErrorInitCheck.h +++ b/clang-tidy/objc/AvoidNSErrorInitCheck.h @@ -1,9 +1,8 @@ //===--- AvoidNSErrorInitCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/AvoidSpinlockCheck.cpp b/clang-tidy/objc/AvoidSpinlockCheck.cpp index 319d9456..ac3d2b28 100644 --- a/clang-tidy/objc/AvoidSpinlockCheck.cpp +++ b/clang-tidy/objc/AvoidSpinlockCheck.cpp @@ -1,9 +1,8 @@ //===--- AvoidSpinlockCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/AvoidSpinlockCheck.h b/clang-tidy/objc/AvoidSpinlockCheck.h index d9dbf8cb..2a3cd40d 100644 --- a/clang-tidy/objc/AvoidSpinlockCheck.h +++ b/clang-tidy/objc/AvoidSpinlockCheck.h @@ -1,9 +1,8 @@ //===--- AvoidSpinlockCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp index 0599b21d..6b8e7951 100644 --- a/clang-tidy/objc/ForbiddenSubclassingCheck.cpp +++ b/clang-tidy/objc/ForbiddenSubclassingCheck.cpp @@ -1,9 +1,8 @@ //===--- ForbiddenSubclassingCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/ForbiddenSubclassingCheck.h b/clang-tidy/objc/ForbiddenSubclassingCheck.h index 6c7e08b3..93ebc7e0 100644 --- a/clang-tidy/objc/ForbiddenSubclassingCheck.h +++ b/clang-tidy/objc/ForbiddenSubclassingCheck.h @@ -1,9 +1,8 @@ //===--- ForbiddenSubclassingCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/ObjCTidyModule.cpp b/clang-tidy/objc/ObjCTidyModule.cpp index 19152c21..5686c9fb 100644 --- a/clang-tidy/objc/ObjCTidyModule.cpp +++ b/clang-tidy/objc/ObjCTidyModule.cpp @@ -1,9 +1,8 @@ //===--- ObjCTidyModule.cpp - clang-tidy --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp index 94b82f00..653c6bb8 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -1,9 +1,8 @@ //===--- PropertyDeclarationCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h index b2683bae..d28bde40 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.h +++ b/clang-tidy/objc/PropertyDeclarationCheck.h @@ -1,9 +1,8 @@ //===--- PropertyDeclarationCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/FasterStringFindCheck.cpp b/clang-tidy/performance/FasterStringFindCheck.cpp index 0c3d249f..bb0a02f0 100644 --- a/clang-tidy/performance/FasterStringFindCheck.cpp +++ b/clang-tidy/performance/FasterStringFindCheck.cpp @@ -1,9 +1,8 @@ //===--- FasterStringFindCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/FasterStringFindCheck.h b/clang-tidy/performance/FasterStringFindCheck.h index ff666f2f..9b28e506 100644 --- a/clang-tidy/performance/FasterStringFindCheck.h +++ b/clang-tidy/performance/FasterStringFindCheck.h @@ -1,9 +1,8 @@ //===--- FasterStringFindCheck.h - clang-tidy--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/ForRangeCopyCheck.cpp b/clang-tidy/performance/ForRangeCopyCheck.cpp index 4b90df43..e0040094 100644 --- a/clang-tidy/performance/ForRangeCopyCheck.cpp +++ b/clang-tidy/performance/ForRangeCopyCheck.cpp @@ -1,9 +1,8 @@ //===--- ForRangeCopyCheck.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/ForRangeCopyCheck.h b/clang-tidy/performance/ForRangeCopyCheck.h index de8b2c91..6621f39a 100644 --- a/clang-tidy/performance/ForRangeCopyCheck.h +++ b/clang-tidy/performance/ForRangeCopyCheck.h @@ -1,9 +1,8 @@ //===--- ForRangeCopyCheck.h - clang-tidy------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp b/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp index 6e731190..e3b90d3b 100644 --- a/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp +++ b/clang-tidy/performance/ImplicitConversionInLoopCheck.cpp @@ -1,9 +1,8 @@ //===--- ImplicitConversionInLoopCheck.cpp - clang-tidy--------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/ImplicitConversionInLoopCheck.h b/clang-tidy/performance/ImplicitConversionInLoopCheck.h index 55cb84c3..3c27498a 100644 --- a/clang-tidy/performance/ImplicitConversionInLoopCheck.h +++ b/clang-tidy/performance/ImplicitConversionInLoopCheck.h @@ -1,9 +1,8 @@ //===--- ImplicitConversionInLoopCheck.h - clang-tidy------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/InefficientAlgorithmCheck.cpp b/clang-tidy/performance/InefficientAlgorithmCheck.cpp index 8cee2817..5ce5ffa0 100644 --- a/clang-tidy/performance/InefficientAlgorithmCheck.cpp +++ b/clang-tidy/performance/InefficientAlgorithmCheck.cpp @@ -1,9 +1,8 @@ //===--- InefficientAlgorithmCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/InefficientAlgorithmCheck.h b/clang-tidy/performance/InefficientAlgorithmCheck.h index 72506cf7..09e2c950 100644 --- a/clang-tidy/performance/InefficientAlgorithmCheck.h +++ b/clang-tidy/performance/InefficientAlgorithmCheck.h @@ -1,9 +1,8 @@ //===--- InefficientAlgorithmCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/InefficientStringConcatenationCheck.cpp b/clang-tidy/performance/InefficientStringConcatenationCheck.cpp index a17916d9..fe4b5a9e 100644 --- a/clang-tidy/performance/InefficientStringConcatenationCheck.cpp +++ b/clang-tidy/performance/InefficientStringConcatenationCheck.cpp @@ -1,9 +1,8 @@ //===--- InefficientStringConcatenationCheck.cpp - clang-tidy--------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/InefficientStringConcatenationCheck.h b/clang-tidy/performance/InefficientStringConcatenationCheck.h index 12a154c2..cfefa339 100644 --- a/clang-tidy/performance/InefficientStringConcatenationCheck.h +++ b/clang-tidy/performance/InefficientStringConcatenationCheck.h @@ -1,10 +1,9 @@ //===--- InefficientStringConcatenationCheck.h - clang-tidy-----------*- C++ //-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tidy/performance/InefficientVectorOperationCheck.cpp index 5b083761..622649ac 100644 --- a/clang-tidy/performance/InefficientVectorOperationCheck.cpp +++ b/clang-tidy/performance/InefficientVectorOperationCheck.cpp @@ -1,9 +1,8 @@ //===--- InefficientVectorOperationCheck.cpp - clang-tidy------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/InefficientVectorOperationCheck.h b/clang-tidy/performance/InefficientVectorOperationCheck.h index 1427ff13..c9785920 100644 --- a/clang-tidy/performance/InefficientVectorOperationCheck.h +++ b/clang-tidy/performance/InefficientVectorOperationCheck.h @@ -1,9 +1,8 @@ //===--- InefficientVectorOperationCheck.h - clang-tidy----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/MoveConstArgCheck.cpp b/clang-tidy/performance/MoveConstArgCheck.cpp index c64769f6..8b5838f9 100644 --- a/clang-tidy/performance/MoveConstArgCheck.cpp +++ b/clang-tidy/performance/MoveConstArgCheck.cpp @@ -1,9 +1,8 @@ //===--- MoveConstArgCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/MoveConstArgCheck.h b/clang-tidy/performance/MoveConstArgCheck.h index 13ed9aee..ec1b81be 100644 --- a/clang-tidy/performance/MoveConstArgCheck.h +++ b/clang-tidy/performance/MoveConstArgCheck.h @@ -1,9 +1,8 @@ //===--- MoveConstArgCheck.h - clang-tidy -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/MoveConstructorInitCheck.cpp b/clang-tidy/performance/MoveConstructorInitCheck.cpp index 52283fb2..abc5f4f2 100644 --- a/clang-tidy/performance/MoveConstructorInitCheck.cpp +++ b/clang-tidy/performance/MoveConstructorInitCheck.cpp @@ -1,9 +1,8 @@ //===--- MoveConstructorInitCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/MoveConstructorInitCheck.h b/clang-tidy/performance/MoveConstructorInitCheck.h index 3b7dda06..34a202e3 100644 --- a/clang-tidy/performance/MoveConstructorInitCheck.h +++ b/clang-tidy/performance/MoveConstructorInitCheck.h @@ -1,9 +1,8 @@ //===--- MoveConstructorInitCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp b/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp index adc5910b..0f9f8cba 100644 --- a/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp +++ b/clang-tidy/performance/NoexceptMoveConstructorCheck.cpp @@ -1,9 +1,8 @@ //===--- NoexceptMoveConstructorCheck.cpp - clang-tidy---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/NoexceptMoveConstructorCheck.h b/clang-tidy/performance/NoexceptMoveConstructorCheck.h index 9687ab1f..43a83459 100644 --- a/clang-tidy/performance/NoexceptMoveConstructorCheck.h +++ b/clang-tidy/performance/NoexceptMoveConstructorCheck.h @@ -1,9 +1,8 @@ //===--- NoexceptMoveConstructorCheck.h - clang-tidy-------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/PerformanceTidyModule.cpp b/clang-tidy/performance/PerformanceTidyModule.cpp index 646c6595..0a5a0be2 100644 --- a/clang-tidy/performance/PerformanceTidyModule.cpp +++ b/clang-tidy/performance/PerformanceTidyModule.cpp @@ -1,9 +1,8 @@ //===--- PeformanceTidyModule.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/TypePromotionInMathFnCheck.cpp b/clang-tidy/performance/TypePromotionInMathFnCheck.cpp index 8ff31a06..7b9b1f79 100644 --- a/clang-tidy/performance/TypePromotionInMathFnCheck.cpp +++ b/clang-tidy/performance/TypePromotionInMathFnCheck.cpp @@ -1,9 +1,8 @@ //===--- TypePromotionInMathFnCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/TypePromotionInMathFnCheck.h b/clang-tidy/performance/TypePromotionInMathFnCheck.h index 22429570..bb5900ae 100644 --- a/clang-tidy/performance/TypePromotionInMathFnCheck.h +++ b/clang-tidy/performance/TypePromotionInMathFnCheck.h @@ -1,9 +1,8 @@ //===--- TypePromotionInMathFnCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tidy/performance/UnnecessaryCopyInitialization.cpp index 6f310573..7e36b374 100644 --- a/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -1,9 +1,8 @@ //===--- UnnecessaryCopyInitialization.cpp - clang-tidy--------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/UnnecessaryCopyInitialization.h b/clang-tidy/performance/UnnecessaryCopyInitialization.h index 1844aa4b..bf785e6a 100644 --- a/clang-tidy/performance/UnnecessaryCopyInitialization.h +++ b/clang-tidy/performance/UnnecessaryCopyInitialization.h @@ -1,9 +1,8 @@ //===--- UnnecessaryCopyInitialization.h - clang-tidy------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/UnnecessaryValueParamCheck.cpp b/clang-tidy/performance/UnnecessaryValueParamCheck.cpp index ff3674fe..44f5fc20 100644 --- a/clang-tidy/performance/UnnecessaryValueParamCheck.cpp +++ b/clang-tidy/performance/UnnecessaryValueParamCheck.cpp @@ -1,9 +1,8 @@ //===--- UnnecessaryValueParamCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/performance/UnnecessaryValueParamCheck.h b/clang-tidy/performance/UnnecessaryValueParamCheck.h index a1d65869..84252edb 100644 --- a/clang-tidy/performance/UnnecessaryValueParamCheck.h +++ b/clang-tidy/performance/UnnecessaryValueParamCheck.h @@ -1,9 +1,8 @@ //===--- UnnecessaryValueParamCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/plugin/ClangTidyPlugin.cpp b/clang-tidy/plugin/ClangTidyPlugin.cpp index 561dc82d..80208c78 100644 --- a/clang-tidy/plugin/ClangTidyPlugin.cpp +++ b/clang-tidy/plugin/ClangTidyPlugin.cpp @@ -1,9 +1,8 @@ //===- ClangTidyPlugin.cpp - clang-tidy as a clang plugin -----------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/portability/PortabilityTidyModule.cpp b/clang-tidy/portability/PortabilityTidyModule.cpp index 013cbcfe..e12821e3 100644 --- a/clang-tidy/portability/PortabilityTidyModule.cpp +++ b/clang-tidy/portability/PortabilityTidyModule.cpp @@ -1,9 +1,8 @@ //===--- PortabilityTidyModule.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/portability/SIMDIntrinsicsCheck.cpp b/clang-tidy/portability/SIMDIntrinsicsCheck.cpp index e104368f..d9e3d263 100644 --- a/clang-tidy/portability/SIMDIntrinsicsCheck.cpp +++ b/clang-tidy/portability/SIMDIntrinsicsCheck.cpp @@ -1,9 +1,8 @@ //===--- SIMDIntrinsicsCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/portability/SIMDIntrinsicsCheck.h b/clang-tidy/portability/SIMDIntrinsicsCheck.h index ebcc8554..9d5cb557 100644 --- a/clang-tidy/portability/SIMDIntrinsicsCheck.h +++ b/clang-tidy/portability/SIMDIntrinsicsCheck.h @@ -1,9 +1,8 @@ //===--- SIMDIntrinsicsCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/AvoidConstParamsInDecls.cpp b/clang-tidy/readability/AvoidConstParamsInDecls.cpp index 51fc4895..91e1495e 100644 --- a/clang-tidy/readability/AvoidConstParamsInDecls.cpp +++ b/clang-tidy/readability/AvoidConstParamsInDecls.cpp @@ -1,9 +1,8 @@ //===--- AvoidConstParamsInDecls.cpp - clang-tidy--------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/AvoidConstParamsInDecls.h b/clang-tidy/readability/AvoidConstParamsInDecls.h index f2d91e82..c8b96b65 100644 --- a/clang-tidy/readability/AvoidConstParamsInDecls.h +++ b/clang-tidy/readability/AvoidConstParamsInDecls.h @@ -1,9 +1,8 @@ //===--- AvoidConstParamsInDecls.h - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/BracesAroundStatementsCheck.cpp b/clang-tidy/readability/BracesAroundStatementsCheck.cpp index 5f5294c2..117ef36d 100644 --- a/clang-tidy/readability/BracesAroundStatementsCheck.cpp +++ b/clang-tidy/readability/BracesAroundStatementsCheck.cpp @@ -1,9 +1,8 @@ //===--- BracesAroundStatementsCheck.cpp - clang-tidy ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/BracesAroundStatementsCheck.h b/clang-tidy/readability/BracesAroundStatementsCheck.h index 919ca463..fb45def3 100644 --- a/clang-tidy/readability/BracesAroundStatementsCheck.h +++ b/clang-tidy/readability/BracesAroundStatementsCheck.h @@ -1,9 +1,8 @@ //===--- BracesAroundStatementsCheck.h - clang-tidy -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ConstReturnTypeCheck.cpp b/clang-tidy/readability/ConstReturnTypeCheck.cpp index d9654df4..9d936d8a 100644 --- a/clang-tidy/readability/ConstReturnTypeCheck.cpp +++ b/clang-tidy/readability/ConstReturnTypeCheck.cpp @@ -1,9 +1,8 @@ //===--- ConstReturnTypeCheck.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ConstReturnTypeCheck.h b/clang-tidy/readability/ConstReturnTypeCheck.h index 2c7e94de..58ebc552 100644 --- a/clang-tidy/readability/ConstReturnTypeCheck.h +++ b/clang-tidy/readability/ConstReturnTypeCheck.h @@ -1,9 +1,8 @@ //===--- ConstReturnTypeCheck.h - clang-tidy --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ContainerSizeEmptyCheck.cpp b/clang-tidy/readability/ContainerSizeEmptyCheck.cpp index 97f9eb71..fe0e1c0a 100644 --- a/clang-tidy/readability/ContainerSizeEmptyCheck.cpp +++ b/clang-tidy/readability/ContainerSizeEmptyCheck.cpp @@ -1,9 +1,8 @@ //===--- ContainerSizeEmptyCheck.cpp - clang-tidy -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "ContainerSizeEmptyCheck.h" diff --git a/clang-tidy/readability/ContainerSizeEmptyCheck.h b/clang-tidy/readability/ContainerSizeEmptyCheck.h index bde83f88..3d8615b0 100644 --- a/clang-tidy/readability/ContainerSizeEmptyCheck.h +++ b/clang-tidy/readability/ContainerSizeEmptyCheck.h @@ -1,9 +1,8 @@ //===--- ContainerSizeEmptyCheck.h - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/DeleteNullPointerCheck.cpp b/clang-tidy/readability/DeleteNullPointerCheck.cpp index 02b9bbe8..0c5eacef 100644 --- a/clang-tidy/readability/DeleteNullPointerCheck.cpp +++ b/clang-tidy/readability/DeleteNullPointerCheck.cpp @@ -1,9 +1,8 @@ //===--- DeleteNullPointerCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/DeleteNullPointerCheck.h b/clang-tidy/readability/DeleteNullPointerCheck.h index 501f6f7d..f877322b 100644 --- a/clang-tidy/readability/DeleteNullPointerCheck.h +++ b/clang-tidy/readability/DeleteNullPointerCheck.h @@ -1,9 +1,8 @@ //===--- DeleteNullPointerCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/DeletedDefaultCheck.cpp b/clang-tidy/readability/DeletedDefaultCheck.cpp index e99ca837..ff2f00b9 100644 --- a/clang-tidy/readability/DeletedDefaultCheck.cpp +++ b/clang-tidy/readability/DeletedDefaultCheck.cpp @@ -1,9 +1,8 @@ //===--- DeletedDefaultCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/DeletedDefaultCheck.h b/clang-tidy/readability/DeletedDefaultCheck.h index 0608b07b..5acf6e28 100644 --- a/clang-tidy/readability/DeletedDefaultCheck.h +++ b/clang-tidy/readability/DeletedDefaultCheck.h @@ -1,9 +1,8 @@ //===--- DeletedDefaultCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tidy/readability/ElseAfterReturnCheck.cpp index 55669b2a..312debbb 100644 --- a/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ b/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -1,9 +1,8 @@ //===--- ElseAfterReturnCheck.cpp - clang-tidy-----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ElseAfterReturnCheck.h b/clang-tidy/readability/ElseAfterReturnCheck.h index 8479ab50..2feb3aa1 100644 --- a/clang-tidy/readability/ElseAfterReturnCheck.h +++ b/clang-tidy/readability/ElseAfterReturnCheck.h @@ -1,9 +1,8 @@ //===--- ElseAfterReturnCheck.h - clang-tidy---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tidy/readability/FunctionSizeCheck.cpp index 4d91f2e7..7be502bf 100644 --- a/clang-tidy/readability/FunctionSizeCheck.cpp +++ b/clang-tidy/readability/FunctionSizeCheck.cpp @@ -1,9 +1,8 @@ //===--- FunctionSize.cpp - clang-tidy ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/FunctionSizeCheck.h b/clang-tidy/readability/FunctionSizeCheck.h index 7defccdb..33340e60 100644 --- a/clang-tidy/readability/FunctionSizeCheck.h +++ b/clang-tidy/readability/FunctionSizeCheck.h @@ -1,9 +1,8 @@ //===--- FunctionSizeCheck.h - clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tidy/readability/IdentifierNamingCheck.cpp index fb3c02e1..56ece5c6 100644 --- a/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -1,9 +1,8 @@ //===--- IdentifierNamingCheck.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/IdentifierNamingCheck.h b/clang-tidy/readability/IdentifierNamingCheck.h index c236ad52..0023a6fa 100644 --- a/clang-tidy/readability/IdentifierNamingCheck.h +++ b/clang-tidy/readability/IdentifierNamingCheck.h @@ -1,9 +1,8 @@ //===--- IdentifierNamingCheck.h - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tidy/readability/ImplicitBoolConversionCheck.cpp index b8ae224b..aae5bcff 100644 --- a/clang-tidy/readability/ImplicitBoolConversionCheck.cpp +++ b/clang-tidy/readability/ImplicitBoolConversionCheck.cpp @@ -1,9 +1,8 @@ //===--- ImplicitBoolConversionCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tidy/readability/ImplicitBoolConversionCheck.h index bb062e02..91d14a73 100644 --- a/clang-tidy/readability/ImplicitBoolConversionCheck.h +++ b/clang-tidy/readability/ImplicitBoolConversionCheck.h @@ -1,9 +1,8 @@ //===--- ImplicitBoolConversionCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp index 280c354f..64a955f6 100644 --- a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp +++ b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.cpp @@ -1,9 +1,8 @@ //===--- InconsistentDeclarationParameterNameCheck.cpp - clang-tidy-------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h index 602856fa..2002b091 100644 --- a/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h +++ b/clang-tidy/readability/InconsistentDeclarationParameterNameCheck.h @@ -1,9 +1,8 @@ //===- InconsistentDeclarationParameterNameCheck.h - clang-tidy-*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/IsolateDeclarationCheck.cpp b/clang-tidy/readability/IsolateDeclarationCheck.cpp index e9ccb17b..32177adf 100644 --- a/clang-tidy/readability/IsolateDeclarationCheck.cpp +++ b/clang-tidy/readability/IsolateDeclarationCheck.cpp @@ -1,9 +1,8 @@ //===--- IsolateDeclarationCheck.cpp - clang-tidy -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/IsolateDeclarationCheck.h b/clang-tidy/readability/IsolateDeclarationCheck.h index b7f4793d..a172d214 100644 --- a/clang-tidy/readability/IsolateDeclarationCheck.h +++ b/clang-tidy/readability/IsolateDeclarationCheck.h @@ -1,9 +1,8 @@ //===--- IsolateDeclarationCheck.h - clang-tidy -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/MagicNumbersCheck.cpp b/clang-tidy/readability/MagicNumbersCheck.cpp index 0a087219..39aaf899 100644 --- a/clang-tidy/readability/MagicNumbersCheck.cpp +++ b/clang-tidy/readability/MagicNumbersCheck.cpp @@ -1,9 +1,8 @@ //===--- MagicNumbersCheck.cpp - clang-tidy-------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-tidy/readability/MagicNumbersCheck.h b/clang-tidy/readability/MagicNumbersCheck.h index db4cc886..1ec9db25 100644 --- a/clang-tidy/readability/MagicNumbersCheck.h +++ b/clang-tidy/readability/MagicNumbersCheck.h @@ -1,9 +1,8 @@ //===--- MagicNumbersCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/MisleadingIndentationCheck.cpp b/clang-tidy/readability/MisleadingIndentationCheck.cpp index 9791531f..767406e3 100644 --- a/clang-tidy/readability/MisleadingIndentationCheck.cpp +++ b/clang-tidy/readability/MisleadingIndentationCheck.cpp @@ -1,9 +1,8 @@ //===--- MisleadingIndentationCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/MisleadingIndentationCheck.h b/clang-tidy/readability/MisleadingIndentationCheck.h index 0ca50bb0..c39212a4 100644 --- a/clang-tidy/readability/MisleadingIndentationCheck.h +++ b/clang-tidy/readability/MisleadingIndentationCheck.h @@ -1,9 +1,8 @@ //===--- MisleadingIndentationCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/MisplacedArrayIndexCheck.cpp b/clang-tidy/readability/MisplacedArrayIndexCheck.cpp index 3d1971be..7b39012b 100644 --- a/clang-tidy/readability/MisplacedArrayIndexCheck.cpp +++ b/clang-tidy/readability/MisplacedArrayIndexCheck.cpp @@ -1,9 +1,8 @@ //===--- MisplacedArrayIndexCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/MisplacedArrayIndexCheck.h b/clang-tidy/readability/MisplacedArrayIndexCheck.h index e9a22314..55bab95c 100644 --- a/clang-tidy/readability/MisplacedArrayIndexCheck.h +++ b/clang-tidy/readability/MisplacedArrayIndexCheck.h @@ -1,9 +1,8 @@ //===--- MisplacedArrayIndexCheck.h - clang-tidy-----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/NamedParameterCheck.cpp b/clang-tidy/readability/NamedParameterCheck.cpp index 6fa9e68f..09b03fe7 100644 --- a/clang-tidy/readability/NamedParameterCheck.cpp +++ b/clang-tidy/readability/NamedParameterCheck.cpp @@ -1,9 +1,8 @@ //===--- NamedParameterCheck.cpp - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/NamedParameterCheck.h b/clang-tidy/readability/NamedParameterCheck.h index bd38ad2f..f783c583 100644 --- a/clang-tidy/readability/NamedParameterCheck.h +++ b/clang-tidy/readability/NamedParameterCheck.h @@ -1,9 +1,8 @@ //===--- NamedParameterCheck.h - clang-tidy ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/NamespaceCommentCheck.cpp b/clang-tidy/readability/NamespaceCommentCheck.cpp index 229cc626..17184ec2 100644 --- a/clang-tidy/readability/NamespaceCommentCheck.cpp +++ b/clang-tidy/readability/NamespaceCommentCheck.cpp @@ -1,9 +1,8 @@ //===--- NamespaceCommentCheck.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/NamespaceCommentCheck.h b/clang-tidy/readability/NamespaceCommentCheck.h index 1b1a2315..8fb32758 100644 --- a/clang-tidy/readability/NamespaceCommentCheck.h +++ b/clang-tidy/readability/NamespaceCommentCheck.h @@ -1,9 +1,8 @@ //===--- NamespaceCommentCheck.h - clang-tidy -------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/NonConstParameterCheck.cpp b/clang-tidy/readability/NonConstParameterCheck.cpp index e33191cf..4372e74c 100644 --- a/clang-tidy/readability/NonConstParameterCheck.cpp +++ b/clang-tidy/readability/NonConstParameterCheck.cpp @@ -1,9 +1,8 @@ //===--- NonConstParameterCheck.cpp - clang-tidy---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/NonConstParameterCheck.h b/clang-tidy/readability/NonConstParameterCheck.h index 3cc73e90..74634c21 100644 --- a/clang-tidy/readability/NonConstParameterCheck.h +++ b/clang-tidy/readability/NonConstParameterCheck.h @@ -1,9 +1,8 @@ //===--- NonConstParameterCheck.h - clang-tidy-------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tidy/readability/ReadabilityTidyModule.cpp index e032d1f6..5b2aed42 100644 --- a/clang-tidy/readability/ReadabilityTidyModule.cpp +++ b/clang-tidy/readability/ReadabilityTidyModule.cpp @@ -1,9 +1,8 @@ //===--- ReadabilityTidyModule.cpp - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantControlFlowCheck.cpp b/clang-tidy/readability/RedundantControlFlowCheck.cpp index d5898ed9..003c05f8 100644 --- a/clang-tidy/readability/RedundantControlFlowCheck.cpp +++ b/clang-tidy/readability/RedundantControlFlowCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantControlFlowCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantControlFlowCheck.h b/clang-tidy/readability/RedundantControlFlowCheck.h index 4b8b6fbf..19433984 100644 --- a/clang-tidy/readability/RedundantControlFlowCheck.h +++ b/clang-tidy/readability/RedundantControlFlowCheck.h @@ -1,9 +1,8 @@ //===--- RedundantControlFlowCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantDeclarationCheck.cpp b/clang-tidy/readability/RedundantDeclarationCheck.cpp index c5b6cc32..ff3809a2 100644 --- a/clang-tidy/readability/RedundantDeclarationCheck.cpp +++ b/clang-tidy/readability/RedundantDeclarationCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantDeclarationCheck.cpp - clang-tidy------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantDeclarationCheck.h b/clang-tidy/readability/RedundantDeclarationCheck.h index 9be79b84..5286bff4 100644 --- a/clang-tidy/readability/RedundantDeclarationCheck.h +++ b/clang-tidy/readability/RedundantDeclarationCheck.h @@ -1,9 +1,8 @@ //===--- RedundantDeclarationCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp index fa503c57..f2360a09 100644 --- a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp +++ b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantFunctionPtrDereferenceCheck.cpp - clang-tidy-------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h index 4cf6d112..19db1d34 100644 --- a/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h +++ b/clang-tidy/readability/RedundantFunctionPtrDereferenceCheck.h @@ -1,9 +1,8 @@ //===--- RedundantFunctionPtrDereferenceCheck.h - clang-tidy-----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantMemberInitCheck.cpp b/clang-tidy/readability/RedundantMemberInitCheck.cpp index 8409f9f4..d38d0a23 100644 --- a/clang-tidy/readability/RedundantMemberInitCheck.cpp +++ b/clang-tidy/readability/RedundantMemberInitCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantMemberInitCheck.cpp - clang-tidy-------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantMemberInitCheck.h b/clang-tidy/readability/RedundantMemberInitCheck.h index 13cc9d3a..f4c4c097 100644 --- a/clang-tidy/readability/RedundantMemberInitCheck.h +++ b/clang-tidy/readability/RedundantMemberInitCheck.h @@ -1,9 +1,8 @@ //===--- RedundantMemberInitCheck.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantPreprocessorCheck.cpp b/clang-tidy/readability/RedundantPreprocessorCheck.cpp index 352e2346..e208c58e 100644 --- a/clang-tidy/readability/RedundantPreprocessorCheck.cpp +++ b/clang-tidy/readability/RedundantPreprocessorCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantPreprocessorCheck.cpp - clang-tidy ----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantPreprocessorCheck.h b/clang-tidy/readability/RedundantPreprocessorCheck.h index d4407656..cb70ac7c 100644 --- a/clang-tidy/readability/RedundantPreprocessorCheck.h +++ b/clang-tidy/readability/RedundantPreprocessorCheck.h @@ -1,9 +1,8 @@ //===--- RedundantPreprocessorCheck.h - clang-tidy --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantSmartptrGetCheck.cpp b/clang-tidy/readability/RedundantSmartptrGetCheck.cpp index 189130ef..73157c9e 100644 --- a/clang-tidy/readability/RedundantSmartptrGetCheck.cpp +++ b/clang-tidy/readability/RedundantSmartptrGetCheck.cpp @@ -1,9 +1,8 @@ //===--- RedundantSmartptrGetCheck.cpp - clang-tidy -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantSmartptrGetCheck.h b/clang-tidy/readability/RedundantSmartptrGetCheck.h index a6f5706c..d4d311ff 100644 --- a/clang-tidy/readability/RedundantSmartptrGetCheck.h +++ b/clang-tidy/readability/RedundantSmartptrGetCheck.h @@ -1,9 +1,8 @@ //===--- RedundantSmartptrGetCheck.h - clang-tidy ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tidy/readability/RedundantStringCStrCheck.cpp index 903a0ed1..f7b0dfc4 100644 --- a/clang-tidy/readability/RedundantStringCStrCheck.cpp +++ b/clang-tidy/readability/RedundantStringCStrCheck.cpp @@ -1,9 +1,8 @@ //===- RedundantStringCStrCheck.cpp - Check for redundant c_str calls -----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clang-tidy/readability/RedundantStringCStrCheck.h b/clang-tidy/readability/RedundantStringCStrCheck.h index 9406f8ea..dd53e181 100644 --- a/clang-tidy/readability/RedundantStringCStrCheck.h +++ b/clang-tidy/readability/RedundantStringCStrCheck.h @@ -1,9 +1,8 @@ //===--- RedundantStringCStrCheck.h - clang-tidy ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantStringInitCheck.cpp b/clang-tidy/readability/RedundantStringInitCheck.cpp index 46ce2a47..9a9a3830 100644 --- a/clang-tidy/readability/RedundantStringInitCheck.cpp +++ b/clang-tidy/readability/RedundantStringInitCheck.cpp @@ -1,9 +1,8 @@ //===- RedundantStringInitCheck.cpp - clang-tidy ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/RedundantStringInitCheck.h b/clang-tidy/readability/RedundantStringInitCheck.h index 0a32eb6d..38399ed9 100644 --- a/clang-tidy/readability/RedundantStringInitCheck.h +++ b/clang-tidy/readability/RedundantStringInitCheck.h @@ -1,9 +1,8 @@ //===- RedundantStringInitCheck.h - clang-tidy ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp index 710635ee..aa58ad11 100644 --- a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp +++ b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp @@ -1,9 +1,8 @@ //===--- SimplifyBooleanExpr.cpp clang-tidy ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.h b/clang-tidy/readability/SimplifyBooleanExprCheck.h index af47453f..dc1daa27 100644 --- a/clang-tidy/readability/SimplifyBooleanExprCheck.h +++ b/clang-tidy/readability/SimplifyBooleanExprCheck.h @@ -1,9 +1,8 @@ //===--- SimplifyBooleanExpr.h clang-tidy -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/SimplifySubscriptExprCheck.cpp b/clang-tidy/readability/SimplifySubscriptExprCheck.cpp index f4c306e9..ec060f86 100644 --- a/clang-tidy/readability/SimplifySubscriptExprCheck.cpp +++ b/clang-tidy/readability/SimplifySubscriptExprCheck.cpp @@ -1,9 +1,8 @@ //===--- SimplifySubscriptExprCheck.cpp - clang-tidy-----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/SimplifySubscriptExprCheck.h b/clang-tidy/readability/SimplifySubscriptExprCheck.h index 86a21b91..2929fbe5 100644 --- a/clang-tidy/readability/SimplifySubscriptExprCheck.h +++ b/clang-tidy/readability/SimplifySubscriptExprCheck.h @@ -1,9 +1,8 @@ //===--- SimplifySubscriptExprCheck.h - clang-tidy---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp index 92d78796..8458fe3c 100644 --- a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp +++ b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp @@ -1,9 +1,8 @@ //===--- StaticAccessedThroughInstanceCheck.cpp - clang-tidy---------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h index c2eebabe..d01d8ac8 100644 --- a/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h +++ b/clang-tidy/readability/StaticAccessedThroughInstanceCheck.h @@ -1,9 +1,8 @@ //===--- StaticAccessedThroughInstanceCheck.h - clang-tidy-------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp index 05546052..ef973a19 100644 --- a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp +++ b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.cpp @@ -1,9 +1,8 @@ //===--- StaticDefinitionInAnonymousNamespaceCheck.cpp - clang-tidy--------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h index 03e99fd0..12601979 100644 --- a/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h +++ b/clang-tidy/readability/StaticDefinitionInAnonymousNamespaceCheck.h @@ -1,9 +1,8 @@ //===--- StaticDefinitionInAnonymousNamespaceCheck.h - clang-tidy*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/StringCompareCheck.cpp b/clang-tidy/readability/StringCompareCheck.cpp index 38ac43f2..395f406a 100644 --- a/clang-tidy/readability/StringCompareCheck.cpp +++ b/clang-tidy/readability/StringCompareCheck.cpp @@ -1,9 +1,8 @@ //===--- MiscStringCompare.cpp - clang-tidy--------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/StringCompareCheck.h b/clang-tidy/readability/StringCompareCheck.h index 248d2ee8..39e5bd52 100644 --- a/clang-tidy/readability/StringCompareCheck.h +++ b/clang-tidy/readability/StringCompareCheck.h @@ -1,9 +1,8 @@ //===--- StringCompareCheck.h - clang-tidy-----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp index bb2c6901..478a3f2f 100644 --- a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp +++ b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.cpp @@ -1,9 +1,8 @@ //===--- UniqueptrDeleteReleaseCheck.cpp - clang-tidy----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h index fd86bdb9..492c642a 100644 --- a/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h +++ b/clang-tidy/readability/UniqueptrDeleteReleaseCheck.h @@ -1,9 +1,8 @@ //===--- UniqueptrDeleteReleaseCheck.h - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp b/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp index 588fb261..eef63b7e 100644 --- a/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp +++ b/clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp @@ -1,9 +1,8 @@ //===--- UppercaseLiteralSuffixCheck.cpp - clang-tidy ---------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/readability/UppercaseLiteralSuffixCheck.h b/clang-tidy/readability/UppercaseLiteralSuffixCheck.h index 7aa631ae..69ddd63e 100644 --- a/clang-tidy/readability/UppercaseLiteralSuffixCheck.h +++ b/clang-tidy/readability/UppercaseLiteralSuffixCheck.h @@ -1,9 +1,8 @@ //===--- UppercaseLiteralSuffixCheck.h - clang-tidy -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/rename_check.py b/clang-tidy/rename_check.py index 53a5ff92..4eb3d740 100755 --- a/clang-tidy/rename_check.py +++ b/clang-tidy/rename_check.py @@ -2,10 +2,9 @@ # #===- rename_check.py - clang-tidy check renamer -------------*- python -*--===# # -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# 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 # #===------------------------------------------------------------------------===# diff --git a/clang-tidy/tool/ClangTidyMain.cpp b/clang-tidy/tool/ClangTidyMain.cpp index 12a60244..469f360d 100644 --- a/clang-tidy/tool/ClangTidyMain.cpp +++ b/clang-tidy/tool/ClangTidyMain.cpp @@ -1,9 +1,8 @@ //===--- tools/extra/clang-tidy/ClangTidyMain.cpp - Clang tidy tool -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clang-tidy/tool/clang-tidy-diff.py b/clang-tidy/tool/clang-tidy-diff.py index 5eb2e3d6..cf6db4a7 100755 --- a/clang-tidy/tool/clang-tidy-diff.py +++ b/clang-tidy/tool/clang-tidy-diff.py @@ -2,10 +2,9 @@ # #===- clang-tidy-diff.py - ClangTidy Diff Checker ------------*- python -*--===# # -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# 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 # #===------------------------------------------------------------------------===# diff --git a/clang-tidy/tool/run-clang-tidy.py b/clang-tidy/tool/run-clang-tidy.py index 93635cbe..5ec40f20 100755 --- a/clang-tidy/tool/run-clang-tidy.py +++ b/clang-tidy/tool/run-clang-tidy.py @@ -2,10 +2,9 @@ # #===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===# # -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# 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 # #===------------------------------------------------------------------------===# # FIXME: Integrate with clang-tidy-diff.py diff --git a/clang-tidy/utils/ASTUtils.cpp b/clang-tidy/utils/ASTUtils.cpp index 3c0427fd..9b8eca13 100644 --- a/clang-tidy/utils/ASTUtils.cpp +++ b/clang-tidy/utils/ASTUtils.cpp @@ -1,9 +1,8 @@ //===---------- ASTUtils.cpp - clang-tidy ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/ASTUtils.h b/clang-tidy/utils/ASTUtils.h index 4196eeb9..ad2a055f 100644 --- a/clang-tidy/utils/ASTUtils.h +++ b/clang-tidy/utils/ASTUtils.h @@ -1,9 +1,8 @@ //===---------- ASTUtils.h - clang-tidy -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/DeclRefExprUtils.cpp b/clang-tidy/utils/DeclRefExprUtils.cpp index 06acd310..628b8506 100644 --- a/clang-tidy/utils/DeclRefExprUtils.cpp +++ b/clang-tidy/utils/DeclRefExprUtils.cpp @@ -1,9 +1,8 @@ //===--- DeclRefExprUtils.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/DeclRefExprUtils.h b/clang-tidy/utils/DeclRefExprUtils.h index c25102f8..2cf8eddc 100644 --- a/clang-tidy/utils/DeclRefExprUtils.h +++ b/clang-tidy/utils/DeclRefExprUtils.h @@ -1,9 +1,8 @@ //===--- DeclRefExprUtils.h - clang-tidy-------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/ExprSequence.cpp b/clang-tidy/utils/ExprSequence.cpp index c3602ff8..0a1558e1 100644 --- a/clang-tidy/utils/ExprSequence.cpp +++ b/clang-tidy/utils/ExprSequence.cpp @@ -1,9 +1,8 @@ //===---------- ExprSequence.cpp - clang-tidy -----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/ExprSequence.h b/clang-tidy/utils/ExprSequence.h index 0868a899..7bb87ad8 100644 --- a/clang-tidy/utils/ExprSequence.h +++ b/clang-tidy/utils/ExprSequence.h @@ -1,9 +1,8 @@ //===------------- ExprSequence.h - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/FixItHintUtils.cpp b/clang-tidy/utils/FixItHintUtils.cpp index 9da93653..c30a59e9 100644 --- a/clang-tidy/utils/FixItHintUtils.cpp +++ b/clang-tidy/utils/FixItHintUtils.cpp @@ -1,9 +1,8 @@ //===--- FixItHintUtils.cpp - clang-tidy-----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/FixItHintUtils.h b/clang-tidy/utils/FixItHintUtils.h index e64a6e41..28bbb12c 100644 --- a/clang-tidy/utils/FixItHintUtils.h +++ b/clang-tidy/utils/FixItHintUtils.h @@ -1,9 +1,8 @@ //===--- FixItHintUtils.h - clang-tidy---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/HeaderFileExtensionsUtils.cpp b/clang-tidy/utils/HeaderFileExtensionsUtils.cpp index b734b897..0215b2f4 100644 --- a/clang-tidy/utils/HeaderFileExtensionsUtils.cpp +++ b/clang-tidy/utils/HeaderFileExtensionsUtils.cpp @@ -1,9 +1,8 @@ //===--- HeaderFileExtensionsUtils.cpp - clang-tidy--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/HeaderFileExtensionsUtils.h b/clang-tidy/utils/HeaderFileExtensionsUtils.h index 20120171..5a132e66 100644 --- a/clang-tidy/utils/HeaderFileExtensionsUtils.h +++ b/clang-tidy/utils/HeaderFileExtensionsUtils.h @@ -1,9 +1,8 @@ //===--- HeaderFileExtensionsUtils.h - clang-tidy----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/HeaderGuard.cpp b/clang-tidy/utils/HeaderGuard.cpp index 515f8821..cc56b3f5 100644 --- a/clang-tidy/utils/HeaderGuard.cpp +++ b/clang-tidy/utils/HeaderGuard.cpp @@ -1,9 +1,8 @@ //===--- HeaderGuard.cpp - clang-tidy -------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/HeaderGuard.h b/clang-tidy/utils/HeaderGuard.h index a2d8288e..f2062e52 100644 --- a/clang-tidy/utils/HeaderGuard.h +++ b/clang-tidy/utils/HeaderGuard.h @@ -1,9 +1,8 @@ //===--- HeaderGuard.h - clang-tidy -----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/IncludeInserter.cpp b/clang-tidy/utils/IncludeInserter.cpp index 64e4213c..6b366cf2 100644 --- a/clang-tidy/utils/IncludeInserter.cpp +++ b/clang-tidy/utils/IncludeInserter.cpp @@ -1,9 +1,8 @@ //===-------- IncludeInserter.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/IncludeInserter.h b/clang-tidy/utils/IncludeInserter.h index 9578649d..a56b5ab5 100644 --- a/clang-tidy/utils/IncludeInserter.h +++ b/clang-tidy/utils/IncludeInserter.h @@ -1,9 +1,8 @@ //===---------- IncludeInserter.h - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/IncludeSorter.cpp b/clang-tidy/utils/IncludeSorter.cpp index 1502da76..9d792272 100644 --- a/clang-tidy/utils/IncludeSorter.cpp +++ b/clang-tidy/utils/IncludeSorter.cpp @@ -1,9 +1,8 @@ //===---------- IncludeSorter.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/IncludeSorter.h b/clang-tidy/utils/IncludeSorter.h index 07fa293d..9c07274a 100644 --- a/clang-tidy/utils/IncludeSorter.h +++ b/clang-tidy/utils/IncludeSorter.h @@ -1,9 +1,8 @@ //===------------ IncludeSorter.h - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/LexerUtils.cpp b/clang-tidy/utils/LexerUtils.cpp index edd4cd62..a6e361d6 100644 --- a/clang-tidy/utils/LexerUtils.cpp +++ b/clang-tidy/utils/LexerUtils.cpp @@ -1,9 +1,8 @@ //===--- LexerUtils.cpp - clang-tidy---------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/LexerUtils.h b/clang-tidy/utils/LexerUtils.h index 55a8b85c..06a03b6e 100644 --- a/clang-tidy/utils/LexerUtils.h +++ b/clang-tidy/utils/LexerUtils.h @@ -1,9 +1,8 @@ //===--- LexerUtils.h - clang-tidy-------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/Matchers.h b/clang-tidy/utils/Matchers.h index 849b36fb..dbb72c9d 100644 --- a/clang-tidy/utils/Matchers.h +++ b/clang-tidy/utils/Matchers.h @@ -1,9 +1,8 @@ //===--- Matchers.h - clang-tidy-------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/NamespaceAliaser.cpp b/clang-tidy/utils/NamespaceAliaser.cpp index 25182304..fe99e684 100644 --- a/clang-tidy/utils/NamespaceAliaser.cpp +++ b/clang-tidy/utils/NamespaceAliaser.cpp @@ -1,9 +1,8 @@ //===---------- NamespaceAliaser.cpp - clang-tidy -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/NamespaceAliaser.h b/clang-tidy/utils/NamespaceAliaser.h index e56d69d3..ab1b9781 100644 --- a/clang-tidy/utils/NamespaceAliaser.h +++ b/clang-tidy/utils/NamespaceAliaser.h @@ -1,9 +1,8 @@ //===---------- NamespaceAliaser.h - clang-tidy ---------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/OptionsUtils.cpp b/clang-tidy/utils/OptionsUtils.cpp index 0b1d27d5..30b76643 100644 --- a/clang-tidy/utils/OptionsUtils.cpp +++ b/clang-tidy/utils/OptionsUtils.cpp @@ -1,9 +1,8 @@ //===--- DanglingHandleCheck.cpp - clang-tidy------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/OptionsUtils.h b/clang-tidy/utils/OptionsUtils.h index d822ac98..26b82e9d 100644 --- a/clang-tidy/utils/OptionsUtils.h +++ b/clang-tidy/utils/OptionsUtils.h @@ -1,9 +1,8 @@ //===--- DanglingHandleCheck.h - clang-tidy----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/TypeTraits.cpp b/clang-tidy/utils/TypeTraits.cpp index 2cdc5064..954a288e 100644 --- a/clang-tidy/utils/TypeTraits.cpp +++ b/clang-tidy/utils/TypeTraits.cpp @@ -1,9 +1,8 @@ //===--- TypeTraits.cpp - clang-tidy---------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/TypeTraits.h b/clang-tidy/utils/TypeTraits.h index ae0b3f0f..6102c288 100644 --- a/clang-tidy/utils/TypeTraits.h +++ b/clang-tidy/utils/TypeTraits.h @@ -1,9 +1,8 @@ //===--- TypeTraits.h - clang-tidy-------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/UsingInserter.cpp b/clang-tidy/utils/UsingInserter.cpp index e479d591..e852532a 100644 --- a/clang-tidy/utils/UsingInserter.cpp +++ b/clang-tidy/utils/UsingInserter.cpp @@ -1,9 +1,8 @@ //===---------- UsingInserter.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/utils/UsingInserter.h b/clang-tidy/utils/UsingInserter.h index 62108e41..9d3c60ca 100644 --- a/clang-tidy/utils/UsingInserter.h +++ b/clang-tidy/utils/UsingInserter.h @@ -1,9 +1,8 @@ //===---------- UsingInserter.h - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/zircon/TemporaryObjectsCheck.cpp b/clang-tidy/zircon/TemporaryObjectsCheck.cpp index be2fb835..d3fac14f 100644 --- a/clang-tidy/zircon/TemporaryObjectsCheck.cpp +++ b/clang-tidy/zircon/TemporaryObjectsCheck.cpp @@ -1,9 +1,8 @@ //===--- TemporaryObjectsCheck.cpp - clang-tidy----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/zircon/TemporaryObjectsCheck.h b/clang-tidy/zircon/TemporaryObjectsCheck.h index 302ef72a..ae06601b 100644 --- a/clang-tidy/zircon/TemporaryObjectsCheck.h +++ b/clang-tidy/zircon/TemporaryObjectsCheck.h @@ -1,9 +1,8 @@ //===--- TemporaryObjectsCheck.h - clang-tidy------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clang-tidy/zircon/ZirconTidyModule.cpp b/clang-tidy/zircon/ZirconTidyModule.cpp index 3e53c23a..94bbd27a 100644 --- a/clang-tidy/zircon/ZirconTidyModule.cpp +++ b/clang-tidy/zircon/ZirconTidyModule.cpp @@ -1,9 +1,8 @@ //===--- ZirconTidyModule.cpp - clang-tidy---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/AST.cpp b/clangd/AST.cpp index a185a6d8..47559c10 100644 --- a/clangd/AST.cpp +++ b/clangd/AST.cpp @@ -1,9 +1,8 @@ //===--- AST.cpp - Utility AST functions -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/AST.h b/clangd/AST.h index 85eb47c4..15c46a4f 100644 --- a/clangd/AST.h +++ b/clangd/AST.h @@ -1,9 +1,8 @@ //===--- AST.h - Utility AST functions -------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Cancellation.cpp b/clangd/Cancellation.cpp index cc1c11ce..6b0e21d3 100644 --- a/clangd/Cancellation.cpp +++ b/clangd/Cancellation.cpp @@ -1,9 +1,8 @@ //===--- Cancellation.cpp -----------------------------------------*-C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Cancellation.h b/clangd/Cancellation.h index d6f26211..6872c448 100644 --- a/clangd/Cancellation.h +++ b/clangd/Cancellation.h @@ -1,9 +1,8 @@ //===--- Cancellation.h -------------------------------------------*-C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Cancellation mechanism for long-running tasks. diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 80792edd..057426fd 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -1,9 +1,8 @@ //===--- ClangdLSPServer.cpp - LSP server ------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/ClangdLSPServer.h b/clangd/ClangdLSPServer.h index 80052b4a..d84c298e 100644 --- a/clangd/ClangdLSPServer.h +++ b/clangd/ClangdLSPServer.h @@ -1,9 +1,8 @@ //===--- ClangdLSPServer.h - LSP server --------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 53a27bdb..24714256 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -1,9 +1,8 @@ //===--- ClangdServer.cpp - Main clangd server code --------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===-------------------------------------------------------------------===// diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index 213f042c..20874c4b 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -1,9 +1,8 @@ //===--- ClangdServer.h - Main clangd server code ----------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 5add1179..f7b8b731 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -1,9 +1,8 @@ //===--- ClangdUnit.cpp ------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index 15bf998d..abcefdb6 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -1,9 +1,8 @@ //===--- ClangdUnit.h --------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 7642ea9d..60da653d 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1,9 +1,8 @@ //===--- CodeComplete.cpp ----------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/CodeComplete.h b/clangd/CodeComplete.h index 4d324142..08151379 100644 --- a/clangd/CodeComplete.h +++ b/clangd/CodeComplete.h @@ -1,9 +1,8 @@ //===--- CodeComplete.h ------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/CodeCompletionStrings.cpp b/clangd/CodeCompletionStrings.cpp index 42a8693f..586be67e 100644 --- a/clangd/CodeCompletionStrings.cpp +++ b/clangd/CodeCompletionStrings.cpp @@ -1,9 +1,8 @@ //===--- CodeCompletionStrings.cpp -------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/CodeCompletionStrings.h b/clangd/CodeCompletionStrings.h index bf44cbda..153e0af1 100644 --- a/clangd/CodeCompletionStrings.h +++ b/clangd/CodeCompletionStrings.h @@ -1,9 +1,8 @@ //===--- CodeCompletionStrings.h ---------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Compiler.cpp b/clangd/Compiler.cpp index c94ef755..2322b878 100644 --- a/clangd/Compiler.cpp +++ b/clangd/Compiler.cpp @@ -1,9 +1,8 @@ //===--- Compiler.cpp --------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Compiler.h b/clangd/Compiler.h index 7a3c43d6..bee74a85 100644 --- a/clangd/Compiler.h +++ b/clangd/Compiler.h @@ -1,9 +1,8 @@ //===--- Compiler.h ----------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Context.cpp b/clangd/Context.cpp index 66654c47..8e8bba6e 100644 --- a/clangd/Context.cpp +++ b/clangd/Context.cpp @@ -1,9 +1,8 @@ //===--- Context.cpp ---------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Context.h b/clangd/Context.h index 7e14f86c..0bb4cbd9 100644 --- a/clangd/Context.h +++ b/clangd/Context.h @@ -1,9 +1,8 @@ //===--- Context.h - Mechanism for passing implicit data --------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index 1cd52ad3..1ccdfcfb 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -1,9 +1,8 @@ //===--- Diagnostics.cpp -----------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Diagnostics.h b/clangd/Diagnostics.h index 6318e88f..0866c3b5 100644 --- a/clangd/Diagnostics.h +++ b/clangd/Diagnostics.h @@ -1,9 +1,8 @@ //===--- Diagnostics.h -------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/DraftStore.cpp b/clangd/DraftStore.cpp index 9b6c1fc4..16d7ddee 100644 --- a/clangd/DraftStore.cpp +++ b/clangd/DraftStore.cpp @@ -1,9 +1,8 @@ //===--- DraftStore.cpp - File contents container ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/DraftStore.h b/clangd/DraftStore.h index 90a2d2cf..1578ce9f 100644 --- a/clangd/DraftStore.h +++ b/clangd/DraftStore.h @@ -1,9 +1,8 @@ //===--- DraftStore.h - File contents container -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/ExpectedTypes.h b/clangd/ExpectedTypes.h index 2f231283..36b7cce1 100644 --- a/clangd/ExpectedTypes.h +++ b/clangd/ExpectedTypes.h @@ -1,9 +1,8 @@ //===--- ExpectedTypes.h - Simplified C++ types -----------------*- C++-*--===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // A simplified model of C++ types that can be used to check whether they are diff --git a/clangd/FS.cpp b/clangd/FS.cpp index 5d690c86..aae15b55 100644 --- a/clangd/FS.cpp +++ b/clangd/FS.cpp @@ -1,9 +1,8 @@ //===--- FS.cpp - File system related utils ----------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/FS.h b/clangd/FS.h index d4003040..e23b3ff1 100644 --- a/clangd/FS.h +++ b/clangd/FS.h @@ -1,9 +1,8 @@ //===--- FS.h - File system related utils ------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/FSProvider.cpp b/clangd/FSProvider.cpp index 81a1adab..be915740 100644 --- a/clangd/FSProvider.cpp +++ b/clangd/FSProvider.cpp @@ -1,9 +1,8 @@ //===--- FSProvider.cpp - VFS provider for ClangdServer -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/FSProvider.h b/clangd/FSProvider.h index 67d2ec15..22957892 100644 --- a/clangd/FSProvider.h +++ b/clangd/FSProvider.h @@ -1,9 +1,8 @@ //===--- FSProvider.h - VFS provider for ClangdServer ------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/FileDistance.cpp b/clangd/FileDistance.cpp index 7bac2516..a6a65ab7 100644 --- a/clangd/FileDistance.cpp +++ b/clangd/FileDistance.cpp @@ -1,9 +1,8 @@ //===--- FileDistance.cpp - File contents container -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/FileDistance.h b/clangd/FileDistance.h index 2623ce76..e7174bcc 100644 --- a/clangd/FileDistance.h +++ b/clangd/FileDistance.h @@ -1,9 +1,8 @@ //===--- FileDistance.h - File proximity scoring -----------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/FindSymbols.cpp b/clangd/FindSymbols.cpp index 208e78c6..00819550 100644 --- a/clangd/FindSymbols.cpp +++ b/clangd/FindSymbols.cpp @@ -1,9 +1,8 @@ //===--- FindSymbols.cpp ------------------------------------*- C++-*------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "FindSymbols.h" diff --git a/clangd/FindSymbols.h b/clangd/FindSymbols.h index a9c8c998..78bdbd33 100644 --- a/clangd/FindSymbols.h +++ b/clangd/FindSymbols.h @@ -1,9 +1,8 @@ //===--- FindSymbols.h --------------------------------------*- C++-*------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Function.h b/clangd/Function.h index c91b9cbe..6d91136b 100644 --- a/clangd/Function.h +++ b/clangd/Function.h @@ -1,9 +1,8 @@ //===--- Function.h - Utility callable wrappers -----------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/FuzzyMatch.cpp b/clangd/FuzzyMatch.cpp index 433242e6..bc613868 100644 --- a/clangd/FuzzyMatch.cpp +++ b/clangd/FuzzyMatch.cpp @@ -1,9 +1,8 @@ //===--- FuzzyMatch.h - Approximate identifier matching ---------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/FuzzyMatch.h b/clangd/FuzzyMatch.h index f0c7e722..81c2edb8 100644 --- a/clangd/FuzzyMatch.h +++ b/clangd/FuzzyMatch.h @@ -1,9 +1,8 @@ //===--- FuzzyMatch.h - Approximate identifier matching ---------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/GlobalCompilationDatabase.cpp b/clangd/GlobalCompilationDatabase.cpp index c2fff7b2..95e7ce7b 100644 --- a/clangd/GlobalCompilationDatabase.cpp +++ b/clangd/GlobalCompilationDatabase.cpp @@ -1,9 +1,8 @@ //===--- GlobalCompilationDatabase.cpp ---------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/GlobalCompilationDatabase.h b/clangd/GlobalCompilationDatabase.h index 181b1781..3f3bea44 100644 --- a/clangd/GlobalCompilationDatabase.h +++ b/clangd/GlobalCompilationDatabase.h @@ -1,9 +1,8 @@ //===--- GlobalCompilationDatabase.h -----------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Headers.cpp b/clangd/Headers.cpp index 06f822b3..c4af420c 100644 --- a/clangd/Headers.cpp +++ b/clangd/Headers.cpp @@ -1,9 +1,8 @@ //===--- Headers.cpp - Include headers ---------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Headers.h b/clangd/Headers.h index 6f0eb807..5358c34e 100644 --- a/clangd/Headers.h +++ b/clangd/Headers.h @@ -1,9 +1,8 @@ //===--- Headers.h - Include headers -----------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/JSONTransport.cpp b/clangd/JSONTransport.cpp index 7189b23c..17310777 100644 --- a/clangd/JSONTransport.cpp +++ b/clangd/JSONTransport.cpp @@ -1,9 +1,8 @@ //===--- JSONTransport.cpp - sending and receiving LSP messages over JSON -===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Logger.h" diff --git a/clangd/Logger.cpp b/clangd/Logger.cpp index 9d4e7b93..7b8c9a3e 100644 --- a/clangd/Logger.cpp +++ b/clangd/Logger.cpp @@ -1,9 +1,8 @@ //===--- Logger.cpp - Logger interface for clangd -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Logger.h b/clangd/Logger.h index 8572ca15..7a5d5140 100644 --- a/clangd/Logger.h +++ b/clangd/Logger.h @@ -1,9 +1,8 @@ //===--- Logger.h - Logger interface for clangd ------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Path.h b/clangd/Path.h index b4c93357..eaa72245 100644 --- a/clangd/Path.h +++ b/clangd/Path.h @@ -1,9 +1,8 @@ //===--- Path.h - Helper typedefs --------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Protocol.cpp b/clangd/Protocol.cpp index cf3c6fd3..84150772 100644 --- a/clangd/Protocol.cpp +++ b/clangd/Protocol.cpp @@ -1,9 +1,8 @@ //===--- Protocol.cpp - Language Server Protocol Implementation -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Protocol.h b/clangd/Protocol.h index 17b69bde..bdcb396e 100644 --- a/clangd/Protocol.h +++ b/clangd/Protocol.h @@ -1,9 +1,8 @@ //===--- Protocol.h - Language Server Protocol Implementation ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Quality.cpp b/clangd/Quality.cpp index cef35c4c..e9e8ff0a 100644 --- a/clangd/Quality.cpp +++ b/clangd/Quality.cpp @@ -1,9 +1,8 @@ //===--- Quality.cpp ---------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Quality.h" diff --git a/clangd/Quality.h b/clangd/Quality.h index 9cb0c2f3..5eea7dbc 100644 --- a/clangd/Quality.h +++ b/clangd/Quality.h @@ -1,9 +1,8 @@ //===--- Quality.h - Ranking alternatives for ambiguous queries --*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/RIFF.cpp b/clangd/RIFF.cpp index c0bf7855..cdbae4f7 100644 --- a/clangd/RIFF.cpp +++ b/clangd/RIFF.cpp @@ -1,9 +1,8 @@ //===--- RIFF.cpp - Binary container file format --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/RIFF.h b/clangd/RIFF.h index f56d0879..d827a90f 100644 --- a/clangd/RIFF.h +++ b/clangd/RIFF.h @@ -1,9 +1,8 @@ //===--- RIFF.h - Binary container file format -------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp index 343fc701..6952e87d 100644 --- a/clangd/SourceCode.cpp +++ b/clangd/SourceCode.cpp @@ -1,9 +1,8 @@ //===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "SourceCode.h" diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index b768d09a..a3dbc7ab 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -1,9 +1,8 @@ //===--- SourceCode.h - Manipulating source code as strings -----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/TUScheduler.cpp b/clangd/TUScheduler.cpp index 23264004..cf0bf0e0 100644 --- a/clangd/TUScheduler.cpp +++ b/clangd/TUScheduler.cpp @@ -1,9 +1,8 @@ //===--- TUScheduler.cpp -----------------------------------------*-C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // For each file, managed by TUScheduler, we create a single ASTWorker that diff --git a/clangd/TUScheduler.h b/clangd/TUScheduler.h index 5ab66d80..cd0c4c78 100644 --- a/clangd/TUScheduler.h +++ b/clangd/TUScheduler.h @@ -1,9 +1,8 @@ //===--- TUScheduler.h -------------------------------------------*-C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Threading.h b/clangd/Threading.h index 4c553288..3c1f8916 100644 --- a/clangd/Threading.h +++ b/clangd/Threading.h @@ -1,9 +1,8 @@ //===--- ThreadPool.h --------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Trace.cpp b/clangd/Trace.cpp index e44d3a13..d650013b 100644 --- a/clangd/Trace.cpp +++ b/clangd/Trace.cpp @@ -1,9 +1,8 @@ //===--- Trace.cpp - Performance tracing facilities -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/Trace.h b/clangd/Trace.h index 4b2f72e7..a36be77a 100644 --- a/clangd/Trace.h +++ b/clangd/Trace.h @@ -1,9 +1,8 @@ //===--- Trace.h - Performance tracing facilities ---------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/Transport.h b/clangd/Transport.h index 87fb8f98..fab51d17 100644 --- a/clangd/Transport.h +++ b/clangd/Transport.h @@ -1,9 +1,8 @@ //===--- Transport.h - sending and receiving LSP messages -------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/URI.cpp b/clangd/URI.cpp index 888acb7f..ed6b4d34 100644 --- a/clangd/URI.cpp +++ b/clangd/URI.cpp @@ -1,9 +1,8 @@ //===---- URI.h - File URIs with schemes -------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/URI.h b/clangd/URI.h index cbde008b..110b39af 100644 --- a/clangd/URI.h +++ b/clangd/URI.h @@ -1,9 +1,8 @@ //===--- URI.h - File URIs with schemes --------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 29561dfe..7db0202d 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -1,9 +1,8 @@ //===--- XRefs.cpp -----------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "XRefs.h" diff --git a/clangd/XRefs.h b/clangd/XRefs.h index 631879d6..cd90c65a 100644 --- a/clangd/XRefs.h +++ b/clangd/XRefs.h @@ -1,9 +1,8 @@ //===--- XRefs.h -------------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/benchmarks/IndexBenchmark.cpp b/clangd/benchmarks/IndexBenchmark.cpp index d71f8fec..439ac9c6 100644 --- a/clangd/benchmarks/IndexBenchmark.cpp +++ b/clangd/benchmarks/IndexBenchmark.cpp @@ -1,9 +1,8 @@ //===--- IndexBenchmark.cpp - Clangd index benchmarks -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/fuzzer/ClangdFuzzer.cpp b/clangd/fuzzer/ClangdFuzzer.cpp index 7afd0798..564643db 100644 --- a/clangd/fuzzer/ClangdFuzzer.cpp +++ b/clangd/fuzzer/ClangdFuzzer.cpp @@ -1,9 +1,8 @@ //===-- ClangdFuzzer.cpp - Fuzz clangd ------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp index fc3bd253..aa67598d 100644 --- a/clangd/index/Background.cpp +++ b/clangd/index/Background.cpp @@ -1,9 +1,8 @@ //===-- Background.cpp - Build an index in a background thread ------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/Background.h b/clangd/index/Background.h index 1a1fee68..2cfbd0e9 100644 --- a/clangd/index/Background.h +++ b/clangd/index/Background.h @@ -1,9 +1,8 @@ //===--- Background.h - Build an index in a background thread ----*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/BackgroundIndexStorage.cpp b/clangd/index/BackgroundIndexStorage.cpp index a83bec6f..266b18ce 100644 --- a/clangd/index/BackgroundIndexStorage.cpp +++ b/clangd/index/BackgroundIndexStorage.cpp @@ -1,9 +1,8 @@ //== BackgroundIndexStorage.cpp - Provide caching support to BackgroundIndex ==/ // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/CanonicalIncludes.cpp b/clangd/index/CanonicalIncludes.cpp index 7351b861..6fa366d4 100644 --- a/clangd/index/CanonicalIncludes.cpp +++ b/clangd/index/CanonicalIncludes.cpp @@ -1,9 +1,8 @@ //===-- CanonicalIncludes.h - remap #inclue headers--------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/CanonicalIncludes.h b/clangd/index/CanonicalIncludes.h index 3751b000..c9baf0ad 100644 --- a/clangd/index/CanonicalIncludes.h +++ b/clangd/index/CanonicalIncludes.h @@ -1,9 +1,8 @@ //===-- CanonicalIncludes.h - remap #include header -------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/index/FileIndex.cpp b/clangd/index/FileIndex.cpp index d3e3596d..8ce42b51 100644 --- a/clangd/index/FileIndex.cpp +++ b/clangd/index/FileIndex.cpp @@ -1,9 +1,8 @@ //===--- FileIndex.cpp - Indexes for files. ------------------------ C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/FileIndex.h b/clangd/index/FileIndex.h index 92e3b2b6..74563276 100644 --- a/clangd/index/FileIndex.h +++ b/clangd/index/FileIndex.h @@ -1,9 +1,8 @@ //===--- FileIndex.h - Index for files. ---------------------------- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index 4036d671..a13d28b3 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -1,9 +1,8 @@ //===--- Index.cpp -----------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/Index.h b/clangd/index/Index.h index cc4cf2a2..d36dd299 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -1,9 +1,8 @@ //===--- Index.h -------------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/IndexAction.h b/clangd/index/IndexAction.h index f2c5298f..748b26e1 100644 --- a/clangd/index/IndexAction.h +++ b/clangd/index/IndexAction.h @@ -1,9 +1,8 @@ //===--- IndexAction.h - Run the indexer as a frontend action ----*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/MemIndex.cpp b/clangd/index/MemIndex.cpp index e4dc56c5..531d1f6d 100644 --- a/clangd/index/MemIndex.cpp +++ b/clangd/index/MemIndex.cpp @@ -1,9 +1,8 @@ //===--- MemIndex.cpp - Dynamic in-memory symbol index. ----------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===-------------------------------------------------------------------===// diff --git a/clangd/index/MemIndex.h b/clangd/index/MemIndex.h index 24f2ba19..47227fd7 100644 --- a/clangd/index/MemIndex.h +++ b/clangd/index/MemIndex.h @@ -1,9 +1,8 @@ //===--- MemIndex.h - Dynamic in-memory symbol index. -------------- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp index 52f54e39..77a67cb0 100644 --- a/clangd/index/Merge.cpp +++ b/clangd/index/Merge.cpp @@ -1,9 +1,8 @@ //===--- Merge.cpp -----------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/Merge.h b/clangd/index/Merge.h index 7569c7a4..5954b6bc 100644 --- a/clangd/index/Merge.h +++ b/clangd/index/Merge.h @@ -1,9 +1,8 @@ //===--- Merge.h -------------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/Serialization.cpp b/clangd/index/Serialization.cpp index a4f99b1c..bdad7fd5 100644 --- a/clangd/index/Serialization.cpp +++ b/clangd/index/Serialization.cpp @@ -1,9 +1,8 @@ //===-- Serialization.cpp - Binary serialization of index data ------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/Serialization.h b/clangd/index/Serialization.h index c403b957..d81b8968 100644 --- a/clangd/index/Serialization.h +++ b/clangd/index/Serialization.h @@ -1,9 +1,8 @@ //===--- Serialization.h - Binary serialization of index data ----*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index d3ce7712..c9abb938 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -1,9 +1,8 @@ //===--- SymbolCollector.cpp -------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/SymbolCollector.h b/clangd/index/SymbolCollector.h index 157735d0..1b10df4c 100644 --- a/clangd/index/SymbolCollector.h +++ b/clangd/index/SymbolCollector.h @@ -1,9 +1,8 @@ //===--- SymbolCollector.h ---------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_COLLECTOR_H diff --git a/clangd/index/SymbolID.cpp b/clangd/index/SymbolID.cpp index 1fd42744..7510063a 100644 --- a/clangd/index/SymbolID.cpp +++ b/clangd/index/SymbolID.cpp @@ -1,9 +1,8 @@ //===--- SymbolID.cpp --------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/SymbolID.h b/clangd/index/SymbolID.h index aa8208c1..0e4fc663 100644 --- a/clangd/index/SymbolID.h +++ b/clangd/index/SymbolID.h @@ -1,9 +1,8 @@ //===--- SymbolID.h ----------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp index 7eb5b4cf..7aab39f4 100644 --- a/clangd/index/YAMLSerialization.cpp +++ b/clangd/index/YAMLSerialization.cpp @@ -1,9 +1,8 @@ //===--- SymbolYAML.cpp ------------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/index/dex/Dex.cpp b/clangd/index/dex/Dex.cpp index c38706c6..b4db1136 100644 --- a/clangd/index/dex/Dex.cpp +++ b/clangd/index/dex/Dex.cpp @@ -1,9 +1,8 @@ //===--- Dex.cpp - Dex Symbol Index Implementation --------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/dex/Dex.h b/clangd/index/dex/Dex.h index c790e417..71814e43 100644 --- a/clangd/index/dex/Dex.h +++ b/clangd/index/dex/Dex.h @@ -1,9 +1,8 @@ //===--- Dex.h - Dex Symbol Index Implementation ----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/index/dex/Iterator.cpp b/clangd/index/dex/Iterator.cpp index 0b132b94..cb294a33 100644 --- a/clangd/index/dex/Iterator.cpp +++ b/clangd/index/dex/Iterator.cpp @@ -1,9 +1,8 @@ //===--- Iterator.cpp - Query Symbol Retrieval ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/dex/Iterator.h b/clangd/index/dex/Iterator.h index 149fd43a..34b42c32 100644 --- a/clangd/index/dex/Iterator.h +++ b/clangd/index/dex/Iterator.h @@ -1,9 +1,8 @@ //===--- Iterator.h - Query Symbol Retrieval --------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/index/dex/PostingList.cpp b/clangd/index/dex/PostingList.cpp index eb2e4757..44a668bb 100644 --- a/clangd/index/dex/PostingList.cpp +++ b/clangd/index/dex/PostingList.cpp @@ -1,9 +1,8 @@ //===--- PostingList.cpp - Symbol identifiers storage interface -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/dex/PostingList.h b/clangd/index/dex/PostingList.h index 81ba64c1..418e4c72 100644 --- a/clangd/index/dex/PostingList.h +++ b/clangd/index/dex/PostingList.h @@ -1,9 +1,8 @@ //===--- PostingList.h - Symbol identifiers storage interface --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/index/dex/Token.h b/clangd/index/dex/Token.h index f80d9254..4c67e9fa 100644 --- a/clangd/index/dex/Token.h +++ b/clangd/index/dex/Token.h @@ -1,9 +1,8 @@ //===--- Token.h - Symbol Search primitive ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/index/dex/Trigram.cpp b/clangd/index/dex/Trigram.cpp index 2ba0ad18..24ae72bf 100644 --- a/clangd/index/dex/Trigram.cpp +++ b/clangd/index/dex/Trigram.cpp @@ -1,9 +1,8 @@ //===--- Trigram.cpp - Trigram generation for Fuzzy Matching ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/index/dex/Trigram.h b/clangd/index/dex/Trigram.h index adce9f42..bf1e5e80 100644 --- a/clangd/index/dex/Trigram.h +++ b/clangd/index/dex/Trigram.h @@ -1,9 +1,8 @@ //===--- Trigram.h - Trigram generation for Fuzzy Matching ------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/clangd/index/dex/dexp/Dexp.cpp b/clangd/index/dex/dexp/Dexp.cpp index 5a0b6d97..820dc66b 100644 --- a/clangd/index/dex/dexp/Dexp.cpp +++ b/clangd/index/dex/dexp/Dexp.cpp @@ -1,9 +1,8 @@ //===--- Dexp.cpp - Dex EXPloration tool ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/indexer/IndexerMain.cpp b/clangd/indexer/IndexerMain.cpp index 18e6304f..1621e8f9 100644 --- a/clangd/indexer/IndexerMain.cpp +++ b/clangd/indexer/IndexerMain.cpp @@ -1,9 +1,8 @@ //===--- IndexerMain.cpp -----------------------------------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index 34e81d3b..80f3f45e 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -1,9 +1,8 @@ //===--- ClangdMain.cpp - clangd server loop ------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/xpc/Conversion.cpp b/clangd/xpc/Conversion.cpp index 45bb11af..3e8d36b7 100644 --- a/clangd/xpc/Conversion.cpp +++ b/clangd/xpc/Conversion.cpp @@ -1,9 +1,8 @@ //===--- Conversion.cpp - LSP data (de-)serialization through XPC - C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/xpc/Conversion.h b/clangd/xpc/Conversion.h index 936f51be..fccc095b 100644 --- a/clangd/xpc/Conversion.h +++ b/clangd/xpc/Conversion.h @@ -1,9 +1,8 @@ //===--- Conversion.h - LSP data (de-)serialization through XPC -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/clangd/xpc/XPCTransport.cpp b/clangd/xpc/XPCTransport.cpp index 496d8e47..f7df8a91 100644 --- a/clangd/xpc/XPCTransport.cpp +++ b/clangd/xpc/XPCTransport.cpp @@ -1,9 +1,8 @@ //===--- XPCTransport.cpp - sending and receiving LSP messages over XPC ---===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Conversion.h" diff --git a/include-fixer/FuzzySymbolIndex.cpp b/include-fixer/FuzzySymbolIndex.cpp index d91f4552..099d7389 100644 --- a/include-fixer/FuzzySymbolIndex.cpp +++ b/include-fixer/FuzzySymbolIndex.cpp @@ -1,9 +1,8 @@ //===--- FuzzySymbolIndex.cpp - Lookup symbols for autocomplete -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "FuzzySymbolIndex.h" diff --git a/include-fixer/FuzzySymbolIndex.h b/include-fixer/FuzzySymbolIndex.h index 245191eb..2ea16609 100644 --- a/include-fixer/FuzzySymbolIndex.h +++ b/include-fixer/FuzzySymbolIndex.h @@ -1,9 +1,8 @@ //===--- FuzzySymbolIndex.h - Lookup symbols for autocomplete ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/InMemorySymbolIndex.cpp b/include-fixer/InMemorySymbolIndex.cpp index 14753bd9..e7858939 100644 --- a/include-fixer/InMemorySymbolIndex.cpp +++ b/include-fixer/InMemorySymbolIndex.cpp @@ -1,9 +1,8 @@ //===-- InMemorySymbolIndex.cpp--------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/InMemorySymbolIndex.h b/include-fixer/InMemorySymbolIndex.h index 0e1310e3..bea8be91 100644 --- a/include-fixer/InMemorySymbolIndex.h +++ b/include-fixer/InMemorySymbolIndex.h @@ -1,9 +1,8 @@ //===-- InMemorySymbolIndex.h -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/include-fixer/IncludeFixer.cpp b/include-fixer/IncludeFixer.cpp index c6dfd7fc..540b263e 100644 --- a/include-fixer/IncludeFixer.cpp +++ b/include-fixer/IncludeFixer.cpp @@ -1,9 +1,8 @@ //===-- IncludeFixer.cpp - Include inserter based on sema callbacks -------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/IncludeFixer.h b/include-fixer/IncludeFixer.h index 13092a34..5528e895 100644 --- a/include-fixer/IncludeFixer.h +++ b/include-fixer/IncludeFixer.h @@ -1,9 +1,8 @@ //===-- IncludeFixer.h - Include inserter -----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/IncludeFixerContext.cpp b/include-fixer/IncludeFixerContext.cpp index 8106e20e..a9fef45c 100644 --- a/include-fixer/IncludeFixerContext.cpp +++ b/include-fixer/IncludeFixerContext.cpp @@ -1,9 +1,8 @@ //===-- IncludeFixerContext.cpp - Include fixer context ---------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/IncludeFixerContext.h b/include-fixer/IncludeFixerContext.h index 3c44574b..bbb87e2b 100644 --- a/include-fixer/IncludeFixerContext.h +++ b/include-fixer/IncludeFixerContext.h @@ -1,9 +1,8 @@ //===-- IncludeFixerContext.h - Include fixer context -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/SymbolIndex.h b/include-fixer/SymbolIndex.h index f3e6ecd9..ca04d50a 100644 --- a/include-fixer/SymbolIndex.h +++ b/include-fixer/SymbolIndex.h @@ -1,9 +1,8 @@ //===-- SymbolIndex.h - Interface for symbol-header matching ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/SymbolIndexManager.cpp b/include-fixer/SymbolIndexManager.cpp index e4312bf1..603b9d4f 100644 --- a/include-fixer/SymbolIndexManager.cpp +++ b/include-fixer/SymbolIndexManager.cpp @@ -1,9 +1,8 @@ //===-- SymbolIndexManager.cpp - Managing multiple SymbolIndices-*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/SymbolIndexManager.h b/include-fixer/SymbolIndexManager.h index 12963ddb..ca2d7399 100644 --- a/include-fixer/SymbolIndexManager.h +++ b/include-fixer/SymbolIndexManager.h @@ -1,9 +1,8 @@ //===-- SymbolIndexManager.h - Managing multiple SymbolIndices --*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/YamlSymbolIndex.cpp b/include-fixer/YamlSymbolIndex.cpp index f3f2d5a8..de72e9a9 100644 --- a/include-fixer/YamlSymbolIndex.cpp +++ b/include-fixer/YamlSymbolIndex.cpp @@ -1,9 +1,8 @@ //===-- YamlSymbolIndex.cpp -----------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/YamlSymbolIndex.h b/include-fixer/YamlSymbolIndex.h index d5d699a2..3c4f5144 100644 --- a/include-fixer/YamlSymbolIndex.h +++ b/include-fixer/YamlSymbolIndex.h @@ -1,9 +1,8 @@ //===-- YamlSymbolIndex.h ---------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/FindAllMacros.cpp b/include-fixer/find-all-symbols/FindAllMacros.cpp index 3dc2b96f..ed1bc2f4 100644 --- a/include-fixer/find-all-symbols/FindAllMacros.cpp +++ b/include-fixer/find-all-symbols/FindAllMacros.cpp @@ -1,9 +1,8 @@ //===-- FindAllMacros.cpp - find all macros ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/FindAllMacros.h b/include-fixer/find-all-symbols/FindAllMacros.h index 10b4a696..5aaf3884 100644 --- a/include-fixer/find-all-symbols/FindAllMacros.h +++ b/include-fixer/find-all-symbols/FindAllMacros.h @@ -1,10 +1,9 @@ //===-- FindAllMacros.h - find all macros -----------------------*- C++ -*-===// // // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/FindAllSymbols.cpp b/include-fixer/find-all-symbols/FindAllSymbols.cpp index bd5032d0..bb6a3fa9 100644 --- a/include-fixer/find-all-symbols/FindAllSymbols.cpp +++ b/include-fixer/find-all-symbols/FindAllSymbols.cpp @@ -1,9 +1,8 @@ //===-- FindAllSymbols.cpp - find all symbols--------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/FindAllSymbols.h b/include-fixer/find-all-symbols/FindAllSymbols.h index fca849f5..d78da668 100644 --- a/include-fixer/find-all-symbols/FindAllSymbols.h +++ b/include-fixer/find-all-symbols/FindAllSymbols.h @@ -1,9 +1,8 @@ //===-- FindAllSymbols.h - find all symbols----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp b/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp index bc00547a..9f1d31dc 100644 --- a/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp +++ b/include-fixer/find-all-symbols/FindAllSymbolsAction.cpp @@ -1,9 +1,8 @@ //===-- FindAllSymbolsAction.cpp - find all symbols action --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/FindAllSymbolsAction.h b/include-fixer/find-all-symbols/FindAllSymbolsAction.h index 7be9fe2b..ccffa4b3 100644 --- a/include-fixer/find-all-symbols/FindAllSymbolsAction.h +++ b/include-fixer/find-all-symbols/FindAllSymbolsAction.h @@ -1,9 +1,8 @@ //===-- FindAllSymbolsAction.h - find all symbols action --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/HeaderMapCollector.cpp b/include-fixer/find-all-symbols/HeaderMapCollector.cpp index 379df81a..6ec49cae 100644 --- a/include-fixer/find-all-symbols/HeaderMapCollector.cpp +++ b/include-fixer/find-all-symbols/HeaderMapCollector.cpp @@ -1,9 +1,8 @@ //===-- HeaderMapCoolector.h - find all symbols------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/HeaderMapCollector.h b/include-fixer/find-all-symbols/HeaderMapCollector.h index 65edd754..21358275 100644 --- a/include-fixer/find-all-symbols/HeaderMapCollector.h +++ b/include-fixer/find-all-symbols/HeaderMapCollector.h @@ -1,9 +1,8 @@ //===-- HeaderMapCoolector.h - find all symbols------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/PathConfig.cpp b/include-fixer/find-all-symbols/PathConfig.cpp index de799b99..4f1ebc77 100644 --- a/include-fixer/find-all-symbols/PathConfig.cpp +++ b/include-fixer/find-all-symbols/PathConfig.cpp @@ -1,10 +1,9 @@ //===-- PathConfig.cpp - Process paths of symbols ---------------*- C++ -*-===// // // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/PathConfig.h b/include-fixer/find-all-symbols/PathConfig.h index 50de5480..9c430f25 100644 --- a/include-fixer/find-all-symbols/PathConfig.h +++ b/include-fixer/find-all-symbols/PathConfig.h @@ -1,10 +1,9 @@ //===-- PathConfig.h - Process paths of symbols -----------------*- C++ -*-===// // // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/PragmaCommentHandler.cpp b/include-fixer/find-all-symbols/PragmaCommentHandler.cpp index 0242d385..49489752 100644 --- a/include-fixer/find-all-symbols/PragmaCommentHandler.cpp +++ b/include-fixer/find-all-symbols/PragmaCommentHandler.cpp @@ -1,9 +1,8 @@ //===-- PragmaCommentHandler.cpp - find all symbols -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/PragmaCommentHandler.h b/include-fixer/find-all-symbols/PragmaCommentHandler.h index 9eb4972c..752c82f5 100644 --- a/include-fixer/find-all-symbols/PragmaCommentHandler.h +++ b/include-fixer/find-all-symbols/PragmaCommentHandler.h @@ -1,9 +1,8 @@ //===-- PragmaCommentHandler.h - find all symbols----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp b/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp index 4a49479b..0d0bbd9f 100644 --- a/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp +++ b/include-fixer/find-all-symbols/STLPostfixHeaderMap.cpp @@ -1,9 +1,8 @@ //===-- STLPostfixHeaderMap.h - hardcoded STL header map --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/STLPostfixHeaderMap.h b/include-fixer/find-all-symbols/STLPostfixHeaderMap.h index 162580d8..49bc5f30 100644 --- a/include-fixer/find-all-symbols/STLPostfixHeaderMap.h +++ b/include-fixer/find-all-symbols/STLPostfixHeaderMap.h @@ -1,9 +1,8 @@ //===-- STLPostfixHeaderMap.h - hardcoded header map for STL ----*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/SymbolInfo.cpp b/include-fixer/find-all-symbols/SymbolInfo.cpp index 00bfbe5f..e5b4dba4 100644 --- a/include-fixer/find-all-symbols/SymbolInfo.cpp +++ b/include-fixer/find-all-symbols/SymbolInfo.cpp @@ -1,9 +1,8 @@ //===-- SymbolInfo.cpp - Symbol Info ----------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/SymbolInfo.h b/include-fixer/find-all-symbols/SymbolInfo.h index 92d360d3..6def1c70 100644 --- a/include-fixer/find-all-symbols/SymbolInfo.h +++ b/include-fixer/find-all-symbols/SymbolInfo.h @@ -1,9 +1,8 @@ //===-- SymbolInfo.h - Symbol Info ------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/SymbolReporter.h b/include-fixer/find-all-symbols/SymbolReporter.h index 2398234c..25e86219 100644 --- a/include-fixer/find-all-symbols/SymbolReporter.h +++ b/include-fixer/find-all-symbols/SymbolReporter.h @@ -1,9 +1,8 @@ //===--- SymbolReporter.h - Symbol Reporter ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp b/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp index e09a5aaf..dbbe0738 100644 --- a/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp +++ b/include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp @@ -1,9 +1,8 @@ //===-- FindAllSymbolsMain.cpp - find all symbols tool ----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/find-all-symbols/tool/run-find-all-symbols.py b/include-fixer/find-all-symbols/tool/run-find-all-symbols.py index 461d959b..5e9dde72 100755 --- a/include-fixer/find-all-symbols/tool/run-find-all-symbols.py +++ b/include-fixer/find-all-symbols/tool/run-find-all-symbols.py @@ -2,10 +2,9 @@ # #=- run-find-all-symbols.py - Parallel find-all-symbols runner -*- python -*-=# # -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# 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 # #===------------------------------------------------------------------------===# diff --git a/include-fixer/plugin/IncludeFixerPlugin.cpp b/include-fixer/plugin/IncludeFixerPlugin.cpp index 0d6bdb75..bc9c4973 100644 --- a/include-fixer/plugin/IncludeFixerPlugin.cpp +++ b/include-fixer/plugin/IncludeFixerPlugin.cpp @@ -1,9 +1,8 @@ //===- IncludeFixerPlugin.cpp - clang-include-fixer as a clang plugin -----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/include-fixer/tool/ClangIncludeFixer.cpp b/include-fixer/tool/ClangIncludeFixer.cpp index d9d97d23..64bfdb75 100644 --- a/include-fixer/tool/ClangIncludeFixer.cpp +++ b/include-fixer/tool/ClangIncludeFixer.cpp @@ -1,9 +1,8 @@ //===-- ClangIncludeFixer.cpp - Standalone include fixer ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/modularize/CoverageChecker.cpp b/modularize/CoverageChecker.cpp index 4e2a23ca..8bcb1c75 100644 --- a/modularize/CoverageChecker.cpp +++ b/modularize/CoverageChecker.cpp @@ -1,9 +1,8 @@ //===--- extra/module-map-checker/CoverageChecker.cpp -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/modularize/CoverageChecker.h b/modularize/CoverageChecker.h index f6c8367a..caafaeb4 100644 --- a/modularize/CoverageChecker.h +++ b/modularize/CoverageChecker.h @@ -1,9 +1,8 @@ //===-- CoverageChecker.h - Module map coverage checker -*- C++ -*-------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===--------------------------------------------------------------------===// /// diff --git a/modularize/Modularize.cpp b/modularize/Modularize.cpp index 83f23402..59fc5c35 100644 --- a/modularize/Modularize.cpp +++ b/modularize/Modularize.cpp @@ -1,9 +1,8 @@ //===- extra/modularize/Modularize.cpp - Check modularized headers --------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/modularize/Modularize.h b/modularize/Modularize.h index a3f2ad3e..d11a6650 100644 --- a/modularize/Modularize.h +++ b/modularize/Modularize.h @@ -1,9 +1,8 @@ //===--- Modularize.h - Common definitions for Modularize -*- C++ -*-----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===--------------------------------------------------------------------===// /// diff --git a/modularize/ModularizeUtilities.cpp b/modularize/ModularizeUtilities.cpp index 85768d5a..c4e13abc 100644 --- a/modularize/ModularizeUtilities.cpp +++ b/modularize/ModularizeUtilities.cpp @@ -1,9 +1,8 @@ //===--- extra/modularize/ModularizeUtilities.cpp -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/modularize/ModularizeUtilities.h b/modularize/ModularizeUtilities.h index 4ad2b565..1c8c0b6d 100644 --- a/modularize/ModularizeUtilities.h +++ b/modularize/ModularizeUtilities.h @@ -1,9 +1,8 @@ //=====-- ModularizeUtilities.h - Utilities for modularize -*- C++ -*-======// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===--------------------------------------------------------------------===// /// diff --git a/modularize/ModuleAssistant.cpp b/modularize/ModuleAssistant.cpp index dacb4f91..c34308c2 100644 --- a/modularize/ModuleAssistant.cpp +++ b/modularize/ModuleAssistant.cpp @@ -1,9 +1,8 @@ //===--- ModuleAssistant.cpp - Module map generation manager --*- C++ -*---===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/modularize/PreprocessorTracker.cpp b/modularize/PreprocessorTracker.cpp index 6cb34c7b..445c0c16 100644 --- a/modularize/PreprocessorTracker.cpp +++ b/modularize/PreprocessorTracker.cpp @@ -1,9 +1,8 @@ //===--- PreprocessorTracker.cpp - Preprocessor tracking -*- C++ -*------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===--------------------------------------------------------------------===// // diff --git a/modularize/PreprocessorTracker.h b/modularize/PreprocessorTracker.h index a283d9f2..8eec76cd 100644 --- a/modularize/PreprocessorTracker.h +++ b/modularize/PreprocessorTracker.h @@ -1,9 +1,8 @@ //===- PreprocessorTracker.h - Tracks preprocessor activities -*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===--------------------------------------------------------------------===// /// diff --git a/pp-trace/PPCallbacksTracker.cpp b/pp-trace/PPCallbacksTracker.cpp index 2530dc2d..4ed40b38 100644 --- a/pp-trace/PPCallbacksTracker.cpp +++ b/pp-trace/PPCallbacksTracker.cpp @@ -1,9 +1,8 @@ //===--- PPCallbacksTracker.cpp - Preprocessor tracker -*--*---------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/pp-trace/PPCallbacksTracker.h b/pp-trace/PPCallbacksTracker.h index b46210ef..ec52feec 100644 --- a/pp-trace/PPCallbacksTracker.h +++ b/pp-trace/PPCallbacksTracker.h @@ -1,9 +1,8 @@ //===--- PPCallbacksTracker.h - Preprocessor tracking -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/pp-trace/PPTrace.cpp b/pp-trace/PPTrace.cpp index 08e0f514..65248285 100644 --- a/pp-trace/PPTrace.cpp +++ b/pp-trace/PPTrace.cpp @@ -1,9 +1,8 @@ //===--- tools/pp-trace/PPTrace.cpp - Clang preprocessor tracer -----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/test/clang-tidy/check_clang_tidy.py b/test/clang-tidy/check_clang_tidy.py index 9768011a..5d808f40 100755 --- a/test/clang-tidy/check_clang_tidy.py +++ b/test/clang-tidy/check_clang_tidy.py @@ -2,10 +2,9 @@ # #===- check_clang_tidy.py - ClangTidy Test Helper ------------*- python -*--===# # -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. +# 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 # #===------------------------------------------------------------------------===# diff --git a/tool-template/ToolTemplate.cpp b/tool-template/ToolTemplate.cpp index 66ec2e84..3220eb33 100644 --- a/tool-template/ToolTemplate.cpp +++ b/tool-template/ToolTemplate.cpp @@ -1,9 +1,8 @@ //===---- tools/extra/ToolTemplate.cpp - Template for refactoring tool ----===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/change-namespace/ChangeNamespaceTests.cpp b/unittests/change-namespace/ChangeNamespaceTests.cpp index 4008600b..d66fede2 100644 --- a/unittests/change-namespace/ChangeNamespaceTests.cpp +++ b/unittests/change-namespace/ChangeNamespaceTests.cpp @@ -1,9 +1,8 @@ //===-- ChangeNamespaceTests.cpp - Change namespace unit tests ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp b/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp index 85aaebf7..c532a37a 100644 --- a/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp +++ b/unittests/clang-apply-replacements/ApplyReplacementsTest.cpp @@ -1,10 +1,9 @@ //===- clang-apply-replacements/ApplyReplacementsTest.cpp //----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/BitcodeTest.cpp b/unittests/clang-doc/BitcodeTest.cpp index 26bdf9ec..c89a6491 100644 --- a/unittests/clang-doc/BitcodeTest.cpp +++ b/unittests/clang-doc/BitcodeTest.cpp @@ -1,9 +1,8 @@ //===-- clang-doc/BitcodeTest.cpp -----------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/ClangDocTest.cpp b/unittests/clang-doc/ClangDocTest.cpp index e763d354..99ea76b7 100644 --- a/unittests/clang-doc/ClangDocTest.cpp +++ b/unittests/clang-doc/ClangDocTest.cpp @@ -1,9 +1,8 @@ //===-- clang-doc/ClangDocTest.cpp ----------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/ClangDocTest.h b/unittests/clang-doc/ClangDocTest.h index 1cc06191..d9f3a65b 100644 --- a/unittests/clang-doc/ClangDocTest.h +++ b/unittests/clang-doc/ClangDocTest.h @@ -1,9 +1,8 @@ //===-- clang-doc/ClangDocTest.h ------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/MDGeneratorTest.cpp b/unittests/clang-doc/MDGeneratorTest.cpp index aa624baa..233ec6ec 100644 --- a/unittests/clang-doc/MDGeneratorTest.cpp +++ b/unittests/clang-doc/MDGeneratorTest.cpp @@ -1,9 +1,8 @@ //===-- clang-doc/MDGeneratorTest.cpp -------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/MergeTest.cpp b/unittests/clang-doc/MergeTest.cpp index ab3afa86..7adc1f3d 100644 --- a/unittests/clang-doc/MergeTest.cpp +++ b/unittests/clang-doc/MergeTest.cpp @@ -1,9 +1,8 @@ //===-- clang-doc/MergeTest.cpp -------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/SerializeTest.cpp b/unittests/clang-doc/SerializeTest.cpp index d5bf8f11..1c044f7d 100644 --- a/unittests/clang-doc/SerializeTest.cpp +++ b/unittests/clang-doc/SerializeTest.cpp @@ -1,9 +1,8 @@ //===-- clang-doc/SerializeTest.cpp ---------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-doc/YAMLGeneratorTest.cpp b/unittests/clang-doc/YAMLGeneratorTest.cpp index a4ac5dfb..8a1ba465 100644 --- a/unittests/clang-doc/YAMLGeneratorTest.cpp +++ b/unittests/clang-doc/YAMLGeneratorTest.cpp @@ -1,10 +1,9 @@ //===-- clang-doc/YAMLGeneratorTest.cpp //------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-move/ClangMoveTests.cpp b/unittests/clang-move/ClangMoveTests.cpp index 97c7ce07..0385a799 100644 --- a/unittests/clang-move/ClangMoveTests.cpp +++ b/unittests/clang-move/ClangMoveTests.cpp @@ -1,9 +1,8 @@ //===-- ClangMoveTest.cpp - clang-move unit tests -------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-query/QueryEngineTest.cpp b/unittests/clang-query/QueryEngineTest.cpp index c1d67a17..df3be130 100644 --- a/unittests/clang-query/QueryEngineTest.cpp +++ b/unittests/clang-query/QueryEngineTest.cpp @@ -1,9 +1,8 @@ //===---- QueryTest.cpp - clang-query test --------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-query/QueryParserTest.cpp b/unittests/clang-query/QueryParserTest.cpp index d4c384c4..01c65452 100644 --- a/unittests/clang-query/QueryParserTest.cpp +++ b/unittests/clang-query/QueryParserTest.cpp @@ -1,9 +1,8 @@ //===---- QueryParserTest.cpp - clang-query test --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-tidy/ClangTidyTest.h b/unittests/clang-tidy/ClangTidyTest.h index 32bb53c1..ca886e42 100644 --- a/unittests/clang-tidy/ClangTidyTest.h +++ b/unittests/clang-tidy/ClangTidyTest.h @@ -1,9 +1,8 @@ //===--- ClangTidyTest.h - clang-tidy ---------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-tidy/IncludeInserterTest.cpp b/unittests/clang-tidy/IncludeInserterTest.cpp index 7a70f66a..bf9a3505 100644 --- a/unittests/clang-tidy/IncludeInserterTest.cpp +++ b/unittests/clang-tidy/IncludeInserterTest.cpp @@ -1,9 +1,8 @@ //===---- IncludeInserterTest.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-tidy/NamespaceAliaserTest.cpp b/unittests/clang-tidy/NamespaceAliaserTest.cpp index e4f8ebce..e4cd74ed 100644 --- a/unittests/clang-tidy/NamespaceAliaserTest.cpp +++ b/unittests/clang-tidy/NamespaceAliaserTest.cpp @@ -1,10 +1,9 @@ //===---- NamespaceAliaserTest.cpp - clang-tidy //----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-tidy/ObjCModuleTest.cpp b/unittests/clang-tidy/ObjCModuleTest.cpp index 92ae8e10..826978b0 100644 --- a/unittests/clang-tidy/ObjCModuleTest.cpp +++ b/unittests/clang-tidy/ObjCModuleTest.cpp @@ -1,9 +1,8 @@ //===---- ObjCModuleTest.cpp - clang-tidy ---------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-tidy/OverlappingReplacementsTest.cpp b/unittests/clang-tidy/OverlappingReplacementsTest.cpp index 87213b17..3aaf5491 100644 --- a/unittests/clang-tidy/OverlappingReplacementsTest.cpp +++ b/unittests/clang-tidy/OverlappingReplacementsTest.cpp @@ -1,9 +1,8 @@ //===---- OverlappingReplacementsTest.cpp - clang-tidy --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clang-tidy/UsingInserterTest.cpp b/unittests/clang-tidy/UsingInserterTest.cpp index 16d25192..71c71596 100644 --- a/unittests/clang-tidy/UsingInserterTest.cpp +++ b/unittests/clang-tidy/UsingInserterTest.cpp @@ -1,9 +1,8 @@ //===---- UsingInserterTest.cpp - clang-tidy ----------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/Annotations.cpp b/unittests/clangd/Annotations.cpp index 474ba05d..7a3f94ac 100644 --- a/unittests/clangd/Annotations.cpp +++ b/unittests/clangd/Annotations.cpp @@ -1,9 +1,8 @@ //===--- Annotations.cpp - Annotated source code for unit tests --*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/Annotations.h b/unittests/clangd/Annotations.h index 4d787c25..07f79b55 100644 --- a/unittests/clangd/Annotations.h +++ b/unittests/clangd/Annotations.h @@ -1,9 +1,8 @@ //===--- Annotations.h - Annotated source code for tests ---------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/clangd/ClangdTests.cpp b/unittests/clangd/ClangdTests.cpp index c1cc623a..26b6065e 100644 --- a/unittests/clangd/ClangdTests.cpp +++ b/unittests/clangd/ClangdTests.cpp @@ -1,9 +1,8 @@ //===-- ClangdTests.cpp - Clangd unit tests ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/ClangdUnitTests.cpp b/unittests/clangd/ClangdUnitTests.cpp index d0b85fd4..04154078 100644 --- a/unittests/clangd/ClangdUnitTests.cpp +++ b/unittests/clangd/ClangdUnitTests.cpp @@ -1,9 +1,8 @@ //===-- ClangdUnitTests.cpp - ClangdUnit tests ------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp index 02f12eab..c8059344 100644 --- a/unittests/clangd/CodeCompleteTests.cpp +++ b/unittests/clangd/CodeCompleteTests.cpp @@ -1,9 +1,8 @@ //===-- CodeCompleteTests.cpp -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/CodeCompletionStringsTests.cpp b/unittests/clangd/CodeCompletionStringsTests.cpp index eab35e14..43429c86 100644 --- a/unittests/clangd/CodeCompletionStringsTests.cpp +++ b/unittests/clangd/CodeCompletionStringsTests.cpp @@ -1,9 +1,8 @@ //===-- CodeCompletionStringsTests.cpp --------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/ContextTests.cpp b/unittests/clangd/ContextTests.cpp index d5cb3ce6..d760f4eb 100644 --- a/unittests/clangd/ContextTests.cpp +++ b/unittests/clangd/ContextTests.cpp @@ -1,9 +1,8 @@ //===-- ContextTests.cpp - Context tests ------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/DexTests.cpp b/unittests/clangd/DexTests.cpp index 078bae27..ce318e2e 100644 --- a/unittests/clangd/DexTests.cpp +++ b/unittests/clangd/DexTests.cpp @@ -1,9 +1,8 @@ //===-- DexTests.cpp ---------------------------------*- C++ -*-----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/DraftStoreTests.cpp b/unittests/clangd/DraftStoreTests.cpp index 78057f3a..ba1007b2 100644 --- a/unittests/clangd/DraftStoreTests.cpp +++ b/unittests/clangd/DraftStoreTests.cpp @@ -1,9 +1,8 @@ //===-- DraftStoreTests.cpp -------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/ExpectedTypeTest.cpp b/unittests/clangd/ExpectedTypeTest.cpp index de3b486d..d109c790 100644 --- a/unittests/clangd/ExpectedTypeTest.cpp +++ b/unittests/clangd/ExpectedTypeTest.cpp @@ -1,9 +1,8 @@ //===-- ExpectedTypeTest.cpp -----------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/FSTests.cpp b/unittests/clangd/FSTests.cpp index 6c0bfec5..044452ca 100644 --- a/unittests/clangd/FSTests.cpp +++ b/unittests/clangd/FSTests.cpp @@ -1,9 +1,8 @@ //===-- FSTests.cpp - File system related tests -----------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/FileDistanceTests.cpp b/unittests/clangd/FileDistanceTests.cpp index 6d7d4777..30035829 100644 --- a/unittests/clangd/FileDistanceTests.cpp +++ b/unittests/clangd/FileDistanceTests.cpp @@ -1,9 +1,8 @@ //===-- FileDistanceTests.cpp ------------------------*- C++ -*-----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/FileIndexTests.cpp b/unittests/clangd/FileIndexTests.cpp index c3b11aef..f471e108 100644 --- a/unittests/clangd/FileIndexTests.cpp +++ b/unittests/clangd/FileIndexTests.cpp @@ -1,9 +1,8 @@ //===-- FileIndexTests.cpp ---------------------------*- C++ -*-----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/FindSymbolsTests.cpp b/unittests/clangd/FindSymbolsTests.cpp index 9b631596..3fb83237 100644 --- a/unittests/clangd/FindSymbolsTests.cpp +++ b/unittests/clangd/FindSymbolsTests.cpp @@ -1,9 +1,8 @@ //===-- FindSymbolsTests.cpp -------------------------*- C++ -*------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Annotations.h" diff --git a/unittests/clangd/FunctionTests.cpp b/unittests/clangd/FunctionTests.cpp index 613190dd..dc12186d 100644 --- a/unittests/clangd/FunctionTests.cpp +++ b/unittests/clangd/FunctionTests.cpp @@ -1,9 +1,8 @@ //===-- FunctionsTests.cpp ------------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/FuzzyMatchTests.cpp b/unittests/clangd/FuzzyMatchTests.cpp index 1c4062ca..d2ddbdaf 100644 --- a/unittests/clangd/FuzzyMatchTests.cpp +++ b/unittests/clangd/FuzzyMatchTests.cpp @@ -1,9 +1,8 @@ //===-- FuzzyMatchTests.cpp - String fuzzy matcher tests --------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/GlobalCompilationDatabaseTests.cpp b/unittests/clangd/GlobalCompilationDatabaseTests.cpp index b0052c75..7615963a 100644 --- a/unittests/clangd/GlobalCompilationDatabaseTests.cpp +++ b/unittests/clangd/GlobalCompilationDatabaseTests.cpp @@ -1,9 +1,8 @@ //===-- GlobalCompilationDatabaseTests.cpp ----------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/HeadersTests.cpp b/unittests/clangd/HeadersTests.cpp index 79f0b9cb..65bcb850 100644 --- a/unittests/clangd/HeadersTests.cpp +++ b/unittests/clangd/HeadersTests.cpp @@ -1,9 +1,8 @@ //===-- HeadersTests.cpp - Include headers unit tests -----------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/IndexActionTests.cpp b/unittests/clangd/IndexActionTests.cpp index 6a3da53a..55ec4594 100644 --- a/unittests/clangd/IndexActionTests.cpp +++ b/unittests/clangd/IndexActionTests.cpp @@ -1,9 +1,8 @@ //===------ IndexActionTests.cpp -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/IndexTests.cpp b/unittests/clangd/IndexTests.cpp index 3b7d6ff2..4ca88cae 100644 --- a/unittests/clangd/IndexTests.cpp +++ b/unittests/clangd/IndexTests.cpp @@ -1,9 +1,8 @@ //===-- IndexTests.cpp -------------------------------*- C++ -*-----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/JSONTransportTests.cpp b/unittests/clangd/JSONTransportTests.cpp index 23c39346..0498c813 100644 --- a/unittests/clangd/JSONTransportTests.cpp +++ b/unittests/clangd/JSONTransportTests.cpp @@ -1,9 +1,8 @@ //===-- JSONTransportTests.cpp -------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Protocol.h" diff --git a/unittests/clangd/Matchers.h b/unittests/clangd/Matchers.h index d666de36..0ace9706 100644 --- a/unittests/clangd/Matchers.h +++ b/unittests/clangd/Matchers.h @@ -1,9 +1,8 @@ //===-- Matchers.h ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/clangd/QualityTests.cpp b/unittests/clangd/QualityTests.cpp index 9175d6bc..259d296d 100644 --- a/unittests/clangd/QualityTests.cpp +++ b/unittests/clangd/QualityTests.cpp @@ -1,9 +1,8 @@ //===-- SourceCodeTests.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/clangd/RIFFTests.cpp b/unittests/clangd/RIFFTests.cpp index 7ea1466e..4cd54f40 100644 --- a/unittests/clangd/RIFFTests.cpp +++ b/unittests/clangd/RIFFTests.cpp @@ -1,9 +1,8 @@ //===-- RIFFTests.cpp - Binary container unit tests -----------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/SerializationTests.cpp b/unittests/clangd/SerializationTests.cpp index a8ffaa1c..3260ac68 100644 --- a/unittests/clangd/SerializationTests.cpp +++ b/unittests/clangd/SerializationTests.cpp @@ -1,9 +1,8 @@ //===-- SerializationTests.cpp - Binary and YAML serialization unit tests -===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/SourceCodeTests.cpp b/unittests/clangd/SourceCodeTests.cpp index b170c130..f7c97e00 100644 --- a/unittests/clangd/SourceCodeTests.cpp +++ b/unittests/clangd/SourceCodeTests.cpp @@ -1,9 +1,8 @@ //===-- SourceCodeTests.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "SourceCode.h" diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index 6f76b175..04a2d96f 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -1,9 +1,8 @@ //===-- SymbolCollectorTests.cpp -------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp index cbd178e6..369c2e75 100644 --- a/unittests/clangd/SymbolInfoTests.cpp +++ b/unittests/clangd/SymbolInfoTests.cpp @@ -1,9 +1,8 @@ //===-- SymbolInfoTests.cpp -----------------------*- C++ -*--------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Annotations.h" diff --git a/unittests/clangd/SyncAPI.cpp b/unittests/clangd/SyncAPI.cpp index 83e6b761..a6c255df 100644 --- a/unittests/clangd/SyncAPI.cpp +++ b/unittests/clangd/SyncAPI.cpp @@ -1,9 +1,8 @@ //===--- SyncAPI.cpp - Sync version of ClangdServer's API --------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/SyncAPI.h b/unittests/clangd/SyncAPI.h index f336e615..65a64798 100644 --- a/unittests/clangd/SyncAPI.h +++ b/unittests/clangd/SyncAPI.h @@ -1,9 +1,8 @@ //===--- SyncAPI.h - Sync version of ClangdServer's API ----------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/clangd/TUSchedulerTests.cpp b/unittests/clangd/TUSchedulerTests.cpp index 27cc6375..261c9b54 100644 --- a/unittests/clangd/TUSchedulerTests.cpp +++ b/unittests/clangd/TUSchedulerTests.cpp @@ -1,9 +1,8 @@ //===-- TUSchedulerTests.cpp ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/TestFS.cpp b/unittests/clangd/TestFS.cpp index 082f15a1..c5b2613f 100644 --- a/unittests/clangd/TestFS.cpp +++ b/unittests/clangd/TestFS.cpp @@ -1,9 +1,8 @@ //===-- TestFS.cpp ----------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "TestFS.h" diff --git a/unittests/clangd/TestFS.h b/unittests/clangd/TestFS.h index 0226fc3d..eabdddf7 100644 --- a/unittests/clangd/TestFS.h +++ b/unittests/clangd/TestFS.h @@ -1,9 +1,8 @@ //===-- TestFS.h ------------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/clangd/TestIndex.cpp b/unittests/clangd/TestIndex.cpp index 714d3a68..a909193d 100644 --- a/unittests/clangd/TestIndex.cpp +++ b/unittests/clangd/TestIndex.cpp @@ -1,9 +1,8 @@ //===-- IndexHelpers.cpp ----------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/TestIndex.h b/unittests/clangd/TestIndex.h index 01dcc086..6fef48d9 100644 --- a/unittests/clangd/TestIndex.h +++ b/unittests/clangd/TestIndex.h @@ -1,9 +1,8 @@ //===-- IndexHelpers.h ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/TestTU.cpp b/unittests/clangd/TestTU.cpp index 6706c449..740c4922 100644 --- a/unittests/clangd/TestTU.cpp +++ b/unittests/clangd/TestTU.cpp @@ -1,9 +1,8 @@ //===--- TestTU.cpp - Scratch source files for testing --------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/TestTU.h b/unittests/clangd/TestTU.h index ced612fa..26b48b32 100644 --- a/unittests/clangd/TestTU.h +++ b/unittests/clangd/TestTU.h @@ -1,9 +1,8 @@ //===--- TestTU.h - Scratch source files for testing -------------*- C++-*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/unittests/clangd/ThreadingTests.cpp b/unittests/clangd/ThreadingTests.cpp index dd27dcce..18b9146e 100644 --- a/unittests/clangd/ThreadingTests.cpp +++ b/unittests/clangd/ThreadingTests.cpp @@ -1,9 +1,8 @@ //===-- ThreadingTests.cpp --------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/TraceTests.cpp b/unittests/clangd/TraceTests.cpp index 98115651..1871e6ac 100644 --- a/unittests/clangd/TraceTests.cpp +++ b/unittests/clangd/TraceTests.cpp @@ -1,9 +1,8 @@ //===-- TraceTests.cpp - Tracing unit tests ---------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/URITests.cpp b/unittests/clangd/URITests.cpp index ae84d56e..52ca7b44 100644 --- a/unittests/clangd/URITests.cpp +++ b/unittests/clangd/URITests.cpp @@ -1,9 +1,8 @@ //===-- URITests.cpp ---------------------------------*- C++ -*-----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index 88394b6c..1af25487 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -1,9 +1,8 @@ //===-- XRefsTests.cpp ---------------------------*- C++ -*--------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 "Annotations.h" diff --git a/unittests/clangd/xpc/ConversionTests.cpp b/unittests/clangd/xpc/ConversionTests.cpp index 7acdc61f..5d0efd83 100644 --- a/unittests/clangd/xpc/ConversionTests.cpp +++ b/unittests/clangd/xpc/ConversionTests.cpp @@ -1,9 +1,8 @@ //===-- ConversionTests.cpp --------------------------*- C++ -*-----------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/include-fixer/FuzzySymbolIndexTests.cpp b/unittests/include-fixer/FuzzySymbolIndexTests.cpp index 17679c5d..3886269f 100644 --- a/unittests/include-fixer/FuzzySymbolIndexTests.cpp +++ b/unittests/include-fixer/FuzzySymbolIndexTests.cpp @@ -1,9 +1,8 @@ //===-- FuzzySymbolIndexTests.cpp - Fuzzy symbol index unit tests ---------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/include-fixer/IncludeFixerTest.cpp b/unittests/include-fixer/IncludeFixerTest.cpp index 519c0837..9b187485 100644 --- a/unittests/include-fixer/IncludeFixerTest.cpp +++ b/unittests/include-fixer/IncludeFixerTest.cpp @@ -1,9 +1,8 @@ //===-- IncludeFixerTest.cpp - Include fixer unit tests -------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp b/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp index 1ad9e7f0..179ad258 100644 --- a/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp +++ b/unittests/include-fixer/find-all-symbols/FindAllSymbolsTests.cpp @@ -1,9 +1,8 @@ //===-- FindAllSymbolsTests.cpp - find all symbols unit tests ---*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/unittests/include/common/VirtualFileHelper.h b/unittests/include/common/VirtualFileHelper.h index 5fa4d53a..03eddb87 100644 --- a/unittests/include/common/VirtualFileHelper.h +++ b/unittests/include/common/VirtualFileHelper.h @@ -1,9 +1,8 @@ //===--- VirtualFileHelper.h ------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// -- cgit v1.2.3 From 90f36400b007503d1286190771260f8e37f9947a Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Sun, 20 Jan 2019 14:28:27 +0000 Subject: [clang-tidy] misc-non-private-member-variables-in-classes: ignore implicit methods Otherwise we don't warn on a struct containing a single public int, but we warn on a struct containing a single public std::string, which is inconsistent. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351686 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../misc/NonPrivateMemberVariablesInClassesCheck.cpp | 11 ++++++----- .../misc-non-private-member-variables-in-classes.rst | 10 +++++----- .../misc-non-private-member-variables-in-classes.cpp | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp index 549647ff..7f57fecd 100644 --- a/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp +++ b/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp @@ -22,8 +22,8 @@ AST_MATCHER(CXXRecordDecl, hasMethods) { return std::distance(Node.method_begin(), Node.method_end()) != 0; } -AST_MATCHER(CXXRecordDecl, hasNonStaticMethod) { - return hasMethod(unless(isStaticStorageClass())) +AST_MATCHER(CXXRecordDecl, hasNonStaticNonImplicitMethod) { + return hasMethod(unless(anyOf(isStaticStorageClass(), isImplicit()))) .matches(Node, Finder, Builder); } @@ -66,10 +66,11 @@ void NonPrivateMemberVariablesInClassesCheck::registerMatchers( IgnorePublicMemberVariables ? isProtected() : unless(isPrivate())); // We only want the records that not only contain the mutable data (non-static - // member variables), but also have some logic (non-static member functions). - // We may optionally ignore records where all the member variables are public. + // member variables), but also have some logic (non-static, non-implicit + // member functions). We may optionally ignore records where all the member + // variables are public. Finder->addMatcher(cxxRecordDecl(anyOf(isStruct(), isClass()), hasMethods(), - hasNonStaticMethod(), + hasNonStaticNonImplicitMethod(), unless(ShouldIgnoreRecord), forEach(InterestingField.bind("field"))) .bind("record"), diff --git a/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst b/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst index db88c9b1..57990622 100644 --- a/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst +++ b/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst @@ -6,11 +6,11 @@ misc-non-private-member-variables-in-classes `cppcoreguidelines-non-private-member-variables-in-classes` redirects here as an alias for this check. -Finds classes that contain non-static data members in addition to non-static -member functions and diagnose all data members declared with a non-``public`` -access specifier. The data members should be declared as ``private`` and -accessed through member functions instead of exposed to derived classes or -class consumers. +Finds classes that contain non-static data members in addition to user-declared +non-static member functions and diagnose all data members declared with a +non-``public`` access specifier. The data members should be declared as +``private`` and accessed through member functions instead of exposed to derived +classes or class consumers. Options ------- diff --git a/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp b/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp index 31052716..2a93ff6a 100644 --- a/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp +++ b/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp @@ -35,6 +35,23 @@ private: int S1_v3; }; +// Only data and implicit or static methods, do not warn + +class C { +public: + C() {} + ~C() {} +}; + +struct S1Implicit { + C S1Implicit_v0; +}; + +struct S1ImplicitAndStatic { + C S1Implicit_v0; + static void s() {} +}; + //----------------------------------------------------------------------------// // All functions are static, do not warn. -- cgit v1.2.3 From 94f89dda790fc5a3f316573e1850073c31083b0f Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 21 Jan 2019 09:52:34 +0000 Subject: Fix typos throughout the license files that somehow I and my reviewers all missed! Thanks to Alex Bradbury for pointing this out, and the fact that I never added the intended `legacy` anchor to the developer policy. Add that anchor too. With hope, this will cause the links to all resolve successfully. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351731 91177308-0d34-0410-b5e6-96231b3b80d8 --- LICENSE.TXT | 2 +- clang-tidy-vs/ClangTidy/license.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LICENSE.TXT b/LICENSE.TXT index 27f66f00..24806ab4 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -234,7 +234,7 @@ mechanisms: file. ============================================================================== -Legacy LLVM License (ttps://llvm.org/docs/DeveloperPolicy.html#legacy): +Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License diff --git a/clang-tidy-vs/ClangTidy/license.txt b/clang-tidy-vs/ClangTidy/license.txt index 92392772..d3d7ed3c 100644 --- a/clang-tidy-vs/ClangTidy/license.txt +++ b/clang-tidy-vs/ClangTidy/license.txt @@ -234,7 +234,7 @@ mechanisms: file. ============================================================================== -Legacy LLVM License (ttps://llvm.org/docs/DeveloperPolicy.html#legacy): +Legacy LLVM License (https://llvm.org/docs/DeveloperPolicy.html#legacy): ============================================================================== University of Illinois/NCSA Open Source License -- cgit v1.2.3 From 3252b378237935fefb1a7e181737af7568a7c8fc Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 21 Jan 2019 10:10:18 +0000 Subject: [clang-tidy] Use getStripPluginsAdjuster Summary: See rC351531 for the introduction of getStripPluginsAdjuster. Reviewers: alexfh Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D56902 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351738 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/ClangTidy.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/clang-tidy/ClangTidy.cpp b/clang-tidy/ClangTidy.cpp index 974c7d59..6534fd44 100644 --- a/clang-tidy/ClangTidy.cpp +++ b/clang-tidy/ClangTidy.cpp @@ -528,24 +528,8 @@ runClangTidy(clang::tidy::ClangTidyContext &Context, return AdjustedArgs; }; - // Remove plugins arguments. - ArgumentsAdjuster PluginArgumentsRemover = - [](const CommandLineArguments &Args, StringRef Filename) { - CommandLineArguments AdjustedArgs; - for (size_t I = 0, E = Args.size(); I < E; ++I) { - if (I + 4 < Args.size() && Args[I] == "-Xclang" && - (Args[I + 1] == "-load" || Args[I + 1] == "-add-plugin" || - StringRef(Args[I + 1]).startswith("-plugin-arg-")) && - Args[I + 2] == "-Xclang") { - I += 3; - } else - AdjustedArgs.push_back(Args[I]); - } - return AdjustedArgs; - }; - Tool.appendArgumentsAdjuster(PerFileExtraArgumentsInserter); - Tool.appendArgumentsAdjuster(PluginArgumentsRemover); + Tool.appendArgumentsAdjuster(getStripPluginsAdjuster()); Context.setEnableProfiling(EnableCheckProfile); Context.setProfileStoragePrefix(StoreCheckProfile); -- cgit v1.2.3 From 10ead75b2238df9e3ddb19dc73431a57cb0ffb66 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Mon, 21 Jan 2019 16:26:54 +0000 Subject: [clang-tidy] Work around http://llvm.org/PR40392 The readability-else-after-return check should be smarter about cases where the variable defined in the condition is used in the `else` branch. This patch makes it just ignore such cases, but alternative solutions may be better (added a FIXME). git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351751 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/readability/ElseAfterReturnCheck.cpp | 14 ++++++++++---- test/clang-tidy/readability-else-after-return.cpp | 12 ++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/clang-tidy/readability/ElseAfterReturnCheck.cpp b/clang-tidy/readability/ElseAfterReturnCheck.cpp index 312debbb..520586df 100644 --- a/clang-tidy/readability/ElseAfterReturnCheck.cpp +++ b/clang-tidy/readability/ElseAfterReturnCheck.cpp @@ -18,16 +18,22 @@ namespace tidy { namespace readability { void ElseAfterReturnCheck::registerMatchers(MatchFinder *Finder) { - const auto ControlFlowInterruptorMatcher = + const auto InterruptsControlFlow = stmt(anyOf(returnStmt().bind("return"), continueStmt().bind("continue"), breakStmt().bind("break"), expr(ignoringImplicit(cxxThrowExpr().bind("throw"))))); Finder->addMatcher( compoundStmt(forEach( ifStmt(unless(isConstexpr()), - hasThen(stmt( - anyOf(ControlFlowInterruptorMatcher, - compoundStmt(has(ControlFlowInterruptorMatcher))))), + // FIXME: Explore alternatives for the + // `if (T x = ...) {... return; } else { }` + // pattern: + // * warn, but don't fix; + // * fix by pulling out the variable declaration out of + // the condition. + unless(hasConditionVariableStatement(anything())), + hasThen(stmt(anyOf(InterruptsControlFlow, + compoundStmt(has(InterruptsControlFlow))))), hasElse(stmt().bind("else"))) .bind("if"))), this); diff --git a/test/clang-tidy/readability-else-after-return.cpp b/test/clang-tidy/readability-else-after-return.cpp index 7e950928..b06c02c9 100644 --- a/test/clang-tidy/readability-else-after-return.cpp +++ b/test/clang-tidy/readability-else-after-return.cpp @@ -105,3 +105,15 @@ void foo() { } } } + +extern int *g(); +extern void h(int **x); + +int *decl_in_condition() { + if (int *x = g()) { + return x; + } else { + h(&x); + return x; + } +} -- cgit v1.2.3 From 2019b52813fb4ea94c218ffa9cb386612bacda98 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 22 Jan 2019 09:10:20 +0000 Subject: [clangd] Filter out plugin related flags and move all commandline manipulations into OverlayCDB. Summary: Some projects make use of clang plugins when building, but clangd is not aware of those plugins therefore can't work with the same compile command arguments. There were multiple places clangd performed commandline manipulations, this one also moves them all into OverlayCDB. Reviewers: ilya-biryukov Subscribers: klimek, sammccall, ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D56841 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351788 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 3 +- clangd/ClangdServer.cpp | 13 +------ clangd/GlobalCompilationDatabase.cpp | 41 +++++++++++++++++++--- clangd/GlobalCompilationDatabase.h | 5 ++- clangd/index/Background.cpp | 10 +++--- clangd/index/Background.h | 5 +-- unittests/clangd/BackgroundIndexTests.cpp | 24 ++++++------- unittests/clangd/ClangdTests.cpp | 23 ++++++++++++ .../clangd/GlobalCompilationDatabaseTests.cpp | 4 +-- 9 files changed, 86 insertions(+), 42 deletions(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 057426fd..d3ee6aa5 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -289,7 +289,8 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, if (UseDirBasedCDB) BaseCDB = llvm::make_unique( CompileCommandsDir); - CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags); + CDB.emplace(BaseCDB.get(), Params.initializationOptions.fallbackFlags, + ClangdServerOpts.ResourceDir); Server.emplace(*CDB, FSProvider, static_cast(*this), ClangdServerOpts); applyConfiguration(Params.initializationOptions.ConfigSettings); diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 24714256..d70321da 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -37,11 +37,6 @@ namespace clang { namespace clangd { namespace { -std::string getStandardResourceDir() { - static int Dummy; // Just an address in this process. - return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); -} - class RefactoringResultCollector final : public tooling::RefactoringResultConsumer { public: @@ -107,8 +102,6 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, DiagnosticsConsumer &DiagConsumer, const Options &Opts) : CDB(CDB), FSProvider(FSProvider), - ResourceDir(Opts.ResourceDir ? *Opts.ResourceDir - : getStandardResourceDir()), DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), @@ -136,7 +129,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, AddIndex(Opts.StaticIndex); if (Opts.BackgroundIndex) { BackgroundIdx = llvm::make_unique( - Context::current().clone(), ResourceDir, FSProvider, CDB, + Context::current().clone(), FSProvider, CDB, BackgroundIndexStorage::createDiskBackedStorageFactory(), Opts.BackgroundIndexRebuildPeriodMs); AddIndex(BackgroundIdx.get()); @@ -461,10 +454,6 @@ tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) { llvm::Optional C = CDB.getCompileCommand(File); if (!C) // FIXME: Suppress diagnostics? Let the user know? C = CDB.getFallbackCommand(File); - - // Inject the resource dir. - // FIXME: Don't overwrite it if it's already there. - C->CommandLine.push_back("-resource-dir=" + ResourceDir); return std::move(*C); } diff --git a/clangd/GlobalCompilationDatabase.cpp b/clangd/GlobalCompilationDatabase.cpp index 95e7ce7b..a9161972 100644 --- a/clangd/GlobalCompilationDatabase.cpp +++ b/clangd/GlobalCompilationDatabase.cpp @@ -8,12 +8,36 @@ #include "GlobalCompilationDatabase.h" #include "Logger.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CompilationDatabase.h" +#include "llvm/ADT/Optional.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" namespace clang { namespace clangd { +namespace { + +void adjustArguments(tooling::CompileCommand &Cmd, + llvm::StringRef ResourceDir) { + // Strip plugin related command line arguments. Clangd does + // not support plugins currently. Therefore it breaks if + // compiler tries to load plugins. + Cmd.CommandLine = + tooling::getStripPluginsAdjuster()(Cmd.CommandLine, Cmd.Filename); + // Inject the resource dir. + // FIXME: Don't overwrite it if it's already there. + if (!ResourceDir.empty()) + Cmd.CommandLine.push_back(("-resource-dir=" + ResourceDir).str()); +} + +std::string getStandardResourceDir() { + static int Dummy; // Just an address in this process. + return CompilerInvocation::GetResourcesPath("clangd", (void *)&Dummy); +} + +} // namespace static std::string getFallbackClangPath() { static int Dummy; @@ -105,8 +129,11 @@ DirectoryBasedGlobalCompilationDatabase::getCDBForFile( } OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base, - std::vector FallbackFlags) - : Base(Base), FallbackFlags(std::move(FallbackFlags)) { + std::vector FallbackFlags, + llvm::Optional ResourceDir) + : Base(Base), ResourceDir(ResourceDir ? std::move(*ResourceDir) + : getStandardResourceDir()), + FallbackFlags(std::move(FallbackFlags)) { if (Base) BaseChanged = Base->watch([this](const std::vector Changes) { OnCommandChanged.broadcast(Changes); @@ -115,16 +142,22 @@ OverlayCDB::OverlayCDB(const GlobalCompilationDatabase *Base, llvm::Optional OverlayCDB::getCompileCommand(PathRef File, ProjectInfo *Project) const { + llvm::Optional Cmd; { std::lock_guard Lock(Mutex); auto It = Commands.find(File); if (It != Commands.end()) { if (Project) Project->SourceRoot = ""; - return It->second; + Cmd = It->second; } } - return Base ? Base->getCompileCommand(File, Project) : None; + if (!Cmd && Base) + Cmd = Base->getCompileCommand(File, Project); + if (!Cmd) + return llvm::None; + adjustArguments(*Cmd, ResourceDir); + return Cmd; } tooling::CompileCommand OverlayCDB::getFallbackCommand(PathRef File) const { diff --git a/clangd/GlobalCompilationDatabase.h b/clangd/GlobalCompilationDatabase.h index 3f3bea44..0a97a30e 100644 --- a/clangd/GlobalCompilationDatabase.h +++ b/clangd/GlobalCompilationDatabase.h @@ -11,6 +11,7 @@ #include "Function.h" #include "Path.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringMap.h" #include #include @@ -97,7 +98,8 @@ public: // Base may be null, in which case no entries are inherited. // FallbackFlags are added to the fallback compile command. OverlayCDB(const GlobalCompilationDatabase *Base, - std::vector FallbackFlags = {}); + std::vector FallbackFlags = {}, + llvm::Optional ResourceDir = llvm::None); llvm::Optional getCompileCommand(PathRef File, ProjectInfo * = nullptr) const override; @@ -112,6 +114,7 @@ private: mutable std::mutex Mutex; llvm::StringMap Commands; /* GUARDED_BY(Mut) */ const GlobalCompilationDatabase *Base; + std::string ResourceDir; std::vector FallbackFlags; CommandChanged::Subscription BaseChanged; }; diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp index aa67598d..ddb0ec43 100644 --- a/clangd/index/Background.cpp +++ b/clangd/index/Background.cpp @@ -126,13 +126,12 @@ llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) { } // namespace BackgroundIndex::BackgroundIndex( - Context BackgroundContext, llvm::StringRef ResourceDir, - const FileSystemProvider &FSProvider, const GlobalCompilationDatabase &CDB, + Context BackgroundContext, const FileSystemProvider &FSProvider, + const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t BuildIndexPeriodMs, size_t ThreadPoolSize) - : SwapIndex(llvm::make_unique()), ResourceDir(ResourceDir), - FSProvider(FSProvider), CDB(CDB), - BackgroundContext(std::move(BackgroundContext)), + : SwapIndex(llvm::make_unique()), FSProvider(FSProvider), + CDB(CDB), BackgroundContext(std::move(BackgroundContext)), BuildIndexPeriodMs(BuildIndexPeriodMs), SymbolsUpdatedSinceLastIndex(false), IndexStorageFactory(std::move(IndexStorageFactory)), @@ -229,7 +228,6 @@ void BackgroundIndex::enqueue(tooling::CompileCommand Cmd, BackgroundIndexStorage *Storage) { enqueueTask(Bind( [this, Storage](tooling::CompileCommand Cmd) { - Cmd.CommandLine.push_back("-resource-dir=" + ResourceDir); // We can't use llvm::StringRef here since we are going to // move from Cmd during the call below. const std::string FileName = Cmd.Filename; diff --git a/clangd/index/Background.h b/clangd/index/Background.h index 2cfbd0e9..ea8ab581 100644 --- a/clangd/index/Background.h +++ b/clangd/index/Background.h @@ -67,9 +67,7 @@ public: /// If BuildIndexPeriodMs is greater than 0, the symbol index will only be /// rebuilt periodically (one per \p BuildIndexPeriodMs); otherwise, index is /// rebuilt for each indexed file. - // FIXME: resource-dir injection should be hoisted somewhere common. - BackgroundIndex(Context BackgroundContext, llvm::StringRef ResourceDir, - const FileSystemProvider &, + BackgroundIndex(Context BackgroundContext, const FileSystemProvider &, const GlobalCompilationDatabase &CDB, BackgroundIndexStorage::Factory IndexStorageFactory, size_t BuildIndexPeriodMs = 0, @@ -98,7 +96,6 @@ private: BackgroundIndexStorage *IndexStorage); // configuration - std::string ResourceDir; const FileSystemProvider &FSProvider; const GlobalCompilationDatabase &CDB; Context BackgroundContext; diff --git a/unittests/clangd/BackgroundIndexTests.cpp b/unittests/clangd/BackgroundIndexTests.cpp index 639d35c8..09a117db 100644 --- a/unittests/clangd/BackgroundIndexTests.cpp +++ b/unittests/clangd/BackgroundIndexTests.cpp @@ -76,7 +76,7 @@ TEST_F(BackgroundIndexTest, NoCrashOnErrorFile) { size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); tooling::CompileCommand Cmd; @@ -113,7 +113,7 @@ TEST_F(BackgroundIndexTest, IndexTwoFiles) { size_t CacheHits = 0; MemoryShardStorage MSS(Storage, CacheHits); OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); tooling::CompileCommand Cmd; @@ -168,7 +168,7 @@ TEST_F(BackgroundIndexTest, ShardStorageTest) { // Check nothing is loaded from Storage, but A.cc and A.h has been stored. { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -178,7 +178,7 @@ TEST_F(BackgroundIndexTest, ShardStorageTest) { { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -224,7 +224,7 @@ TEST_F(BackgroundIndexTest, DirectIncludesTest) { Cmd.CommandLine = {"clang++", testPath("root/A.cc")}; { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -262,7 +262,7 @@ TEST_F(BackgroundIndexTest, DISABLED_PeriodicalIndex) { MemoryShardStorage MSS(Storage, CacheHits); OverlayCDB CDB(/*Base=*/nullptr); BackgroundIndex Idx( - Context::empty(), "", FS, CDB, [&](llvm::StringRef) { return &MSS; }, + Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }, /*BuildIndexPeriodMs=*/500); FS.Files[testPath("root/A.cc")] = "#include \"A.h\""; @@ -310,7 +310,7 @@ TEST_F(BackgroundIndexTest, ShardStorageLoad) { // Check nothing is loaded from Storage, but A.cc and A.h has been stored. { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -325,7 +325,7 @@ TEST_F(BackgroundIndexTest, ShardStorageLoad) { )cpp"; { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -343,7 +343,7 @@ TEST_F(BackgroundIndexTest, ShardStorageLoad) { { CacheHits = 0; OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -384,7 +384,7 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { // Check that A.cc, A.h and B.h has been stored. { OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -400,7 +400,7 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { { CacheHits = 0; OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); @@ -416,7 +416,7 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { { CacheHits = 0; OverlayCDB CDB(/*Base=*/nullptr); - BackgroundIndex Idx(Context::empty(), "", FS, CDB, + BackgroundIndex Idx(Context::empty(), FS, CDB, [&](llvm::StringRef) { return &MSS; }); CDB.setCompileCommand(testPath("root/A.cc"), Cmd); ASSERT_TRUE(Idx.blockUntilIdleForTest()); diff --git a/unittests/clangd/ClangdTests.cpp b/unittests/clangd/ClangdTests.cpp index 26b6065e..871348ac 100644 --- a/unittests/clangd/ClangdTests.cpp +++ b/unittests/clangd/ClangdTests.cpp @@ -9,6 +9,7 @@ #include "Annotations.h" #include "ClangdLSPServer.h" #include "ClangdServer.h" +#include "GlobalCompilationDatabase.h" #include "Matchers.h" #include "SyncAPI.h" #include "TestFS.h" @@ -1036,6 +1037,28 @@ TEST(ClangdTests, PreambleVFSStatCache) { } #endif +TEST_F(ClangdVFSTest, FlagsWithPlugins) { + MockFSProvider FS; + ErrorCheckingDiagConsumer DiagConsumer; + MockCompilationDatabase CDB; + CDB.ExtraClangFlags = { + "-Xclang", + "-add-plugin", + "-Xclang", + "random-plugin", + }; + OverlayCDB OCDB(&CDB); + ClangdServer Server(OCDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + auto FooCpp = testPath("foo.cpp"); + const auto SourceContents = "int main() { return 0; }"; + FS.Files[FooCpp] = FooCpp; + Server.addDocument(FooCpp, SourceContents); + auto Result = dumpASTWithoutMemoryLocs(Server, FooCpp); + EXPECT_TRUE(Server.blockUntilIdleForTest()) << "Waiting for diagnostics"; + EXPECT_NE(Result, ""); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/unittests/clangd/GlobalCompilationDatabaseTests.cpp b/unittests/clangd/GlobalCompilationDatabaseTests.cpp index 7615963a..a1b696f6 100644 --- a/unittests/clangd/GlobalCompilationDatabaseTests.cpp +++ b/unittests/clangd/GlobalCompilationDatabaseTests.cpp @@ -64,7 +64,7 @@ protected: }; TEST_F(OverlayCDBTest, GetCompileCommand) { - OverlayCDB CDB(Base.get()); + OverlayCDB CDB(Base.get(), {}, std::string("")); EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")), Base->getCompileCommand(testPath("foo.cc"))); EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None); @@ -84,7 +84,7 @@ TEST_F(OverlayCDBTest, GetFallbackCommand) { } TEST_F(OverlayCDBTest, NoBase) { - OverlayCDB CDB(nullptr, {"-DA=6"}); + OverlayCDB CDB(nullptr, {"-DA=6"}, std::string("")); EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), None); auto Override = cmd(testPath("bar.cc"), "-DA=5"); CDB.setCompileCommand(testPath("bar.cc"), Override); -- cgit v1.2.3 From e0844947aa2ca638f840d176ff01207fae0e9150 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 22 Jan 2019 09:39:05 +0000 Subject: [clangd] Support clang-tidy configuration in clangd. Summary: This patch adds some basic supports for clang-tidy configurations in clangd: - clangd will respect .clang-tidy configurations for each file - we don't aim to support all clang-tidy options in clangd, only a small subset of condfigurations (options related to which checks will be enabled) are supported. - add a `clang-tidy-checks` CLI option that can override options from .clang-tidy file Reviewers: ilya-biryukov, sammccall Reviewed By: sammccall Subscribers: javed.absar, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D55256 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351792 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 4 +++- clangd/ClangdLSPServer.h | 5 +++-- clangd/ClangdServer.cpp | 10 +++++++--- clangd/ClangdServer.h | 11 +++++++++++ clangd/ClangdUnit.cpp | 17 +++++++---------- clangd/ClangdUnit.h | 5 ++++- clangd/tool/ClangdMain.cpp | 17 ++++++++++++++++- unittests/clangd/ClangdUnitTests.cpp | 3 +++ unittests/clangd/FileIndexTests.cpp | 3 ++- unittests/clangd/TUSchedulerTests.cpp | 3 ++- unittests/clangd/TestTU.cpp | 2 ++ unittests/clangd/TestTU.h | 2 ++ 12 files changed, 62 insertions(+), 20 deletions(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index d3ee6aa5..e90ee916 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -720,11 +720,13 @@ void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params, } ClangdLSPServer::ClangdLSPServer(class Transport &Transp, + const FileSystemProvider &FSProvider, const clangd::CodeCompleteOptions &CCOpts, llvm::Optional CompileCommandsDir, bool UseDirBasedCDB, const ClangdServer::Options &Opts) - : Transp(Transp), MsgHandler(new MessageHandler(*this)), CCOpts(CCOpts), + : Transp(Transp), MsgHandler(new MessageHandler(*this)), + FSProvider(FSProvider), CCOpts(CCOpts), SupportedSymbolKinds(defaultSymbolKinds()), SupportedCompletionItemKinds(defaultCompletionItemKinds()), UseDirBasedCDB(UseDirBasedCDB), diff --git a/clangd/ClangdLSPServer.h b/clangd/ClangdLSPServer.h index d84c298e..40b9fc40 100644 --- a/clangd/ClangdLSPServer.h +++ b/clangd/ClangdLSPServer.h @@ -37,7 +37,8 @@ public: /// for compile_commands.json in all parent directories of each file. /// If UseDirBasedCDB is false, compile commands are not read from disk. // FIXME: Clean up signature around CDBs. - ClangdLSPServer(Transport &Transp, const clangd::CodeCompleteOptions &CCOpts, + ClangdLSPServer(Transport &Transp, const FileSystemProvider &FSProvider, + const clangd::CodeCompleteOptions &CCOpts, llvm::Optional CompileCommandsDir, bool UseDirBasedCDB, const ClangdServer::Options &Opts); ~ClangdLSPServer(); @@ -128,7 +129,7 @@ private: void call(StringRef Method, llvm::json::Value Params); void notify(StringRef Method, llvm::json::Value Params); - RealFileSystemProvider FSProvider; + const FileSystemProvider &FSProvider; /// Options used for code completion clangd::CodeCompleteOptions CCOpts; /// Options used for diagnostics. diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index d70321da..5f494210 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -105,6 +105,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, DynamicIdx(Opts.BuildDynamicSymbolIndex ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), + ClangTidyOptProvider(Opts.ClangTidyOptProvider), WorkspaceRoot(Opts.WorkspaceRoot), PCHs(std::make_shared()), // Pass a callback into `WorkScheduler` to extract symbols from a newly @@ -140,13 +141,16 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags) { + tidy::ClangTidyOptions Options = tidy::ClangTidyOptions::getDefaults(); + if (ClangTidyOptProvider) + Options = ClangTidyOptProvider->getOptions(File); // FIXME: some build systems like Bazel will take time to preparing // environment to build the file, it would be nice if we could emit a // "PreparingBuild" status to inform users, it is non-trivial given the // current implementation. - WorkScheduler.update(File, - ParseInputs{getCompileCommand(File), - FSProvider.getFileSystem(), Contents.str()}, + WorkScheduler.update(File, ParseInputs{getCompileCommand(File), + FSProvider.getFileSystem(), + Contents.str(), Options}, WantDiags); } diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index 20874c4b..dc9581b5 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDSERVER_H +#include "../clang-tidy/ClangTidyOptions.h" #include "Cancellation.h" #include "ClangdUnit.h" #include "CodeComplete.h" @@ -92,6 +93,13 @@ public: /// If set, use this index to augment code completion results. SymbolIndex *StaticIndex = nullptr; + /// If set, enable clang-tidy in clangd, used to get clang-tidy + /// configurations for a particular file. + /// Clangd supports only a small subset of ClangTidyOptions, these options + /// (Checks, CheckOptions) are about which clang-tidy checks will be + /// enabled. + tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr; + /// Clangd's workspace root. Relevant for "workspace" operations not bound /// to a particular file. /// FIXME: If not set, should use the current working directory. @@ -257,6 +265,9 @@ private: // Storage for merged views of the various indexes. std::vector> MergedIdx; + // The provider used to provide a clang-tidy option for a specific file. + tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr; + // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex) llvm::StringMap> CachedCompletionFuzzyFindRequestByFile; diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index f7b8b731..268f7d1b 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -132,6 +132,9 @@ public: CompilerInstance &Clang) { auto &PP = Clang.getPreprocessor(); auto *ExistingCallbacks = PP.getPPCallbacks(); + // No need to replay events if nobody is listening. + if (!ExistingCallbacks) + return; PP.addPPCallbacks(std::unique_ptr( new ReplayPreamble(Includes, ExistingCallbacks, Clang.getSourceManager(), PP, Clang.getLangOpts()))); @@ -227,7 +230,8 @@ ParsedAST::build(std::unique_ptr CI, std::shared_ptr Preamble, std::unique_ptr Buffer, std::shared_ptr PCHs, - llvm::IntrusiveRefCntPtr VFS) { + llvm::IntrusiveRefCntPtr VFS, + const tidy::ClangTidyOptions &ClangTidyOpts) { assert(CI); // Command-line parsing sets DisableFree to true by default, but we don't want // to leak memory in clangd. @@ -264,15 +268,8 @@ ParsedAST::build(std::unique_ptr CI, tidy::ClangTidyCheckFactories CTFactories; for (const auto &E : tidy::ClangTidyModuleRegistry::entries()) E.instantiate()->addCheckFactories(CTFactories); - auto CTOpts = tidy::ClangTidyOptions::getDefaults(); - // FIXME: this needs to be configurable, and we need to support .clang-tidy - // files and other options providers. - // These checks exercise the matcher- and preprocessor-based hooks. - CTOpts.Checks = "bugprone-sizeof-expression," - "bugprone-macro-repeated-side-effects," - "modernize-deprecated-headers"; CTContext.emplace(llvm::make_unique( - tidy::ClangTidyGlobalOptions(), CTOpts)); + tidy::ClangTidyGlobalOptions(), ClangTidyOpts)); CTContext->setDiagnosticsEngine(&Clang->getDiagnostics()); CTContext->setASTContext(&Clang->getASTContext()); CTContext->setCurrentFile(MainInput.getFile()); @@ -538,7 +535,7 @@ buildAST(PathRef FileName, std::unique_ptr Invocation, return ParsedAST::build(llvm::make_unique(*Invocation), Preamble, llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents), - PCHs, std::move(VFS)); + PCHs, std::move(VFS), Inputs.ClangTidyOpts); } SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index abcefdb6..3a4841d7 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H +#include "../clang-tidy/ClangTidyOptions.h" #include "Diagnostics.h" #include "FS.h" #include "Function.h" @@ -64,6 +65,7 @@ struct ParseInputs { tooling::CompileCommand CompileCommand; IntrusiveRefCntPtr FS; std::string Contents; + tidy::ClangTidyOptions ClangTidyOpts; }; /// Stores and provides access to parsed AST. @@ -76,7 +78,8 @@ public: std::shared_ptr Preamble, std::unique_ptr Buffer, std::shared_ptr PCHs, - IntrusiveRefCntPtr VFS); + IntrusiveRefCntPtr VFS, + const tidy::ClangTidyOptions &ClangTidyOpts); ParsedAST(ParsedAST &&Other); ParsedAST &operator=(ParsedAST &&Other); diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index 80f3f45e..c969a5b7 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -201,6 +201,12 @@ static llvm::cl::opt EnableFunctionArgSnippets( "placeholders for method parameters."), llvm::cl::init(CodeCompleteOptions().EnableFunctionArgSnippets)); +static llvm::cl::opt ClangTidyChecks( + "clang-tidy-checks", + llvm::cl::desc("List of clang-tidy checks to run (this will overrides " + ".clang-tidy files)"), + llvm::cl::init(""), llvm::cl::Hidden); + namespace { /// \brief Supports a test URI scheme with relaxed constraints for lit tests. @@ -408,6 +414,7 @@ int main(int argc, char *argv[]) { CCOpts.EnableFunctionArgSnippets = EnableFunctionArgSnippets; CCOpts.AllScopes = AllScopesCompletion; + RealFileSystemProvider FSProvider; // Initialize and run ClangdLSPServer. // Change stdin to binary to not lose \r\n on windows. llvm::sys::ChangeStdinToBinary(); @@ -427,8 +434,16 @@ int main(int argc, char *argv[]) { PrettyPrint, InputStyle); } + // Create an empty clang-tidy option. + auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); + OverrideClangTidyOptions.Checks = ClangTidyChecks; + tidy::FileOptionsProvider ClangTidyOptProvider( + tidy::ClangTidyGlobalOptions(), + /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); + Opts.ClangTidyOptProvider = &ClangTidyOptProvider; ClangdLSPServer LSPServer( - *TransportLayer, CCOpts, CompileCommandsDirPath, + *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath, /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs, Opts); llvm::set_thread_name("clangd.main"); return LSPServer.run() ? 0 diff --git a/unittests/clangd/ClangdUnitTests.cpp b/unittests/clangd/ClangdUnitTests.cpp index 04154078..b5e83a08 100644 --- a/unittests/clangd/ClangdUnitTests.cpp +++ b/unittests/clangd/ClangdUnitTests.cpp @@ -141,6 +141,9 @@ TEST(DiagnosticsTest, ClangTidy) { )cpp"); auto TU = TestTU::withCode(Test.code()); TU.HeaderFilename = "assert.h"; // Suppress "not found" error. + TU.ClangTidyChecks = + "-*, bugprone-sizeof-expression, bugprone-macro-repeated-side-effects, " + "modernize-deprecated-headers"; EXPECT_THAT( TU.build().getDiagnostics(), UnorderedElementsAre( diff --git a/unittests/clangd/FileIndexTests.cpp b/unittests/clangd/FileIndexTests.cpp index f471e108..b0c21c0d 100644 --- a/unittests/clangd/FileIndexTests.cpp +++ b/unittests/clangd/FileIndexTests.cpp @@ -363,7 +363,8 @@ TEST(FileIndexTest, ReferencesInMainFileWithPreamble) { auto AST = ParsedAST::build(createInvocationFromCommandLine(Cmd), PreambleData, llvm::MemoryBuffer::getMemBufferCopy(Main.code()), - std::make_shared(), PI.FS); + std::make_shared(), PI.FS, + tidy::ClangTidyOptions::getDefaults()); ASSERT_TRUE(AST); FileIndex Index; Index.updateMain(MainFile, *AST); diff --git a/unittests/clangd/TUSchedulerTests.cpp b/unittests/clangd/TUSchedulerTests.cpp index 261c9b54..79ee779d 100644 --- a/unittests/clangd/TUSchedulerTests.cpp +++ b/unittests/clangd/TUSchedulerTests.cpp @@ -38,7 +38,8 @@ class TUSchedulerTests : public ::testing::Test { protected: ParseInputs getInputs(PathRef File, std::string Contents) { return ParseInputs{*CDB.getCompileCommand(File), - buildTestFS(Files, Timestamps), std::move(Contents)}; + buildTestFS(Files, Timestamps), std::move(Contents), + tidy::ClangTidyOptions::getDefaults()}; } void updateWithCallback(TUScheduler &S, PathRef File, diff --git a/unittests/clangd/TestTU.cpp b/unittests/clangd/TestTU.cpp index 740c4922..067d3f3f 100644 --- a/unittests/clangd/TestTU.cpp +++ b/unittests/clangd/TestTU.cpp @@ -35,6 +35,8 @@ ParsedAST TestTU::build() const { Inputs.CompileCommand.Directory = testRoot(); Inputs.Contents = Code; Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}}); + Inputs.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); + Inputs.ClangTidyOpts.Checks = ClangTidyChecks; auto PCHs = std::make_shared(); auto CI = buildCompilerInvocation(Inputs); assert(CI && "Failed to build compilation invocation."); diff --git a/unittests/clangd/TestTU.h b/unittests/clangd/TestTU.h index 26b48b32..7b84e4b5 100644 --- a/unittests/clangd/TestTU.h +++ b/unittests/clangd/TestTU.h @@ -48,6 +48,8 @@ struct TestTU { // Extra arguments for the compiler invocation. std::vector ExtraArgs; + llvm::Optional ClangTidyChecks; + ParsedAST build() const; SymbolSlab headerSymbols() const; std::unique_ptr index() const; -- cgit v1.2.3 From 8b19ebe1b9b12f7bd7888a15d63cbb0479d168c3 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 22 Jan 2019 09:58:53 +0000 Subject: [clangd] NFC: Use buildCompilerInvocation in CodeComplete Reviewers: ilya-biryukov, sammccall Reviewed By: sammccall Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D56860 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351793 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.cpp | 28 ---------------------------- clangd/ClangdUnit.h | 14 +------------- clangd/CodeComplete.cpp | 21 +++------------------ clangd/Compiler.cpp | 28 ++++++++++++++++++++++++++++ clangd/Compiler.h | 14 ++++++++++++++ 5 files changed, 46 insertions(+), 59 deletions(-) diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 268f7d1b..5e232b79 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -418,34 +418,6 @@ ParsedAST::ParsedAST(std::shared_ptr Preamble, assert(this->Action); } -std::unique_ptr -buildCompilerInvocation(const ParseInputs &Inputs) { - std::vector ArgStrs; - for (const auto &S : Inputs.CompileCommand.CommandLine) - ArgStrs.push_back(S.c_str()); - - if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { - log("Couldn't set working directory when creating compiler invocation."); - // We proceed anyway, our lit-tests rely on results for non-existing working - // dirs. - } - - // FIXME(ibiryukov): store diagnostics from CommandLine when we start - // reporting them. - IgnoreDiagnostics IgnoreDiagnostics; - llvm::IntrusiveRefCntPtr CommandLineDiagsEngine = - CompilerInstance::createDiagnostics(new DiagnosticOptions, - &IgnoreDiagnostics, false); - std::unique_ptr CI = createInvocationFromCommandLine( - ArgStrs, CommandLineDiagsEngine, Inputs.FS); - if (!CI) - return nullptr; - // createInvocationFromCommandLine sets DisableFree. - CI->getFrontendOpts().DisableFree = false; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; - return CI; -} - std::shared_ptr buildPreamble(PathRef FileName, CompilerInvocation &CI, std::shared_ptr OldPreamble, diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index 3a4841d7..ba430d5d 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -9,7 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_CLANGDUNIT_H -#include "../clang-tidy/ClangTidyOptions.h" +#include "Compiler.h" #include "Diagnostics.h" #include "FS.h" #include "Function.h" @@ -60,14 +60,6 @@ struct PreambleData { std::unique_ptr StatCache; }; -/// Information required to run clang, e.g. to parse AST or do code completion. -struct ParseInputs { - tooling::CompileCommand CompileCommand; - IntrusiveRefCntPtr FS; - std::string Contents; - tidy::ClangTidyOptions ClangTidyOpts; -}; - /// Stores and provides access to parsed AST. class ParsedAST { public: @@ -137,10 +129,6 @@ private: using PreambleParsedCallback = std::function)>; -/// Builds compiler invocation that could be used to build AST or preamble. -std::unique_ptr -buildCompilerInvocation(const ParseInputs &Inputs); - /// Rebuild the preamble for the new inputs unless the old one can be reused. /// If \p OldPreamble can be reused, it is returned unchanged. /// If \p OldPreamble is null, always builds the preamble. diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 60da653d..5a5eb8cd 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1016,33 +1016,17 @@ bool semaCodeComplete(std::unique_ptr Consumer, const SemaCompleteInput &Input, IncludeStructure *Includes = nullptr) { trace::Span Tracer("Sema completion"); - std::vector ArgStrs; - for (const auto &S : Input.Command.CommandLine) - ArgStrs.push_back(S.c_str()); - - if (Input.VFS->setCurrentWorkingDirectory(Input.Command.Directory)) { - log("Couldn't set working directory"); - // We run parsing anyway, our lit-tests rely on results for non-existing - // working dirs. - } - llvm::IntrusiveRefCntPtr VFS = Input.VFS; if (Input.Preamble && Input.Preamble->StatCache) VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS)); - IgnoreDiagnostics DummyDiagsConsumer; - auto CI = createInvocationFromCommandLine( - ArgStrs, - CompilerInstance::createDiagnostics(new DiagnosticOptions, - &DummyDiagsConsumer, false), - VFS); + auto CI = + buildCompilerInvocation(ParseInputs{Input.Command, VFS, Input.Contents}); if (!CI) { elog("Couldn't create CompilerInvocation"); return false; } auto &FrontendOpts = CI->getFrontendOpts(); - FrontendOpts.DisableFree = false; FrontendOpts.SkipFunctionBodies = true; - CI->getLangOpts()->CommentOpts.ParseAllComments = true; // Disable typo correction in Sema. CI->getLangOpts()->SpellChecking = false; // Setup code completion. @@ -1072,6 +1056,7 @@ bool semaCodeComplete(std::unique_ptr Consumer, *Offset; // NOTE: we must call BeginSourceFile after prepareCompilerInstance. Otherwise // the remapped buffers do not get freed. + IgnoreDiagnostics DummyDiagsConsumer; auto Clang = prepareCompilerInstance( std::move(CI), (Input.Preamble && !CompletingInPreamble) ? &Input.Preamble->Preamble diff --git a/clangd/Compiler.cpp b/clangd/Compiler.cpp index 2322b878..1eecce98 100644 --- a/clangd/Compiler.cpp +++ b/clangd/Compiler.cpp @@ -39,6 +39,34 @@ void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, IgnoreDiagnostics::log(DiagLevel, Info); } +std::unique_ptr +buildCompilerInvocation(const ParseInputs &Inputs) { + std::vector ArgStrs; + for (const auto &S : Inputs.CompileCommand.CommandLine) + ArgStrs.push_back(S.c_str()); + + if (Inputs.FS->setCurrentWorkingDirectory(Inputs.CompileCommand.Directory)) { + log("Couldn't set working directory when creating compiler invocation."); + // We proceed anyway, our lit-tests rely on results for non-existing working + // dirs. + } + + // FIXME(ibiryukov): store diagnostics from CommandLine when we start + // reporting them. + IgnoreDiagnostics IgnoreDiagnostics; + llvm::IntrusiveRefCntPtr CommandLineDiagsEngine = + CompilerInstance::createDiagnostics(new DiagnosticOptions, + &IgnoreDiagnostics, false); + std::unique_ptr CI = createInvocationFromCommandLine( + ArgStrs, CommandLineDiagsEngine, Inputs.FS); + if (!CI) + return nullptr; + // createInvocationFromCommandLine sets DisableFree. + CI->getFrontendOpts().DisableFree = false; + CI->getLangOpts()->CommentOpts.ParseAllComments = true; + return CI; +} + std::unique_ptr prepareCompilerInstance(std::unique_ptr CI, const PrecompiledPreamble *Preamble, diff --git a/clangd/Compiler.h b/clangd/Compiler.h index bee74a85..13b499c8 100644 --- a/clangd/Compiler.h +++ b/clangd/Compiler.h @@ -15,9 +15,11 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H +#include "../clang-tidy/ClangTidyOptions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PrecompiledPreamble.h" +#include "clang/Tooling/CompilationDatabase.h" namespace clang { namespace clangd { @@ -31,6 +33,18 @@ public: const clang::Diagnostic &Info) override; }; +/// Information required to run clang, e.g. to parse AST or do code completion. +struct ParseInputs { + tooling::CompileCommand CompileCommand; + IntrusiveRefCntPtr FS; + std::string Contents; + tidy::ClangTidyOptions ClangTidyOpts; +}; + +/// Builds compiler invocation that could be used to build AST or preamble. +std::unique_ptr +buildCompilerInvocation(const ParseInputs &Inputs); + /// Creates a compiler instance, configured so that: /// - Contents of the parsed file are remapped to \p MainFile. /// - Preamble is overriden to use PCH passed to this function. It means the -- cgit v1.2.3 From 3cbf6a79a9208fcdb92e6beb25e6b3e2bd097437 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 22 Jan 2019 12:21:25 +0000 Subject: [clangd] Fix the `-Wtype-limits` warning, NFC The assertion is always true, and triggers a compiler warning, so remove it. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351809 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Merge.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp index 77a67cb0..d967db8a 100644 --- a/clangd/index/Merge.cpp +++ b/clangd/index/Merge.cpp @@ -102,7 +102,6 @@ void MergedIndex::refs(const RefsRequest &Req, Callback(O); --Remaining; }); - assert(Remaining >= 0); if (Remaining == 0) return; // We return less than Req.Limit if static index returns more refs for dirty -- cgit v1.2.3 From c88e3fc072fe40ebf5873483bbb86adb29a0a554 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 22 Jan 2019 12:55:15 +0000 Subject: [clangd] Fix the broken buildbot. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351812 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/clangd/tool/CMakeLists.txt b/clangd/tool/CMakeLists.txt index 1ad2ca1b..6547a830 100644 --- a/clangd/tool/CMakeLists.txt +++ b/clangd/tool/CMakeLists.txt @@ -17,6 +17,7 @@ endif() target_link_libraries(clangd PRIVATE clangBasic + clangTidy clangDaemon clangFormat clangFrontend -- cgit v1.2.3 From d6eb9c35a62963e224ac9c3720db8fb06896bf8e Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Tue, 22 Jan 2019 12:55:27 +0000 Subject: [clangd] NFC: reduce log noise from Diagnostics. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D57042 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351813 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Diagnostics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index 1ccdfcfb..3c226762 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -403,8 +403,8 @@ void StoreDiags::flushLastDiag() { if (mentionsMainFile(*LastDiag)) Output.push_back(std::move(*LastDiag)); else - log("Dropped diagnostic outside main file: {0}: {1}", LastDiag->File, - LastDiag->Message); + vlog("Dropped diagnostic outside main file: {0}: {1}", LastDiag->File, + LastDiag->Message); LastDiag.reset(); } -- cgit v1.2.3 From d85321d7b0b1a40148333789fe0f8fc2037e2c3a Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Tue, 22 Jan 2019 12:59:34 +0000 Subject: [clang-tidy] Fix whitespace in docs. NFC Actually, just testing commits via monorepo ;) git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351814 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/index.rst | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst index 4172d134..f8e9270a 100644 --- a/docs/clang-tidy/index.rst +++ b/docs/clang-tidy/index.rst @@ -260,21 +260,20 @@ An overview of all the command-line options: Suppressing Undesired Diagnostics ================================= -:program:`clang-tidy` diagnostics are intended to call out code that does -not adhere to a coding standard, or is otherwise problematic in some way. -However, if it is known that the code is correct, the check-specific ways -to silence the diagnostics could be used, if they are available (e.g. -bugprone-use-after-move can be silenced by re-initializing the variable after it -has been moved out, bugprone-string-integer-assignment can be suppressed by -explicitly casting the integer to char, readability-implicit-bool-conversion can -also be suppressed by using explicit casts, etc.). If they are not available or -if changing the semantics of the code is not desired, the ``NOLINT`` or -``NOLINTNEXTLINE`` comments can be used instead. For example: +:program:`clang-tidy` diagnostics are intended to call out code that does not +adhere to a coding standard, or is otherwise problematic in some way. However, +if it is known that the code is correct, the check-specific ways to silence the +diagnostics could be used, if they are available (e.g. bugprone-use-after-move +can be silenced by re-initializing the variable after it has been moved out, +bugprone-string-integer-assignment can be suppressed by explicitly casting the +integer to ``char``, readability-implicit-bool-conversion can also be suppressed +by using explicit casts, etc.). If they are not available or if changing the +semantics of the code is not desired, the ``NOLINT`` or ``NOLINTNEXTLINE`` +comments can be used instead. For example: .. code-block:: c++ - class Foo - { + class Foo { // Silent all the diagnostics for the line Foo(int param); // NOLINT @@ -283,7 +282,7 @@ if changing the semantics of the code is not desired, the ``NOLINT`` or // Silent only the specified diagnostics for the next line // NOLINTNEXTLINE(google-explicit-constructor, google-runtime-int) - Foo(bool param); + Foo(bool param); }; The formal syntax of ``NOLINT``/``NOLINTNEXTLINE`` is the following: @@ -307,8 +306,8 @@ The formal syntax of ``NOLINT``/``NOLINTNEXTLINE`` is the following: Note that whitespaces between ``NOLINT``/``NOLINTNEXTLINE`` and the opening parenthesis are not allowed (in this case the comment will be treated just as -``NOLINT``/``NOLINTNEXTLINE``), whereas in check names list (inside -the parenthesis) whitespaces can be used and will be ignored. +``NOLINT``/``NOLINTNEXTLINE``), whereas in check names list (inside the +parenthesis) whitespaces can be used and will be ignored. .. _LibTooling: http://clang.llvm.org/docs/LibTooling.html .. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html -- cgit v1.2.3 From 611e4a77fcc91e343db09542cd152bd8515d9e6d Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Tue, 22 Jan 2019 13:35:16 +0000 Subject: Fix "missing field 'ClangTidyOpts' initializer" warning. NFCI. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351818 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CodeComplete.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 5a5eb8cd..40b4c78d 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1019,8 +1019,9 @@ bool semaCodeComplete(std::unique_ptr Consumer, llvm::IntrusiveRefCntPtr VFS = Input.VFS; if (Input.Preamble && Input.Preamble->StatCache) VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS)); - auto CI = - buildCompilerInvocation(ParseInputs{Input.Command, VFS, Input.Contents}); + auto CI = buildCompilerInvocation( + ParseInputs{Input.Command, VFS, Input.Contents, + tidy::ClangTidyOptions::getDefaults()}); if (!CI) { elog("Couldn't create CompilerInvocation"); return false; -- cgit v1.2.3 From f8d9fdc72e875c2d1e0c6c856743ac477d859a62 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 22 Jan 2019 14:48:04 +0000 Subject: [clangd] Followup fix of rL351818 ClangTidyOptions::getDefaults is not free, it will initialize all clang-tidy modules to get check-specific options, and we don't use this information in CodeComplete, so using an empty one (constructed by default constructor) is sufficient. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351826 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CodeComplete.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 40b4c78d..e1be6b45 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1019,9 +1019,11 @@ bool semaCodeComplete(std::unique_ptr Consumer, llvm::IntrusiveRefCntPtr VFS = Input.VFS; if (Input.Preamble && Input.Preamble->StatCache) VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS)); - auto CI = buildCompilerInvocation( - ParseInputs{Input.Command, VFS, Input.Contents, - tidy::ClangTidyOptions::getDefaults()}); + ParseInputs PInput; + PInput.CompileCommand = Input.Command; + PInput.FS = VFS; + PInput.Contents = Input.Contents; + auto CI = buildCompilerInvocation(PInput); if (!CI) { elog("Couldn't create CompilerInvocation"); return false; -- cgit v1.2.3 From f2ffa978ad57c9a736e7e1f330406d0f51b2f51c Mon Sep 17 00:00:00 2001 From: Eugene Zelenko Date: Tue, 22 Jan 2019 19:19:48 +0000 Subject: [Documentation] Use HTTPS whenever possible. Differential revision: https://reviews.llvm.org/D56926 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351862 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-doc.rst | 4 +- docs/clang-rename.rst | 8 +- docs/clang-tidy.rst | 2 +- docs/clang-tidy/Integrations.rst | 2 +- .../google-objc-avoid-throwing-exception.rst | 2 +- .../google-objc-global-variable-declaration.rst | 2 +- docs/clang-tidy/checks/llvm-include-order.rst | 2 +- docs/clang-tidy/checks/llvm-namespace-comment.rst | 2 +- docs/clang-tidy/checks/modernize-pass-by-value.rst | 2 +- docs/clang-tidy/checks/modernize-use-emplace.rst | 2 +- .../checks/portability-simd-intrinsics.rst | 2 +- .../checks/readability-else-after-return.rst | 4 +- .../checks/readability-magic-numbers.rst | 2 +- docs/clang-tidy/index.rst | 6 +- docs/clangd.rst | 10 +- docs/include-fixer.rst | 2 +- docs/modularize.rst | 8 +- docs/pp-trace.rst | 130 ++++++++++----------- 18 files changed, 96 insertions(+), 96 deletions(-) diff --git a/docs/clang-doc.rst b/docs/clang-doc.rst index f891b71a..96120687 100644 --- a/docs/clang-doc.rst +++ b/docs/clang-doc.rst @@ -20,10 +20,10 @@ Use ===== :program:`clang-doc` is a `LibTooling -`_-based tool, and so requires a +`_-based tool, and so requires a compile command database for your project (for an example of how to do this see `How To Setup Tooling For LLVM -`_). +`_). The tool can be used on a single file or multiple files as defined in the compile commands database: diff --git a/docs/clang-rename.rst b/docs/clang-rename.rst index f6227795..0c9194c4 100644 --- a/docs/clang-rename.rst +++ b/docs/clang-rename.rst @@ -24,10 +24,10 @@ Using Clang-Rename ================== :program:`clang-rename` is a `LibTooling -`_-based tool, and it's easier to +`_-based tool, and it's easier to work with if you set up a compile command database for your project (for an example of how to do this see `How To Setup Tooling For LLVM -`_). You can also +`_). You can also specify compilation options on the command line after `--`: .. code-block:: console @@ -140,7 +140,7 @@ Vim Integration You can call :program:`clang-rename` directly from Vim! To set up :program:`clang-rename` integration for Vim see `clang-rename/tool/clang-rename.py -`_. +`_. Please note that **you have to save all buffers, in which the replacement will happen before running the tool**. @@ -157,7 +157,7 @@ Emacs Integration You can also use :program:`clang-rename` while using Emacs! To set up :program:`clang-rename` integration for Emacs see `clang-rename/tool/clang-rename.el -`_. +`_. Once installed, you can point your cursor to symbols you want to rename, press `M-X`, type `clang-rename` and new desired name. diff --git a/docs/clang-tidy.rst b/docs/clang-tidy.rst index bcd2bf1e..b9a18069 100644 --- a/docs/clang-tidy.rst +++ b/docs/clang-tidy.rst @@ -3,4 +3,4 @@ .. meta:: :http-equiv=refresh: 0;URL='clang-tidy/' -clang-tidy documentation has moved here: http://clang.llvm.org/extra/clang-tidy/ +clang-tidy documentation has moved here: https://clang.llvm.org/extra/clang-tidy/ diff --git a/docs/clang-tidy/Integrations.rst b/docs/clang-tidy/Integrations.rst index 2d1e1956..dad7f7d9 100644 --- a/docs/clang-tidy/Integrations.rst +++ b/docs/clang-tidy/Integrations.rst @@ -64,7 +64,7 @@ static analysis using :program:`clang-tidy`. The plugin launches the output to provide a list of issues. .. _QtCreator: https://www.qt.io/ -.. _Clang Code Model: http://doc.qt.io/qtcreator/creator-clang-codemodel.html +.. _Clang Code Model: https://doc.qt.io/qtcreator/creator-clang-codemodel.html QtCreator_ 4.6 integrates :program:`clang-tidy` warnings into the editor diagnostics under the `Clang Code Model`_. To employ :program:`clang-tidy` diff --git a/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst b/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst index 39b02174..884e9719 100644 --- a/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst +++ b/docs/clang-tidy/checks/google-objc-avoid-throwing-exception.rst @@ -36,4 +36,4 @@ Instead, returning an error via ``NSError **`` is preferred: } The corresponding style guide rule: -http://google.github.io/styleguide/objcguide.html#avoid-throwing-exceptions +https://google.github.io/styleguide/objcguide.html#avoid-throwing-exceptions diff --git a/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst b/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst index d4703706..e4b41fbc 100644 --- a/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst +++ b/docs/clang-tidy/checks/google-objc-global-variable-declaration.rst @@ -7,7 +7,7 @@ Finds global variable declarations in Objective-C files that do not follow the pattern of variable names in Google's Objective-C Style Guide. The corresponding style guide rule: -http://google.github.io/styleguide/objcguide.html#variable-names +https://google.github.io/styleguide/objcguide.html#variable-names All the global variables should follow the pattern of `g[A-Z].*` (variables) or `k[A-Z].*` (constants). The check will suggest a variable name that follows the diff --git a/docs/clang-tidy/checks/llvm-include-order.rst b/docs/clang-tidy/checks/llvm-include-order.rst index dba98376..8a215b8e 100644 --- a/docs/clang-tidy/checks/llvm-include-order.rst +++ b/docs/clang-tidy/checks/llvm-include-order.rst @@ -6,4 +6,4 @@ llvm-include-order Checks the correct order of ``#includes``. -See http://llvm.org/docs/CodingStandards.html#include-style +See https://llvm.org/docs/CodingStandards.html#include-style diff --git a/docs/clang-tidy/checks/llvm-namespace-comment.rst b/docs/clang-tidy/checks/llvm-namespace-comment.rst index f6bc5985..be90260b 100644 --- a/docs/clang-tidy/checks/llvm-namespace-comment.rst +++ b/docs/clang-tidy/checks/llvm-namespace-comment.rst @@ -8,7 +8,7 @@ check. Checks that long namespaces have a closing comment. -http://llvm.org/docs/CodingStandards.html#namespace-indentation +https://llvm.org/docs/CodingStandards.html#namespace-indentation https://google.github.io/styleguide/cppguide.html#Namespaces diff --git a/docs/clang-tidy/checks/modernize-pass-by-value.rst b/docs/clang-tidy/checks/modernize-pass-by-value.rst index f49648d4..e538135a 100644 --- a/docs/clang-tidy/checks/modernize-pass-by-value.rst +++ b/docs/clang-tidy/checks/modernize-pass-by-value.rst @@ -144,7 +144,7 @@ Example: + C(std::string S) : S(std::move(S)) {} }; -.. _Clang Compiler User’s Manual - Microsoft extensions: http://clang.llvm.org/docs/UsersManual.html#microsoft-extensions +.. _Clang Compiler User’s Manual - Microsoft extensions: https://clang.llvm.org/docs/UsersManual.html#microsoft-extensions .. seealso:: diff --git a/docs/clang-tidy/checks/modernize-use-emplace.rst b/docs/clang-tidy/checks/modernize-use-emplace.rst index 533125e9..447a110f 100644 --- a/docs/clang-tidy/checks/modernize-use-emplace.rst +++ b/docs/clang-tidy/checks/modernize-use-emplace.rst @@ -10,7 +10,7 @@ results in less verbose and potentially more efficient code. Right now the check doesn't support ``push_front`` and ``insert``. It also doesn't support ``insert`` functions for associative containers because replacing ``insert`` with ``emplace`` may result in -`speed regression `_, but it might get support with some addition flag in the future. +`speed regression `_, but it might get support with some addition flag in the future. By default only ``std::vector``, ``std::deque``, ``std::list`` are considered. This list can be modified using the :option:`ContainersWithPushBack` option. diff --git a/docs/clang-tidy/checks/portability-simd-intrinsics.rst b/docs/clang-tidy/checks/portability-simd-intrinsics.rst index 2cd9d9f7..fedd47a1 100644 --- a/docs/clang-tidy/checks/portability-simd-intrinsics.rst +++ b/docs/clang-tidy/checks/portability-simd-intrinsics.rst @@ -46,4 +46,4 @@ Options The namespace used to suggest `P0214`_ alternatives. If not specified, `std::` for `-std=c++2a` and `std::experimental::` for `-std=c++11`. -.. _P0214: http://wg21.link/p0214 +.. _P0214: https://wg21.link/p0214 diff --git a/docs/clang-tidy/checks/readability-else-after-return.rst b/docs/clang-tidy/checks/readability-else-after-return.rst index 949b5bb4..c178a6a6 100644 --- a/docs/clang-tidy/checks/readability-else-after-return.rst +++ b/docs/clang-tidy/checks/readability-else-after-return.rst @@ -3,7 +3,7 @@ readability-else-after-return ============================= -`LLVM Coding Standards `_ advises to +`LLVM Coding Standards `_ advises to reduce indentation where possible and where it makes understanding code easier. Early exit is one of the suggested enforcements of that. Please do not use ``else`` or ``else if`` after something that interrupts control flow - like @@ -61,4 +61,4 @@ Would be transformed into: This check helps to enforce this `LLVM Coding Standards recommendation -`_. +`_. diff --git a/docs/clang-tidy/checks/readability-magic-numbers.rst b/docs/clang-tidy/checks/readability-magic-numbers.rst index 946672ed..9968809e 100644 --- a/docs/clang-tidy/checks/readability-magic-numbers.rst +++ b/docs/clang-tidy/checks/readability-magic-numbers.rst @@ -9,7 +9,7 @@ code and not introduced via constants or symbols. Many coding guidelines advise replacing the magic values with symbolic constants to improve readability. Here are a few references: - * `Rule ES.45: Avoid “magic constants”; use symbolic constants in C++ Core Guidelines `_ + * `Rule ES.45: Avoid “magic constants”; use symbolic constants in C++ Core Guidelines `_ * `Rule 5.1.1 Use symbolic names instead of literal values in code in High Integrity C++ `_ * Item 17 in "C++ Coding Standards: 101 Rules, Guidelines and Best Practices" by Herb Sutter and Andrei Alexandrescu diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst index f8e9270a..720c581d 100644 --- a/docs/clang-tidy/index.rst +++ b/docs/clang-tidy/index.rst @@ -225,7 +225,7 @@ An overview of all the command-line options: CMake option to get this output). When no build path is specified, a search for compile_commands.json will be attempted through all parent paths of the first input file . See: - http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an + https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html for an example of setting up Clang Tooling on a source tree. ... specify the paths of source files. These paths are @@ -309,5 +309,5 @@ parenthesis are not allowed (in this case the comment will be treated just as ``NOLINT``/``NOLINTNEXTLINE``), whereas in check names list (inside the parenthesis) whitespaces can be used and will be ignored. -.. _LibTooling: http://clang.llvm.org/docs/LibTooling.html -.. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +.. _LibTooling: https://clang.llvm.org/docs/LibTooling.html +.. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html diff --git a/docs/clangd.rst b/docs/clangd.rst index 0b276380..84696e3b 100644 --- a/docs/clangd.rst +++ b/docs/clangd.rst @@ -31,7 +31,7 @@ Installing Clangd ================== Packages are available for debian-based distributions, see the `LLVM packages -page `_. :program:`Clangd` is included in the +page `_. :program:`Clangd` is included in the `clang-tools` package. However, it is a good idea to check your distribution's packaging system first as it might already be available. @@ -147,14 +147,14 @@ Getting Involved ================== A good place for interested contributors is the `Clangd developer mailing list -`_. For discussions with the +`_. For discussions with the broader community on topics not only related to Clangd, use `Clang developer mailing list -`_. +`_. If you're also interested in contributing patches to :program:`Clangd`, take a look at the `LLVM Developer Policy -`_ and `Code Reviews -`_ page. Contributions of new features +`_ and `Code Reviews +`_ page. Contributions of new features to the `Language Server Protocol `_ itself would also be very useful, so that :program:`Clangd` can eventually implement them in a diff --git a/docs/include-fixer.rst b/docs/include-fixer.rst index fcd2998b..9898840c 100644 --- a/docs/include-fixer.rst +++ b/docs/include-fixer.rst @@ -32,7 +32,7 @@ them up if called with a source file from that tree. Note that by default ``compile_commands.json`` as generated by CMake does not include header files, so only implementation files can be handled by tools. -.. _How To Setup Tooling For LLVM: http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html +.. _How To Setup Tooling For LLVM: https://clang.llvm.org/docs/HowToSetupToolingForLLVM.html Creating a Symbol Index From a Compilation Database --------------------------------------------------- diff --git a/docs/modularize.rst b/docs/modularize.rst index 6fe49b42..406ab9ce 100644 --- a/docs/modularize.rst +++ b/docs/modularize.rst @@ -42,9 +42,9 @@ To build from source: Before continuing, take a look at :doc:`ModularizeUsage` to see how to invoke modularize. -.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html -.. _Building LLVM with CMake: http://llvm.org/docs/CMake.html -.. _Clang Tools Documentation: http://clang.llvm.org/docs/ClangTools.html +.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html +.. _Building LLVM with CMake: https://llvm.org/docs/CMake.html +.. _Clang Tools Documentation: https://clang.llvm.org/docs/ClangTools.html What Modularize Checks ====================== @@ -262,4 +262,4 @@ names. If a header has one of these names, an underscore ('_') will be prepended to the name. For example, if the header name is ``header.h``, because ``header`` is a keyword, the module name will be ``_header``. For a list of the module map keywords, please see: -`Lexical structure `_ +`Lexical structure `_ diff --git a/docs/pp-trace.rst b/docs/pp-trace.rst index b8768ed0..9cfbef59 100644 --- a/docs/pp-trace.rst +++ b/docs/pp-trace.rst @@ -11,7 +11,7 @@ pp-trace User's Manual activity. It's also used as a test of Clang's PPCallbacks interface. It runs a given source file through the Clang preprocessor, displaying selected information from callback functions overridden in a -`PPCallbacks `_ +`PPCallbacks `_ derivation. The output is in a high-level YAML format, described in :ref:`OutputFormat`. @@ -32,7 +32,7 @@ specific to pp-trace, which are described below in ```` specifies the source file to run through the preprocessor. ```` is a place-holder for regular -`Clang Compiler Options `_, +`Clang Compiler Options `_, which must follow the . .. _CommandLineOptions: @@ -88,7 +88,7 @@ Command Line Options pp-trace Output Format ====================== -The pp-trace output is formatted as YAML. See http://yaml.org/ for general +The pp-trace output is formatted as YAML. See https://yaml.org/ for general YAML information. It's arranged as a sequence of information about the callback call, including the callback name and argument information, for example::: @@ -150,8 +150,8 @@ Note that in some cases, such as when a structure pointer is an argument value, only some key member or members are shown to represent the value, instead of trying to display all members of the structure. -`FileChanged `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`FileChanged `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileChanged is called when the preprocessor enters or exits a file, both the top level file being compiled, as well as any #include directives. It will @@ -177,8 +177,8 @@ Example::: FileType: C_User PrevFID: (invalid) -`FileSkipped `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`FileSkipped `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileSkipped is called when a source file is skipped as the result of header guard optimization. @@ -200,8 +200,8 @@ Example::: FilenameTok: "filename.h" FileType: C_User -`FileNotFound `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`FileNotFound `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FileNotFound is called when an inclusion directive results in a file-not-found error. @@ -220,8 +220,8 @@ Example::: FileName: "/path/filename.h" RecoveryPath: -`InclusionDirective `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`InclusionDirective `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ InclusionDirective is called when an inclusion directive of any kind (#include, #import, etc.) has been processed, regardless of whether the inclusion will actually result in an inclusion. @@ -253,8 +253,8 @@ Example::: RelativePath: "Input/Level1B.h" Imported: (null) -`moduleImport `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`moduleImport `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ moduleImport is called when there was an explicit module-import syntax. @@ -275,8 +275,8 @@ Example::: Path: [{Name: Level1B, Loc: "d:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:9"}, {Name: Level2B, Loc: "d:/Clang/llvmnewmod/tools/clang/tools/extra/test/pp-trace/pp-trace-modules.cpp:4:17"}] Imported: Level2B -`EndOfMainFile `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`EndOfMainFile `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ EndOfMainFile is called when the end of the main file is reached. @@ -292,8 +292,8 @@ Example::: - Callback: EndOfMainFile -`Ident `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Ident `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ident is called when a #ident or #sccs directive is read. @@ -312,8 +312,8 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-ident.cpp:3:1" str: "$Id$" -`PragmaDirective `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaDirective `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaDirective is called when start reading any pragma directive. @@ -332,8 +332,8 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1" Introducer: PIK_HashPragma -`PragmaComment `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaComment `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaComment is called when a #pragma comment directive is read. @@ -354,8 +354,8 @@ Example::: Kind: library Str: kernel32.lib -`PragmaDetectMismatch `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaDetectMismatch `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaDetectMismatch is called when a #pragma detect_mismatch directive is read. @@ -376,8 +376,8 @@ Example::: Name: name Value: value -`PragmaDebug `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaDebug `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaDebug is called when a #pragma clang __debug directive is read. @@ -396,8 +396,8 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1" DebugType: warning -`PragmaMessage `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaMessage `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaMessage is called when a #pragma message directive is read. @@ -420,8 +420,8 @@ Example::: Kind: PMK_Message Str: The message text. -`PragmaDiagnosticPush `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaDiagnosticPush `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaDiagnosticPush is called when a #pragma gcc dianostic push directive is read. @@ -440,7 +440,7 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1" Namespace: "GCC" -`PragmaDiagnosticPop `_ Callback +`PragmaDiagnosticPop `_ Callback ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaDiagnosticPop is called when a #pragma gcc dianostic pop directive is read. @@ -460,8 +460,8 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1" Namespace: "GCC" -`PragmaDiagnostic `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaDiagnostic `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaDiagnostic is called when a #pragma gcc dianostic directive is read. @@ -484,8 +484,8 @@ Example::: mapping: MAP_WARNING Str: WarningName -`PragmaOpenCLExtension `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaOpenCLExtension `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaOpenCLExtension is called when OpenCL extension is either disabled or enabled with a pragma. @@ -508,8 +508,8 @@ Example::: StateLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:18" State: 1 -`PragmaWarning `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaWarning `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaWarning is called when a #pragma warning directive is read. @@ -530,8 +530,8 @@ Example::: WarningSpec: disable Ids: 1,2,3 -`PragmaWarningPush `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaWarningPush `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaWarningPush is called when a #pragma warning(push) directive is read. @@ -550,8 +550,8 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1" Level: 1 -`PragmaWarningPop `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`PragmaWarningPop `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ PragmaWarningPop is called when a #pragma warning(pop) directive is read. @@ -568,8 +568,8 @@ Example::: - Callback: PragmaWarningPop Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-pragma.cpp:3:1" -`MacroExpands `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`MacroExpands `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MacroExpands is called when ::HandleMacroExpandedIdentifier when a macro invocation is found. @@ -592,8 +592,8 @@ Example::: Range: [(nonfile), (nonfile)] Args: [a y, b] -`MacroDefined `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`MacroDefined `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MacroDefined is called when a macro definition is seen. @@ -612,8 +612,8 @@ Example::: MacroNameTok: X_IMPL MacroDirective: MD_Define -`MacroUndefined `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`MacroUndefined `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ MacroUndefined is called when a macro #undef is seen. @@ -632,8 +632,8 @@ Example::: MacroNameTok: X_IMPL MacroDirective: MD_Define -`Defined `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Defined `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Defined is called when the 'defined' operator is seen. @@ -654,8 +654,8 @@ Example::: MacroDirective: (null) Range: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:5", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:19"] -`SourceRangeSkipped `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`SourceRangeSkipped `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ SourceRangeSkipped is called when a source range is skipped. @@ -672,8 +672,8 @@ Example::: - Callback: SourceRangeSkipped Range: [":/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2", ":/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:9:2"] -`If `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`If `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ If is called when an #if is seen. @@ -694,8 +694,8 @@ Example::: ConditionRange: ["D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:4", "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:9:1"] ConditionValue: false -`Elif `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Elif `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Elif is called when an #elif is seen. @@ -718,8 +718,8 @@ Example::: ConditionValue: false IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2" -`Ifdef `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Ifdef `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ifdef is called when an #ifdef is seen. @@ -740,8 +740,8 @@ Example::: MacroNameTok: MACRO MacroDirective: MD_Define -`Ifndef `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Ifndef `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Ifndef is called when an #ifndef is seen. @@ -762,8 +762,8 @@ Example::: MacroNameTok: MACRO MacroDirective: MD_Define -`Else `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Else `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Else is called when an #else is seen. @@ -782,8 +782,8 @@ Example::: Loc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:10:2" IfLoc: "D:/Clang/llvm/tools/clang/tools/extra/test/pp-trace/pp-trace-macro.cpp:8:2" -`Endif `_ Callback -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +`Endif `_ Callback +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Endif is called when an #endif is seen. @@ -819,7 +819,7 @@ To build from source: * If using CMake, you can also use the ``pp-trace`` target to build just the pp-trace tool and its dependencies. -.. _Getting Started with the LLVM System: http://llvm.org/docs/GettingStarted.html -.. _Building LLVM with CMake: http://llvm.org/docs/CMake.html -.. _Clang Tools Documentation: http://clang.llvm.org/docs/ClangTools.html +.. _Getting Started with the LLVM System: https://llvm.org/docs/GettingStarted.html +.. _Building LLVM with CMake: https://llvm.org/docs/CMake.html +.. _Clang Tools Documentation: https://clang.llvm.org/docs/ClangTools.html -- cgit v1.2.3 From 09d33e8cff0c541676416b8e690d3f966dfdffd9 Mon Sep 17 00:00:00 2001 From: Zinovy Nis Date: Tue, 22 Jan 2019 20:27:02 +0000 Subject: [doc] Replace 'class' with 'struct' for 'public' by default Make sample syntax correct. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351867 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/bugprone-parent-virtual-call.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst b/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst index e1021b18..c3521272 100755 --- a/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst +++ b/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst @@ -8,15 +8,15 @@ to overridden parent's virtual methods. .. code-block:: c++ - class A { + struct A { int virtual foo() {...} }; - class B: public A { + struct B: public A { int foo() override {...} }; - class C: public B { + struct C: public B { int foo() override { A::foo(); } // ^^^^^^^^ // warning: qualified name A::foo refers to a member overridden in subclass; did you mean 'B'? [bugprone-parent-virtual-call] -- cgit v1.2.3 From 1a8a53c675ff69323a854109b6ffd7dbd481ffca Mon Sep 17 00:00:00 2001 From: Stephane Moore Date: Wed, 23 Jan 2019 02:34:21 +0000 Subject: =?UTF-8?q?[clang-tidy]=20Delete=20obsolete=20objc-property-declar?= =?UTF-8?q?ation=20options=20=E2=9C=82=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: The `Acronyms` and `IncludeDefaultAcronyms` options were deprecated in https://reviews.llvm.org/D51832. These options can be removed. Tested by running the clang-tidy tests. Reviewers: benhamilton, aaron.ballman Reviewed By: aaron.ballman Subscribers: Eugene.Zelenko, xazax.hun, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D56945 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351921 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/objc/PropertyDeclarationCheck.cpp | 14 -------------- clang-tidy/objc/PropertyDeclarationCheck.h | 11 ++--------- docs/ReleaseNotes.rst | 4 ++++ docs/clang-tidy/checks/objc-property-declaration.rst | 12 ------------ 4 files changed, 6 insertions(+), 35 deletions(-) diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp index 653c6bb8..eba702be 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -97,14 +97,6 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) { } } // namespace -PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - SpecialAcronyms( - utils::options::parseStringList(Options.get("Acronyms", ""))), - IncludeDefaultAcronyms(Options.get("IncludeDefaultAcronyms", true)), - EscapedAcronyms() {} - void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) { // this check should only be applied to ObjC sources. if (!getLangOpts().ObjC) return; @@ -145,12 +137,6 @@ void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) { << generateFixItHint(MatchedDecl, StandardProperty); } -void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "Acronyms", - utils::options::serializeStringList(SpecialAcronyms)); - Options.store(Opts, "IncludeDefaultAcronyms", IncludeDefaultAcronyms); -} - } // namespace objc } // namespace tidy } // namespace clang diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h index d28bde40..49af5df5 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.h +++ b/clang-tidy/objc/PropertyDeclarationCheck.h @@ -10,8 +10,6 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H #include "../ClangTidy.h" -#include -#include namespace clang { namespace tidy { @@ -27,15 +25,10 @@ namespace objc { /// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html class PropertyDeclarationCheck : public ClangTidyCheck { public: - PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context); + PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - void storeOptions(ClangTidyOptions::OptionMap &Options) override; - -private: - const std::vector SpecialAcronyms; - const bool IncludeDefaultAcronyms; - std::vector EscapedAcronyms; }; } // namespace objc diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index bb699349..8379412d 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -73,6 +73,10 @@ Improvements to clang-tidy Checks for casts of ``absl::Duration`` conversion functions, and recommends the right conversion function instead. +- The :option:`Acronyms` and :option:`IncludeDefaultAcronyms` options for the + :doc:`objc-property-declaration ` + check have been removed. + Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/objc-property-declaration.rst b/docs/clang-tidy/checks/objc-property-declaration.rst index 49df5102..60b9c82e 100644 --- a/docs/clang-tidy/checks/objc-property-declaration.rst +++ b/docs/clang-tidy/checks/objc-property-declaration.rst @@ -40,15 +40,3 @@ lowercase letters followed by a '_' to avoid naming conflict. For example: @property(nonatomic, assign) int abc_lowerCamelCase; The corresponding style rule: https://developer.apple.com/library/content/qa/qa1908/_index.html - - -Options -------- - -.. option:: Acronyms - - This option is deprecated and ignored. - -.. option:: IncludeDefaultAcronyms - - This option is deprecated and ignored. -- cgit v1.2.3 From 60d1d88f83df0942a0e8d186cde028990cfcf7a8 Mon Sep 17 00:00:00 2001 From: Stephane Moore Date: Wed, 23 Jan 2019 02:58:59 +0000 Subject: Revert rCTE351921 to fix documentation geneeration. Original review: https://reviews.llvm.org/D56945 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351922 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/objc/PropertyDeclarationCheck.cpp | 14 ++++++++++++++ clang-tidy/objc/PropertyDeclarationCheck.h | 11 +++++++++-- docs/ReleaseNotes.rst | 4 ---- docs/clang-tidy/checks/objc-property-declaration.rst | 12 ++++++++++++ 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp index eba702be..653c6bb8 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -97,6 +97,14 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) { } } // namespace +PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name, + ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + SpecialAcronyms( + utils::options::parseStringList(Options.get("Acronyms", ""))), + IncludeDefaultAcronyms(Options.get("IncludeDefaultAcronyms", true)), + EscapedAcronyms() {} + void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) { // this check should only be applied to ObjC sources. if (!getLangOpts().ObjC) return; @@ -137,6 +145,12 @@ void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) { << generateFixItHint(MatchedDecl, StandardProperty); } +void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "Acronyms", + utils::options::serializeStringList(SpecialAcronyms)); + Options.store(Opts, "IncludeDefaultAcronyms", IncludeDefaultAcronyms); +} + } // namespace objc } // namespace tidy } // namespace clang diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h index 49af5df5..d28bde40 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.h +++ b/clang-tidy/objc/PropertyDeclarationCheck.h @@ -10,6 +10,8 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H #include "../ClangTidy.h" +#include +#include namespace clang { namespace tidy { @@ -25,10 +27,15 @@ namespace objc { /// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html class PropertyDeclarationCheck : public ClangTidyCheck { public: - PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context); void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Options) override; + +private: + const std::vector SpecialAcronyms; + const bool IncludeDefaultAcronyms; + std::vector EscapedAcronyms; }; } // namespace objc diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 8379412d..bb699349 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -73,10 +73,6 @@ Improvements to clang-tidy Checks for casts of ``absl::Duration`` conversion functions, and recommends the right conversion function instead. -- The :option:`Acronyms` and :option:`IncludeDefaultAcronyms` options for the - :doc:`objc-property-declaration ` - check have been removed. - Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/objc-property-declaration.rst b/docs/clang-tidy/checks/objc-property-declaration.rst index 60b9c82e..49df5102 100644 --- a/docs/clang-tidy/checks/objc-property-declaration.rst +++ b/docs/clang-tidy/checks/objc-property-declaration.rst @@ -40,3 +40,15 @@ lowercase letters followed by a '_' to avoid naming conflict. For example: @property(nonatomic, assign) int abc_lowerCamelCase; The corresponding style rule: https://developer.apple.com/library/content/qa/qa1908/_index.html + + +Options +------- + +.. option:: Acronyms + + This option is deprecated and ignored. + +.. option:: IncludeDefaultAcronyms + + This option is deprecated and ignored. -- cgit v1.2.3 From f72b5d8ce50f90a6b96c0ce52d7394d9a9f0131f Mon Sep 17 00:00:00 2001 From: Zinovy Nis Date: Wed, 23 Jan 2019 06:46:27 +0000 Subject: [doc] Fix svn property for bugprone-parent-virtual-call.rst git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351925 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/bugprone-parent-virtual-call.rst | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 docs/clang-tidy/checks/bugprone-parent-virtual-call.rst diff --git a/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst b/docs/clang-tidy/checks/bugprone-parent-virtual-call.rst old mode 100755 new mode 100644 -- cgit v1.2.3 From e49e2e6daf9e2ea954a0d99026b16c0727dacc91 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 23 Jan 2019 08:04:17 +0000 Subject: [clangd] Link clangTidy into clangd tests Patch by Nathan Ridge! Differential Revision: https://reviews.llvm.org/D57077 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351929 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/unittests/clangd/CMakeLists.txt b/unittests/clangd/CMakeLists.txt index ccc19275..73655fe8 100644 --- a/unittests/clangd/CMakeLists.txt +++ b/unittests/clangd/CMakeLists.txt @@ -59,6 +59,7 @@ target_link_libraries(ClangdTests clangLex clangSema clangSerialization + clangTidy clangTooling clangToolingCore clangToolingInclusions -- cgit v1.2.3 From 5280d806bd74498fc8b0c2d9421fd15871928b23 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 23 Jan 2019 10:35:12 +0000 Subject: [clangd] Fix crash due to ObjCPropertyDecl With ObjCPropertyDecl, ASTNode.OrigD can be a ObjCPropertyImplDecl which is not a NamedDecl, leading to a crash since the code incorrectly assumes ASTNode.OrigD will always be a NamedDecl. Change by dgoldman (David Goldman)! Differential Revision: https://reviews.llvm.org/D56916 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351941 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/SymbolCollector.cpp | 14 ++++++++++---- unittests/clangd/SymbolCollectorTests.cpp | 15 +++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index c9abb938..83087632 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -347,19 +347,25 @@ bool SymbolCollector::handleDeclOccurence( if (!ID) return true; - const NamedDecl &OriginalDecl = *cast(ASTNode.OrigD); + // FIXME: ObjCPropertyDecl are not properly indexed here: + // - ObjCPropertyDecl may have an OrigD of ObjCPropertyImplDecl, which is + // not a NamedDecl. + auto *OriginalDecl = dyn_cast(ASTNode.OrigD); + if (!OriginalDecl) + return true; + const Symbol *BasicSymbol = Symbols.find(*ID); if (!BasicSymbol) // Regardless of role, ND is the canonical declaration. BasicSymbol = addDeclaration(*ND, std::move(*ID), IsMainFileOnly); - else if (isPreferredDeclaration(OriginalDecl, Roles)) + else if (isPreferredDeclaration(*OriginalDecl, Roles)) // If OriginalDecl is preferred, replace the existing canonical // declaration (e.g. a class forward declaration). There should be at most // one duplicate as we expect to see only one preferred declaration per // TU, because in practice they are definitions. - BasicSymbol = addDeclaration(OriginalDecl, std::move(*ID), IsMainFileOnly); + BasicSymbol = addDeclaration(*OriginalDecl, std::move(*ID), IsMainFileOnly); if (Roles & static_cast(index::SymbolRole::Definition)) - addDefinition(OriginalDecl, *BasicSymbol); + addDefinition(*OriginalDecl, *BasicSymbol); return true; } diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index 04a2d96f..a830f0ab 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -437,6 +437,21 @@ TEST_F(SymbolCollectorTest, ObjCSymbols) { QName("MyProtocol"), QName("MyProtocol::someMethodName3:"))); } +TEST_F(SymbolCollectorTest, ObjCPropertyImpl) { + const std::string Header = R"( + @interface Container + @property(nonatomic) int magic; + @end + + @implementation Container + @end + )"; + TestFileName = testPath("test.m"); + runSymbolCollector(Header, /*Main=*/"", {"-xobjective-c++"}); + EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Container"), + QName("Container::magic"))); +} + TEST_F(SymbolCollectorTest, Locations) { Annotations Header(R"cpp( // Declared in header, defined in main. -- cgit v1.2.3 From 943ee035269caeda499432fc9fa9638f97a4877e Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 23 Jan 2019 11:32:07 +0000 Subject: [clangd] Workaround a test failure after r351941 This should fix failing buildbots. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@351943 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/SymbolCollectorTests.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index a830f0ab..ff38952f 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -448,8 +448,10 @@ TEST_F(SymbolCollectorTest, ObjCPropertyImpl) { )"; TestFileName = testPath("test.m"); runSymbolCollector(Header, /*Main=*/"", {"-xobjective-c++"}); - EXPECT_THAT(Symbols, UnorderedElementsAre(QName("Container"), - QName("Container::magic"))); + EXPECT_THAT(Symbols, Contains(QName("Container"))); + EXPECT_THAT(Symbols, Contains(QName("Container::magic"))); + // FIXME: Results also contain Container::_magic on some platforms. + // Figure out why it's platform-dependent. } TEST_F(SymbolCollectorTest, Locations) { -- cgit v1.2.3 From 8809d5edb209a786cffdbf7f604a23819a493201 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 24 Jan 2019 07:58:42 +0000 Subject: [extra] unit tests enable crash-recovery cases on FreeBSD Seems the previous statement does not hold up anymore. Reviewers: steveire Reviewed By: steveire Differential Revision: https://reviews.llvm.org/D57102 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352031 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/lit.cfg | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/lit.cfg b/test/lit.cfg index 7fe56f7f..ed7bb83c 100644 --- a/test/lit.cfg +++ b/test/lit.cfg @@ -99,11 +99,9 @@ config.environment['LD_LIBRARY_PATH'] = path if lit_config.useValgrind: config.target_triple += '-vg' +config.available_features.add('crash-recovery') # Set available features we allow tests to conditionalize on. # -# As of 2011.08, crash-recovery tests still do not pass on FreeBSD. -if platform.system() not in ['FreeBSD']: - config.available_features.add('crash-recovery') # Shell execution if execute_external: -- cgit v1.2.3 From 7f320ab4839c298d1ee491c78c72c95681228567 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Thu, 24 Jan 2019 10:41:43 +0000 Subject: [CodeComplete] [clangd] Fix crash on ValueDecl with a null type Reviewers: kadircet Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D57093 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352040 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ExpectedTypes.cpp | 4 +++- unittests/clangd/CodeCompleteTests.cpp | 11 +++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/clangd/ExpectedTypes.cpp b/clangd/ExpectedTypes.cpp index 4bbf0651..59d9e149 100644 --- a/clangd/ExpectedTypes.cpp +++ b/clangd/ExpectedTypes.cpp @@ -35,8 +35,10 @@ static llvm::Optional typeOfCompletion(const CodeCompletionResult &R) { auto *VD = dyn_cast_or_null(R.Declaration); if (!VD) - return None; // We handle only variables and functions below. + return llvm::None; // We handle only variables and functions below. auto T = VD->getType(); + if (T.isNull()) + return llvm::None; if (auto FuncT = T->getAs()) { // Functions are a special case. They are completed as 'foo()' and we want // to match their return type rather than the function type itself. diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp index c8059344..16d5eef0 100644 --- a/unittests/clangd/CodeCompleteTests.cpp +++ b/unittests/clangd/CodeCompleteTests.cpp @@ -2319,6 +2319,17 @@ TEST(CompletionTest, ObjectiveCMethodTwoArgumentsFromMiddle) { EXPECT_THAT(C, ElementsAre(SnippetSuffix("${1:(unsigned int)}"))); } +TEST(CompletionTest, WorksWithNullType) { + auto R = completions(R"cpp( + int main() { + for (auto [loopVar] : y ) { // y has to be unresolved. + int z = loopV^; + } + } + )cpp"); + EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar"))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From e5ac0331dfb10bd8945e69cb61682e1a110766e9 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 24 Jan 2019 14:25:53 +0000 Subject: [clangd] Clean the cache of file statuses on vscode-clangd when clangd crashes. Summary: Clear the cached file statuses, otherwise we will leave some garbage texts on the status bar when clangd crashes. Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D56540 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352049 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/clients/clangd-vscode/src/extension.ts | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/clangd/clients/clangd-vscode/src/extension.ts b/clangd/clients/clangd-vscode/src/extension.ts index cad6a3a1..d4ab6787 100644 --- a/clangd/clients/clangd-vscode/src/extension.ts +++ b/clangd/clients/clangd-vscode/src/extension.ts @@ -40,6 +40,11 @@ class FileStatus { this.statusBarItem.show(); } + clear() { + this.statuses.clear(); + this.statusBarItem.hide(); + } + dispose() { this.statusBarItem.dispose(); } @@ -112,9 +117,16 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(vscode.window.onDidChangeActiveTextEditor(() => { status.updateStatus(); })); - clangdClient.onReady().then(() => { - clangdClient.onNotification( - 'textDocument/clangd.fileStatus', - (fileStatus) => { status.onFileUpdated(fileStatus); }); - }) + clangdClient.onDidChangeState( + ({ newState }) => { + if (newState == vscodelc.State.Running) { + // clangd starts or restarts after crash. + clangdClient.onNotification( + 'textDocument/clangd.fileStatus', + (fileStatus) => { status.onFileUpdated(fileStatus); }); + } else if (newState == vscodelc.State.Stopped) { + // Clear all cached statuses when clangd crashes. + status.clear(); + } + }) } -- cgit v1.2.3 From 5540de03073b8bd8a9e18aa3b064f3ac96b571ae Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Thu, 24 Jan 2019 19:23:50 +0000 Subject: [clang-tidy] Rename the absl duration helper functions; NFC git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352088 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/DurationComparisonCheck.cpp | 2 +- clang-tidy/abseil/DurationConversionCastCheck.cpp | 7 ++++--- clang-tidy/abseil/DurationFactoryScaleCheck.cpp | 4 ++-- clang-tidy/abseil/DurationRewriter.cpp | 10 +++++----- clang-tidy/abseil/DurationRewriter.h | 6 +++--- clang-tidy/abseil/DurationSubtractionCheck.cpp | 3 ++- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tidy/abseil/DurationComparisonCheck.cpp index b724622d..337f2ca0 100644 --- a/clang-tidy/abseil/DurationComparisonCheck.cpp +++ b/clang-tidy/abseil/DurationComparisonCheck.cpp @@ -34,7 +34,7 @@ void DurationComparisonCheck::registerMatchers(MatchFinder *Finder) { void DurationComparisonCheck::check(const MatchFinder::MatchResult &Result) { const auto *Binop = Result.Nodes.getNodeAs("binop"); - llvm::Optional Scale = getScaleForInverse( + llvm::Optional Scale = getScaleForDurationInverse( Result.Nodes.getNodeAs("function_decl")->getName()); if (!Scale) return; diff --git a/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tidy/abseil/DurationConversionCastCheck.cpp index 827ab56a..f0ae82c0 100644 --- a/clang-tidy/abseil/DurationConversionCastCheck.cpp +++ b/clang-tidy/abseil/DurationConversionCastCheck.cpp @@ -44,14 +44,15 @@ void DurationConversionCastCheck::check( const auto *Arg = Result.Nodes.getNodeAs("arg"); StringRef ConversionFuncName = FuncDecl->getName(); - llvm::Optional Scale = getScaleForInverse(ConversionFuncName); + llvm::Optional Scale = + getScaleForDurationInverse(ConversionFuncName); if (!Scale) return; // Casting a double to an integer. if (MatchedCast->getTypeAsWritten()->isIntegerType() && ConversionFuncName.contains("Double")) { - llvm::StringRef NewFuncName = getInverseForScale(*Scale).second; + llvm::StringRef NewFuncName = getDurationInverseForScale(*Scale).second; diag(MatchedCast->getBeginLoc(), "duration should be converted directly to an integer rather than " @@ -66,7 +67,7 @@ void DurationConversionCastCheck::check( // Casting an integer to a double. if (MatchedCast->getTypeAsWritten()->isRealFloatingType() && ConversionFuncName.contains("Int64")) { - llvm::StringRef NewFuncName = getInverseForScale(*Scale).first; + llvm::StringRef NewFuncName = getDurationInverseForScale(*Scale).first; diag(MatchedCast->getBeginLoc(), "duration should be converted directly to " "a floating-piont number rather than " diff --git a/clang-tidy/abseil/DurationFactoryScaleCheck.cpp b/clang-tidy/abseil/DurationFactoryScaleCheck.cpp index 0884a1db..c3b41919 100644 --- a/clang-tidy/abseil/DurationFactoryScaleCheck.cpp +++ b/clang-tidy/abseil/DurationFactoryScaleCheck.cpp @@ -209,7 +209,7 @@ void DurationFactoryScaleCheck::check(const MatchFinder::MatchResult &Result) { diag(Call->getBeginLoc(), "internal duration scaling can be removed") << FixItHint::CreateReplacement( Call->getSourceRange(), - (llvm::Twine(getFactoryForScale(*NewScale)) + "(" + + (llvm::Twine(getDurationFactoryForScale(*NewScale)) + "(" + tooling::fixit::getText(*Remainder, *Result.Context) + ")") .str()); } @@ -222,7 +222,7 @@ void DurationFactoryScaleCheck::check(const MatchFinder::MatchResult &Result) { diag(Call->getBeginLoc(), "internal duration scaling can be removed") << FixItHint::CreateReplacement( Call->getSourceRange(), - (llvm::Twine(getFactoryForScale(*NewScale)) + "(" + + (llvm::Twine(getDurationFactoryForScale(*NewScale)) + "(" + tooling::fixit::getText(*Remainder, *Result.Context) + ")") .str()); } diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index eac7df66..5a3f98bf 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -37,7 +37,7 @@ truncateIfIntegral(const FloatingLiteral &FloatLiteral) { } const std::pair & -getInverseForScale(DurationScale Scale) { +getDurationInverseForScale(DurationScale Scale) { static const llvm::IndexedMap, DurationScale2IndexFunctor> InverseMap = []() { @@ -71,7 +71,7 @@ static llvm::Optional rewriteInverseDurationCall(const MatchFinder::MatchResult &Result, DurationScale Scale, const Expr &Node) { const std::pair &InverseFunctions = - getInverseForScale(Scale); + getDurationInverseForScale(Scale); if (const auto *MaybeCallArg = selectFirst( "e", match(callExpr(callee(functionDecl(hasAnyName( @@ -85,7 +85,7 @@ rewriteInverseDurationCall(const MatchFinder::MatchResult &Result, } /// Returns the factory function name for a given `Scale`. -llvm::StringRef getFactoryForScale(DurationScale Scale) { +llvm::StringRef getDurationFactoryForScale(DurationScale Scale) { switch (Scale) { case DurationScale::Hours: return "absl::Hours"; @@ -175,7 +175,7 @@ std::string simplifyDurationFactoryArg(const MatchFinder::MatchResult &Result, return tooling::fixit::getText(Node, *Result.Context).str(); } -llvm::Optional getScaleForInverse(llvm::StringRef Name) { +llvm::Optional getScaleForDurationInverse(llvm::StringRef Name) { static const llvm::StringMap ScaleMap( {{"ToDoubleHours", DurationScale::Hours}, {"ToInt64Hours", DurationScale::Hours}, @@ -210,7 +210,7 @@ std::string rewriteExprFromNumberToDuration( if (IsLiteralZero(Result, RootNode)) return std::string("absl::ZeroDuration()"); - return (llvm::Twine(getFactoryForScale(Scale)) + "(" + + return (llvm::Twine(getDurationFactoryForScale(Scale)) + "(" + simplifyDurationFactoryArg(Result, RootNode) + ")") .str(); } diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index ac8fe19f..1542b4c3 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -29,7 +29,7 @@ enum class DurationScale : std::uint8_t { /// Given a `Scale`, return the appropriate factory function call for /// constructing a `Duration` for that scale. -llvm::StringRef getFactoryForScale(DurationScale Scale); +llvm::StringRef getDurationFactoryForScale(DurationScale Scale); // Determine if `Node` represents a literal floating point or integral zero. bool IsLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result, @@ -60,13 +60,13 @@ simplifyDurationFactoryArg(const ast_matchers::MatchFinder::MatchResult &Result, /// Given the name of an inverse Duration function (e.g., `ToDoubleSeconds`), /// return its `DurationScale`, or `None` if a match is not found. -llvm::Optional getScaleForInverse(llvm::StringRef Name); +llvm::Optional getScaleForDurationInverse(llvm::StringRef Name); /// Given a `Scale` return the fully qualified inverse functions for it. /// The first returned value is the inverse for `double`, and the second /// returned value is the inverse for `int64`. const std::pair & -getInverseForScale(DurationScale Scale); +getDurationInverseForScale(DurationScale Scale); /// Assuming `Node` has type `double` or `int` representing a time interval of /// `Scale`, return the expression to make it a suitable `Duration`. diff --git a/clang-tidy/abseil/DurationSubtractionCheck.cpp b/clang-tidy/abseil/DurationSubtractionCheck.cpp index 17f610ae..32217144 100644 --- a/clang-tidy/abseil/DurationSubtractionCheck.cpp +++ b/clang-tidy/abseil/DurationSubtractionCheck.cpp @@ -37,7 +37,8 @@ void DurationSubtractionCheck::check(const MatchFinder::MatchResult &Result) { if (Binop->getExprLoc().isMacroID() || Binop->getExprLoc().isInvalid()) return; - llvm::Optional Scale = getScaleForInverse(FuncDecl->getName()); + llvm::Optional Scale = + getScaleForDurationInverse(FuncDecl->getName()); if (!Scale) return; -- cgit v1.2.3 From 6189413c4dc7c60f6baee8c1d15946bf8addd428 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 25 Jan 2019 10:03:49 +0000 Subject: [clang-tidy] Add check for underscores in googletest names. Summary: Adds a clang-tidy warning for underscores in googletest names. Patch by Kar Epker! Reviewers: hokein, alexfh, aaron.ballman Reviewed By: hokein Subscribers: Eugene.Zelenko, JonasToth, MyDeveloperDay, lebedev.ri, xazax.hun, mgorny, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D56424 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352183 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../AvoidUnderscoreInGoogletestNameCheck.cpp | 89 +++++++++++++++++ .../google/AvoidUnderscoreInGoogletestNameCheck.h | 33 +++++++ clang-tidy/google/CMakeLists.txt | 1 + clang-tidy/google/GoogleTidyModule.cpp | 4 + docs/ReleaseNotes.rst | 8 ++ ...ability-avoid-underscore-in-googletest-name.rst | 34 +++++++ docs/clang-tidy/checks/list.rst | 1 + ...ability-avoid-underscore-in-googletest-name.cpp | 108 +++++++++++++++++++++ 8 files changed, 278 insertions(+) create mode 100644 clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp create mode 100644 clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h create mode 100644 docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst create mode 100644 test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp diff --git a/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp new file mode 100644 index 00000000..fbc47b77 --- /dev/null +++ b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.cpp @@ -0,0 +1,89 @@ +//===--- AvoidUnderscoreInGoogletestNameCheck.cpp - clang-tidy --*- 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 + +#include "AvoidUnderscoreInGoogletestNameCheck.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Lex/MacroArgs.h" + +namespace clang { +namespace tidy { +namespace google { +namespace readability { + +constexpr llvm::StringLiteral kDisabledTestPrefix = "DISABLED_"; + +// Determines whether the macro is a Googletest test macro. +static bool isGoogletestTestMacro(StringRef MacroName) { + static const llvm::StringSet<> MacroNames = {"TEST", "TEST_F", "TEST_P", + "TYPED_TEST", "TYPED_TEST_P"}; + return MacroNames.find(MacroName) != MacroNames.end(); +} + +namespace { + +class AvoidUnderscoreInGoogletestNameCallback : public PPCallbacks { +public: + AvoidUnderscoreInGoogletestNameCallback( + Preprocessor *PP, AvoidUnderscoreInGoogletestNameCheck *Check) + : PP(PP), Check(Check) {} + + // Detects expansions of the TEST, TEST_F, TEST_P, TYPED_TEST, TYPED_TEST_P + // macros and checks that their arguments do not have any underscores. + void MacroExpands(const Token &MacroNameToken, + const MacroDefinition &MacroDefinition, SourceRange Range, + const MacroArgs *Args) override { + IdentifierInfo *NameIdentifierInfo = MacroNameToken.getIdentifierInfo(); + if (!NameIdentifierInfo) + return; + StringRef MacroName = NameIdentifierInfo->getName(); + if (!isGoogletestTestMacro(MacroName) || !Args || + Args->getNumMacroArguments() < 2) + return; + const Token *TestCaseNameToken = Args->getUnexpArgument(0); + const Token *TestNameToken = Args->getUnexpArgument(1); + if (!TestCaseNameToken || !TestNameToken) + return; + std::string TestCaseName = PP->getSpelling(*TestCaseNameToken); + if (TestCaseName.find('_') != std::string::npos) + Check->diag(TestCaseNameToken->getLocation(), + "avoid using \"_\" in test case name \"%0\" according to " + "Googletest FAQ") + << TestCaseName; + + std::string TestNameMaybeDisabled = PP->getSpelling(*TestNameToken); + StringRef TestName = TestNameMaybeDisabled; + TestName.consume_front(kDisabledTestPrefix); + if (TestName.contains('_')) + Check->diag(TestNameToken->getLocation(), + "avoid using \"_\" in test name \"%0\" according to " + "Googletest FAQ") + << TestName; + } + +private: + Preprocessor *PP; + AvoidUnderscoreInGoogletestNameCheck *Check; +}; + +} // namespace + +void AvoidUnderscoreInGoogletestNameCheck::registerPPCallbacks( + CompilerInstance &Compiler) { + Compiler.getPreprocessor().addPPCallbacks( + llvm::make_unique( + &Compiler.getPreprocessor(), this)); +} + +} // namespace readability +} // namespace google +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h new file mode 100644 index 00000000..8a1a2f25 --- /dev/null +++ b/clang-tidy/google/AvoidUnderscoreInGoogletestNameCheck.h @@ -0,0 +1,33 @@ +//===--- AvoidUnderscoreInGoogletestNameCheck.h - clang-tidy ----*- 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_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace google { +namespace readability { + +// Check for underscores in the names of googletest tests, per +// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore +class AvoidUnderscoreInGoogletestNameCheck : public ClangTidyCheck { +public: + using ClangTidyCheck::ClangTidyCheck; + + void registerPPCallbacks(CompilerInstance &Compiler) override; +}; + +} // namespace readability +} // namespace google +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_GOOGLE_AVOIDUNDERSCOREINGOOGLETESTNAMECHECK_H diff --git a/clang-tidy/google/CMakeLists.txt b/clang-tidy/google/CMakeLists.txt index 2ded4aab..4d0a326f 100644 --- a/clang-tidy/google/CMakeLists.txt +++ b/clang-tidy/google/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyGoogleModule AvoidCStyleCastsCheck.cpp AvoidThrowingObjCExceptionCheck.cpp + AvoidUnderscoreInGoogletestNameCheck.cpp DefaultArgumentsCheck.cpp ExplicitConstructorCheck.cpp ExplicitMakePairCheck.cpp diff --git a/clang-tidy/google/GoogleTidyModule.cpp b/clang-tidy/google/GoogleTidyModule.cpp index e6236ec2..c2a9ec5e 100644 --- a/clang-tidy/google/GoogleTidyModule.cpp +++ b/clang-tidy/google/GoogleTidyModule.cpp @@ -14,6 +14,7 @@ #include "../readability/NamespaceCommentCheck.h" #include "AvoidCStyleCastsCheck.h" #include "AvoidThrowingObjCExceptionCheck.h" +#include "AvoidUnderscoreInGoogletestNameCheck.h" #include "DefaultArgumentsCheck.h" #include "ExplicitConstructorCheck.h" #include "ExplicitMakePairCheck.h" @@ -60,6 +61,9 @@ class GoogleModule : public ClangTidyModule { "google-runtime-operator"); CheckFactories.registerCheck( "google-runtime-references"); + CheckFactories + .registerCheck( + "google-readability-avoid-underscore-in-googletest-name"); CheckFactories.registerCheck( "google-readability-casting"); CheckFactories.registerCheck( diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index bb699349..ecac6607 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -73,6 +73,14 @@ Improvements to clang-tidy Checks for casts of ``absl::Duration`` conversion functions, and recommends the right conversion function instead. +- New :doc:`google-readability-avoid-underscore-in-googletest-name + ` + check. + + Checks whether there are underscores in googletest test and test case names in + test macros, which is prohibited by the Googletest FAQ. + + Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst b/docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst new file mode 100644 index 00000000..75b1a9ab --- /dev/null +++ b/docs/clang-tidy/checks/google-readability-avoid-underscore-in-googletest-name.rst @@ -0,0 +1,34 @@ +.. title:: clang-tidy - google-readability-avoid-underscore-in-googletest-name + +google-readability-avoid-underscore-in-googletest-name +====================================================== + +Checks whether there are underscores in googletest test and test case names in +test macros: + +- ``TEST`` +- ``TEST_F`` +- ``TEST_P`` +- ``TYPED_TEST`` +- ``TYPED_TEST_P`` + +The ``FRIEND_TEST`` macro is not included. + +For example: + +.. code-block:: c++ + + TEST(TestCaseName, Illegal_TestName) {} + TEST(Illegal_TestCaseName, TestName) {} + +would trigger the check. `Underscores are not allowed`_ in test names nor test +case names. + +The ``DISABLED_`` prefix, which may be used to `disable individual tests`_, is +ignored when checking test names, but the rest of the rest of the test name is +still checked. + +This check does not propose any fixes. + +.. _Underscores are not allowed: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore +.. _disable individual tests: https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 509b1406..8397675e 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -131,6 +131,7 @@ Clang-Tidy Checks google-objc-avoid-throwing-exception google-objc-function-naming google-objc-global-variable-declaration + google-readability-avoid-underscore-in-googletest-name google-readability-braces-around-statements (redirects to readability-braces-around-statements) google-readability-casting google-readability-function-size (redirects to readability-function-size) diff --git a/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp b/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp new file mode 100644 index 00000000..6e8a5c2d --- /dev/null +++ b/test/clang-tidy/readability-avoid-underscore-in-googletest-name.cpp @@ -0,0 +1,108 @@ +// RUN: %check_clang_tidy %s google-readability-avoid-underscore-in-googletest-name %t + +#define TEST(test_case_name, test_name) void test_case_name##test_name() +#define TEST_F(test_case_name, test_name) void test_case_name##test_name() +#define TEST_P(test_case_name, test_name) void test_case_name##test_name() +#define TYPED_TEST(test_case_name, test_name) void test_case_name##test_name() +#define TYPED_TEST_P(test_case_name, test_name) void test_case_name##test_name() +#define FRIEND_TEST(test_case_name, test_name) void test_case_name##test_name() + +TEST(TestCaseName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST(TestCaseName, DISABLED_Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST(TestCaseName, Illegal_Test_Name) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST(Illegal_TestCaseName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST(Illegal_Test_CaseName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_Test_CaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST(Illegal_TestCaseName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: avoid using "_" in test case name "Illegal_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST_F(TestCaseFixtureName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST_F(TestCaseFixtureName, DISABLED_Illegal_Test_Name) {} +// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST_F(TestCaseFixtureName, Illegal_Test_Name) {} +// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST_F(Illegal_TestCaseFixtureName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST_F(Illegal_TestCaseFixtureName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +// CHECK-MESSAGES: :[[@LINE-2]]:37: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST_F(Illegal_Test_CaseFixtureName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Test_CaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST_P(ParameterizedTestCaseFixtureName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST_P(ParameterizedTestCaseFixtureName, DISABLED_Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST_P(ParameterizedTestCaseFixtureName, Illegal_Test_Name) {} +// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST_P(Illegal_ParameterizedTestCaseFixtureName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TEST_P(Illegal_ParameterizedTestCaseFixtureName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_ParameterizedTestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +// CHECK-MESSAGES: :[[@LINE-2]]:50: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TEST_P(Illegal_Parameterized_TestCaseFixtureName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: avoid using "_" in test case name "Illegal_Parameterized_TestCaseFixtureName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TYPED_TEST(TypedTestCaseName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TYPED_TEST(TypedTestCaseName, DISABLED_Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TYPED_TEST(TypedTestCaseName, Illegal_Test_Name) {} +// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TYPED_TEST(Illegal_TypedTestCaseName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TYPED_TEST(Illegal_TypedTestCaseName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_TypedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +// CHECK-MESSAGES: :[[@LINE-2]]:39: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TYPED_TEST(Illegal_Typed_TestCaseName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid using "_" in test case name "Illegal_Typed_TestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TYPED_TEST_P(TypeParameterizedTestCaseName, DISABLED_Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TYPED_TEST_P(TypeParameterizedTestCaseName, Illegal_Test_Name) {} +// CHECK-MESSAGES: :[[@LINE-1]]:45: warning: avoid using "_" in test name "Illegal_Test_Name" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +TYPED_TEST_P(Illegal_TypeParameterizedTestCaseName, Illegal_TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_TypeParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] +// CHECK-MESSAGES: :[[@LINE-2]]:53: warning: avoid using "_" in test name "Illegal_TestName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +TYPED_TEST_P(Illegal_Type_ParameterizedTestCaseName, TestName) {} +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: avoid using "_" in test case name "Illegal_Type_ParameterizedTestCaseName" according to Googletest FAQ [google-readability-avoid-underscore-in-googletest-name] + +// Underscores are allowed to disable a test with the DISABLED_ prefix. +// https://github.com/google/googletest/blob/master/googletest/docs/faq.md#why-should-test-suite-names-and-test-names-not-contain-underscore +TEST(TestCaseName, TestName) {} +TEST(TestCaseName, DISABLED_TestName) {} + +TEST_F(TestCaseFixtureName, TestName) {} +TEST_F(TestCaseFixtureName, DISABLED_TestName) {} + +TEST_P(ParameterizedTestCaseFixtureName, TestName) {} +TEST_P(ParameterizedTestCaseFixtureName, DISABLED_TestName) {} + +TYPED_TEST(TypedTestName, TestName) {} +TYPED_TEST(TypedTestName, DISABLED_TestName) {} + +TYPED_TEST_P(TypeParameterizedTestName, TestName) {} +TYPED_TEST_P(TypeParameterizedTestName, DISABLED_TestName) {} + +FRIEND_TEST(FriendTest, Is_NotChecked) {} +FRIEND_TEST(Friend_Test, IsNotChecked) {} +FRIEND_TEST(Friend_Test, Is_NotChecked) {} -- cgit v1.2.3 From 27fe819fb0bb0d80d56943e9c6030ef4e6ca2994 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 25 Jan 2019 10:14:27 +0000 Subject: [clangd] Log clang-tidy configuration, NFC Summary: This is used for debugging purpose. Reviewers: sammccall Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D57057 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352184 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 5e232b79..551d1798 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -265,6 +265,8 @@ ParsedAST::build(std::unique_ptr CI, llvm::Optional CTContext; { trace::Span Tracer("ClangTidyInit"); + vlog("ClangTidy configuration for file {0}: {1}", MainInput.getFile(), + tidy::configurationAsText(ClangTidyOpts)); tidy::ClangTidyCheckFactories CTFactories; for (const auto &E : tidy::ClangTidyModuleRegistry::entries()) E.instantiate()->addCheckFactories(CTFactories); -- cgit v1.2.3 From 63a2be787b54317fd19518f8c15054d93c504675 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 25 Jan 2019 15:14:03 +0000 Subject: [clangd] NFC: fix clang-tidy warnings. Most are about llvm code style violation (found via readability-identifier-naming check). git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352205 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.h | 4 ++-- clangd/CodeComplete.cpp | 8 ++++---- clangd/Protocol.cpp | 24 ++++++++++++------------ clangd/SourceCode.cpp | 2 +- clangd/SourceCode.h | 2 +- clangd/TUScheduler.cpp | 2 +- clangd/XRefs.cpp | 4 ++-- clangd/index/Index.cpp | 8 ++++---- clangd/index/Serialization.cpp | 6 +++--- clangd/index/SymbolID.cpp | 3 ++- unittests/clangd/SourceCodeTests.cpp | 6 +++--- 11 files changed, 35 insertions(+), 34 deletions(-) diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index ba430d5d..23adb15c 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -31,7 +31,7 @@ class raw_ostream; namespace vfs { class FileSystem; -} +} // namespace vfs } // namespace llvm namespace clang { @@ -39,7 +39,7 @@ class PCHContainerOperations; namespace tooling { struct CompileCommand; -} +} // namespace tooling namespace clangd { diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index e1be6b45..66100d8c 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1588,9 +1588,9 @@ speculateCompletionFilter(llvm::StringRef Content, Position Pos) { // Start from the character before the cursor. int St = *Offset - 1; // FIXME(ioeric): consider UTF characters? - auto IsValidIdentifierChar = [](char c) { - return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || - (c >= '0' && c <= '9') || (c == '_')); + auto IsValidIdentifierChar = [](char C) { + return ((C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || + (C >= '0' && C <= '9') || (C == '_')); }; size_t Len = 0; for (; (St >= 0) && IsValidIdentifierChar(Content[St]); --St, ++Len) { @@ -1682,7 +1682,7 @@ CompletionItem CodeCompletion::render(const CodeCompleteOptions &Opts) const { // is mainly to help LSP clients again, so that changes do not effect each // other. for (const auto &FixIt : FixIts) { - if (IsRangeConsecutive(FixIt.range, LSP.textEdit->range)) { + if (isRangeConsecutive(FixIt.range, LSP.textEdit->range)) { LSP.textEdit->newText = FixIt.newText + LSP.textEdit->newText; LSP.textEdit->range.start = FixIt.range.start; } else { diff --git a/clangd/Protocol.cpp b/clangd/Protocol.cpp index 84150772..89b1cbf3 100644 --- a/clangd/Protocol.cpp +++ b/clangd/Protocol.cpp @@ -455,25 +455,25 @@ bool operator==(const SymbolDetails &LHS, const SymbolDetails &RHS) { } llvm::json::Value toJSON(const SymbolDetails &P) { - llvm::json::Object result{{"name", llvm::json::Value(nullptr)}, + llvm::json::Object Result{{"name", llvm::json::Value(nullptr)}, {"containerName", llvm::json::Value(nullptr)}, {"usr", llvm::json::Value(nullptr)}, {"id", llvm::json::Value(nullptr)}}; if (!P.name.empty()) - result["name"] = P.name; + Result["name"] = P.name; if (!P.containerName.empty()) - result["containerName"] = P.containerName; + Result["containerName"] = P.containerName; if (!P.USR.empty()) - result["usr"] = P.USR; + Result["usr"] = P.USR; if (P.ID.hasValue()) - result["id"] = P.ID.getValue().str(); + Result["id"] = P.ID.getValue().str(); // Older clang cannot compile 'return Result', even though it is legal. - return llvm::json::Value(std::move(result)); + return llvm::json::Value(std::move(Result)); } llvm::raw_ostream &operator<<(llvm::raw_ostream &O, const SymbolDetails &S) { @@ -559,10 +559,10 @@ bool fromJSON(const llvm::json::Value &Params, CompletionContext &R) { if (!O) return false; - int triggerKind; - if (!O.map("triggerKind", triggerKind)) + int TriggerKind; + if (!O.map("triggerKind", TriggerKind)) return false; - R.triggerKind = static_cast(triggerKind); + R.triggerKind = static_cast(TriggerKind); if (auto *TC = Params.getAsObject()->get("triggerCharacter")) return fromJSON(*TC, R.triggerCharacter); @@ -619,11 +619,11 @@ bool fromJSON(const llvm::json::Value &E, CompletionItemKind &Out) { CompletionItemKind adjustKindToCapability(CompletionItemKind Kind, - CompletionItemKindBitset &supportedCompletionItemKinds) { + CompletionItemKindBitset &SupportedCompletionItemKinds) { auto KindVal = static_cast(Kind); if (KindVal >= CompletionItemKindMin && - KindVal <= supportedCompletionItemKinds.size() && - supportedCompletionItemKinds[KindVal]) + KindVal <= SupportedCompletionItemKinds.size() && + SupportedCompletionItemKinds[KindVal]) return Kind; switch (Kind) { diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp index 6952e87d..ede64353 100644 --- a/clangd/SourceCode.cpp +++ b/clangd/SourceCode.cpp @@ -231,7 +231,7 @@ TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, return Result; } -bool IsRangeConsecutive(const Range &Left, const Range &Right) { +bool isRangeConsecutive(const Range &Left, const Range &Right) { return Left.end.line == Right.start.line && Left.end.character == Right.start.character; } diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index a3dbc7ab..7c8499d8 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -90,7 +90,7 @@ TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, llvm::Optional getCanonicalPath(const FileEntry *F, const SourceManager &SourceMgr); -bool IsRangeConsecutive(const Range &Left, const Range &Right); +bool isRangeConsecutive(const Range &Left, const Range &Right); } // namespace clangd } // namespace clang #endif diff --git a/clangd/TUScheduler.cpp b/clangd/TUScheduler.cpp index cf0bf0e0..14319ab9 100644 --- a/clangd/TUScheduler.cpp +++ b/clangd/TUScheduler.cpp @@ -61,7 +61,7 @@ using std::chrono::steady_clock; namespace { class ASTWorker; -} +} // namespace static clang::clangd::Key kFileBeingProcessed; diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 7db0202d..2f0990a9 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -137,7 +137,7 @@ public: SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override { if (Loc == SearchedLocation) { - auto isImplicitExpr = [](const Expr *E) { + auto IsImplicitExpr = [](const Expr *E) { if (!E) return false; // We assume that a constructor expression is implict (was inserted by @@ -149,7 +149,7 @@ public: return isa(E); }; - bool IsExplicit = !isImplicitExpr(ASTNode.OrigE); + bool IsExplicit = !IsImplicitExpr(ASTNode.OrigE); // Find and add definition declarations (for GoToDefinition). // We don't use parameter `D`, as Parameter `D` is the canonical // declaration, which is the first declaration of a redeclarable diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index a13d28b3..c773cd69 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -53,12 +53,12 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) { llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) { if (F == Symbol::None) return OS << "None"; - std::string s; + std::string S; if (F & Symbol::Deprecated) - s += "deprecated|"; + S += "deprecated|"; if (F & Symbol::IndexedForCodeCompletion) - s += "completion|"; - return OS << llvm::StringRef(s).rtrim('|'); + S += "completion|"; + return OS << llvm::StringRef(S).rtrim('|'); } llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) { diff --git a/clangd/index/Serialization.cpp b/clangd/index/Serialization.cpp index bdad7fd5..20c43ab0 100644 --- a/clangd/index/Serialization.cpp +++ b/clangd/index/Serialization.cpp @@ -105,9 +105,9 @@ public: }; void write32(uint32_t I, llvm::raw_ostream &OS) { - char buf[4]; - llvm::support::endian::write32le(buf, I); - OS.write(buf, sizeof(buf)); + char Buf[4]; + llvm::support::endian::write32le(Buf, I); + OS.write(Buf, sizeof(Buf)); } void writeVar(uint32_t I, llvm::raw_ostream &OS) { diff --git a/clangd/index/SymbolID.cpp b/clangd/index/SymbolID.cpp index 7510063a..b97103d3 100644 --- a/clangd/index/SymbolID.cpp +++ b/clangd/index/SymbolID.cpp @@ -49,7 +49,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolID &ID) { llvm::hash_code hash_value(const SymbolID &ID) { // We already have a good hash, just return the first bytes. - assert(sizeof(size_t) <= SymbolID::RawSize && "size_t longer than SHA1!"); + static_assert(sizeof(size_t) <= SymbolID::RawSize, + "size_t longer than SHA1!"); size_t Result; memcpy(&Result, ID.raw().data(), sizeof(size_t)); return llvm::hash_code(Result); diff --git a/unittests/clangd/SourceCodeTests.cpp b/unittests/clangd/SourceCodeTests.cpp index f7c97e00..c17ce46c 100644 --- a/unittests/clangd/SourceCodeTests.cpp +++ b/unittests/clangd/SourceCodeTests.cpp @@ -133,11 +133,11 @@ TEST(SourceCodeTests, OffsetToPosition) { } TEST(SourceCodeTests, IsRangeConsecutive) { - EXPECT_TRUE(IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4}))); + EXPECT_TRUE(isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 3}, {2, 4}))); EXPECT_FALSE( - IsRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4}))); + isRangeConsecutive(range({0, 2}, {0, 3}), range({2, 3}, {2, 4}))); EXPECT_FALSE( - IsRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5}))); + isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5}))); } } // namespace -- cgit v1.2.3 From b8b6cee67ff741c0bd06d791db2563983a41b346 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 25 Jan 2019 18:05:43 +0000 Subject: Temporairly disable readability-uppercase-literal-suffix tests that depend on _Float16, to get bots back to green git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352224 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp | 2 ++ .../readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp index 4d41db7a..0421288d 100644 --- a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp +++ b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp @@ -3,6 +3,8 @@ // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S +// REQUIRES: disabled + #include "readability-uppercase-literal-suffix.h" void floating_point_suffix() { diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp index 4cc9d6d2..0cd02030 100644 --- a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp +++ b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp @@ -3,6 +3,8 @@ // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S +// REQUIRES: disabled + #include "readability-uppercase-literal-suffix.h" void floating_point_suffix() { -- cgit v1.2.3 From d83c214f60d0c8cb8e172d41563754fa2a9bc48b Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Fri, 25 Jan 2019 19:05:12 +0000 Subject: [clang-tidy] fix unit tests for dropped _Float16 support in X86 Summary: Because _Float16 was disabled for X86 targets the unit-tests started failing. Extract the pieces for _Float16 and run theses tests under AArch64. Reviewers: aaron.ballman, erichkeane, lebedev.ri Reviewed By: erichkeane Subscribers: javed.absar, xazax.hun, kristof.beyls, cfe-commits Differential Revision: https://reviews.llvm.org/D57249 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352231 91177308-0d34-0410-b5e6-96231b3b80d8 --- ...eadability-uppercase-literal-suffix-float16.cpp | 51 ++++++++++++++++++++++ ...ity-uppercase-literal-suffix-floating-point.cpp | 30 ------------- ...e-literal-suffix-hexadecimal-floating-point.cpp | 17 -------- 3 files changed, 51 insertions(+), 47 deletions(-) create mode 100644 test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp new file mode 100644 index 00000000..b2b858f9 --- /dev/null +++ b/test/clang-tidy/readability-uppercase-literal-suffix-float16.cpp @@ -0,0 +1,51 @@ +// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target aarch64-linux-gnu -I %S + +#include "readability-uppercase-literal-suffix.h" + +void float16_normal_literals() { + // _Float16 + + static constexpr auto v14 = 1.f16; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase + // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16; + // CHECK-MESSAGES-NEXT: ^ ~ + // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} + // CHECK-FIXES: static constexpr auto v14 = 1.F16; + static_assert(is_same::value, ""); + static_assert(v14 == 1.F16, ""); + + static constexpr auto v15 = 1.e0f16; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase + // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16; + // CHECK-MESSAGES-NEXT: ^ ~ + // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} + // CHECK-FIXES: static constexpr auto v15 = 1.e0F16; + static_assert(is_same::value, ""); + static_assert(v15 == 1.F16, ""); + + static constexpr auto v16 = 1.F16; // OK. + static_assert(is_same::value, ""); + static_assert(v16 == 1.F16, ""); + + static constexpr auto v17 = 1.e0F16; // OK. + static_assert(is_same::value, ""); + static_assert(v17 == 1.F16, ""); +} + +void float16_hexadecimal_literals() { +// _Float16 + + static constexpr auto v13 = 0xfp0f16; + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase + // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16; + // CHECK-MESSAGES-NEXT: ^ ~ + // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} + // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16; + static_assert(is_same::value, ""); + static_assert(v13 == 0xfp0F16, ""); + + static constexpr auto v14 = 0xfp0F16; // OK. + static_assert(is_same::value, ""); + static_assert(v14 == 0xfp0F16, ""); + +} diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp index 0421288d..50e75fae 100644 --- a/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp +++ b/test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp @@ -3,8 +3,6 @@ // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S -// REQUIRES: disabled - #include "readability-uppercase-literal-suffix.h" void floating_point_suffix() { @@ -99,34 +97,6 @@ void floating_point_suffix() { static constexpr auto v13 = 1.e0Q; // OK. static_assert(is_same::value, ""); static_assert(v13 == 1., ""); - - // _Float16 - - static constexpr auto v14 = 1.f16; - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase - // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16; - // CHECK-MESSAGES-NEXT: ^ ~ - // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} - // CHECK-FIXES: static constexpr auto v14 = 1.F16; - static_assert(is_same::value, ""); - static_assert(v14 == 1.F16, ""); - - static constexpr auto v15 = 1.e0f16; - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase - // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16; - // CHECK-MESSAGES-NEXT: ^ ~ - // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} - // CHECK-FIXES: static constexpr auto v15 = 1.e0F16; - static_assert(is_same::value, ""); - static_assert(v15 == 1.F16, ""); - - static constexpr auto v16 = 1.F16; // OK. - static_assert(is_same::value, ""); - static_assert(v16 == 1.F16, ""); - - static constexpr auto v17 = 1.e0F16; // OK. - static_assert(is_same::value, ""); - static_assert(v17 == 1.F16, ""); } void floating_point_complex_suffix() { diff --git a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp index 0cd02030..415c6d8e 100644 --- a/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp +++ b/test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp @@ -3,8 +3,6 @@ // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S // RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S -// REQUIRES: disabled - #include "readability-uppercase-literal-suffix.h" void floating_point_suffix() { @@ -95,21 +93,6 @@ void floating_point_suffix() { static constexpr auto v12 = 0xfp0Q; // OK. static_assert(is_same::value, ""); static_assert(v12 == 0xfp0, ""); - - // _Float16 - - static constexpr auto v13 = 0xfp0f16; - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase - // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16; - // CHECK-MESSAGES-NEXT: ^ ~ - // CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}} - // CHECK-FIXES: static constexpr auto v13 = 0xfp0F16; - static_assert(is_same::value, ""); - static_assert(v13 == 0xfp0F16, ""); - - static constexpr auto v14 = 0xfp0F16; // OK. - static_assert(is_same::value, ""); - static_assert(v14 == 0xfp0F16, ""); } void floating_point_complex_suffix() { -- cgit v1.2.3 From 5f87337d3ad21ac3f0f5a05244059eaa735236d7 Mon Sep 17 00:00:00 2001 From: Kristof Umann Date: Sat, 26 Jan 2019 21:22:58 +0000 Subject: Fix a lit test failure after D54438 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352290 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/clang-tidy/static-analyzer-config.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/clang-tidy/static-analyzer-config.cpp b/test/clang-tidy/static-analyzer-config.cpp index 9ca87cf8..d07c0c3a 100644 --- a/test/clang-tidy/static-analyzer-config.cpp +++ b/test/clang-tidy/static-analyzer-config.cpp @@ -1,5 +1,5 @@ // REQUIRES: static-analyzer -// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.Malloc:Optimistic", value: true}]}' -- | FileCheck %s +// RUN: clang-tidy %s -checks='-*,clang-analyzer-unix.Malloc' -config='{CheckOptions: [{ key: "clang-analyzer-unix.DynamicMemoryModeling:Optimistic", value: true}]}' -- | FileCheck %s typedef __typeof(sizeof(int)) size_t; void *malloc(size_t); void free(void *); -- cgit v1.2.3 From 2037b239d0ba5b045d4b78783f1dea0448cf73db Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Mon, 28 Jan 2019 14:01:55 +0000 Subject: [clangd] Suggest adding missing includes for incomplete type diagnostics. Summary: This enables clangd to intercept compiler diagnostics and attach fixes (e.g. by querying index). This patch adds missing includes for incomplete types e.g. member access into class with only forward declaration. This would allow adding missing includes for user-typed symbol names that are missing declarations (e.g. typos) in the future. Reviewers: sammccall Reviewed By: sammccall Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, mgrang, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D56903 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352361 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 1 + clangd/ClangdServer.cpp | 19 +- clangd/ClangdServer.h | 6 + clangd/ClangdUnit.cpp | 44 ++++- clangd/ClangdUnit.h | 5 +- clangd/CodeComplete.cpp | 64 +----- clangd/Compiler.h | 11 +- clangd/Diagnostics.cpp | 5 + clangd/Diagnostics.h | 6 + clangd/Headers.cpp | 35 ++++ clangd/Headers.h | 11 ++ clangd/IncludeFixer.cpp | 113 +++++++++++ clangd/IncludeFixer.h | 54 +++++ clangd/SourceCode.cpp | 13 ++ clangd/SourceCode.h | 7 + clangd/tool/ClangdMain.cpp | 7 + unittests/clangd/CMakeLists.txt | 1 + unittests/clangd/ClangdUnitTests.cpp | 257 ------------------------ unittests/clangd/CodeCompleteTests.cpp | 48 +---- unittests/clangd/DiagnosticsTests.cpp | 351 +++++++++++++++++++++++++++++++++ unittests/clangd/FileIndexTests.cpp | 2 +- unittests/clangd/TUSchedulerTests.cpp | 10 +- unittests/clangd/TestIndex.cpp | 54 +++++ unittests/clangd/TestIndex.h | 13 ++ unittests/clangd/TestTU.cpp | 7 +- unittests/clangd/TestTU.h | 2 + 26 files changed, 763 insertions(+), 383 deletions(-) create mode 100644 clangd/IncludeFixer.cpp create mode 100644 clangd/IncludeFixer.h create mode 100644 unittests/clangd/DiagnosticsTests.cpp diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index 92f62001..b58f8a83 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -40,6 +40,7 @@ add_clang_library(clangDaemon FuzzyMatch.cpp GlobalCompilationDatabase.cpp Headers.cpp + IncludeFixer.cpp JSONTransport.cpp Logger.cpp Protocol.cpp diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 5f494210..9b9eb10d 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -7,6 +7,7 @@ //===-------------------------------------------------------------------===// #include "ClangdServer.h" +#include "ClangdUnit.h" #include "CodeComplete.h" #include "FindSymbols.h" #include "Headers.h" @@ -106,6 +107,7 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, ? new FileIndex(Opts.HeavyweightDynamicSymbolIndex) : nullptr), ClangTidyOptProvider(Opts.ClangTidyOptProvider), + SuggestMissingIncludes(Opts.SuggestMissingIncludes), WorkspaceRoot(Opts.WorkspaceRoot), PCHs(std::make_shared()), // Pass a callback into `WorkScheduler` to extract symbols from a newly @@ -141,17 +143,22 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, WantDiagnostics WantDiags) { - tidy::ClangTidyOptions Options = tidy::ClangTidyOptions::getDefaults(); + ParseOptions Opts; + Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); if (ClangTidyOptProvider) - Options = ClangTidyOptProvider->getOptions(File); + Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File); + Opts.SuggestMissingIncludes = SuggestMissingIncludes; // FIXME: some build systems like Bazel will take time to preparing // environment to build the file, it would be nice if we could emit a // "PreparingBuild" status to inform users, it is non-trivial given the // current implementation. - WorkScheduler.update(File, ParseInputs{getCompileCommand(File), - FSProvider.getFileSystem(), - Contents.str(), Options}, - WantDiags); + ParseInputs Inputs; + Inputs.CompileCommand = getCompileCommand(File); + Inputs.FS = FSProvider.getFileSystem(); + Inputs.Contents = Contents; + Inputs.Opts = std::move(Opts); + Inputs.Index = Index; + WorkScheduler.update(File, Inputs, WantDiags); } void ClangdServer::removeDocument(PathRef File) { WorkScheduler.remove(File); } diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index dc9581b5..0be16026 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -114,6 +114,8 @@ public: /// Time to wait after a new file version before computing diagnostics. std::chrono::steady_clock::duration UpdateDebounce = std::chrono::milliseconds(500); + + bool SuggestMissingIncludes = false; }; // Sensible default options for use in tests. // Features like indexing must be enabled if desired. @@ -268,6 +270,10 @@ private: // The provider used to provide a clang-tidy option for a specific file. tidy::ClangTidyOptionsProvider *ClangTidyOptProvider = nullptr; + // If this is true, suggest include insertion fixes for diagnostic errors that + // can be caused by missing includes (e.g. member access in incomplete type). + bool SuggestMissingIncludes = false; + // GUARDED_BY(CachedCompletionFuzzyFindRequestMutex) llvm::StringMap> CachedCompletionFuzzyFindRequestByFile; diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 551d1798..5c798594 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -11,9 +11,12 @@ #include "../clang-tidy/ClangTidyModuleRegistry.h" #include "Compiler.h" #include "Diagnostics.h" +#include "Headers.h" +#include "IncludeFixer.h" #include "Logger.h" #include "SourceCode.h" #include "Trace.h" +#include "index/Index.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/LangOptions.h" #include "clang/Frontend/CompilerInstance.h" @@ -30,10 +33,12 @@ #include "clang/Serialization/ASTWriter.h" #include "clang/Tooling/CompilationDatabase.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/raw_ostream.h" #include +#include namespace clang { namespace clangd { @@ -231,7 +236,7 @@ ParsedAST::build(std::unique_ptr CI, std::unique_ptr Buffer, std::shared_ptr PCHs, llvm::IntrusiveRefCntPtr VFS, - const tidy::ClangTidyOptions &ClangTidyOpts) { + const SymbolIndex *Index, const ParseOptions &Opts) { assert(CI); // Command-line parsing sets DisableFree to true by default, but we don't want // to leak memory in clangd. @@ -240,9 +245,11 @@ ParsedAST::build(std::unique_ptr CI, Preamble ? &Preamble->Preamble : nullptr; StoreDiags ASTDiags; + std::string Content = Buffer->getBuffer(); + auto Clang = prepareCompilerInstance(std::move(CI), PreamblePCH, std::move(Buffer), - std::move(PCHs), std::move(VFS), ASTDiags); + std::move(PCHs), VFS, ASTDiags); if (!Clang) return None; @@ -266,12 +273,12 @@ ParsedAST::build(std::unique_ptr CI, { trace::Span Tracer("ClangTidyInit"); vlog("ClangTidy configuration for file {0}: {1}", MainInput.getFile(), - tidy::configurationAsText(ClangTidyOpts)); + tidy::configurationAsText(Opts.ClangTidyOpts)); tidy::ClangTidyCheckFactories CTFactories; for (const auto &E : tidy::ClangTidyModuleRegistry::entries()) E.instantiate()->addCheckFactories(CTFactories); CTContext.emplace(llvm::make_unique( - tidy::ClangTidyGlobalOptions(), ClangTidyOpts)); + tidy::ClangTidyGlobalOptions(), Opts.ClangTidyOpts)); CTContext->setDiagnosticsEngine(&Clang->getDiagnostics()); CTContext->setASTContext(&Clang->getASTContext()); CTContext->setCurrentFile(MainInput.getFile()); @@ -284,6 +291,27 @@ ParsedAST::build(std::unique_ptr CI, } } + // Add IncludeFixer which can recorver diagnostics caused by missing includes + // (e.g. incomplete type) and attach include insertion fixes to diagnostics. + llvm::Optional FixIncludes; + auto BuildDir = VFS->getCurrentWorkingDirectory(); + if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) { + auto Style = getFormatStyleForFile(MainInput.getFile(), Content, VFS.get()); + auto Inserter = std::make_shared( + MainInput.getFile(), Content, Style, BuildDir.get(), + Clang->getPreprocessor().getHeaderSearchInfo()); + if (Preamble) { + for (const auto &Inc : Preamble->Includes.MainFileIncludes) + Inserter->addExisting(Inc); + } + FixIncludes.emplace(MainInput.getFile(), Inserter, *Index, + /*IndexRequestLimit=*/5); + ASTDiags.contributeFixes([&FixIncludes](DiagnosticsEngine::Level DiagLevl, + const clang::Diagnostic &Info) { + return FixIncludes->fix(DiagLevl, Info); + }); + } + // Copy over the includes from the preamble, then combine with the // non-preamble includes below. auto Includes = Preamble ? Preamble->Includes : IncludeStructure{}; @@ -506,10 +534,10 @@ buildAST(PathRef FileName, std::unique_ptr Invocation, // dirs. } - return ParsedAST::build(llvm::make_unique(*Invocation), - Preamble, - llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents), - PCHs, std::move(VFS), Inputs.ClangTidyOpts); + return ParsedAST::build( + llvm::make_unique(*Invocation), Preamble, + llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents), PCHs, + std::move(VFS), Inputs.Index ? Inputs.Index : nullptr, Inputs.Opts); } SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index 23adb15c..f4883fd5 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -16,6 +16,7 @@ #include "Headers.h" #include "Path.h" #include "Protocol.h" +#include "index/Index.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Lex/Preprocessor.h" @@ -70,8 +71,8 @@ public: std::shared_ptr Preamble, std::unique_ptr Buffer, std::shared_ptr PCHs, - IntrusiveRefCntPtr VFS, - const tidy::ClangTidyOptions &ClangTidyOpts); + IntrusiveRefCntPtr VFS, const SymbolIndex *Index, + const ParseOptions &Opts); ParsedAST(ParsedAST &&Other); ParsedAST &operator=(ParsedAST &&Other); diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 66100d8c..83dcfb7a 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -177,28 +177,6 @@ std::string getOptionalParameters(const CodeCompletionString &CCS, return Result; } -/// Creates a `HeaderFile` from \p Header which can be either a URI or a literal -/// include. -static llvm::Expected toHeaderFile(llvm::StringRef Header, - llvm::StringRef HintPath) { - if (isLiteralInclude(Header)) - return HeaderFile{Header.str(), /*Verbatim=*/true}; - auto U = URI::parse(Header); - if (!U) - return U.takeError(); - - auto IncludePath = URI::includeSpelling(*U); - if (!IncludePath) - return IncludePath.takeError(); - if (!IncludePath->empty()) - return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true}; - - auto Resolved = URI::resolve(*U, HintPath); - if (!Resolved) - return Resolved.takeError(); - return HeaderFile{std::move(*Resolved), /*Verbatim=*/false}; -} - /// A code completion result, in clang-native form. /// It may be promoted to a CompletionItem if it's among the top-ranked results. struct CompletionCandidate { @@ -1019,11 +997,12 @@ bool semaCodeComplete(std::unique_ptr Consumer, llvm::IntrusiveRefCntPtr VFS = Input.VFS; if (Input.Preamble && Input.Preamble->StatCache) VFS = Input.Preamble->StatCache->getConsumingFS(std::move(VFS)); - ParseInputs PInput; - PInput.CompileCommand = Input.Command; - PInput.FS = VFS; - PInput.Contents = Input.Contents; - auto CI = buildCompilerInvocation(PInput); + ParseInputs ParseInput; + ParseInput.CompileCommand = Input.Command; + ParseInput.FS = VFS; + ParseInput.Contents = Input.Contents; + ParseInput.Opts = ParseOptions(); + auto CI = buildCompilerInvocation(ParseInput); if (!CI) { elog("Couldn't create CompilerInvocation"); return false; @@ -1143,24 +1122,6 @@ speculativeFuzzyFindRequestForCompletion(FuzzyFindRequest CachedReq, return CachedReq; } -// Returns the most popular include header for \p Sym. If two headers are -// equally popular, prefer the shorter one. Returns empty string if \p Sym has -// no include header. -llvm::SmallVector getRankedIncludes(const Symbol &Sym) { - auto Includes = Sym.IncludeHeaders; - // Sort in descending order by reference count and header length. - llvm::sort(Includes, [](const Symbol::IncludeHeaderWithReferences &LHS, - const Symbol::IncludeHeaderWithReferences &RHS) { - if (LHS.References == RHS.References) - return LHS.IncludeHeader.size() < RHS.IncludeHeader.size(); - return LHS.References > RHS.References; - }); - llvm::SmallVector Headers; - for (const auto &Include : Includes) - Headers.push_back(Include.IncludeHeader); - return Headers; -} - // Runs Sema-based (AST) and Index-based completion, returns merged results. // // There are a few tricky considerations: @@ -1241,19 +1202,12 @@ public: CodeCompleteResult Output; auto RecorderOwner = llvm::make_unique(Opts, [&]() { assert(Recorder && "Recorder is not set"); - auto Style = - format::getStyle(format::DefaultFormatStyle, SemaCCInput.FileName, - format::DefaultFallbackStyle, SemaCCInput.Contents, - SemaCCInput.VFS.get()); - if (!Style) { - log("getStyle() failed for file {0}: {1}. Fallback is LLVM style.", - SemaCCInput.FileName, Style.takeError()); - Style = format::getLLVMStyle(); - } + auto Style = getFormatStyleForFile( + SemaCCInput.FileName, SemaCCInput.Contents, SemaCCInput.VFS.get()); // If preprocessor was run, inclusions from preprocessor callback should // already be added to Includes. Inserter.emplace( - SemaCCInput.FileName, SemaCCInput.Contents, *Style, + SemaCCInput.FileName, SemaCCInput.Contents, Style, SemaCCInput.Command.Directory, Recorder->CCSema->getPreprocessor().getHeaderSearchInfo()); for (const auto &Inc : Includes.MainFileIncludes) diff --git a/clangd/Compiler.h b/clangd/Compiler.h index 13b499c8..9466d8e2 100644 --- a/clangd/Compiler.h +++ b/clangd/Compiler.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_COMPILER_H #include "../clang-tidy/ClangTidyOptions.h" +#include "index/Index.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PrecompiledPreamble.h" @@ -33,12 +34,20 @@ public: const clang::Diagnostic &Info) override; }; +// Options to run clang e.g. when parsing AST. +struct ParseOptions { + tidy::ClangTidyOptions ClangTidyOpts; + bool SuggestMissingIncludes = false; +}; + /// Information required to run clang, e.g. to parse AST or do code completion. struct ParseInputs { tooling::CompileCommand CompileCommand; IntrusiveRefCntPtr FS; std::string Contents; - tidy::ClangTidyOptions ClangTidyOpts; + // Used to recover from diagnostics (e.g. find missing includes for symbol). + const SymbolIndex *Index = nullptr; + ParseOptions Opts; }; /// Builds compiler invocation that could be used to build AST or preamble. diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index 3c226762..f370caa8 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -374,6 +374,11 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, if (!Info.getFixItHints().empty()) AddFix(true /* try to invent a message instead of repeating the diag */); + if (Fixer) { + auto ExtraFixes = Fixer(DiagLevel, Info); + LastDiag->Fixes.insert(LastDiag->Fixes.end(), ExtraFixes.begin(), + ExtraFixes.end()); + } } else { // Handle a note to an existing diagnostic. if (!LastDiag) { diff --git a/clangd/Diagnostics.h b/clangd/Diagnostics.h index 0866c3b5..9130ad56 100644 --- a/clangd/Diagnostics.h +++ b/clangd/Diagnostics.h @@ -99,9 +99,15 @@ public: void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) override; + using DiagFixer = std::function(DiagnosticsEngine::Level, + const clang::Diagnostic &)>; + /// If set, possibly adds fixes for diagnostics using \p Fixer. + void contributeFixes(DiagFixer Fixer) { this->Fixer = Fixer; } + private: void flushLastDiag(); + DiagFixer Fixer = nullptr; std::vector Output; llvm::Optional LangOpts; llvm::Optional LastDiag; diff --git a/clangd/Headers.cpp b/clangd/Headers.cpp index c4af420c..a5759a4e 100644 --- a/clangd/Headers.cpp +++ b/clangd/Headers.cpp @@ -73,6 +73,41 @@ bool HeaderFile::valid() const { (!Verbatim && llvm::sys::path::is_absolute(File)); } +llvm::Expected toHeaderFile(llvm::StringRef Header, + llvm::StringRef HintPath) { + if (isLiteralInclude(Header)) + return HeaderFile{Header.str(), /*Verbatim=*/true}; + auto U = URI::parse(Header); + if (!U) + return U.takeError(); + + auto IncludePath = URI::includeSpelling(*U); + if (!IncludePath) + return IncludePath.takeError(); + if (!IncludePath->empty()) + return HeaderFile{std::move(*IncludePath), /*Verbatim=*/true}; + + auto Resolved = URI::resolve(*U, HintPath); + if (!Resolved) + return Resolved.takeError(); + return HeaderFile{std::move(*Resolved), /*Verbatim=*/false}; +} + +llvm::SmallVector getRankedIncludes(const Symbol &Sym) { + auto Includes = Sym.IncludeHeaders; + // Sort in descending order by reference count and header length. + llvm::sort(Includes, [](const Symbol::IncludeHeaderWithReferences &LHS, + const Symbol::IncludeHeaderWithReferences &RHS) { + if (LHS.References == RHS.References) + return LHS.IncludeHeader.size() < RHS.IncludeHeader.size(); + return LHS.References > RHS.References; + }); + llvm::SmallVector Headers; + for (const auto &Include : Includes) + Headers.push_back(Include.IncludeHeader); + return Headers; +} + std::unique_ptr collectIncludeStructureCallback(const SourceManager &SM, IncludeStructure *Out) { diff --git a/clangd/Headers.h b/clangd/Headers.h index 5358c34e..e29f7f6b 100644 --- a/clangd/Headers.h +++ b/clangd/Headers.h @@ -12,10 +12,12 @@ #include "Path.h" #include "Protocol.h" #include "SourceCode.h" +#include "index/Index.h" #include "clang/Format/Format.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Tooling/Inclusions/HeaderIncludes.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" @@ -37,6 +39,15 @@ struct HeaderFile { bool valid() const; }; +/// Creates a `HeaderFile` from \p Header which can be either a URI or a literal +/// include. +llvm::Expected toHeaderFile(llvm::StringRef Header, + llvm::StringRef HintPath); + +// Returns include headers for \p Sym sorted by popularity. If two headers are +// equally popular, prefer the shorter one. +llvm::SmallVector getRankedIncludes(const Symbol &Sym); + // An #include directive that we found in the main file. struct Inclusion { Range R; // Inclusion range. diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp new file mode 100644 index 00000000..0f498884 --- /dev/null +++ b/clangd/IncludeFixer.cpp @@ -0,0 +1,113 @@ +//===--- IncludeFixer.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 "IncludeFixer.h" +#include "AST.h" +#include "Diagnostics.h" +#include "Logger.h" +#include "SourceCode.h" +#include "Trace.h" +#include "index/Index.h" +#include "clang/AST/Decl.h" +#include "clang/AST/Type.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" +#include "llvm/ADT/None.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/FormatVariadic.h" + +namespace clang { +namespace clangd { + +std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, + const clang::Diagnostic &Info) const { + if (IndexRequestCount >= IndexRequestLimit) + return {}; // Avoid querying index too many times in a single parse. + switch (Info.getID()) { + case diag::err_incomplete_type: + case diag::err_incomplete_member_access: + case diag::err_incomplete_base_class: + // Incomplete type diagnostics should have a QualType argument for the + // incomplete type. + for (unsigned Idx = 0; Idx < Info.getNumArgs(); ++Idx) { + if (Info.getArgKind(Idx) == DiagnosticsEngine::ak_qualtype) { + auto QT = QualType::getFromOpaquePtr((void *)Info.getRawArg(Idx)); + if (const Type *T = QT.getTypePtrOrNull()) + if (T->isIncompleteType()) + return fixIncompleteType(*T); + } + } + } + return {}; +} + +std::vector IncludeFixer::fixIncompleteType(const Type &T) const { + // Only handle incomplete TagDecl type. + const TagDecl *TD = T.getAsTagDecl(); + if (!TD) + return {}; + std::string TypeName = printQualifiedName(*TD); + trace::Span Tracer("Fix include for incomplete type"); + SPAN_ATTACH(Tracer, "type", TypeName); + vlog("Trying to fix include for incomplete type {0}", TypeName); + + auto ID = getSymbolID(TD); + if (!ID) + return {}; + ++IndexRequestCount; + // FIXME: consider batching the requests for all diagnostics. + // FIXME: consider caching the lookup results. + LookupRequest Req; + Req.IDs.insert(*ID); + llvm::Optional Matched; + Index.lookup(Req, [&](const Symbol &Sym) { + if (Matched) + return; + Matched = Sym; + }); + + if (!Matched || Matched->IncludeHeaders.empty() || !Matched->Definition || + Matched->CanonicalDeclaration.FileURI != Matched->Definition.FileURI) + return {}; + return fixesForSymbol(*Matched); +} + +std::vector IncludeFixer::fixesForSymbol(const Symbol &Sym) const { + auto Inserted = [&](llvm::StringRef Header) + -> llvm::Expected> { + auto ResolvedDeclaring = + toHeaderFile(Sym.CanonicalDeclaration.FileURI, File); + if (!ResolvedDeclaring) + return ResolvedDeclaring.takeError(); + auto ResolvedInserted = toHeaderFile(Header, File); + if (!ResolvedInserted) + return ResolvedInserted.takeError(); + return std::make_pair( + Inserter->calculateIncludePath(*ResolvedDeclaring, *ResolvedInserted), + Inserter->shouldInsertInclude(*ResolvedDeclaring, *ResolvedInserted)); + }; + + std::vector Fixes; + for (const auto &Inc : getRankedIncludes(Sym)) { + if (auto ToInclude = Inserted(Inc)) { + if (ToInclude->second) + if (auto Edit = Inserter->insert(ToInclude->first)) + Fixes.push_back( + Fix{llvm::formatv("Add include {0} for symbol {1}{2}", + ToInclude->first, Sym.Scope, Sym.Name), + {std::move(*Edit)}}); + } else { + vlog("Failed to calculate include insertion for {0} into {1}: {2}", File, + Inc, ToInclude.takeError()); + } + } + return Fixes; +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/IncludeFixer.h b/clangd/IncludeFixer.h new file mode 100644 index 00000000..740710cf --- /dev/null +++ b/clangd/IncludeFixer.h @@ -0,0 +1,54 @@ +//===--- IncludeFixer.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_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H + +#include "Diagnostics.h" +#include "Headers.h" +#include "index/Index.h" +#include "clang/AST/Type.h" +#include "clang/Basic/Diagnostic.h" +#include "llvm/ADT/StringRef.h" +#include + +namespace clang { +namespace clangd { + +/// Attempts to recover from error diagnostics by suggesting include insertion +/// fixes. For example, member access into incomplete type can be fixes by +/// include headers with the definition. +class IncludeFixer { +public: + IncludeFixer(llvm::StringRef File, std::shared_ptr Inserter, + const SymbolIndex &Index, unsigned IndexRequestLimit) + : File(File), Inserter(std::move(Inserter)), Index(Index), + IndexRequestLimit(IndexRequestLimit) {} + + /// Returns include insertions that can potentially recover the diagnostic. + std::vector fix(DiagnosticsEngine::Level DiagLevel, + const clang::Diagnostic &Info) const; + +private: + /// Attempts to recover diagnostic caused by an incomplete type \p T. + std::vector fixIncompleteType(const Type &T) const; + + /// Generates header insertion fixes for \p Sym. + std::vector fixesForSymbol(const Symbol &Sym) const; + + std::string File; + std::shared_ptr Inserter; + const SymbolIndex &Index; + const unsigned IndexRequestLimit; // Make at most 5 index requests. + mutable unsigned IndexRequestCount = 0; +}; + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INCLUDE_FIXER_H diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp index ede64353..1d8ceb2c 100644 --- a/clangd/SourceCode.cpp +++ b/clangd/SourceCode.cpp @@ -248,5 +248,18 @@ llvm::Optional digestFile(const SourceManager &SM, FileID FID) { return digest(Content); } +format::FormatStyle getFormatStyleForFile(llvm::StringRef File, + llvm::StringRef Content, + llvm::vfs::FileSystem *FS) { + auto Style = format::getStyle(format::DefaultFormatStyle, File, + format::DefaultFallbackStyle, Content, FS); + if (!Style) { + log("getStyle() failed for file {0}: {1}. Fallback is LLVM style.", File, + Style.takeError()); + Style = format::getLLVMStyle(); + } + return *Style; +} + } // namespace clangd } // namespace clang diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index 7c8499d8..2bbfd338 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -16,7 +16,9 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" +#include "clang/Format/Format.h" #include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/SHA1.h" namespace clang { @@ -91,6 +93,11 @@ llvm::Optional getCanonicalPath(const FileEntry *F, const SourceManager &SourceMgr); bool isRangeConsecutive(const Range &Left, const Range &Right); + +format::FormatStyle getFormatStyleForFile(llvm::StringRef File, + llvm::StringRef Content, + llvm::vfs::FileSystem *FS); + } // namespace clangd } // namespace clang #endif diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index c969a5b7..e83ac2f1 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -207,6 +207,12 @@ static llvm::cl::opt ClangTidyChecks( ".clang-tidy files)"), llvm::cl::init(""), llvm::cl::Hidden); +static llvm::cl::opt SuggestMissingIncludes( + "suggest-missing-includes", + llvm::cl::desc("Attempts to fix diagnostic errors caused by missing " + "includes using index."), + llvm::cl::init(false)); + namespace { /// \brief Supports a test URI scheme with relaxed constraints for lit tests. @@ -442,6 +448,7 @@ int main(int argc, char *argv[]) { /* Default */ tidy::ClangTidyOptions::getDefaults(), /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); Opts.ClangTidyOptProvider = &ClangTidyOptProvider; + Opts.SuggestMissingIncludes = SuggestMissingIncludes; ClangdLSPServer LSPServer( *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath, /*UseDirBasedCDB=*/CompileArgsFrom == FilesystemCompileArgs, Opts); diff --git a/unittests/clangd/CMakeLists.txt b/unittests/clangd/CMakeLists.txt index 73655fe8..13aca898 100644 --- a/unittests/clangd/CMakeLists.txt +++ b/unittests/clangd/CMakeLists.txt @@ -18,6 +18,7 @@ add_extra_unittest(ClangdTests CodeCompletionStringsTests.cpp ContextTests.cpp DexTests.cpp + DiagnosticsTests.cpp DraftStoreTests.cpp ExpectedTypeTest.cpp FileDistanceTests.cpp diff --git a/unittests/clangd/ClangdUnitTests.cpp b/unittests/clangd/ClangdUnitTests.cpp index b5e83a08..dd3fc6dd 100644 --- a/unittests/clangd/ClangdUnitTests.cpp +++ b/unittests/clangd/ClangdUnitTests.cpp @@ -19,263 +19,6 @@ namespace clangd { namespace { using testing::ElementsAre; -using testing::Field; -using testing::IsEmpty; -using testing::Pair; -using testing::UnorderedElementsAre; - -testing::Matcher WithFix(testing::Matcher FixMatcher) { - return Field(&Diag::Fixes, ElementsAre(FixMatcher)); -} - -testing::Matcher WithNote(testing::Matcher NoteMatcher) { - return Field(&Diag::Notes, ElementsAre(NoteMatcher)); -} - -MATCHER_P2(Diag, Range, Message, - "Diag at " + llvm::to_string(Range) + " = [" + Message + "]") { - return arg.Range == Range && arg.Message == Message; -} - -MATCHER_P3(Fix, Range, Replacement, Message, - "Fix " + llvm::to_string(Range) + " => " + - testing::PrintToString(Replacement) + " = [" + Message + "]") { - return arg.Message == Message && arg.Edits.size() == 1 && - arg.Edits[0].range == Range && arg.Edits[0].newText == Replacement; -} - -MATCHER_P(EqualToLSPDiag, LSPDiag, - "LSP diagnostic " + llvm::to_string(LSPDiag)) { - return std::tie(arg.range, arg.severity, arg.message) == - std::tie(LSPDiag.range, LSPDiag.severity, LSPDiag.message); -} - -MATCHER_P(EqualToFix, Fix, "LSP fix " + llvm::to_string(Fix)) { - if (arg.Message != Fix.Message) - return false; - if (arg.Edits.size() != Fix.Edits.size()) - return false; - for (std::size_t I = 0; I < arg.Edits.size(); ++I) { - if (arg.Edits[I].range != Fix.Edits[I].range || - arg.Edits[I].newText != Fix.Edits[I].newText) - return false; - } - return true; -} - -// Helper function to make tests shorter. -Position pos(int line, int character) { - Position Res; - Res.line = line; - Res.character = character; - return Res; -} - -TEST(DiagnosticsTest, DiagnosticRanges) { - // Check we report correct ranges, including various edge-cases. - Annotations Test(R"cpp( - namespace test{}; - void $decl[[foo]](); - int main() { - $typo[[go\ -o]](); - foo()$semicolon[[]]//with comments - $unk[[unknown]](); - double $type[[bar]] = "foo"; - struct Foo { int x; }; Foo a; - a.$nomember[[y]]; - test::$nomembernamespace[[test]]; - } - )cpp"); - EXPECT_THAT( - TestTU::withCode(Test.code()).build().getDiagnostics(), - ElementsAre( - // This range spans lines. - AllOf(Diag(Test.range("typo"), - "use of undeclared identifier 'goo'; did you mean 'foo'?"), - WithFix( - Fix(Test.range("typo"), "foo", "change 'go\\ o' to 'foo'")), - // This is a pretty normal range. - WithNote(Diag(Test.range("decl"), "'foo' declared here"))), - // This range is zero-width and insertion. Therefore make sure we are - // not expanding it into other tokens. Since we are not going to - // replace those. - AllOf(Diag(Test.range("semicolon"), "expected ';' after expression"), - WithFix(Fix(Test.range("semicolon"), ";", "insert ';'"))), - // This range isn't provided by clang, we expand to the token. - Diag(Test.range("unk"), "use of undeclared identifier 'unknown'"), - Diag(Test.range("type"), - "cannot initialize a variable of type 'double' with an lvalue " - "of type 'const char [4]'"), - Diag(Test.range("nomember"), "no member named 'y' in 'Foo'"), - Diag(Test.range("nomembernamespace"), - "no member named 'test' in namespace 'test'"))); -} - -TEST(DiagnosticsTest, FlagsMatter) { - Annotations Test("[[void]] main() {}"); - auto TU = TestTU::withCode(Test.code()); - EXPECT_THAT(TU.build().getDiagnostics(), - ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"), - WithFix(Fix(Test.range(), "int", - "change 'void' to 'int'"))))); - // Same code built as C gets different diagnostics. - TU.Filename = "Plain.c"; - EXPECT_THAT( - TU.build().getDiagnostics(), - ElementsAre(AllOf( - Diag(Test.range(), "return type of 'main' is not 'int'"), - WithFix(Fix(Test.range(), "int", "change return type to 'int'"))))); -} - -TEST(DiagnosticsTest, ClangTidy) { - Annotations Test(R"cpp( - #include $deprecated[["assert.h"]] - - #define $macrodef[[SQUARE]](X) (X)*(X) - int main() { - return $doubled[[sizeof]](sizeof(int)); - int y = 4; - return SQUARE($macroarg[[++]]y); - } - )cpp"); - auto TU = TestTU::withCode(Test.code()); - TU.HeaderFilename = "assert.h"; // Suppress "not found" error. - TU.ClangTidyChecks = - "-*, bugprone-sizeof-expression, bugprone-macro-repeated-side-effects, " - "modernize-deprecated-headers"; - EXPECT_THAT( - TU.build().getDiagnostics(), - UnorderedElementsAre( - AllOf(Diag(Test.range("deprecated"), - "inclusion of deprecated C++ header 'assert.h'; consider " - "using 'cassert' instead [modernize-deprecated-headers]"), - WithFix(Fix(Test.range("deprecated"), "", - "change '\"assert.h\"' to ''"))), - Diag(Test.range("doubled"), - "suspicious usage of 'sizeof(sizeof(...))' " - "[bugprone-sizeof-expression]"), - AllOf( - Diag(Test.range("macroarg"), - "side effects in the 1st macro argument 'X' are repeated in " - "macro expansion [bugprone-macro-repeated-side-effects]"), - WithNote(Diag(Test.range("macrodef"), - "macro 'SQUARE' defined here " - "[bugprone-macro-repeated-side-effects]"))), - Diag(Test.range("macroarg"), - "multiple unsequenced modifications to 'y'"))); -} - -TEST(DiagnosticsTest, Preprocessor) { - // This looks like a preamble, but there's an #else in the middle! - // Check that: - // - the #else doesn't generate diagnostics (we had this bug) - // - we get diagnostics from the taken branch - // - we get no diagnostics from the not taken branch - Annotations Test(R"cpp( - #ifndef FOO - #define FOO - int a = [[b]]; - #else - int x = y; - #endif - )cpp"); - EXPECT_THAT( - TestTU::withCode(Test.code()).build().getDiagnostics(), - ElementsAre(Diag(Test.range(), "use of undeclared identifier 'b'"))); -} - -TEST(DiagnosticsTest, InsideMacros) { - Annotations Test(R"cpp( - #define TEN 10 - #define RET(x) return x + 10 - - int* foo() { - RET($foo[[0]]); - } - int* bar() { - return $bar[[TEN]]; - } - )cpp"); - EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(), - ElementsAre(Diag(Test.range("foo"), - "cannot initialize return object of type " - "'int *' with an rvalue of type 'int'"), - Diag(Test.range("bar"), - "cannot initialize return object of type " - "'int *' with an rvalue of type 'int'"))); -} - -TEST(DiagnosticsTest, ToLSP) { - clangd::Diag D; - D.Message = "something terrible happened"; - D.Range = {pos(1, 2), pos(3, 4)}; - D.InsideMainFile = true; - D.Severity = DiagnosticsEngine::Error; - D.File = "foo/bar/main.cpp"; - - clangd::Note NoteInMain; - NoteInMain.Message = "declared somewhere in the main file"; - NoteInMain.Range = {pos(5, 6), pos(7, 8)}; - NoteInMain.Severity = DiagnosticsEngine::Remark; - NoteInMain.File = "../foo/bar/main.cpp"; - NoteInMain.InsideMainFile = true; - D.Notes.push_back(NoteInMain); - - clangd::Note NoteInHeader; - NoteInHeader.Message = "declared somewhere in the header file"; - NoteInHeader.Range = {pos(9, 10), pos(11, 12)}; - NoteInHeader.Severity = DiagnosticsEngine::Note; - NoteInHeader.File = "../foo/baz/header.h"; - NoteInHeader.InsideMainFile = false; - D.Notes.push_back(NoteInHeader); - - clangd::Fix F; - F.Message = "do something"; - D.Fixes.push_back(F); - - auto MatchingLSP = [](const DiagBase &D, StringRef Message) { - clangd::Diagnostic Res; - Res.range = D.Range; - Res.severity = getSeverity(D.Severity); - Res.message = Message; - return Res; - }; - - // Diagnostics should turn into these: - clangd::Diagnostic MainLSP = MatchingLSP(D, R"(Something terrible happened - -main.cpp:6:7: remark: declared somewhere in the main file - -../foo/baz/header.h:10:11: -note: declared somewhere in the header file)"); - - clangd::Diagnostic NoteInMainLSP = - MatchingLSP(NoteInMain, R"(Declared somewhere in the main file - -main.cpp:2:3: error: something terrible happened)"); - - // Transform dianostics and check the results. - std::vector>> LSPDiags; - toLSPDiags(D, -#ifdef _WIN32 - URIForFile::canonicalize("c:\\path\\to\\foo\\bar\\main.cpp", - /*TUPath=*/""), -#else - URIForFile::canonicalize("/path/to/foo/bar/main.cpp", /*TUPath=*/""), -#endif - ClangdDiagnosticOptions(), - [&](clangd::Diagnostic LSPDiag, ArrayRef Fixes) { - LSPDiags.push_back( - {std::move(LSPDiag), - std::vector(Fixes.begin(), Fixes.end())}); - }); - - EXPECT_THAT( - LSPDiags, - ElementsAre(Pair(EqualToLSPDiag(MainLSP), ElementsAre(EqualToFix(F))), - Pair(EqualToLSPDiag(NoteInMainLSP), IsEmpty()))); -} TEST(ClangdUnitTest, GetBeginningOfIdentifier) { std::string Preamble = R"cpp( diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp index 16d5eef0..ba539fc2 100644 --- a/unittests/clangd/CodeCompleteTests.cpp +++ b/unittests/clangd/CodeCompleteTests.cpp @@ -16,6 +16,7 @@ #include "SourceCode.h" #include "SyncAPI.h" #include "TestFS.h" +#include "TestIndex.h" #include "index/MemIndex.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/Support/Error.h" @@ -137,53 +138,6 @@ CodeCompleteResult completions(llvm::StringRef Text, FilePath); } -std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle, - llvm::StringRef Repl) { - std::string Result; - llvm::raw_string_ostream OS(Result); - std::pair Split; - for (Split = Haystack.split(Needle); !Split.second.empty(); - Split = Split.first.split(Needle)) - OS << Split.first << Repl; - Result += Split.first; - OS.flush(); - return Result; -} - -// Helpers to produce fake index symbols for memIndex() or completions(). -// USRFormat is a regex replacement string for the unqualified part of the USR. -Symbol sym(llvm::StringRef QName, index::SymbolKind Kind, - llvm::StringRef USRFormat) { - Symbol Sym; - std::string USR = "c:"; // We synthesize a few simple cases of USRs by hand! - size_t Pos = QName.rfind("::"); - if (Pos == llvm::StringRef::npos) { - Sym.Name = QName; - Sym.Scope = ""; - } else { - Sym.Name = QName.substr(Pos + 2); - Sym.Scope = QName.substr(0, Pos + 2); - USR += "@N@" + replace(QName.substr(0, Pos), "::", "@N@"); // ns:: -> @N@ns - } - USR += llvm::Regex("^.*$").sub(USRFormat, Sym.Name); // e.g. func -> @F@func# - Sym.ID = SymbolID(USR); - Sym.SymInfo.Kind = Kind; - Sym.Flags |= Symbol::IndexedForCodeCompletion; - Sym.Origin = SymbolOrigin::Static; - return Sym; -} -Symbol func(llvm::StringRef Name) { // Assumes the function has no args. - return sym(Name, index::SymbolKind::Function, "@F@\\0#"); // no args -} -Symbol cls(llvm::StringRef Name) { - return sym(Name, index::SymbolKind::Class, "@S@\\0"); -} -Symbol var(llvm::StringRef Name) { - return sym(Name, index::SymbolKind::Variable, "@\\0"); -} -Symbol ns(llvm::StringRef Name) { - return sym(Name, index::SymbolKind::Namespace, "@N@\\0"); -} Symbol withReferences(int N, Symbol S) { S.References = N; return S; diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp new file mode 100644 index 00000000..ea1952e9 --- /dev/null +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -0,0 +1,351 @@ +//===--- DiagnosticsTests.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 "Annotations.h" +#include "ClangdUnit.h" +#include "SourceCode.h" +#include "TestIndex.h" +#include "TestTU.h" +#include "index/MemIndex.h" +#include "llvm/Support/ScopedPrinter.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace { + +using testing::ElementsAre; +using testing::Field; +using testing::IsEmpty; +using testing::Pair; +using testing::UnorderedElementsAre; + +testing::Matcher WithFix(testing::Matcher FixMatcher) { + return Field(&Diag::Fixes, ElementsAre(FixMatcher)); +} + +testing::Matcher WithNote(testing::Matcher NoteMatcher) { + return Field(&Diag::Notes, ElementsAre(NoteMatcher)); +} + +MATCHER_P2(Diag, Range, Message, + "Diag at " + llvm::to_string(Range) + " = [" + Message + "]") { + return arg.Range == Range && arg.Message == Message; +} + +MATCHER_P3(Fix, Range, Replacement, Message, + "Fix " + llvm::to_string(Range) + " => " + + testing::PrintToString(Replacement) + " = [" + Message + "]") { + return arg.Message == Message && arg.Edits.size() == 1 && + arg.Edits[0].range == Range && arg.Edits[0].newText == Replacement; +} + +MATCHER_P(EqualToLSPDiag, LSPDiag, + "LSP diagnostic " + llvm::to_string(LSPDiag)) { + return std::tie(arg.range, arg.severity, arg.message) == + std::tie(LSPDiag.range, LSPDiag.severity, LSPDiag.message); +} + +MATCHER_P(EqualToFix, Fix, "LSP fix " + llvm::to_string(Fix)) { + if (arg.Message != Fix.Message) + return false; + if (arg.Edits.size() != Fix.Edits.size()) + return false; + for (std::size_t I = 0; I < arg.Edits.size(); ++I) { + if (arg.Edits[I].range != Fix.Edits[I].range || + arg.Edits[I].newText != Fix.Edits[I].newText) + return false; + } + return true; +} + + +// Helper function to make tests shorter. +Position pos(int line, int character) { + Position Res; + Res.line = line; + Res.character = character; + return Res; +} + +TEST(DiagnosticsTest, DiagnosticRanges) { + // Check we report correct ranges, including various edge-cases. + Annotations Test(R"cpp( + namespace test{}; + void $decl[[foo]](); + int main() { + $typo[[go\ +o]](); + foo()$semicolon[[]]//with comments + $unk[[unknown]](); + double $type[[bar]] = "foo"; + struct Foo { int x; }; Foo a; + a.$nomember[[y]]; + test::$nomembernamespace[[test]]; + } + )cpp"); + EXPECT_THAT( + TestTU::withCode(Test.code()).build().getDiagnostics(), + ElementsAre( + // This range spans lines. + AllOf(Diag(Test.range("typo"), + "use of undeclared identifier 'goo'; did you mean 'foo'?"), + WithFix( + Fix(Test.range("typo"), "foo", "change 'go\\ o' to 'foo'")), + // This is a pretty normal range. + WithNote(Diag(Test.range("decl"), "'foo' declared here"))), + // This range is zero-width and insertion. Therefore make sure we are + // not expanding it into other tokens. Since we are not going to + // replace those. + AllOf(Diag(Test.range("semicolon"), "expected ';' after expression"), + WithFix(Fix(Test.range("semicolon"), ";", "insert ';'"))), + // This range isn't provided by clang, we expand to the token. + Diag(Test.range("unk"), "use of undeclared identifier 'unknown'"), + Diag(Test.range("type"), + "cannot initialize a variable of type 'double' with an lvalue " + "of type 'const char [4]'"), + Diag(Test.range("nomember"), "no member named 'y' in 'Foo'"), + Diag(Test.range("nomembernamespace"), + "no member named 'test' in namespace 'test'"))); +} + +TEST(DiagnosticsTest, FlagsMatter) { + Annotations Test("[[void]] main() {}"); + auto TU = TestTU::withCode(Test.code()); + EXPECT_THAT(TU.build().getDiagnostics(), + ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"), + WithFix(Fix(Test.range(), "int", + "change 'void' to 'int'"))))); + // Same code built as C gets different diagnostics. + TU.Filename = "Plain.c"; + EXPECT_THAT( + TU.build().getDiagnostics(), + ElementsAre(AllOf( + Diag(Test.range(), "return type of 'main' is not 'int'"), + WithFix(Fix(Test.range(), "int", "change return type to 'int'"))))); +} + +TEST(DiagnosticsTest, ClangTidy) { + Annotations Test(R"cpp( + #include $deprecated[["assert.h"]] + + #define $macrodef[[SQUARE]](X) (X)*(X) + int main() { + return $doubled[[sizeof]](sizeof(int)); + int y = 4; + return SQUARE($macroarg[[++]]y); + } + )cpp"); + auto TU = TestTU::withCode(Test.code()); + TU.HeaderFilename = "assert.h"; // Suppress "not found" error. + TU.ClangTidyChecks = + "-*, bugprone-sizeof-expression, bugprone-macro-repeated-side-effects, " + "modernize-deprecated-headers"; + EXPECT_THAT( + TU.build().getDiagnostics(), + UnorderedElementsAre( + AllOf(Diag(Test.range("deprecated"), + "inclusion of deprecated C++ header 'assert.h'; consider " + "using 'cassert' instead [modernize-deprecated-headers]"), + WithFix(Fix(Test.range("deprecated"), "", + "change '\"assert.h\"' to ''"))), + Diag(Test.range("doubled"), + "suspicious usage of 'sizeof(sizeof(...))' " + "[bugprone-sizeof-expression]"), + AllOf( + Diag(Test.range("macroarg"), + "side effects in the 1st macro argument 'X' are repeated in " + "macro expansion [bugprone-macro-repeated-side-effects]"), + WithNote(Diag(Test.range("macrodef"), + "macro 'SQUARE' defined here " + "[bugprone-macro-repeated-side-effects]"))), + Diag(Test.range("macroarg"), + "multiple unsequenced modifications to 'y'"))); +} + +TEST(DiagnosticsTest, Preprocessor) { + // This looks like a preamble, but there's an #else in the middle! + // Check that: + // - the #else doesn't generate diagnostics (we had this bug) + // - we get diagnostics from the taken branch + // - we get no diagnostics from the not taken branch + Annotations Test(R"cpp( + #ifndef FOO + #define FOO + int a = [[b]]; + #else + int x = y; + #endif + )cpp"); + EXPECT_THAT( + TestTU::withCode(Test.code()).build().getDiagnostics(), + ElementsAre(Diag(Test.range(), "use of undeclared identifier 'b'"))); +} + +TEST(DiagnosticsTest, InsideMacros) { + Annotations Test(R"cpp( + #define TEN 10 + #define RET(x) return x + 10 + + int* foo() { + RET($foo[[0]]); + } + int* bar() { + return $bar[[TEN]]; + } + )cpp"); + EXPECT_THAT(TestTU::withCode(Test.code()).build().getDiagnostics(), + ElementsAre(Diag(Test.range("foo"), + "cannot initialize return object of type " + "'int *' with an rvalue of type 'int'"), + Diag(Test.range("bar"), + "cannot initialize return object of type " + "'int *' with an rvalue of type 'int'"))); +} + +TEST(DiagnosticsTest, ToLSP) { + clangd::Diag D; + D.Message = "something terrible happened"; + D.Range = {pos(1, 2), pos(3, 4)}; + D.InsideMainFile = true; + D.Severity = DiagnosticsEngine::Error; + D.File = "foo/bar/main.cpp"; + + clangd::Note NoteInMain; + NoteInMain.Message = "declared somewhere in the main file"; + NoteInMain.Range = {pos(5, 6), pos(7, 8)}; + NoteInMain.Severity = DiagnosticsEngine::Remark; + NoteInMain.File = "../foo/bar/main.cpp"; + NoteInMain.InsideMainFile = true; + D.Notes.push_back(NoteInMain); + + clangd::Note NoteInHeader; + NoteInHeader.Message = "declared somewhere in the header file"; + NoteInHeader.Range = {pos(9, 10), pos(11, 12)}; + NoteInHeader.Severity = DiagnosticsEngine::Note; + NoteInHeader.File = "../foo/baz/header.h"; + NoteInHeader.InsideMainFile = false; + D.Notes.push_back(NoteInHeader); + + clangd::Fix F; + F.Message = "do something"; + D.Fixes.push_back(F); + + auto MatchingLSP = [](const DiagBase &D, StringRef Message) { + clangd::Diagnostic Res; + Res.range = D.Range; + Res.severity = getSeverity(D.Severity); + Res.message = Message; + return Res; + }; + + // Diagnostics should turn into these: + clangd::Diagnostic MainLSP = MatchingLSP(D, R"(Something terrible happened + +main.cpp:6:7: remark: declared somewhere in the main file + +../foo/baz/header.h:10:11: +note: declared somewhere in the header file)"); + + clangd::Diagnostic NoteInMainLSP = + MatchingLSP(NoteInMain, R"(Declared somewhere in the main file + +main.cpp:2:3: error: something terrible happened)"); + + // Transform dianostics and check the results. + std::vector>> LSPDiags; + toLSPDiags(D, +#ifdef _WIN32 + URIForFile::canonicalize("c:\\path\\to\\foo\\bar\\main.cpp", + /*TUPath=*/""), +#else + URIForFile::canonicalize("/path/to/foo/bar/main.cpp", /*TUPath=*/""), +#endif + ClangdDiagnosticOptions(), + [&](clangd::Diagnostic LSPDiag, ArrayRef Fixes) { + LSPDiags.push_back( + {std::move(LSPDiag), + std::vector(Fixes.begin(), Fixes.end())}); + }); + + EXPECT_THAT( + LSPDiags, + ElementsAre(Pair(EqualToLSPDiag(MainLSP), ElementsAre(EqualToFix(F))), + Pair(EqualToLSPDiag(NoteInMainLSP), IsEmpty()))); +} + +TEST(IncludeFixerTest, IncompleteType) { + Annotations Test(R"cpp( +$insert[[]]namespace ns { + class X; +} +class Y : $base[[public ns::X]] {}; +int main() { + ns::X *x; + x$access[[->]]f(); +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + Symbol Sym = cls("ns::X"); + Sym.Flags |= Symbol::IndexedForCodeCompletion; + Sym.CanonicalDeclaration.FileURI = "unittest:///x.h"; + Sym.Definition.FileURI = "unittest:///x.h"; + Sym.IncludeHeaders.emplace_back("\"x.h\"", 1); + + SymbolSlab::Builder Slab; + Slab.insert(Sym); + auto Index = MemIndex::build(std::move(Slab).build(), RefSlab()); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT( + TU.build().getDiagnostics(), + UnorderedElementsAre( + AllOf(Diag(Test.range("base"), "base class has incomplete type"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))), + AllOf(Diag(Test.range("access"), + "member access into incomplete type 'ns::X'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))))); +} + +TEST(IncludeFixerTest, NoSuggestIncludeWhenNoDefinitionInHeader) { + Annotations Test(R"cpp( +$insert[[]]namespace ns { + class X; +} +class Y : $base[[public ns::X]] {}; +int main() { + ns::X *x; + x$access[[->]]f(); +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + Symbol Sym = cls("ns::X"); + Sym.Flags |= Symbol::IndexedForCodeCompletion; + Sym.CanonicalDeclaration.FileURI = "unittest:///x.h"; + Sym.Definition.FileURI = "unittest:///x.cc"; + Sym.IncludeHeaders.emplace_back("\"x.h\"", 1); + + SymbolSlab::Builder Slab; + Slab.insert(Sym); + auto Index = MemIndex::build(std::move(Slab).build(), RefSlab()); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT(TU.build().getDiagnostics(), + UnorderedElementsAre( + Diag(Test.range("base"), "base class has incomplete type"), + Diag(Test.range("access"), + "member access into incomplete type 'ns::X'"))); +} + +} // namespace +} // namespace clangd +} // namespace clang + diff --git a/unittests/clangd/FileIndexTests.cpp b/unittests/clangd/FileIndexTests.cpp index b0c21c0d..898dd64d 100644 --- a/unittests/clangd/FileIndexTests.cpp +++ b/unittests/clangd/FileIndexTests.cpp @@ -364,7 +364,7 @@ TEST(FileIndexTest, ReferencesInMainFileWithPreamble) { ParsedAST::build(createInvocationFromCommandLine(Cmd), PreambleData, llvm::MemoryBuffer::getMemBufferCopy(Main.code()), std::make_shared(), PI.FS, - tidy::ClangTidyOptions::getDefaults()); + /*Index=*/nullptr, ParseOptions()); ASSERT_TRUE(AST); FileIndex Index; Index.updateMain(MainFile, *AST); diff --git a/unittests/clangd/TUSchedulerTests.cpp b/unittests/clangd/TUSchedulerTests.cpp index 79ee779d..e5b42328 100644 --- a/unittests/clangd/TUSchedulerTests.cpp +++ b/unittests/clangd/TUSchedulerTests.cpp @@ -26,7 +26,6 @@ using ::testing::AllOf; using ::testing::AnyOf; using ::testing::Each; using ::testing::ElementsAre; -using ::testing::Pair; using ::testing::Pointee; using ::testing::UnorderedElementsAre; @@ -37,9 +36,12 @@ MATCHER_P2(TUState, State, ActionName, "") { class TUSchedulerTests : public ::testing::Test { protected: ParseInputs getInputs(PathRef File, std::string Contents) { - return ParseInputs{*CDB.getCompileCommand(File), - buildTestFS(Files, Timestamps), std::move(Contents), - tidy::ClangTidyOptions::getDefaults()}; + ParseInputs Inputs; + Inputs.CompileCommand = *CDB.getCompileCommand(File); + Inputs.FS = buildTestFS(Files, Timestamps); + Inputs.Contents = std::move(Contents); + Inputs.Opts = ParseOptions(); + return Inputs; } void updateWithCallback(TUScheduler &S, PathRef File, diff --git a/unittests/clangd/TestIndex.cpp b/unittests/clangd/TestIndex.cpp index a909193d..877bb75e 100644 --- a/unittests/clangd/TestIndex.cpp +++ b/unittests/clangd/TestIndex.cpp @@ -7,6 +7,8 @@ //===----------------------------------------------------------------------===// #include "TestIndex.h" +#include "clang/Index/IndexSymbol.h" +#include "llvm/Support/Regex.h" namespace clang { namespace clangd { @@ -25,6 +27,58 @@ Symbol symbol(llvm::StringRef QName) { return Sym; } +static std::string replace(llvm::StringRef Haystack, llvm::StringRef Needle, + llvm::StringRef Repl) { + std::string Result; + llvm::raw_string_ostream OS(Result); + std::pair Split; + for (Split = Haystack.split(Needle); !Split.second.empty(); + Split = Split.first.split(Needle)) + OS << Split.first << Repl; + Result += Split.first; + OS.flush(); + return Result; +} + +// Helpers to produce fake index symbols for memIndex() or completions(). +// USRFormat is a regex replacement string for the unqualified part of the USR. +Symbol sym(llvm::StringRef QName, index::SymbolKind Kind, + llvm::StringRef USRFormat) { + Symbol Sym; + std::string USR = "c:"; // We synthesize a few simple cases of USRs by hand! + size_t Pos = QName.rfind("::"); + if (Pos == llvm::StringRef::npos) { + Sym.Name = QName; + Sym.Scope = ""; + } else { + Sym.Name = QName.substr(Pos + 2); + Sym.Scope = QName.substr(0, Pos + 2); + USR += "@N@" + replace(QName.substr(0, Pos), "::", "@N@"); // ns:: -> @N@ns + } + USR += llvm::Regex("^.*$").sub(USRFormat, Sym.Name); // e.g. func -> @F@func# + Sym.ID = SymbolID(USR); + Sym.SymInfo.Kind = Kind; + Sym.Flags |= Symbol::IndexedForCodeCompletion; + Sym.Origin = SymbolOrigin::Static; + return Sym; +} + +Symbol func(llvm::StringRef Name) { // Assumes the function has no args. + return sym(Name, index::SymbolKind::Function, "@F@\\0#"); // no args +} + +Symbol cls(llvm::StringRef Name) { + return sym(Name, index::SymbolKind::Class, "@S@\\0"); +} + +Symbol var(llvm::StringRef Name) { + return sym(Name, index::SymbolKind::Variable, "@\\0"); +} + +Symbol ns(llvm::StringRef Name) { + return sym(Name, index::SymbolKind::Namespace, "@N@\\0"); +} + SymbolSlab generateSymbols(std::vector QualifiedNames) { SymbolSlab::Builder Slab; for (llvm::StringRef QName : QualifiedNames) diff --git a/unittests/clangd/TestIndex.h b/unittests/clangd/TestIndex.h index 6fef48d9..01de089e 100644 --- a/unittests/clangd/TestIndex.h +++ b/unittests/clangd/TestIndex.h @@ -18,6 +18,19 @@ namespace clangd { // Creates Symbol instance and sets SymbolID to given QualifiedName. Symbol symbol(llvm::StringRef QName); +// Helpers to produce fake index symbols with proper SymbolID. +// USRFormat is a regex replacement string for the unqualified part of the USR. +Symbol sym(llvm::StringRef QName, index::SymbolKind Kind, + llvm::StringRef USRFormat); +// Creats a function symbol assuming no function arg. +Symbol func(llvm::StringRef Name); +// Creates a class symbol. +Symbol cls(llvm::StringRef Name); +// Creates a variable symbol. +Symbol var(llvm::StringRef Name); +// Creates a namespace symbol. +Symbol ns(llvm::StringRef Name); + // Create a slab of symbols with the given qualified names as IDs and names. SymbolSlab generateSymbols(std::vector QualifiedNames); diff --git a/unittests/clangd/TestTU.cpp b/unittests/clangd/TestTU.cpp index 067d3f3f..8c61bb80 100644 --- a/unittests/clangd/TestTU.cpp +++ b/unittests/clangd/TestTU.cpp @@ -35,8 +35,11 @@ ParsedAST TestTU::build() const { Inputs.CompileCommand.Directory = testRoot(); Inputs.Contents = Code; Inputs.FS = buildTestFS({{FullFilename, Code}, {FullHeaderName, HeaderCode}}); - Inputs.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); - Inputs.ClangTidyOpts.Checks = ClangTidyChecks; + Inputs.Opts = ParseOptions(); + Inputs.Opts.ClangTidyOpts.Checks = ClangTidyChecks; + Inputs.Index = ExternalIndex; + if (Inputs.Index) + Inputs.Opts.SuggestMissingIncludes = true; auto PCHs = std::make_shared(); auto CI = buildCompilerInvocation(Inputs); assert(CI && "Failed to build compilation invocation."); diff --git a/unittests/clangd/TestTU.h b/unittests/clangd/TestTU.h index 7b84e4b5..beed124c 100644 --- a/unittests/clangd/TestTU.h +++ b/unittests/clangd/TestTU.h @@ -49,6 +49,8 @@ struct TestTU { std::vector ExtraArgs; llvm::Optional ClangTidyChecks; + // Index to use when building AST. + const SymbolIndex *ExternalIndex = nullptr; ParsedAST build() const; SymbolSlab headerSymbols() const; -- cgit v1.2.3 From c26f920a294c0b3819700fedde1243e0728af93d Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Mon, 28 Jan 2019 14:03:09 +0000 Subject: [clang-tidy] Add the abseil-duration-addition check Differential Revision: https://reviews.llvm.org/D57185 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352362 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/AbseilTidyModule.cpp | 3 + clang-tidy/abseil/CMakeLists.txt | 1 + clang-tidy/abseil/DurationAdditionCheck.cpp | 73 ++++++++++++++++ clang-tidy/abseil/DurationAdditionCheck.h | 35 ++++++++ clang-tidy/abseil/DurationRewriter.cpp | 35 ++++++++ clang-tidy/abseil/DurationRewriter.h | 15 ++++ docs/ReleaseNotes.rst | 7 +- .../clang-tidy/checks/abseil-duration-addition.rst | 21 +++++ docs/clang-tidy/checks/list.rst | 1 + test/clang-tidy/Inputs/absl/time/time.h | 13 +++ test/clang-tidy/abseil-duration-addition.cpp | 98 ++++++++++++++++++++++ 11 files changed, 301 insertions(+), 1 deletion(-) create mode 100644 clang-tidy/abseil/DurationAdditionCheck.cpp create mode 100644 clang-tidy/abseil/DurationAdditionCheck.h create mode 100644 docs/clang-tidy/checks/abseil-duration-addition.rst create mode 100644 test/clang-tidy/abseil-duration-addition.cpp diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp index 6c92166b..b05318bb 100644 --- a/clang-tidy/abseil/AbseilTidyModule.cpp +++ b/clang-tidy/abseil/AbseilTidyModule.cpp @@ -9,6 +9,7 @@ #include "../ClangTidy.h" #include "../ClangTidyModule.h" #include "../ClangTidyModuleRegistry.h" +#include "DurationAdditionCheck.h" #include "DurationComparisonCheck.h" #include "DurationConversionCastCheck.h" #include "DurationDivisionCheck.h" @@ -30,6 +31,8 @@ namespace abseil { class AbseilModule : public ClangTidyModule { public: void addCheckFactories(ClangTidyCheckFactories &CheckFactories) override { + CheckFactories.registerCheck( + "abseil-duration-addition"); CheckFactories.registerCheck( "abseil-duration-comparison"); CheckFactories.registerCheck( diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt index 6a37bab5..68247ba4 100644 --- a/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tidy/abseil/CMakeLists.txt @@ -2,6 +2,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyAbseilModule AbseilTidyModule.cpp + DurationAdditionCheck.cpp DurationComparisonCheck.cpp DurationConversionCastCheck.cpp DurationDivisionCheck.cpp diff --git a/clang-tidy/abseil/DurationAdditionCheck.cpp b/clang-tidy/abseil/DurationAdditionCheck.cpp new file mode 100644 index 00000000..1ff8452e --- /dev/null +++ b/clang-tidy/abseil/DurationAdditionCheck.cpp @@ -0,0 +1,73 @@ +//===--- DurationAdditionCheck.cpp - clang-tidy----------------------------===// +// +// 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 "DurationAdditionCheck.h" +#include "DurationRewriter.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace abseil { + +void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) { + Finder->addMatcher( + binaryOperator(hasOperatorName("+"), + hasEitherOperand(expr(ignoringParenImpCasts( + callExpr(callee(functionDecl(TimeFactoryFunction()) + .bind("function_decl"))) + .bind("call"))))) + .bind("binop"), + this); +} + +void DurationAdditionCheck::check(const MatchFinder::MatchResult &Result) { + const BinaryOperator *Binop = + Result.Nodes.getNodeAs("binop"); + const CallExpr *Call = Result.Nodes.getNodeAs("call"); + + // Don't try to replace things inside of macro definitions. + if (Binop->getExprLoc().isMacroID() || Binop->getExprLoc().isInvalid()) + return; + + llvm::Optional Scale = getScaleForTimeInverse( + Result.Nodes.getNodeAs("function_decl")->getName()); + if (!Scale) + return; + + llvm::StringRef TimeFactory = getTimeFactoryForScale(*Scale); + + FixItHint Hint; + if (Call == Binop->getLHS()->IgnoreParenImpCasts()) { + Hint = FixItHint::CreateReplacement( + Binop->getSourceRange(), + (llvm::Twine(TimeFactory) + "(" + + tooling::fixit::getText(*Call->getArg(0), *Result.Context) + " + " + + rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS()) + ")") + .str()); + } else { + assert(Call == Binop->getRHS()->IgnoreParenImpCast() && + "Call should be found on the RHS"); + Hint = FixItHint::CreateReplacement( + Binop->getSourceRange(), + (llvm::Twine(TimeFactory) + "(" + + rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS()) + + " + " + tooling::fixit::getText(*Call->getArg(0), *Result.Context) + + ")") + .str()); + } + + diag(Binop->getBeginLoc(), "perform addition in the duration domain") << Hint; +} + +} // namespace abseil +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/abseil/DurationAdditionCheck.h b/clang-tidy/abseil/DurationAdditionCheck.h new file mode 100644 index 00000000..64b4d89e --- /dev/null +++ b/clang-tidy/abseil/DurationAdditionCheck.h @@ -0,0 +1,35 @@ +//===--- DurationAdditionCheck.h - clang-tidy -------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace abseil { + +/// Checks for cases where addition should be performed in the +/// ``absl::Time`` domain. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-duration-addition.html +class DurationAdditionCheck : public ClangTidyCheck { +public: + DurationAdditionCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace abseil +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEADDITIONCHECK_H diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index 5a3f98bf..fb974f6c 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -103,6 +103,25 @@ llvm::StringRef getDurationFactoryForScale(DurationScale Scale) { llvm_unreachable("unknown scaling factor"); } +/// Returns the Time factory function name for a given `Scale`. +llvm::StringRef getTimeFactoryForScale(DurationScale scale) { + switch (scale) { + case DurationScale::Hours: + return "absl::ToUnixHours"; + case DurationScale::Minutes: + return "absl::ToUnixMinutes"; + case DurationScale::Seconds: + return "absl::ToUnixSeconds"; + case DurationScale::Milliseconds: + return "absl::ToUnixMillis"; + case DurationScale::Microseconds: + return "absl::ToUnixMicros"; + case DurationScale::Nanoseconds: + return "absl::ToUnixNanos"; + } + llvm_unreachable("unknown scaling factor"); +} + /// Returns `true` if `Node` is a value which evaluates to a literal `0`. bool IsLiteralZero(const MatchFinder::MatchResult &Result, const Expr &Node) { auto ZeroMatcher = @@ -197,6 +216,22 @@ llvm::Optional getScaleForDurationInverse(llvm::StringRef Name) { return ScaleIter->second; } +llvm::Optional getScaleForTimeInverse(llvm::StringRef Name) { + static const llvm::StringMap ScaleMap( + {{"ToUnixHours", DurationScale::Hours}, + {"ToUnixMinutes", DurationScale::Minutes}, + {"ToUnixSeconds", DurationScale::Seconds}, + {"ToUnixMillis", DurationScale::Milliseconds}, + {"ToUnixMicros", DurationScale::Microseconds}, + {"ToUnixNanos", DurationScale::Nanoseconds}}); + + auto ScaleIter = ScaleMap.find(std::string(Name)); + if (ScaleIter == ScaleMap.end()) + return llvm::None; + + return ScaleIter->second; +} + std::string rewriteExprFromNumberToDuration( const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, const Expr *Node) { diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index 1542b4c3..36dd5396 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -31,6 +31,9 @@ enum class DurationScale : std::uint8_t { /// constructing a `Duration` for that scale. llvm::StringRef getDurationFactoryForScale(DurationScale Scale); +/// Returns the Time factory function name for a given `Scale`. +llvm::StringRef getTimeFactoryForScale(DurationScale scale); + // Determine if `Node` represents a literal floating point or integral zero. bool IsLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result, const Expr &Node); @@ -62,6 +65,10 @@ simplifyDurationFactoryArg(const ast_matchers::MatchFinder::MatchResult &Result, /// return its `DurationScale`, or `None` if a match is not found. llvm::Optional getScaleForDurationInverse(llvm::StringRef Name); +/// Given the name of an inverse Time function (e.g., `ToUnixSeconds`), +/// return its `DurationScale`, or `None` if a match is not found. +llvm::Optional getScaleForTimeInverse(llvm::StringRef Name); + /// Given a `Scale` return the fully qualified inverse functions for it. /// The first returned value is the inverse for `double`, and the second /// returned value is the inverse for `int64`. @@ -99,6 +106,14 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, "::absl::Minutes", "::absl::Hours")); } +AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, + TimeFactoryFunction) { + using namespace clang::ast_matchers; + return functionDecl(hasAnyName( + "::absl::ToUnixHours", "::absl::ToUnixMinutes", "::absl::ToUnixSeconds", + "::absl::ToUnixMillis", "::absl::ToUnixMicros", "::absl::ToUnixNanos")); +} + } // namespace abseil } // namespace tidy } // namespace clang diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index ecac6607..1f6889ac 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -67,6 +67,12 @@ The improvements are... Improvements to clang-tidy -------------------------- +- New :doc:`abseil-duration-addition + ` check. + + Checks for cases where addition should be performed in the ``absl::Time`` + domain. + - New :doc:`abseil-duration-conversion-cast ` check. @@ -80,7 +86,6 @@ Improvements to clang-tidy Checks whether there are underscores in googletest test and test case names in test macros, which is prohibited by the Googletest FAQ. - Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/abseil-duration-addition.rst b/docs/clang-tidy/checks/abseil-duration-addition.rst new file mode 100644 index 00000000..2f3d805e --- /dev/null +++ b/docs/clang-tidy/checks/abseil-duration-addition.rst @@ -0,0 +1,21 @@ +.. title:: clang-tidy - abseil-duration-addition + +abseil-duration-addition +======================== + +Check for cases where addition should be performed in the ``absl::Time`` domain. +When adding two values, and one is known to be an ``absl::Time``, we can infer +that the other should be interpreted as an ``absl::Duration`` of a similar +scale, and make that inference explicit. + +Examples: + +.. code-block:: c++ + + // Original - Addition in the integer domain + int x; + absl::Time t; + int result = absl::ToUnixSeconds(t) + x; + + // Suggestion - Addition in the absl::Time domain + int result = absl::TounixSeconds(t + absl::Seconds(x)); diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 8397675e..487f6828 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -4,6 +4,7 @@ Clang-Tidy Checks ================= .. toctree:: + abseil-duration-addition abseil-duration-comparison abseil-duration-conversion-cast abseil-duration-division diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h index 9d136a5d..385eed82 100644 --- a/test/clang-tidy/Inputs/absl/time/time.h +++ b/test/clang-tidy/Inputs/absl/time/time.h @@ -55,6 +55,19 @@ int64_t ToInt64Milliseconds(Duration d); int64_t ToInt64Microseconds(Duration d); int64_t ToInt64Nanoseconds(Duration d); +int64_t ToUnixHours(Time t); +int64_t ToUnixMinutes(Time t); +int64_t ToUnixSeconds(Time t); +int64_t ToUnixMillis(Time t); +int64_t ToUnixMicros(Time t); +int64_t ToUnixNanos(Time t); +Time FromUnixHours(int64_t); +Time FromUnixMinutes(int64_t); +Time FromUnixSeconds(int64_t); +Time FromUnixMillis(int64_t); +Time FromUnixMicros(int64_t); +Time FromUnixNanos(int64_t); + // Relational Operators constexpr bool operator<(Duration lhs, Duration rhs); constexpr bool operator>(Duration lhs, Duration rhs); diff --git a/test/clang-tidy/abseil-duration-addition.cpp b/test/clang-tidy/abseil-duration-addition.cpp new file mode 100644 index 00000000..33cfc58f --- /dev/null +++ b/test/clang-tidy/abseil-duration-addition.cpp @@ -0,0 +1,98 @@ +// RUN: %check_clang_tidy %s abseil-duration-addition %t -- -- -I%S/Inputs + +#include "absl/time/time.h" + +void f() { + absl::Time t; + int i; + + i = absl::ToUnixHours(t) + 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixHours(t + absl::Hours(5)) + i = absl::ToUnixMinutes(t) + 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMinutes(t + absl::Minutes(5)) + i = absl::ToUnixSeconds(t) + 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5)) + i = absl::ToUnixMillis(t) + 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMillis(t + absl::Milliseconds(5)) + i = absl::ToUnixMicros(t) + 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMicros(t + absl::Microseconds(5)) + i = absl::ToUnixNanos(t) + 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(5)) + + i = 3 + absl::ToUnixHours(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t) + i = 3 + absl::ToUnixMinutes(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMinutes(absl::Minutes(3) + t) + i = 3 + absl::ToUnixSeconds(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixSeconds(absl::Seconds(3) + t) + i = 3 + absl::ToUnixMillis(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMillis(absl::Milliseconds(3) + t) + i = 3 + absl::ToUnixMicros(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMicros(absl::Microseconds(3) + t) + i = 3 + absl::ToUnixNanos(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixNanos(absl::Nanoseconds(3) + t) + + // Undoing inverse conversions + i = absl::ToUnixMicros(t) + absl::ToInt64Microseconds(absl::Seconds(1)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixMicros(t + absl::Seconds(1)) + + // Parens + i = 3 + (absl::ToUnixHours(t)); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixHours(absl::Hours(3) + t) + + // Float folding + i = absl::ToUnixSeconds(t) + 5.0; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(5)) + + // We can rewrite the argument of the duration conversion +#define THIRTY absl::FromUnixSeconds(30) + i = absl::ToUnixSeconds(THIRTY) + 1; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixSeconds(THIRTY + absl::Seconds(1)) +#undef THIRTY + + // Some other contexts + if (absl::ToUnixSeconds(t) + 1.0 > 10) {} + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixSeconds(t + absl::Seconds(1)) + + // These should not match + i = 5 + 6; + i = absl::ToUnixSeconds(t) - 1.0; + i = absl::ToUnixSeconds(t) * 1.0; + i = absl::ToUnixSeconds(t) / 1.0; + i += absl::ToInt64Microseconds(absl::Seconds(1)); + +#define PLUS_FIVE(z) absl::ToUnixSeconds(z) + 5 + i = PLUS_FIVE(t); +#undef PLUS_FIVE +} + +// Within a templated function +template +void foo(absl::Time t) { + int i = absl::ToUnixNanos(t) + T{}; + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform addition in the duration domain [abseil-duration-addition] + // CHECK-FIXES: absl::ToUnixNanos(t + absl::Nanoseconds(T{})) +} + +void g() { + absl::Time t; + foo(t); + foo(t); +} -- cgit v1.2.3 From 3c71df1a357ee1d5c296e228aefefcc2ecb7f299 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 28 Jan 2019 14:07:45 +0000 Subject: [clang-tidy] Fix a build error. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352364 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/DurationAdditionCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tidy/abseil/DurationAdditionCheck.cpp b/clang-tidy/abseil/DurationAdditionCheck.cpp index 1ff8452e..51b9f577 100644 --- a/clang-tidy/abseil/DurationAdditionCheck.cpp +++ b/clang-tidy/abseil/DurationAdditionCheck.cpp @@ -54,7 +54,7 @@ void DurationAdditionCheck::check(const MatchFinder::MatchResult &Result) { rewriteExprFromNumberToDuration(Result, *Scale, Binop->getRHS()) + ")") .str()); } else { - assert(Call == Binop->getRHS()->IgnoreParenImpCast() && + assert(Call == Binop->getRHS()->IgnoreParenImpCasts() && "Call should be found on the RHS"); Hint = FixItHint::CreateReplacement( Binop->getSourceRange(), -- cgit v1.2.3 From b42530a260d1e87b98044cdf7be826156bf7314d Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 28 Jan 2019 14:11:49 +0000 Subject: [clangd] Index main-file macros (bug 39761) Patch by Nathan Ridge! Differential Revision: https://reviews.llvm.org/D55739 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352367 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/SymbolCollector.cpp | 17 +++++++++++++--- unittests/clangd/FindSymbolsTests.cpp | 15 +++++++++------ unittests/clangd/SymbolCollectorTests.cpp | 32 ++++++++++++++++++------------- 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index 83087632..cbbbd505 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -379,13 +379,21 @@ bool SymbolCollector::handleMacroOccurence(const IdentifierInfo *Name, const auto &SM = PP->getSourceManager(); auto DefLoc = MI->getDefinitionLoc(); - if (SM.isInMainFile(SM.getExpansionLoc(DefLoc))) - return true; + // Header guards are not interesting in index. Builtin macros don't have // useful locations and are not needed for code completions. if (MI->isUsedForHeaderGuard() || MI->isBuiltinMacro()) return true; + // Skip main-file symbols if we are not collecting them. + bool IsMainFileSymbol = SM.isInMainFile(SM.getExpansionLoc(DefLoc)); + if (IsMainFileSymbol && !Opts.CollectMainFileSymbols) + return false; + + // Also avoid storing predefined macros like __DBL_MIN__. + if (SM.isWrittenInBuiltinFile(DefLoc)) + return true; + // Mark the macro as referenced if this is a reference coming from the main // file. The macro may not be an interesting symbol, but it's cheaper to check // at the end. @@ -410,7 +418,10 @@ bool SymbolCollector::handleMacroOccurence(const IdentifierInfo *Name, Symbol S; S.ID = std::move(*ID); S.Name = Name->getName(); - S.Flags |= Symbol::IndexedForCodeCompletion; + if (!IsMainFileSymbol) { + S.Flags |= Symbol::IndexedForCodeCompletion; + S.Flags |= Symbol::VisibleOutsideFile; + } S.SymInfo = index::getSymbolInfoForMacro(*MI); std::string FileURI; // FIXME: use the result to filter out symbols. diff --git a/unittests/clangd/FindSymbolsTests.cpp b/unittests/clangd/FindSymbolsTests.cpp index 3fb83237..78447f35 100644 --- a/unittests/clangd/FindSymbolsTests.cpp +++ b/unittests/clangd/FindSymbolsTests.cpp @@ -87,13 +87,16 @@ protected: } // namespace -TEST_F(WorkspaceSymbolsTest, NoMacro) { +TEST_F(WorkspaceSymbolsTest, Macros) { addFile("foo.cpp", R"cpp( - #define MACRO X - )cpp"); - - // Macros are not in the index. - EXPECT_THAT(getSymbols("macro"), IsEmpty()); + #define MACRO X + )cpp"); + + // LSP's SymbolKind doesn't have a "Macro" kind, and + // indexSymbolKindToSymbolKind() currently maps macros + // to SymbolKind::String. + EXPECT_THAT(getSymbols("macro"), + ElementsAre(AllOf(QName("MACRO"), WithKind(SymbolKind::String)))); } TEST_F(WorkspaceSymbolsTest, NoLocals) { diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index ff38952f..258cfa9d 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -1069,21 +1069,27 @@ TEST_F(SymbolCollectorTest, CollectMacros) { MAC(p); )"); - const std::string Main = R"( - #define MAIN 1 // not indexed - USED(t); - )"; + + Annotations Main(R"( + #define $main[[MAIN]] 1 + USED(t); + )"); CollectorOpts.CountReferences = true; CollectorOpts.CollectMacro = true; - runSymbolCollector(Header.code(), Main); - EXPECT_THAT(Symbols, - UnorderedElementsAre(QName("p"), QName("t"), - AllOf(QName("X"), DeclURI(TestHeaderURI), - IncludeHeader(TestHeaderURI)), - AllOf(Labeled("MAC(x)"), RefCount(0), - DeclRange(Header.range("mac"))), - AllOf(Labeled("USED(y)"), RefCount(1), - DeclRange(Header.range("used"))))); + runSymbolCollector(Header.code(), Main.code()); + EXPECT_THAT( + Symbols, + UnorderedElementsAre( + QName("p"), QName("t"), + AllOf(QName("X"), DeclURI(TestHeaderURI), + IncludeHeader(TestHeaderURI)), + AllOf(Labeled("MAC(x)"), RefCount(0), + + DeclRange(Header.range("mac")), VisibleOutsideFile()), + AllOf(Labeled("USED(y)"), RefCount(1), + DeclRange(Header.range("used")), VisibleOutsideFile()), + AllOf(Labeled("MAIN"), RefCount(0), DeclRange(Main.range("main")), + Not(VisibleOutsideFile())))); } TEST_F(SymbolCollectorTest, DeprecatedSymbols) { -- cgit v1.2.3 From eed2cd31996b98d69a90a65dfb35e66dcb7b224c Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 29 Jan 2019 11:19:15 +0000 Subject: [clangd] Make USRs for macros to be position independent Summary: USRs for macros were not cannonical due to usage of cursor location instead of definition location. Reviewers: jkorous Subscribers: ilya-biryukov, ioeric, MaskRay, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D57228 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352481 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 3 ++- unittests/clangd/SymbolInfoTests.cpp | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 2f0990a9..9138cf7e 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -794,7 +794,8 @@ std::vector getSymbolInfo(ParsedAST &AST, Position Pos) { SymbolDetails NewMacro; NewMacro.name = Macro.Name; llvm::SmallString<32> USR; - if (!index::generateUSRForMacro(NewMacro.name, Loc, SM, USR)) { + if (!index::generateUSRForMacro(NewMacro.name, + Macro.Info->getDefinitionLoc(), SM, USR)) { NewMacro.USR = USR.str(); NewMacro.ID = SymbolID(NewMacro.USR); } diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp index 369c2e75..69a27f23 100644 --- a/unittests/clangd/SymbolInfoTests.cpp +++ b/unittests/clangd/SymbolInfoTests.cpp @@ -149,7 +149,13 @@ TEST(SymbolInfoTests, All) { #define MACRO 5\nint i = MAC^RO; )cpp", {CreateExpectedSymbolDetails("MACRO", "", - "c:TestTU.cpp@55@macro@MACRO")}}, + "c:TestTU.cpp@38@macro@MACRO")}}, + { + R"cpp( // Macro reference + #define MACRO 5\nint i = MACRO^; + )cpp", + {CreateExpectedSymbolDetails("MACRO", "", + "c:TestTU.cpp@38@macro@MACRO")}}, { R"cpp( // Multiple symbols returned - using overloaded function name void foo() {} -- cgit v1.2.3 From 835e32ef4e6e916f86ec2ff786369c0b9f68a4c4 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 29 Jan 2019 12:32:32 +0000 Subject: [clangd] dlog clang-tidy configuration vlog seems to be too spammy in unittests. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352485 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 5c798594..6b5e1764 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -272,7 +272,7 @@ ParsedAST::build(std::unique_ptr CI, llvm::Optional CTContext; { trace::Span Tracer("ClangTidyInit"); - vlog("ClangTidy configuration for file {0}: {1}", MainInput.getFile(), + dlog("ClangTidy configuration for file {0}: {1}", MainInput.getFile(), tidy::configurationAsText(Opts.ClangTidyOpts)); tidy::ClangTidyCheckFactories CTFactories; for (const auto &E : tidy::ClangTidyModuleRegistry::entries()) -- cgit v1.2.3 From 38b66ffe45519080621e44d11f07dfbef3b58bda Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 29 Jan 2019 14:17:36 +0000 Subject: [clangd] Interfaces for writing code tweaks Summary: The code tweaks are an implementation of mini-refactorings exposed via the LSP code actions. They run in two stages: - Stage 1. Decides whether the action is available to the user and collects all the information required to finish the action. Should be cheap, since this will run over all the actions known to clangd on each textDocument/codeAction request from the client. - Stage 2. Uses information from stage 1 to produce the actual edits that the code action should perform. This stage can be expensive and will only run if the user chooses to perform the specified action in the UI. One unfortunate consequence of this change is increased latency of processing the textDocument/codeAction requests, which now wait for an AST. However, we cannot avoid this with what we have available in the LSP today. Reviewers: kadircet, ioeric, hokein, sammccall Reviewed By: sammccall Subscribers: mgrang, mgorny, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D56267 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352494 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 3 + clangd/ClangdLSPServer.cpp | 109 +++++++++++++++++++++++++++++----- clangd/ClangdServer.cpp | 54 +++++++++++++++++ clangd/ClangdServer.h | 14 +++++ clangd/Protocol.cpp | 19 ++++++ clangd/Protocol.h | 19 ++++++ clangd/SourceCode.cpp | 10 ++++ clangd/SourceCode.h | 5 ++ clangd/refactor/Tweak.cpp | 74 +++++++++++++++++++++++ clangd/refactor/Tweak.h | 98 ++++++++++++++++++++++++++++++ clangd/refactor/tweaks/CMakeLists.txt | 13 ++++ clangd/refactor/tweaks/Dummy.cpp | 9 +++ clangd/tool/CMakeLists.txt | 1 + test/clangd/fixits-command.test | 4 +- test/clangd/initialize-params.test | 3 +- 15 files changed, 416 insertions(+), 19 deletions(-) create mode 100644 clangd/refactor/Tweak.cpp create mode 100644 clangd/refactor/Tweak.h create mode 100644 clangd/refactor/tweaks/CMakeLists.txt create mode 100644 clangd/refactor/tweaks/Dummy.cpp diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index b58f8a83..24954f04 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -71,6 +71,8 @@ add_clang_library(clangDaemon index/dex/PostingList.cpp index/dex/Trigram.cpp + refactor/Tweak.cpp + LINK_LIBS clangAST clangASTMatchers @@ -108,6 +110,7 @@ add_clang_library(clangDaemon ${CLANGD_ATOMIC_LIB} ) +add_subdirectory(refactor/tweaks) if( LLVM_LIB_FUZZING_ENGINE OR LLVM_USE_SANITIZE_COVERAGE ) add_subdirectory(fuzzer) endif() diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index e90ee916..cb8bf5a6 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -8,11 +8,14 @@ #include "ClangdLSPServer.h" #include "Diagnostics.h" +#include "Protocol.h" #include "SourceCode.h" #include "Trace.h" #include "URI.h" +#include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/Path.h" #include "llvm/Support/ScopedPrinter.h" @@ -30,6 +33,28 @@ public: } }; +/// Transforms a tweak into a code action that would apply it if executed. +/// EXPECTS: T.prepare() was called and returned true. +CodeAction toCodeAction(const ClangdServer::TweakRef &T, const URIForFile &File, + Range Selection) { + CodeAction CA; + CA.title = T.Title; + CA.kind = CodeAction::REFACTOR_KIND; + // This tweak may have an expensive second stage, we only run it if the user + // actually chooses it in the UI. We reply with a command that would run the + // corresponding tweak. + // FIXME: for some tweaks, computing the edits is cheap and we could send them + // directly. + CA.command.emplace(); + CA.command->title = T.Title; + CA.command->command = Command::CLANGD_APPLY_TWEAK; + CA.command->tweakArgs.emplace(); + CA.command->tweakArgs->file = File; + CA.command->tweakArgs->tweakID = T.ID; + CA.command->tweakArgs->selection = Selection; + return CA; +}; + void adjustSymbolKinds(llvm::MutableArrayRef Syms, SymbolKindBitset Kinds) { for (auto &S : Syms) { @@ -338,7 +363,9 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, {"referencesProvider", true}, {"executeCommandProvider", llvm::json::Object{ - {"commands", {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND}}, + {"commands", + {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND, + ExecuteCommandParams::CLANGD_APPLY_TWEAK}}, }}, }}}}); } @@ -400,7 +427,7 @@ void ClangdLSPServer::onFileEvent(const DidChangeWatchedFilesParams &Params) { void ClangdLSPServer::onCommand(const ExecuteCommandParams &Params, Callback Reply) { - auto ApplyEdit = [&](WorkspaceEdit WE) { + auto ApplyEdit = [this](WorkspaceEdit WE) { ApplyWorkspaceEditParams Edit; Edit.edit = std::move(WE); // Ideally, we would wait for the response and if there is no error, we @@ -420,6 +447,31 @@ void ClangdLSPServer::onCommand(const ExecuteCommandParams &Params, Reply("Fix applied."); ApplyEdit(*Params.workspaceEdit); + } else if (Params.command == ExecuteCommandParams::CLANGD_APPLY_TWEAK && + Params.tweakArgs) { + auto Code = DraftMgr.getDraft(Params.tweakArgs->file.file()); + if (!Code) + return Reply(llvm::createStringError( + llvm::inconvertibleErrorCode(), + "trying to apply a code action for a non-added file")); + + auto Action = [ApplyEdit](decltype(Reply) Reply, URIForFile File, + std::string Code, + llvm::Expected R) { + if (!R) + return Reply(R.takeError()); + + WorkspaceEdit WE; + WE.changes.emplace(); + (*WE.changes)[File.uri()] = replacementsToEdits(Code, *R); + + Reply("Fix applied."); + ApplyEdit(std::move(WE)); + }; + Server->applyTweak(Params.tweakArgs->file.file(), + Params.tweakArgs->selection, Params.tweakArgs->tweakID, + Bind(Action, std::move(Reply), Params.tweakArgs->file, + std::move(*Code))); } else { // We should not get here because ExecuteCommandParams would not have // parsed in the first place and this handler should not be called. But if @@ -601,28 +653,53 @@ static llvm::Optional asCommand(const CodeAction &Action) { void ClangdLSPServer::onCodeAction(const CodeActionParams &Params, Callback Reply) { - auto Code = DraftMgr.getDraft(Params.textDocument.uri.file()); + URIForFile File = Params.textDocument.uri; + auto Code = DraftMgr.getDraft(File.file()); if (!Code) return Reply(llvm::make_error( "onCodeAction called for non-added file", ErrorCode::InvalidParams)); // We provide a code action for Fixes on the specified diagnostics. - std::vector Actions; + std::vector FixIts; for (const Diagnostic &D : Params.context.diagnostics) { - for (auto &F : getFixes(Params.textDocument.uri.file(), D)) { - Actions.push_back(toCodeAction(F, Params.textDocument.uri)); - Actions.back().diagnostics = {D}; + for (auto &F : getFixes(File.file(), D)) { + FixIts.push_back(toCodeAction(F, Params.textDocument.uri)); + FixIts.back().diagnostics = {D}; } } - if (SupportsCodeAction) - Reply(llvm::json::Array(Actions)); - else { - std::vector Commands; - for (const auto &Action : Actions) - if (auto Command = asCommand(Action)) - Commands.push_back(std::move(*Command)); - Reply(llvm::json::Array(Commands)); - } + // Now enumerate the semantic code actions. + auto ConsumeActions = + [this](decltype(Reply) Reply, URIForFile File, std::string Code, + Range Selection, std::vector FixIts, + llvm::Expected> Tweaks) { + if (!Tweaks) { + auto Err = Tweaks.takeError(); + if (Err.isA()) + return Reply(std::move(Err)); // do no logging, this is expected. + elog("error while getting semantic code actions: {0}", + std::move(Err)); + return Reply(llvm::json::Array(FixIts)); + } + + std::vector Actions = std::move(FixIts); + Actions.reserve(Actions.size() + Tweaks->size()); + for (const auto &T : *Tweaks) + Actions.push_back(toCodeAction(T, File, Selection)); + + if (SupportsCodeAction) + return Reply(llvm::json::Array(Actions)); + std::vector Commands; + for (const auto &Action : Actions) { + if (auto Command = asCommand(Action)) + Commands.push_back(std::move(*Command)); + } + return Reply(llvm::json::Array(Commands)); + }; + + Server->enumerateTweaks(File.file(), Params.range, + Bind(ConsumeActions, std::move(Reply), + std::move(File), std::move(*Code), Params.range, + std::move(FixIts))); } void ClangdLSPServer::onCompletion(const CompletionParams &Params, diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 9b9eb10d..7221b382 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -16,11 +16,13 @@ #include "XRefs.h" #include "index/FileIndex.h" #include "index/Merge.h" +#include "refactor/Tweak.h" #include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Lex/Preprocessor.h" #include "clang/Tooling/CompilationDatabase.h" +#include "clang/Tooling/Core/Replacement.h" #include "clang/Tooling/Refactoring/RefactoringResultConsumer.h" #include "clang/Tooling/Refactoring/Rename/RenamingAction.h" #include "llvm/ADT/ArrayRef.h" @@ -28,10 +30,12 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include +#include #include namespace clang { @@ -325,6 +329,56 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName, "Rename", File, Bind(Action, File.str(), NewName.str(), std::move(CB))); } +void ClangdServer::enumerateTweaks(PathRef File, Range Sel, + Callback> CB) { + auto Action = [Sel](decltype(CB) CB, std::string File, + Expected InpAST) { + if (!InpAST) + return CB(InpAST.takeError()); + + auto &AST = InpAST->AST; + auto CursorLoc = sourceLocationInMainFile( + AST.getASTContext().getSourceManager(), Sel.start); + if (!CursorLoc) + return CB(CursorLoc.takeError()); + Tweak::Selection Inputs = {InpAST->Inputs.Contents, InpAST->AST, + *CursorLoc}; + + std::vector Res; + for (auto &T : prepareTweaks(Inputs)) + Res.push_back({T->id(), T->title()}); + CB(std::move(Res)); + }; + + WorkScheduler.runWithAST("EnumerateTweaks", File, + Bind(Action, std::move(CB), File.str())); +} + +void ClangdServer::applyTweak(PathRef File, Range Sel, TweakID ID, + Callback CB) { + auto Action = [ID, Sel](decltype(CB) CB, std::string File, + Expected InpAST) { + if (!InpAST) + return CB(InpAST.takeError()); + + auto &AST = InpAST->AST; + auto CursorLoc = sourceLocationInMainFile( + AST.getASTContext().getSourceManager(), Sel.start); + if (!CursorLoc) + return CB(CursorLoc.takeError()); + Tweak::Selection Inputs = {InpAST->Inputs.Contents, InpAST->AST, + *CursorLoc}; + + auto A = prepareTweak(ID, Inputs); + if (!A) + return CB(A.takeError()); + // FIXME: run formatter on top of resulting replacements. + return CB((*A)->apply(Inputs)); + }; + WorkScheduler.runWithAST("ApplyTweak", File, + Bind(Action, std::move(CB), File.str())); +} + void ClangdServer::dumpAST(PathRef File, llvm::unique_function Callback) { auto Action = [](decltype(Callback) Callback, diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index 0be16026..cc9f713c 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -21,8 +21,10 @@ #include "index/Background.h" #include "index/FileIndex.h" #include "index/Index.h" +#include "refactor/Tweak.h" #include "clang/Tooling/CompilationDatabase.h" #include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/FunctionExtras.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -211,6 +213,18 @@ public: void rename(PathRef File, Position Pos, llvm::StringRef NewName, Callback> CB); + struct TweakRef { + TweakID ID; /// ID to pass for applyTweak. + std::string Title; /// A single-line message to show in the UI. + }; + /// Enumerate the code tweaks available to the user at a specified point. + void enumerateTweaks(PathRef File, Range Sel, + Callback> CB); + + /// Apply the code tweak with a specified \p ID. + void applyTweak(PathRef File, Range Sel, TweakID ID, + Callback CB); + /// Only for testing purposes. /// Waits until all requests to worker thread are finished and dumps AST for /// \p File. \p File must be in the list of added documents. diff --git a/clangd/Protocol.cpp b/clangd/Protocol.cpp index 89b1cbf3..ef6f491a 100644 --- a/clangd/Protocol.cpp +++ b/clangd/Protocol.cpp @@ -421,6 +421,9 @@ bool fromJSON(const llvm::json::Value &Params, WorkspaceEdit &R) { const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND = "clangd.applyFix"; +const llvm::StringLiteral ExecuteCommandParams::CLANGD_APPLY_TWEAK = + "clangd.applyTweak"; + bool fromJSON(const llvm::json::Value &Params, ExecuteCommandParams &R) { llvm::json::ObjectMapper O(Params); if (!O || !O.map("command", R.command)) @@ -431,6 +434,8 @@ bool fromJSON(const llvm::json::Value &Params, ExecuteCommandParams &R) { return Args && Args->size() == 1 && fromJSON(Args->front(), R.workspaceEdit); } + if (R.command == ExecuteCommandParams::CLANGD_APPLY_TWEAK) + return Args && Args->size() == 1 && fromJSON(Args->front(), R.tweakArgs); return false; // Unrecognized command. } @@ -497,10 +502,13 @@ llvm::json::Value toJSON(const Command &C) { auto Cmd = llvm::json::Object{{"title", C.title}, {"command", C.command}}; if (C.workspaceEdit) Cmd["arguments"] = {*C.workspaceEdit}; + if (C.tweakArgs) + Cmd["arguments"] = {*C.tweakArgs}; return std::move(Cmd); } const llvm::StringLiteral CodeAction::QUICKFIX_KIND = "quickfix"; +const llvm::StringLiteral CodeAction::REFACTOR_KIND = "refactor"; llvm::json::Value toJSON(const CodeAction &CA) { auto CodeAction = llvm::json::Object{{"title", CA.title}}; @@ -544,6 +552,17 @@ llvm::json::Value toJSON(const WorkspaceEdit &WE) { return llvm::json::Object{{"changes", std::move(FileChanges)}}; } +bool fromJSON(const llvm::json::Value &Params, TweakArgs &A) { + llvm::json::ObjectMapper O(Params); + return O && O.map("file", A.file) && O.map("selection", A.selection) && + O.map("tweakID", A.tweakID); +} + +llvm::json::Value toJSON(const TweakArgs &A) { + return llvm::json::Object{ + {"tweakID", A.tweakID}, {"selection", A.selection}, {"file", A.file}}; +} + llvm::json::Value toJSON(const ApplyWorkspaceEditParams &Params) { return llvm::json::Object{{"edit", Params.edit}}; } diff --git a/clangd/Protocol.h b/clangd/Protocol.h index bdcb396e..95a66711 100644 --- a/clangd/Protocol.h +++ b/clangd/Protocol.h @@ -631,6 +631,21 @@ struct WorkspaceEdit { bool fromJSON(const llvm::json::Value &, WorkspaceEdit &); llvm::json::Value toJSON(const WorkspaceEdit &WE); +/// Arguments for the 'applyTweak' command. The server sends these commands as a +/// response to the textDocument/codeAction request. The client can later send a +/// command back to the server if the user requests to execute a particular code +/// tweak. +struct TweakArgs { + /// A file provided by the client on a textDocument/codeAction request. + URIForFile file; + /// A selection provided by the client on a textDocument/codeAction request. + Range selection; + /// ID of the tweak that should be executed. Corresponds to Tweak::id(). + std::string tweakID; +}; +bool fromJSON(const llvm::json::Value &, TweakArgs &); +llvm::json::Value toJSON(const TweakArgs &A); + /// Exact commands are not specified in the protocol so we define the /// ones supported by Clangd here. The protocol specifies the command arguments /// to be "any[]" but to make this safer and more manageable, each command we @@ -642,12 +657,15 @@ llvm::json::Value toJSON(const WorkspaceEdit &WE); struct ExecuteCommandParams { // Command to apply fix-its. Uses WorkspaceEdit as argument. const static llvm::StringLiteral CLANGD_APPLY_FIX_COMMAND; + // Command to apply the code action. Uses TweakArgs as argument. + const static llvm::StringLiteral CLANGD_APPLY_TWEAK; /// The command identifier, e.g. CLANGD_APPLY_FIX_COMMAND std::string command; // Arguments llvm::Optional workspaceEdit; + llvm::Optional tweakArgs; }; bool fromJSON(const llvm::json::Value &, ExecuteCommandParams &); @@ -669,6 +687,7 @@ struct CodeAction { /// Used to filter code actions. llvm::Optional kind; const static llvm::StringLiteral QUICKFIX_KIND; + const static llvm::StringLiteral REFACTOR_KIND; /// The diagnostics that this code action resolves. llvm::Optional> diagnostics; diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp index 1d8ceb2c..1f89ad6a 100644 --- a/clangd/SourceCode.cpp +++ b/clangd/SourceCode.cpp @@ -141,6 +141,16 @@ Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc) { return P; } +llvm::Expected sourceLocationInMainFile(const SourceManager &SM, + Position P) { + llvm::StringRef Code = SM.getBuffer(SM.getMainFileID())->getBuffer(); + auto Offset = + positionToOffset(Code, P, /*AllowColumnBeyondLineLength=*/false); + if (!Offset) + return Offset.takeError(); + return SM.getLocForStartOfFile(SM.getMainFileID()).getLocWithOffset(*Offset); +} + Range halfOpenToRange(const SourceManager &SM, CharSourceRange R) { // Clang is 1-based, LSP uses 0-based indexes. Position Begin = sourceLocToPosition(SM, R.getBegin()); diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index 2bbfd338..0d520de2 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -56,6 +56,11 @@ Position offsetToPosition(llvm::StringRef Code, size_t Offset); /// FIXME: This should return an error if the location is invalid. Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc); +/// Return the file location, corresponding to \p P. Note that one should take +/// care to avoid comparing the result with expansion locations. +llvm::Expected sourceLocationInMainFile(const SourceManager &SM, + Position P); + // Converts a half-open clang source range to an LSP range. // Note that clang also uses closed source ranges, which this can't handle! Range halfOpenToRange(const SourceManager &SM, CharSourceRange R); diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp new file mode 100644 index 00000000..4b316280 --- /dev/null +++ b/clangd/refactor/Tweak.cpp @@ -0,0 +1,74 @@ +//===--- Tweak.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 "Tweak.h" +#include "Logger.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/Registry.h" +#include +#include + +LLVM_INSTANTIATE_REGISTRY(llvm::Registry); + +namespace clang { +namespace clangd { + +/// A handy typedef to save some typing. +typedef llvm::Registry TweakRegistry; + +namespace { +/// Asserts invariants on TweakRegistry. No-op with assertion disabled. +void validateRegistry() { +#ifndef NDEBUG + llvm::StringSet<> Seen; + for (const auto &E : TweakRegistry::entries()) { + // REGISTER_TWEAK ensures E.getName() is equal to the tweak class name. + // We check that id() matches it. + assert(E.instantiate()->id() == E.getName() && + "id should be equal to class name"); + assert(Seen.try_emplace(E.getName()).second && "duplicate check id"); + } +#endif +} +} // namespace + +std::vector> prepareTweaks(const Tweak::Selection &S) { + validateRegistry(); + + std::vector> Available; + for (const auto &E : TweakRegistry::entries()) { + std::unique_ptr T = E.instantiate(); + if (!T->prepare(S)) + continue; + Available.push_back(std::move(T)); + } + // Ensure deterministic order of the results. + llvm::sort(Available, + [](const std::unique_ptr &L, + const std::unique_ptr &R) { return L->id() < R->id(); }); + return Available; +} + +llvm::Expected> prepareTweak(TweakID ID, + const Tweak::Selection &S) { + auto It = llvm::find_if( + TweakRegistry::entries(), + [ID](const TweakRegistry::entry &E) { return E.getName() == ID; }); + if (It == TweakRegistry::end()) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "id of the tweak is invalid"); + std::unique_ptr T = It->instantiate(); + if (!T->prepare(S)) + return llvm::createStringError(llvm::inconvertibleErrorCode(), + "failed to prepare() a check"); + return T; +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h new file mode 100644 index 00000000..df00bf7f --- /dev/null +++ b/clangd/refactor/Tweak.h @@ -0,0 +1,98 @@ +//===--- Tweak.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 +// +//===----------------------------------------------------------------------===// +// Tweaks are small refactoring-like actions that run over the AST and produce +// the set of edits as a result. They are local, i.e. they should take the +// current editor context, e.g. the cursor position and selection into account. +// The actions are executed in two stages: +// - Stage 1 should check whether the action is available in a current +// context. It should be cheap and fast to compute as it is executed for all +// available actions on every client request, which happen quite frequently. +// - Stage 2 is performed after stage 1 and can be more expensive to compute. +// It is performed when the user actually chooses the action. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_ACTIONS_TWEAK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_ACTIONS_TWEAK_H + +#include "ClangdUnit.h" +#include "Protocol.h" +#include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" +namespace clang { +namespace clangd { + +using TweakID = llvm::StringRef; + +/// An interface base for small context-sensitive refactoring actions. +/// To implement a new tweak use the following pattern in a .cpp file: +/// class MyTweak : public Tweak { +/// public: +/// TweakID id() const override final; // definition provided by +/// // REGISTER_TWEAK. +/// // implement other methods here. +/// }; +/// REGISTER_TWEAK(MyTweak); +class Tweak { +public: + /// Input to prepare and apply tweaks. + struct Selection { + /// The text of the active document. + llvm::StringRef Code; + /// Parsed AST of the active file. + ParsedAST &AST; + /// A location of the cursor in the editor. + SourceLocation Cursor; + // FIXME: add selection when there are checks relying on it. + // FIXME: provide a way to get sources and ASTs for other files. + // FIXME: cache some commonly required information (e.g. AST nodes under + // cursor) to avoid redundant AST visit in every action. + }; + virtual ~Tweak() = default; + /// A unique id of the action, it is always equal to the name of the class + /// defining the Tweak. Definition is provided automatically by + /// REGISTER_TWEAK. + virtual TweakID id() const = 0; + /// Run the first stage of the action. The non-None result indicates that the + /// action is available and should be shown to the user. Returns None if the + /// action is not available. + /// This function should be fast, if the action requires non-trivial work it + /// should be moved into 'apply'. + /// Returns true iff the action is available and apply() can be called on it. + virtual bool prepare(const Selection &Sel) = 0; + /// Run the second stage of the action that would produce the actual changes. + /// EXPECTS: prepare() was called and returned true. + virtual Expected apply(const Selection &Sel) = 0; + /// A one-line title of the action that should be shown to the users in the + /// UI. + /// EXPECTS: prepare() was called and returned true. + virtual std::string title() const = 0; +}; + +// All tweaks must be registered in the .cpp file next to their definition. +#define REGISTER_TWEAK(Subclass) \ + ::llvm::Registry<::clang::clangd::Tweak>::Add \ + TweakRegistrationFor##Subclass(#Subclass, /*Description=*/""); \ + ::clang::clangd::TweakID Subclass::id() const { \ + return llvm::StringLiteral(#Subclass); \ + } + +/// Calls prepare() on all tweaks, returning those that can run on the +/// selection. +std::vector> prepareTweaks(const Tweak::Selection &S); + +// Calls prepare() on the tweak with a given ID. +// If prepare() returns false, returns an error. +// If prepare() returns true, returns the corresponding tweak. +llvm::Expected> prepareTweak(TweakID ID, + const Tweak::Selection &S); + +} // namespace clangd +} // namespace clang + +#endif diff --git a/clangd/refactor/tweaks/CMakeLists.txt b/clangd/refactor/tweaks/CMakeLists.txt new file mode 100644 index 00000000..630a9d06 --- /dev/null +++ b/clangd/refactor/tweaks/CMakeLists.txt @@ -0,0 +1,13 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..) + +# A target containing all code tweaks (i.e. mini-refactorings) provided by +# clangd. +# Built as an object library to make sure linker does not remove global +# constructors that register individual tweaks in a global registry. +# To enable these tweaks in exectubales or shared libraries, add +# $ to a list of sources, see +# clangd/tool/CMakeLists.txt for an example. +add_clang_library(clangDaemonTweaks OBJECT + Dummy.cpp # FIXME: to avoid CMake errors due to empty inputs, remove when a + # first tweak lands. + ) diff --git a/clangd/refactor/tweaks/Dummy.cpp b/clangd/refactor/tweaks/Dummy.cpp new file mode 100644 index 00000000..f64716ae --- /dev/null +++ b/clangd/refactor/tweaks/Dummy.cpp @@ -0,0 +1,9 @@ +//===--- Dummy.cpp -----------------------------------------------*- C++-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// Does nothing, only here to avoid cmake errors for empty libraries. \ No newline at end of file diff --git a/clangd/tool/CMakeLists.txt b/clangd/tool/CMakeLists.txt index 6547a830..9057f4e2 100644 --- a/clangd/tool/CMakeLists.txt +++ b/clangd/tool/CMakeLists.txt @@ -3,6 +3,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/..) add_clang_tool(clangd ClangdMain.cpp + $ ) set(LLVM_LINK_COMPONENTS diff --git a/test/clangd/fixits-command.test b/test/clangd/fixits-command.test index 67f70dbe..369b34a9 100644 --- a/test/clangd/fixits-command.test +++ b/test/clangd/fixits-command.test @@ -23,7 +23,7 @@ # CHECK-NEXT: "uri": "file://{{.*}}/foo.c" # CHECK-NEXT: } --- -{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} +{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} # CHECK: "id": 2, # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": [ @@ -92,7 +92,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] --- -{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} +{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} # Make sure unused "code" and "source" fields ignored gracefully # CHECK: "id": 3, # CHECK-NEXT: "jsonrpc": "2.0", diff --git a/test/clangd/initialize-params.test b/test/clangd/initialize-params.test index 62f7b41a..a71b925f 100644 --- a/test/clangd/initialize-params.test +++ b/test/clangd/initialize-params.test @@ -25,7 +25,8 @@ # CHECK-NEXT: "documentSymbolProvider": true, # CHECK-NEXT: "executeCommandProvider": { # CHECK-NEXT: "commands": [ -# CHECK-NEXT: "clangd.applyFix" +# CHECK-NEXT: "clangd.applyFix", +# CHECK-NEXT: "clangd.applyTweak" # CHECK-NEXT: ] # CHECK-NEXT: }, # CHECK-NEXT: "hoverProvider": true, -- cgit v1.2.3 From 8d94bde0b762e70485d3bba6d4f4a2b336d743a0 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 29 Jan 2019 14:31:19 +0000 Subject: [clangd] Unit test for sourceLocationInMainFile. This should have been part of r352494, which added the corresponding function. The unit test ended up as a separate commit accidentally. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352501 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/SourceCodeTests.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/unittests/clangd/SourceCodeTests.cpp b/unittests/clangd/SourceCodeTests.cpp index c17ce46c..316a0d52 100644 --- a/unittests/clangd/SourceCodeTests.cpp +++ b/unittests/clangd/SourceCodeTests.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// +#include "Annotations.h" #include "SourceCode.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_os_ostream.h" @@ -16,6 +17,9 @@ namespace clang { namespace clangd { namespace { +using llvm::Failed; +using llvm::HasValue; + MATCHER_P2(Pos, Line, Col, "") { return arg.line == Line && arg.character == Col; } @@ -140,6 +144,38 @@ TEST(SourceCodeTests, IsRangeConsecutive) { isRangeConsecutive(range({2, 2}, {2, 3}), range({2, 4}, {2, 5}))); } +TEST(SourceCodeTests, SourceLocationInMainFile) { + Annotations Source(R"cpp( + ^in^t ^foo + ^bar + ^baz ^() {} {} {} {} { }^ +)cpp"); + + SourceManagerForFile Owner("foo.cpp", Source.code()); + SourceManager &SM = Owner.get(); + + SourceLocation StartOfFile = SM.getLocForStartOfFile(SM.getMainFileID()); + EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 0)), + HasValue(StartOfFile)); + // End of file. + EXPECT_THAT_EXPECTED( + sourceLocationInMainFile(SM, position(4, 0)), + HasValue(StartOfFile.getLocWithOffset(Source.code().size()))); + // Column number is too large. + EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 1)), Failed()); + EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(0, 100)), + Failed()); + EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(4, 1)), Failed()); + // Line number is too large. + EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, position(5, 0)), Failed()); + // Check all positions mentioned in the test return valid results. + for (auto P : Source.points()) { + size_t Offset = llvm::cantFail(positionToOffset(Source.code(), P)); + EXPECT_THAT_EXPECTED(sourceLocationInMainFile(SM, P), + HasValue(StartOfFile.getLocWithOffset(Offset))); + } +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From ed3cd857d675c39146dc39441a21020e4fbe0a89 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 29 Jan 2019 15:52:05 +0000 Subject: [clangd] Make -clang-tidy-checks a non-hidden command-line arg Summary: This looks like a useful user-facing configuration parameter, which should be discoverable. Also fix a small typo in the description. Reviewers: hokein Reviewed By: hokein Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D57384 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352509 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/ClangdMain.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index e83ac2f1..69732ebf 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -203,9 +203,9 @@ static llvm::cl::opt EnableFunctionArgSnippets( static llvm::cl::opt ClangTidyChecks( "clang-tidy-checks", - llvm::cl::desc("List of clang-tidy checks to run (this will overrides " + llvm::cl::desc("List of clang-tidy checks to run (this will override " ".clang-tidy files)"), - llvm::cl::init(""), llvm::cl::Hidden); + llvm::cl::init("")); static llvm::cl::opt SuggestMissingIncludes( "suggest-missing-includes", -- cgit v1.2.3 From e72ef06dae79543c70a64dcd3e31e4d27ef10c87 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 29 Jan 2019 15:57:14 +0000 Subject: [clangd] Attempt to fix failing buildbots after r352494 For failures see: http://lab.llvm.org:8011/builders/clang-x86_64-linux-abi-test/builds/38501/steps/build-unified-tree/logs/stdio git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352510 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/refactor/Tweak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp index 4b316280..d70022e8 100644 --- a/clangd/refactor/Tweak.cpp +++ b/clangd/refactor/Tweak.cpp @@ -67,7 +67,7 @@ llvm::Expected> prepareTweak(TweakID ID, if (!T->prepare(S)) return llvm::createStringError(llvm::inconvertibleErrorCode(), "failed to prepare() a check"); - return T; + return std::move(T); } } // namespace clangd -- cgit v1.2.3 From a8f7cee6bfa4c4f602fea82d1e44edd8a3086eb6 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 29 Jan 2019 16:04:39 +0000 Subject: [clangd] Remove extra ';' to fix -Wpedantic warning. NFC git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352511 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/refactor/Tweak.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp index d70022e8..de6020c0 100644 --- a/clangd/refactor/Tweak.cpp +++ b/clangd/refactor/Tweak.cpp @@ -14,7 +14,7 @@ #include #include -LLVM_INSTANTIATE_REGISTRY(llvm::Registry); +LLVM_INSTANTIATE_REGISTRY(llvm::Registry) namespace clang { namespace clangd { -- cgit v1.2.3 From ec556ecf27724d29e8d0139ae27055fc7ccbeb24 Mon Sep 17 00:00:00 2001 From: James Y Knight Date: Tue, 29 Jan 2019 16:37:27 +0000 Subject: Adjust documentation for git migration. This fixes most references to the paths: llvm.org/svn/ llvm.org/git/ llvm.org/viewvc/ github.com/llvm-mirror/ github.com/llvm-project/ reviews.llvm.org/diffusion/ to instead point to https://github.com/llvm/llvm-project. This is *not* a trivial substitution, because additionally, all the checkout instructions had to be migrated to instruct users on how to use the monorepo layout, setting LLVM_ENABLE_PROJECTS instead of checking out various projects into various subdirectories. I've attempted to not change any scripts here, only documentation. The scripts will have to be addressed separately. Additionally, I've deleted one document which appeared to be outdated and unneeded: lldb/docs/building-with-debug-llvm.txt Differential Revision: https://reviews.llvm.org/D57330 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352514 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-rename.rst | 6 +++--- docs/clang-tidy/Contributing.rst | 4 ++-- docs/clang-tidy/Integrations.rst | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/clang-rename.rst b/docs/clang-rename.rst index 0c9194c4..2796141f 100644 --- a/docs/clang-rename.rst +++ b/docs/clang-rename.rst @@ -139,8 +139,8 @@ Vim Integration You can call :program:`clang-rename` directly from Vim! To set up :program:`clang-rename` integration for Vim see -`clang-rename/tool/clang-rename.py -`_. +`clang/tools/clang-rename/clang-rename.py +`_. Please note that **you have to save all buffers, in which the replacement will happen before running the tool**. @@ -157,7 +157,7 @@ Emacs Integration You can also use :program:`clang-rename` while using Emacs! To set up :program:`clang-rename` integration for Emacs see `clang-rename/tool/clang-rename.el -`_. +`_. Once installed, you can point your cursor to symbols you want to rename, press `M-X`, type `clang-rename` and new desired name. diff --git a/docs/clang-tidy/Contributing.rst b/docs/clang-tidy/Contributing.rst index 6d61809e..719bed38 100644 --- a/docs/clang-tidy/Contributing.rst +++ b/docs/clang-tidy/Contributing.rst @@ -127,7 +127,7 @@ style used in the project. For code reviews we mostly use `LLVM Phabricator`_. Next, you need to decide which module the check belongs to. Modules are located in subdirectories of `clang-tidy/ -`_ +`_ and contain checks targeting a certain aspect of code quality (performance, readability, etc.), certain coding style or standard (Google, LLVM, CERT, etc.) or a widely used API (e.g. MPI). Their names are same as user-facing check @@ -210,7 +210,7 @@ can further inspect them and report diagnostics. (If you want to see an example of a useful check, look at `clang-tidy/google/ExplicitConstructorCheck.h -`_ +`_ and `clang-tidy/google/ExplicitConstructorCheck.cpp `_). diff --git a/docs/clang-tidy/Integrations.rst b/docs/clang-tidy/Integrations.rst index dad7f7d9..ba08bf7f 100644 --- a/docs/clang-tidy/Integrations.rst +++ b/docs/clang-tidy/Integrations.rst @@ -75,7 +75,7 @@ choose the checks to be performed in the Clang Code Model Warnings menu. .. _ReSharper C++: https://www.jetbrains.com/help/resharper/Clang_Tidy_Integration.html .. _Visual Assist: https://docs.wholetomato.com/default.asp?W761 .. _Clang Power Tools: https://marketplace.visualstudio.com/items?itemName=caphyon.ClangPowerTools -.. _clang-tidy-vs: https://github.com/llvm-mirror/clang-tools-extra/tree/master/clang-tidy-vs +.. _clang-tidy-vs: https://github.com/llvm/llvm-project/tree/master/clang-tools-extra/clang-tidy-vs `MS Visual Studio`_ has a native clang-tidy-vs_ plugin and also can integrate :program:`clang-tidy` by means of three other tools. The `ReSharper C++`_ -- cgit v1.2.3 From 9ee3fd6e7b11c2f89195c6725013917a6b055201 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 30 Jan 2019 09:39:01 +0000 Subject: [clangd] Fix a use after move Introduced in r352494. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352612 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index cb8bf5a6..705777c3 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -697,8 +697,8 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params, }; Server->enumerateTweaks(File.file(), Params.range, - Bind(ConsumeActions, std::move(Reply), - std::move(File), std::move(*Code), Params.range, + Bind(ConsumeActions, std::move(Reply), File, + std::move(*Code), Params.range, std::move(FixIts))); } -- cgit v1.2.3 From b4253dcb49ab259c3f7bb430338c3ccf3404bb54 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 30 Jan 2019 14:24:17 +0000 Subject: [clangd] Drop fixes if replying with tweaks resulted in an error This should not happen in normal operation, as it implies that the diagnostics with some available fixes were produced but the AST is invalid. Moreover, the code had an error: always returned code actions ignoring the SupportsCodeAction capability and writing a test for this is impossible, since this can only happen due to programmer's error rather than invalid inputs. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352624 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 10 ++-------- test/clangd/fixits-codeaction.test | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 705777c3..0671ee36 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -672,14 +672,8 @@ void ClangdLSPServer::onCodeAction(const CodeActionParams &Params, [this](decltype(Reply) Reply, URIForFile File, std::string Code, Range Selection, std::vector FixIts, llvm::Expected> Tweaks) { - if (!Tweaks) { - auto Err = Tweaks.takeError(); - if (Err.isA()) - return Reply(std::move(Err)); // do no logging, this is expected. - elog("error while getting semantic code actions: {0}", - std::move(Err)); - return Reply(llvm::json::Array(FixIts)); - } + if (!Tweaks) + return Reply(Tweaks.takeError()); std::vector Actions = std::move(FixIts); Actions.reserve(Actions.size() + Tweaks->size()); diff --git a/test/clangd/fixits-codeaction.test b/test/clangd/fixits-codeaction.test index 97dd4ff2..253df992 100644 --- a/test/clangd/fixits-codeaction.test +++ b/test/clangd/fixits-codeaction.test @@ -23,7 +23,7 @@ # CHECK-NEXT: "uri": "file://{{.*}}/foo.c" # CHECK-NEXT: } --- -{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":104,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} +{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} # CHECK: "id": 2, # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": [ -- cgit v1.2.3 From e718a871a7bd61599de5f902cdec3c0a7ffa35c0 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 31 Jan 2019 10:46:37 +0000 Subject: [clang-tidy] refactor bugprone-exception-escape analysis into class Summary: The check `bugprone-exception-escape` does an AST-based analysis to determine if a function might throw an exception and warns based on that information. The analysis part is refactored into a standalone class similiar to `ExprMutAnalyzer` that is generally useful. I intent to use that class in a new check to automatically introduce `noexcept` if possible. Reviewers: aaron.ballman, alexfh, hokein, baloghadamsoftware, lebedev.ri Reviewed By: baloghadamsoftware, lebedev.ri Subscribers: lebedev.ri, mgorny, xazax.hun, rnkovacs, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D57100 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352741 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/ExceptionEscapeCheck.cpp | 165 +++------------------------ clang-tidy/bugprone/ExceptionEscapeCheck.h | 6 +- clang-tidy/utils/CMakeLists.txt | 1 + clang-tidy/utils/ExceptionAnalyzer.cpp | 154 +++++++++++++++++++++++++ clang-tidy/utils/ExceptionAnalyzer.h | 48 ++++++++ 5 files changed, 223 insertions(+), 151 deletions(-) create mode 100644 clang-tidy/utils/ExceptionAnalyzer.cpp create mode 100644 clang-tidy/utils/ExceptionAnalyzer.h diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index bd57da99..0849e2e7 100644 --- a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -1,4 +1,4 @@ -//===--- ExceptionEscapeCheck.cpp - clang-tidy-----------------------------===// +//===--- ExceptionEscapeCheck.cpp - clang-tidy ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,158 +10,21 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" - #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringSet.h" using namespace clang::ast_matchers; -namespace { -typedef llvm::SmallVector TypeVec; -} // namespace - namespace clang { - -static bool isBaseOf(const Type *DerivedType, const Type *BaseType) { - const auto *DerivedClass = DerivedType->getAsCXXRecordDecl(); - const auto *BaseClass = BaseType->getAsCXXRecordDecl(); - if (!DerivedClass || !BaseClass) - return false; - - return !DerivedClass->forallBases( - [BaseClass](const CXXRecordDecl *Cur) { return Cur != BaseClass; }); -} - -static const TypeVec -throwsException(const Stmt *St, const TypeVec &Caught, - llvm::SmallSet &CallStack); - -static const TypeVec -throwsException(const FunctionDecl *Func, - llvm::SmallSet &CallStack) { - if (CallStack.count(Func)) - return TypeVec(); - - if (const Stmt *Body = Func->getBody()) { - CallStack.insert(Func); - const TypeVec Result = throwsException(Body, TypeVec(), CallStack); - CallStack.erase(Func); - return Result; - } - - TypeVec Result; - if (const auto *FPT = Func->getType()->getAs()) { - for (const QualType Ex : FPT->exceptions()) { - Result.push_back(Ex.getTypePtr()); - } - } - return Result; -} - -static const TypeVec -throwsException(const Stmt *St, const TypeVec &Caught, - llvm::SmallSet &CallStack) { - TypeVec Results; - - if (!St) - return Results; - - if (const auto *Throw = dyn_cast(St)) { - if (const auto *ThrownExpr = Throw->getSubExpr()) { - const auto *ThrownType = - ThrownExpr->getType()->getUnqualifiedDesugaredType(); - if (ThrownType->isReferenceType()) { - ThrownType = ThrownType->castAs() - ->getPointeeType() - ->getUnqualifiedDesugaredType(); - } - if (const auto *TD = ThrownType->getAsTagDecl()) { - if (TD->getDeclName().isIdentifier() && TD->getName() == "bad_alloc" - && TD->isInStdNamespace()) - return Results; - } - Results.push_back(ThrownExpr->getType()->getUnqualifiedDesugaredType()); - } else { - Results.append(Caught.begin(), Caught.end()); - } - } else if (const auto *Try = dyn_cast(St)) { - TypeVec Uncaught = throwsException(Try->getTryBlock(), Caught, CallStack); - for (unsigned i = 0; i < Try->getNumHandlers(); ++i) { - const CXXCatchStmt *Catch = Try->getHandler(i); - if (!Catch->getExceptionDecl()) { - const TypeVec Rethrown = - throwsException(Catch->getHandlerBlock(), Uncaught, CallStack); - Results.append(Rethrown.begin(), Rethrown.end()); - Uncaught.clear(); - } else { - const auto *CaughtType = - Catch->getCaughtType()->getUnqualifiedDesugaredType(); - if (CaughtType->isReferenceType()) { - CaughtType = CaughtType->castAs() - ->getPointeeType() - ->getUnqualifiedDesugaredType(); - } - auto NewEnd = - llvm::remove_if(Uncaught, [&CaughtType](const Type *ThrownType) { - return ThrownType == CaughtType || - isBaseOf(ThrownType, CaughtType); - }); - if (NewEnd != Uncaught.end()) { - Uncaught.erase(NewEnd, Uncaught.end()); - const TypeVec Rethrown = throwsException( - Catch->getHandlerBlock(), TypeVec(1, CaughtType), CallStack); - Results.append(Rethrown.begin(), Rethrown.end()); - } - } - } - Results.append(Uncaught.begin(), Uncaught.end()); - } else if (const auto *Call = dyn_cast(St)) { - if (const FunctionDecl *Func = Call->getDirectCallee()) { - TypeVec Excs = throwsException(Func, CallStack); - Results.append(Excs.begin(), Excs.end()); - } - } else { - for (const Stmt *Child : St->children()) { - TypeVec Excs = throwsException(Child, Caught, CallStack); - Results.append(Excs.begin(), Excs.end()); - } - } - return Results; -} - -static const TypeVec throwsException(const FunctionDecl *Func) { - llvm::SmallSet CallStack; - return throwsException(Func, CallStack); -} - -namespace ast_matchers { -AST_MATCHER_P(FunctionDecl, throws, internal::Matcher, InnerMatcher) { - TypeVec ExceptionList = throwsException(&Node); - auto NewEnd = llvm::remove_if( - ExceptionList, [this, Finder, Builder](const Type *Exception) { - return !InnerMatcher.matches(*Exception, Finder, Builder); - }); - ExceptionList.erase(NewEnd, ExceptionList.end()); - return ExceptionList.size(); -} - -AST_MATCHER_P(Type, isIgnored, llvm::StringSet<>, IgnoredExceptions) { - if (const auto *TD = Node.getAsTagDecl()) { - if (TD->getDeclName().isIdentifier()) - return IgnoredExceptions.count(TD->getName()) > 0; - } - return false; -} - +namespace { AST_MATCHER_P(FunctionDecl, isEnabled, llvm::StringSet<>, FunctionsThatShouldNotThrow) { return FunctionsThatShouldNotThrow.count(Node.getNameAsString()) > 0; } -} // namespace ast_matchers +} // namespace namespace tidy { namespace bugprone { - ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), RawFunctionsThatShouldNotThrow(Options.get( @@ -173,9 +36,12 @@ ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name, .split(FunctionsThatShouldNotThrowVec, ",", -1, false); FunctionsThatShouldNotThrow.insert(FunctionsThatShouldNotThrowVec.begin(), FunctionsThatShouldNotThrowVec.end()); + + llvm::StringSet<> IgnoredExceptions; StringRef(RawIgnoredExceptions).split(IgnoredExceptionsVec, ",", -1, false); IgnoredExceptions.insert(IgnoredExceptionsVec.begin(), IgnoredExceptionsVec.end()); + Tracer.ignoreExceptions(std::move(IgnoredExceptions)); } void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { @@ -193,22 +59,25 @@ void ExceptionEscapeCheck::registerMatchers(MatchFinder *Finder) { cxxConstructorDecl(isMoveConstructor()), cxxMethodDecl(isMoveAssignmentOperator()), hasName("main"), hasName("swap"), - isEnabled(FunctionsThatShouldNotThrow)), - throws(unless(isIgnored(IgnoredExceptions)))) + isEnabled(FunctionsThatShouldNotThrow))) .bind("thrower"), this); } void ExceptionEscapeCheck::check(const MatchFinder::MatchResult &Result) { - const FunctionDecl *MatchedDecl = - Result.Nodes.getNodeAs("thrower"); + const auto *MatchedDecl = Result.Nodes.getNodeAs("thrower"); + if (!MatchedDecl) return; - // FIXME: We should provide more information about the exact location where - // the exception is thrown, maybe the full path the exception escapes - diag(MatchedDecl->getLocation(), "an exception may be thrown in function %0 " - "which should not throw exceptions") << MatchedDecl; + if (Tracer.throwsException(MatchedDecl)) + // FIXME: We should provide more information about the exact location where + // the exception is thrown, maybe the full path the exception escapes + diag(MatchedDecl->getLocation(), + "an exception may be thrown in function %0 " + + "which should not throw exceptions") + << MatchedDecl; } } // namespace bugprone diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.h b/clang-tidy/bugprone/ExceptionEscapeCheck.h index 5f4ddf2b..4626e425 100644 --- a/clang-tidy/bugprone/ExceptionEscapeCheck.h +++ b/clang-tidy/bugprone/ExceptionEscapeCheck.h @@ -1,4 +1,4 @@ -//===--- ExceptionEscapeCheck.h - clang-tidy---------------------*- C++ -*-===// +//===--- ExceptionEscapeCheck.h - clang-tidy --------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_BUGPRONE_EXCEPTION_ESCAPE_H #include "../ClangTidy.h" - +#include "../utils/ExceptionAnalyzer.h" #include "llvm/ADT/StringSet.h" namespace clang { @@ -36,7 +36,7 @@ private: std::string RawIgnoredExceptions; llvm::StringSet<> FunctionsThatShouldNotThrow; - llvm::StringSet<> IgnoredExceptions; + utils::ExceptionAnalyzer Tracer; }; } // namespace bugprone diff --git a/clang-tidy/utils/CMakeLists.txt b/clang-tidy/utils/CMakeLists.txt index 9162bce1..68ab7a10 100644 --- a/clang-tidy/utils/CMakeLists.txt +++ b/clang-tidy/utils/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangTidyUtils ASTUtils.cpp DeclRefExprUtils.cpp + ExceptionAnalyzer.cpp ExprSequence.cpp FixItHintUtils.cpp HeaderFileExtensionsUtils.cpp diff --git a/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tidy/utils/ExceptionAnalyzer.cpp new file mode 100644 index 00000000..7f1ca529 --- /dev/null +++ b/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -0,0 +1,154 @@ +//===--- ExceptionAnalyzer.cpp - clang-tidy -------------------------------===// +// +// 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 "ExceptionAnalyzer.h" + +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +namespace clang { +static bool isBaseOf(const Type *DerivedType, const Type *BaseType) { + const auto *DerivedClass = DerivedType->getAsCXXRecordDecl(); + const auto *BaseClass = BaseType->getAsCXXRecordDecl(); + if (!DerivedClass || !BaseClass) + return false; + + return !DerivedClass->forallBases( + [BaseClass](const CXXRecordDecl *Cur) { return Cur != BaseClass; }); +} + +namespace tidy { +namespace utils { + +ExceptionAnalyzer::TypeVec ExceptionAnalyzer::throwsException( + const FunctionDecl *Func, + llvm::SmallSet &CallStack) { + if (CallStack.count(Func)) + return TypeVec(); + + if (const Stmt *Body = Func->getBody()) { + CallStack.insert(Func); + const TypeVec Result = throwsException(Body, TypeVec(), CallStack); + CallStack.erase(Func); + return Result; + } + + TypeVec Result; + if (const auto *FPT = Func->getType()->getAs()) { + for (const QualType Ex : FPT->exceptions()) { + Result.push_back(Ex.getTypePtr()); + } + } + return Result; +} + +ExceptionAnalyzer::TypeVec ExceptionAnalyzer::throwsException( + const Stmt *St, const TypeVec &Caught, + llvm::SmallSet &CallStack) { + TypeVec Results; + + if (!St) + return Results; + + if (const auto *Throw = dyn_cast(St)) { + if (const auto *ThrownExpr = Throw->getSubExpr()) { + const auto *ThrownType = + ThrownExpr->getType()->getUnqualifiedDesugaredType(); + if (ThrownType->isReferenceType()) { + ThrownType = ThrownType->castAs() + ->getPointeeType() + ->getUnqualifiedDesugaredType(); + } + if (const auto *TD = ThrownType->getAsTagDecl()) { + if (TD->getDeclName().isIdentifier() && TD->getName() == "bad_alloc" && + TD->isInStdNamespace()) + return Results; + } + Results.push_back(ThrownExpr->getType()->getUnqualifiedDesugaredType()); + } else { + Results.append(Caught.begin(), Caught.end()); + } + } else if (const auto *Try = dyn_cast(St)) { + TypeVec Uncaught = throwsException(Try->getTryBlock(), Caught, CallStack); + for (unsigned i = 0; i < Try->getNumHandlers(); ++i) { + const CXXCatchStmt *Catch = Try->getHandler(i); + if (!Catch->getExceptionDecl()) { + const TypeVec Rethrown = + throwsException(Catch->getHandlerBlock(), Uncaught, CallStack); + Results.append(Rethrown.begin(), Rethrown.end()); + Uncaught.clear(); + } else { + const auto *CaughtType = + Catch->getCaughtType()->getUnqualifiedDesugaredType(); + if (CaughtType->isReferenceType()) { + CaughtType = CaughtType->castAs() + ->getPointeeType() + ->getUnqualifiedDesugaredType(); + } + auto NewEnd = + llvm::remove_if(Uncaught, [&CaughtType](const Type *ThrownType) { + return ThrownType == CaughtType || + isBaseOf(ThrownType, CaughtType); + }); + if (NewEnd != Uncaught.end()) { + Uncaught.erase(NewEnd, Uncaught.end()); + const TypeVec Rethrown = throwsException( + Catch->getHandlerBlock(), TypeVec(1, CaughtType), CallStack); + Results.append(Rethrown.begin(), Rethrown.end()); + } + } + } + Results.append(Uncaught.begin(), Uncaught.end()); + } else if (const auto *Call = dyn_cast(St)) { + if (const FunctionDecl *Func = Call->getDirectCallee()) { + TypeVec Excs = throwsException(Func, CallStack); + Results.append(Excs.begin(), Excs.end()); + } + } else { + for (const Stmt *Child : St->children()) { + TypeVec Excs = throwsException(Child, Caught, CallStack); + Results.append(Excs.begin(), Excs.end()); + } + } + return Results; +} + +bool ExceptionAnalyzer::throwsException(const FunctionDecl *Func) { + // Check if the function has already been analyzed and reuse that result. + if (FunctionCache.count(Func) > 0) + return FunctionCache[Func]; + + llvm::SmallSet CallStack; + TypeVec ExceptionList = throwsException(Func, CallStack); + + // Remove all ignored exceptions from the list of exceptions that can be + // thrown. + auto NewEnd = llvm::remove_if(ExceptionList, [this](const Type *Exception) { + return isIgnoredExceptionType(Exception); + }); + ExceptionList.erase(NewEnd, ExceptionList.end()); + + // Cache the result of the analysis. + bool FunctionThrows = ExceptionList.size() > 0; + FunctionCache.insert(std::make_pair(Func, FunctionThrows)); + + return FunctionThrows; +} + +bool ExceptionAnalyzer::isIgnoredExceptionType(const Type *Exception) { + if (const auto *TD = Exception->getAsTagDecl()) { + if (TD->getDeclName().isIdentifier()) + return IgnoredExceptions.count(TD->getName()) > 0; + } + return false; +} + +} // namespace utils +} // namespace tidy + +} // namespace clang diff --git a/clang-tidy/utils/ExceptionAnalyzer.h b/clang-tidy/utils/ExceptionAnalyzer.h new file mode 100644 index 00000000..327da300 --- /dev/null +++ b/clang-tidy/utils/ExceptionAnalyzer.h @@ -0,0 +1,48 @@ +//===--- ExceptionAnalyzer.h - clang-tidy -----------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H + +#include "clang/AST/ASTContext.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringSet.h" + +namespace clang { +namespace tidy { +namespace utils { + +/// This class analysis if a `FunctionDecl` can in principle throw an exception, +/// either directly or indirectly. +/// It can be configured to ignore custom exception types. +class ExceptionAnalyzer { +public: + ExceptionAnalyzer() = default; + + bool throwsException(const FunctionDecl *Func); + void ignoreExceptions(llvm::StringSet<> ExceptionNames) { + IgnoredExceptions = std::move(ExceptionNames); + } + +private: + using TypeVec = llvm::SmallVector; + + TypeVec throwsException(const FunctionDecl *Func, + llvm::SmallSet &CallStack); + TypeVec throwsException(const Stmt *St, const TypeVec &Caught, + llvm::SmallSet &CallStack); + bool isIgnoredExceptionType(const Type *Exception); + + llvm::StringSet<> IgnoredExceptions; + llvm::DenseMap FunctionCache; +}; +} // namespace utils +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H -- cgit v1.2.3 From d5c0bca6c8d5b4aa3a5087e6c2acb096e8ed8595 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 31 Jan 2019 16:09:25 +0000 Subject: [clangd] Append "(fix available)" to diagnostic message when fixes are present. Summary: This would make diagnostic fixits more discoverable, especially for plugins like YCM. Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D57509 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352764 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Diagnostics.cpp | 2 ++ test/clangd/diagnostic-category.test | 2 +- test/clangd/diagnostics.test | 2 +- test/clangd/did-change-configuration-params.test | 2 +- test/clangd/execute-command.test | 2 +- test/clangd/fixits-codeaction.test | 8 ++++---- test/clangd/fixits-command.test | 6 +++--- test/clangd/fixits-embed-in-diagnostic.test | 2 +- unittests/clangd/DiagnosticsTests.cpp | 3 ++- 9 files changed, 16 insertions(+), 13 deletions(-) diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index f370caa8..83876217 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -165,6 +165,8 @@ std::string mainMessage(const Diag &D) { std::string Result; llvm::raw_string_ostream OS(Result); OS << D.Message; + if (!D.Fixes.empty()) + OS << " (" << (D.Fixes.size() > 1 ? "fixes" : "fix") << " available)"; for (auto &Note : D.Notes) { OS << "\n\n"; printDiag(OS, Note); diff --git a/test/clangd/diagnostic-category.test b/test/clangd/diagnostic-category.test index 440afbb1..08ad581c 100644 --- a/test/clangd/diagnostic-category.test +++ b/test/clangd/diagnostic-category.test @@ -7,7 +7,7 @@ # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { # CHECK-NEXT: "category": "Semantic Issue", -# CHECK-NEXT: "message": "Use of 'Point' with tag type that does not match previous declaration\n\nfoo.c:1:8: note: previous use is here", +# CHECK-NEXT: "message": "Use of 'Point' with tag type that does not match previous declaration (fix available)\n\nfoo.c:1:8: note: previous use is here", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 22, diff --git a/test/clangd/diagnostics.test b/test/clangd/diagnostics.test index a191c082..ae662693 100644 --- a/test/clangd/diagnostics.test +++ b/test/clangd/diagnostics.test @@ -6,7 +6,7 @@ # CHECK-NEXT: "params": { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Return type of 'main' is not 'int'", +# CHECK-NEXT: "message": "Return type of 'main' is not 'int' (fix available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 4, diff --git a/test/clangd/did-change-configuration-params.test b/test/clangd/did-change-configuration-params.test index 51b4a874..5c216014 100644 --- a/test/clangd/did-change-configuration-params.test +++ b/test/clangd/did-change-configuration-params.test @@ -24,7 +24,7 @@ # CHECK-NEXT: "params": { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Variable 'i' is uninitialized when used here", +# CHECK-NEXT: "message": "Variable 'i' is uninitialized when used here (fix available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 28, diff --git a/test/clangd/execute-command.test b/test/clangd/execute-command.test index 85d4b9b8..3c9c45f8 100644 --- a/test/clangd/execute-command.test +++ b/test/clangd/execute-command.test @@ -6,7 +6,7 @@ # CHECK-NEXT: "params": { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 37, diff --git a/test/clangd/fixits-codeaction.test b/test/clangd/fixits-codeaction.test index 253df992..47d75655 100644 --- a/test/clangd/fixits-codeaction.test +++ b/test/clangd/fixits-codeaction.test @@ -6,7 +6,7 @@ # CHECK-NEXT: "params": { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 37, @@ -23,14 +23,14 @@ # CHECK-NEXT: "uri": "file://{{.*}}/foo.c" # CHECK-NEXT: } --- -{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} +{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses (fixes available)"}]}}} # CHECK: "id": 2, # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": [ # CHECK-NEXT: { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 37, @@ -82,7 +82,7 @@ # CHECK-NEXT: { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 37, diff --git a/test/clangd/fixits-command.test b/test/clangd/fixits-command.test index 369b34a9..da508321 100644 --- a/test/clangd/fixits-command.test +++ b/test/clangd/fixits-command.test @@ -6,7 +6,7 @@ # CHECK-NEXT: "params": { # CHECK-NEXT: "diagnostics": [ # CHECK-NEXT: { -# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses", +# CHECK-NEXT: "message": "Using the result of an assignment as a condition without parentheses (fixes available)", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 37, @@ -23,7 +23,7 @@ # CHECK-NEXT: "uri": "file://{{.*}}/foo.c" # CHECK-NEXT: } --- -{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} +{"jsonrpc":"2.0","id":2,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses (fixes available)"}]}}} # CHECK: "id": 2, # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": [ @@ -92,7 +92,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] --- -{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses"}]}}} +{"jsonrpc":"2.0","id":3,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///foo.c"},"range":{"start":{"line":0,"character":13},"end":{"line":0,"character":35}},"context":{"diagnostics":[{"range":{"start": {"line": 0, "character": 32}, "end": {"line": 0, "character": 37}},"severity":2,"message":"Using the result of an assignment as a condition without parentheses (fixes available)"}]}}} # Make sure unused "code" and "source" fields ignored gracefully # CHECK: "id": 3, # CHECK-NEXT: "jsonrpc": "2.0", diff --git a/test/clangd/fixits-embed-in-diagnostic.test b/test/clangd/fixits-embed-in-diagnostic.test index f1aa1cfe..560fca6b 100644 --- a/test/clangd/fixits-embed-in-diagnostic.test +++ b/test/clangd/fixits-embed-in-diagnostic.test @@ -31,7 +31,7 @@ # CHECK-NEXT: "title": "change 'union' to 'struct'" # CHECK-NEXT: } # CHECK-NEXT: ], -# CHECK-NEXT: "message": "Use of 'Point' with tag type that does not match previous declaration\n\nfoo.c:1:8: note: previous use is here", +# CHECK-NEXT: "message": "Use of 'Point' with tag type that does not match previous declaration (fix available)\n\nfoo.c:1:8: note: previous use is here", # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 22, diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index ea1952e9..ca544013 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -246,7 +246,8 @@ TEST(DiagnosticsTest, ToLSP) { }; // Diagnostics should turn into these: - clangd::Diagnostic MainLSP = MatchingLSP(D, R"(Something terrible happened + clangd::Diagnostic MainLSP = + MatchingLSP(D, R"(Something terrible happened (fix available) main.cpp:6:7: remark: declared somewhere in the main file -- cgit v1.2.3 From 69229498abf5f9cce5918bd7665f4852c63c896e Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Thu, 31 Jan 2019 21:30:05 +0000 Subject: [clangd] A code action to swap branches of an if statement Reviewers: sammccall Reviewed By: sammccall Subscribers: llvm-commits, mgorny, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D56611 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352796 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/SourceCode.cpp | 68 ++++++++++++- clangd/SourceCode.h | 41 ++++++++ clangd/refactor/tweaks/CMakeLists.txt | 3 +- clangd/refactor/tweaks/Dummy.cpp | 9 -- clangd/refactor/tweaks/SwapIfBranches.cpp | 132 +++++++++++++++++++++++++ unittests/clangd/CMakeLists.txt | 3 + unittests/clangd/TweakTests.cpp | 158 ++++++++++++++++++++++++++++++ 7 files changed, 401 insertions(+), 13 deletions(-) delete mode 100644 clangd/refactor/tweaks/Dummy.cpp create mode 100644 clangd/refactor/tweaks/SwapIfBranches.cpp create mode 100644 unittests/clangd/TweakTests.cpp diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp index 1f89ad6a..a4af1a9d 100644 --- a/clangd/SourceCode.cpp +++ b/clangd/SourceCode.cpp @@ -11,6 +11,8 @@ #include "clang/AST/ASTContext.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" #include "llvm/Support/Path.h" @@ -141,6 +143,69 @@ Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc) { return P; } +bool isValidFileRange(const SourceManager &Mgr, SourceRange R) { + if (!R.getBegin().isValid() || !R.getEnd().isValid()) + return false; + + FileID BeginFID; + size_t BeginOffset = 0; + std::tie(BeginFID, BeginOffset) = Mgr.getDecomposedLoc(R.getBegin()); + + FileID EndFID; + size_t EndOffset = 0; + std::tie(EndFID, EndOffset) = Mgr.getDecomposedLoc(R.getEnd()); + + return BeginFID.isValid() && BeginFID == EndFID && BeginOffset <= EndOffset; +} + +bool halfOpenRangeContains(const SourceManager &Mgr, SourceRange R, + SourceLocation L) { + assert(isValidFileRange(Mgr, R)); + + FileID BeginFID; + size_t BeginOffset = 0; + std::tie(BeginFID, BeginOffset) = Mgr.getDecomposedLoc(R.getBegin()); + size_t EndOffset = Mgr.getFileOffset(R.getEnd()); + + FileID LFid; + size_t LOffset; + std::tie(LFid, LOffset) = Mgr.getDecomposedLoc(L); + return BeginFID == LFid && BeginOffset <= LOffset && LOffset < EndOffset; +} + +bool halfOpenRangeTouches(const SourceManager &Mgr, SourceRange R, + SourceLocation L) { + return L == R.getEnd() || halfOpenRangeContains(Mgr, R, L); +} + +llvm::Optional toHalfOpenFileRange(const SourceManager &Mgr, + const LangOptions &LangOpts, + SourceRange R) { + auto Begin = Mgr.getFileLoc(R.getBegin()); + if (Begin.isInvalid()) + return llvm::None; + auto End = Mgr.getFileLoc(R.getEnd()); + if (End.isInvalid()) + return llvm::None; + End = Lexer::getLocForEndOfToken(End, 0, Mgr, LangOpts); + + SourceRange Result(Begin, End); + if (!isValidFileRange(Mgr, Result)) + return llvm::None; + return Result; +} + +llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R) { + assert(isValidFileRange(SM, R)); + bool Invalid = false; + auto *Buf = SM.getBuffer(SM.getFileID(R.getBegin()), &Invalid); + assert(!Invalid); + + size_t BeginOffset = SM.getFileOffset(R.getBegin()); + size_t EndOffset = SM.getFileOffset(R.getEnd()); + return Buf->getBuffer().substr(BeginOffset, EndOffset - BeginOffset); +} + llvm::Expected sourceLocationInMainFile(const SourceManager &SM, Position P) { llvm::StringRef Code = SM.getBuffer(SM.getMainFileID())->getBuffer(); @@ -169,8 +234,7 @@ std::pair offsetToClangLineColumn(llvm::StringRef Code, return {Lines + 1, Offset - StartOfLine + 1}; } -std::pair -splitQualifiedName(llvm::StringRef QName) { +std::pair splitQualifiedName(StringRef QName) { size_t Pos = QName.rfind("::"); if (Pos == llvm::StringRef::npos) return {llvm::StringRef(), QName}; diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index 0d520de2..37b7b166 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SOURCECODE_H #include "Protocol.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/LangOptions.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Format/Format.h" @@ -61,6 +62,46 @@ Position sourceLocToPosition(const SourceManager &SM, SourceLocation Loc); llvm::Expected sourceLocationInMainFile(const SourceManager &SM, Position P); +/// Turns a token range into a half-open range and checks its correctness. +/// The resulting range will have only valid source location on both sides, both +/// of which are file locations. +/// +/// File locations always point to a particular offset in a file, i.e. they +/// never refer to a location inside a macro expansion. Turning locations from +/// macro expansions into file locations is ambiguous - one can use +/// SourceManager::{getExpansion|getFile|getSpelling}Loc. This function +/// calls SourceManager::getFileLoc on both ends of \p R to do the conversion. +/// +/// User input (e.g. cursor position) is expressed as a file location, so this +/// function can be viewed as a way to normalize the ranges used in the clang +/// AST so that they are comparable with ranges coming from the user input. +llvm::Optional toHalfOpenFileRange(const SourceManager &Mgr, + const LangOptions &LangOpts, + SourceRange R); + +/// Returns true iff all of the following conditions hold: +/// - start and end locations are valid, +/// - start and end locations are file locations from the same file +/// (i.e. expansion locations are not taken into account). +/// - start offset <= end offset. +/// FIXME: introduce a type for source range with this invariant. +bool isValidFileRange(const SourceManager &Mgr, SourceRange R); + +/// Returns true iff \p L is contained in \p R. +/// EXPECTS: isValidFileRange(R) == true, L is a file location. +bool halfOpenRangeContains(const SourceManager &Mgr, SourceRange R, + SourceLocation L); + +/// Returns true iff \p L is contained in \p R or \p L is equal to the end point +/// of \p R. +/// EXPECTS: isValidFileRange(R) == true, L is a file location. +bool halfOpenRangeTouches(const SourceManager &Mgr, SourceRange R, + SourceLocation L); + +/// Returns the source code covered by the source range. +/// EXPECTS: isValidFileRange(R) == true. +llvm::StringRef toSourceCode(const SourceManager &SM, SourceRange R); + // Converts a half-open clang source range to an LSP range. // Note that clang also uses closed source ranges, which this can't handle! Range halfOpenToRange(const SourceManager &SM, CharSourceRange R); diff --git a/clangd/refactor/tweaks/CMakeLists.txt b/clangd/refactor/tweaks/CMakeLists.txt index 630a9d06..62d50ba2 100644 --- a/clangd/refactor/tweaks/CMakeLists.txt +++ b/clangd/refactor/tweaks/CMakeLists.txt @@ -8,6 +8,5 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..) # $ to a list of sources, see # clangd/tool/CMakeLists.txt for an example. add_clang_library(clangDaemonTweaks OBJECT - Dummy.cpp # FIXME: to avoid CMake errors due to empty inputs, remove when a - # first tweak lands. + SwapIfBranches.cpp ) diff --git a/clangd/refactor/tweaks/Dummy.cpp b/clangd/refactor/tweaks/Dummy.cpp deleted file mode 100644 index f64716ae..00000000 --- a/clangd/refactor/tweaks/Dummy.cpp +++ /dev/null @@ -1,9 +0,0 @@ -//===--- Dummy.cpp -----------------------------------------------*- C++-*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// Does nothing, only here to avoid cmake errors for empty libraries. \ No newline at end of file diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp new file mode 100644 index 00000000..4de498ff --- /dev/null +++ b/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -0,0 +1,132 @@ +//===--- SwapIfBranches.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 "ClangdUnit.h" +#include "Logger.h" +#include "SourceCode.h" +#include "refactor/Tweak.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Stmt.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" +#include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Error.h" + +namespace clang { +namespace clangd { +namespace { +/// Swaps the 'then' and 'else' branch of the if statement. +/// Before: +/// if (foo) { return 10; } else { continue; } +/// ^^^^^^^ ^^^^ +/// After: +/// if (foo) { continue; } else { return 10; } +class SwapIfBranches : public Tweak { +public: + TweakID id() const override final; + + bool prepare(const Selection &Inputs) override; + Expected apply(const Selection &Inputs) override; + std::string title() const override; + +private: + IfStmt *If = nullptr; +}; + +REGISTER_TWEAK(SwapIfBranches); + +class FindIfUnderCursor : public RecursiveASTVisitor { +public: + FindIfUnderCursor(ASTContext &Ctx, SourceLocation CursorLoc, IfStmt *&Result) + : Ctx(Ctx), CursorLoc(CursorLoc), Result(Result) {} + + bool VisitIfStmt(IfStmt *If) { + // Check if the cursor is in the range of 'if (cond)'. + // FIXME: this does not contain the closing paren, add it too. + auto R = toHalfOpenFileRange( + Ctx.getSourceManager(), Ctx.getLangOpts(), + SourceRange(If->getIfLoc(), If->getCond()->getEndLoc().isValid() + ? If->getCond()->getEndLoc() + : If->getIfLoc())); + if (R && halfOpenRangeTouches(Ctx.getSourceManager(), *R, CursorLoc)) { + Result = If; + return false; + } + // Check the range of 'else'. + R = toHalfOpenFileRange(Ctx.getSourceManager(), Ctx.getLangOpts(), + SourceRange(If->getElseLoc())); + if (R && halfOpenRangeTouches(Ctx.getSourceManager(), *R, CursorLoc)) { + Result = If; + return false; + } + + return true; + } + +private: + ASTContext &Ctx; + SourceLocation CursorLoc; + IfStmt *&Result; +}; +} // namespace + +bool SwapIfBranches::prepare(const Selection &Inputs) { + auto &Ctx = Inputs.AST.getASTContext(); + FindIfUnderCursor(Ctx, Inputs.Cursor, If).TraverseAST(Ctx); + if (!If) + return false; + + // avoid dealing with single-statement brances, they require careful handling + // to avoid changing semantics of the code (i.e. dangling else). + if (!If->getThen() || !llvm::isa(If->getThen()) || + !If->getElse() || !llvm::isa(If->getElse())) + return false; + return true; +} + +Expected SwapIfBranches::apply(const Selection &Inputs) { + auto &Ctx = Inputs.AST.getASTContext(); + auto &SrcMgr = Ctx.getSourceManager(); + + auto ThenRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(), + If->getThen()->getSourceRange()); + if (!ThenRng) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Could not obtain range of the 'then' branch. Macros?"); + auto ElseRng = toHalfOpenFileRange(SrcMgr, Ctx.getLangOpts(), + If->getElse()->getSourceRange()); + if (!ElseRng) + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "Could not obtain range of the 'else' branch. Macros?"); + + auto ThenCode = toSourceCode(SrcMgr, *ThenRng); + auto ElseCode = toSourceCode(SrcMgr, *ElseRng); + + tooling::Replacements Result; + if (auto Err = Result.add(tooling::Replacement(Ctx.getSourceManager(), + ThenRng->getBegin(), + ThenCode.size(), ElseCode))) + return std::move(Err); + if (auto Err = Result.add(tooling::Replacement(Ctx.getSourceManager(), + ElseRng->getBegin(), + ElseCode.size(), ThenCode))) + return std::move(Err); + return Result; +} + +std::string SwapIfBranches::title() const { return "Swap if branches"; } +} // namespace clangd +} // namespace clang diff --git a/unittests/clangd/CMakeLists.txt b/unittests/clangd/CMakeLists.txt index 13aca898..aebab1fe 100644 --- a/unittests/clangd/CMakeLists.txt +++ b/unittests/clangd/CMakeLists.txt @@ -45,8 +45,11 @@ add_extra_unittest(ClangdTests TestTU.cpp ThreadingTests.cpp TraceTests.cpp + TweakTests.cpp URITests.cpp XRefsTests.cpp + + $ ) target_link_libraries(ClangdTests diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp new file mode 100644 index 00000000..8306b482 --- /dev/null +++ b/unittests/clangd/TweakTests.cpp @@ -0,0 +1,158 @@ +//===-- TweakTests.cpp ------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "Annotations.h" +#include "SourceCode.h" +#include "TestTU.h" +#include "refactor/Tweak.h" +#include "clang/AST/Expr.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Tooling/Core/Replacement.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" +#include "llvm/Testing/Support/Error.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include + +using llvm::Failed; +using llvm::HasValue; +using llvm::Succeeded; +using ::testing::IsEmpty; +using ::testing::Not; + +namespace clang { +namespace clangd { +namespace { + +std::string markRange(llvm::StringRef Code, Range R) { + size_t Begin = llvm::cantFail(positionToOffset(Code, R.start)); + size_t End = llvm::cantFail(positionToOffset(Code, R.end)); + assert(Begin <= End); + if (Begin == End) // Mark a single point. + return (Code.substr(0, Begin) + "^" + Code.substr(Begin)).str(); + // Mark a range. + return (Code.substr(0, Begin) + "[[" + Code.substr(Begin, End - Begin) + + "]]" + Code.substr(End)) + .str(); +} + +void checkAvailable(TweakID ID, llvm::StringRef Input, bool Available) { + Annotations Code(Input); + ASSERT_TRUE(0 < Code.points().size() || 0 < Code.ranges().size()) + << "no points of interest specified"; + TestTU TU; + TU.Filename = "foo.cpp"; + TU.Code = Code.code(); + + ParsedAST AST = TU.build(); + + auto CheckOver = [&](Range Selection) { + auto CursorLoc = llvm::cantFail(sourceLocationInMainFile( + AST.getASTContext().getSourceManager(), Selection.start)); + auto T = prepareTweak(ID, Tweak::Selection{Code.code(), AST, CursorLoc}); + if (Available) + EXPECT_THAT_EXPECTED(T, Succeeded()) + << "code is " << markRange(Code.code(), Selection); + else + EXPECT_THAT_EXPECTED(T, Failed()) + << "code is " << markRange(Code.code(), Selection); + }; + for (auto P : Code.points()) + CheckOver(Range{P, P}); + for (auto R : Code.ranges()) + CheckOver(R); +} + +/// Checks action is available at every point and range marked in \p Input. +void checkAvailable(TweakID ID, llvm::StringRef Input) { + return checkAvailable(ID, Input, /*Available=*/true); +} + +/// Same as checkAvailable, but checks the action is not available. +void checkNotAvailable(TweakID ID, llvm::StringRef Input) { + return checkAvailable(ID, Input, /*Available=*/false); +} +llvm::Expected apply(TweakID ID, llvm::StringRef Input) { + Annotations Code(Input); + Range SelectionRng; + if (Code.points().size() != 0) { + assert(Code.ranges().size() == 0 && + "both a cursor point and a selection range were specified"); + SelectionRng = Range{Code.point(), Code.point()}; + } else { + SelectionRng = Code.range(); + } + TestTU TU; + TU.Filename = "foo.cpp"; + TU.Code = Code.code(); + + ParsedAST AST = TU.build(); + auto CursorLoc = llvm::cantFail(sourceLocationInMainFile( + AST.getASTContext().getSourceManager(), SelectionRng.start)); + Tweak::Selection S = {Code.code(), AST, CursorLoc}; + + auto T = prepareTweak(ID, S); + if (!T) + return T.takeError(); + auto Replacements = (*T)->apply(S); + if (!Replacements) + return Replacements.takeError(); + return applyAllReplacements(Code.code(), *Replacements); +} + +void checkTransform(llvm::StringRef ID, llvm::StringRef Input, + llvm::StringRef Output) { + EXPECT_THAT_EXPECTED(apply(ID, Input), HasValue(Output)) + << "action id is" << ID; +} + +TEST(TweakTest, SwapIfBranches) { + llvm::StringLiteral ID = "SwapIfBranches"; + + checkAvailable(ID, R"cpp( + void test() { + ^i^f^^(^t^r^u^e^) { return 100; } ^e^l^s^e^ { continue; } + } + )cpp"); + + checkNotAvailable(ID, R"cpp( + void test() { + if (true) {^return ^100;^ } else { ^continue^;^ } + } + )cpp"); + + llvm::StringLiteral Input = R"cpp( + void test() { + ^if (true) { return 100; } else { continue; } + } + )cpp"; + llvm::StringLiteral Output = R"cpp( + void test() { + if (true) { continue; } else { return 100; } + } + )cpp"; + checkTransform(ID, Input, Output); + + Input = R"cpp( + void test() { + ^if () { return 100; } else { continue; } + } + )cpp"; + Output = R"cpp( + void test() { + if () { continue; } else { return 100; } + } + )cpp"; + checkTransform(ID, Input, Output); +} + +} // namespace +} // namespace clangd +} // namespace clang -- cgit v1.2.3 From 9b9b5b5dd19609738cebb659d37547208197fa63 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 05:41:50 +0000 Subject: [clangd] Fix crash in applyTweak, remove TweakID alias. Strings are complicated, giving them opaque names makes us forget they're complicated. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352837 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdServer.cpp | 13 +++++++------ clangd/ClangdServer.h | 4 ++-- clangd/refactor/Tweak.cpp | 2 +- clangd/refactor/Tweak.h | 13 ++++--------- clangd/refactor/tweaks/SwapIfBranches.cpp | 2 +- unittests/clangd/TweakTests.cpp | 10 ++++------ 6 files changed, 19 insertions(+), 25 deletions(-) diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 7221b382..6857b42a 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -354,10 +354,10 @@ void ClangdServer::enumerateTweaks(PathRef File, Range Sel, Bind(Action, std::move(CB), File.str())); } -void ClangdServer::applyTweak(PathRef File, Range Sel, TweakID ID, +void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, Callback CB) { - auto Action = [ID, Sel](decltype(CB) CB, std::string File, - Expected InpAST) { + auto Action = [Sel](decltype(CB) CB, std::string File, std::string TweakID, + Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); @@ -369,14 +369,15 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, TweakID ID, Tweak::Selection Inputs = {InpAST->Inputs.Contents, InpAST->AST, *CursorLoc}; - auto A = prepareTweak(ID, Inputs); + auto A = prepareTweak(TweakID, Inputs); if (!A) return CB(A.takeError()); // FIXME: run formatter on top of resulting replacements. return CB((*A)->apply(Inputs)); }; - WorkScheduler.runWithAST("ApplyTweak", File, - Bind(Action, std::move(CB), File.str())); + WorkScheduler.runWithAST( + "ApplyTweak", File, + Bind(Action, std::move(CB), File.str(), TweakID.str())); } void ClangdServer::dumpAST(PathRef File, diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index cc9f713c..f53718fa 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -214,7 +214,7 @@ public: Callback> CB); struct TweakRef { - TweakID ID; /// ID to pass for applyTweak. + std::string ID; /// ID to pass for applyTweak. std::string Title; /// A single-line message to show in the UI. }; /// Enumerate the code tweaks available to the user at a specified point. @@ -222,7 +222,7 @@ public: Callback> CB); /// Apply the code tweak with a specified \p ID. - void applyTweak(PathRef File, Range Sel, TweakID ID, + void applyTweak(PathRef File, Range Sel, StringRef ID, Callback CB); /// Only for testing purposes. diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp index de6020c0..02a22442 100644 --- a/clangd/refactor/Tweak.cpp +++ b/clangd/refactor/Tweak.cpp @@ -55,7 +55,7 @@ std::vector> prepareTweaks(const Tweak::Selection &S) { return Available; } -llvm::Expected> prepareTweak(TweakID ID, +llvm::Expected> prepareTweak(StringRef ID, const Tweak::Selection &S) { auto It = llvm::find_if( TweakRegistry::entries(), diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h index df00bf7f..abd4995e 100644 --- a/clangd/refactor/Tweak.h +++ b/clangd/refactor/Tweak.h @@ -27,14 +27,11 @@ namespace clang { namespace clangd { -using TweakID = llvm::StringRef; - /// An interface base for small context-sensitive refactoring actions. /// To implement a new tweak use the following pattern in a .cpp file: /// class MyTweak : public Tweak { /// public: -/// TweakID id() const override final; // definition provided by -/// // REGISTER_TWEAK. +/// const char* id() const override final; // defined by REGISTER_TWEAK. /// // implement other methods here. /// }; /// REGISTER_TWEAK(MyTweak); @@ -57,7 +54,7 @@ public: /// A unique id of the action, it is always equal to the name of the class /// defining the Tweak. Definition is provided automatically by /// REGISTER_TWEAK. - virtual TweakID id() const = 0; + virtual const char *id() const = 0; /// Run the first stage of the action. The non-None result indicates that the /// action is available and should be shown to the user. Returns None if the /// action is not available. @@ -78,9 +75,7 @@ public: #define REGISTER_TWEAK(Subclass) \ ::llvm::Registry<::clang::clangd::Tweak>::Add \ TweakRegistrationFor##Subclass(#Subclass, /*Description=*/""); \ - ::clang::clangd::TweakID Subclass::id() const { \ - return llvm::StringLiteral(#Subclass); \ - } + const char *Subclass::id() const { return #Subclass; } /// Calls prepare() on all tweaks, returning those that can run on the /// selection. @@ -89,7 +84,7 @@ std::vector> prepareTweaks(const Tweak::Selection &S); // Calls prepare() on the tweak with a given ID. // If prepare() returns false, returns an error. // If prepare() returns true, returns the corresponding tweak. -llvm::Expected> prepareTweak(TweakID ID, +llvm::Expected> prepareTweak(StringRef TweakID, const Tweak::Selection &S); } // namespace clangd diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp index 4de498ff..2e0f33af 100644 --- a/clangd/refactor/tweaks/SwapIfBranches.cpp +++ b/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -34,7 +34,7 @@ namespace { /// if (foo) { continue; } else { return 10; } class SwapIfBranches : public Tweak { public: - TweakID id() const override final; + const char *id() const override final; bool prepare(const Selection &Inputs) override; Expected apply(const Selection &Inputs) override; diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp index 8306b482..905f06b8 100644 --- a/unittests/clangd/TweakTests.cpp +++ b/unittests/clangd/TweakTests.cpp @@ -24,8 +24,6 @@ using llvm::Failed; using llvm::HasValue; using llvm::Succeeded; -using ::testing::IsEmpty; -using ::testing::Not; namespace clang { namespace clangd { @@ -43,7 +41,7 @@ std::string markRange(llvm::StringRef Code, Range R) { .str(); } -void checkAvailable(TweakID ID, llvm::StringRef Input, bool Available) { +void checkAvailable(StringRef ID, llvm::StringRef Input, bool Available) { Annotations Code(Input); ASSERT_TRUE(0 < Code.points().size() || 0 < Code.ranges().size()) << "no points of interest specified"; @@ -71,15 +69,15 @@ void checkAvailable(TweakID ID, llvm::StringRef Input, bool Available) { } /// Checks action is available at every point and range marked in \p Input. -void checkAvailable(TweakID ID, llvm::StringRef Input) { +void checkAvailable(StringRef ID, llvm::StringRef Input) { return checkAvailable(ID, Input, /*Available=*/true); } /// Same as checkAvailable, but checks the action is not available. -void checkNotAvailable(TweakID ID, llvm::StringRef Input) { +void checkNotAvailable(StringRef ID, llvm::StringRef Input) { return checkAvailable(ID, Input, /*Available=*/false); } -llvm::Expected apply(TweakID ID, llvm::StringRef Input) { +llvm::Expected apply(StringRef ID, llvm::StringRef Input) { Annotations Code(Input); Range SelectionRng; if (Code.points().size() != 0) { -- cgit v1.2.3 From f3dee9692ece38a95b2911b697a9ca6d0f6c51bf Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 1 Feb 2019 08:23:23 +0000 Subject: [clangd] Fix -DBUILD_SHARED_LIBS=ON build - SwapIfBranches needs clangAST. Else, fails with: [1/2] Linking CXX executable bin/clangd FAILED: bin/clangd : && /usr/bin/g++ -pipe -O2 -g0 -UNDEBUG -fPIC -fvisibility-inlines-hidden -Werror=date-time -std=c++11 -Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wno-missing-field-initializers -pedantic -Wno-long-long -Wimplicit-fallthrough -Wno-maybe-uninitialized -Wno-class-memaccess -Wno-noexcept-type -Wdelete-non-virtual-dtor -Wno-comment -fdiagnostics-color -ffunction-sections -fdata-sections -fno-common -Woverloaded-virtual -fno-strict-aliasing -pipe -O2 -g0 -UNDEBUG -fuse-ld=lld -Wl,--color-diagnostics -Wl,-allow-shlib-undefined -Wl,-O3 -Wl,--gc-sections tools/clang/tools/extra/clangd/refactor/tweaks/CMakeFiles/obj.clangDaemonTweaks.dir/SwapIfBranches.cpp.o tools/clang/tools/extra/clangd/tool/CMakeFiles/clangd.dir/ClangdMain.cpp.o -o bin/clangd -Wl,-rpath,"\$ORIGIN/../lib" lib/libLLVMSupport.so.9svn -lpthread lib/libclangBasic.so.9svn lib/libclangTidy.so.9svn lib/libclangDaemon.so.9svn lib/libclangFormat.so.9svn lib/libclangFrontend.so.9svn lib/libclangSema.so.9svn lib/libclangTooling.so.9svn lib/libclangToolingCore.so.9svn && : ld.lld: error: undefined symbol: clang::FunctionDecl::getBody(clang::FunctionDecl const*&) const >>> referenced by SwapIfBranches.cpp >>> tools/clang/tools/extra/clangd/refactor/tweaks/CMakeFiles/obj.clangDaemonTweaks.dir/SwapIfBranches.cpp.o:(clang::FunctionDecl::getBody() const) and so on. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352841 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/clangd/tool/CMakeLists.txt b/clangd/tool/CMakeLists.txt index 9057f4e2..93d7f145 100644 --- a/clangd/tool/CMakeLists.txt +++ b/clangd/tool/CMakeLists.txt @@ -17,6 +17,7 @@ endif() target_link_libraries(clangd PRIVATE + clangAST clangBasic clangTidy clangDaemon -- cgit v1.2.3 From 13766b0908ca1c20bd1c5a4c96ed0d709d0830fb Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Fri, 1 Feb 2019 08:58:37 +0000 Subject: [clangd] clangDaemonTweaks - fix -DBUILD_SHARED_LIBS=ON build Followup for rL352841. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352843 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/refactor/tweaks/CMakeLists.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/clangd/refactor/tweaks/CMakeLists.txt b/clangd/refactor/tweaks/CMakeLists.txt index 62d50ba2..6aeb5efd 100644 --- a/clangd/refactor/tweaks/CMakeLists.txt +++ b/clangd/refactor/tweaks/CMakeLists.txt @@ -1,5 +1,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..) +set(LLVM_LINK_COMPONENTS + support + ) + # A target containing all code tweaks (i.e. mini-refactorings) provided by # clangd. # Built as an object library to make sure linker does not remove global @@ -9,4 +13,9 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../..) # clangd/tool/CMakeLists.txt for an example. add_clang_library(clangDaemonTweaks OBJECT SwapIfBranches.cpp + + LINK_LIBS + clangAST + clangDaemon + clangToolingCore ) -- cgit v1.2.3 From db5c618a5bdb23c02d37959ffc9f67560361faed Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 11:09:06 +0000 Subject: [clangd] Unbreak fuzzer target git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352857 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/fuzzer/ClangdFuzzer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clangd/fuzzer/ClangdFuzzer.cpp b/clangd/fuzzer/ClangdFuzzer.cpp index 564643db..c9852270 100644 --- a/clangd/fuzzer/ClangdFuzzer.cpp +++ b/clangd/fuzzer/ClangdFuzzer.cpp @@ -15,6 +15,7 @@ #include "ClangdLSPServer.h" #include "ClangdServer.h" #include "CodeComplete.h" +#include "FSProvider.h" #include #include @@ -29,12 +30,13 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { auto Transport = newJSONTransport(In, llvm::nulls(), /*InMirror=*/nullptr, /*Pretty=*/false, /*Style=*/JSONStreamStyle::Standard); + RealFileSystemProvider FS; CodeCompleteOptions CCOpts; CCOpts.EnableSnippets = false; ClangdServer::Options Opts; // Initialize and run ClangdLSPServer. - ClangdLSPServer LSPServer(*Transport, CCOpts, llvm::None, false, Opts); + ClangdLSPServer LSPServer(*Transport, FS, CCOpts, llvm::None, false, Opts); LSPServer.run(); return 0; } -- cgit v1.2.3 From 5b60b9a1c834e9ae23c4379815dc6fb7157a9f7b Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 11:20:20 +0000 Subject: [clangd] Use delimited style to make life easier for the fuzzer git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352863 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/fuzzer/ClangdFuzzer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/fuzzer/ClangdFuzzer.cpp b/clangd/fuzzer/ClangdFuzzer.cpp index c9852270..eba98261 100644 --- a/clangd/fuzzer/ClangdFuzzer.cpp +++ b/clangd/fuzzer/ClangdFuzzer.cpp @@ -29,7 +29,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) { std::FILE *In = fmemopen(data, size, "r"); auto Transport = newJSONTransport(In, llvm::nulls(), /*InMirror=*/nullptr, /*Pretty=*/false, - /*Style=*/JSONStreamStyle::Standard); + /*Style=*/JSONStreamStyle::Delimited); RealFileSystemProvider FS; CodeCompleteOptions CCOpts; CCOpts.EnableSnippets = false; -- cgit v1.2.3 From 820bac171c912a763b2df27786e8e6215c3e74e4 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 11:26:13 +0000 Subject: [clangd] Implement textDocument/declaration from LSP 3.14 Summary: LSP now reflects the declaration/definition distinction. Language server changes: - textDocument/definition now returns a definition if one is found, otherwise the declaration. It no longer returns declaration + definition if they are distinct. - textDocument/declaration returns the best declaration we can find. - For macros, the active macro definition is returned for both methods. - For include directive, the top of the target file is returned for both. There doesn't appear to be a discovery mechanism (we can't return everything to clients that only know about definition), so this changes existing behavior. In practice, it should greatly reduce the fraction of the time we need to show the user a menu of options. C++ API changes: - findDefinitions is replaced by locateSymbolAt, which returns a vector - one for each symbol under the cursor. - this contains the preferred declaration, the definition (if found), and the symbol name This API enables some potentially-neat extensions, like swapping between decl and def, and exposing the symbol name to the UI in the case of multiple symbols. Reviewers: hokein Subscribers: ilya-biryukov, javed.absar, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D57388 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352864 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 35 +++++- clangd/ClangdLSPServer.h | 2 + clangd/ClangdServer.cpp | 9 +- clangd/ClangdServer.h | 7 +- clangd/XRefs.cpp | 178 ++++++++++++-------------- clangd/XRefs.h | 20 ++- test/clangd/initialize-params.test | 1 + unittests/clangd/ClangdTests.cpp | 23 ++-- unittests/clangd/SyncAPI.cpp | 8 +- unittests/clangd/SyncAPI.h | 4 +- unittests/clangd/TUSchedulerTests.cpp | 8 +- unittests/clangd/XRefsTests.cpp | 226 +++++++++++++++++++--------------- 12 files changed, 290 insertions(+), 231 deletions(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 0671ee36..7e7acf94 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -354,6 +354,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, llvm::json::Object{ {"triggerCharacters", {"(", ","}}, }}, + {"declarationProvider", true}, {"definitionProvider", true}, {"documentHighlightProvider", true}, {"hoverProvider", true}, @@ -727,8 +728,37 @@ void ClangdLSPServer::onSignatureHelp(const TextDocumentPositionParams &Params, void ClangdLSPServer::onGoToDefinition(const TextDocumentPositionParams &Params, Callback> Reply) { - Server->findDefinitions(Params.textDocument.uri.file(), Params.position, - std::move(Reply)); + Server->locateSymbolAt( + Params.textDocument.uri.file(), Params.position, + Bind( + [&](decltype(Reply) Reply, + llvm::Expected> Symbols) { + if (!Symbols) + return Reply(Symbols.takeError()); + std::vector Defs; + for (const auto &S : *Symbols) + Defs.push_back(S.Definition.getValueOr(S.PreferredDeclaration)); + Reply(std::move(Defs)); + }, + std::move(Reply))); +} + +void ClangdLSPServer::onGoToDeclaration( + const TextDocumentPositionParams &Params, + Callback> Reply) { + Server->locateSymbolAt( + Params.textDocument.uri.file(), Params.position, + Bind( + [&](decltype(Reply) Reply, + llvm::Expected> Symbols) { + if (!Symbols) + return Reply(Symbols.takeError()); + std::vector Decls; + for (const auto &S : *Symbols) + Decls.push_back(S.PreferredDeclaration); + Reply(std::move(Decls)); + }, + std::move(Reply))); } void ClangdLSPServer::onSwitchSourceHeader(const TextDocumentIdentifier &Params, @@ -814,6 +844,7 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp, MsgHandler->bind("textDocument/completion", &ClangdLSPServer::onCompletion); MsgHandler->bind("textDocument/signatureHelp", &ClangdLSPServer::onSignatureHelp); MsgHandler->bind("textDocument/definition", &ClangdLSPServer::onGoToDefinition); + MsgHandler->bind("textDocument/declaration", &ClangdLSPServer::onGoToDeclaration); MsgHandler->bind("textDocument/references", &ClangdLSPServer::onReference); MsgHandler->bind("textDocument/switchSourceHeader", &ClangdLSPServer::onSwitchSourceHeader); MsgHandler->bind("textDocument/rename", &ClangdLSPServer::onRename); diff --git a/clangd/ClangdLSPServer.h b/clangd/ClangdLSPServer.h index 40b9fc40..cda46ad1 100644 --- a/clangd/ClangdLSPServer.h +++ b/clangd/ClangdLSPServer.h @@ -77,6 +77,8 @@ private: void onCompletion(const CompletionParams &, Callback); void onSignatureHelp(const TextDocumentPositionParams &, Callback); + void onGoToDeclaration(const TextDocumentPositionParams &, + Callback>); void onGoToDefinition(const TextDocumentPositionParams &, Callback>); void onReference(const ReferenceParams &, Callback>); diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 6857b42a..a677c49a 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -13,7 +13,6 @@ #include "Headers.h" #include "SourceCode.h" #include "Trace.h" -#include "XRefs.h" #include "index/FileIndex.h" #include "index/Merge.h" #include "refactor/Tweak.h" @@ -400,13 +399,13 @@ void ClangdServer::dumpAST(PathRef File, WorkScheduler.runWithAST("DumpAST", File, Bind(Action, std::move(Callback))); } -void ClangdServer::findDefinitions(PathRef File, Position Pos, - Callback> CB) { - auto Action = [Pos, this](Callback> CB, +void ClangdServer::locateSymbolAt(PathRef File, Position Pos, + Callback> CB) { + auto Action = [Pos, this](decltype(CB) CB, llvm::Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); - CB(clangd::findDefinitions(InpAST->AST, Pos, Index)); + CB(clangd::locateSymbolAt(InpAST->AST, Pos, Index)); }; WorkScheduler.runWithAST("Definitions", File, Bind(Action, std::move(CB))); diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index f53718fa..f3294186 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -18,6 +18,7 @@ #include "GlobalCompilationDatabase.h" #include "Protocol.h" #include "TUScheduler.h" +#include "XRefs.h" #include "index/Background.h" #include "index/FileIndex.h" #include "index/Index.h" @@ -167,9 +168,9 @@ public: /// called for tracked files. void signatureHelp(PathRef File, Position Pos, Callback CB); - /// Get definition of symbol at a specified \p Line and \p Column in \p File. - void findDefinitions(PathRef File, Position Pos, - Callback> CB); + /// Find declaration/definition locations of symbol at a specified position. + void locateSymbolAt(PathRef File, Position Pos, + Callback> CB); /// Helper function that returns a path to the corresponding source file when /// given a header file and vice versa. diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 9138cf7e..74ededc6 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -21,18 +21,26 @@ namespace clang { namespace clangd { namespace { -// Get the definition from a given declaration `D`. -// Return nullptr if no definition is found, or the declaration type of `D` is -// not supported. +// Returns the single definition of the entity declared by D, if visible. +// In particular: +// - for non-redeclarable kinds (e.g. local vars), return D +// - for kinds that allow multiple definitions (e.g. namespaces), return nullptr +// Kinds of nodes that always return nullptr here will not have definitions +// reported by locateSymbolAt(). const Decl *getDefinition(const Decl *D) { assert(D); + // Decl has one definition that we can find. if (const auto *TD = dyn_cast(D)) return TD->getDefinition(); - else if (const auto *VD = dyn_cast(D)) + if (const auto *VD = dyn_cast(D)) return VD->getDefinition(); - else if (const auto *FD = dyn_cast(D)) + if (const auto *FD = dyn_cast(D)) return FD->getDefinition(); - return nullptr; + // Only a single declaration is allowed. + if (isa(D)) // except cases above + return D; + // Multiple definitions are allowed. + return nullptr; // except cases above } void logIfOverflow(const SymbolLocation &Loc) { @@ -240,8 +248,8 @@ llvm::Optional makeLocation(ParsedAST &AST, SourceLocation TokLoc, } // namespace -std::vector findDefinitions(ParsedAST &AST, Position Pos, - const SymbolIndex *Index) { +std::vector locateSymbolAt(ParsedAST &AST, Position Pos, + const SymbolIndex *Index) { const auto &SM = AST.getASTContext().getSourceManager(); auto MainFilePath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); @@ -250,114 +258,83 @@ std::vector findDefinitions(ParsedAST &AST, Position Pos, return {}; } - std::vector Result; - // Handle goto definition for #include. + // Treat #included files as symbols, to enable go-to-definition on them. for (auto &Inc : AST.getIncludeStructure().MainFileIncludes) { - if (!Inc.Resolved.empty() && Inc.R.start.line == Pos.line) - Result.push_back( - Location{URIForFile::canonicalize(Inc.Resolved, *MainFilePath), {}}); + if (!Inc.Resolved.empty() && Inc.R.start.line == Pos.line) { + LocatedSymbol File; + File.Name = llvm::sys::path::filename(Inc.Resolved); + File.PreferredDeclaration = { + URIForFile::canonicalize(Inc.Resolved, *MainFilePath), Range{}}; + File.Definition = File.PreferredDeclaration; + // We're not going to find any further symbols on #include lines. + return {std::move(File)}; + } } - if (!Result.empty()) - return Result; - // Identified symbols at a specific position. SourceLocation SourceLocationBeg = getBeginningOfIdentifier(AST, Pos, SM.getMainFileID()); auto Symbols = getSymbolAtPosition(AST, SourceLocationBeg); - for (auto Item : Symbols.Macros) { - auto Loc = Item.Info->getDefinitionLoc(); - auto L = makeLocation(AST, Loc, *MainFilePath); - if (L) - Result.push_back(*L); + // Macros are simple: there's no declaration/definition distinction. + // As a consequence, there's no need to look them up in the index either. + std::vector Result; + for (auto M : Symbols.Macros) { + if (auto Loc = + makeLocation(AST, M.Info->getDefinitionLoc(), *MainFilePath)) { + LocatedSymbol Macro; + Macro.Name = M.Name; + Macro.PreferredDeclaration = *Loc; + Macro.Definition = Loc; + Result.push_back(std::move(Macro)); + } } - // Declaration and definition are different terms in C-family languages, and - // LSP only defines the "GoToDefinition" specification, so we try to perform - // the "most sensible" GoTo operation: - // - // - We use the location from AST and index (if available) to provide the - // final results. When there are duplicate results, we prefer AST over - // index because AST is more up-to-date. - // - // - For each symbol, we will return a location of the canonical declaration - // (e.g. function declaration in header), and a location of definition if - // they are available. - // - // So the work flow: - // - // 1. Identify the symbols being search for by traversing the AST. - // 2. Populate one of the locations with the AST location. - // 3. Use the AST information to query the index, and populate the index - // location (if available). - // 4. Return all populated locations for all symbols, definition first ( - // which we think is the users wants most often). - struct CandidateLocation { - llvm::Optional Def; - llvm::Optional Decl; - }; - // We respect the order in Symbols.Decls. - llvm::SmallVector ResultCandidates; - llvm::DenseMap CandidatesIndex; + // Decls are more complicated. + // The AST contains at least a declaration, maybe a definition. + // These are up-to-date, and so generally preferred over index results. + // We perform a single batch index lookup to find additional definitions. + + // Results follow the order of Symbols.Decls. + // Keep track of SymbolID -> index mapping, to fill in index data later. + llvm::DenseMap ResultIndex; // Emit all symbol locations (declaration or definition) from AST. for (const DeclInfo &DI : Symbols.Decls) { const Decl *D = DI.D; - // Fake key for symbols don't have USR (no SymbolID). - // Ideally, there should be a USR for each identified symbols. Symbols - // without USR are rare and unimportant cases, we use the a fake holder to - // minimize the invasiveness of these cases. - SymbolID Key(""); + auto Loc = makeLocation(AST, findNameLoc(D), *MainFilePath); + if (!Loc) + continue; + + Result.emplace_back(); + if (auto *ND = dyn_cast(D)) + Result.back().Name = printName(AST.getASTContext(), *ND); + Result.back().PreferredDeclaration = *Loc; + // DeclInfo.D is always a definition if possible, so this check works. + if (getDefinition(D) == D) + Result.back().Definition = *Loc; + + // Record SymbolID for index lookup later. if (auto ID = getSymbolID(D)) - Key = *ID; - - auto R = CandidatesIndex.try_emplace(Key, ResultCandidates.size()); - if (R.second) // new entry - ResultCandidates.emplace_back(); - auto &Candidate = ResultCandidates[R.first->second]; - - auto Loc = findNameLoc(D); - auto L = makeLocation(AST, Loc, *MainFilePath); - // The declaration in the identified symbols is a definition if possible - // otherwise it is declaration. - bool IsDef = getDefinition(D) == D; - // Populate one of the slots with location for the AST. - if (!IsDef) - Candidate.Decl = L; - else - Candidate.Def = L; + ResultIndex[*ID] = Result.size() - 1; } - if (Index) { + // Now query the index for all Symbol IDs we found in the AST. + if (Index && !ResultIndex.empty()) { LookupRequest QueryRequest; - // Build request for index query, using SymbolID. - for (auto It : CandidatesIndex) + for (auto It : ResultIndex) QueryRequest.IDs.insert(It.first); - std::string TUPath; - const FileEntry *FE = SM.getFileEntryForID(SM.getMainFileID()); - if (auto Path = getCanonicalPath(FE, SM)) - TUPath = *Path; - // Query the index and populate the empty slot. - Index->lookup(QueryRequest, [&TUPath, &ResultCandidates, - &CandidatesIndex](const Symbol &Sym) { - auto It = CandidatesIndex.find(Sym.ID); - assert(It != CandidatesIndex.end()); - auto &Value = ResultCandidates[It->second]; - - if (!Value.Def) - Value.Def = toLSPLocation(Sym.Definition, TUPath); - if (!Value.Decl) - Value.Decl = toLSPLocation(Sym.CanonicalDeclaration, TUPath); - }); - } + Index->lookup(QueryRequest, [&](const Symbol &Sym) { + auto &R = Result[ResultIndex.lookup(Sym.ID)]; + + // Special case: if the AST yielded a definition, then it may not be + // the right *declaration*. Prefer the one from the index. + if (R.Definition) // from AST + if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, *MainFilePath)) + R.PreferredDeclaration = *Loc; - // Populate the results, definition first. - for (const auto &Candidate : ResultCandidates) { - if (Candidate.Def) - Result.push_back(*Candidate.Def); - if (Candidate.Decl && - Candidate.Decl != Candidate.Def) // Decl and Def might be the same - Result.push_back(*Candidate.Decl); + if (!R.Definition) + R.Definition = toLSPLocation(Sym.Definition, *MainFilePath); + }); } return Result; @@ -805,5 +782,12 @@ std::vector getSymbolInfo(ParsedAST &AST, Position Pos) { return Results; } +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LocatedSymbol &S) { + OS << S.Name << ": " << S.PreferredDeclaration; + if (S.Definition) + OS << " def=" << *S.Definition; + return OS; +} + } // namespace clangd } // namespace clang diff --git a/clangd/XRefs.h b/clangd/XRefs.h index cd90c65a..25e5d867 100644 --- a/clangd/XRefs.h +++ b/clangd/XRefs.h @@ -22,9 +22,25 @@ namespace clang { namespace clangd { +// Describes where a symbol is declared and defined (as far as clangd knows). +// There are three cases: +// - a declaration only, no definition is known (e.g. only header seen) +// - a declaration and a distinct definition (e.g. function declared in header) +// - a declaration and an equal definition (e.g. inline function, or class) +// For some types of symbol, e.g. macros, definition == declaration always. +struct LocatedSymbol { + // The (unqualified) name of the symbol. + std::string Name; + // The canonical or best declaration: where most users find its interface. + Location PreferredDeclaration; + // Where the symbol is defined, if known. May equal PreferredDeclaration. + llvm::Optional Definition; +}; +llvm::raw_ostream &operator<<(llvm::raw_ostream &, const LocatedSymbol &); /// Get definition of symbol at a specified \p Pos. -std::vector findDefinitions(ParsedAST &AST, Position Pos, - const SymbolIndex *Index = nullptr); +/// Multiple locations may be returned, corresponding to distinct symbols. +std::vector locateSymbolAt(ParsedAST &AST, Position Pos, + const SymbolIndex *Index = nullptr); /// Returns highlights for all usages of a symbol at \p Pos. std::vector findDocumentHighlights(ParsedAST &AST, diff --git a/test/clangd/initialize-params.test b/test/clangd/initialize-params.test index a71b925f..b9fec65e 100644 --- a/test/clangd/initialize-params.test +++ b/test/clangd/initialize-params.test @@ -14,6 +14,7 @@ # CHECK-NEXT: ":" # CHECK-NEXT: ] # CHECK-NEXT: }, +# CHECK-NEXT: "declarationProvider": true, # CHECK-NEXT: "definitionProvider": true, # CHECK-NEXT: "documentFormattingProvider": true, # CHECK-NEXT: "documentHighlightProvider": true, diff --git a/unittests/clangd/ClangdTests.cpp b/unittests/clangd/ClangdTests.cpp index 871348ac..6454ec8a 100644 --- a/unittests/clangd/ClangdTests.cpp +++ b/unittests/clangd/ClangdTests.cpp @@ -43,8 +43,9 @@ using ::testing::IsEmpty; using ::testing::Pair; using ::testing::UnorderedElementsAre; -MATCHER_P2(FileRange, File, Range, "") { - return Location{URIForFile::canonicalize(File, testRoot()), Range} == arg; +MATCHER_P2(DeclAt, File, Range, "") { + return arg.PreferredDeclaration == + Location{URIForFile::canonicalize(File, testRoot()), Range}; } bool diagsContainErrors(const std::vector &Diagnostics) { @@ -458,10 +459,9 @@ int hello; UnorderedElementsAre(Pair(FooCpp, false), Pair(BarCpp, true), Pair(BazCpp, false))); - auto Locations = runFindDefinitions(Server, FooCpp, FooSource.point()); + auto Locations = runLocateSymbolAt(Server, FooCpp, FooSource.point()); EXPECT_TRUE(bool(Locations)); - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooCpp, FooSource.range("one")))); + EXPECT_THAT(*Locations, ElementsAre(DeclAt(FooCpp, FooSource.range("one")))); // Undefine MACRO, close baz.cpp. CDB.ExtraClangFlags.clear(); @@ -474,10 +474,9 @@ int hello; EXPECT_THAT(DiagConsumer.filesWithDiags(), UnorderedElementsAre(Pair(FooCpp, false), Pair(BarCpp, false))); - Locations = runFindDefinitions(Server, FooCpp, FooSource.point()); + Locations = runLocateSymbolAt(Server, FooCpp, FooSource.point()); EXPECT_TRUE(bool(Locations)); - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooCpp, FooSource.range("two")))); + EXPECT_THAT(*Locations, ElementsAre(DeclAt(FooCpp, FooSource.range("two")))); } TEST_F(ClangdVFSTest, MemoryUsage) { @@ -532,7 +531,7 @@ TEST_F(ClangdVFSTest, InvalidCompileCommand) { runAddDocument(Server, FooCpp, "int main() {}"); EXPECT_EQ(runDumpAST(Server, FooCpp), ""); - EXPECT_ERROR(runFindDefinitions(Server, FooCpp, Position())); + EXPECT_ERROR(runLocateSymbolAt(Server, FooCpp, Position())); EXPECT_ERROR(runFindDocumentHighlights(Server, FooCpp, Position())); EXPECT_ERROR(runRename(Server, FooCpp, Position(), "new_name")); // FIXME: codeComplete and signatureHelp should also return errors when they @@ -717,7 +716,7 @@ int d; clangd::CodeCompleteOptions())); }; - auto FindDefinitionsRequest = [&]() { + auto LocateSymbolRequest = [&]() { unsigned FileIndex = FileIndexDist(RandGen); // Make sure we don't violate the ClangdServer's contract. if (ReqStats[FileIndex].FileIsRemoved) @@ -727,13 +726,13 @@ int d; Pos.line = LineDist(RandGen); Pos.character = ColumnDist(RandGen); - ASSERT_TRUE(!!runFindDefinitions(Server, FilePaths[FileIndex], Pos)); + ASSERT_TRUE(!!runLocateSymbolAt(Server, FilePaths[FileIndex], Pos)); }; std::vector> AsyncRequests = { AddDocumentRequest, ForceReparseRequest, RemoveDocumentRequest}; std::vector> BlockingRequests = { - CodeCompletionRequest, FindDefinitionsRequest}; + CodeCompletionRequest, LocateSymbolRequest}; // Bash requests to ClangdServer in a loop. std::uniform_int_distribution AsyncRequestIndexDist( diff --git a/unittests/clangd/SyncAPI.cpp b/unittests/clangd/SyncAPI.cpp index a6c255df..91e7a919 100644 --- a/unittests/clangd/SyncAPI.cpp +++ b/unittests/clangd/SyncAPI.cpp @@ -84,10 +84,10 @@ llvm::Expected runSignatureHelp(ClangdServer &Server, return std::move(*Result); } -llvm::Expected> -runFindDefinitions(ClangdServer &Server, PathRef File, Position Pos) { - llvm::Optional>> Result; - Server.findDefinitions(File, Pos, capture(Result)); +llvm::Expected> +runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos) { + llvm::Optional>> Result; + Server.locateSymbolAt(File, Pos, capture(Result)); return std::move(*Result); } diff --git a/unittests/clangd/SyncAPI.h b/unittests/clangd/SyncAPI.h index 65a64798..8de9c053 100644 --- a/unittests/clangd/SyncAPI.h +++ b/unittests/clangd/SyncAPI.h @@ -32,8 +32,8 @@ runCodeComplete(ClangdServer &Server, PathRef File, Position Pos, llvm::Expected runSignatureHelp(ClangdServer &Server, PathRef File, Position Pos); -llvm::Expected> -runFindDefinitions(ClangdServer &Server, PathRef File, Position Pos); +llvm::Expected> +runLocateSymbolAt(ClangdServer &Server, PathRef File, Position Pos); llvm::Expected> runFindDocumentHighlights(ClangdServer &Server, PathRef File, Position Pos); diff --git a/unittests/clangd/TUSchedulerTests.cpp b/unittests/clangd/TUSchedulerTests.cpp index e5b42328..6c71bf45 100644 --- a/unittests/clangd/TUSchedulerTests.cpp +++ b/unittests/clangd/TUSchedulerTests.cpp @@ -687,10 +687,10 @@ TEST_F(TUSchedulerTests, TUStatus) { // We schedule the following tasks in the queue: // [Update] [GoToDefinition] Server.addDocument(testPath("foo.cpp"), Code.code(), WantDiagnostics::Yes); - Server.findDefinitions(testPath("foo.cpp"), Code.point(), - [](Expected> Result) { - ASSERT_TRUE((bool)Result); - }); + Server.locateSymbolAt(testPath("foo.cpp"), Code.point(), + [](Expected> Result) { + ASSERT_TRUE((bool)Result); + }); ASSERT_TRUE(Server.blockUntilIdleForTest()); diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index 1af25487..e68790a2 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -17,6 +17,7 @@ #include "index/SymbolCollector.h" #include "clang/Index/IndexingAction.h" #include "llvm/Support/Path.h" +#include "llvm/Support/ScopedPrinter.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -25,7 +26,6 @@ namespace clangd { namespace { using testing::ElementsAre; -using testing::Field; using testing::IsEmpty; using testing::Matcher; using testing::UnorderedElementsAreArray; @@ -95,9 +95,35 @@ TEST(HighlightsTest, All) { } } +MATCHER_P3(Sym, Name, Decl, DefOrNone, "") { + llvm::Optional Def = DefOrNone; + if (Name != arg.Name) { + *result_listener << "Name is " << arg.Name; + return false; + } + if (Decl != arg.PreferredDeclaration.range) { + *result_listener << "Declaration is " + << llvm::to_string(arg.PreferredDeclaration); + return false; + } + if (Def && !arg.Definition) { + *result_listener << "Has no definition"; + return false; + } + if (Def && arg.Definition->range != *Def) { + *result_listener << "Definition is " << llvm::to_string(arg.Definition); + return false; + } + return true; +} +testing::Matcher Sym(std::string Name, Range Decl) { + return Sym(Name, Decl, llvm::None); +} +MATCHER_P(Sym, Name, "") { return arg.Name == Name; } + MATCHER_P(RangeIs, R, "") { return arg.range == R; } -TEST(GoToDefinition, WithIndex) { +TEST(LocateSymbol, WithIndex) { Annotations SymbolHeader(R"cpp( class $forward[[Forward]]; class $foo[[Foo]] {}; @@ -115,9 +141,9 @@ TEST(GoToDefinition, WithIndex) { TU.Code = SymbolCpp.code(); TU.HeaderCode = SymbolHeader.code(); auto Index = TU.index(); - auto runFindDefinitionsWithIndex = [&Index](const Annotations &Main) { + auto LocateWithIndex = [&Index](const Annotations &Main) { auto AST = TestTU::withCode(Main.code()).build(); - return clangd::findDefinitions(AST, Main.point(), Index.get()); + return clangd::locateSymbolAt(AST, Main.point(), Index.get()); }; Annotations Test(R"cpp(// only declaration in AST. @@ -126,9 +152,8 @@ TEST(GoToDefinition, WithIndex) { ^f1(); } )cpp"); - EXPECT_THAT(runFindDefinitionsWithIndex(Test), - testing::ElementsAreArray( - {RangeIs(SymbolCpp.range("f1")), RangeIs(Test.range())})); + EXPECT_THAT(LocateWithIndex(Test), + ElementsAre(Sym("f1", Test.range(), SymbolCpp.range("f1")))); Test = Annotations(R"cpp(// definition in AST. void [[f1]]() {} @@ -136,30 +161,30 @@ TEST(GoToDefinition, WithIndex) { ^f1(); } )cpp"); - EXPECT_THAT(runFindDefinitionsWithIndex(Test), - testing::ElementsAreArray( - {RangeIs(Test.range()), RangeIs(SymbolHeader.range("f1"))})); + EXPECT_THAT(LocateWithIndex(Test), + ElementsAre(Sym("f1", SymbolHeader.range("f1"), Test.range()))); Test = Annotations(R"cpp(// forward declaration in AST. class [[Foo]]; F^oo* create(); )cpp"); - EXPECT_THAT(runFindDefinitionsWithIndex(Test), - testing::ElementsAreArray( - {RangeIs(SymbolHeader.range("foo")), RangeIs(Test.range())})); + EXPECT_THAT(LocateWithIndex(Test), + ElementsAre(Sym("Foo", Test.range(), SymbolHeader.range("foo")))); Test = Annotations(R"cpp(// defintion in AST. class [[Forward]] {}; F^orward create(); )cpp"); - EXPECT_THAT(runFindDefinitionsWithIndex(Test), - testing::ElementsAreArray({ - RangeIs(Test.range()), - RangeIs(SymbolHeader.range("forward")), - })); + EXPECT_THAT( + LocateWithIndex(Test), + ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range()))); } -TEST(GoToDefinition, All) { +TEST(LocateSymbol, All) { + // Ranges in tests: + // $decl is the declaration location (if absent, no symbol is located) + // $def is the definition location (if absent, symbol has no definition) + // unnamed range becomes both $decl and $def. const char *Tests[] = { R"cpp(// Local variable int main() { @@ -186,7 +211,7 @@ TEST(GoToDefinition, All) { )cpp", R"cpp(// Function declaration via call - int [[foo]](int); + int $decl[[foo]](int); int main() { return ^foo(42); } @@ -222,7 +247,7 @@ TEST(GoToDefinition, All) { )cpp", R"cpp(// Method call - struct Foo { int [[x]](); }; + struct Foo { int $decl[[x]](); }; int main() { Foo bar; bar.^x(); @@ -230,7 +255,7 @@ TEST(GoToDefinition, All) { )cpp", R"cpp(// Typedef - typedef int [[Foo]]; + typedef int $decl[[Foo]]; int main() { ^Foo bar; } @@ -243,7 +268,7 @@ TEST(GoToDefinition, All) { )cpp", */ R"cpp(// Namespace - namespace [[ns]] { + namespace $decl[[ns]] { struct Foo { static void bar(); } } // namespace ns int main() { ^ns::Foo::bar(); } @@ -304,30 +329,45 @@ TEST(GoToDefinition, All) { }; for (const char *Test : Tests) { Annotations T(Test); + llvm::Optional WantDecl; + llvm::Optional WantDef; + if (!T.ranges().empty()) + WantDecl = WantDef = T.range(); + if (!T.ranges("decl").empty()) + WantDecl = T.range("decl"); + if (!T.ranges("def").empty()) + WantDef = T.range("def"); + auto AST = TestTU::withCode(T.code()).build(); - std::vector> ExpectedLocations; - for (const auto &R : T.ranges()) - ExpectedLocations.push_back(RangeIs(R)); - EXPECT_THAT(findDefinitions(AST, T.point()), - ElementsAreArray(ExpectedLocations)) - << Test; + auto Results = locateSymbolAt(AST, T.point()); + + if (!WantDecl) { + EXPECT_THAT(Results, IsEmpty()) << Test; + } else { + ASSERT_THAT(Results, ::testing::SizeIs(1)) << Test; + EXPECT_EQ(Results[0].PreferredDeclaration.range, *WantDecl) << Test; + llvm::Optional GotDef; + if (Results[0].Definition) + GotDef = Results[0].Definition->range; + EXPECT_EQ(WantDef, GotDef) << Test; + } } } -TEST(GoToDefinition, Rank) { +TEST(LocateSymbol, Ambiguous) { auto T = Annotations(R"cpp( - struct $foo1[[Foo]] { - $foo2[[Foo]](); - $foo3[[Foo]](Foo&&); - $foo4[[Foo]](const char*); + struct Foo { + Foo(); + Foo(Foo&&); + Foo(const char*); }; - Foo $f[[f]](); + Foo f(); - void $g[[g]](Foo foo); + void g(Foo foo); void call() { - const char* $str[[str]] = "123"; + const char* str = "123"; Foo a = $1^str; Foo b = Foo($2^str); Foo c = $3^f(); @@ -336,26 +376,20 @@ TEST(GoToDefinition, Rank) { } )cpp"); auto AST = TestTU::withCode(T.code()).build(); - EXPECT_THAT(findDefinitions(AST, T.point("1")), - ElementsAre(RangeIs(T.range("str")), RangeIs(T.range("foo4")))); - EXPECT_THAT(findDefinitions(AST, T.point("2")), - ElementsAre(RangeIs(T.range("str")))); - EXPECT_THAT(findDefinitions(AST, T.point("3")), - ElementsAre(RangeIs(T.range("f")), RangeIs(T.range("foo3")))); - EXPECT_THAT(findDefinitions(AST, T.point("4")), - ElementsAre(RangeIs(T.range("g")))); - EXPECT_THAT(findDefinitions(AST, T.point("5")), - ElementsAre(RangeIs(T.range("f")), RangeIs(T.range("foo3")))); - - auto DefinitionAtPoint6 = findDefinitions(AST, T.point("6")); - EXPECT_EQ(3ul, DefinitionAtPoint6.size()); - EXPECT_THAT(DefinitionAtPoint6, HasSubsequence(RangeIs(T.range("str")), - RangeIs(T.range("foo4")))); - EXPECT_THAT(DefinitionAtPoint6, HasSubsequence(RangeIs(T.range("str")), - RangeIs(T.range("foo3")))); + // Ordered assertions are deliberate: we expect a predictable order. + EXPECT_THAT(locateSymbolAt(AST, T.point("1")), + ElementsAre(Sym("str"), Sym("Foo"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("3")), + ElementsAre(Sym("f"), Sym("Foo"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("5")), + ElementsAre(Sym("f"), Sym("Foo"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("6")), + ElementsAre(Sym("str"), Sym("Foo"), Sym("Foo"))); } -TEST(GoToDefinition, RelPathsInCompileCommand) { +TEST(LocateSymbol, RelPathsInCompileCommand) { // The source is in "/clangd-test/src". // We build in "/clangd-test/build". @@ -397,24 +431,23 @@ int [[bar_not_preamble]]; // Go to a definition in main source file. auto Locations = - runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p1")); + runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p1")); EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooCpp, SourceAnnotations.range()))); + EXPECT_THAT(*Locations, ElementsAre(Sym("foo", SourceAnnotations.range()))); // Go to a definition in header_in_preamble.h. - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p2")); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p2")); EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(HeaderInPreambleH, - HeaderInPreambleAnnotations.range()))); + EXPECT_THAT( + *Locations, + ElementsAre(Sym("bar_preamble", HeaderInPreambleAnnotations.range()))); // Go to a definition in header_not_in_preamble.h. - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("p3")); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("p3")); EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error"; EXPECT_THAT(*Locations, - ElementsAre(FileRange(HeaderNotInPreambleH, - HeaderNotInPreambleAnnotations.range()))); + ElementsAre(Sym("bar_not_preamble", + HeaderNotInPreambleAnnotations.range()))); } TEST(Hover, All) { @@ -1061,46 +1094,39 @@ TEST(GoToInclude, All) { Server.addDocument(FooCpp, SourceAnnotations.code()); // Test include in preamble. - auto Locations = - runFindDefinitions(Server, FooCpp, SourceAnnotations.point()); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); + auto Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point()); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range()))); // Test include in preamble, last char. - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("2")); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("2")); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range()))); - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("3")); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("3")); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range()))); // Test include outside of preamble. - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("6")); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("6")); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range()))); // Test a few positions that do not result in Locations. - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("4")); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("4")); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; EXPECT_THAT(*Locations, IsEmpty()); - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("5")); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("5")); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range()))); - Locations = runFindDefinitions(Server, FooCpp, SourceAnnotations.point("7")); - ASSERT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, - ElementsAre(FileRange(FooH, HeaderAnnotations.range()))); + Locations = runLocateSymbolAt(Server, FooCpp, SourceAnnotations.point("7")); + ASSERT_TRUE(bool(Locations)) << "locateSymbolAt returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo.h", HeaderAnnotations.range()))); } -TEST(GoToDefinition, WithPreamble) { +TEST(LocateSymbol, WithPreamble) { // Test stragety: AST should always use the latest preamble instead of last // good preamble. MockFSProvider FS; @@ -1120,18 +1146,18 @@ TEST(GoToDefinition, WithPreamble) { FS.Files[FooH] = FooHeader.code(); runAddDocument(Server, FooCpp, FooWithHeader.code()); - // GoToDefinition goes to a #include file: the result comes from the preamble. + // LocateSymbol goes to a #include file: the result comes from the preamble. EXPECT_THAT( - cantFail(runFindDefinitions(Server, FooCpp, FooWithHeader.point())), - ElementsAre(FileRange(FooH, FooHeader.range()))); + cantFail(runLocateSymbolAt(Server, FooCpp, FooWithHeader.point())), + ElementsAre(Sym("foo.h", FooHeader.range()))); // Only preamble is built, and no AST is built in this request. Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::No); // We build AST here, and it should use the latest preamble rather than the // stale one. EXPECT_THAT( - cantFail(runFindDefinitions(Server, FooCpp, FooWithoutHeader.point())), - ElementsAre(FileRange(FooCpp, FooWithoutHeader.range()))); + cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())), + ElementsAre(Sym("foo", FooWithoutHeader.range()))); // Reset test environment. runAddDocument(Server, FooCpp, FooWithHeader.code()); @@ -1139,8 +1165,8 @@ TEST(GoToDefinition, WithPreamble) { Server.addDocument(FooCpp, FooWithoutHeader.code(), WantDiagnostics::Yes); // Use the AST being built in above request. EXPECT_THAT( - cantFail(runFindDefinitions(Server, FooCpp, FooWithoutHeader.point())), - ElementsAre(FileRange(FooCpp, FooWithoutHeader.range()))); + cantFail(runLocateSymbolAt(Server, FooCpp, FooWithoutHeader.point())), + ElementsAre(Sym("foo", FooWithoutHeader.range()))); } TEST(FindReferences, WithinAST) { -- cgit v1.2.3 From 3a4dfd62c2def9861d4d0e277ce832dcb8e7ccb4 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 13:07:37 +0000 Subject: [clangd] Penalize file-scope symbols in the ranking for non-completion queries Patch by Nathan Ridge! Differential Revision: https://reviews.llvm.org/D56653 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352868 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Quality.cpp | 21 +++++++++++++++++---- unittests/clangd/QualityTests.cpp | 12 +++++++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/clangd/Quality.cpp b/clangd/Quality.cpp index e9e8ff0a..50e3f7ee 100644 --- a/clangd/Quality.cpp +++ b/clangd/Quality.cpp @@ -282,12 +282,12 @@ computeScope(const NamedDecl *D) { } void SymbolRelevanceSignals::merge(const Symbol &IndexResult) { - // FIXME: Index results always assumed to be at global scope. If Scope becomes - // relevant to non-completion requests, we should recognize class members etc. - SymbolURI = IndexResult.CanonicalDeclaration.FileURI; SymbolScope = IndexResult.Scope; IsInstanceMember |= isInstanceMember(IndexResult.SymInfo); + if (!(IndexResult.Flags & Symbol::VisibleOutsideFile)) { + Scope = AccessibleScope::FileScope; + } } void SymbolRelevanceSignals::merge(const CodeCompletionResult &SemaCCResult) { @@ -365,7 +365,7 @@ float SymbolRelevanceSignals::evaluate() const { case GlobalScope: break; case FileScope: - Score *= 1.5; + Score *= 1.5f; break; case ClassScope: Score *= 2; @@ -374,6 +374,19 @@ float SymbolRelevanceSignals::evaluate() const { Score *= 4; break; } + } else { + // For non-completion queries, the wider the scope where a symbol is + // visible, the more likely it is to be relevant. + switch (Scope) { + case GlobalScope: + break; + case FileScope: + Score *= 0.5f; + break; + default: + // TODO: Handle other scopes as we start to use them for index results. + break; + } } if (TypeMatchesPreferred) diff --git a/unittests/clangd/QualityTests.cpp b/unittests/clangd/QualityTests.cpp index 259d296d..5ae6dd57 100644 --- a/unittests/clangd/QualityTests.cpp +++ b/unittests/clangd/QualityTests.cpp @@ -178,6 +178,16 @@ TEST(QualityTests, SymbolRelevanceSignalExtraction) { BaseMember.InBaseClass = true; Relevance.merge(BaseMember); EXPECT_TRUE(Relevance.InBaseClass); + + auto Index = Test.index(); + Symbol X; + FuzzyFindRequest Req; + Req.Query = "X"; + Req.AnyScope = true; + Index->fuzzyFind(Req, [&X](const Symbol& S){ X = S; }); + Relevance = {}; + Relevance.merge(X); + EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope); } // Do the signals move the scores in the direction we expect? @@ -264,7 +274,7 @@ TEST(QualityTests, SymbolRelevanceSignalsSanity) { SymbolRelevanceSignals Scoped; Scoped.Scope = SymbolRelevanceSignals::FileScope; - EXPECT_EQ(Scoped.evaluate(), Default.evaluate()); + EXPECT_LT(Scoped.evaluate(), Default.evaluate()); Scoped.Query = SymbolRelevanceSignals::CodeComplete; EXPECT_GT(Scoped.evaluate(), Default.evaluate()); -- cgit v1.2.3 From ece24a8e592e161d15db90f69f1f1db33baec73a Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 15:05:11 +0000 Subject: [clangd] Lib to compute and represent selection under cursor. Summary: The primary problem this solves is to expose the codeAction selection to AST-based refactorings in a way that makes it easy and efficient for them to bind to the right parts of the AST. It should also allow us to make XRefs based features (textDocument/definition) more robust, more easily implement textDocument/typeDefinition etc. As an example, template parameter references can be identified without special handling. There should be slight speedup too: we can prune most of the AST traversal in most cases. Elephant in the room: this is similar-but-different to Tooling/Refactoring/ASTSelection. That captures a smaller set of AST nodes, has a slightly different way of representing selections, and generally has mare features and does more work. The overall shape is pretty similar, and yet I can't quite get to behave as I expect. Reviewers: ilya-biryukov, kadircet Subscribers: mgorny, ioeric, MaskRay, jkorous, mgrang, arphaman Tags: #clang Differential Revision: https://reviews.llvm.org/D57562 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352874 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 1 + clangd/Selection.cpp | 301 ++++++++++++++++++++++++++++++++++++ clangd/Selection.h | 123 +++++++++++++++ unittests/clangd/CMakeLists.txt | 1 + unittests/clangd/SelectionTests.cpp | 244 +++++++++++++++++++++++++++++ 5 files changed, 670 insertions(+) create mode 100644 clangd/Selection.cpp create mode 100644 clangd/Selection.h create mode 100644 unittests/clangd/SelectionTests.cpp diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index 24954f04..6db78920 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -46,6 +46,7 @@ add_clang_library(clangDaemon Protocol.cpp Quality.cpp RIFF.cpp + Selection.cpp SourceCode.cpp Threading.cpp Trace.cpp diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp new file mode 100644 index 00000000..ada79891 --- /dev/null +++ b/clangd/Selection.cpp @@ -0,0 +1,301 @@ +//===--- Selection.h ------------------------------------------------------===// +// +// 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 "Selection.h" +#include "ClangdUnit.h" +#include "clang/AST/RecursiveASTVisitor.h" + +namespace clang { +namespace clangd { +namespace { +using Node = SelectionTree::Node; +using ast_type_traits::DynTypedNode; + +// We find the selection by visiting written nodes in the AST, looking for nodes +// that intersect with the selected character range. +// +// While traversing, we maintain a parent stack. As nodes pop off the stack, +// we decide whether to keep them or not. To be kept, they must either be +// selected or contain some nodes that are. +// +// For simple cases (not inside macros) we prune subtrees that don't intersect. +class SelectionVisitor : public RecursiveASTVisitor { +public: + // Runs the visitor to gather selected nodes and their ancestors. + // If there is any selection, the root (TUDecl) is the first node. + static std::deque collect(ASTContext &AST, unsigned Begin, + unsigned End, FileID File) { + SelectionVisitor V(AST, Begin, End, File); + V.TraverseAST(AST); + assert(V.Stack.size() == 1 && "Unpaired push/pop?"); + assert(V.Stack.top() == &V.Nodes.front()); + if (V.Nodes.size() == 1) // TUDecl, but no nodes under it. + V.Nodes.clear(); + return std::move(V.Nodes); + } + + // We traverse all "well-behaved" nodes the same way: + // - push the node onto the stack + // - traverse its children recursively + // - pop it from the stack + // - hit testing: is intersection(node, selection) - union(children) empty? + // - attach it to the tree if it or any children hit the selection + // + // Two categories of nodes are not "well-behaved": + // - those without source range information, we don't record those + // - those that can't be stored in DynTypedNode. + // We're missing some interesting things like Attr due to the latter. + bool TraverseDecl(Decl *X) { + if (isa(X)) + return Base::TraverseDecl(X); // Already pushed by constructor. + return traverseNode(X, [&] { return Base::TraverseDecl(X); }); + } + bool TraverseTypeLoc(TypeLoc X) { + return traverseNode(&X, [&] { return Base::TraverseTypeLoc(X); }); + } + bool TraverseTypeNestedNameSpecifierLoc(NestedNameSpecifierLoc X) { + return traverseNode( + &X, [&] { return Base::TraverseNestedNameSpecifierLoc(X); }); + } + bool TraverseConstructorInitializer(CXXCtorInitializer *X) { + return traverseNode( + X, [&] { return Base::TraverseConstructorInitializer(X); }); + } + // Stmt is the same, but this form allows the data recursion optimization. + bool dataTraverseStmtPre(Stmt *X) { + if (!X || canSafelySkipNode(X->getSourceRange())) + return false; + push(DynTypedNode::create(*X)); + return true; + } + bool dataTraverseStmtPost(Stmt *X) { + pop(); + return true; + } + // Uninteresting parts of the AST that don't have locations within them. + bool TraverseNestedNameSpecifier(NestedNameSpecifier *) { return true; } + bool TraverseType(QualType) { return true; } + +private: + using Base = RecursiveASTVisitor; + SelectionVisitor(ASTContext &AST, unsigned SelBegin, unsigned SelEnd, + FileID SelFile) + : SM(AST.getSourceManager()), LangOpts(AST.getLangOpts()), + SelBegin(SelBegin), SelEnd(SelEnd), SelFile(SelFile), + SelBeginTokenStart(SM.getFileOffset(Lexer::GetBeginningOfToken( + SM.getComposedLoc(SelFile, SelBegin), SM, LangOpts))) { + // Ensure we have a node for the TU decl, regardless of traversal scope. + Nodes.emplace_back(); + Nodes.back().ASTNode = DynTypedNode::create(*AST.getTranslationUnitDecl()); + Nodes.back().Parent = nullptr; + Nodes.back().Selected = SelectionTree::Unselected; + Stack.push(&Nodes.back()); + } + + // Generic case of TraverseFoo. Func should be the call to Base::TraverseFoo. + // Node is always a pointer so the generic code can handle any null checks. + template + bool traverseNode(T *Node, const Func &Body) { + if (Node == nullptr || canSafelySkipNode(Node->getSourceRange())) + return true; + push(DynTypedNode::create(*Node)); + bool Ret = Body(); + pop(); + return Ret; + } + + // An optimization for a common case: nodes outside macro expansions that + // don't intersect the selection may be recursively skipped. + bool canSafelySkipNode(SourceRange S) { + auto B = SM.getDecomposedLoc(S.getBegin()); + auto E = SM.getDecomposedLoc(S.getEnd()); + if (B.first != SelFile || E.first != SelFile) + return false; + return B.second >= SelEnd || E.second < SelBeginTokenStart; + } + + // Pushes a node onto the ancestor stack. Pairs with pop(). + void push(DynTypedNode Node) { + Nodes.emplace_back(); + Nodes.back().ASTNode = std::move(Node); + Nodes.back().Parent = Stack.top(); + Nodes.back().Selected = SelectionTree::Unselected; + Stack.push(&Nodes.back()); + } + + // Pops a node off the ancestor stack, and finalizes it. Pairs with push(). + void pop() { + Node &N = *Stack.top(); + N.Selected = computeSelection(N); + if (N.Selected || !N.Children.empty()) { + // Attach to the tree. + N.Parent->Children.push_back(&N); + } else { + // Neither N any children are selected, it doesn't belong in the tree. + assert(&N == &Nodes.back()); + Nodes.pop_back(); + } + Stack.pop(); + } + + // Perform hit-testing of a complete Node against the selection. + // This runs for every node in the AST, and must be fast in common cases. + // This is called from pop(), so we can take children into account. + SelectionTree::Selection computeSelection(const Node &N) { + SourceRange S = N.ASTNode.getSourceRange(); + if (!S.isValid()) + return SelectionTree::Unselected; + // getTopMacroCallerLoc() allows selection of constructs in macro args. e.g: + // #define LOOP_FOREVER(Body) for(;;) { Body } + // void IncrementLots(int &x) { + // LOOP_FOREVER( ++x; ) + // } + // Selecting "++x" or "x" will do the right thing. + auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin())); + auto E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd())); + // Otherwise, nodes in macro expansions can't be selected. + if (B.first != SelFile || E.first != SelFile) + return SelectionTree::Unselected; + // Cheap test: is there any overlap at all between the selection and range? + // Note that E.second is the *start* of the last token, which is why we + // compare against the "rounded-down" SelBegin. + if (B.second >= SelEnd || E.second < SelBeginTokenStart) + return SelectionTree::Unselected; + + // We hit something, need some more precise checks. + // Adjust [B, E) to be a half-open character range. + E.second += Lexer::MeasureTokenLength(S.getEnd(), SM, LangOpts); + // This node's own selected text is (this range ^ selection) - child ranges. + // If that's empty, then we've only collided with children. + if (nodesCoverRange(N.Children, std::max(SelBegin, B.second), + std::min(SelEnd, E.second))) + return SelectionTree::Unselected; // Hit children only. + // Some of our own characters are covered, this is a true hit. + return (B.second >= SelBegin && E.second <= SelEnd) + ? SelectionTree::Complete + : SelectionTree::Partial; + } + + // Is the range [Begin, End) entirely covered by the union of the Nodes? + // (The range is a parent node's extent, and the covering nodes are children). + bool nodesCoverRange(llvm::ArrayRef Nodes, unsigned Begin, + unsigned End) { + if (Begin >= End) + return true; + if (Nodes.empty()) + return false; + + // Collect all the expansion ranges, as offsets. + SmallVector, 8> ChildRanges; + for (const Node *N : Nodes) { + CharSourceRange R = SM.getExpansionRange(N->ASTNode.getSourceRange()); + auto B = SM.getDecomposedLoc(R.getBegin()); + auto E = SM.getDecomposedLoc(R.getEnd()); + if (B.first != SelFile || E.first != SelFile) + continue; + assert(R.isTokenRange()); + // Try to cover up to the next token, spaces between children don't count. + if (auto Tok = Lexer::findNextToken(R.getEnd(), SM, LangOpts)) + E.second = SM.getFileOffset(Tok->getLocation()); + else + E.second += Lexer::MeasureTokenLength(R.getEnd(), SM, LangOpts); + ChildRanges.push_back({B.second, E.second}); + } + llvm::sort(ChildRanges); + + // Scan through the child ranges, removing as we go. + for (const auto R : ChildRanges) { + if (R.first > Begin) + return false; // [Begin, R.first) is not covered. + Begin = R.second; // Eliminate [R.first, R.second). + if (Begin >= End) + return true; // Remaining range is empty. + } + return false; // Went through all children, trailing characters remain. + } + + SourceManager &SM; + const LangOptions &LangOpts; + std::stack Stack; + std::deque Nodes; // Stable pointers as we add more nodes. + // Half-open selection range. + unsigned SelBegin; + unsigned SelEnd; + FileID SelFile; + // If the selection start slices a token in half, the beginning of that token. + // This is useful for checking whether the end of a token range overlaps + // the selection: range.end < SelBeginTokenStart is equivalent to + // range.end + measureToken(range.end) < SelBegin (assuming range.end points + // to a token), and it saves a lex every time. + unsigned SelBeginTokenStart; +}; + +} // namespace + +void SelectionTree::print(llvm::raw_ostream &OS, const SelectionTree::Node &N, + int Indent) const { + if (N.Selected) + OS.indent(Indent - 1) << (N.Selected == SelectionTree::Complete ? '*' + : '.'); + else + OS.indent(Indent); + OS << N.ASTNode.getNodeKind().asStringRef() << " "; + N.ASTNode.print(OS, PrintPolicy); + OS << "\n"; + for (const Node *Child : N.Children) + print(OS, *Child, Indent + 2); +} + +// Decide which selection emulates a "point" query in between characters. +static std::pair pointBounds(unsigned Offset, FileID FID, + ASTContext &AST) { + StringRef Buf = AST.getSourceManager().getBufferData(FID); + // Edge-cases where the choice is forced. + if (Buf.size() == 0) + return {0, 0}; + if (Offset == 0) + return {0, 1}; + if (Offset == Buf.size()) + return {Offset - 1, Offset}; + // We could choose either this byte or the previous. Usually we prefer the + // character on the right of the cursor (or under a block cursor). + // But if that's whitespace, we likely want the token on the left. + if (isWhitespace(Buf[Offset]) && !isWhitespace(Buf[Offset - 1])) + return {Offset - 1, Offset}; + return {Offset, Offset + 1}; +} + +SelectionTree::SelectionTree(ASTContext &AST, unsigned Begin, unsigned End) + : PrintPolicy(AST.getLangOpts()) { + // No fundamental reason the selection needs to be in the main file, + // but that's all clangd has needed so far. + FileID FID = AST.getSourceManager().getMainFileID(); + if (Begin == End) + std::tie(Begin, End) = pointBounds(Begin, FID, AST); + PrintPolicy.TerseOutput = true; + + Nodes = SelectionVisitor::collect(AST, Begin, End, FID); + Root = Nodes.empty() ? nullptr : &Nodes.front(); +} + +SelectionTree::SelectionTree(ASTContext &AST, unsigned Offset) + : SelectionTree(AST, Offset, Offset) {} + +const Node *SelectionTree::commonAncestor() const { + if (!Root) + return nullptr; + for (const Node *Ancestor = Root;; Ancestor = Ancestor->Children.front()) { + if (Ancestor->Selected || Ancestor->Children.size() > 1) + return Ancestor; + // The tree only contains ancestors of the interesting nodes. + assert(!Ancestor->Children.empty() && "bad node in selection tree"); + } +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/Selection.h b/clangd/Selection.h new file mode 100644 index 00000000..c7cee64a --- /dev/null +++ b/clangd/Selection.h @@ -0,0 +1,123 @@ +//===--- Selection.h - What's under the cursor? -------------------*-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 +// +//===----------------------------------------------------------------------===// +// Many features are triggered at locations/ranges and operate on AST nodes. +// (e.g. go-to-definition or code tweaks). +// At a high level, such features need to work out which node is the correct +// target. +// +// There are a few levels of ambiguity here: +// +// Which tokens are included: +// int x = one + two; // what should "go to definition" do? +// ^^^^^^ +// +// Same token means multiple things: +// string("foo") // class string, or a constructor? +// ^ +// +// Which level of the AST is interesting? +// if (err) { // reference to 'err', or operator bool(), +// ^ // or the if statement itself? +// +// Here we build and expose a data structure that allows features to resolve +// these ambiguities in an appropriate way: +// - we determine which low-level nodes are partly or completely covered +// by the selection. +// - we expose a tree of the selected nodes and their lexical parents. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_SELECTION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_SELECTION_H +#include "clang/AST/ASTTypeTraits.h" +#include "clang/AST/PrettyPrinter.h" +#include "llvm/ADT/SmallVector.h" + +namespace clang { +namespace clangd { +class ParsedAST; + +// A selection can partially or completely cover several AST nodes. +// The SelectionTree contains nodes that are covered, and their parents. +// SelectionTree does not contain all AST nodes, rather only: +// Decl, Stmt, TypeLoc, NestedNamespaceSpecifierLoc, CXXCtorInitializer. +// (These are the nodes with source ranges that fit in DynTypedNode). +// +// Usually commonAncestor() is the place to start: +// - it's the simplest answer to "what node is under the cursor" +// - the selected Expr (for example) can be found by walking up the parent +// chain and checking Node->ASTNode. +// - if you want to traverse the selected nodes, they are all under +// commonAncestor() in the tree. +// +// The SelectionTree owns the Node structures, but the ASTNode attributes +// point back into the AST it was constructed with. +class SelectionTree { +public: + // Creates a selection tree at the given byte offset in the main file. + // This is approximately equivalent to a range of one character. + // (Usually, the character to the right of Offset, sometimes to the left). + SelectionTree(ASTContext &AST, unsigned Offset); + // Creates a selection tree for the given range in the main file. + // The range includes bytes [Start, End). + // If Start == End, uses the same heuristics as SelectionTree(AST, Start). + SelectionTree(ASTContext &AST, unsigned Start, unsigned End); + + // Describes to what extent an AST node is covered by the selection. + enum Selection { + // The AST node owns no characters covered by the selection. + // Note that characters owned by children don't count: + // if (x == 0) scream(); + // ^^^^^^ + // The IfStmt would be Unselected because all the selected characters are + // associated with its children. + // (Invisible nodes like ImplicitCastExpr are always unselected). + Unselected, + // The AST node owns selected characters, but is not completely covered. + Partial, + // The AST node owns characters, and is covered by the selection. + Complete, + }; + // An AST node that is implicated in the selection. + // (Either selected directly, or some descendant is selected). + struct Node { + // The parent within the selection tree. nullptr for TranslationUnitDecl. + Node *Parent; + // Direct children within the selection tree. + llvm::SmallVector Children; + // The corresponding node from the full AST. + ast_type_traits::DynTypedNode ASTNode; + // The extent to which this node is covered by the selection. + Selection Selected; + }; + + // The most specific common ancestor of all the selected nodes. + // If there is no selection, this is nullptr. + const Node *commonAncestor() const; + // The selection node corresponding to TranslationUnitDecl. + // If there is no selection, this is nullptr. + const Node *root() const { return Root; } + +private: + std::deque Nodes; // Stable-pointer storage. + const Node *Root; + clang::PrintingPolicy PrintPolicy; + + void print(llvm::raw_ostream &OS, const Node &N, int Indent) const; + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, + const SelectionTree &T) { + if (auto R = T.root()) + T.print(OS, *R, 0); + else + OS << "(empty selection)\n"; + return OS; + } +}; + +} // namespace clangd +} // namespace clang +#endif diff --git a/unittests/clangd/CMakeLists.txt b/unittests/clangd/CMakeLists.txt index aebab1fe..deae9ceb 100644 --- a/unittests/clangd/CMakeLists.txt +++ b/unittests/clangd/CMakeLists.txt @@ -34,6 +34,7 @@ add_extra_unittest(ClangdTests JSONTransportTests.cpp QualityTests.cpp RIFFTests.cpp + SelectionTests.cpp SerializationTests.cpp SourceCodeTests.cpp SymbolCollectorTests.cpp diff --git a/unittests/clangd/SelectionTests.cpp b/unittests/clangd/SelectionTests.cpp new file mode 100644 index 00000000..6cfee5d2 --- /dev/null +++ b/unittests/clangd/SelectionTests.cpp @@ -0,0 +1,244 @@ +//===-- RIFFTests.cpp - Binary container unit tests -----------------------===// +// +// 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 "Annotations.h" +#include "Selection.h" +#include "SourceCode.h" +#include "TestTU.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace { +using ::testing::UnorderedElementsAreArray; + +SelectionTree makeSelectionTree(const StringRef MarkedCode, ParsedAST &AST) { + Annotations Test(MarkedCode); + switch (Test.points().size()) { + case 1: // Point selection. + return SelectionTree(AST.getASTContext(), + cantFail(positionToOffset(Test.code(), Test.point()))); + case 2: // Range selection. + return SelectionTree( + AST.getASTContext(), + cantFail(positionToOffset(Test.code(), Test.points()[0])), + cantFail(positionToOffset(Test.code(), Test.points()[1]))); + default: + ADD_FAILURE() << "Expected 1-2 points for selection.\n" << MarkedCode; + return SelectionTree(AST.getASTContext(), 0u, 0u); + } +} + +Range nodeRange(const SelectionTree::Node *N, ParsedAST &AST) { + if (!N) + return Range{}; + SourceManager &SM = AST.getASTContext().getSourceManager(); + StringRef Buffer = SM.getBufferData(SM.getMainFileID()); + SourceRange SR = N->ASTNode.getSourceRange(); + SR.setBegin(SM.getFileLoc(SR.getBegin())); + SR.setEnd(SM.getFileLoc(SR.getEnd())); + CharSourceRange R = + Lexer::getAsCharRange(SR, SM, AST.getASTContext().getLangOpts()); + return Range{offsetToPosition(Buffer, SM.getFileOffset(R.getBegin())), + offsetToPosition(Buffer, SM.getFileOffset(R.getEnd()) + 1)}; +} + +std::string nodeKind(const SelectionTree::Node *N) { + if (!N) + return ""; + return N->ASTNode.getNodeKind().asStringRef().str(); +} + +std::vector allNodes(const SelectionTree &T) { + std::vector Result = {T.root()}; + for (unsigned I = 0; I < Result.size(); ++I) { + const SelectionTree::Node *N = Result[I]; + Result.insert(Result.end(), N->Children.begin(), N->Children.end()); + } + return Result; +} + +// Returns true if Common is a descendent of Root. +// Verifies nothing is selected above Common. +bool verifyCommonAncestor(const SelectionTree::Node *Root, + const SelectionTree::Node *Common, + StringRef MarkedCode) { + if (Root == Common) + return true; + if (Root->Selected) + ADD_FAILURE() << "Selected nodes outside common ancestor\n" << MarkedCode; + bool Seen = false; + for (const SelectionTree::Node *Child : Root->Children) + if (verifyCommonAncestor(Child, Common, MarkedCode)) { + if (Seen) + ADD_FAILURE() << "Saw common ancestor twice\n" << MarkedCode; + Seen = true; + } + return Seen; +} + +TEST(SelectionTest, CommonAncestor) { + struct Case { + // Selection is between ^marks^. + // common ancestor marked with a [[range]]. + const char *Code; + const char *CommonAncestorKind; + }; + Case Cases[] = { + { + R"cpp( + struct AAA { struct BBB { static int ccc(); };}; + int x = AAA::[[B^B^B]]::ccc(); + )cpp", + "TypeLoc", + }, + { + R"cpp( + struct AAA { struct BBB { static int ccc(); };}; + int x = AAA::[[B^BB^]]::ccc(); + )cpp", + "TypeLoc", + }, + { + R"cpp( + struct AAA { struct BBB { static int ccc(); };}; + int x = [[AAA::BBB::c^c^c]](); + )cpp", + "DeclRefExpr", + }, + { + R"cpp( + struct AAA { struct BBB { static int ccc(); };}; + int x = [[AAA::BBB::cc^c(^)]]; + )cpp", + "CallExpr", + }, + + { + R"cpp( + void foo() { [[if (1^11) { return; } else {^ }]] } + )cpp", + "IfStmt", + }, + { + R"cpp( + void foo(); + #define CALL_FUNCTION(X) X() + void bar() { CALL_FUNCTION([[f^o^o]]); } + )cpp", + "DeclRefExpr", + }, + { + R"cpp( + void foo(); + #define CALL_FUNCTION(X) X() + void bar() { CALL_FUNC^TION([[fo^o]]); } + )cpp", + "DeclRefExpr", + }, + { + R"cpp( + void foo(); + #define CALL_FUNCTION(X) X() + void bar() [[{ C^ALL_FUNC^TION(foo); }]] + )cpp", + "CompoundStmt", + }, + { + R"cpp( + void foo(); + #define CALL_FUNCTION(X) X^()^ + void bar() { CALL_FUNCTION(foo); } + )cpp", + nullptr, + }, + + // Point selections. + {"void foo() { [[^foo]](); }", "DeclRefExpr"}, + {"void foo() { [[f^oo]](); }", "DeclRefExpr"}, + {"void foo() { [[fo^o]](); }", "DeclRefExpr"}, + {"void foo() { [[foo^()]]; }", "CallExpr"}, + {"void foo() { [[foo^]] (); }", "DeclRefExpr"}, + {"int bar; void foo() [[{ foo (); }]]^", "CompoundStmt"}, + {"[[^void]] foo();", "TypeLoc"}, + {"^", nullptr}, + {"void foo() { [[foo^^]] (); }", "DeclRefExpr"}, + + // FIXME: Ideally we'd get a declstmt or the VarDecl itself here. + // This doesn't happen now; the RAV doesn't traverse a node containing ;. + {"int x = 42;^", nullptr}, + {"int x = 42^;", nullptr}, + + // Node types that have caused problems in the past. + {"template void foo() { [[^T]] t; }", "TypeLoc"}, + }; + for (const Case &C : Cases) { + Annotations Test(C.Code); + auto AST = TestTU::withCode(Test.code()).build(); + auto T = makeSelectionTree(C.Code, AST); + + if (Test.ranges().empty()) { + // If no [[range]] is marked in the example, there should be no selection. + EXPECT_FALSE(T.commonAncestor()) << C.Code << "\n" << T; + EXPECT_FALSE(T.root()) << C.Code << "\n" << T; + } else { + // If there is an expected selection, both common ancestor and root + // should exist with the appropriate node types in them. + EXPECT_EQ(C.CommonAncestorKind, nodeKind(T.commonAncestor())) + << C.Code << "\n" + << T; + EXPECT_EQ("TranslationUnitDecl", nodeKind(T.root())) << C.Code; + // Convert the reported common ancestor to a range and verify it. + EXPECT_EQ(nodeRange(T.commonAncestor(), AST), Test.range()) + << C.Code << "\n" + << T; + + // Check that common ancestor is reachable on exactly one path from root, + // and no nodes outside it are selected. + EXPECT_TRUE(verifyCommonAncestor(T.root(), T.commonAncestor(), C.Code)) + << C.Code; + } + } +} + +TEST(SelectionTest, Selected) { + // Selection with ^marks^. + // Partially selected nodes marked with a [[range]]. + // Completely selected nodes marked with a $C[[range]]. + const char *Cases[] = { + R"cpp( int abc, xyz = [[^ab^c]]; )cpp", + R"cpp( int abc, xyz = [[a^bc^]]; )cpp", + R"cpp( int abc, xyz = $C[[^abc^]]; )cpp", + R"cpp( + void foo() { + [[if ([[1^11]]) $C[[{ + $C[[return]]; + }]] else [[{^ + }]]]] + } + )cpp", + }; + for (const char *C : Cases) { + Annotations Test(C); + auto AST = TestTU::withCode(Test.code()).build(); + auto T = makeSelectionTree(C, AST); + + std::vector Complete, Partial; + for (const SelectionTree::Node *N : allNodes(T)) + if (N->Selected == SelectionTree::Complete) + Complete.push_back(nodeRange(N, AST)); + else if (N->Selected == SelectionTree::Partial) + Partial.push_back(nodeRange(N, AST)); + EXPECT_THAT(Complete, UnorderedElementsAreArray(Test.ranges("C"))) << C; + EXPECT_THAT(Partial, UnorderedElementsAreArray(Test.ranges())) << C; + } +} + +} // namespace +} // namespace clangd +} // namespace clang -- cgit v1.2.3 From c82e996bf1ac74dc7f146230fa47ca726ef3698b Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 15:09:41 +0000 Subject: [clangd] Lib to compute and represent selection under cursor. Summary: The primary problem this solves is to expose the codeAction selection to AST-based refactorings in a way that makes it easy and efficient for them to bind to the right parts of the AST. It should also allow us to make XRefs based features (textDocument/definition) more robust, more easily implement textDocument/typeDefinition etc. As an example, template parameter references can be identified without special handling. There should be slight speedup too: we can prune most of the AST traversal in most cases. Elephant in the room: this is similar-but-different to Tooling/Refactoring/ASTSelection. That captures a smaller set of AST nodes, has a slightly different way of representing selections, and generally has mare features and does more work. The overall shape is pretty similar, and yet I can't quite get to behave as I expect. Reviewers: ilya-biryukov, kadircet Subscribers: mgorny, ioeric, MaskRay, jkorous, mgrang, arphaman Tags: #clang Differential Revision: https://reviews.llvm.org/D57562 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352875 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Selection.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp index ada79891..41182a8f 100644 --- a/clangd/Selection.cpp +++ b/clangd/Selection.cpp @@ -112,9 +112,15 @@ private: // An optimization for a common case: nodes outside macro expansions that // don't intersect the selection may be recursively skipped. bool canSafelySkipNode(SourceRange S) { +<<<<<<< HEAD auto B = SM.getDecomposedLoc(S.getBegin()); auto E = SM.getDecomposedLoc(S.getEnd()); if (B.first != SelFile || E.first != SelFile) +======= + auto B = SM.getDecomposedLoc(S.getBegin()), + E = SM.getDecomposedLoc(S.getEnd()); + if (B.first != SM.getMainFileID() || E.first != SM.getMainFileID()) +>>>>>>> [clangd] Lib to compute and represent selection under cursor. return false; return B.second >= SelEnd || E.second < SelBeginTokenStart; } @@ -156,6 +162,7 @@ private: // LOOP_FOREVER( ++x; ) // } // Selecting "++x" or "x" will do the right thing. +<<<<<<< HEAD auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin())); auto E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd())); // Otherwise, nodes in macro expansions can't be selected. @@ -164,6 +171,16 @@ private: // Cheap test: is there any overlap at all between the selection and range? // Note that E.second is the *start* of the last token, which is why we // compare against the "rounded-down" SelBegin. +======= + auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin())), + E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd())); + // Otherwise, nodes in macro expansions can't be selected. + if (B.first != SM.getMainFileID() || E.first != SM.getMainFileID()) + return SelectionTree::Unselected; + // Cheap test: is there any overlap at all between the selection and range? + // Note that E.second is the *start* of the last token, which is why we + // compare against the "rounded-down" MinOffset. +>>>>>>> [clangd] Lib to compute and represent selection under cursor. if (B.second >= SelEnd || E.second < SelBeginTokenStart) return SelectionTree::Unselected; @@ -196,7 +213,11 @@ private: CharSourceRange R = SM.getExpansionRange(N->ASTNode.getSourceRange()); auto B = SM.getDecomposedLoc(R.getBegin()); auto E = SM.getDecomposedLoc(R.getEnd()); +<<<<<<< HEAD if (B.first != SelFile || E.first != SelFile) +======= + if (B.first != SM.getMainFileID() || E.first != SM.getMainFileID()) +>>>>>>> [clangd] Lib to compute and represent selection under cursor. continue; assert(R.isTokenRange()); // Try to cover up to the next token, spaces between children don't count. @@ -222,6 +243,7 @@ private: SourceManager &SM; const LangOptions &LangOpts; std::stack Stack; +<<<<<<< HEAD std::deque Nodes; // Stable pointers as we add more nodes. // Half-open selection range. unsigned SelBegin; @@ -233,6 +255,10 @@ private: // range.end + measureToken(range.end) < SelBegin (assuming range.end points // to a token), and it saves a lex every time. unsigned SelBeginTokenStart; +======= + std::deque Nodes; + unsigned SelBegin, SelEnd, SelBeginTokenStart; +>>>>>>> [clangd] Lib to compute and represent selection under cursor. }; } // namespace @@ -252,9 +278,16 @@ void SelectionTree::print(llvm::raw_ostream &OS, const SelectionTree::Node &N, } // Decide which selection emulates a "point" query in between characters. +<<<<<<< HEAD static std::pair pointBounds(unsigned Offset, FileID FID, ASTContext &AST) { StringRef Buf = AST.getSourceManager().getBufferData(FID); +======= +static std::pair pointBounds(unsigned Offset, + ASTContext &AST) { + StringRef Buf = AST.getSourceManager().getBufferData( + AST.getSourceManager().getMainFileID()); +>>>>>>> [clangd] Lib to compute and represent selection under cursor. // Edge-cases where the choice is forced. if (Buf.size() == 0) return {0, 0}; @@ -272,6 +305,7 @@ static std::pair pointBounds(unsigned Offset, FileID FID, SelectionTree::SelectionTree(ASTContext &AST, unsigned Begin, unsigned End) : PrintPolicy(AST.getLangOpts()) { +<<<<<<< HEAD // No fundamental reason the selection needs to be in the main file, // but that's all clangd has needed so far. FileID FID = AST.getSourceManager().getMainFileID(); @@ -286,6 +320,16 @@ SelectionTree::SelectionTree(ASTContext &AST, unsigned Begin, unsigned End) SelectionTree::SelectionTree(ASTContext &AST, unsigned Offset) : SelectionTree(AST, Offset, Offset) {} +======= + if (Begin == End) + std::tie(Begin, End) = pointBounds(Begin, AST); + PrintPolicy.TerseOutput = true; + + Nodes = SelectionVisitor(AST, Begin, End).take(); + Root = Nodes.empty() ? nullptr : &Nodes.front(); +} + +>>>>>>> [clangd] Lib to compute and represent selection under cursor. const Node *SelectionTree::commonAncestor() const { if (!Root) return nullptr; @@ -297,5 +341,11 @@ const Node *SelectionTree::commonAncestor() const { } } +<<<<<<< HEAD +======= +SelectionTree::SelectionTree(ASTContext &AST, unsigned Offset) + : SelectionTree(AST, Offset, Offset) {} + +>>>>>>> [clangd] Lib to compute and represent selection under cursor. } // namespace clangd } // namespace clang -- cgit v1.2.3 From 3531ea17aee51e2b7fc38e477204d33ae6660ba1 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 1 Feb 2019 15:09:47 +0000 Subject: [clangd] Expose SelectionTree to code tweaks, and use it for swap if branches. Summary: This reduces the per-check implementation burden and redundant work. It also makes checks range-aware by default (treating the commonAncestor as if it were a point selection should be good baseline behavior). Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet Tags: #clang Differential Revision: https://reviews.llvm.org/D57570 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352876 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdServer.cpp | 41 +++++++++++------------ clangd/Selection.cpp | 50 ---------------------------- clangd/refactor/Tweak.cpp | 8 +++++ clangd/refactor/Tweak.h | 7 ++-- clangd/refactor/tweaks/SwapIfBranches.cpp | 55 +++++++------------------------ unittests/clangd/TweakTests.cpp | 47 ++++++++++++++++++++++---- 6 files changed, 84 insertions(+), 124 deletions(-) diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index a677c49a..595e0758 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -328,23 +328,28 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName, "Rename", File, Bind(Action, File.str(), NewName.str(), std::move(CB))); } +static llvm::Expected +tweakSelection(const Range &Sel, const InputsAndAST &AST) { + auto Begin = positionToOffset(AST.Inputs.Contents, Sel.start); + if (!Begin) + return Begin.takeError(); + auto End = positionToOffset(AST.Inputs.Contents, Sel.end); + if (!End) + return End.takeError(); + return Tweak::Selection(AST.AST, *Begin, *End); +} + void ClangdServer::enumerateTweaks(PathRef File, Range Sel, Callback> CB) { auto Action = [Sel](decltype(CB) CB, std::string File, Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); - - auto &AST = InpAST->AST; - auto CursorLoc = sourceLocationInMainFile( - AST.getASTContext().getSourceManager(), Sel.start); - if (!CursorLoc) - return CB(CursorLoc.takeError()); - Tweak::Selection Inputs = {InpAST->Inputs.Contents, InpAST->AST, - *CursorLoc}; - + auto Selection = tweakSelection(Sel, *InpAST); + if (!Selection) + return CB(Selection.takeError()); std::vector Res; - for (auto &T : prepareTweaks(Inputs)) + for (auto &T : prepareTweaks(*Selection)) Res.push_back({T->id(), T->title()}); CB(std::move(Res)); }; @@ -359,20 +364,14 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); - - auto &AST = InpAST->AST; - auto CursorLoc = sourceLocationInMainFile( - AST.getASTContext().getSourceManager(), Sel.start); - if (!CursorLoc) - return CB(CursorLoc.takeError()); - Tweak::Selection Inputs = {InpAST->Inputs.Contents, InpAST->AST, - *CursorLoc}; - - auto A = prepareTweak(TweakID, Inputs); + auto Selection = tweakSelection(Sel, *InpAST); + if (!Selection) + return CB(Selection.takeError()); + auto A = prepareTweak(TweakID, *Selection); if (!A) return CB(A.takeError()); // FIXME: run formatter on top of resulting replacements. - return CB((*A)->apply(Inputs)); + return CB((*A)->apply(*Selection)); }; WorkScheduler.runWithAST( "ApplyTweak", File, diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp index 41182a8f..ada79891 100644 --- a/clangd/Selection.cpp +++ b/clangd/Selection.cpp @@ -112,15 +112,9 @@ private: // An optimization for a common case: nodes outside macro expansions that // don't intersect the selection may be recursively skipped. bool canSafelySkipNode(SourceRange S) { -<<<<<<< HEAD auto B = SM.getDecomposedLoc(S.getBegin()); auto E = SM.getDecomposedLoc(S.getEnd()); if (B.first != SelFile || E.first != SelFile) -======= - auto B = SM.getDecomposedLoc(S.getBegin()), - E = SM.getDecomposedLoc(S.getEnd()); - if (B.first != SM.getMainFileID() || E.first != SM.getMainFileID()) ->>>>>>> [clangd] Lib to compute and represent selection under cursor. return false; return B.second >= SelEnd || E.second < SelBeginTokenStart; } @@ -162,7 +156,6 @@ private: // LOOP_FOREVER( ++x; ) // } // Selecting "++x" or "x" will do the right thing. -<<<<<<< HEAD auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin())); auto E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd())); // Otherwise, nodes in macro expansions can't be selected. @@ -171,16 +164,6 @@ private: // Cheap test: is there any overlap at all between the selection and range? // Note that E.second is the *start* of the last token, which is why we // compare against the "rounded-down" SelBegin. -======= - auto B = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getBegin())), - E = SM.getDecomposedLoc(SM.getTopMacroCallerLoc(S.getEnd())); - // Otherwise, nodes in macro expansions can't be selected. - if (B.first != SM.getMainFileID() || E.first != SM.getMainFileID()) - return SelectionTree::Unselected; - // Cheap test: is there any overlap at all between the selection and range? - // Note that E.second is the *start* of the last token, which is why we - // compare against the "rounded-down" MinOffset. ->>>>>>> [clangd] Lib to compute and represent selection under cursor. if (B.second >= SelEnd || E.second < SelBeginTokenStart) return SelectionTree::Unselected; @@ -213,11 +196,7 @@ private: CharSourceRange R = SM.getExpansionRange(N->ASTNode.getSourceRange()); auto B = SM.getDecomposedLoc(R.getBegin()); auto E = SM.getDecomposedLoc(R.getEnd()); -<<<<<<< HEAD if (B.first != SelFile || E.first != SelFile) -======= - if (B.first != SM.getMainFileID() || E.first != SM.getMainFileID()) ->>>>>>> [clangd] Lib to compute and represent selection under cursor. continue; assert(R.isTokenRange()); // Try to cover up to the next token, spaces between children don't count. @@ -243,7 +222,6 @@ private: SourceManager &SM; const LangOptions &LangOpts; std::stack Stack; -<<<<<<< HEAD std::deque Nodes; // Stable pointers as we add more nodes. // Half-open selection range. unsigned SelBegin; @@ -255,10 +233,6 @@ private: // range.end + measureToken(range.end) < SelBegin (assuming range.end points // to a token), and it saves a lex every time. unsigned SelBeginTokenStart; -======= - std::deque Nodes; - unsigned SelBegin, SelEnd, SelBeginTokenStart; ->>>>>>> [clangd] Lib to compute and represent selection under cursor. }; } // namespace @@ -278,16 +252,9 @@ void SelectionTree::print(llvm::raw_ostream &OS, const SelectionTree::Node &N, } // Decide which selection emulates a "point" query in between characters. -<<<<<<< HEAD static std::pair pointBounds(unsigned Offset, FileID FID, ASTContext &AST) { StringRef Buf = AST.getSourceManager().getBufferData(FID); -======= -static std::pair pointBounds(unsigned Offset, - ASTContext &AST) { - StringRef Buf = AST.getSourceManager().getBufferData( - AST.getSourceManager().getMainFileID()); ->>>>>>> [clangd] Lib to compute and represent selection under cursor. // Edge-cases where the choice is forced. if (Buf.size() == 0) return {0, 0}; @@ -305,7 +272,6 @@ static std::pair pointBounds(unsigned Offset, SelectionTree::SelectionTree(ASTContext &AST, unsigned Begin, unsigned End) : PrintPolicy(AST.getLangOpts()) { -<<<<<<< HEAD // No fundamental reason the selection needs to be in the main file, // but that's all clangd has needed so far. FileID FID = AST.getSourceManager().getMainFileID(); @@ -320,16 +286,6 @@ SelectionTree::SelectionTree(ASTContext &AST, unsigned Begin, unsigned End) SelectionTree::SelectionTree(ASTContext &AST, unsigned Offset) : SelectionTree(AST, Offset, Offset) {} -======= - if (Begin == End) - std::tie(Begin, End) = pointBounds(Begin, AST); - PrintPolicy.TerseOutput = true; - - Nodes = SelectionVisitor(AST, Begin, End).take(); - Root = Nodes.empty() ? nullptr : &Nodes.front(); -} - ->>>>>>> [clangd] Lib to compute and represent selection under cursor. const Node *SelectionTree::commonAncestor() const { if (!Root) return nullptr; @@ -341,11 +297,5 @@ const Node *SelectionTree::commonAncestor() const { } } -<<<<<<< HEAD -======= -SelectionTree::SelectionTree(ASTContext &AST, unsigned Offset) - : SelectionTree(AST, Offset, Offset) {} - ->>>>>>> [clangd] Lib to compute and represent selection under cursor. } // namespace clangd } // namespace clang diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp index 02a22442..34634e64 100644 --- a/clangd/refactor/Tweak.cpp +++ b/clangd/refactor/Tweak.cpp @@ -38,6 +38,14 @@ void validateRegistry() { } } // namespace +Tweak::Selection::Selection(ParsedAST &AST, unsigned RangeBegin, + unsigned RangeEnd) + : AST(AST), ASTSelection(AST.getASTContext(), RangeBegin, RangeEnd) { + auto &SM = AST.getASTContext().getSourceManager(); + Code = SM.getBufferData(SM.getMainFileID()); + Cursor = SM.getComposedLoc(SM.getMainFileID(), RangeBegin); +} + std::vector> prepareTweaks(const Tweak::Selection &S) { validateRegistry(); diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h index abd4995e..94164bc7 100644 --- a/clangd/refactor/Tweak.h +++ b/clangd/refactor/Tweak.h @@ -21,6 +21,7 @@ #include "ClangdUnit.h" #include "Protocol.h" +#include "Selection.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -39,16 +40,16 @@ class Tweak { public: /// Input to prepare and apply tweaks. struct Selection { + Selection(ParsedAST &AST, unsigned RangeBegin, unsigned RangeEnd); /// The text of the active document. llvm::StringRef Code; /// Parsed AST of the active file. ParsedAST &AST; /// A location of the cursor in the editor. SourceLocation Cursor; - // FIXME: add selection when there are checks relying on it. + // The AST nodes that were selected. + SelectionTree ASTSelection; // FIXME: provide a way to get sources and ASTs for other files. - // FIXME: cache some commonly required information (e.g. AST nodes under - // cursor) to avoid redundant AST visit in every action. }; virtual ~Tweak() = default; /// A unique id of the action, it is always equal to the name of the class diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp index 2e0f33af..f28cbe53 100644 --- a/clangd/refactor/tweaks/SwapIfBranches.cpp +++ b/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -41,58 +41,23 @@ public: std::string title() const override; private: - IfStmt *If = nullptr; + const IfStmt *If = nullptr; }; REGISTER_TWEAK(SwapIfBranches); -class FindIfUnderCursor : public RecursiveASTVisitor { -public: - FindIfUnderCursor(ASTContext &Ctx, SourceLocation CursorLoc, IfStmt *&Result) - : Ctx(Ctx), CursorLoc(CursorLoc), Result(Result) {} - - bool VisitIfStmt(IfStmt *If) { - // Check if the cursor is in the range of 'if (cond)'. - // FIXME: this does not contain the closing paren, add it too. - auto R = toHalfOpenFileRange( - Ctx.getSourceManager(), Ctx.getLangOpts(), - SourceRange(If->getIfLoc(), If->getCond()->getEndLoc().isValid() - ? If->getCond()->getEndLoc() - : If->getIfLoc())); - if (R && halfOpenRangeTouches(Ctx.getSourceManager(), *R, CursorLoc)) { - Result = If; - return false; - } - // Check the range of 'else'. - R = toHalfOpenFileRange(Ctx.getSourceManager(), Ctx.getLangOpts(), - SourceRange(If->getElseLoc())); - if (R && halfOpenRangeTouches(Ctx.getSourceManager(), *R, CursorLoc)) { - Result = If; +bool SwapIfBranches::prepare(const Selection &Inputs) { + for (const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor(); + N && !If; N = N->Parent) { + // Stop once we hit a block, e.g. a lambda in the if condition. + if (dyn_cast_or_null(N->ASTNode.get())) return false; - } - - return true; + If = dyn_cast_or_null(N->ASTNode.get()); } - -private: - ASTContext &Ctx; - SourceLocation CursorLoc; - IfStmt *&Result; -}; -} // namespace - -bool SwapIfBranches::prepare(const Selection &Inputs) { - auto &Ctx = Inputs.AST.getASTContext(); - FindIfUnderCursor(Ctx, Inputs.Cursor, If).TraverseAST(Ctx); - if (!If) - return false; - // avoid dealing with single-statement brances, they require careful handling // to avoid changing semantics of the code (i.e. dangling else). - if (!If->getThen() || !llvm::isa(If->getThen()) || - !If->getElse() || !llvm::isa(If->getElse())) - return false; - return true; + return If && dyn_cast_or_null(If->getThen()) && + dyn_cast_or_null(If->getElse()); } Expected SwapIfBranches::apply(const Selection &Inputs) { @@ -128,5 +93,7 @@ Expected SwapIfBranches::apply(const Selection &Inputs) { } std::string SwapIfBranches::title() const { return "Swap if branches"; } + +} // namespace } // namespace clangd } // namespace clang diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp index 905f06b8..f747c991 100644 --- a/unittests/clangd/TweakTests.cpp +++ b/unittests/clangd/TweakTests.cpp @@ -52,9 +52,9 @@ void checkAvailable(StringRef ID, llvm::StringRef Input, bool Available) { ParsedAST AST = TU.build(); auto CheckOver = [&](Range Selection) { - auto CursorLoc = llvm::cantFail(sourceLocationInMainFile( - AST.getASTContext().getSourceManager(), Selection.start)); - auto T = prepareTweak(ID, Tweak::Selection{Code.code(), AST, CursorLoc}); + unsigned Begin = cantFail(positionToOffset(Code.code(), Selection.start)); + unsigned End = cantFail(positionToOffset(Code.code(), Selection.end)); + auto T = prepareTweak(ID, Tweak::Selection(AST, Begin, End)); if (Available) EXPECT_THAT_EXPECTED(T, Succeeded()) << "code is " << markRange(Code.code(), Selection); @@ -92,9 +92,9 @@ llvm::Expected apply(StringRef ID, llvm::StringRef Input) { TU.Code = Code.code(); ParsedAST AST = TU.build(); - auto CursorLoc = llvm::cantFail(sourceLocationInMainFile( - AST.getASTContext().getSourceManager(), SelectionRng.start)); - Tweak::Selection S = {Code.code(), AST, CursorLoc}; + unsigned Begin = cantFail(positionToOffset(Code.code(), SelectionRng.start)); + unsigned End = cantFail(positionToOffset(Code.code(), SelectionRng.end)); + Tweak::Selection S(AST, Begin, End); auto T = prepareTweak(ID, S); if (!T) @@ -149,6 +149,41 @@ TEST(TweakTest, SwapIfBranches) { } )cpp"; checkTransform(ID, Input, Output); + + // Available in subexpressions of the condition. + checkAvailable(ID, R"cpp( + void test() { + if(2 + [[2]] + 2) { return 2 + 2 + 2; } else { continue; } + } + )cpp"); + // But not as part of the branches. + checkNotAvailable(ID, R"cpp( + void test() { + if(2 + 2 + 2) { return 2 + [[2]] + 2; } else { continue; } + } + )cpp"); + // Range covers the "else" token, so available. + checkAvailable(ID, R"cpp( + void test() { + if(2 + 2 + 2) { return 2 + [[2 + 2; } else { continue;]] } + } + )cpp"); + // Not available in compound statements in condition. + checkNotAvailable(ID, R"cpp( + void test() { + if([]{return [[true]];}()) { return 2 + 2 + 2; } else { continue; } + } + )cpp"); + // Not available if both sides aren't braced. + checkNotAvailable(ID, R"cpp( + void test() { + ^if (1) return; else { return; } + } + )cpp"); + // Only one if statement is supported! + checkNotAvailable(ID, R"cpp( + [[if(1){}else{}if(2){}else{}]] + )cpp"); } } // namespace -- cgit v1.2.3 From b5ed3914b4b13626cbbf7fda55e99c88a3c29b27 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Sat, 2 Feb 2019 05:56:00 +0000 Subject: [Clangd] textDocument/definition and textDocument/declaration "bounce" between definition and declaration location when they are distinct. Summary: This helps minimize the disruption of not returning declarations as part of a find-definition response (r352864). Reviewers: hokein Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, ilya-biryukov Tags: #clang Differential Revision: https://reviews.llvm.org/D57580 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352953 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 40 ++++++++++++++++++++++++++++++------- test/clangd/xrefs.test | 49 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 7e7acf94..893d85ab 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -726,18 +726,41 @@ void ClangdLSPServer::onSignatureHelp(const TextDocumentPositionParams &Params, std::move(Reply)); } +// Go to definition has a toggle function: if def and decl are distinct, then +// the first press gives you the def, the second gives you the matching def. +// getToggle() returns the counterpart location that under the cursor. +// +// We return the toggled location alone (ignoring other symbols) to encourage +// editors to "bounce" quickly between locations, without showing a menu. +static Location *getToggle(const TextDocumentPositionParams &Point, + LocatedSymbol &Sym) { + // Toggle only makes sense with two distinct locations. + if (!Sym.Definition || *Sym.Definition == Sym.PreferredDeclaration) + return nullptr; + if (Sym.Definition->uri.file() == Point.textDocument.uri.file() && + Sym.Definition->range.contains(Point.position)) + return &Sym.PreferredDeclaration; + if (Sym.PreferredDeclaration.uri.file() == Point.textDocument.uri.file() && + Sym.PreferredDeclaration.range.contains(Point.position)) + return &*Sym.Definition; + return nullptr; +} + void ClangdLSPServer::onGoToDefinition(const TextDocumentPositionParams &Params, Callback> Reply) { Server->locateSymbolAt( Params.textDocument.uri.file(), Params.position, Bind( - [&](decltype(Reply) Reply, - llvm::Expected> Symbols) { + [&, Params](decltype(Reply) Reply, + llvm::Expected> Symbols) { if (!Symbols) return Reply(Symbols.takeError()); std::vector Defs; - for (const auto &S : *Symbols) + for (auto &S : *Symbols) { + if (Location *Toggle = getToggle(Params, S)) + return Reply(std::vector{std::move(*Toggle)}); Defs.push_back(S.Definition.getValueOr(S.PreferredDeclaration)); + } Reply(std::move(Defs)); }, std::move(Reply))); @@ -749,13 +772,16 @@ void ClangdLSPServer::onGoToDeclaration( Server->locateSymbolAt( Params.textDocument.uri.file(), Params.position, Bind( - [&](decltype(Reply) Reply, - llvm::Expected> Symbols) { + [&, Params](decltype(Reply) Reply, + llvm::Expected> Symbols) { if (!Symbols) return Reply(Symbols.takeError()); std::vector Decls; - for (const auto &S : *Symbols) - Decls.push_back(S.PreferredDeclaration); + for (auto &S : *Symbols) { + if (Location *Toggle = getToggle(Params, S)) + return Reply(std::vector{std::move(*Toggle)}); + Decls.push_back(std::move(S.PreferredDeclaration)); + } Reply(std::move(Decls)); }, std::move(Reply))); diff --git a/test/clangd/xrefs.test b/test/clangd/xrefs.test index 58ca44cb..128c97ff 100644 --- a/test/clangd/xrefs.test +++ b/test/clangd/xrefs.test @@ -1,9 +1,9 @@ # RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s {"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} --- -{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"int x = 0;\nint y = x;"}}} +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"extern int x;\nint x = 0;\nint y = x;"}}} --- -{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}} +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":8}}} # CHECK: "id": 1, # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": [ @@ -11,10 +11,30 @@ # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 5, -# CHECK-NEXT: "line": 0 +# CHECK-NEXT: "line": 1 # CHECK-NEXT: }, # CHECK-NEXT: "start": { # CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file://{{.*}}/{{([A-Z]:/)?}}main.cpp" +# CHECK-NEXT: } +# CHECK-NEXT: ] +--- +# Toggle: we're on the definition, so jump to the declaration. +{"jsonrpc":"2.0","id":1,"method":"textDocument/definition","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":4}}} +# CHECK: "id": 1, +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": [ +# CHECK-NEXT: { +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 12, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 11, # CHECK-NEXT: "line": 0 # CHECK-NEXT: } # CHECK-NEXT: }, @@ -22,7 +42,7 @@ # CHECK-NEXT: } # CHECK-NEXT: ] --- -{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":1,"character":8}}} +{"jsonrpc":"2.0","id":1,"method":"textDocument/documentHighlight","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":8}}} # CHECK: "id": 1 # CHECK-NEXT: "jsonrpc": "2.0", # CHECK-NEXT: "result": [ @@ -30,25 +50,38 @@ # CHECK-NEXT: "kind": 1, # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { -# CHECK-NEXT: "character": 5, +# CHECK-NEXT: "character": 12, # CHECK-NEXT: "line": 0 # CHECK-NEXT: }, # CHECK-NEXT: "start": { -# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "character": 11, # CHECK-NEXT: "line": 0 # CHECK-NEXT: } # CHECK-NEXT: } # CHECK-NEXT: }, # CHECK-NEXT: { +# CHECK-NEXT: "kind": 1, +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 5, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 4, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { # CHECK-NEXT: "kind": 2, # CHECK-NEXT: "range": { # CHECK-NEXT: "end": { # CHECK-NEXT: "character": 9, -# CHECK-NEXT: "line": 1 +# CHECK-NEXT: "line": 2 # CHECK-NEXT: }, # CHECK-NEXT: "start": { # CHECK-NEXT: "character": 8, -# CHECK-NEXT: "line": 1 +# CHECK-NEXT: "line": 2 # CHECK-NEXT: } # CHECK-NEXT: } # CHECK-NEXT: } -- cgit v1.2.3 From 2a24769502cdd179f17d94fd650299bfd0e3d56b Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 2 Feb 2019 10:35:39 +0000 Subject: [clangd] Fix heap-use-after-free after r352868 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352957 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/QualityTests.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/unittests/clangd/QualityTests.cpp b/unittests/clangd/QualityTests.cpp index 5ae6dd57..e2fe8f3a 100644 --- a/unittests/clangd/QualityTests.cpp +++ b/unittests/clangd/QualityTests.cpp @@ -180,14 +180,17 @@ TEST(QualityTests, SymbolRelevanceSignalExtraction) { EXPECT_TRUE(Relevance.InBaseClass); auto Index = Test.index(); - Symbol X; FuzzyFindRequest Req; Req.Query = "X"; Req.AnyScope = true; - Index->fuzzyFind(Req, [&X](const Symbol& S){ X = S; }); - Relevance = {}; - Relevance.merge(X); - EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope); + bool Matched = false; + Index->fuzzyFind(Req, [&](const Symbol &S) { + Matched = true; + Relevance = {}; + Relevance.merge(S); + EXPECT_EQ(Relevance.Scope, SymbolRelevanceSignals::FileScope); + }); + EXPECT_TRUE(Matched); } // Do the signals move the scores in the direction we expect? -- cgit v1.2.3 From d3156cee564b7dfb0c4147656562e30befd259ae Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Sat, 2 Feb 2019 19:57:37 +0000 Subject: [clang-tidy] Rename time lookup functions; NFC git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352964 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/DurationAdditionCheck.cpp | 4 ++-- clang-tidy/abseil/DurationRewriter.cpp | 2 +- clang-tidy/abseil/DurationRewriter.h | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/clang-tidy/abseil/DurationAdditionCheck.cpp b/clang-tidy/abseil/DurationAdditionCheck.cpp index 51b9f577..60047096 100644 --- a/clang-tidy/abseil/DurationAdditionCheck.cpp +++ b/clang-tidy/abseil/DurationAdditionCheck.cpp @@ -22,7 +22,7 @@ void DurationAdditionCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( binaryOperator(hasOperatorName("+"), hasEitherOperand(expr(ignoringParenImpCasts( - callExpr(callee(functionDecl(TimeFactoryFunction()) + callExpr(callee(functionDecl(TimeConversionFunction()) .bind("function_decl"))) .bind("call"))))) .bind("binop"), @@ -43,7 +43,7 @@ void DurationAdditionCheck::check(const MatchFinder::MatchResult &Result) { if (!Scale) return; - llvm::StringRef TimeFactory = getTimeFactoryForScale(*Scale); + llvm::StringRef TimeFactory = getTimeInverseForScale(*Scale); FixItHint Hint; if (Call == Binop->getLHS()->IgnoreParenImpCasts()) { diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index fb974f6c..c3e40789 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -104,7 +104,7 @@ llvm::StringRef getDurationFactoryForScale(DurationScale Scale) { } /// Returns the Time factory function name for a given `Scale`. -llvm::StringRef getTimeFactoryForScale(DurationScale scale) { +llvm::StringRef getTimeInverseForScale(DurationScale scale) { switch (scale) { case DurationScale::Hours: return "absl::ToUnixHours"; diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index 36dd5396..54a60f60 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -31,9 +31,6 @@ enum class DurationScale : std::uint8_t { /// constructing a `Duration` for that scale. llvm::StringRef getDurationFactoryForScale(DurationScale Scale); -/// Returns the Time factory function name for a given `Scale`. -llvm::StringRef getTimeFactoryForScale(DurationScale scale); - // Determine if `Node` represents a literal floating point or integral zero. bool IsLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result, const Expr &Node); @@ -75,6 +72,9 @@ llvm::Optional getScaleForTimeInverse(llvm::StringRef Name); const std::pair & getDurationInverseForScale(DurationScale Scale); +/// Returns the Time inverse function name for a given `Scale`. +llvm::StringRef getTimeInverseForScale(DurationScale scale); + /// Assuming `Node` has type `double` or `int` representing a time interval of /// `Scale`, return the expression to make it a suitable `Duration`. std::string rewriteExprFromNumberToDuration( @@ -107,7 +107,7 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, } AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, - TimeFactoryFunction) { + TimeConversionFunction) { using namespace clang::ast_matchers; return functionDecl(hasAnyName( "::absl::ToUnixHours", "::absl::ToUnixMinutes", "::absl::ToUnixSeconds", -- cgit v1.2.3 From 9db0915c116e1301b04849416c1c9008dface6f9 Mon Sep 17 00:00:00 2001 From: Stephane Moore Date: Sat, 2 Feb 2019 22:07:00 +0000 Subject: =?UTF-8?q?[clang-tidy]=20Make=20google-objc-function-naming=20ign?= =?UTF-8?q?ore=20implicit=20functions=20=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Implicit functions are outside the control of source authors and should be exempt from style restrictions. Tested via running clang tools tests. Reviewers: aaron.ballman Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Differential Revision: https://reviews.llvm.org/D57207 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352968 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/google/FunctionNamingCheck.cpp | 10 +++++++--- test/clang-tidy/google-objc-function-naming.m | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tidy/google/FunctionNamingCheck.cpp index 3eeb6fa6..8096d65d 100644 --- a/clang-tidy/google/FunctionNamingCheck.cpp +++ b/clang-tidy/google/FunctionNamingCheck.cpp @@ -93,12 +93,16 @@ void FunctionNamingCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().ObjC) return; - // Match function declarations that are not in system headers and are not - // main. + // Enforce Objective-C function naming conventions on all functions except: + // • Functions defined in system headers. + // • C++ member functions. + // • Namespaced functions. + // • Implicitly defined functions. + // • The main function. Finder->addMatcher( functionDecl( unless(anyOf(isExpansionInSystemHeader(), cxxMethodDecl(), - hasAncestor(namespaceDecl()), isMain(), + hasAncestor(namespaceDecl()), isMain(), isImplicit(), matchesName(validFunctionNameRegex(true)), allOf(isStaticStorageClass(), matchesName(validFunctionNameRegex(false)))))) diff --git a/test/clang-tidy/google-objc-function-naming.m b/test/clang-tidy/google-objc-function-naming.m index d0336d26..82169cf9 100644 --- a/test/clang-tidy/google-objc-function-naming.m +++ b/test/clang-tidy/google-objc-function-naming.m @@ -1,5 +1,13 @@ // RUN: %check_clang_tidy %s google-objc-function-naming %t +#import + +static void TestImplicitFunctionDeclaration(int a) { + // Call a builtin function so that the compiler generates an implicit + // function declaration. + printf("%d", a); +} + typedef _Bool bool; static bool ispositive(int a) { return a > 0; } -- cgit v1.2.3 From 07599ccf0c97fd013b07981363eb7db2d6f6d13f Mon Sep 17 00:00:00 2001 From: Stephane Moore Date: Sat, 2 Feb 2019 23:01:20 +0000 Subject: =?UTF-8?q?Revert=20rCTE352968=20due=20to=20compilation=20failures?= =?UTF-8?q?=20=F0=9F=92=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352969 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/google/FunctionNamingCheck.cpp | 10 +++------- test/clang-tidy/google-objc-function-naming.m | 8 -------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tidy/google/FunctionNamingCheck.cpp index 8096d65d..3eeb6fa6 100644 --- a/clang-tidy/google/FunctionNamingCheck.cpp +++ b/clang-tidy/google/FunctionNamingCheck.cpp @@ -93,16 +93,12 @@ void FunctionNamingCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().ObjC) return; - // Enforce Objective-C function naming conventions on all functions except: - // • Functions defined in system headers. - // • C++ member functions. - // • Namespaced functions. - // • Implicitly defined functions. - // • The main function. + // Match function declarations that are not in system headers and are not + // main. Finder->addMatcher( functionDecl( unless(anyOf(isExpansionInSystemHeader(), cxxMethodDecl(), - hasAncestor(namespaceDecl()), isMain(), isImplicit(), + hasAncestor(namespaceDecl()), isMain(), matchesName(validFunctionNameRegex(true)), allOf(isStaticStorageClass(), matchesName(validFunctionNameRegex(false)))))) diff --git a/test/clang-tidy/google-objc-function-naming.m b/test/clang-tidy/google-objc-function-naming.m index 82169cf9..d0336d26 100644 --- a/test/clang-tidy/google-objc-function-naming.m +++ b/test/clang-tidy/google-objc-function-naming.m @@ -1,13 +1,5 @@ // RUN: %check_clang_tidy %s google-objc-function-naming %t -#import - -static void TestImplicitFunctionDeclaration(int a) { - // Call a builtin function so that the compiler generates an implicit - // function declaration. - printf("%d", a); -} - typedef _Bool bool; static bool ispositive(int a) { return a > 0; } -- cgit v1.2.3 From 2c69098650c4f07a0d5413f5e42b9c9d1edcda09 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sun, 3 Feb 2019 14:08:30 +0000 Subject: Remove trailing semicolon. NFCI. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352990 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 893d85ab..981c69df 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -53,7 +53,7 @@ CodeAction toCodeAction(const ClangdServer::TweakRef &T, const URIForFile &File, CA.command->tweakArgs->tweakID = T.ID; CA.command->tweakArgs->selection = Selection; return CA; -}; +} void adjustSymbolKinds(llvm::MutableArrayRef Syms, SymbolKindBitset Kinds) { -- cgit v1.2.3 From 255a91ad3eaa10b5421502c88a201ee992c44b68 Mon Sep 17 00:00:00 2001 From: Simon Pilgrim Date: Sun, 3 Feb 2019 14:11:32 +0000 Subject: Remove trailing semicolon. NFCI. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@352991 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/refactor/tweaks/SwapIfBranches.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp index f28cbe53..9b0b72d9 100644 --- a/clangd/refactor/tweaks/SwapIfBranches.cpp +++ b/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -44,7 +44,7 @@ private: const IfStmt *If = nullptr; }; -REGISTER_TWEAK(SwapIfBranches); +REGISTER_TWEAK(SwapIfBranches) bool SwapIfBranches::prepare(const Selection &Inputs) { for (const SelectionTree::Node *N = Inputs.ASTSelection.commonAncestor(); -- cgit v1.2.3 From abac278a102506137f96f1b69e95b8509285be9d Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 4 Feb 2019 09:20:41 +0000 Subject: [clangd] Update vscode dependencies This allows us to use latest LSP v3.14.0 (for go-to-declaration feature). git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353026 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/clients/clangd-vscode/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clangd/clients/clangd-vscode/package.json b/clangd/clients/clangd-vscode/package.json index 89b61ff9..ecc05d5e 100644 --- a/clangd/clients/clangd-vscode/package.json +++ b/clangd/clients/clangd-vscode/package.json @@ -6,7 +6,7 @@ "publisher": "llvm-vs-code-extensions", "homepage": "https://clang.llvm.org/extra/clangd.html", "engines": { - "vscode": "^1.27.0" + "vscode": "^1.30.0" }, "categories": [ "Programming Languages", @@ -32,8 +32,8 @@ "test": "node ./node_modules/vscode/bin/test" }, "dependencies": { - "vscode-languageclient": "^5.1.0", - "vscode-languageserver": "^5.1.0" + "vscode-languageclient": "^5.2.0", + "vscode-languageserver": "^5.2.0" }, "devDependencies": { "typescript": "^2.0.3", -- cgit v1.2.3 From c7ccea5a5eff5ab550024fc738ae8ab8f9298cec Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 4 Feb 2019 09:26:42 +0000 Subject: [clangd] Bump vscode-clangd v0.0.10 CHANGELOG: - cleanup filestatus caches when clangd crashes - extension workwith LSP v3.14.0, support go-to-declaration feature git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353027 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/clients/clangd-vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/clients/clangd-vscode/package.json b/clangd/clients/clangd-vscode/package.json index ecc05d5e..bea96537 100644 --- a/clangd/clients/clangd-vscode/package.json +++ b/clangd/clients/clangd-vscode/package.json @@ -2,7 +2,7 @@ "name": "vscode-clangd", "displayName": "vscode-clangd", "description": "Clang Language Server", - "version": "0.0.9", + "version": "0.0.10", "publisher": "llvm-vs-code-extensions", "homepage": "https://clang.llvm.org/extra/clangd.html", "engines": { -- cgit v1.2.3 From 8bbdbd0946bd4ea3d7e95f71073449ea49b106c8 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 4 Feb 2019 16:19:57 +0000 Subject: [clangd] Enable include insertion for static index Summary: This enables include insertion by adding canonical includes into preambledata. Reviewers: ioeric, ilya-biryukov Subscribers: javed.absar, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D57508 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353054 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdServer.cpp | 6 +++-- clangd/ClangdUnit.cpp | 46 ++++++++++++++++++++++++++++------ clangd/ClangdUnit.h | 12 ++++++--- clangd/TUScheduler.cpp | 6 +++-- clangd/TUScheduler.h | 4 ++- clangd/index/FileIndex.cpp | 27 ++++++++++---------- clangd/index/FileIndex.h | 8 +++--- unittests/clangd/CodeCompleteTests.cpp | 30 ++++++++++++++++++++++ unittests/clangd/FileIndexTests.cpp | 22 ++++++++++------ unittests/clangd/TestTU.cpp | 6 +++-- 10 files changed, 125 insertions(+), 42 deletions(-) diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 595e0758..2dcf0fb3 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -13,6 +13,7 @@ #include "Headers.h" #include "SourceCode.h" #include "Trace.h" +#include "index/CanonicalIncludes.h" #include "index/FileIndex.h" #include "index/Merge.h" #include "refactor/Tweak.h" @@ -69,9 +70,10 @@ struct UpdateIndexCallbacks : public ParsingCallbacks { : FIndex(FIndex), DiagConsumer(DiagConsumer) {} void onPreambleAST(PathRef Path, ASTContext &Ctx, - std::shared_ptr PP) override { + std::shared_ptr PP, + const CanonicalIncludes &CanonIncludes) override { if (FIndex) - FIndex->updatePreamble(Path, Ctx, std::move(PP)); + FIndex->updatePreamble(Path, Ctx, std::move(PP), CanonIncludes); } void onMainAST(PathRef Path, ParsedAST &AST) override { diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 6b5e1764..ffb96fbf 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -16,6 +16,7 @@ #include "Logger.h" #include "SourceCode.h" #include "Trace.h" +#include "index/CanonicalIncludes.h" #include "index/Index.h" #include "clang/AST/ASTContext.h" #include "clang/Basic/LangOptions.h" @@ -99,11 +100,16 @@ public: IncludeStructure takeIncludes() { return std::move(Includes); } + CanonicalIncludes takeCanonicalIncludes() { + addSystemHeadersMapping(&CanonIncludes); + return std::move(CanonIncludes); + } + void AfterExecute(CompilerInstance &CI) override { if (!ParsedCallback) return; trace::Span Tracer("Running PreambleCallback"); - ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr()); + ParsedCallback(CI.getASTContext(), CI.getPreprocessorPtr(), CanonIncludes); } void BeforeExecute(CompilerInstance &CI) override { @@ -115,10 +121,17 @@ public: return collectIncludeStructureCallback(*SourceMgr, &Includes); } + CommentHandler *getCommentHandler() override { + IWYUHandler = collectIWYUHeaderMaps(&CanonIncludes); + return IWYUHandler.get(); + } + private: PathRef File; PreambleParsedCallback ParsedCallback; IncludeStructure Includes; + CanonicalIncludes CanonIncludes; + std::unique_ptr IWYUHandler = nullptr; SourceManager *SourceMgr = nullptr; }; @@ -324,6 +337,17 @@ ParsedAST::build(std::unique_ptr CI, Clang->getPreprocessor().addPPCallbacks( collectIncludeStructureCallback(Clang->getSourceManager(), &Includes)); + // Copy over the includes from the preamble, then combine with the + // non-preamble includes below. + CanonicalIncludes CanonIncludes; + if (Preamble) + CanonIncludes = Preamble->CanonIncludes; + else + addSystemHeadersMapping(&CanonIncludes); + std::unique_ptr IWYUHandler = + collectIWYUHeaderMaps(&CanonIncludes); + Clang->getPreprocessor().addCommentHandler(IWYUHandler.get()); + if (!Action->Execute()) log("Execute() failed when building AST for {0}", MainInput.getFile()); @@ -353,7 +377,7 @@ ParsedAST::build(std::unique_ptr CI, Diags.insert(Diags.begin(), Preamble->Diags.begin(), Preamble->Diags.end()); return ParsedAST(std::move(Preamble), std::move(Clang), std::move(Action), std::move(ParsedDecls), std::move(Diags), - std::move(Includes)); + std::move(Includes), std::move(CanonIncludes)); } ParsedAST::ParsedAST(ParsedAST &&Other) = default; @@ -429,21 +453,28 @@ const IncludeStructure &ParsedAST::getIncludeStructure() const { return Includes; } +const CanonicalIncludes &ParsedAST::getCanonicalIncludes() const { + return CanonIncludes; +} + PreambleData::PreambleData(PrecompiledPreamble Preamble, std::vector Diags, IncludeStructure Includes, - std::unique_ptr StatCache) + std::unique_ptr StatCache, + CanonicalIncludes CanonIncludes) : Preamble(std::move(Preamble)), Diags(std::move(Diags)), - Includes(std::move(Includes)), StatCache(std::move(StatCache)) {} + Includes(std::move(Includes)), StatCache(std::move(StatCache)), + CanonIncludes(std::move(CanonIncludes)) {} ParsedAST::ParsedAST(std::shared_ptr Preamble, std::unique_ptr Clang, std::unique_ptr Action, std::vector LocalTopLevelDecls, - std::vector Diags, IncludeStructure Includes) + std::vector Diags, IncludeStructure Includes, + CanonicalIncludes CanonIncludes) : Preamble(std::move(Preamble)), Clang(std::move(Clang)), Action(std::move(Action)), Diags(std::move(Diags)), LocalTopLevelDecls(std::move(LocalTopLevelDecls)), - Includes(std::move(Includes)) { + Includes(std::move(Includes)), CanonIncludes(std::move(CanonIncludes)) { assert(this->Clang); assert(this->Action); } @@ -510,7 +541,8 @@ buildPreamble(PathRef FileName, CompilerInvocation &CI, FileName); return std::make_shared( std::move(*BuiltPreamble), PreambleDiagnostics.take(), - SerializedDeclsCollector.takeIncludes(), std::move(StatCache)); + SerializedDeclsCollector.takeIncludes(), std::move(StatCache), + SerializedDeclsCollector.takeCanonicalIncludes()); } else { elog("Could not build a preamble for file {0}", FileName); return nullptr; diff --git a/clangd/ClangdUnit.h b/clangd/ClangdUnit.h index f4883fd5..d5bdd1ab 100644 --- a/clangd/ClangdUnit.h +++ b/clangd/ClangdUnit.h @@ -16,6 +16,7 @@ #include "Headers.h" #include "Path.h" #include "Protocol.h" +#include "index/CanonicalIncludes.h" #include "index/Index.h" #include "clang/Frontend/FrontendAction.h" #include "clang/Frontend/PrecompiledPreamble.h" @@ -48,7 +49,8 @@ namespace clangd { struct PreambleData { PreambleData(PrecompiledPreamble Preamble, std::vector Diags, IncludeStructure Includes, - std::unique_ptr StatCache); + std::unique_ptr StatCache, + CanonicalIncludes CanonIncludes); tooling::CompileCommand CompileCommand; PrecompiledPreamble Preamble; @@ -59,6 +61,7 @@ struct PreambleData { // Cache of FS operations performed when building the preamble. // When reusing a preamble, this cache can be consumed to save IO. std::unique_ptr StatCache; + CanonicalIncludes CanonIncludes; }; /// Stores and provides access to parsed AST. @@ -100,13 +103,14 @@ public: /// bytes. Does not include the size of the preamble. std::size_t getUsedBytes() const; const IncludeStructure &getIncludeStructure() const; + const CanonicalIncludes &getCanonicalIncludes() const; private: ParsedAST(std::shared_ptr Preamble, std::unique_ptr Clang, std::unique_ptr Action, std::vector LocalTopLevelDecls, std::vector Diags, - IncludeStructure Includes); + IncludeStructure Includes, CanonicalIncludes CanonIncludes); // In-memory preambles must outlive the AST, it is important that this member // goes before Clang and Action. @@ -125,10 +129,12 @@ private: // top-level decls from the preamble. std::vector LocalTopLevelDecls; IncludeStructure Includes; + CanonicalIncludes CanonIncludes; }; using PreambleParsedCallback = - std::function)>; + std::function, + const CanonicalIncludes &)>; /// Rebuild the preamble for the new inputs unless the old one can be reused. /// If \p OldPreamble can be reused, it is returned unchanged. diff --git a/clangd/TUScheduler.cpp b/clangd/TUScheduler.cpp index 14319ab9..c7730827 100644 --- a/clangd/TUScheduler.cpp +++ b/clangd/TUScheduler.cpp @@ -45,6 +45,7 @@ #include "Cancellation.h" #include "Logger.h" #include "Trace.h" +#include "index/CanonicalIncludes.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PCHContainerOperations.h" #include "llvm/ADT/ScopeExit.h" @@ -385,8 +386,9 @@ void ASTWorker::update(ParseInputs Inputs, WantDiagnostics WantDiags) { std::shared_ptr NewPreamble = buildPreamble( FileName, *Invocation, OldPreamble, OldCommand, Inputs, PCHs, StorePreambleInMemory, - [this](ASTContext &Ctx, std::shared_ptr PP) { - Callbacks.onPreambleAST(FileName, Ctx, std::move(PP)); + [this](ASTContext &Ctx, std::shared_ptr PP, + const CanonicalIncludes &CanonIncludes) { + Callbacks.onPreambleAST(FileName, Ctx, std::move(PP), CanonIncludes); }); bool CanReuseAST = InputsAreTheSame && (OldPreamble == NewPreamble); diff --git a/clangd/TUScheduler.h b/clangd/TUScheduler.h index cd0c4c78..abcf4aa3 100644 --- a/clangd/TUScheduler.h +++ b/clangd/TUScheduler.h @@ -12,6 +12,7 @@ #include "ClangdUnit.h" #include "Function.h" #include "Threading.h" +#include "index/CanonicalIncludes.h" #include "llvm/ADT/StringMap.h" #include @@ -91,7 +92,8 @@ public: /// contains only AST nodes from the #include directives at the start of the /// file. AST node in the current file should be observed on onMainAST call. virtual void onPreambleAST(PathRef Path, ASTContext &Ctx, - std::shared_ptr PP) {} + std::shared_ptr PP, + const CanonicalIncludes &) {} /// Called on the AST built for the file itself. Note that preamble AST nodes /// are not deserialized and should be processed in the onPreambleAST call /// instead. diff --git a/clangd/index/FileIndex.cpp b/clangd/index/FileIndex.cpp index 8ce42b51..bc102d29 100644 --- a/clangd/index/FileIndex.cpp +++ b/clangd/index/FileIndex.cpp @@ -10,6 +10,7 @@ #include "ClangdUnit.h" #include "Logger.h" #include "SymbolCollector.h" +#include "index/CanonicalIncludes.h" #include "index/Index.h" #include "index/MemIndex.h" #include "index/Merge.h" @@ -28,14 +29,11 @@ namespace clangd { static std::pair indexSymbols(ASTContext &AST, std::shared_ptr PP, - llvm::ArrayRef DeclsToIndex, bool IsIndexMainAST) { + llvm::ArrayRef DeclsToIndex, + const CanonicalIncludes &Includes, bool IsIndexMainAST) { SymbolCollector::Options CollectorOpts; - // FIXME(ioeric): we might also want to collect include headers. We would need - // to make sure all includes are canonicalized (with CanonicalIncludes), which - // is not trivial given the current way of collecting symbols: we only have - // AST at this point, but we also need preprocessor callbacks (e.g. - // CommentHandler for IWYU pragma) to canonicalize includes. - CollectorOpts.CollectIncludePath = false; + CollectorOpts.CollectIncludePath = true; + CollectorOpts.Includes = &Includes; CollectorOpts.CountReferences = false; CollectorOpts.Origin = SymbolOrigin::Dynamic; @@ -47,7 +45,7 @@ indexSymbols(ASTContext &AST, std::shared_ptr PP, if (IsIndexMainAST) { // We only collect refs when indexing main AST. CollectorOpts.RefFilter = RefKind::All; - }else { + } else { IndexOpts.IndexMacrosInPreprocessor = true; CollectorOpts.CollectMacro = true; } @@ -72,16 +70,16 @@ indexSymbols(ASTContext &AST, std::shared_ptr PP, std::pair indexMainDecls(ParsedAST &AST) { return indexSymbols(AST.getASTContext(), AST.getPreprocessorPtr(), - AST.getLocalTopLevelDecls(), + AST.getLocalTopLevelDecls(), AST.getCanonicalIncludes(), /*IsIndexMainAST=*/true); } -SymbolSlab indexHeaderSymbols(ASTContext &AST, - std::shared_ptr PP) { +SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr PP, + const CanonicalIncludes &Includes) { std::vector DeclsToIndex( AST.getTranslationUnitDecl()->decls().begin(), AST.getTranslationUnitDecl()->decls().end()); - return indexSymbols(AST, std::move(PP), DeclsToIndex, + return indexSymbols(AST, std::move(PP), DeclsToIndex, Includes, /*IsIndexMainAST=*/false) .first; } @@ -195,8 +193,9 @@ FileIndex::FileIndex(bool UseDex) MainFileIndex(llvm::make_unique()) {} void FileIndex::updatePreamble(PathRef Path, ASTContext &AST, - std::shared_ptr PP) { - auto Symbols = indexHeaderSymbols(AST, std::move(PP)); + std::shared_ptr PP, + const CanonicalIncludes &Includes) { + auto Symbols = indexHeaderSymbols(AST, std::move(PP), Includes); PreambleSymbols.update(Path, llvm::make_unique(std::move(Symbols)), llvm::make_unique()); diff --git a/clangd/index/FileIndex.h b/clangd/index/FileIndex.h index 74563276..f1e37c33 100644 --- a/clangd/index/FileIndex.h +++ b/clangd/index/FileIndex.h @@ -19,6 +19,7 @@ #include "Index.h" #include "MemIndex.h" #include "Merge.h" +#include "index/CanonicalIncludes.h" #include "clang/Lex/Preprocessor.h" #include @@ -84,7 +85,8 @@ public: /// Update preamble symbols of file \p Path with all declarations in \p AST /// and macros in \p PP. void updatePreamble(PathRef Path, ASTContext &AST, - std::shared_ptr PP); + std::shared_ptr PP, + const CanonicalIncludes &Includes); /// Update symbols and references from main file \p Path with /// `indexMainDecls`. @@ -124,8 +126,8 @@ std::pair indexMainDecls(ParsedAST &AST); /// Idex declarations from \p AST and macros from \p PP that are declared in /// included headers. -SymbolSlab indexHeaderSymbols(ASTContext &AST, - std::shared_ptr PP); +SymbolSlab indexHeaderSymbols(ASTContext &AST, std::shared_ptr PP, + const CanonicalIncludes &Includes); } // namespace clangd } // namespace clang diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp index ba539fc2..3a0082a2 100644 --- a/unittests/clangd/CodeCompleteTests.cpp +++ b/unittests/clangd/CodeCompleteTests.cpp @@ -645,6 +645,36 @@ TEST(CompletionTest, CompletionInPreamble) { EXPECT_THAT(Results, ElementsAre(Named("ifndef"))); } +TEST(CompletionTest, DynamicIndexIncludeInsertion) { + MockFSProvider FS; + MockCompilationDatabase CDB; + IgnoreDiagnostics DiagConsumer; + ClangdServer::Options Opts = ClangdServer::optsForTest(); + Opts.BuildDynamicSymbolIndex = true; + ClangdServer Server(CDB, FS, DiagConsumer, Opts); + + FS.Files[testPath("foo_header.h")] = R"cpp( + struct Foo { + // Member doc + int foo(); + }; + )cpp"; + const std::string FileContent(R"cpp( + #include "foo_header.h" + int Foo::foo() { + return 42; + } + )cpp"); + Server.addDocument(testPath("foo_impl.cpp"), FileContent); + // Wait for the dynamic index being built. + ASSERT_TRUE(Server.blockUntilIdleForTest()); + EXPECT_THAT( + completions(Server, "Foo^ foo;").Completions, + ElementsAre(AllOf(Named("Foo"), + HasInclude('"' + testPath("foo_header.h") + '"'), + InsertInclude()))); +} + TEST(CompletionTest, DynamicIndexMultiFile) { MockFSProvider FS; MockCompilationDatabase CDB; diff --git a/unittests/clangd/FileIndexTests.cpp b/unittests/clangd/FileIndexTests.cpp index 898dd64d..0b037a50 100644 --- a/unittests/clangd/FileIndexTests.cpp +++ b/unittests/clangd/FileIndexTests.cpp @@ -12,6 +12,7 @@ #include "SyncAPI.h" #include "TestFS.h" #include "TestTU.h" +#include "index/CanonicalIncludes.h" #include "index/FileIndex.h" #include "index/Index.h" #include "clang/Frontend/CompilerInvocation.h" @@ -147,8 +148,8 @@ void update(FileIndex &M, llvm::StringRef Basename, llvm::StringRef Code) { File.HeaderFilename = (Basename + ".h").str(); File.HeaderCode = Code; auto AST = File.build(); - M.updatePreamble(File.Filename, AST.getASTContext(), - AST.getPreprocessorPtr()); + M.updatePreamble(File.Filename, AST.getASTContext(), AST.getPreprocessorPtr(), + AST.getCanonicalIncludes()); } TEST(FileIndexTest, CustomizedURIScheme) { @@ -199,13 +200,16 @@ TEST(FileIndexTest, ClassMembers) { QName("X::f"))); } -TEST(FileIndexTest, NoIncludeCollected) { +TEST(FileIndexTest, IncludeCollected) { FileIndex M; - update(M, "f", "class string {};"); + update( + M, "f", + "// IWYU pragma: private, include \nclass string {};"); auto Symbols = runFuzzyFind(M, ""); EXPECT_THAT(Symbols, ElementsAre(_)); - EXPECT_THAT(Symbols.begin()->IncludeHeaders, IsEmpty()); + EXPECT_THAT(Symbols.begin()->IncludeHeaders.front().IncludeHeader, + ""); } TEST(FileIndexTest, TemplateParamsInLabel) { @@ -270,10 +274,11 @@ TEST(FileIndexTest, RebuildWithPreamble) { buildPreamble( FooCpp, *CI, /*OldPreamble=*/nullptr, tooling::CompileCommand(), PI, std::make_shared(), /*StoreInMemory=*/true, - [&](ASTContext &Ctx, std::shared_ptr PP) { + [&](ASTContext &Ctx, std::shared_ptr PP, + const CanonicalIncludes &CanonIncludes) { EXPECT_FALSE(IndexUpdated) << "Expected only a single index update"; IndexUpdated = true; - Index.updatePreamble(FooCpp, Ctx, std::move(PP)); + Index.updatePreamble(FooCpp, Ctx, std::move(PP), CanonIncludes); }); ASSERT_TRUE(IndexUpdated); @@ -358,7 +363,8 @@ TEST(FileIndexTest, ReferencesInMainFileWithPreamble) { MainFile, *buildCompilerInvocation(PI), /*OldPreamble=*/nullptr, tooling::CompileCommand(), PI, std::make_shared(), /*StoreInMemory=*/true, - [&](ASTContext &Ctx, std::shared_ptr PP) {}); + [&](ASTContext &Ctx, std::shared_ptr PP, + const CanonicalIncludes &) {}); // Build AST for main file with preamble. auto AST = ParsedAST::build(createInvocationFromCommandLine(Cmd), PreambleData, diff --git a/unittests/clangd/TestTU.cpp b/unittests/clangd/TestTU.cpp index 8c61bb80..c2f0d897 100644 --- a/unittests/clangd/TestTU.cpp +++ b/unittests/clangd/TestTU.cpp @@ -59,13 +59,15 @@ ParsedAST TestTU::build() const { SymbolSlab TestTU::headerSymbols() const { auto AST = build(); - return indexHeaderSymbols(AST.getASTContext(), AST.getPreprocessorPtr()); + return indexHeaderSymbols(AST.getASTContext(), AST.getPreprocessorPtr(), + AST.getCanonicalIncludes()); } std::unique_ptr TestTU::index() const { auto AST = build(); auto Idx = llvm::make_unique(/*UseDex=*/true); - Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr()); + Idx->updatePreamble(Filename, AST.getASTContext(), AST.getPreprocessorPtr(), + AST.getCanonicalIncludes()); Idx->updateMain(Filename, AST); return std::move(Idx); } -- cgit v1.2.3 From cd9ab0d12e688e69741d6cfd71af56a49b8a99f3 Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Mon, 4 Feb 2019 19:28:20 +0000 Subject: [clang-tidy] Add the abseil-duration-unnecessary-conversion check Differential Revision: https://reviews.llvm.org/D57353 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353079 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/AbseilTidyModule.cpp | 3 + clang-tidy/abseil/CMakeLists.txt | 1 + .../abseil/DurationUnnecessaryConversionCheck.cpp | 58 ++++++++++++++++++ .../abseil/DurationUnnecessaryConversionCheck.h | 35 +++++++++++ docs/ReleaseNotes.rst | 6 ++ .../abseil-duration-unnecessary-conversion.rst | 31 ++++++++++ docs/clang-tidy/checks/list.rst | 1 + test/clang-tidy/Inputs/absl/time/time.h | 2 + .../abseil-duration-unnecessary-conversion.cpp | 69 ++++++++++++++++++++++ 9 files changed, 206 insertions(+) create mode 100644 clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp create mode 100644 clang-tidy/abseil/DurationUnnecessaryConversionCheck.h create mode 100644 docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst create mode 100644 test/clang-tidy/abseil-duration-unnecessary-conversion.cpp diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp index b05318bb..1489b48b 100644 --- a/clang-tidy/abseil/AbseilTidyModule.cpp +++ b/clang-tidy/abseil/AbseilTidyModule.cpp @@ -16,6 +16,7 @@ #include "DurationFactoryFloatCheck.h" #include "DurationFactoryScaleCheck.h" #include "DurationSubtractionCheck.h" +#include "DurationUnnecessaryConversionCheck.h" #include "FasterStrsplitDelimiterCheck.h" #include "NoInternalDependenciesCheck.h" #include "NoNamespaceCheck.h" @@ -45,6 +46,8 @@ public: "abseil-duration-factory-scale"); CheckFactories.registerCheck( "abseil-duration-subtraction"); + CheckFactories.registerCheck( + "abseil-duration-unnecessary-conversion"); CheckFactories.registerCheck( "abseil-faster-strsplit-delimiter"); CheckFactories.registerCheck( diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt index 68247ba4..578dd57d 100644 --- a/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tidy/abseil/CMakeLists.txt @@ -10,6 +10,7 @@ add_clang_library(clangTidyAbseilModule DurationFactoryScaleCheck.cpp DurationRewriter.cpp DurationSubtractionCheck.cpp + DurationUnnecessaryConversionCheck.cpp FasterStrsplitDelimiterCheck.cpp NoInternalDependenciesCheck.cpp NoNamespaceCheck.cpp diff --git a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp new file mode 100644 index 00000000..83650cd1 --- /dev/null +++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp @@ -0,0 +1,58 @@ +//===--- DurationUnnecessaryConversionCheck.cpp - clang-tidy +//-----------------------===// +// +// 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 "DurationUnnecessaryConversionCheck.h" +#include "DurationRewriter.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace abseil { + +void DurationUnnecessaryConversionCheck::registerMatchers(MatchFinder *Finder) { + for (const auto &Scale : {"Hours", "Minutes", "Seconds", "Milliseconds", + "Microseconds", "Nanoseconds"}) { + std::string DurationFactory = (llvm::Twine("::absl::") + Scale).str(); + std::string FloatConversion = + (llvm::Twine("::absl::ToDouble") + Scale).str(); + std::string IntegerConversion = + (llvm::Twine("::absl::ToInt64") + Scale).str(); + + Finder->addMatcher( + callExpr( + callee(functionDecl(hasName(DurationFactory))), + hasArgument(0, callExpr(callee(functionDecl(hasAnyName( + FloatConversion, IntegerConversion))), + hasArgument(0, expr().bind("arg"))))) + .bind("call"), + this); + } +} + +void DurationUnnecessaryConversionCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *OuterCall = Result.Nodes.getNodeAs("call"); + const auto *Arg = Result.Nodes.getNodeAs("arg"); + + if (!isNotInMacro(Result, OuterCall)) + return; + + diag(OuterCall->getBeginLoc(), "remove unnecessary absl::Duration conversions") + << FixItHint::CreateReplacement( + OuterCall->getSourceRange(), + tooling::fixit::getText(*Arg, *Result.Context)); +} + +} // namespace abseil +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h new file mode 100644 index 00000000..18061338 --- /dev/null +++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.h @@ -0,0 +1,35 @@ +//===--- DurationUnnecessaryConversionCheck.h - clang-tidy ------*- 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_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace abseil { + +/// Finds and fixes cases where ``absl::Duration`` values are being converted +/// to numeric types and back again. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-duration-unnecessary-conversion.html +class DurationUnnecessaryConversionCheck : public ClangTidyCheck { +public: + DurationUnnecessaryConversionCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace abseil +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMEDOUBLECONVERSIONCHECK_H diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 1f6889ac..9f833954 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -79,6 +79,12 @@ Improvements to clang-tidy Checks for casts of ``absl::Duration`` conversion functions, and recommends the right conversion function instead. +- New :doc:`abseil-duration-unnecessary-conversion + ` check. + + Finds and fixes cases where ``absl::Duration`` values are being converted to + numeric types and back again. + - New :doc:`google-readability-avoid-underscore-in-googletest-name ` check. diff --git a/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst new file mode 100644 index 00000000..938c46d5 --- /dev/null +++ b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst @@ -0,0 +1,31 @@ +.. title:: clang-tidy - abseil-duration-unnecessary-conversion + +abseil-duration-unnecessary-conversion +====================================== + +Finds and fixes cases where ``absl::Duration`` values are being converted to +numeric types and back again. + +Examples: + +.. code-block:: c++ + + // Original - Conversion to double and back again + absl::Duration d1; + absl::Duration d2 = absl::Seconds(absl::ToDoubleSeconds(d1)); + + // Suggestion - Remove unnecessary conversions + absl::Duration d2 = d1; + + + // Original - Conversion to integer and back again + absl::Duration d1; + absl::Duration d2 = absl::Hours(absl::ToInt64Hours(d1)); + + // Suggestion - Remove unnecessary conversions + absl::Duration d2 = d1; + +Note: Converting to an integer and back to an ``absl::Duration`` might be a +truncating operation if the value is not aligned to the scale of conversion. +In the rare case where this is the intended result, callers should use +``absl::Trunc`` to truncate explicitly. diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 487f6828..13d8f6fb 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -11,6 +11,7 @@ Clang-Tidy Checks abseil-duration-factory-float abseil-duration-factory-scale abseil-duration-subtraction + abseil-duration-unnecessary-conversion abseil-faster-strsplit-delimiter abseil-no-internal-dependencies abseil-no-namespace diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h index 385eed82..8da3c2c3 100644 --- a/test/clang-tidy/Inputs/absl/time/time.h +++ b/test/clang-tidy/Inputs/absl/time/time.h @@ -14,6 +14,8 @@ public: Duration &operator/=(float r); Duration &operator/=(double r); template Duration &operator/=(T r); + + Duration &operator+(Duration d); }; template Duration operator*(Duration lhs, T rhs); diff --git a/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp new file mode 100644 index 00000000..9414182c --- /dev/null +++ b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp @@ -0,0 +1,69 @@ +// RUN: %check_clang_tidy %s abseil-duration-unnecessary-conversion %t -- -- -I%S/Inputs + +#include "absl/time/time.h" + +void f() { + absl::Duration d1, d2; + + // Floating point + d2 = absl::Hours(absl::ToDoubleHours(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Minutes(absl::ToDoubleMinutes(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Seconds(absl::ToDoubleSeconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + + // Integer point + d2 = absl::Hours(absl::ToInt64Hours(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Minutes(absl::ToInt64Minutes(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Seconds(absl::ToInt64Seconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Microseconds(absl::ToInt64Microseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d1 + + // As macro argument +#define PLUS_FIVE_S(x) x + absl::Seconds(5) + d2 = PLUS_FIVE_S(absl::Seconds(absl::ToInt64Seconds(d1))); + // CHECK-MESSAGES: [[@LINE-1]]:20: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: PLUS_FIVE_S(d1) +#undef PLUS_FIVE_S + + // Split by macro: should not change +#define TOSECONDS(x) absl::Seconds(x) + d2 = TOSECONDS(absl::ToInt64Seconds(d1)); +#undef TOSECONDS + + // Don't change something inside a macro definition +#define VALUE(x) absl::Hours(absl::ToInt64Hours(x)); + d2 = VALUE(d1); +#undef VALUE + + // These should not match + d2 = absl::Seconds(absl::ToDoubleMilliseconds(d1)); + d2 = absl::Seconds(4); + int i = absl::ToInt64Milliseconds(d1); +} -- cgit v1.2.3 From d1aed22c28d79eb84340b8f40bd1f421b53010e0 Mon Sep 17 00:00:00 2001 From: Malcolm Parsons Date: Mon, 4 Feb 2019 21:09:31 +0000 Subject: [clang-tidy] Handle unions with existing default-member-init Summary: clang-tidy's modernize-use-default-member-init was crashing for unions with an existing default member initializer. Fixes PR40492 Reviewers: aaron.ballman, alexfh, JonasToth Reviewed By: JonasToth Subscribers: JonasToth, riccibruno, xazax.hun, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D57665 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353092 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/modernize/UseDefaultMemberInitCheck.cpp | 2 +- test/clang-tidy/modernize-use-default-member-init.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp index e2ab13b8..342b0ad2 100644 --- a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -273,7 +273,7 @@ void UseDefaultMemberInitCheck::checkDefaultInit( void UseDefaultMemberInitCheck::checkExistingInit( const MatchFinder::MatchResult &Result, const CXXCtorInitializer *Init) { - const FieldDecl *Field = Init->getMember(); + const FieldDecl *Field = Init->getAnyMember(); if (!sameValue(Field->getInClassInitializer(), Init->getInit())) return; diff --git a/test/clang-tidy/modernize-use-default-member-init.cpp b/test/clang-tidy/modernize-use-default-member-init.cpp index 0ed65df3..d35ad330 100644 --- a/test/clang-tidy/modernize-use-default-member-init.cpp +++ b/test/clang-tidy/modernize-use-default-member-init.cpp @@ -382,6 +382,16 @@ struct ExistingString { const char *e4 = "bar"; }; +struct UnionExisting { + UnionExisting() : e(5.0) {} + // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: member initializer for 'e' is redundant + // CHECK-FIXES: UnionExisting() {} + union { + int i; + double e = 5.0; + }; +}; + template struct NegativeTemplateExisting { NegativeTemplateExisting(int) : t(0) {} -- cgit v1.2.3 From 584fcfea9a5f6c010a0e32ea077cb517ed8df56d Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 6 Feb 2019 09:08:26 +0000 Subject: [clangd] Some minor fixes. Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57755 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353283 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Selection.cpp | 2 +- clangd/refactor/Tweak.h | 4 ++-- unittests/clangd/SelectionTests.cpp | 2 +- unittests/clangd/TweakTests.cpp | 7 +++---- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp index ada79891..2c2fd476 100644 --- a/clangd/Selection.cpp +++ b/clangd/Selection.cpp @@ -1,4 +1,4 @@ -//===--- Selection.h ------------------------------------------------------===// +//===--- Selection.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h index 94164bc7..35c3ce8a 100644 --- a/clangd/refactor/Tweak.h +++ b/clangd/refactor/Tweak.h @@ -56,8 +56,8 @@ public: /// defining the Tweak. Definition is provided automatically by /// REGISTER_TWEAK. virtual const char *id() const = 0; - /// Run the first stage of the action. The non-None result indicates that the - /// action is available and should be shown to the user. Returns None if the + /// Run the first stage of the action. Returns true indicating that the + /// action is available and should be shown to the user. Returns false if the /// action is not available. /// This function should be fast, if the action requires non-trivial work it /// should be moved into 'apply'. diff --git a/unittests/clangd/SelectionTests.cpp b/unittests/clangd/SelectionTests.cpp index 6cfee5d2..88406b63 100644 --- a/unittests/clangd/SelectionTests.cpp +++ b/unittests/clangd/SelectionTests.cpp @@ -1,4 +1,4 @@ -//===-- RIFFTests.cpp - Binary container unit tests -----------------------===// +//===-- SelectionTests.cpp - ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp index f747c991..baa60292 100644 --- a/unittests/clangd/TweakTests.cpp +++ b/unittests/clangd/TweakTests.cpp @@ -1,9 +1,8 @@ //===-- TweakTests.cpp ------------------------------------------*- C++ -*-===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// -- cgit v1.2.3 From d4d90c7519231d1d2a8e10d0ea74392ab9d07d25 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 6 Feb 2019 09:10:47 +0000 Subject: [clangd] Add CLI flag "-clang-tidy" to enable/disable running clang-tidy checks. Reviewers: sammccall Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57746 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353284 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/ClangdMain.cpp | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index 69732ebf..6c102eda 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -203,10 +203,16 @@ static llvm::cl::opt EnableFunctionArgSnippets( static llvm::cl::opt ClangTidyChecks( "clang-tidy-checks", - llvm::cl::desc("List of clang-tidy checks to run (this will override " - ".clang-tidy files)"), + llvm::cl::desc( + "List of clang-tidy checks to run (this will override " + ".clang-tidy files). Only meaningful when -clang-tidy flag is on."), llvm::cl::init("")); +static llvm::cl::opt EnableClangTidy( + "clang-tidy", + llvm::cl::desc("Enable clang-tidy diagnostics."), + llvm::cl::init(false)); + static llvm::cl::opt SuggestMissingIncludes( "suggest-missing-includes", llvm::cl::desc("Attempts to fix diagnostic errors caused by missing " @@ -441,13 +447,16 @@ int main(int argc, char *argv[]) { } // Create an empty clang-tidy option. - auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); - OverrideClangTidyOptions.Checks = ClangTidyChecks; - tidy::FileOptionsProvider ClangTidyOptProvider( - tidy::ClangTidyGlobalOptions(), - /* Default */ tidy::ClangTidyOptions::getDefaults(), - /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); - Opts.ClangTidyOptProvider = &ClangTidyOptProvider; + std::unique_ptr ClangTidyOptProvider; + if (EnableClangTidy) { + auto OverrideClangTidyOptions = tidy::ClangTidyOptions::getDefaults(); + OverrideClangTidyOptions.Checks = ClangTidyChecks; + ClangTidyOptProvider = llvm::make_unique( + tidy::ClangTidyGlobalOptions(), + /* Default */ tidy::ClangTidyOptions::getDefaults(), + /* Override */ OverrideClangTidyOptions, FSProvider.getFileSystem()); + } + Opts.ClangTidyOptProvider = ClangTidyOptProvider.get(); Opts.SuggestMissingIncludes = SuggestMissingIncludes; ClangdLSPServer LSPServer( *TransportLayer, FSProvider, CCOpts, CompileCommandsDirPath, -- cgit v1.2.3 From a093fa64c7b354d699360e477d35cc5d0d22e0f7 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 6 Feb 2019 13:47:49 +0000 Subject: [clangd] Enable clangd on Objective-C in VSCode Summary: Thanks to Andreas Ostermeyer for raising this on the mailing list. Reviewers: hokein Reviewed By: hokein Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57813 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353295 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/clients/clangd-vscode/package.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clangd/clients/clangd-vscode/package.json b/clangd/clients/clangd-vscode/package.json index bea96537..36e8e692 100644 --- a/clangd/clients/clangd-vscode/package.json +++ b/clangd/clients/clangd-vscode/package.json @@ -21,8 +21,10 @@ "LLVM" ], "activationEvents": [ + "onLanguage:c", "onLanguage:cpp", - "onLanguage:c" + "onLanguage:objective-c", + "onLanguage:objective-cpp" ], "main": "./out/src/extension", "scripts": { -- cgit v1.2.3 From 90319cdadc486051c44d8b4f0f3e7b3f713948e9 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 6 Feb 2019 13:53:24 +0000 Subject: [clangd] Update dev dependencies of clangd-vscode Summary: The version bumps are a result of running `npm audit`, which found 3 security issues in previous versions of our dependencies. Also add 'package-lock.json' to the repo, it's a common practice to check in those files into the repository to get consistent versions of dependencies when running on different machines. Reviewers: hokein Reviewed By: hokein Subscribers: dschuff, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57814 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353296 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/clients/clangd-vscode/.gitignore | 1 - clangd/clients/clangd-vscode/package-lock.json | 2027 ++++++++++++++++++++++++ clangd/clients/clangd-vscode/package.json | 8 +- 3 files changed, 2031 insertions(+), 5 deletions(-) create mode 100644 clangd/clients/clangd-vscode/package-lock.json diff --git a/clangd/clients/clangd-vscode/.gitignore b/clangd/clients/clangd-vscode/.gitignore index 1294fe26..5df8049b 100644 --- a/clangd/clients/clangd-vscode/.gitignore +++ b/clangd/clients/clangd-vscode/.gitignore @@ -1,3 +1,2 @@ out node_modules -package-lock.json diff --git a/clangd/clients/clangd-vscode/package-lock.json b/clangd/clients/clangd-vscode/package-lock.json new file mode 100644 index 00000000..90685912 --- /dev/null +++ b/clangd/clients/clangd-vscode/package-lock.json @@ -0,0 +1,2027 @@ +{ + "name": "vscode-clangd", + "version": "0.0.10", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/mocha": { + "version": "2.2.48", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.48.tgz", + "integrity": "sha512-nlK/iyETgafGli8Zh9zJVCTicvU3iajSkRwOh3Hhiva598CMqNJ4NcVCGMTGKpGpTYj/9R8RLzS9NAykSSCqGw==", + "dev": true + }, + "@types/node": { + "version": "6.14.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-6.14.2.tgz", + "integrity": "sha512-JWB3xaVfsfnFY8Ofc9rTB/op0fqqTSqy4vBcVk1LuRJvta7KTX+D//fCkiTMeLGhdr2EbFZzQjC97gvmPilk9Q==", + "dev": true + }, + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-cyan": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-cyan/-/ansi-cyan-0.1.1.tgz", + "integrity": "sha1-U4rlKK+JgvKK4w2G8vF0VtJgmHM=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-red": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ansi-red/-/ansi-red-0.1.1.tgz", + "integrity": "sha1-jGOPnRCAgAo1PJwoyKgcpHBdlGw=", + "dev": true, + "requires": { + "ansi-wrap": "0.1.0" + } + }, + "ansi-wrap": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "arr-diff": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz", + "integrity": "sha1-aHwydYFjWI/vfeezb6vklesaOZo=", + "dev": true, + "requires": { + "arr-flatten": "^1.0.1", + "array-slice": "^0.2.3" + } + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-2.1.0.tgz", + "integrity": "sha1-IPnqtexw9cfSFbEHexw5Fh0pLH0=", + "dev": true + }, + "array-differ": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true + }, + "array-slice": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", + "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "dev": true + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "clone": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz", + "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-stats": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz", + "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "dashdash": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", + "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-assign": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", + "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "event-stream": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz", + "integrity": "sha1-SrTJoPWlTbkzi0w02Gv86PSzVXE=", + "dev": true, + "requires": { + "duplexer": "~0.1.1", + "from": "~0", + "map-stream": "~0.1.0", + "pause-stream": "0.0.11", + "split": "0.3", + "stream-combiner": "~0.0.4", + "through": "~2.3.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-1.1.4.tgz", + "integrity": "sha1-Gda/lN/AnXa6cR85uHLSH/TdkHE=", + "dev": true, + "requires": { + "kind-of": "^1.1.0" + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "flush-write-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.0.tgz", + "integrity": "sha512-6MHED/cmsyux1G4/Cek2Z776y9t7WCNd3h2h/HW91vFeU7pzMhA8XvAlDhHcanG5IWuIh/xcC7JASY4WQpG6xg==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", + "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "from": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz", + "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=", + "dev": true + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "gulp-chmod": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-chmod/-/gulp-chmod-2.0.0.tgz", + "integrity": "sha1-AMOQuSigeZslGsz2MaoJ4BzGKZw=", + "dev": true, + "requires": { + "deep-assign": "^1.0.0", + "stat-mode": "^0.2.0", + "through2": "^2.0.0" + } + }, + "gulp-filter": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/gulp-filter/-/gulp-filter-5.1.0.tgz", + "integrity": "sha1-oF4Rr/sHz33PQafeHLe2OsN4PnM=", + "dev": true, + "requires": { + "multimatch": "^2.0.0", + "plugin-error": "^0.1.2", + "streamfilter": "^1.0.5" + } + }, + "gulp-gunzip": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gulp-gunzip/-/gulp-gunzip-1.0.0.tgz", + "integrity": "sha1-FbdBFF6Dqcb1CIYkG1fMWHHxUak=", + "dev": true, + "requires": { + "through2": "~0.6.5", + "vinyl": "~0.4.6" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "through2": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", + "dev": true, + "requires": { + "readable-stream": ">=1.0.33-1 <1.1.0-0", + "xtend": ">=4.0.0 <4.1.0-0" + } + } + } + }, + "gulp-remote-src-vscode": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/gulp-remote-src-vscode/-/gulp-remote-src-vscode-0.5.1.tgz", + "integrity": "sha512-mw4OGjtC/jlCWJFhbcAlel4YPvccChlpsl3JceNiB/DLJi24/UPxXt53/N26lgI3dknEqd4ErfdHrO8sJ5bATQ==", + "dev": true, + "requires": { + "event-stream": "3.3.4", + "node.extend": "^1.1.2", + "request": "^2.79.0", + "through2": "^2.0.3", + "vinyl": "^2.0.1" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "gulp-untar": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/gulp-untar/-/gulp-untar-0.0.7.tgz", + "integrity": "sha512-0QfbCH2a1k2qkTLWPqTX+QO4qNsHn3kC546YhAP3/n0h+nvtyGITDuDrYBMDZeW4WnFijmkOvBWa5HshTic1tw==", + "dev": true, + "requires": { + "event-stream": "~3.3.4", + "streamifier": "~0.1.1", + "tar": "^2.2.1", + "through2": "~2.0.3", + "vinyl": "^1.2.0" + }, + "dependencies": { + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "vinyl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-1.2.0.tgz", + "integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=", + "dev": true, + "requires": { + "clone": "^1.0.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + } + } + }, + "gulp-vinyl-zip": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/gulp-vinyl-zip/-/gulp-vinyl-zip-2.1.2.tgz", + "integrity": "sha512-wJn09jsb8PyvUeyFF7y7ImEJqJwYy40BqL9GKfJs6UGpaGW9A+N68Q+ajsIpb9AeR6lAdjMbIdDPclIGo1/b7Q==", + "dev": true, + "requires": { + "event-stream": "3.3.4", + "queue": "^4.2.1", + "through2": "^2.0.3", + "vinyl": "^2.0.2", + "vinyl-fs": "^3.0.3", + "yauzl": "^2.2.1", + "yazl": "^2.2.1" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "is": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", + "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true + }, + "json-schema": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "jsprim": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", + "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "kind-of": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-1.1.0.tgz", + "integrity": "sha1-FAo9LUGjbS78+pN3tiwk+ElaXEQ=", + "dev": true + }, + "lazystream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", + "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "map-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz", + "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + }, + "dependencies": { + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "node.extend": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/node.extend/-/node.extend-1.1.8.tgz", + "integrity": "sha512-L/dvEBwyg3UowwqOUTyDsGBU6kjBQOpOhshio9V3i3BMPv5YUb9+mWNN8MK0IbWqT0AqaTSONZf0aTuMMahWgA==", + "dev": true, + "requires": { + "has": "^1.0.3", + "is": "^3.2.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "now-and-later": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", + "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pause-stream": { + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", + "dev": true, + "requires": { + "through": "~2.3" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "plugin-error": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-0.1.2.tgz", + "integrity": "sha1-O5uzM1zPAPQl4HQ34ZJ2ln2kes4=", + "dev": true, + "requires": { + "ansi-cyan": "^0.1.1", + "ansi-red": "^0.1.1", + "arr-diff": "^1.0.1", + "arr-union": "^2.0.1", + "extend-shallow": "^1.1.2" + } + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "querystringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.0.tgz", + "integrity": "sha512-sluvZZ1YiTLD5jsqZcDmFyV2EwToyXZBfpoVOmktMmW+VEnhgakFHnasVph65fOjGPTWN0Nw3+XQaSeMayr0kg==", + "dev": true + }, + "queue": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/queue/-/queue-4.5.1.tgz", + "integrity": "sha512-AMD7w5hRXcFSb8s9u38acBZ+309u6GsiibP4/0YacJeaurRshogB7v/ZcVPxP5gD5+zIw6ixRHdutiYUJfwKHw==", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "split": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", + "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", + "dev": true, + "requires": { + "through": "2" + } + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stat-mode": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-0.2.2.tgz", + "integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=", + "dev": true + }, + "stream-combiner": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz", + "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=", + "dev": true, + "requires": { + "duplexer": "~0.1.1" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "streamfilter": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/streamfilter/-/streamfilter-1.0.7.tgz", + "integrity": "sha512-Gk6KZM+yNA1JpW0KzlZIhjo3EaBJDkYfXtYSbOwNIQ7Zd6006E6+sCFlW1NDvFG/vnXhKmw6TJJgiEQg/8lXfQ==", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "streamifier": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/streamifier/-/streamifier-0.1.1.tgz", + "integrity": "sha1-l+mNj6TRBdYqJpHR3AfoINuN/E8=", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + }, + "dependencies": { + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + } + } + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + }, + "typescript": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "url-parse": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.4.tgz", + "integrity": "sha512-/92DTTorg4JjktLNLe6GPS2/RvAd/RGr6LuktmWSMLEOa6rjnlrFXNgSbSmkNvCoL2T028A0a1JaJLzRMlFoHg==", + "dev": true, + "requires": { + "querystringify": "^2.0.0", + "requires-port": "^1.0.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vinyl": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz", + "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=", + "dev": true, + "requires": { + "clone": "^0.2.0", + "clone-stats": "^0.0.1" + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "vinyl-source-stream": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vinyl-source-stream/-/vinyl-source-stream-1.1.2.tgz", + "integrity": "sha1-YrU6E1YQqJbpjKlr7jqH8Aio54A=", + "dev": true, + "requires": { + "through2": "^2.0.3", + "vinyl": "^0.4.3" + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "vinyl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz", + "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "vscode": { + "version": "1.1.28", + "resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.28.tgz", + "integrity": "sha512-vxpRMKVa/DgSihyy8I7puRZKiwQm9NK/e5oDTEFDtughhEHrspi0UaXKe795b1DFgO3XJe6KLiXzC8mJonvvWw==", + "dev": true, + "requires": { + "glob": "^7.1.2", + "gulp-chmod": "^2.0.0", + "gulp-filter": "^5.0.1", + "gulp-gunzip": "1.0.0", + "gulp-remote-src-vscode": "^0.5.1", + "gulp-untar": "^0.0.7", + "gulp-vinyl-zip": "^2.1.2", + "mocha": "^4.0.1", + "request": "^2.88.0", + "semver": "^5.4.1", + "source-map-support": "^0.5.0", + "url-parse": "^1.4.3", + "vinyl-fs": "^3.0.3", + "vinyl-source-stream": "^1.1.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "diff": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", + "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mocha": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", + "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "dev": true, + "requires": { + "browser-stdout": "1.3.0", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.3.1", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.3", + "he": "1.1.1", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + } + } + } + }, + "vscode-jsonrpc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", + "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==" + }, + "vscode-languageclient": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz", + "integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==", + "requires": { + "semver": "^5.5.0", + "vscode-languageserver-protocol": "3.14.1" + } + }, + "vscode-languageserver": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", + "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", + "requires": { + "vscode-languageserver-protocol": "3.14.1", + "vscode-uri": "^1.0.6" + } + }, + "vscode-languageserver-protocol": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", + "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", + "requires": { + "vscode-jsonrpc": "^4.0.0", + "vscode-languageserver-types": "3.14.0" + } + }, + "vscode-languageserver-types": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", + "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==" + }, + "vscode-uri": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.6.tgz", + "integrity": "sha512-sLI2L0uGov3wKVb9EB+vIQBl9tVP90nqRvxSoJ35vI3NjxE8jfsE5DSOhWgSunHSZmKS4OCi2jrtfxK7uyp2ww==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } + } + } +} diff --git a/clangd/clients/clangd-vscode/package.json b/clangd/clients/clangd-vscode/package.json index 36e8e692..31a259b4 100644 --- a/clangd/clients/clangd-vscode/package.json +++ b/clangd/clients/clangd-vscode/package.json @@ -38,11 +38,11 @@ "vscode-languageserver": "^5.2.0" }, "devDependencies": { - "typescript": "^2.0.3", - "vscode": "^1.1.0", - "mocha": "^2.3.3", + "@types/mocha": "^2.2.32", "@types/node": "^6.0.40", - "@types/mocha": "^2.2.32" + "mocha": "^5.2.0", + "typescript": "^2.0.3", + "vscode": "^1.1.0" }, "repository": { "type": "svn", -- cgit v1.2.3 From a3ef8503a646dc3832cbdeed1fe08a6a29d1b722 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 6 Feb 2019 15:24:50 +0000 Subject: [clangd] Format tweak's replacements. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353306 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdServer.cpp | 6 +++-- clangd/ClangdUnit.cpp | 3 +-- clangd/Compiler.h | 2 ++ clangd/SourceCode.cpp | 9 +++++++ clangd/SourceCode.h | 5 ++++ clangd/refactor/Tweak.cpp | 8 +++++++ clangd/refactor/Tweak.h | 14 ++++++++--- clangd/refactor/tweaks/SwapIfBranches.cpp | 7 ++++-- unittests/clangd/TweakTests.cpp | 40 +++++++++++++++++++++++++++---- 9 files changed, 81 insertions(+), 13 deletions(-) diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 2dcf0fb3..1aa87998 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -152,6 +152,9 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); if (ClangTidyOptProvider) Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File); + // FIXME: cache this. + Opts.Style = + getFormatStyleForFile(File, Contents, FSProvider.getFileSystem().get()); Opts.SuggestMissingIncludes = SuggestMissingIncludes; // FIXME: some build systems like Bazel will take time to preparing // environment to build the file, it would be nice if we could emit a @@ -372,8 +375,7 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, auto A = prepareTweak(TweakID, *Selection); if (!A) return CB(A.takeError()); - // FIXME: run formatter on top of resulting replacements. - return CB((*A)->apply(*Selection)); + return CB((*A)->apply(*Selection, InpAST->Inputs.Opts.Style)); }; WorkScheduler.runWithAST( "ApplyTweak", File, diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index ffb96fbf..cb7fae5f 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -309,9 +309,8 @@ ParsedAST::build(std::unique_ptr CI, llvm::Optional FixIncludes; auto BuildDir = VFS->getCurrentWorkingDirectory(); if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) { - auto Style = getFormatStyleForFile(MainInput.getFile(), Content, VFS.get()); auto Inserter = std::make_shared( - MainInput.getFile(), Content, Style, BuildDir.get(), + MainInput.getFile(), Content, Opts.Style, BuildDir.get(), Clang->getPreprocessor().getHeaderSearchInfo()); if (Preamble) { for (const auto &Inc : Preamble->Includes.MainFileIncludes) diff --git a/clangd/Compiler.h b/clangd/Compiler.h index 9466d8e2..2d5c1b3e 100644 --- a/clangd/Compiler.h +++ b/clangd/Compiler.h @@ -17,6 +17,7 @@ #include "../clang-tidy/ClangTidyOptions.h" #include "index/Index.h" +#include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PrecompiledPreamble.h" @@ -38,6 +39,7 @@ public: struct ParseOptions { tidy::ClangTidyOptions ClangTidyOpts; bool SuggestMissingIncludes = false; + format::FormatStyle Style; }; /// Information required to run clang, e.g. to parse AST or do code completion. diff --git a/clangd/SourceCode.cpp b/clangd/SourceCode.cpp index a4af1a9d..86146758 100644 --- a/clangd/SourceCode.cpp +++ b/clangd/SourceCode.cpp @@ -335,5 +335,14 @@ format::FormatStyle getFormatStyleForFile(llvm::StringRef File, return *Style; } +llvm::Expected +cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces, + const format::FormatStyle &Style) { + auto CleanReplaces = cleanupAroundReplacements(Code, Replaces, Style); + if (!CleanReplaces) + return CleanReplaces; + return formatReplacements(Code, std::move(*CleanReplaces), Style); +} + } // namespace clangd } // namespace clang diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index 37b7b166..e6ce8c3b 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -144,6 +144,11 @@ format::FormatStyle getFormatStyleForFile(llvm::StringRef File, llvm::StringRef Content, llvm::vfs::FileSystem *FS); +// Cleanup and format the given replacements. +llvm::Expected +cleanupAndFormat(StringRef Code, const tooling::Replacements &Replaces, + const format::FormatStyle &Style); + } // namespace clangd } // namespace clang #endif diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp index 34634e64..6a3b090b 100644 --- a/clangd/refactor/Tweak.cpp +++ b/clangd/refactor/Tweak.cpp @@ -46,6 +46,14 @@ Tweak::Selection::Selection(ParsedAST &AST, unsigned RangeBegin, Cursor = SM.getComposedLoc(SM.getMainFileID(), RangeBegin); } +Expected Tweak::apply(const Selection &Sel, + const format::FormatStyle &Style) { + auto RawReplacements = execute(Sel); + if (!RawReplacements) + return RawReplacements; + return cleanupAndFormat(Sel.Code, *RawReplacements, Style); +} + std::vector> prepareTweaks(const Tweak::Selection &S) { validateRegistry(); diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h index 35c3ce8a..108e07e1 100644 --- a/clangd/refactor/Tweak.h +++ b/clangd/refactor/Tweak.h @@ -22,6 +22,7 @@ #include "ClangdUnit.h" #include "Protocol.h" #include "Selection.h" +#include "clang/Format/Format.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -47,7 +48,7 @@ public: ParsedAST &AST; /// A location of the cursor in the editor. SourceLocation Cursor; - // The AST nodes that were selected. + /// The AST nodes that were selected. SelectionTree ASTSelection; // FIXME: provide a way to get sources and ASTs for other files. }; @@ -63,13 +64,20 @@ public: /// should be moved into 'apply'. /// Returns true iff the action is available and apply() can be called on it. virtual bool prepare(const Selection &Sel) = 0; - /// Run the second stage of the action that would produce the actual changes. + /// Format and apply the actual changes generated from the second stage of the + /// action. /// EXPECTS: prepare() was called and returned true. - virtual Expected apply(const Selection &Sel) = 0; + Expected apply(const Selection &Sel, + const format::FormatStyle &Style); /// A one-line title of the action that should be shown to the users in the /// UI. /// EXPECTS: prepare() was called and returned true. virtual std::string title() const = 0; + +protected: + /// Run the second stage of the action that would produce the actual changes. + /// EXPECTS: prepare() was called and returned true. + virtual Expected execute(const Selection &Sel) = 0; }; // All tweaks must be registered in the .cpp file next to their definition. diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp index 9b0b72d9..40dd6987 100644 --- a/clangd/refactor/tweaks/SwapIfBranches.cpp +++ b/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -37,9 +37,11 @@ public: const char *id() const override final; bool prepare(const Selection &Inputs) override; - Expected apply(const Selection &Inputs) override; std::string title() const override; +protected: + Expected execute(const Selection &Inputs) override; + private: const IfStmt *If = nullptr; }; @@ -60,7 +62,8 @@ bool SwapIfBranches::prepare(const Selection &Inputs) { dyn_cast_or_null(If->getElse()); } -Expected SwapIfBranches::apply(const Selection &Inputs) { +Expected +SwapIfBranches::execute(const Selection &Inputs) { auto &Ctx = Inputs.AST.getASTContext(); auto &SrcMgr = Ctx.getSourceManager(); diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp index baa60292..a76d3aea 100644 --- a/unittests/clangd/TweakTests.cpp +++ b/unittests/clangd/TweakTests.cpp @@ -98,7 +98,7 @@ llvm::Expected apply(StringRef ID, llvm::StringRef Input) { auto T = prepareTweak(ID, S); if (!T) return T.takeError(); - auto Replacements = (*T)->apply(S); + auto Replacements = (*T)->apply(S, clang::format::getLLVMStyle()); if (!Replacements) return Replacements.takeError(); return applyAllReplacements(Code.code(), *Replacements); @@ -127,12 +127,40 @@ TEST(TweakTest, SwapIfBranches) { llvm::StringLiteral Input = R"cpp( void test() { - ^if (true) { return 100; } else { continue; } + ^if (true) { + return 100; + } else { + continue; + } } )cpp"; llvm::StringLiteral Output = R"cpp( void test() { - if (true) { continue; } else { return 100; } + if (true) { + continue; + } else { + return 100; + } + } + )cpp"; + checkTransform(ID, Input, Output); + + Input = R"cpp( + void test() { + ^if () { + return 100; + } else { + continue; + } + } + )cpp"; + Output = R"cpp( + void test() { + if () { + continue; + } else { + return 100; + } } )cpp"; checkTransform(ID, Input, Output); @@ -144,7 +172,11 @@ TEST(TweakTest, SwapIfBranches) { )cpp"; Output = R"cpp( void test() { - if () { continue; } else { return 100; } + if () { + continue; + } else { + return 100; + } } )cpp"; checkTransform(ID, Input, Output); -- cgit v1.2.3 From 43a3e0bbe965dd09c19d82d3d2cb83eac9391b56 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 6 Feb 2019 15:29:54 +0000 Subject: [clangd] Bump vscode-clangd v0.0.11 CHANGELOG: - activate the extension on ObjC files. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353309 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/clients/clangd-vscode/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/clients/clangd-vscode/package.json b/clangd/clients/clangd-vscode/package.json index 31a259b4..f9ac9222 100644 --- a/clangd/clients/clangd-vscode/package.json +++ b/clangd/clients/clangd-vscode/package.json @@ -2,7 +2,7 @@ "name": "vscode-clangd", "displayName": "vscode-clangd", "description": "Clang Language Server", - "version": "0.0.10", + "version": "0.0.11", "publisher": "llvm-vs-code-extensions", "homepage": "https://clang.llvm.org/extra/clangd.html", "engines": { -- cgit v1.2.3 From a7e2607804824a5f76de936530259e7e0a24b17e Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 6 Feb 2019 15:36:23 +0000 Subject: [clangd] Add type boost to fuzzy find in Dex. Summary: No noticeable impact on code completions overall except some improvement on cross-namespace completion. Reviewers: sammccall, ilya-biryukov Reviewed By: sammccall Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57815 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353310 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CodeComplete.cpp | 2 + clangd/index/Index.cpp | 4 +- clangd/index/Index.h | 9 ++-- clangd/index/dex/Dex.cpp | 99 ++++++++++++++++++++++++------------------- clangd/index/dex/Dex.h | 4 ++ clangd/index/dex/Token.h | 7 ++- unittests/clangd/DexTests.cpp | 22 ++++++++++ 7 files changed, 97 insertions(+), 50 deletions(-) diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 83dcfb7a..b059216a 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1333,6 +1333,8 @@ private: Req.AnyScope = AllScopes; // FIXME: we should send multiple weighted paths here. Req.ProximityPaths.push_back(FileName); + if (PreferredType) + Req.PreferredTypes.push_back(PreferredType->raw()); vlog("Code complete: fuzzyFind({0:2})", toJSON(Req)); if (SpecFuzzyFind) diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index c773cd69..36c591d9 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -179,7 +179,8 @@ bool fromJSON(const llvm::json::Value &Parameters, FuzzyFindRequest &Request) { O && O.map("Query", Request.Query) && O.map("Scopes", Request.Scopes) && O.map("AnyScope", Request.AnyScope) && O.map("Limit", Limit) && O.map("RestrictForCodeCompletion", Request.RestrictForCodeCompletion) && - O.map("ProximityPaths", Request.ProximityPaths); + O.map("ProximityPaths", Request.ProximityPaths) && + O.map("PreferredTypes", Request.PreferredTypes); if (OK && Limit <= std::numeric_limits::max()) Request.Limit = Limit; return OK; @@ -193,6 +194,7 @@ llvm::json::Value toJSON(const FuzzyFindRequest &Request) { {"Limit", Request.Limit}, {"RestrictForCodeCompletion", Request.RestrictForCodeCompletion}, {"ProximityPaths", llvm::json::Array{Request.ProximityPaths}}, + {"PreferredTypes", llvm::json::Array{Request.PreferredTypes}}, }; } diff --git a/clangd/index/Index.h b/clangd/index/Index.h index d36dd299..4f6feb93 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -454,14 +454,15 @@ struct FuzzyFindRequest { /// Contextually relevant files (e.g. the file we're code-completing in). /// Paths should be absolute. std::vector ProximityPaths; - - // FIXME(ibiryukov): add expected type to the request. + /// Preferred types of symbols. These are raw representation of `OpaqueType`. + std::vector PreferredTypes; bool operator==(const FuzzyFindRequest &Req) const { return std::tie(Query, Scopes, Limit, RestrictForCodeCompletion, - ProximityPaths) == + ProximityPaths, PreferredTypes) == std::tie(Req.Query, Req.Scopes, Req.Limit, - Req.RestrictForCodeCompletion, Req.ProximityPaths); + Req.RestrictForCodeCompletion, Req.ProximityPaths, + Req.PreferredTypes); } bool operator!=(const FuzzyFindRequest &Req) const { return !(*this == Req); } }; diff --git a/clangd/index/dex/Dex.cpp b/clangd/index/dex/Dex.cpp index b4db1136..d767bb51 100644 --- a/clangd/index/dex/Dex.cpp +++ b/clangd/index/dex/Dex.cpp @@ -42,7 +42,6 @@ const Token RestrictedForCodeCompletion = // Returns the tokens which are given symbols's characteristics. For example, // trigrams and scopes. // FIXME(kbobyrev): Support more token types: -// * Types // * Namespace proximity std::vector generateSearchTokens(const Symbol &Sym) { std::vector Result = generateIdentifierTrigrams(Sym.Name); @@ -54,49 +53,11 @@ std::vector generateSearchTokens(const Symbol &Sym) { Result.emplace_back(Token::Kind::ProximityURI, ProximityURI); if (Sym.Flags & Symbol::IndexedForCodeCompletion) Result.emplace_back(RestrictedForCodeCompletion); + if (!Sym.Type.empty()) + Result.emplace_back(Token::Kind::Type, Sym.Type); return Result; } -// Constructs BOOST iterators for Path Proximities. -std::unique_ptr createFileProximityIterator( - llvm::ArrayRef ProximityPaths, - const llvm::DenseMap &InvertedIndex, - const Corpus &Corpus) { - std::vector> BoostingIterators; - // Deduplicate parent URIs extracted from the ProximityPaths. - llvm::StringSet<> ParentURIs; - llvm::StringMap Sources; - for (const auto &Path : ProximityPaths) { - Sources[Path] = SourceParams(); - auto PathURI = URI::create(Path); - const auto PathProximityURIs = generateProximityURIs(PathURI.toString()); - for (const auto &ProximityURI : PathProximityURIs) - ParentURIs.insert(ProximityURI); - } - // Use SymbolRelevanceSignals for symbol relevance evaluation: use defaults - // for all parameters except for Proximity Path distance signal. - SymbolRelevanceSignals PathProximitySignals; - // DistanceCalculator will find the shortest distance from ProximityPaths to - // any URI extracted from the ProximityPaths. - URIDistance DistanceCalculator(Sources); - PathProximitySignals.FileProximityMatch = &DistanceCalculator; - // Try to build BOOST iterator for each Proximity Path provided by - // ProximityPaths. Boosting factor should depend on the distance to the - // Proximity Path: the closer processed path is, the higher boosting factor. - for (const auto &ParentURI : ParentURIs.keys()) { - Token Tok(Token::Kind::ProximityURI, ParentURI); - const auto It = InvertedIndex.find(Tok); - if (It != InvertedIndex.end()) { - // FIXME(kbobyrev): Append LIMIT on top of every BOOST iterator. - PathProximitySignals.SymbolURI = ParentURI; - BoostingIterators.push_back(Corpus.boost( - It->second.iterator(&It->first), PathProximitySignals.evaluate())); - } - } - BoostingIterators.push_back(Corpus.all()); - return Corpus.unionOf(std::move(BoostingIterators)); -} - } // namespace void Dex::buildIndex() { @@ -141,6 +102,57 @@ std::unique_ptr Dex::iterator(const Token &Tok) const { : It->second.iterator(&It->first); } +// Constructs BOOST iterators for Path Proximities. +std::unique_ptr Dex::createFileProximityIterator( + llvm::ArrayRef ProximityPaths) const { + std::vector> BoostingIterators; + // Deduplicate parent URIs extracted from the ProximityPaths. + llvm::StringSet<> ParentURIs; + llvm::StringMap Sources; + for (const auto &Path : ProximityPaths) { + Sources[Path] = SourceParams(); + auto PathURI = URI::create(Path); + const auto PathProximityURIs = generateProximityURIs(PathURI.toString()); + for (const auto &ProximityURI : PathProximityURIs) + ParentURIs.insert(ProximityURI); + } + // Use SymbolRelevanceSignals for symbol relevance evaluation: use defaults + // for all parameters except for Proximity Path distance signal. + SymbolRelevanceSignals PathProximitySignals; + // DistanceCalculator will find the shortest distance from ProximityPaths to + // any URI extracted from the ProximityPaths. + URIDistance DistanceCalculator(Sources); + PathProximitySignals.FileProximityMatch = &DistanceCalculator; + // Try to build BOOST iterator for each Proximity Path provided by + // ProximityPaths. Boosting factor should depend on the distance to the + // Proximity Path: the closer processed path is, the higher boosting factor. + for (const auto &ParentURI : ParentURIs.keys()) { + // FIXME(kbobyrev): Append LIMIT on top of every BOOST iterator. + auto It = iterator(Token(Token::Kind::ProximityURI, ParentURI)); + if (It->kind() != Iterator::Kind::False) { + PathProximitySignals.SymbolURI = ParentURI; + BoostingIterators.push_back( + Corpus.boost(std::move(It), PathProximitySignals.evaluate())); + } + } + BoostingIterators.push_back(Corpus.all()); + return Corpus.unionOf(std::move(BoostingIterators)); +} + +// Constructs BOOST iterators for preferred types. +std::unique_ptr +Dex::createTypeBoostingIterator(llvm::ArrayRef Types) const { + std::vector> BoostingIterators; + SymbolRelevanceSignals PreferredTypeSignals; + PreferredTypeSignals.TypeMatchesPreferred = true; + auto Boost = PreferredTypeSignals.evaluate(); + for (const auto &T : Types) + BoostingIterators.push_back( + Corpus.boost(iterator(Token(Token::Kind::Type, T)), Boost)); + BoostingIterators.push_back(Corpus.all()); + return Corpus.unionOf(std::move(BoostingIterators)); +} + /// Constructs iterators over tokens extracted from the query and exhausts it /// while applying Callback to each symbol in the order of decreasing quality /// of the matched symbols. @@ -174,8 +186,9 @@ bool Dex::fuzzyFind(const FuzzyFindRequest &Req, Criteria.push_back(Corpus.unionOf(move(ScopeIterators))); // Add proximity paths boosting (all symbols, some boosted). - Criteria.push_back( - createFileProximityIterator(Req.ProximityPaths, InvertedIndex, Corpus)); + Criteria.push_back(createFileProximityIterator(Req.ProximityPaths)); + // Add boosting for preferred types. + Criteria.push_back(createTypeBoostingIterator(Req.PreferredTypes)); if (Req.RestrictForCodeCompletion) Criteria.push_back(iterator(RestrictedForCodeCompletion)); diff --git a/clangd/index/dex/Dex.h b/clangd/index/dex/Dex.h index 71814e43..fb80ca03 100644 --- a/clangd/index/dex/Dex.h +++ b/clangd/index/dex/Dex.h @@ -77,6 +77,10 @@ public: private: void buildIndex(); std::unique_ptr iterator(const Token &Tok) const; + std::unique_ptr + createFileProximityIterator(llvm::ArrayRef ProximityPaths) const; + std::unique_ptr + createTypeBoostingIterator(llvm::ArrayRef Types) const; /// Stores symbols sorted in the descending order of symbol quality.. std::vector Symbols; diff --git a/clangd/index/dex/Token.h b/clangd/index/dex/Token.h index 4c67e9fa..37859bcf 100644 --- a/clangd/index/dex/Token.h +++ b/clangd/index/dex/Token.h @@ -62,11 +62,11 @@ struct Token { /// Example: "file:///path/to/clang-tools-extra/clangd/index/SymbolIndex.h" /// and some amount of its parents. ProximityURI, + /// Type of symbol (see `Symbol::Type`). + Type, /// Internal Token type for invalid/special tokens, e.g. empty tokens for /// llvm::DenseMap. Sentinel, - /// FIXME(kbobyrev): Add other Token Kinds - /// * Type with qualified type name or its USR }; Token(Kind TokenKind, llvm::StringRef Data) @@ -91,6 +91,9 @@ struct Token { case Kind::ProximityURI: OS << "U="; break; + case Kind::Type: + OS << "Ty="; + break; case Kind::Sentinel: OS << "?="; break; diff --git a/unittests/clangd/DexTests.cpp b/unittests/clangd/DexTests.cpp index ce318e2e..cd52daac 100644 --- a/unittests/clangd/DexTests.cpp +++ b/unittests/clangd/DexTests.cpp @@ -688,6 +688,28 @@ TEST(DexTests, Refs) { EXPECT_THAT(Files, ElementsAre(AnyOf("foo.h", "foo.cc"))); } +TEST(DexTest, PreferredTypesBoosting) { + auto Sym1 = symbol("t1"); + Sym1.Type = "T1"; + auto Sym2 = symbol("t2"); + Sym2.Type = "T2"; + + std::vector Symbols{Sym1, Sym2}; + Dex I(Symbols, RefSlab()); + + FuzzyFindRequest Req; + Req.AnyScope = true; + Req.Query = "t"; + // The best candidate can change depending on the preferred type. + Req.Limit = 1; + + Req.PreferredTypes = {Sym1.Type}; + EXPECT_THAT(match(I, Req), ElementsAre("t1")); + + Req.PreferredTypes = {Sym2.Type}; + EXPECT_THAT(match(I, Req), ElementsAre("t2")); +} + } // namespace } // namespace dex } // namespace clangd -- cgit v1.2.3 From a3c45a211572ba218550e426a29ef00b05c4ad40 Mon Sep 17 00:00:00 2001 From: Roman Lebedev Date: Wed, 6 Feb 2019 19:17:30 +0000 Subject: [clang-tidy] modernize-avoid-c-arrays: avoid main function (PR40604) Summary: The check should ignore the main function, the program entry point. It is not possible to use `std::array<>` for the `argv`. The alternative is to use `char** argv`. Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=40604 | PR40604 ]] Reviewers: JonasToth, aaron.ballman Reviewed By: aaron.ballman Subscribers: xazax.hun, hans, cfe-commits Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D57787 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353327 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/modernize/AvoidCArraysCheck.cpp | 9 ++++++++- docs/clang-tidy/checks/modernize-avoid-c-arrays.rst | 4 ++++ .../modernize-avoid-c-arrays-ignores-main.cpp | 18 ++++++++++++++++++ ...dernize-avoid-c-arrays-ignores-three-arg-main.cpp | 20 ++++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp create mode 100644 test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp diff --git a/clang-tidy/modernize/AvoidCArraysCheck.cpp b/clang-tidy/modernize/AvoidCArraysCheck.cpp index bceda5c2..e3dffd06 100644 --- a/clang-tidy/modernize/AvoidCArraysCheck.cpp +++ b/clang-tidy/modernize/AvoidCArraysCheck.cpp @@ -30,6 +30,12 @@ AST_MATCHER(clang::RecordDecl, isExternCContext) { return Node.isExternCContext(); } +AST_MATCHER(clang::ParmVarDecl, isArgvOfMain) { + const clang::DeclContext *DC = Node.getDeclContext(); + const auto *FD = llvm::dyn_cast(DC); + return FD ? FD->isMain() : false; +} + } // namespace namespace clang { @@ -43,7 +49,8 @@ void AvoidCArraysCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( typeLoc(hasValidBeginLoc(), hasType(arrayType()), - unless(anyOf(hasParent(varDecl(isExternC())), + unless(anyOf(hasParent(parmVarDecl(isArgvOfMain())), + hasParent(varDecl(isExternC())), hasParent(fieldDecl( hasParent(recordDecl(isExternCContext())))), hasAncestor(functionDecl(isExternC()))))) diff --git a/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst b/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst index 8f856a52..d7bc7474 100644 --- a/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst +++ b/docs/clang-tidy/checks/modernize-avoid-c-arrays.rst @@ -54,3 +54,7 @@ such headers between C code, and C++ code. } } + +Similarly, the ``main()`` function is ignored. Its second and third parameters +can be either ``char* argv[]`` or ``char** argv``, but can not be +``std::array<>``. diff --git a/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp b/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp new file mode 100644 index 00000000..6549422f --- /dev/null +++ b/test/clang-tidy/modernize-avoid-c-arrays-ignores-main.cpp @@ -0,0 +1,18 @@ +// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t + +int not_main(int argc, char *argv[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead + int f4[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +} + +int main(int argc, char *argv[]) { + int f5[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead + + auto not_main = [](int argc, char *argv[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead + int f6[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead + }; +} diff --git a/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp b/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp new file mode 100644 index 00000000..22a4016f --- /dev/null +++ b/test/clang-tidy/modernize-avoid-c-arrays-ignores-three-arg-main.cpp @@ -0,0 +1,20 @@ +// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t + +int not_main(int argc, char *argv[], char *argw[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead + // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: do not declare C-style arrays, use std::array<> instead + int f4[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead +} + +int main(int argc, char *argv[], char *argw[]) { + int f5[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead + + auto not_main = [](int argc, char *argv[], char *argw[]) { + // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead + // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: do not declare C-style arrays, use std::array<> instead + int f6[] = {1, 2}; + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead + }; +} -- cgit v1.2.3 From 4ffeeada0e22434cd629cf6b5fd91752f1505e82 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 7 Feb 2019 09:23:22 +0000 Subject: [clangd] Suggest adding missing includes for typos (like include-fixer). Summary: This adds include-fixer feature into clangd based on D56903. Clangd now captures diagnostics caused by typos and attach include insertion fixes to potentially fix the typo. Reviewers: sammccall Reviewed By: sammccall Subscribers: cfe-commits, kadircet, arphaman, mgrang, jkorous, MaskRay, javed.absar, ilya-biryukov, mgorny Tags: #clang Differential Revision: https://reviews.llvm.org/D57021 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353380 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.cpp | 9 +- clangd/IncludeFixer.cpp | 212 +++++++++++++++++++++++++++++++--- clangd/IncludeFixer.h | 37 +++++- clangd/SourceCode.h | 10 +- unittests/clangd/DiagnosticsTests.cpp | 95 +++++++++++++-- 5 files changed, 329 insertions(+), 34 deletions(-) diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index cb7fae5f..09ab772d 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -322,6 +322,7 @@ ParsedAST::build(std::unique_ptr CI, const clang::Diagnostic &Info) { return FixIncludes->fix(DiagLevl, Info); }); + Clang->setExternalSemaSource(FixIncludes->unresolvedNameRecorder()); } // Copy over the includes from the preamble, then combine with the @@ -565,10 +566,10 @@ buildAST(PathRef FileName, std::unique_ptr Invocation, // dirs. } - return ParsedAST::build( - llvm::make_unique(*Invocation), Preamble, - llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents), PCHs, - std::move(VFS), Inputs.Index ? Inputs.Index : nullptr, Inputs.Opts); + return ParsedAST::build(llvm::make_unique(*Invocation), + Preamble, + llvm::MemoryBuffer::getMemBufferCopy(Inputs.Contents), + PCHs, std::move(VFS), Inputs.Index, Inputs.Opts); } SourceLocation getBeginningOfIdentifier(ParsedAST &Unit, const Position &Pos, diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index 0f498884..adcb51a4 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -14,16 +14,47 @@ #include "Trace.h" #include "index/Index.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" +#include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticSema.h" +#include "clang/Sema/DeclSpec.h" +#include "clang/Sema/Lookup.h" +#include "clang/Sema/Scope.h" +#include "clang/Sema/Sema.h" +#include "clang/Sema/TypoCorrection.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" +#include namespace clang { namespace clangd { +namespace { + +// Collects contexts visited during a Sema name lookup. +class VisitedContextCollector : public VisibleDeclConsumer { +public: + void EnteredContext(DeclContext *Ctx) override { Visited.push_back(Ctx); } + + void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx, + bool InBaseClass) override {} + + std::vector takeVisitedContexts() { + return std::move(Visited); + } + +private: + std::vector Visited; +}; + +} // namespace + std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) const { if (IndexRequestCount >= IndexRequestLimit) @@ -42,6 +73,28 @@ std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, return fixIncompleteType(*T); } } + break; + case diag::err_unknown_typename: + case diag::err_unknown_typename_suggest: + case diag::err_typename_nested_not_found: + case diag::err_no_template: + case diag::err_no_template_suggest: + if (LastUnresolvedName) { + // Try to fix unresolved name caused by missing declaraion. + // E.g. + // clang::SourceManager SM; + // ~~~~~~~~~~~~~ + // UnresolvedName + // or + // namespace clang { SourceManager SM; } + // ~~~~~~~~~~~~~ + // UnresolvedName + // We only attempt to recover a diagnostic if it has the same location as + // the last seen unresolved name. + if (DiagLevel >= DiagnosticsEngine::Error && + LastUnresolvedName->Loc == Info.getLocation()) + return fixUnresolvedName(); + } } return {}; } @@ -74,11 +127,12 @@ std::vector IncludeFixer::fixIncompleteType(const Type &T) const { if (!Matched || Matched->IncludeHeaders.empty() || !Matched->Definition || Matched->CanonicalDeclaration.FileURI != Matched->Definition.FileURI) return {}; - return fixesForSymbol(*Matched); + return fixesForSymbols({*Matched}); } -std::vector IncludeFixer::fixesForSymbol(const Symbol &Sym) const { - auto Inserted = [&](llvm::StringRef Header) +std::vector +IncludeFixer::fixesForSymbols(llvm::ArrayRef Syms) const { + auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header) -> llvm::Expected> { auto ResolvedDeclaring = toHeaderFile(Sym.CanonicalDeclaration.FileURI, File); @@ -93,21 +147,151 @@ std::vector IncludeFixer::fixesForSymbol(const Symbol &Sym) const { }; std::vector Fixes; - for (const auto &Inc : getRankedIncludes(Sym)) { - if (auto ToInclude = Inserted(Inc)) { - if (ToInclude->second) - if (auto Edit = Inserter->insert(ToInclude->first)) - Fixes.push_back( - Fix{llvm::formatv("Add include {0} for symbol {1}{2}", - ToInclude->first, Sym.Scope, Sym.Name), - {std::move(*Edit)}}); - } else { - vlog("Failed to calculate include insertion for {0} into {1}: {2}", File, - Inc, ToInclude.takeError()); + // Deduplicate fixes by include headers. This doesn't distiguish symbols in + // different scopes from the same header, but this case should be rare and is + // thus ignored. + llvm::StringSet<> InsertedHeaders; + for (const auto &Sym : Syms) { + for (const auto &Inc : getRankedIncludes(Sym)) { + if (auto ToInclude = Inserted(Sym, Inc)) { + if (ToInclude->second) { + auto I = InsertedHeaders.try_emplace(ToInclude->first); + if (!I.second) + continue; + if (auto Edit = Inserter->insert(ToInclude->first)) + Fixes.push_back( + Fix{llvm::formatv("Add include {0} for symbol {1}{2}", + ToInclude->first, Sym.Scope, Sym.Name), + {std::move(*Edit)}}); + } + } else { + vlog("Failed to calculate include insertion for {0} into {1}: {2}", + File, Inc, ToInclude.takeError()); + } } } return Fixes; } +class IncludeFixer::UnresolvedNameRecorder : public ExternalSemaSource { +public: + UnresolvedNameRecorder(llvm::Optional &LastUnresolvedName) + : LastUnresolvedName(LastUnresolvedName) {} + + void InitializeSema(Sema &S) override { this->SemaPtr = &S; } + + // Captures the latest typo and treat it as an unresolved name that can + // potentially be fixed by adding #includes. + TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, int LookupKind, + Scope *S, CXXScopeSpec *SS, + CorrectionCandidateCallback &CCC, + DeclContext *MemberContext, bool EnteringContext, + const ObjCObjectPointerType *OPT) override { + assert(SemaPtr && "Sema must have been set."); + if (SemaPtr->isSFINAEContext()) + return TypoCorrection(); + if (!SemaPtr->SourceMgr.isWrittenInMainFile(Typo.getLoc())) + return clang::TypoCorrection(); + + assert(S && "Enclosing scope must be set."); + + UnresolvedName Unresolved; + Unresolved.Name = Typo.getAsString(); + Unresolved.Loc = Typo.getBeginLoc(); + + // FIXME: support invalid scope before a type name. In the following + // example, namespace "clang::tidy::" hasn't been declared/imported. + // namespace clang { + // void f() { + // tidy::Check c; + // ~~~~ + // // or + // clang::tidy::Check c; + // ~~~~ + // } + // } + // For both cases, the typo and the diagnostic are both on "tidy", and no + // diagnostic is generated for "Check". However, what we want to fix is + // "clang::tidy::Check". + + // Extract the typed scope. This is not done lazily because `SS` can get + // out of scope and it's relatively cheap. + llvm::Optional SpecifiedScope; + if (SS && SS->isNotEmpty()) { // "::" or "ns::" + if (auto *Nested = SS->getScopeRep()) { + if (Nested->getKind() == NestedNameSpecifier::Global) + SpecifiedScope = ""; + else if (const auto *NS = Nested->getAsNamespace()) + SpecifiedScope = printNamespaceScope(*NS); + else + // We don't fix symbols in scopes that are not top-level e.g. class + // members, as we don't collect includes for them. + return TypoCorrection(); + } + } + + auto *Sem = SemaPtr; // Avoid capturing `this`. + Unresolved.GetScopes = [Sem, SpecifiedScope, S, LookupKind]() { + std::vector Scopes; + if (SpecifiedScope) { + Scopes.push_back(*SpecifiedScope); + } else { + // No scope qualifier is specified. Collect all accessible scopes in the + // context. + VisitedContextCollector Collector; + Sem->LookupVisibleDecls( + S, static_cast(LookupKind), Collector, + /*IncludeGlobalScope=*/false, + /*LoadExternal=*/false); + + Scopes.push_back(""); + for (const auto *Ctx : Collector.takeVisitedContexts()) + if (isa(Ctx)) + Scopes.push_back(printNamespaceScope(*Ctx)); + } + return Scopes; + }; + LastUnresolvedName = std::move(Unresolved); + + // Never return a valid correction to try to recover. Our suggested fixes + // always require a rebuild. + return TypoCorrection(); + } + +private: + Sema *SemaPtr = nullptr; + + llvm::Optional &LastUnresolvedName; +}; + +llvm::IntrusiveRefCntPtr +IncludeFixer::unresolvedNameRecorder() { + return new UnresolvedNameRecorder(LastUnresolvedName); +} + +std::vector IncludeFixer::fixUnresolvedName() const { + assert(LastUnresolvedName.hasValue()); + auto &Unresolved = *LastUnresolvedName; + std::vector Scopes = Unresolved.GetScopes(); + vlog("Trying to fix unresolved name \"{0}\" in scopes: [{1}]", + Unresolved.Name, llvm::join(Scopes.begin(), Scopes.end(), ", ")); + + FuzzyFindRequest Req; + Req.AnyScope = false; + Req.Query = Unresolved.Name; + Req.Scopes = Scopes; + Req.RestrictForCodeCompletion = true; + Req.Limit = 100; + + SymbolSlab::Builder Matches; + Index.fuzzyFind(Req, [&](const Symbol &Sym) { + if (Sym.Name != Req.Query) + return; + if (!Sym.IncludeHeaders.empty()) + Matches.insert(Sym); + }); + auto Syms = std::move(Matches).build(); + return fixesForSymbols(std::vector(Syms.begin(), Syms.end())); +} } // namespace clangd } // namespace clang diff --git a/clangd/IncludeFixer.h b/clangd/IncludeFixer.h index 740710cf..da292b56 100644 --- a/clangd/IncludeFixer.h +++ b/clangd/IncludeFixer.h @@ -14,6 +14,13 @@ #include "index/Index.h" #include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Sema/ExternalSemaSource.h" +#include "clang/Sema/Sema.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" #include @@ -34,18 +41,44 @@ public: std::vector fix(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) const; + /// Returns an ExternalSemaSource that records failed name lookups in Sema. + /// This allows IncludeFixer to suggest inserting headers that define those + /// names. + llvm::IntrusiveRefCntPtr unresolvedNameRecorder(); + private: /// Attempts to recover diagnostic caused by an incomplete type \p T. std::vector fixIncompleteType(const Type &T) const; - /// Generates header insertion fixes for \p Sym. - std::vector fixesForSymbol(const Symbol &Sym) const; + /// Generates header insertion fixes for all symbols. Fixes are deduplicated. + std::vector fixesForSymbols(llvm::ArrayRef Syms) const; + + struct UnresolvedName { + std::string Name; // E.g. "X" in foo::X. + SourceLocation Loc; // Start location of the unresolved name. + // Lazily get the possible scopes of the unresolved name. `Sema` must be + // alive when this is called. + std::function()> GetScopes; + }; + + /// Records the last unresolved name seen by Sema. + class UnresolvedNameRecorder; + + /// Attempts to fix the unresolved name associated with the current + /// diagnostic. We assume a diagnostic is caused by a unresolved name when + /// they have the same source location and the unresolved name is the last + /// one we've seen during the Sema run. + std::vector fixUnresolvedName() const; std::string File; std::shared_ptr Inserter; const SymbolIndex &Index; const unsigned IndexRequestLimit; // Make at most 5 index requests. mutable unsigned IndexRequestCount = 0; + + // These collect the last unresolved name so that we can associate it with the + // diagnostic. + llvm::Optional LastUnresolvedName; }; } // namespace clangd diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index e6ce8c3b..82d94928 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -47,7 +47,7 @@ size_t lspLength(StringRef Code); /// The returned value is in the range [0, Code.size()]. llvm::Expected positionToOffset(llvm::StringRef Code, Position P, - bool AllowColumnsBeyondLineLength = true); + bool AllowColumnsBeyondLineLength = true); /// Turn an offset in Code into a [line, column] pair. /// The offset must be in range [0, Code.size()]. @@ -110,7 +110,7 @@ Range halfOpenToRange(const SourceManager &SM, CharSourceRange R); // The offset must be in range [0, Code.size()]. // Prefer to use SourceManager if one is available. std::pair offsetToClangLineColumn(llvm::StringRef Code, - size_t Offset); + size_t Offset); /// From "a::b::c", return {"a::b::", "c"}. Scope is empty if there's no /// qualifier. @@ -120,10 +120,10 @@ splitQualifiedName(llvm::StringRef QName); TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R); std::vector replacementsToEdits(StringRef Code, - const tooling::Replacements &Repls); + const tooling::Replacements &Repls); TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, - const LangOptions &L); + const LangOptions &L); /// Get the canonical path of \p F. This means: /// @@ -136,7 +136,7 @@ TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, /// component that generate it, so that paths are normalized as much as /// possible. llvm::Optional getCanonicalPath(const FileEntry *F, - const SourceManager &SourceMgr); + const SourceManager &SourceMgr); bool isRangeConsecutive(const Range &Left, const Range &Right); diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index ca544013..e9f24315 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -30,6 +30,11 @@ testing::Matcher WithFix(testing::Matcher FixMatcher) { return Field(&Diag::Fixes, ElementsAre(FixMatcher)); } +testing::Matcher WithFix(testing::Matcher FixMatcher1, + testing::Matcher FixMatcher2) { + return Field(&Diag::Fixes, UnorderedElementsAre(FixMatcher1, FixMatcher2)); +} + testing::Matcher WithNote(testing::Matcher NoteMatcher) { return Field(&Diag::Notes, ElementsAre(NoteMatcher)); } @@ -281,6 +286,26 @@ main.cpp:2:3: error: something terrible happened)"); Pair(EqualToLSPDiag(NoteInMainLSP), IsEmpty()))); } +struct SymbolWithHeader { + std::string QName; + std::string DeclaringFile; + std::string IncludeHeader; +}; + +std::unique_ptr +buildIndexWithSymbol(llvm::ArrayRef Syms) { + SymbolSlab::Builder Slab; + for (const auto &S : Syms) { + Symbol Sym = cls(S.QName); + Sym.Flags |= Symbol::IndexedForCodeCompletion; + Sym.CanonicalDeclaration.FileURI = S.DeclaringFile.c_str(); + Sym.Definition.FileURI = S.DeclaringFile.c_str(); + Sym.IncludeHeaders.emplace_back(S.IncludeHeader, 1); + Slab.insert(Sym); + } + return MemIndex::build(std::move(Slab).build(), RefSlab()); +} + TEST(IncludeFixerTest, IncompleteType) { Annotations Test(R"cpp( $insert[[]]namespace ns { @@ -293,15 +318,8 @@ int main() { } )cpp"); auto TU = TestTU::withCode(Test.code()); - Symbol Sym = cls("ns::X"); - Sym.Flags |= Symbol::IndexedForCodeCompletion; - Sym.CanonicalDeclaration.FileURI = "unittest:///x.h"; - Sym.Definition.FileURI = "unittest:///x.h"; - Sym.IncludeHeaders.emplace_back("\"x.h\"", 1); - - SymbolSlab::Builder Slab; - Slab.insert(Sym); - auto Index = MemIndex::build(std::move(Slab).build(), RefSlab()); + auto Index = buildIndexWithSymbol( + {SymbolWithHeader{"ns::X", "unittest:///x.h", "\"x.h\""}}); TU.ExternalIndex = Index.get(); EXPECT_THAT( @@ -346,6 +364,65 @@ int main() { "member access into incomplete type 'ns::X'"))); } +TEST(IncludeFixerTest, Typo) { + Annotations Test(R"cpp( +$insert[[]]namespace ns { +void foo() { + $unqualified[[X]] x; +} +} +void bar() { + ns::$qualified[[X]] x; // ns:: is valid. + ::$global[[Global]] glob; +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = buildIndexWithSymbol( + {SymbolWithHeader{"ns::X", "unittest:///x.h", "\"x.h\""}, + SymbolWithHeader{"Global", "unittest:///global.h", "\"global.h\""}}); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT( + TU.build().getDiagnostics(), + UnorderedElementsAre( + AllOf(Diag(Test.range("unqualified"), "unknown type name 'X'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))), + AllOf(Diag(Test.range("qualified"), + "no type named 'X' in namespace 'ns'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))), + AllOf(Diag(Test.range("global"), + "no type named 'Global' in the global namespace"), + WithFix(Fix(Test.range("insert"), "#include \"global.h\"\n", + "Add include \"global.h\" for symbol Global"))))); +} + +TEST(IncludeFixerTest, MultipleMatchedSymbols) { + Annotations Test(R"cpp( +$insert[[]]namespace na { +namespace nb { +void foo() { + $unqualified[[X]] x; +} +} +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = buildIndexWithSymbol( + {SymbolWithHeader{"na::X", "unittest:///a.h", "\"a.h\""}, + SymbolWithHeader{"na::nb::X", "unittest:///b.h", "\"b.h\""}}); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT(TU.build().getDiagnostics(), + UnorderedElementsAre(AllOf( + Diag(Test.range("unqualified"), "unknown type name 'X'"), + WithFix(Fix(Test.range("insert"), "#include \"a.h\"\n", + "Add include \"a.h\" for symbol na::X"), + Fix(Test.range("insert"), "#include \"b.h\"\n", + "Add include \"b.h\" for symbol na::nb::X"))))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From 5acf26a46ec0493424d55165817ace5ad583759a Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Thu, 7 Feb 2019 10:34:43 +0000 Subject: [clang-tidy] Expand and clarify the NOLINT documentation a bit. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353382 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/index.rst | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst index 720c581d..1cbd8dc5 100644 --- a/docs/clang-tidy/index.rst +++ b/docs/clang-tidy/index.rst @@ -262,25 +262,46 @@ Suppressing Undesired Diagnostics :program:`clang-tidy` diagnostics are intended to call out code that does not adhere to a coding standard, or is otherwise problematic in some way. However, -if it is known that the code is correct, the check-specific ways to silence the -diagnostics could be used, if they are available (e.g. bugprone-use-after-move -can be silenced by re-initializing the variable after it has been moved out, -bugprone-string-integer-assignment can be suppressed by explicitly casting the -integer to ``char``, readability-implicit-bool-conversion can also be suppressed -by using explicit casts, etc.). If they are not available or if changing the -semantics of the code is not desired, the ``NOLINT`` or ``NOLINTNEXTLINE`` -comments can be used instead. For example: +if the code is known to be correct, it may be useful to silence the warning. +Some clang-tidy checks provide a check-specific way to silence the diagnostics, +e.g. `bugprone-use-after-move `_ can be +silenced by re-initializing the variable after it has been moved out, +`bugprone-string-integer-assignment +`_ can be suppressed by explicitly +casting the integer to ``char``, `readability-implicit-bool-conversion +`_ can also be suppressed by using +explicit casts, etc. + +If a specific suppression mechanism is not available for a certain warning, or +its use is not desired for some reason, :program:`clang-tidy` has a generic +mechanism to suppress diagnostics using ``NOLINT`` or ``NOLINTNEXTLINE`` +comments. + +The ``NOLINT`` comment instructs :program:`clang-tidy` to ignore warnings on the +*same line* (it doesn't apply to a function, a block of code or any other +language construct, it applies to the line of code it is on). If introducing the +comment in the same line would change the formatting in undesired way, the +``NOLINTNEXTLINE`` comment allows to suppress clang-tidy warnings on the *next +line*. + +Both comments can be followed by an optional list of check names in parentheses +(see below for the formal syntax). + +For example: .. code-block:: c++ class Foo { - // Silent all the diagnostics for the line + // Suppress all the diagnostics for the line Foo(int param); // NOLINT - // Silent only the specified checks for the line + // Consider explaining the motivation to suppress the warning. + Foo(char param); // NOLINT: Allow implicit conversion from `char`, because . + + // Silence only the specified checks for the line Foo(double param); // NOLINT(google-explicit-constructor, google-runtime-int) - // Silent only the specified diagnostics for the next line + // Silence only the specified diagnostics for the next line // NOLINTNEXTLINE(google-explicit-constructor, google-runtime-int) Foo(bool param); }; -- cgit v1.2.3 From 4d8ed1900ae0ccd37b5c1d1d92ff4ab4dbcd0c34 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 7 Feb 2019 11:00:59 +0000 Subject: [clang-tidy] Fixed a std::bind() transformation There was an extra semicolon that was somehow working in some contexts. Patch by oleg.smolsky. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353389 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/modernize/AvoidBindCheck.cpp | 2 +- test/clang-tidy/modernize-avoid-bind.cpp | 44 ++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/clang-tidy/modernize/AvoidBindCheck.cpp b/clang-tidy/modernize/AvoidBindCheck.cpp index 44174243..c51b6e86 100644 --- a/clang-tidy/modernize/AvoidBindCheck.cpp +++ b/clang-tidy/modernize/AvoidBindCheck.cpp @@ -169,7 +169,7 @@ void AvoidBindCheck::check(const MatchFinder::MatchResult &Result) { Ref->printPretty(Stream, nullptr, Result.Context->getPrintingPolicy()); Stream << "("; addFunctionCallArgs(Args, Stream); - Stream << "); };"; + Stream << "); }"; Diag << FixItHint::CreateReplacement(MatchedDecl->getSourceRange(), Stream.str()); diff --git a/test/clang-tidy/modernize-avoid-bind.cpp b/test/clang-tidy/modernize-avoid-bind.cpp index 1c78b9e6..721801be 100644 --- a/test/clang-tidy/modernize-avoid-bind.cpp +++ b/test/clang-tidy/modernize-avoid-bind.cpp @@ -77,3 +77,47 @@ void n() { // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind // CHECK-FIXES: auto clj = [] { return C::add(1, 1); }; } + +// Let's fake a minimal std::function-like facility. +namespace std { +template +_Tp declval(); + +template +struct __res { + template + static decltype(declval<_Functor>()(_Args()...)) _S_test(int); + + template + static void _S_test(...); + + using type = decltype(_S_test<_ArgTypes...>(0)); +}; + +template +struct function; + +template +struct function { + template ::type> + function(_Functor) {} +}; +} // namespace std + +struct Thing {}; +void UseThing(Thing *); + +struct Callback { + Callback(); + Callback(std::function); + void Reset(std::function); +}; + +void test(Thing *t) { + Callback cb; + if (t) + cb.Reset(std::bind(UseThing, t)); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind + // CHECK-FIXES: cb.Reset([=] { return UseThing(t); }); +} -- cgit v1.2.3 From b1b03e8002a97bc067ebd3ff95b10860b7355118 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 7 Feb 2019 15:34:37 +0000 Subject: [clangd] Use Dex for dynamic index by default. Summary: Memory usage for a sample TU: Without Dex: 17.9M With Dex: 24.4M The memory increase is considerable but seems tolerable. Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57878 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353413 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/ClangdMain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index 6c102eda..9495869b 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -31,7 +31,7 @@ namespace clangd { static llvm::cl::opt UseDex("use-dex-index", llvm::cl::desc("Use experimental Dex dynamic index."), - llvm::cl::init(false), llvm::cl::Hidden); + llvm::cl::init(true), llvm::cl::Hidden); static llvm::cl::opt CompileCommandsDir( "compile-commands-dir", -- cgit v1.2.3 From 5ee2453924d318c7beb0959fc7ebaacf1e59b0bf Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 7 Feb 2019 15:38:14 +0000 Subject: [ELF] Format lines inadvertently indented by rCTE353380 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353415 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/SourceCode.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clangd/SourceCode.h b/clangd/SourceCode.h index 82d94928..e6ce8c3b 100644 --- a/clangd/SourceCode.h +++ b/clangd/SourceCode.h @@ -47,7 +47,7 @@ size_t lspLength(StringRef Code); /// The returned value is in the range [0, Code.size()]. llvm::Expected positionToOffset(llvm::StringRef Code, Position P, - bool AllowColumnsBeyondLineLength = true); + bool AllowColumnsBeyondLineLength = true); /// Turn an offset in Code into a [line, column] pair. /// The offset must be in range [0, Code.size()]. @@ -110,7 +110,7 @@ Range halfOpenToRange(const SourceManager &SM, CharSourceRange R); // The offset must be in range [0, Code.size()]. // Prefer to use SourceManager if one is available. std::pair offsetToClangLineColumn(llvm::StringRef Code, - size_t Offset); + size_t Offset); /// From "a::b::c", return {"a::b::", "c"}. Scope is empty if there's no /// qualifier. @@ -120,10 +120,10 @@ splitQualifiedName(llvm::StringRef QName); TextEdit replacementToEdit(StringRef Code, const tooling::Replacement &R); std::vector replacementsToEdits(StringRef Code, - const tooling::Replacements &Repls); + const tooling::Replacements &Repls); TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, - const LangOptions &L); + const LangOptions &L); /// Get the canonical path of \p F. This means: /// @@ -136,7 +136,7 @@ TextEdit toTextEdit(const FixItHint &FixIt, const SourceManager &M, /// component that generate it, so that paths are normalized as much as /// possible. llvm::Optional getCanonicalPath(const FileEntry *F, - const SourceManager &SourceMgr); + const SourceManager &SourceMgr); bool isRangeConsecutive(const Range &Left, const Range &Right); -- cgit v1.2.3 From 5a5dde2a9791ee0956966b9e7792388c41604808 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 7 Feb 2019 16:00:44 +0000 Subject: [clangd] Fix an assertion failure in Selection. Summary: The assertion is triggered when the Decl is null. Details for the assertion: F0207 09:55:09.069385 47308 logging.cc:84] assert.h assertion failed at llvm/include/llvm/Support/Casting.h:105 in static bool llvm::isa_impl_cl::doit(const From *) [To = clang::TranslationUnitDecl, From = const clang::Decl *]: Val && "isa<> used on a null pointer" 15 *** Check failure stack trace: *** 19 @ 0x55615c1f7e06 __assert_fail 20 @ 0x55615a6297d8 clang::clangd::(anonymous namespace)::SelectionVisitor::TraverseDecl() 21 @ 0x55615a62f48d clang::RecursiveASTVisitor<>::TraverseTemplateTemplateParmDecl() 22 @ 0x55615a62b264 clang::RecursiveASTVisitor<>::TraverseDecl() 23 @ 0x55615a62979c clang::clangd::(anonymous namespace)::SelectionVisitor::TraverseDecl() 24 @ 0x55615a63060c clang::RecursiveASTVisitor<>::TraverseClassTemplatePartialSpecializationDecl() 25 @ 0x55615a62ae45 clang::RecursiveASTVisitor<>::TraverseDecl() Reviewers: sammccall Subscribers: javed.absar, kristof.beyls, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57879 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353421 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Selection.cpp | 2 +- unittests/clangd/SelectionTests.cpp | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp index 2c2fd476..d1ea30e7 100644 --- a/clangd/Selection.cpp +++ b/clangd/Selection.cpp @@ -51,7 +51,7 @@ public: // - those that can't be stored in DynTypedNode. // We're missing some interesting things like Attr due to the latter. bool TraverseDecl(Decl *X) { - if (isa(X)) + if (X && isa(X)) return Base::TraverseDecl(X); // Already pushed by constructor. return traverseNode(X, [&] { return Base::TraverseDecl(X); }); } diff --git a/unittests/clangd/SelectionTests.cpp b/unittests/clangd/SelectionTests.cpp index 88406b63..2322a0e6 100644 --- a/unittests/clangd/SelectionTests.cpp +++ b/unittests/clangd/SelectionTests.cpp @@ -176,6 +176,16 @@ TEST(SelectionTest, CommonAncestor) { // Node types that have caused problems in the past. {"template void foo() { [[^T]] t; }", "TypeLoc"}, + + // No crash + { + R"cpp( + template struct Foo {}; + template <[[template class /*cursor here*/^U]]> + struct Foo*> {}; + )cpp", + "TemplateTemplateParmDecl" + }, }; for (const Case &C : Cases) { Annotations Test(C.Code); -- cgit v1.2.3 From c1edfe33db2dadf60f9639981a8581b9735d308e Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Thu, 7 Feb 2019 16:04:30 +0000 Subject: [clangd] Reduce number of threads used by BackgroundIndex to number of physical cores. Summary: clangd is using as many threads as logical cores for BackgroundIndex by default. We observed that it increases latency of foreground tasks. This patch aims to change that default to number of physical cores to get rid of that extra latency. Reviewers: ilya-biryukov Reviewed By: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57819 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353422 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Background.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/clangd/index/Background.h b/clangd/index/Background.h index ea8ab581..808c03a3 100644 --- a/clangd/index/Background.h +++ b/clangd/index/Background.h @@ -67,11 +67,12 @@ public: /// If BuildIndexPeriodMs is greater than 0, the symbol index will only be /// rebuilt periodically (one per \p BuildIndexPeriodMs); otherwise, index is /// rebuilt for each indexed file. - BackgroundIndex(Context BackgroundContext, const FileSystemProvider &, - const GlobalCompilationDatabase &CDB, - BackgroundIndexStorage::Factory IndexStorageFactory, - size_t BuildIndexPeriodMs = 0, - size_t ThreadPoolSize = llvm::hardware_concurrency()); + BackgroundIndex( + Context BackgroundContext, const FileSystemProvider &, + const GlobalCompilationDatabase &CDB, + BackgroundIndexStorage::Factory IndexStorageFactory, + size_t BuildIndexPeriodMs = 0, + size_t ThreadPoolSize = llvm::heavyweight_hardware_concurrency()); ~BackgroundIndex(); // Blocks while the current task finishes. // Enqueue translation units for indexing. -- cgit v1.2.3 From 2b0cff51377d619ebee152f4bf5c114949a586ba Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Thu, 7 Feb 2019 16:10:39 +0000 Subject: [clangd] Mention indexing in docs. Reviewers: sammccall Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Differential Revision: https://reviews.llvm.org/D57392 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353423 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/docs/clangd.rst b/docs/clangd.rst index 84696e3b..0843bcaf 100644 --- a/docs/clangd.rst +++ b/docs/clangd.rst @@ -143,6 +143,25 @@ Emacs Integration :program:`Emacs` provides `lsp-mode `_ and `Eglot `_ plugins for LSP integration. +Project-wide Index +================== + +By default :program:`Clangd` only has a view on symbols coming from files you +are currently editing. You can extend this view to whole project by providing a +project-wide index to :program:`Clangd`. + +There are two ways you can generate a project-wide index for clangd: + +- Passing experimental `-background-index` commandline argument, which will + incrementally build an index of projects that you work on and make use of that + in clangd automatically. +- Generate an index file using `clangd-indexer + `_ + Afterwards you can pass generated index file to clangd using + `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't included + alongside clangd in the standard clang-tools package. You will likely have to + build from source to use this option* + Getting Involved ================== -- cgit v1.2.3 From 9bca318a2462370bfdc6e006957cae39ac244198 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Fri, 8 Feb 2019 13:27:47 +0000 Subject: [clangd] Fix an assertion in TypoCorrection. Summary: https://github.com/clangd/clangd/issues/7 Reviewers: sammccall, hokein Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57944 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353514 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/IncludeFixer.cpp | 13 +++++++------ unittests/clangd/DiagnosticsTests.cpp | 15 +++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index adcb51a4..cdd973a2 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -192,12 +192,6 @@ public: if (!SemaPtr->SourceMgr.isWrittenInMainFile(Typo.getLoc())) return clang::TypoCorrection(); - assert(S && "Enclosing scope must be set."); - - UnresolvedName Unresolved; - Unresolved.Name = Typo.getAsString(); - Unresolved.Loc = Typo.getBeginLoc(); - // FIXME: support invalid scope before a type name. In the following // example, namespace "clang::tidy::" hasn't been declared/imported. // namespace clang { @@ -228,6 +222,12 @@ public: return TypoCorrection(); } } + if (!SpecifiedScope && !S) // Give up if no scope available. + return TypoCorrection(); + + UnresolvedName Unresolved; + Unresolved.Name = Typo.getAsString(); + Unresolved.Loc = Typo.getBeginLoc(); auto *Sem = SemaPtr; // Avoid capturing `this`. Unresolved.GetScopes = [Sem, SpecifiedScope, S, LookupKind]() { @@ -235,6 +235,7 @@ public: if (SpecifiedScope) { Scopes.push_back(*SpecifiedScope); } else { + assert(S); // No scope qualifier is specified. Collect all accessible scopes in the // context. VisitedContextCollector Collector; diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index e9f24315..a42e5a71 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -423,6 +423,21 @@ void foo() { "Add include \"b.h\" for symbol na::nb::X"))))); } +TEST(IncludeFixerTest, NoCrashMemebrAccess) { + Annotations Test(R"cpp( + struct X { int xyz; }; + void g() { X x; x.$[[xy]] } + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = buildIndexWithSymbol( + SymbolWithHeader{"na::X", "unittest:///a.h", "\"a.h\""}); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT( + TU.build().getDiagnostics(), + UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'"))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From f01344e74386e2fc76f7c160f922d78a341f2ece Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum Date: Fri, 8 Feb 2019 14:57:22 +0000 Subject: [clang-tidy][NFC] Test commit. Add missing comma. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353523 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/readability/ConstReturnTypeCheck.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tidy/readability/ConstReturnTypeCheck.cpp b/clang-tidy/readability/ConstReturnTypeCheck.cpp index 9d936d8a..a6fccd2b 100644 --- a/clang-tidy/readability/ConstReturnTypeCheck.cpp +++ b/clang-tidy/readability/ConstReturnTypeCheck.cpp @@ -22,8 +22,8 @@ namespace readability { // Finds the location of the qualifying `const` token in the `FunctionDecl`'s // return type. Returns `None` when the return type is not `const`-qualified or -// `const` does not appear in `Def`'s source like when the type is an alias or a -// macro. +// `const` does not appear in `Def`'s source like, when the type is an alias or +// a macro. static llvm::Optional findConstToRemove(const FunctionDecl *Def, const MatchFinder::MatchResult &Result) { -- cgit v1.2.3 From 7c2485c23db73fa6100b1dc5002a87403bda9d45 Mon Sep 17 00:00:00 2001 From: Yitzhak Mandelbaum Date: Fri, 8 Feb 2019 15:05:57 +0000 Subject: [clang-tidy][NFC] Fix typo. Fix placement of comma from previous (test) commit. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353525 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/readability/ConstReturnTypeCheck.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tidy/readability/ConstReturnTypeCheck.cpp b/clang-tidy/readability/ConstReturnTypeCheck.cpp index a6fccd2b..0f237ec8 100644 --- a/clang-tidy/readability/ConstReturnTypeCheck.cpp +++ b/clang-tidy/readability/ConstReturnTypeCheck.cpp @@ -22,7 +22,7 @@ namespace readability { // Finds the location of the qualifying `const` token in the `FunctionDecl`'s // return type. Returns `None` when the return type is not `const`-qualified or -// `const` does not appear in `Def`'s source like, when the type is an alias or +// `const` does not appear in `Def`'s source, like when the type is an alias or // a macro. static llvm::Optional findConstToRemove(const FunctionDecl *Def, -- cgit v1.2.3 From 70f4cf2cd408204b5e7b2a2fd3f6fc7010039e9e Mon Sep 17 00:00:00 2001 From: Paul Hoad Date: Fri, 8 Feb 2019 17:00:01 +0000 Subject: [clang-tidy] Add options to bugprone-argument-comment to add missing argument comments to literals bugprone-argument-comment only supports identifying those comments which do not match the function parameter name This revision add 3 options to adding missing argument comments to literals (granularity on type is added to control verbosity of fixit) ``` CheckOptions: - key: bugprone-argument-comment.CommentBoolLiterals value: '1' - key: bugprone-argument-comment.CommentFloatLiterals value: '1' - key: bugprone-argument-comment.CommentIntegerLiterals value: '1' - key: bugprone-argument-comment.CommentStringLiterals value: '1' - key: bugprone-argument-comment.CommentCharacterLiterals value: '1' - key: bugprone-argument-comment.CommentUserDefinedLiterals value: '1' - key: bugprone-argument-comment.CommentNullPtrs value: '1' ``` After applying these options, literal arguments will be preceded with /*ParameterName=*/ Reviewers: JonasToth, Eugene.Zelenko, alexfh, hokein, aaron.ballman Reviewed By: aaron.ballman, Eugene.Zelenko Differential Revision: https://reviews.llvm.org/D57674 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353535 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/ArgumentCommentCheck.cpp | 67 +++++++-- clang-tidy/bugprone/ArgumentCommentCheck.h | 14 +- docs/ReleaseNotes.rst | 6 + .../checks/bugprone-argument-comment.rst | 155 +++++++++++++++++++++ .../bugprone-argument-comment-literals.cpp | 124 +++++++++++++++++ 5 files changed, 354 insertions(+), 12 deletions(-) create mode 100644 test/clang-tidy/bugprone-argument-comment-literals.cpp diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.cpp b/clang-tidy/bugprone/ArgumentCommentCheck.cpp index f939aa0e..5d6c7c9a 100644 --- a/clang-tidy/bugprone/ArgumentCommentCheck.cpp +++ b/clang-tidy/bugprone/ArgumentCommentCheck.cpp @@ -11,6 +11,7 @@ #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Token.h" + #include "../utils/LexerUtils.h" using namespace clang::ast_matchers; @@ -23,17 +24,37 @@ ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0), + CommentBoolLiterals(Options.getLocalOrGlobal("CommentBoolLiterals", 0) != + 0), + CommentIntegerLiterals( + Options.getLocalOrGlobal("CommentIntegerLiterals", 0) != 0), + CommentFloatLiterals( + Options.getLocalOrGlobal("CommentFloatLiterals", 0) != 0), + CommentStringLiterals( + Options.getLocalOrGlobal("CommentStringLiterals", 0) != 0), + CommentUserDefinedLiterals( + Options.getLocalOrGlobal("CommentUserDefinedLiterals", 0) != 0), + CommentCharacterLiterals( + Options.getLocalOrGlobal("CommentCharacterLiterals", 0) != 0), + CommentNullPtrs(Options.getLocalOrGlobal("CommentNullPtrs", 0) != 0), IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {} void ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "StrictMode", StrictMode); + Options.store(Opts, "CommentBoolLiterals", CommentBoolLiterals); + Options.store(Opts, "CommentIntegerLiterals", CommentIntegerLiterals); + Options.store(Opts, "CommentFloatLiterals", CommentFloatLiterals); + Options.store(Opts, "CommentStringLiterals", CommentStringLiterals); + Options.store(Opts, "CommentUserDefinedLiterals", CommentUserDefinedLiterals); + Options.store(Opts, "CommentCharacterLiterals", CommentCharacterLiterals); + Options.store(Opts, "CommentNullPtrs", CommentNullPtrs); } void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher( callExpr(unless(cxxOperatorCallExpr()), - // NewCallback's arguments relate to the pointed function, don't - // check them against NewCallback's parameter names. + // NewCallback's arguments relate to the pointed function, + // don't check them against NewCallback's parameter names. // FIXME: Make this configurable. unless(hasDeclaration(functionDecl( hasAnyName("NewCallback", "NewPermanentCallback"))))) @@ -126,8 +147,8 @@ static bool isLikelyTypo(llvm::ArrayRef Params, const unsigned Threshold = 2; // Other parameters must be an edit distance at least Threshold more away - // from this parameter. This gives us greater confidence that this is a typo - // of this parameter and not one with a similar name. + // from this parameter. This gives us greater confidence that this is a + // typo of this parameter and not one with a similar name. unsigned OtherED = ArgNameLower.edit_distance(II->getName().lower(), /*AllowReplacements=*/true, ThisED + Threshold); @@ -180,8 +201,8 @@ static const CXXMethodDecl *findMockedMethod(const CXXMethodDecl *Method) { } return nullptr; } - if (const auto *Next = dyn_cast_or_null( - Method->getNextDeclInContext())) { + if (const auto *Next = + dyn_cast_or_null(Method->getNextDeclInContext())) { if (looksLikeExpectMethod(Next) && areMockAndExpectMethods(Method, Next)) return Method; } @@ -206,6 +227,21 @@ static const FunctionDecl *resolveMocks(const FunctionDecl *Func) { return Func; } +// Given the argument type and the options determine if we should +// be adding an argument comment. +bool ArgumentCommentCheck::shouldAddComment(const Expr *Arg) const { + if (Arg->getExprLoc().isMacroID()) + return false; + Arg = Arg->IgnoreImpCasts(); + return (CommentBoolLiterals && isa(Arg)) || + (CommentIntegerLiterals && isa(Arg)) || + (CommentFloatLiterals && isa(Arg)) || + (CommentUserDefinedLiterals && isa(Arg)) || + (CommentCharacterLiterals && isa(Arg)) || + (CommentStringLiterals && isa(Arg)) || + (CommentNullPtrs && isa(Arg)); +} + void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, const FunctionDecl *OriginalCallee, SourceLocation ArgBeginLoc, @@ -219,7 +255,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, if (NumArgs == 0) return; - auto makeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) { + auto MakeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) { return Lexer::makeFileCharRange(CharSourceRange::getCharRange(Begin, End), Ctx->getSourceManager(), Ctx->getLangOpts()); @@ -242,7 +278,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, } CharSourceRange BeforeArgument = - makeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc()); + MakeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc()); ArgBeginLoc = Args[I]->getEndLoc(); std::vector> Comments; @@ -250,7 +286,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, Comments = getCommentsInRange(Ctx, BeforeArgument); } else { // Fall back to parsing back from the start of the argument. - CharSourceRange ArgsRange = makeFileCharRange( + CharSourceRange ArgsRange = MakeFileCharRange( Args[I]->getBeginLoc(), Args[NumArgs - 1]->getEndLoc()); Comments = getCommentsBeforeLoc(Ctx, ArgsRange.getBegin()); } @@ -277,8 +313,19 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx, } } } + + // If the argument comments are missing for literals add them. + if (Comments.empty() && shouldAddComment(Args[I])) { + std::string ArgComment = + (llvm::Twine("/*") + II->getName() + "=*/").str(); + DiagnosticBuilder Diag = + diag(Args[I]->getBeginLoc(), + "argument comment missing for literal argument %0") + << II + << FixItHint::CreateInsertion(Args[I]->getBeginLoc(), ArgComment); + } } -} +} // namespace bugprone void ArgumentCommentCheck::check(const MatchFinder::MatchResult &Result) { const auto *E = Result.Nodes.getNodeAs("expr"); diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.h b/clang-tidy/bugprone/ArgumentCommentCheck.h index 2eee74d6..451b309c 100644 --- a/clang-tidy/bugprone/ArgumentCommentCheck.h +++ b/clang-tidy/bugprone/ArgumentCommentCheck.h @@ -26,7 +26,8 @@ namespace bugprone { /// /// ... /// f(/*bar=*/true); -/// // warning: argument name 'bar' in comment does not match parameter name 'foo' +/// // warning: argument name 'bar' in comment does not match parameter name +/// 'foo' /// \endcode /// /// The check tries to detect typos and suggest automated fixes for them. @@ -39,12 +40,21 @@ public: void storeOptions(ClangTidyOptions::OptionMap &Opts) override; private: - const bool StrictMode; + const unsigned StrictMode : 1; + const unsigned CommentBoolLiterals : 1; + const unsigned CommentIntegerLiterals : 1; + const unsigned CommentFloatLiterals : 1; + const unsigned CommentStringLiterals : 1; + const unsigned CommentUserDefinedLiterals : 1; + const unsigned CommentCharacterLiterals : 1; + const unsigned CommentNullPtrs : 1; llvm::Regex IdentRE; void checkCallArgs(ASTContext *Ctx, const FunctionDecl *Callee, SourceLocation ArgBeginLoc, llvm::ArrayRef Args); + + bool shouldAddComment(const Expr *Arg) const; }; } // namespace bugprone diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 9f833954..f932af42 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -92,6 +92,12 @@ Improvements to clang-tidy Checks whether there are underscores in googletest test and test case names in test macros, which is prohibited by the Googletest FAQ. +- The :doc:`bugprone-argument-comment + ` now supports + `CommentBoolLiterals`, `CommentIntegerLiterals`, `CommentFloatLiterals`, + `CommentUserDefiniedLiterals`, `CommentStringLiterals`, + `CommentCharacterLiterals` & `CommentNullPtrs` options. + Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/bugprone-argument-comment.rst b/docs/clang-tidy/checks/bugprone-argument-comment.rst index 5f7e5f0d..afc12186 100644 --- a/docs/clang-tidy/checks/bugprone-argument-comment.rst +++ b/docs/clang-tidy/checks/bugprone-argument-comment.rst @@ -27,3 +27,158 @@ Options When zero (default value), the check will ignore leading and trailing underscores and case when comparing names -- otherwise they are taken into account. + +.. option:: CommentBoolLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the boolean literal argument. + +Before: + +.. code-block:: c++ + + void foo(bool TurnKey, bool PressButton); + + foo(true, false); + +After: + +.. code-block:: c++ + + void foo(bool TurnKey, bool PressButton); + + foo(/*TurnKey=*/true, /*PressButton=*/false); + +.. option:: CommentIntegerLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the integer literal argument. + +Before: + +.. code-block:: c++ + + void foo(int MeaningOfLife); + + foo(42); + +After: + +.. code-block:: c++ + + void foo(int MeaningOfLife); + + foo(/*MeaningOfLife=*/42); + +.. option:: CommentFloatLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the float/double literal argument. + +Before: + +.. code-block:: c++ + + void foo(float Pi); + + foo(3.14159); + +After: + +.. code-block:: c++ + + void foo(float Pi); + + foo(/*Pi=*/3.14159); + +.. option:: CommentStringLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the string literal argument. + +Before: + +.. code-block:: c++ + + void foo(const char *String); + void foo(const wchar_t *WideString); + + foo("Hello World"); + foo(L"Hello World"); + +After: + +.. code-block:: c++ + + void foo(const char *String); + void foo(const wchar_t *WideString); + + foo(/*String=*/"Hello World"); + foo(/*WideString=*/L"Hello World"); + +.. option:: CommentCharacterLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the character literal argument. + +Before: + +.. code-block:: c++ + + void foo(char *Character); + + foo('A'); + +After: + +.. code-block:: c++ + + void foo(char *Character); + + foo(/*Character=*/'A'); + +.. option:: CommentUserDefinedLiterals + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the user defined literal argument. + +Before: + +.. code-block:: c++ + + void foo(double Distance); + + double operator"" _km(long double); + + foo(402.0_km); + +After: + +.. code-block:: c++ + + void foo(double Distance); + + double operator"" _km(long double); + + foo(/*Distance=*/402.0_km); + +.. option:: CommentNullPtrs + + When true, the check will add argument comments in the format + ``/*ParameterName=*/`` right before the nullptr literal argument. + +Before: + +.. code-block:: c++ + + void foo(A* Value); + + foo(nullptr); + +After: + +.. code-block:: c++ + + void foo(A* Value); + + foo(/*Value=*/nullptr); diff --git a/test/clang-tidy/bugprone-argument-comment-literals.cpp b/test/clang-tidy/bugprone-argument-comment-literals.cpp new file mode 100644 index 00000000..739c9a59 --- /dev/null +++ b/test/clang-tidy/bugprone-argument-comment-literals.cpp @@ -0,0 +1,124 @@ +// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \ +// RUN: -config="{CheckOptions: [{key: CommentBoolLiterals, value: 1},{key: CommentIntegerLiterals, value: 1}, {key: CommentFloatLiterals, value: 1}, {key: CommentUserDefinedLiterals, value: 1}, {key: CommentStringLiterals, value: 1}, {key: CommentNullPtrs, value: 1}, {key: CommentCharacterLiterals, value: 1}]}" -- + +struct A { + void foo(bool abc); + void foo(bool abc, bool cde); + void foo(const char *, bool abc); + void foo(int iabc); + void foo(float fabc); + void foo(double dabc); + void foo(const char *strabc); + void fooW(const wchar_t *wstrabc); + void fooPtr(A *ptrabc); + void foo(char chabc); +}; + +#define FOO 1 + +void g(int a); +void h(double b); +void i(const char *c); + +double operator"" _km(long double); + +void test() { + A a; + + a.foo(true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/true); + + a.foo(false); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false); + + a.foo(true, false); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-MESSAGES: [[@LINE-2]]:15: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/true, /*cde=*/false); + + a.foo(false, true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-MESSAGES: [[@LINE-2]]:16: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + a.foo(/*abc=*/false, true); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + a.foo(false, /*cde=*/true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + bool val1 = true; + bool val2 = false; + a.foo(val1, val2); + + a.foo("", true); + // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo("", /*abc=*/true); + + a.foo(0); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'iabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*iabc=*/0); + + a.foo(1.0f); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'fabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*fabc=*/1.0f); + + a.foo(1.0); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*dabc=*/1.0); + + int val3 = 10; + a.foo(val3); + + float val4 = 10.0; + a.foo(val4); + + double val5 = 10.0; + a.foo(val5); + + a.foo("Hello World"); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'strabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*strabc=*/"Hello World"); + // + a.fooW(L"Hello World"); + // CHECK-MESSAGES: [[@LINE-1]]:10: warning: argument comment missing for literal argument 'wstrabc' [bugprone-argument-comment] + // CHECK-FIXES: a.fooW(/*wstrabc=*/L"Hello World"); + + a.fooPtr(nullptr); + // CHECK-MESSAGES: [[@LINE-1]]:12: warning: argument comment missing for literal argument 'ptrabc' [bugprone-argument-comment] + // CHECK-FIXES: a.fooPtr(/*ptrabc=*/nullptr); + + a.foo(402.0_km); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*dabc=*/402.0_km); + + a.foo('A'); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'chabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*chabc=*/'A'); + + g(FOO); + h(1.0f); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument 'b' [bugprone-argument-comment] + // CHECK-FIXES: h(/*b=*/1.0f); + i(__FILE__); + + // FIXME Would like the below to add argument comments. + g((1)); + // FIXME But we should not add argument comments here. + g(_Generic(0, int : 0)); +} + +void f(bool _with_underscores_); +void ignores_underscores() { + f(false); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument '_with_underscores_' [bugprone-argument-comment] + // CHECK-FIXES: f(/*_with_underscores_=*/false); + + f(true); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument + // CHECK-FIXES: f(/*_with_underscores_=*/true); +} -- cgit v1.2.3 From 8214828fc69893248caf7291d73b70690e4f6987 Mon Sep 17 00:00:00 2001 From: Malcolm Parsons Date: Fri, 8 Feb 2019 19:44:42 +0000 Subject: [clang-tidy] Don't use assignment for value-initialized enums Summary: The modernize-use-default-member-init check crashes when trying to create an assignment value for a value-initialized enum because it isn't a BuiltinType. An enum cannot be initialized by assigning 0 to it unless a cast is added. It could be initialized with an enumerator with the value 0, but there might not be one. Avoid these issues by ignoring the UseAssignment setting for value-initialized enums. Fixes PR35050. Reviewers: aaron.ballman, alexfh, JonasToth Reviewed By: JonasToth Subscribers: xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57852 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353554 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/modernize/UseDefaultMemberInitCheck.cpp | 9 ++++++--- test/clang-tidy/modernize-use-default-member-init-assignment.cpp | 8 ++++++++ test/clang-tidy/modernize-use-default-member-init.cpp | 8 ++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp index 342b0ad2..3c2e0e90 100644 --- a/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp +++ b/clang-tidy/modernize/UseDefaultMemberInitCheck.cpp @@ -255,17 +255,20 @@ void UseDefaultMemberInitCheck::checkDefaultInit( CharSourceRange InitRange = CharSourceRange::getCharRange(LParenEnd, Init->getRParenLoc()); + bool ValueInit = isa(Init->getInit()); + bool CanAssign = UseAssignment && (!ValueInit || !Init->getInit()->getType()->isEnumeralType()); + auto Diag = diag(Field->getLocation(), "use default member initializer for %0") << Field - << FixItHint::CreateInsertion(FieldEnd, UseAssignment ? " = " : "{") + << FixItHint::CreateInsertion(FieldEnd, CanAssign ? " = " : "{") << FixItHint::CreateInsertionFromRange(FieldEnd, InitRange); - if (UseAssignment && isa(Init->getInit())) + if (CanAssign && ValueInit) Diag << FixItHint::CreateInsertion( FieldEnd, getValueOfValueInit(Init->getInit()->getType())); - if (!UseAssignment) + if (!CanAssign) Diag << FixItHint::CreateInsertion(FieldEnd, "}"); Diag << FixItHint::CreateRemoval(Init->getSourceRange()); diff --git a/test/clang-tidy/modernize-use-default-member-init-assignment.cpp b/test/clang-tidy/modernize-use-default-member-init-assignment.cpp index fdc0db18..b98055c9 100644 --- a/test/clang-tidy/modernize-use-default-member-init-assignment.cpp +++ b/test/clang-tidy/modernize-use-default-member-init-assignment.cpp @@ -166,6 +166,14 @@ struct PositiveEnum { // CHECK-FIXES: Enum e = Foo; }; +struct PositiveValueEnum { + PositiveValueEnum() : e() {} + // CHECK-FIXES: PositiveValueEnum() {} + Enum e; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e' + // CHECK-FIXES: Enum e{}; +}; + struct PositiveString { PositiveString() : s("foo") {} // CHECK-FIXES: PositiveString() {} diff --git a/test/clang-tidy/modernize-use-default-member-init.cpp b/test/clang-tidy/modernize-use-default-member-init.cpp index d35ad330..825bfa0b 100644 --- a/test/clang-tidy/modernize-use-default-member-init.cpp +++ b/test/clang-tidy/modernize-use-default-member-init.cpp @@ -165,6 +165,14 @@ struct PositiveEnum { // CHECK-FIXES: Enum e{Foo}; }; +struct PositiveValueEnum { + PositiveValueEnum() : e() {} + // CHECK-FIXES: PositiveValueEnum() {} + Enum e; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use default member initializer for 'e' + // CHECK-FIXES: Enum e{}; +}; + struct PositiveString { PositiveString() : s("foo") {} // CHECK-FIXES: PositiveString() {} -- cgit v1.2.3 From e93e9e8801c112252072d9b934445f29eb9a9a53 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 11 Feb 2019 10:31:13 +0000 Subject: [clangd] Make system header mappings available for PreambleParsedCallback Summary: SystemHeaderMappings were added only after takeIncludes call, which resulted in getting mapping on main file ast updates but not on preamble ast updates. Fixes https://github.com/clangd/clangd/issues/8 Reviewers: hokein Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58029 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353687 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.cpp | 9 ++++----- unittests/clangd/FileIndexTests.cpp | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 09ab772d..1689a644 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -96,14 +96,13 @@ private: class CppFilePreambleCallbacks : public PreambleCallbacks { public: CppFilePreambleCallbacks(PathRef File, PreambleParsedCallback ParsedCallback) - : File(File), ParsedCallback(ParsedCallback) {} + : File(File), ParsedCallback(ParsedCallback) { + addSystemHeadersMapping(&CanonIncludes); + } IncludeStructure takeIncludes() { return std::move(Includes); } - CanonicalIncludes takeCanonicalIncludes() { - addSystemHeadersMapping(&CanonIncludes); - return std::move(CanonIncludes); - } + CanonicalIncludes takeCanonicalIncludes() { return std::move(CanonIncludes); } void AfterExecute(CompilerInstance &CI) override { if (!ParsedCallback) diff --git a/unittests/clangd/FileIndexTests.cpp b/unittests/clangd/FileIndexTests.cpp index 0b037a50..fc374bba 100644 --- a/unittests/clangd/FileIndexTests.cpp +++ b/unittests/clangd/FileIndexTests.cpp @@ -212,6 +212,39 @@ TEST(FileIndexTest, IncludeCollected) { ""); } +TEST(FileIndexTest, HasSystemHeaderMappingsInPreamble) { + FileIndex Index; + const std::string Header = R"cpp( + class Foo {}; + )cpp"; + auto MainFile = testPath("foo.cpp"); + auto HeaderFile = testPath("bits/alloc_traits.h"); + std::vector Cmd = {"clang", "-xc++", MainFile.c_str(), + "-include", HeaderFile.c_str()}; + // Preparse ParseInputs. + ParseInputs PI; + PI.CompileCommand.Directory = testRoot(); + PI.CompileCommand.Filename = MainFile; + PI.CompileCommand.CommandLine = {Cmd.begin(), Cmd.end()}; + PI.Contents = ""; + PI.FS = buildTestFS({{MainFile, ""}, {HeaderFile, Header}}); + + // Prepare preamble. + auto CI = buildCompilerInvocation(PI); + auto PreambleData = buildPreamble( + MainFile, *buildCompilerInvocation(PI), /*OldPreamble=*/nullptr, + tooling::CompileCommand(), PI, std::make_shared(), + /*StoreInMemory=*/true, + [&](ASTContext &Ctx, std::shared_ptr PP, + const CanonicalIncludes &Includes) { + Index.updatePreamble(MainFile, Ctx, PP, Includes); + }); + auto Symbols = runFuzzyFind(Index, ""); + EXPECT_THAT(Symbols, ElementsAre(_)); + EXPECT_THAT(Symbols.begin()->IncludeHeaders.front().IncludeHeader, + ""); +} + TEST(FileIndexTest, TemplateParamsInLabel) { auto Source = R"cpp( template -- cgit v1.2.3 From 4d6befeeec52104e9c77800b91786bd47a5323bf Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 11 Feb 2019 13:01:47 +0000 Subject: [clangd] Fix broken windows build bots. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353694 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/FileIndexTests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unittests/clangd/FileIndexTests.cpp b/unittests/clangd/FileIndexTests.cpp index fc374bba..5667cb8f 100644 --- a/unittests/clangd/FileIndexTests.cpp +++ b/unittests/clangd/FileIndexTests.cpp @@ -218,7 +218,7 @@ TEST(FileIndexTest, HasSystemHeaderMappingsInPreamble) { class Foo {}; )cpp"; auto MainFile = testPath("foo.cpp"); - auto HeaderFile = testPath("bits/alloc_traits.h"); + auto HeaderFile = testPath("algorithm"); std::vector Cmd = {"clang", "-xc++", MainFile.c_str(), "-include", HeaderFile.c_str()}; // Preparse ParseInputs. @@ -242,7 +242,7 @@ TEST(FileIndexTest, HasSystemHeaderMappingsInPreamble) { auto Symbols = runFuzzyFind(Index, ""); EXPECT_THAT(Symbols, ElementsAre(_)); EXPECT_THAT(Symbols.begin()->IncludeHeaders.front().IncludeHeader, - ""); + ""); } TEST(FileIndexTest, TemplateParamsInLabel) { -- cgit v1.2.3 From 3548ba485031fb459736c576db3dc8d3ad6cf74f Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 11 Feb 2019 13:03:08 +0000 Subject: [clangd] Index parameters in function decls Reviewers: hokein Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57950 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353696 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 2 ++ unittests/clangd/SymbolInfoTests.cpp | 6 ++++++ unittests/clangd/XRefsTests.cpp | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 74ededc6..3f89165b 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -215,6 +215,7 @@ IdentifiedSymbol getSymbolAtPosition(ParsedAST &AST, SourceLocation Pos) { IndexOpts.SystemSymbolFilter = index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; + IndexOpts.IndexParametersInDeclarations = true; indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(), AST.getLocalTopLevelDecls(), DeclMacrosFinder, IndexOpts); @@ -400,6 +401,7 @@ findRefs(const std::vector &Decls, ParsedAST &AST) { IndexOpts.SystemSymbolFilter = index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; + IndexOpts.IndexParametersInDeclarations = true; indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(), AST.getLocalTopLevelDecls(), RefFinder, IndexOpts); return std::move(RefFinder).take(); diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp index 69a27f23..ed34c036 100644 --- a/unittests/clangd/SymbolInfoTests.cpp +++ b/unittests/clangd/SymbolInfoTests.cpp @@ -301,6 +301,12 @@ TEST(SymbolInfoTests, All) { } )cpp", {CreateExpectedSymbolDetails("bar", "foo::", "c:@E@foo@bar")}}, + { + R"cpp( // Parameters in declarations + void foo(int ba^r); + )cpp", + {CreateExpectedSymbolDetails("bar", "foo", + "c:TestTU.cpp@50@F@foo#I#@bar")}}, { R"cpp( // Type inferrence with auto keyword struct foo {}; diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index e68790a2..acbeaf48 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -86,6 +86,10 @@ TEST(HighlightsTest, All) { auto *X = &[[foo]]; } )cpp", + + R"cpp(// Function parameter in decl + void foo(int [[^bar]]); + )cpp", }; for (const char *Test : Tests) { Annotations T(Test); -- cgit v1.2.3 From 0fd783186a92b265e018c4897db4283cf9ff70f9 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Mon, 11 Feb 2019 15:05:29 +0000 Subject: [clangd] Prefer location from codegen files when merging symbols. Summary: For example, if an index symbol has location in a .proto file and an AST symbol has location in a generated .proto.h file, then we prefer location in .proto which is more meaningful to users. Also use `mergeSymbols` to get the preferred location between AST location and index location in go-to-def. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58037 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353708 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 45 ++++++++++++++++++++++++++++++++++++++--- clangd/index/Merge.cpp | 30 ++++++++++++++++++++++----- unittests/clangd/IndexTests.cpp | 16 +++++++++++++++ unittests/clangd/XRefsTests.cpp | 20 ++++++++++++++++++ 4 files changed, 103 insertions(+), 8 deletions(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 3f89165b..5c97c6a6 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -10,6 +10,8 @@ #include "Logger.h" #include "SourceCode.h" #include "URI.h" +#include "index/Index.h" +#include "index/Merge.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Index/IndexDataConsumer.h" @@ -77,6 +79,32 @@ llvm::Optional toLSPLocation(const SymbolLocation &Loc, return LSPLoc; } +SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) { + SymbolLocation SymLoc; + URIStorage = Loc.uri.uri(); + SymLoc.FileURI = URIStorage.c_str(); + SymLoc.Start.setLine(Loc.range.start.line); + SymLoc.Start.setColumn(Loc.range.start.character); + SymLoc.End.setLine(Loc.range.end.line); + SymLoc.End.setColumn(Loc.range.end.character); + return SymLoc; +} + +// Returns the preferred location between an AST location and an index location. +SymbolLocation getPreferredLocation(const Location &ASTLoc, + const SymbolLocation &IdxLoc) { + // Also use a dummy symbol for the index location so that other fields (e.g. + // definition) are not factored into the preferrence. + Symbol ASTSym, IdxSym; + ASTSym.ID = IdxSym.ID = SymbolID("dummy_id"); + std::string URIStore; + ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, URIStore); + IdxSym.CanonicalDeclaration = IdxLoc; + auto Merged = mergeSymbol(ASTSym, IdxSym); + return Merged.CanonicalDeclaration; +} + + struct MacroDecl { llvm::StringRef Name; const MacroInfo *Info; @@ -329,12 +357,23 @@ std::vector locateSymbolAt(ParsedAST &AST, Position Pos, // Special case: if the AST yielded a definition, then it may not be // the right *declaration*. Prefer the one from the index. - if (R.Definition) // from AST + if (R.Definition) { // from AST if (auto Loc = toLSPLocation(Sym.CanonicalDeclaration, *MainFilePath)) R.PreferredDeclaration = *Loc; - - if (!R.Definition) + } else { R.Definition = toLSPLocation(Sym.Definition, *MainFilePath); + + if (Sym.CanonicalDeclaration) { + // Use merge logic to choose AST or index declaration. + // We only do this for declarations as definitions from AST + // is generally preferred (e.g. definitions in main file). + if (auto Loc = + toLSPLocation(getPreferredLocation(R.PreferredDeclaration, + Sym.CanonicalDeclaration), + *MainFilePath)) + R.PreferredDeclaration = *Loc; + } + } }); } diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp index d967db8a..65e9b86d 100644 --- a/clangd/index/Merge.cpp +++ b/clangd/index/Merge.cpp @@ -9,9 +9,13 @@ #include "Merge.h" #include "Logger.h" #include "Trace.h" +#include "index/Index.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/raw_ostream.h" +#include +#include namespace clang { namespace clangd { @@ -114,6 +118,23 @@ void MergedIndex::refs(const RefsRequest &Req, }); } +// Returns true if \p L is (strictly) preferred to \p R (e.g. by file paths). If +// neither is preferred, this returns false. +bool prefer(const SymbolLocation &L, const SymbolLocation &R) { + if (!L) + return false; + if (!R) + return true; + auto HasCodeGenSuffix = [](const SymbolLocation &Loc) { + constexpr static const char *CodegenSuffixes[] = {".proto"}; + return std::any_of(std::begin(CodegenSuffixes), std::end(CodegenSuffixes), + [&](llvm::StringRef Suffix) { + return llvm::StringRef(Loc.FileURI).endswith(Suffix); + }); + }; + return HasCodeGenSuffix(L) && !HasCodeGenSuffix(R); +} + Symbol mergeSymbol(const Symbol &L, const Symbol &R) { assert(L.ID == R.ID); // We prefer information from TUs that saw the definition. @@ -128,12 +149,11 @@ Symbol mergeSymbol(const Symbol &L, const Symbol &R) { Symbol S = PreferR ? R : L; // The target symbol we're merging into. const Symbol &O = PreferR ? L : R; // The "other" less-preferred symbol. - // For each optional field, fill it from O if missing in S. - // (It might be missing in O too, but that's a no-op). - if (!S.Definition) - S.Definition = O.Definition; - if (!S.CanonicalDeclaration) + // Only use locations in \p O if it's (strictly) preferred. + if (prefer(O.CanonicalDeclaration, S.CanonicalDeclaration)) S.CanonicalDeclaration = O.CanonicalDeclaration; + if (prefer(O.Definition, S.Definition)) + S.Definition = O.Definition; S.References += O.References; if (S.Signature == "") S.Signature = O.Signature; diff --git a/unittests/clangd/IndexTests.cpp b/unittests/clangd/IndexTests.cpp index 4ca88cae..7d60ede1 100644 --- a/unittests/clangd/IndexTests.cpp +++ b/unittests/clangd/IndexTests.cpp @@ -253,6 +253,22 @@ TEST(MergeTest, PreferSymbolWithDefn) { EXPECT_EQ(M.Name, "right"); } +TEST(MergeTest, PreferSymbolLocationInCodegenFile) { + Symbol L, R; + + L.ID = R.ID = SymbolID("hello"); + L.CanonicalDeclaration.FileURI = "file:/x.proto.h"; + R.CanonicalDeclaration.FileURI = "file:/x.proto"; + + Symbol M = mergeSymbol(L, R); + EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/x.proto"); + + // Prefer L if both have codegen suffix. + L.CanonicalDeclaration.FileURI = "file:/y.proto"; + M = mergeSymbol(L, R); + EXPECT_EQ(StringRef(M.CanonicalDeclaration.FileURI), "file:/y.proto"); +} + TEST(MergeIndexTest, Refs) { FileIndex Dyn; FileIndex StaticIndex; diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index acbeaf48..fea90137 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -184,6 +184,26 @@ TEST(LocateSymbol, WithIndex) { ElementsAre(Sym("Forward", SymbolHeader.range("forward"), Test.range()))); } +TEST(LocateSymbol, WithIndexPreferredLocation) { + Annotations SymbolHeader(R"cpp( + class $[[Proto]] {}; + )cpp"); + TestTU TU; + TU.HeaderCode = SymbolHeader.code(); + TU.HeaderFilename = "x.proto"; // Prefer locations in codegen files. + auto Index = TU.index(); + + Annotations Test(R"cpp(// only declaration in AST. + // Shift to make range different. + class [[Proto]]; + P^roto* create(); + )cpp"); + + auto AST = TestTU::withCode(Test.code()).build(); + auto Locs = clangd::locateSymbolAt(AST, Test.point(), Index.get()); + EXPECT_THAT(Locs, ElementsAre(Sym("Proto", SymbolHeader.range()))); +} + TEST(LocateSymbol, All) { // Ranges in tests: // $decl is the declaration location (if absent, no symbol is located) -- cgit v1.2.3 From 88620742ce6d0543aa75bd13e4800eee0f9f364e Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 11 Feb 2019 15:18:11 +0000 Subject: Revamp the "[clangd] Format tweak's replacements" Summary: This patch contains two parts: 1) reverts commit r353306. 2) move the format logic out from tweaks, keep tweaks API unchanged. Reviewers: sammccall, ilya-biryukov Reviewed By: ilya-biryukov Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58051 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353712 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdServer.cpp | 18 +++++++---- clangd/ClangdUnit.cpp | 3 +- clangd/Compiler.h | 2 -- clangd/refactor/Tweak.cpp | 8 ----- clangd/refactor/Tweak.h | 14 ++------- clangd/refactor/tweaks/SwapIfBranches.cpp | 7 ++--- test/clangd/tweaks-format.test | 50 +++++++++++++++++++++++++++++++ unittests/clangd/TweakTests.cpp | 40 +++---------------------- 8 files changed, 73 insertions(+), 69 deletions(-) create mode 100644 test/clangd/tweaks-format.test diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 1aa87998..11e3d2c0 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -152,9 +152,6 @@ void ClangdServer::addDocument(PathRef File, llvm::StringRef Contents, Opts.ClangTidyOpts = tidy::ClangTidyOptions::getDefaults(); if (ClangTidyOptProvider) Opts.ClangTidyOpts = ClangTidyOptProvider->getOptions(File); - // FIXME: cache this. - Opts.Style = - getFormatStyleForFile(File, Contents, FSProvider.getFileSystem().get()); Opts.SuggestMissingIncludes = SuggestMissingIncludes; // FIXME: some build systems like Bazel will take time to preparing // environment to build the file, it would be nice if we could emit a @@ -365,8 +362,9 @@ void ClangdServer::enumerateTweaks(PathRef File, Range Sel, void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, Callback CB) { - auto Action = [Sel](decltype(CB) CB, std::string File, std::string TweakID, - Expected InpAST) { + auto Action = [Sel, this](decltype(CB) CB, std::string File, + std::string TweakID, + Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); auto Selection = tweakSelection(Sel, *InpAST); @@ -375,7 +373,15 @@ void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, auto A = prepareTweak(TweakID, *Selection); if (!A) return CB(A.takeError()); - return CB((*A)->apply(*Selection, InpAST->Inputs.Opts.Style)); + auto RawReplacements = (*A)->apply(*Selection); + if (!RawReplacements) + return CB(RawReplacements.takeError()); + // FIXME: this function has I/O operations (find .clang-format file), figure + // out a way to cache the format style. + auto Style = getFormatStyleForFile(File, InpAST->Inputs.Contents, + InpAST->Inputs.FS.get()); + return CB( + cleanupAndFormat(InpAST->Inputs.Contents, *RawReplacements, Style)); }; WorkScheduler.runWithAST( "ApplyTweak", File, diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index 1689a644..b07abd9a 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -308,8 +308,9 @@ ParsedAST::build(std::unique_ptr CI, llvm::Optional FixIncludes; auto BuildDir = VFS->getCurrentWorkingDirectory(); if (Opts.SuggestMissingIncludes && Index && !BuildDir.getError()) { + auto Style = getFormatStyleForFile(MainInput.getFile(), Content, VFS.get()); auto Inserter = std::make_shared( - MainInput.getFile(), Content, Opts.Style, BuildDir.get(), + MainInput.getFile(), Content, Style, BuildDir.get(), Clang->getPreprocessor().getHeaderSearchInfo()); if (Preamble) { for (const auto &Inc : Preamble->Includes.MainFileIncludes) diff --git a/clangd/Compiler.h b/clangd/Compiler.h index 2d5c1b3e..9466d8e2 100644 --- a/clangd/Compiler.h +++ b/clangd/Compiler.h @@ -17,7 +17,6 @@ #include "../clang-tidy/ClangTidyOptions.h" #include "index/Index.h" -#include "clang/Format/Format.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Frontend/CompilerInvocation.h" #include "clang/Frontend/PrecompiledPreamble.h" @@ -39,7 +38,6 @@ public: struct ParseOptions { tidy::ClangTidyOptions ClangTidyOpts; bool SuggestMissingIncludes = false; - format::FormatStyle Style; }; /// Information required to run clang, e.g. to parse AST or do code completion. diff --git a/clangd/refactor/Tweak.cpp b/clangd/refactor/Tweak.cpp index 6a3b090b..34634e64 100644 --- a/clangd/refactor/Tweak.cpp +++ b/clangd/refactor/Tweak.cpp @@ -46,14 +46,6 @@ Tweak::Selection::Selection(ParsedAST &AST, unsigned RangeBegin, Cursor = SM.getComposedLoc(SM.getMainFileID(), RangeBegin); } -Expected Tweak::apply(const Selection &Sel, - const format::FormatStyle &Style) { - auto RawReplacements = execute(Sel); - if (!RawReplacements) - return RawReplacements; - return cleanupAndFormat(Sel.Code, *RawReplacements, Style); -} - std::vector> prepareTweaks(const Tweak::Selection &S) { validateRegistry(); diff --git a/clangd/refactor/Tweak.h b/clangd/refactor/Tweak.h index 108e07e1..35c3ce8a 100644 --- a/clangd/refactor/Tweak.h +++ b/clangd/refactor/Tweak.h @@ -22,7 +22,6 @@ #include "ClangdUnit.h" #include "Protocol.h" #include "Selection.h" -#include "clang/Format/Format.h" #include "clang/Tooling/Core/Replacement.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/StringRef.h" @@ -48,7 +47,7 @@ public: ParsedAST &AST; /// A location of the cursor in the editor. SourceLocation Cursor; - /// The AST nodes that were selected. + // The AST nodes that were selected. SelectionTree ASTSelection; // FIXME: provide a way to get sources and ASTs for other files. }; @@ -64,20 +63,13 @@ public: /// should be moved into 'apply'. /// Returns true iff the action is available and apply() can be called on it. virtual bool prepare(const Selection &Sel) = 0; - /// Format and apply the actual changes generated from the second stage of the - /// action. + /// Run the second stage of the action that would produce the actual changes. /// EXPECTS: prepare() was called and returned true. - Expected apply(const Selection &Sel, - const format::FormatStyle &Style); + virtual Expected apply(const Selection &Sel) = 0; /// A one-line title of the action that should be shown to the users in the /// UI. /// EXPECTS: prepare() was called and returned true. virtual std::string title() const = 0; - -protected: - /// Run the second stage of the action that would produce the actual changes. - /// EXPECTS: prepare() was called and returned true. - virtual Expected execute(const Selection &Sel) = 0; }; // All tweaks must be registered in the .cpp file next to their definition. diff --git a/clangd/refactor/tweaks/SwapIfBranches.cpp b/clangd/refactor/tweaks/SwapIfBranches.cpp index 40dd6987..9b0b72d9 100644 --- a/clangd/refactor/tweaks/SwapIfBranches.cpp +++ b/clangd/refactor/tweaks/SwapIfBranches.cpp @@ -37,11 +37,9 @@ public: const char *id() const override final; bool prepare(const Selection &Inputs) override; + Expected apply(const Selection &Inputs) override; std::string title() const override; -protected: - Expected execute(const Selection &Inputs) override; - private: const IfStmt *If = nullptr; }; @@ -62,8 +60,7 @@ bool SwapIfBranches::prepare(const Selection &Inputs) { dyn_cast_or_null(If->getElse()); } -Expected -SwapIfBranches::execute(const Selection &Inputs) { +Expected SwapIfBranches::apply(const Selection &Inputs) { auto &Ctx = Inputs.AST.getASTContext(); auto &SrcMgr = Ctx.getSourceManager(); diff --git a/test/clangd/tweaks-format.test b/test/clangd/tweaks-format.test new file mode 100644 index 00000000..8fe7a112 --- /dev/null +++ b/test/clangd/tweaks-format.test @@ -0,0 +1,50 @@ +# RUN: clangd -lit-test < %s | FileCheck %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cc","languageId":"cpp","version":1,"text":"int f() { if (true) { return 1; } else {} }"}}} +--- +{"jsonrpc":"2.0","id":5,"method":"textDocument/codeAction","params":{"textDocument":{"uri":"test:///main.cc"},"range":{"start":{"line":0,"character":11},"end":{"line":0,"character":11}},"context":{"diagnostics":[]}}} +--- +{"jsonrpc":"2.0","id":6,"method":"workspace/executeCommand","params":{"command":"clangd.applyTweak","arguments":[{"file":"test:///main.cc","selection":{"end":{"character":11,"line":0},"start":{"character":11,"line":0}},"tweakID":"SwapIfBranches"}]}} +# CHECK: "newText": "\n ", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 10, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 9, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "{\n }", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 33, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 20, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: { +# CHECK-NEXT: "newText": "{\n return 1;\n }\n", +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 42, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 39, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: } +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":3,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} diff --git a/unittests/clangd/TweakTests.cpp b/unittests/clangd/TweakTests.cpp index a76d3aea..baa60292 100644 --- a/unittests/clangd/TweakTests.cpp +++ b/unittests/clangd/TweakTests.cpp @@ -98,7 +98,7 @@ llvm::Expected apply(StringRef ID, llvm::StringRef Input) { auto T = prepareTweak(ID, S); if (!T) return T.takeError(); - auto Replacements = (*T)->apply(S, clang::format::getLLVMStyle()); + auto Replacements = (*T)->apply(S); if (!Replacements) return Replacements.takeError(); return applyAllReplacements(Code.code(), *Replacements); @@ -127,40 +127,12 @@ TEST(TweakTest, SwapIfBranches) { llvm::StringLiteral Input = R"cpp( void test() { - ^if (true) { - return 100; - } else { - continue; - } + ^if (true) { return 100; } else { continue; } } )cpp"; llvm::StringLiteral Output = R"cpp( void test() { - if (true) { - continue; - } else { - return 100; - } - } - )cpp"; - checkTransform(ID, Input, Output); - - Input = R"cpp( - void test() { - ^if () { - return 100; - } else { - continue; - } - } - )cpp"; - Output = R"cpp( - void test() { - if () { - continue; - } else { - return 100; - } + if (true) { continue; } else { return 100; } } )cpp"; checkTransform(ID, Input, Output); @@ -172,11 +144,7 @@ TEST(TweakTest, SwapIfBranches) { )cpp"; Output = R"cpp( void test() { - if () { - continue; - } else { - return 100; - } + if () { continue; } else { return 100; } } )cpp"; checkTransform(ID, Input, Output); -- cgit v1.2.3 From 43a715d3a5b1592c67a40d3404bc5fed2ca5e67b Mon Sep 17 00:00:00 2001 From: Francis Visoiu Mistrih Date: Mon, 11 Feb 2019 22:36:47 +0000 Subject: [NFC][clangd] Remove unused lambda capture Avoid this warning: llvm/clang-tools-extra/clangd/ClangdServer.cpp:365:23: warning: lambda capture 'this' is not used [-Wunused-lambda-capture] auto Action = [Sel, this](decltype(CB) CB, std::string File, ~~^~~~ 1 warning generated. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353760 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdServer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 11e3d2c0..9dc33280 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -362,7 +362,7 @@ void ClangdServer::enumerateTweaks(PathRef File, Range Sel, void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, Callback CB) { - auto Action = [Sel, this](decltype(CB) CB, std::string File, + auto Action = [Sel](decltype(CB) CB, std::string File, std::string TweakID, Expected InpAST) { if (!InpAST) -- cgit v1.2.3 From 333ac7989785f95735b5b36affdd341fbd3b769b Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Tue, 12 Feb 2019 10:38:45 +0000 Subject: [clangd] Fix use-after-free in XRefs git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353821 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 5c97c6a6..b296a056 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -92,19 +92,18 @@ SymbolLocation toIndexLocation(const Location &Loc, std::string &URIStorage) { // Returns the preferred location between an AST location and an index location. SymbolLocation getPreferredLocation(const Location &ASTLoc, - const SymbolLocation &IdxLoc) { + const SymbolLocation &IdxLoc, + std::string &Scratch) { // Also use a dummy symbol for the index location so that other fields (e.g. // definition) are not factored into the preferrence. Symbol ASTSym, IdxSym; ASTSym.ID = IdxSym.ID = SymbolID("dummy_id"); - std::string URIStore; - ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, URIStore); + ASTSym.CanonicalDeclaration = toIndexLocation(ASTLoc, Scratch); IdxSym.CanonicalDeclaration = IdxLoc; auto Merged = mergeSymbol(ASTSym, IdxSym); return Merged.CanonicalDeclaration; } - struct MacroDecl { llvm::StringRef Name; const MacroInfo *Info; @@ -352,6 +351,7 @@ std::vector locateSymbolAt(ParsedAST &AST, Position Pos, LookupRequest QueryRequest; for (auto It : ResultIndex) QueryRequest.IDs.insert(It.first); + std::string Scratch; Index->lookup(QueryRequest, [&](const Symbol &Sym) { auto &R = Result[ResultIndex.lookup(Sym.ID)]; @@ -367,10 +367,10 @@ std::vector locateSymbolAt(ParsedAST &AST, Position Pos, // Use merge logic to choose AST or index declaration. // We only do this for declarations as definitions from AST // is generally preferred (e.g. definitions in main file). - if (auto Loc = - toLSPLocation(getPreferredLocation(R.PreferredDeclaration, - Sym.CanonicalDeclaration), - *MainFilePath)) + if (auto Loc = toLSPLocation( + getPreferredLocation(R.PreferredDeclaration, + Sym.CanonicalDeclaration, Scratch), + *MainFilePath)) R.PreferredDeclaration = *Loc; } } -- cgit v1.2.3 From 1ae839a6967a573241dec66a697caebd56c7b2f4 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 12 Feb 2019 16:54:47 +0000 Subject: [clangd] Fix a lit-test. Summary: Fixes https://bugs.llvm.org/show_bug.cgi?id=40593. Non-percent-encoded chars doesn't cause any problems on the input-side since we assume everything after authority section is data and don't interpret them as delimeters. Reviewers: sammccall Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58126 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353857 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/clangd/Inputs/background-index/definition.jsonrpc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/clangd/Inputs/background-index/definition.jsonrpc b/test/clangd/Inputs/background-index/definition.jsonrpc index 89d50482..933e7791 100644 --- a/test/clangd/Inputs/background-index/definition.jsonrpc +++ b/test/clangd/Inputs/background-index/definition.jsonrpc @@ -44,7 +44,7 @@ } } } -# CHECK: "uri": "file://DIRECTORY/foo.cpp" +# CHECK: "uri": "file://{{.*}}/foo.cpp" --- {"jsonrpc":"2.0","id":3,"method":"shutdown"} --- -- cgit v1.2.3 From 80b6bd266d30d1fbc12b8cf16db684365492c0e6 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 13 Feb 2019 08:58:54 +0000 Subject: [clangd] Handle a few more diag kinds in include fixer. Reviewers: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58135 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@353926 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/IncludeFixer.cpp | 6 ++++++ unittests/clangd/DiagnosticsTests.cpp | 19 +++++++++++++++---- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index cdd973a2..177d5774 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -79,6 +79,12 @@ std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, case diag::err_typename_nested_not_found: case diag::err_no_template: case diag::err_no_template_suggest: + case diag::err_undeclared_use: + case diag::err_undeclared_use_suggest: + case diag::err_undeclared_var_use: + case diag::err_undeclared_var_use_suggest: + case diag::err_no_member: // Could be no member in namespace. + case diag::err_no_member_suggest: if (LastUnresolvedName) { // Try to fix unresolved name caused by missing declaraion. // E.g. diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index a42e5a71..d9c9dfc9 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -368,11 +368,14 @@ TEST(IncludeFixerTest, Typo) { Annotations Test(R"cpp( $insert[[]]namespace ns { void foo() { - $unqualified[[X]] x; + $unqualified1[[X]] x; + $unqualified2[[X]]::Nested n; } } void bar() { - ns::$qualified[[X]] x; // ns:: is valid. + ns::$qualified1[[X]] x; // ns:: is valid. + ns::$qualified2[[X]](); // Error: no member in namespace + ::$global[[Global]] glob; } )cpp"); @@ -385,13 +388,21 @@ void bar() { EXPECT_THAT( TU.build().getDiagnostics(), UnorderedElementsAre( - AllOf(Diag(Test.range("unqualified"), "unknown type name 'X'"), + AllOf(Diag(Test.range("unqualified1"), "unknown type name 'X'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))), + AllOf(Diag(Test.range("unqualified2"), + "use of undeclared identifier 'X'"), WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", "Add include \"x.h\" for symbol ns::X"))), - AllOf(Diag(Test.range("qualified"), + AllOf(Diag(Test.range("qualified1"), "no type named 'X' in namespace 'ns'"), WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", "Add include \"x.h\" for symbol ns::X"))), + AllOf(Diag(Test.range("qualified2"), + "no member named 'X' in namespace 'ns'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))), AllOf(Diag(Test.range("global"), "no type named 'Global' in the global namespace"), WithFix(Fix(Test.range("insert"), "#include \"global.h\"\n", -- cgit v1.2.3 From ab354de81d7dc2baceedeb3f8991e8f56f5bfac4 Mon Sep 17 00:00:00 2001 From: Volodymyr Sapsai Date: Thu, 14 Feb 2019 22:37:30 +0000 Subject: [clang-tidy] Mention language version in test explicitly. "modernize-use-using" check is applicable only to C++11 and later. Spell it out to avoid relying on default language version. rdar://problem/47932196 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354069 91177308-0d34-0410-b5e6-96231b3b80d8 --- test/clang-tidy/clang-tidy-mac-libcxx.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/clang-tidy/clang-tidy-mac-libcxx.cpp b/test/clang-tidy/clang-tidy-mac-libcxx.cpp index 153a5d6e..d124a344 100644 --- a/test/clang-tidy/clang-tidy-mac-libcxx.cpp +++ b/test/clang-tidy/clang-tidy-mac-libcxx.cpp @@ -8,7 +8,7 @@ // RUN: cp -r %S/Inputs/mock-libcxx %t/ // // Pretend clang is installed beside the mock library that we provided. -// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json +// RUN: echo '[{"directory":"%t","command":"%t/mock-libcxx/bin/clang++ -stdlib=libc++ -std=c++11 -target x86_64-apple-darwin -c test.cpp","file":"test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json // RUN: cp "%s" "%t/test.cpp" // RUN: clang-tidy -header-filter='.*' -system-headers -checks='-*,modernize-use-using' "%t/test.cpp" | FileCheck %s // CHECK: mock_vector:{{[0-9]+}}:{{[0-9]+}}: warning: use 'using' instead of 'typedef' -- cgit v1.2.3 From cc9a995d3f91e976da4ee6ecd1b7a0d930c19c73 Mon Sep 17 00:00:00 2001 From: Sam McCall Date: Fri, 15 Feb 2019 11:04:25 +0000 Subject: [clangd] Unlink VFS working dir from OS working dir. Reland of r351051 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354116 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/FSProvider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clangd/FSProvider.cpp b/clangd/FSProvider.cpp index be915740..5d1434bf 100644 --- a/clangd/FSProvider.cpp +++ b/clangd/FSProvider.cpp @@ -74,9 +74,10 @@ clang::clangd::RealFileSystemProvider::getFileSystem() const { // FIXME: Try to use a similar approach in Sema instead of relying on // propagation of the 'isVolatile' flag through all layers. #ifdef _WIN32 - return new VolatileFileSystem(llvm::vfs::getRealFileSystem()); + return new VolatileFileSystem( + llvm::vfs::createPhysicalFileSystem().release()); #else - return llvm::vfs::getRealFileSystem(); + return llvm::vfs::createPhysicalFileSystem().release(); #endif } } // namespace clangd -- cgit v1.2.3 From 4aa33868c8e69acf970db89a0aa0bb85f57c046c Mon Sep 17 00:00:00 2001 From: Stephane Moore Date: Sat, 16 Feb 2019 04:27:12 +0000 Subject: =?UTF-8?q?[clang-tidy]=20Delete=20obsolete=20objc-property-declar?= =?UTF-8?q?ation=20options=20=E2=9C=82=EF=B8=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: The Acronyms and IncludeDefaultAcronyms options were deprecated in https://reviews.llvm.org/D51832. These options can be removed. Tested by running the clang-tidy tests. This is an amended resubmission of https://reviews.llvm.org/D56945. Reviewers: Eugene.Zelenko, aaron.ballman Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57080 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354195 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/objc/PropertyDeclarationCheck.cpp | 14 -------------- clang-tidy/objc/PropertyDeclarationCheck.h | 11 ++--------- docs/ReleaseNotes.rst | 4 ++++ docs/clang-tidy/checks/objc-property-declaration.rst | 12 ------------ 4 files changed, 6 insertions(+), 35 deletions(-) diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp index 653c6bb8..eba702be 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -97,14 +97,6 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) { } } // namespace -PropertyDeclarationCheck::PropertyDeclarationCheck(StringRef Name, - ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - SpecialAcronyms( - utils::options::parseStringList(Options.get("Acronyms", ""))), - IncludeDefaultAcronyms(Options.get("IncludeDefaultAcronyms", true)), - EscapedAcronyms() {} - void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) { // this check should only be applied to ObjC sources. if (!getLangOpts().ObjC) return; @@ -145,12 +137,6 @@ void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) { << generateFixItHint(MatchedDecl, StandardProperty); } -void PropertyDeclarationCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { - Options.store(Opts, "Acronyms", - utils::options::serializeStringList(SpecialAcronyms)); - Options.store(Opts, "IncludeDefaultAcronyms", IncludeDefaultAcronyms); -} - } // namespace objc } // namespace tidy } // namespace clang diff --git a/clang-tidy/objc/PropertyDeclarationCheck.h b/clang-tidy/objc/PropertyDeclarationCheck.h index d28bde40..49af5df5 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.h +++ b/clang-tidy/objc/PropertyDeclarationCheck.h @@ -10,8 +10,6 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_OBJC_PROPERTY_DECLARATION_H #include "../ClangTidy.h" -#include -#include namespace clang { namespace tidy { @@ -27,15 +25,10 @@ namespace objc { /// http://clang.llvm.org/extra/clang-tidy/checks/objc-property-declaration.html class PropertyDeclarationCheck : public ClangTidyCheck { public: - PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context); + PropertyDeclarationCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; - void storeOptions(ClangTidyOptions::OptionMap &Options) override; - -private: - const std::vector SpecialAcronyms; - const bool IncludeDefaultAcronyms; - std::vector EscapedAcronyms; }; } // namespace objc diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index f932af42..d92cda0b 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -98,6 +98,10 @@ Improvements to clang-tidy `CommentUserDefiniedLiterals`, `CommentStringLiterals`, `CommentCharacterLiterals` & `CommentNullPtrs` options. +- The `Acronyms` and `IncludeDefaultAcronyms` options for the + :doc:`objc-property-declaration ` + check have been removed. + Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/objc-property-declaration.rst b/docs/clang-tidy/checks/objc-property-declaration.rst index 49df5102..60b9c82e 100644 --- a/docs/clang-tidy/checks/objc-property-declaration.rst +++ b/docs/clang-tidy/checks/objc-property-declaration.rst @@ -40,15 +40,3 @@ lowercase letters followed by a '_' to avoid naming conflict. For example: @property(nonatomic, assign) int abc_lowerCamelCase; The corresponding style rule: https://developer.apple.com/library/content/qa/qa1908/_index.html - - -Options -------- - -.. option:: Acronyms - - This option is deprecated and ignored. - -.. option:: IncludeDefaultAcronyms - - This option is deprecated and ignored. -- cgit v1.2.3 From 1e8232450ee6b7f65f7261956041518135ebc933 Mon Sep 17 00:00:00 2001 From: Bruno Ricci Date: Sun, 17 Feb 2019 18:21:54 +0000 Subject: [clang-tidy][NFCI] DanglingHandleCheck: Remove a superflous IgnoreParenImpCasts ExprWithCleanups is currently not skipped by IgnoreParenImpCasts, but is skipped by IgnoreImpCasts. In view of fixing this inconsistency in D57267, remove the IgnoreParenImpCasts between the ReturnStmt and the ExprWithCleanups which is not needed since ExprWithCleanups is always created as a direct child of ReturnStmt (by inspection of each ReturnStmt::Create in Sema/SemaStmt.cpp). NFC intended. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354228 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/DanglingHandleCheck.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/clang-tidy/bugprone/DanglingHandleCheck.cpp b/clang-tidy/bugprone/DanglingHandleCheck.cpp index 9cefc20f..74ad2e75 100644 --- a/clang-tidy/bugprone/DanglingHandleCheck.cpp +++ b/clang-tidy/bugprone/DanglingHandleCheck.cpp @@ -163,9 +163,8 @@ void DanglingHandleCheck::registerMatchersForReturn(MatchFinder *Finder) { // Return a temporary. Finder->addMatcher( - returnStmt( - has(ignoringParenImpCasts(exprWithCleanups(has(ignoringParenImpCasts( - handleFrom(IsAHandle, handleFromTemporaryValue(IsAHandle)))))))) + returnStmt(has(exprWithCleanups(has(ignoringParenImpCasts(handleFrom( + IsAHandle, handleFromTemporaryValue(IsAHandle))))))) .bind("bad_stmt"), this); } -- cgit v1.2.3 From 86f9f2fb2dd4e38f4f09c4a6385ddc501fc60d69 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Mon, 18 Feb 2019 12:50:35 +0000 Subject: [clang-tidy] Fix links in docs. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354266 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/index.rst | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/clang-tidy/index.rst b/docs/clang-tidy/index.rst index 1cbd8dc5..12a32dfb 100644 --- a/docs/clang-tidy/index.rst +++ b/docs/clang-tidy/index.rst @@ -264,13 +264,14 @@ Suppressing Undesired Diagnostics adhere to a coding standard, or is otherwise problematic in some way. However, if the code is known to be correct, it may be useful to silence the warning. Some clang-tidy checks provide a check-specific way to silence the diagnostics, -e.g. `bugprone-use-after-move `_ can be +e.g. `bugprone-use-after-move `_ can be silenced by re-initializing the variable after it has been moved out, `bugprone-string-integer-assignment -`_ can be suppressed by explicitly -casting the integer to ``char``, `readability-implicit-bool-conversion -`_ can also be suppressed by using -explicit casts, etc. +`_ can be suppressed by +explicitly casting the integer to ``char``, +`readability-implicit-bool-conversion +`_ can also be suppressed by +using explicit casts, etc. If a specific suppression mechanism is not available for a certain warning, or its use is not desired for some reason, :program:`clang-tidy` has a generic -- cgit v1.2.3 From 30f467e1c602f2bb522672eef2eb80e8b2e3b517 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Mon, 18 Feb 2019 13:12:10 +0000 Subject: [clangd] Cache include fixes for diagnostics caused by the same unresolved name or incomplete type. Summary: Multiple diagnostics can be caused by the same unresolved name or incomplete type, especially if the code is copy-pasted without #includes. The cache can avoid making repetitive index requests, and thus reduce latency and allow more diagnostics to be fixed (we limit the number of index requests for each parse). Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58239 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354268 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/IncludeFixer.cpp | 82 ++++++++++++++++++++++++++--------- clangd/IncludeFixer.h | 14 +++++- unittests/clangd/DiagnosticsTests.cpp | 38 ++++++++++++++++ 3 files changed, 113 insertions(+), 21 deletions(-) diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index 177d5774..9b9b6e13 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -27,6 +27,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" @@ -57,8 +58,6 @@ private: std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, const clang::Diagnostic &Info) const { - if (IndexRequestCount >= IndexRequestLimit) - return {}; // Avoid querying index too many times in a single parse. switch (Info.getID()) { case diag::err_incomplete_type: case diag::err_incomplete_member_access: @@ -118,26 +117,21 @@ std::vector IncludeFixer::fixIncompleteType(const Type &T) const { auto ID = getSymbolID(TD); if (!ID) return {}; - ++IndexRequestCount; - // FIXME: consider batching the requests for all diagnostics. - // FIXME: consider caching the lookup results. - LookupRequest Req; - Req.IDs.insert(*ID); - llvm::Optional Matched; - Index.lookup(Req, [&](const Symbol &Sym) { - if (Matched) - return; - Matched = Sym; - }); - - if (!Matched || Matched->IncludeHeaders.empty() || !Matched->Definition || - Matched->CanonicalDeclaration.FileURI != Matched->Definition.FileURI) + llvm::Optional Symbols = lookupCached(*ID); + if (!Symbols) return {}; - return fixesForSymbols({*Matched}); + const SymbolSlab &Syms = **Symbols; + std::vector Fixes; + if (!Syms.empty()) { + auto &Matched = *Syms.begin(); + if (!Matched.IncludeHeaders.empty() && Matched.Definition && + Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI) + Fixes = fixesForSymbols(Syms); + } + return Fixes; } -std::vector -IncludeFixer::fixesForSymbols(llvm::ArrayRef Syms) const { +std::vector IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const { auto Inserted = [&](const Symbol &Sym, llvm::StringRef Header) -> llvm::Expected> { auto ResolvedDeclaring = @@ -289,6 +283,24 @@ std::vector IncludeFixer::fixUnresolvedName() const { Req.RestrictForCodeCompletion = true; Req.Limit = 100; + if (llvm::Optional Syms = fuzzyFindCached(Req)) + return fixesForSymbols(**Syms); + + return {}; +} + + +llvm::Optional +IncludeFixer::fuzzyFindCached(const FuzzyFindRequest &Req) const { + auto ReqStr = llvm::formatv("{0}", toJSON(Req)).str(); + auto I = FuzzyFindCache.find(ReqStr); + if (I != FuzzyFindCache.end()) + return &I->second; + + if (IndexRequestCount >= IndexRequestLimit) + return llvm::None; + IndexRequestCount++; + SymbolSlab::Builder Matches; Index.fuzzyFind(Req, [&](const Symbol &Sym) { if (Sym.Name != Req.Query) @@ -297,7 +309,37 @@ std::vector IncludeFixer::fixUnresolvedName() const { Matches.insert(Sym); }); auto Syms = std::move(Matches).build(); - return fixesForSymbols(std::vector(Syms.begin(), Syms.end())); + auto E = FuzzyFindCache.try_emplace(ReqStr, std::move(Syms)); + return &E.first->second; +} + +llvm::Optional +IncludeFixer::lookupCached(const SymbolID &ID) const { + LookupRequest Req; + Req.IDs.insert(ID); + + auto I = LookupCache.find(ID); + if (I != LookupCache.end()) + return &I->second; + + if (IndexRequestCount >= IndexRequestLimit) + return llvm::None; + IndexRequestCount++; + + // FIXME: consider batching the requests for all diagnostics. + SymbolSlab::Builder Matches; + Index.lookup(Req, [&](const Symbol &Sym) { Matches.insert(Sym); }); + auto Syms = std::move(Matches).build(); + + std::vector Fixes; + if (!Syms.empty()) { + auto &Matched = *Syms.begin(); + if (!Matched.IncludeHeaders.empty() && Matched.Definition && + Matched.CanonicalDeclaration.FileURI == Matched.Definition.FileURI) + Fixes = fixesForSymbols(Syms); + } + auto E = LookupCache.try_emplace(ID, std::move(Syms)); + return &E.first->second; } } // namespace clangd diff --git a/clangd/IncludeFixer.h b/clangd/IncludeFixer.h index da292b56..f1eac45d 100644 --- a/clangd/IncludeFixer.h +++ b/clangd/IncludeFixer.h @@ -21,6 +21,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include @@ -51,7 +52,7 @@ private: std::vector fixIncompleteType(const Type &T) const; /// Generates header insertion fixes for all symbols. Fixes are deduplicated. - std::vector fixesForSymbols(llvm::ArrayRef Syms) const; + std::vector fixesForSymbols(const SymbolSlab &Syms) const; struct UnresolvedName { std::string Name; // E.g. "X" in foo::X. @@ -79,6 +80,17 @@ private: // These collect the last unresolved name so that we can associate it with the // diagnostic. llvm::Optional LastUnresolvedName; + + // There can be multiple diagnostics that are caused by the same unresolved + // name or incomplete type in one parse, especially when code is + // copy-and-pasted without #includes. We cache the index results based on + // index requests. + mutable llvm::StringMap FuzzyFindCache; + mutable llvm::DenseMap LookupCache; + // Returns None if the number of index requests has reached the limit. + llvm::Optional + fuzzyFindCached(const FuzzyFindRequest &Req) const; + llvm::Optional lookupCached(const SymbolID &ID) const; }; } // namespace clangd diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index d9c9dfc9..d1108489 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -449,6 +449,44 @@ TEST(IncludeFixerTest, NoCrashMemebrAccess) { UnorderedElementsAre(Diag(Test.range(), "no member named 'xy' in 'X'"))); } +TEST(IncludeFixerTest, UseCachedIndexResults) { + // As index results for the identical request are cached, more than 5 fixes + // are generated. + Annotations Test(R"cpp( +$insert[[]]void foo() { + $x1[[X]] x; + $x2[[X]] x; + $x3[[X]] x; + $x4[[X]] x; + $x5[[X]] x; + $x6[[X]] x; + $x7[[X]] x; +} + +class X; +void bar(X *x) { + x$a1[[->]]f(); + x$a2[[->]]f(); + x$a3[[->]]f(); + x$a4[[->]]f(); + x$a5[[->]]f(); + x$a6[[->]]f(); + x$a7[[->]]f(); +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = + buildIndexWithSymbol(SymbolWithHeader{"X", "unittest:///a.h", "\"a.h\""}); + TU.ExternalIndex = Index.get(); + + auto Parsed = TU.build(); + for (const auto &D : Parsed.getDiagnostics()) { + EXPECT_EQ(D.Fixes.size(), 1u); + EXPECT_EQ(D.Fixes[0].Message, + std::string("Add include \"a.h\" for symbol X")); + } +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From b0546c2208f7a70dcad63d8cb3a43b2f316555dc Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 18 Feb 2019 14:23:19 +0000 Subject: [clangd] Add tests for template specializations Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58190 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354272 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/XRefsTests.cpp | 52 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index fea90137..3b9610cb 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -350,6 +350,58 @@ TEST(LocateSymbol, All) { FF(); void f() { T^est a; } )cpp", + + R"cpp(// explicit template specialization + template + struct Foo { void bar() {} }; + + template <> + struct [[Foo]] { void bar() {} }; + + void foo() { + Foo abc; + Fo^o b; + } + )cpp", + + R"cpp(// implicit template specialization + template + struct [[Foo]] { void bar() {} }; + template <> + struct Foo { void bar() {} }; + void foo() { + Fo^o abc; + Foo b; + } + )cpp", + + R"cpp(// partial template specialization + template + struct Foo { void bar() {} }; + template + struct [[Foo]] { void bar() {} }; + ^Foo x; + )cpp", + + R"cpp(// function template specializations + template + void foo(T) {} + template <> + void [[foo]](int) {} + void bar() { + fo^o(10); + } + )cpp", + + R"cpp(// variable template decls + template + T var = T(); + + template <> + double [[var]] = 10; + + double y = va^r; + )cpp", }; for (const char *Test : Tests) { Annotations T(Test); -- cgit v1.2.3 From 4b3c970d49899229a710241231092a6c261b8085 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Tue, 19 Feb 2019 14:32:22 +0000 Subject: [clangd] Handle unresolved scope specifier when fixing includes. Summary: In the following examples, "clangd" is unresolved, and the fixer will try to fix include for `clang::clangd`; however, clang::clangd::X is usually intended. So when handling a qualifier that is unresolved, we change the unresolved name and scopes so that the fixer will fix "clang::clangd::X" in the following example. ``` namespace clang { clangd::X ~~~~~~ } // or clang::clangd::X ~~~~~~ ``` Reviewers: sammccall Reviewed By: sammccall Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58185 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354330 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/IncludeFixer.cpp | 177 +++++++++++++++++++++++++++------- unittests/clangd/DiagnosticsTests.cpp | 90 ++++++++++++++++- 2 files changed, 226 insertions(+), 41 deletions(-) diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index 9b9b6e13..b04cf21a 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -19,6 +19,10 @@ #include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticSema.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TokenKinds.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Scope.h" @@ -28,6 +32,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/Error.h" #include "llvm/Support/FormatVariadic.h" @@ -172,6 +177,121 @@ std::vector IncludeFixer::fixesForSymbols(const SymbolSlab &Syms) const { } return Fixes; } + +// Returns the identifiers qualified by an unresolved name. \p Loc is the +// start location of the unresolved name. For the example below, this returns +// "::X::Y" that is qualified by unresolved name "clangd": +// clang::clangd::X::Y +// ~ +llvm::Optional qualifiedByUnresolved(const SourceManager &SM, + SourceLocation Loc, + const LangOptions &LangOpts) { + std::string Result; + + SourceLocation NextLoc = Loc; + while (auto CCTok = Lexer::findNextToken(NextLoc, SM, LangOpts)) { + if (!CCTok->is(tok::coloncolon)) + break; + auto IDTok = Lexer::findNextToken(CCTok->getLocation(), SM, LangOpts); + if (!IDTok || !IDTok->is(tok::raw_identifier)) + break; + Result.append(("::" + IDTok->getRawIdentifier()).str()); + NextLoc = IDTok->getLocation(); + } + if (Result.empty()) + return llvm::None; + return Result; +} + +// An unresolved name and its scope information that can be extracted cheaply. +struct CheapUnresolvedName { + std::string Name; + // This is the part of what was typed that was resolved, and it's in its + // resolved form not its typed form (think `namespace clang { clangd::x }` --> + // `clang::clangd::`). + llvm::Optional ResolvedScope; + + // Unresolved part of the scope. When the unresolved name is a specifier, we + // use the name that comes after it as the alternative name to resolve and use + // the specifier as the extra scope in the accessible scopes. + llvm::Optional UnresolvedScope; +}; + +// Extracts unresolved name and scope information around \p Unresolved. +// FIXME: try to merge this with the scope-wrangling code in CodeComplete. +llvm::Optional extractUnresolvedNameCheaply( + const SourceManager &SM, const DeclarationNameInfo &Unresolved, + CXXScopeSpec *SS, const LangOptions &LangOpts, bool UnresolvedIsSpecifier) { + bool Invalid = false; + llvm::StringRef Code = SM.getBufferData( + SM.getDecomposedLoc(Unresolved.getBeginLoc()).first, &Invalid); + if (Invalid) + return llvm::None; + CheapUnresolvedName Result; + Result.Name = Unresolved.getAsString(); + if (SS && SS->isNotEmpty()) { // "::" or "ns::" + if (auto *Nested = SS->getScopeRep()) { + if (Nested->getKind() == NestedNameSpecifier::Global) + Result.ResolvedScope = ""; + else if (const auto *NS = Nested->getAsNamespace()) { + auto SpecifiedNS = printNamespaceScope(*NS); + + // Check the specifier spelled in the source. + // If the resolved scope doesn't end with the spelled scope. The + // resolved scope can come from a sema typo correction. For example, + // sema assumes that "clangd::" is a typo of "clang::" and uses + // "clang::" as the specified scope in: + // namespace clang { clangd::X; } + // In this case, we use the "typo" specifier as extra scope instead + // of using the scope assumed by sema. + auto B = SM.getFileOffset(SS->getBeginLoc()); + auto E = SM.getFileOffset(SS->getEndLoc()); + std::string Spelling = (Code.substr(B, E - B) + "::").str(); + if (llvm::StringRef(SpecifiedNS).endswith(Spelling)) + Result.ResolvedScope = SpecifiedNS; + else + Result.UnresolvedScope = Spelling; + } else if (const auto *ANS = Nested->getAsNamespaceAlias()) { + Result.ResolvedScope = printNamespaceScope(*ANS->getNamespace()); + } else { + // We don't fix symbols in scopes that are not top-level e.g. class + // members, as we don't collect includes for them. + return llvm::None; + } + } + } + + if (UnresolvedIsSpecifier) { + // If the unresolved name is a specifier e.g. + // clang::clangd::X + // ~~~~~~ + // We try to resolve clang::clangd::X instead of clang::clangd. + // FIXME: We won't be able to fix include if the specifier is what we + // should resolve (e.g. it's a class scope specifier). Collecting include + // headers for nested types could make this work. + + // Not using the end location as it doesn't always point to the end of + // identifier. + if (auto QualifiedByUnresolved = + qualifiedByUnresolved(SM, Unresolved.getBeginLoc(), LangOpts)) { + auto Split = splitQualifiedName(*QualifiedByUnresolved); + if (!Result.UnresolvedScope) + Result.UnresolvedScope.emplace(); + // If UnresolvedSpecifiedScope is already set, we simply append the + // extra scope. Suppose the unresolved name is "index" in the following + // example: + // namespace clang { clangd::index::X; } + // ~~~~~~ ~~~~~ + // "clangd::" is assumed to be clang:: by Sema, and we would have used + // it as extra scope. With "index" being a specifier, we append "index::" + // to the extra scope. + Result.UnresolvedScope->append((Result.Name + Split.first).str()); + Result.Name = Split.second; + } + } + return Result; +} + class IncludeFixer::UnresolvedNameRecorder : public ExternalSemaSource { public: UnresolvedNameRecorder(llvm::Optional &LastUnresolvedName) @@ -192,51 +312,30 @@ public: if (!SemaPtr->SourceMgr.isWrittenInMainFile(Typo.getLoc())) return clang::TypoCorrection(); - // FIXME: support invalid scope before a type name. In the following - // example, namespace "clang::tidy::" hasn't been declared/imported. - // namespace clang { - // void f() { - // tidy::Check c; - // ~~~~ - // // or - // clang::tidy::Check c; - // ~~~~ - // } - // } - // For both cases, the typo and the diagnostic are both on "tidy", and no - // diagnostic is generated for "Check". However, what we want to fix is - // "clang::tidy::Check". - - // Extract the typed scope. This is not done lazily because `SS` can get - // out of scope and it's relatively cheap. - llvm::Optional SpecifiedScope; - if (SS && SS->isNotEmpty()) { // "::" or "ns::" - if (auto *Nested = SS->getScopeRep()) { - if (Nested->getKind() == NestedNameSpecifier::Global) - SpecifiedScope = ""; - else if (const auto *NS = Nested->getAsNamespace()) - SpecifiedScope = printNamespaceScope(*NS); - else - // We don't fix symbols in scopes that are not top-level e.g. class - // members, as we don't collect includes for them. - return TypoCorrection(); - } - } - if (!SpecifiedScope && !S) // Give up if no scope available. + // This is not done lazily because `SS` can get out of scope and it's + // relatively cheap. + auto Extracted = extractUnresolvedNameCheaply( + SemaPtr->SourceMgr, Typo, SS, SemaPtr->LangOpts, + static_cast(LookupKind) == + Sema::LookupNameKind::LookupNestedNameSpecifierName); + if (!Extracted) return TypoCorrection(); - + auto CheapUnresolved = std::move(*Extracted); UnresolvedName Unresolved; - Unresolved.Name = Typo.getAsString(); + Unresolved.Name = CheapUnresolved.Name; Unresolved.Loc = Typo.getBeginLoc(); + if (!CheapUnresolved.ResolvedScope && !S) // Give up if no scope available. + return TypoCorrection(); + auto *Sem = SemaPtr; // Avoid capturing `this`. - Unresolved.GetScopes = [Sem, SpecifiedScope, S, LookupKind]() { + Unresolved.GetScopes = [Sem, CheapUnresolved, S, LookupKind]() { std::vector Scopes; - if (SpecifiedScope) { - Scopes.push_back(*SpecifiedScope); + if (CheapUnresolved.ResolvedScope) { + Scopes.push_back(*CheapUnresolved.ResolvedScope); } else { assert(S); - // No scope qualifier is specified. Collect all accessible scopes in the + // No scope specifier is specified. Collect all accessible scopes in the // context. VisitedContextCollector Collector; Sem->LookupVisibleDecls( @@ -249,6 +348,10 @@ public: if (isa(Ctx)) Scopes.push_back(printNamespaceScope(*Ctx)); } + + if (CheapUnresolved.UnresolvedScope) + for (auto &Scope : Scopes) + Scope.append(*CheapUnresolved.UnresolvedScope); return Scopes; }; LastUnresolvedName = std::move(Unresolved); diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index d1108489..f6f6de39 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -20,6 +20,7 @@ namespace clang { namespace clangd { namespace { +using testing::_; using testing::ElementsAre; using testing::Field; using testing::IsEmpty; @@ -369,6 +370,8 @@ TEST(IncludeFixerTest, Typo) { $insert[[]]namespace ns { void foo() { $unqualified1[[X]] x; + // No fix if the unresolved type is used as specifier. (ns::)X::Nested will be + // considered the unresolved type. $unqualified2[[X]]::Nested n; } } @@ -391,10 +394,7 @@ void bar() { AllOf(Diag(Test.range("unqualified1"), "unknown type name 'X'"), WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", "Add include \"x.h\" for symbol ns::X"))), - AllOf(Diag(Test.range("unqualified2"), - "use of undeclared identifier 'X'"), - WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", - "Add include \"x.h\" for symbol ns::X"))), + Diag(Test.range("unqualified2"), "use of undeclared identifier 'X'"), AllOf(Diag(Test.range("qualified1"), "no type named 'X' in namespace 'ns'"), WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", @@ -487,6 +487,88 @@ void bar(X *x) { } } +TEST(IncludeFixerTest, UnresolvedNameAsSpecifier) { + Annotations Test(R"cpp( +$insert[[]]namespace ns { +} +void g() { ns::$[[scope]]::X_Y(); } + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = buildIndexWithSymbol( + SymbolWithHeader{"ns::scope::X_Y", "unittest:///x.h", "\"x.h\""}); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT( + TU.build().getDiagnostics(), + UnorderedElementsAre(AllOf( + Diag(Test.range(), "no member named 'scope' in namespace 'ns'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::scope::X_Y"))))); +} + +TEST(IncludeFixerTest, UnresolvedSpecifierWithSemaCorrection) { + Annotations Test(R"cpp( +$insert[[]]namespace clang { +void f() { + // "clangd::" will be corrected to "clang::" by Sema. + $q1[[clangd]]::$x[[X]] x; + $q2[[clangd]]::$ns[[ns]]::Y y; +} +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = buildIndexWithSymbol( + {SymbolWithHeader{"clang::clangd::X", "unittest:///x.h", "\"x.h\""}, + SymbolWithHeader{"clang::clangd::ns::Y", "unittest:///y.h", "\"y.h\""}}); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT( + TU.build().getDiagnostics(), + UnorderedElementsAre( + AllOf( + Diag(Test.range("q1"), "use of undeclared identifier 'clangd'; " + "did you mean 'clang'?"), + WithFix(_, // change clangd to clang + Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol clang::clangd::X"))), + AllOf( + Diag(Test.range("x"), "no type named 'X' in namespace 'clang'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol clang::clangd::X"))), + AllOf( + Diag(Test.range("q2"), "use of undeclared identifier 'clangd'; " + "did you mean 'clang'?"), + WithFix( + _, // change clangd to clangd + Fix(Test.range("insert"), "#include \"y.h\"\n", + "Add include \"y.h\" for symbol clang::clangd::ns::Y"))), + AllOf(Diag(Test.range("ns"), + "no member named 'ns' in namespace 'clang'"), + WithFix(Fix( + Test.range("insert"), "#include \"y.h\"\n", + "Add include \"y.h\" for symbol clang::clangd::ns::Y"))))); +} + +TEST(IncludeFixerTest, SpecifiedScopeIsNamespaceAlias) { + Annotations Test(R"cpp( +$insert[[]]namespace a {} +namespace b = a; +namespace c { + b::$[[X]] x; +} + )cpp"); + auto TU = TestTU::withCode(Test.code()); + auto Index = buildIndexWithSymbol( + SymbolWithHeader{"a::X", "unittest:///x.h", "\"x.h\""}); + TU.ExternalIndex = Index.get(); + + EXPECT_THAT(TU.build().getDiagnostics(), + UnorderedElementsAre(AllOf( + Diag(Test.range(), "no type named 'X' in namespace 'a'"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol a::X"))))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From 667d3d6560fd23ebd2c9715f36c15cf9ff1f55bb Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 19 Feb 2019 16:50:37 +0000 Subject: [clangd] Add an option in the code to not display number of fixes Summary: Only to the APIs, which are used by our embedders. We do not plan to add a user-facing option for this. Reviewers: sammccall, ioeric Reviewed By: sammccall Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58387 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354349 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Diagnostics.cpp | 6 +++--- clangd/Diagnostics.h | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index 83876217..186ab066 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -161,11 +161,11 @@ std::string capitalize(std::string Message) { /// /// dir1/dir2/dir3/../../dir4/header.h:12:23 /// note: candidate function not viable: requires 3 arguments -std::string mainMessage(const Diag &D) { +std::string mainMessage(const Diag &D, bool DisplayFixesCount) { std::string Result; llvm::raw_string_ostream OS(Result); OS << D.Message; - if (!D.Fixes.empty()) + if (DisplayFixesCount && !D.Fixes.empty()) OS << " (" << (D.Fixes.size() > 1 ? "fixes" : "fix") << " available)"; for (auto &Note : D.Notes) { OS << "\n\n"; @@ -252,7 +252,7 @@ void toLSPDiags( { clangd::Diagnostic Main = FillBasicFields(D); - Main.message = mainMessage(D); + Main.message = mainMessage(D, Opts.DisplayFixesCount); if (Opts.EmbedFixesInDiagnostics) { Main.codeActions.emplace(); for (const auto &Fix : D.Fixes) diff --git a/clangd/Diagnostics.h b/clangd/Diagnostics.h index 9130ad56..095590b9 100644 --- a/clangd/Diagnostics.h +++ b/clangd/Diagnostics.h @@ -32,6 +32,10 @@ struct ClangdDiagnosticOptions { /// stage during which the issue was produced, e.g. "Semantic Issue" or "Parse /// Issue". bool SendDiagnosticCategory = false; + + /// If true, Clangd will add a number of available fixes to the diagnostic's + /// message. + bool DisplayFixesCount = true; }; /// Contains basic information about a diagnostic. -- cgit v1.2.3 From a1270e738bd93c4b0582fb127312d311c3635d8d Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Wed, 20 Feb 2019 09:41:26 +0000 Subject: [clangd] Testcase for bug 39811 Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58133 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354442 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/XRefsTests.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index 3b9610cb..9857dab7 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -1441,6 +1441,35 @@ TEST(FindReferences, NoQueryForLocalSymbols) { } } +TEST(GoTo, WithSysRoot) { + const char *CustoomRoot = "/sys/root/"; + Annotations Main(R"cpp( + #include "header.h" + int main() { + return f^oo(); + })cpp"); + Annotations Header("int [[foo]](){return 42;}"); + + MockCompilationDatabase CDB; + CDB.ExtraClangFlags = {"--sysroot", CustoomRoot}; + IgnoreDiagnostics DiagConsumer; + MockFSProvider FS; + ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); + + // Fill the filesystem. + auto FooCpp = testPath("foo.cpp"); + FS.Files[FooCpp] = Main.code(); + auto HeaderPath = (llvm::StringRef(CustoomRoot) + "include/header.h").str(); + FS.Files[HeaderPath] = Header.code(); + + runAddDocument(Server, FooCpp, Main.code()); + + // Go to a definition in main source file. + auto Locations = runLocateSymbolAt(Server, FooCpp, Main.point()); + EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error"; + EXPECT_THAT(*Locations, ElementsAre(Sym("foo", Header.range()))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From 7af73dbb8b236e64e7ffd8402f41553927823b68 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Wed, 20 Feb 2019 10:32:04 +0000 Subject: [clangd] Try to fix windows build bots git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354444 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/XRefsTests.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index 9857dab7..3469644e 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -1442,7 +1442,11 @@ TEST(FindReferences, NoQueryForLocalSymbols) { } TEST(GoTo, WithSysRoot) { - const char *CustoomRoot = "/sys/root/"; +#ifdef _WIN32 + const char *CustomRoot = "C:\\sys\\root\\"; +#else + const char *CustomRoot = "/sys/root/"; +#endif Annotations Main(R"cpp( #include "header.h" int main() { @@ -1451,7 +1455,7 @@ TEST(GoTo, WithSysRoot) { Annotations Header("int [[foo]](){return 42;}"); MockCompilationDatabase CDB; - CDB.ExtraClangFlags = {"--sysroot", CustoomRoot}; + CDB.ExtraClangFlags = {"--sysroot", CustomRoot}; IgnoreDiagnostics DiagConsumer; MockFSProvider FS; ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); @@ -1459,7 +1463,8 @@ TEST(GoTo, WithSysRoot) { // Fill the filesystem. auto FooCpp = testPath("foo.cpp"); FS.Files[FooCpp] = Main.code(); - auto HeaderPath = (llvm::StringRef(CustoomRoot) + "include/header.h").str(); + llvm::SmallString<128> HeaderPath(CustomRoot); + llvm::sys::path::append(HeaderPath, "include", "header.h"); FS.Files[HeaderPath] = Header.code(); runAddDocument(Server, FooCpp, Main.code()); -- cgit v1.2.3 From b9ae67da6f2e1177965f42997ed7b53cf120b52c Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Wed, 20 Feb 2019 11:45:20 +0000 Subject: [clangd] Revert r354442 and r354444 Looks like sysroot is only working on linux. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354453 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/XRefsTests.cpp | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index 3469644e..3b9610cb 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -1441,40 +1441,6 @@ TEST(FindReferences, NoQueryForLocalSymbols) { } } -TEST(GoTo, WithSysRoot) { -#ifdef _WIN32 - const char *CustomRoot = "C:\\sys\\root\\"; -#else - const char *CustomRoot = "/sys/root/"; -#endif - Annotations Main(R"cpp( - #include "header.h" - int main() { - return f^oo(); - })cpp"); - Annotations Header("int [[foo]](){return 42;}"); - - MockCompilationDatabase CDB; - CDB.ExtraClangFlags = {"--sysroot", CustomRoot}; - IgnoreDiagnostics DiagConsumer; - MockFSProvider FS; - ClangdServer Server(CDB, FS, DiagConsumer, ClangdServer::optsForTest()); - - // Fill the filesystem. - auto FooCpp = testPath("foo.cpp"); - FS.Files[FooCpp] = Main.code(); - llvm::SmallString<128> HeaderPath(CustomRoot); - llvm::sys::path::append(HeaderPath, "include", "header.h"); - FS.Files[HeaderPath] = Header.code(); - - runAddDocument(Server, FooCpp, Main.code()); - - // Go to a definition in main source file. - auto Locations = runLocateSymbolAt(Server, FooCpp, Main.point()); - EXPECT_TRUE(bool(Locations)) << "findDefinitions returned an error"; - EXPECT_THAT(*Locations, ElementsAre(Sym("foo", Header.range()))); -} - } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From e55342cba09fd4061674bdbcdef85ea37406453b Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 20 Feb 2019 12:31:44 +0000 Subject: [clangd] Fix a typo. NFC The documentation for -index-file mentioned clang-index instead of clangd-indexer. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354456 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/ClangdMain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index 9495869b..2e2fcbd1 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -163,7 +163,7 @@ static llvm::cl::opt IndexFile( "index-file", llvm::cl::desc( "Index file to build the static index. The file must have been created " - "by a compatible clangd-index.\n" + "by a compatible clangd-indexer.\n" "WARNING: This option is experimental only, and will be removed " "eventually. Don't rely on it."), llvm::cl::init(""), llvm::cl::Hidden); -- cgit v1.2.3 From 8d6529f533e555238551c08641d53e772ee4c52b Mon Sep 17 00:00:00 2001 From: Yan Zhang Date: Wed, 20 Feb 2019 17:32:41 +0000 Subject: Update property prefix regex to allow numbers. Subscribers: jfb, cfe-commits Differential Revision: https://reviews.llvm.org/D56896 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354485 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/objc/PropertyDeclarationCheck.cpp | 19 +++++++++---------- test/clang-tidy/objc-property-declaration.m | 1 + 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/clang-tidy/objc/PropertyDeclarationCheck.cpp b/clang-tidy/objc/PropertyDeclarationCheck.cpp index eba702be..094c193c 100644 --- a/clang-tidy/objc/PropertyDeclarationCheck.cpp +++ b/clang-tidy/objc/PropertyDeclarationCheck.cpp @@ -80,7 +80,8 @@ std::string validPropertyNameRegex(bool UsedInMatcher) { } bool hasCategoryPropertyPrefix(llvm::StringRef PropertyName) { - auto RegexExp = llvm::Regex("^[a-zA-Z]+_[a-zA-Z0-9][a-zA-Z0-9_]+$"); + auto RegexExp = + llvm::Regex("^[a-zA-Z][a-zA-Z0-9]*_[a-zA-Z0-9][a-zA-Z0-9_]+$"); return RegexExp.match(PropertyName); } @@ -91,8 +92,7 @@ bool prefixedPropertyNameValid(llvm::StringRef PropertyName) { if (Prefix.lower() != Prefix) { return false; } - auto RegexExp = - llvm::Regex(llvm::StringRef(validPropertyNameRegex(false))); + auto RegexExp = llvm::Regex(llvm::StringRef(validPropertyNameRegex(false))); return RegexExp.match(PropertyName.substr(Start + 1)); } } // namespace @@ -101,13 +101,12 @@ void PropertyDeclarationCheck::registerMatchers(MatchFinder *Finder) { // this check should only be applied to ObjC sources. if (!getLangOpts().ObjC) return; - Finder->addMatcher( - objcPropertyDecl( - // the property name should be in Lower Camel Case like - // 'lowerCamelCase' - unless(matchesName(validPropertyNameRegex(true)))) - .bind("property"), - this); + Finder->addMatcher(objcPropertyDecl( + // the property name should be in Lower Camel Case like + // 'lowerCamelCase' + unless(matchesName(validPropertyNameRegex(true)))) + .bind("property"), + this); } void PropertyDeclarationCheck::check(const MatchFinder::MatchResult &Result) { diff --git a/test/clang-tidy/objc-property-declaration.m b/test/clang-tidy/objc-property-declaration.m index 07a06205..b56bdcd1 100644 --- a/test/clang-tidy/objc-property-declaration.m +++ b/test/clang-tidy/objc-property-declaration.m @@ -46,6 +46,7 @@ typedef void *CGColorRef; @property(strong, nonatomic) NSString *URLStr; @property(assign, nonatomic) int abc_camelCase; @property(strong, nonatomic) NSString *abc_URL; +@property(strong, nonatomic) NSString *opac2_sourceComponent; @end @interface Foo () -- cgit v1.2.3 From a225d040ba1ab533b5c031ca34c8c7da2b806b4c Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 20 Feb 2019 19:08:06 +0000 Subject: [clangd] Store index in '.clangd/index' instead of '.clangd-index' Summary: To take up the .clangd folder for other potential uses in the future. Reviewers: kadircet, sammccall Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58440 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354505 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Background.h | 2 +- clangd/index/BackgroundIndexStorage.cpp | 8 ++++---- test/clangd/background-index.test | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/clangd/index/Background.h b/clangd/index/Background.h index 808c03a3..48743530 100644 --- a/clangd/index/Background.h +++ b/clangd/index/Background.h @@ -54,7 +54,7 @@ public: llvm::unique_function; // Creates an Index Storage that saves shards into disk. Index storage uses - // CDBDirectory + ".clangd-index/" as the folder to save shards. + // CDBDirectory + ".clangd/index/" as the folder to save shards. static Factory createDiskBackedStorageFactory(); }; diff --git a/clangd/index/BackgroundIndexStorage.cpp b/clangd/index/BackgroundIndexStorage.cpp index 266b18ce..85941264 100644 --- a/clangd/index/BackgroundIndexStorage.cpp +++ b/clangd/index/BackgroundIndexStorage.cpp @@ -63,19 +63,19 @@ writeAtomically(llvm::StringRef OutPath, } // Uses disk as a storage for index shards. Creates a directory called -// ".clangd-index/" under the path provided during construction. +// ".clangd/index/" under the path provided during construction. class DiskBackedIndexStorage : public BackgroundIndexStorage { std::string DiskShardRoot; public: - // Sets DiskShardRoot to (Directory + ".clangd-index/") which is the base + // Sets DiskShardRoot to (Directory + ".clangd/index/") which is the base // directory for all shard files. DiskBackedIndexStorage(llvm::StringRef Directory) { llvm::SmallString<128> CDBDirectory(Directory); - llvm::sys::path::append(CDBDirectory, ".clangd-index/"); + llvm::sys::path::append(CDBDirectory, ".clangd", "index"); DiskShardRoot = CDBDirectory.str(); std::error_code OK; - std::error_code EC = llvm::sys::fs::create_directory(DiskShardRoot); + std::error_code EC = llvm::sys::fs::create_directories(DiskShardRoot); if (EC != OK) { elog("Failed to create directory {0} for index storage: {1}", DiskShardRoot, EC.message()); diff --git a/test/clangd/background-index.test b/test/clangd/background-index.test index 34c419ac..1d11736d 100644 --- a/test/clangd/background-index.test +++ b/test/clangd/background-index.test @@ -13,7 +13,7 @@ # RUN: clangd -background-index -background-index-rebuild-period=0 -lit-test < %t/definition.jsonrpc | FileCheck %t/definition.jsonrpc # Test that the index is writing files in the expected location. -# RUN: ls %t/.clangd-index/foo.cpp.*.idx +# RUN: ls %t/.clangd/index/foo.cpp.*.idx # Test the index is read from disk: delete code and restart clangd. # RUN: rm %t/foo.cpp -- cgit v1.2.3 From fae848526cdda3c07318f881b6f88056071012e9 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 20 Feb 2019 19:26:39 +0000 Subject: [clangd] Fix a crash in Selection Summary: The assertion checking that a range of a node is a token range does not hold in case of "split" tokens, e.g. between two closing template argument lists (`vector>`). Reviewers: kadircet, sammccall Reviewed By: kadircet Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58447 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354507 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Selection.cpp | 3 +-- unittests/clangd/SelectionTests.cpp | 5 +++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/clangd/Selection.cpp b/clangd/Selection.cpp index d1ea30e7..233a4369 100644 --- a/clangd/Selection.cpp +++ b/clangd/Selection.cpp @@ -198,11 +198,10 @@ private: auto E = SM.getDecomposedLoc(R.getEnd()); if (B.first != SelFile || E.first != SelFile) continue; - assert(R.isTokenRange()); // Try to cover up to the next token, spaces between children don't count. if (auto Tok = Lexer::findNextToken(R.getEnd(), SM, LangOpts)) E.second = SM.getFileOffset(Tok->getLocation()); - else + else if (R.isTokenRange()) E.second += Lexer::MeasureTokenLength(R.getEnd(), SM, LangOpts); ChildRanges.push_back({B.second, E.second}); } diff --git a/unittests/clangd/SelectionTests.cpp b/unittests/clangd/SelectionTests.cpp index 2322a0e6..2d962712 100644 --- a/unittests/clangd/SelectionTests.cpp +++ b/unittests/clangd/SelectionTests.cpp @@ -232,6 +232,11 @@ TEST(SelectionTest, Selected) { }]]]] } )cpp", + R"cpp( + template + struct unique_ptr {}; + void foo(^$C[[unique_ptr>]]^ a) {} + )cpp", }; for (const char *C : Cases) { Annotations Test(C); -- cgit v1.2.3 From a0bcbdb5c50e1909efd6acc916fd8cd4b3ff4c41 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Wed, 20 Feb 2019 21:04:36 +0000 Subject: [clang-tidy] refactor ExceptionAnalyzer further to give ternary answer Summary: The analsis on the throwing behvaiour on functions and statements gave only a binary answer whether an exception could occur and if yes which types are thrown. This refactoring allows keeping track if there is a unknown factor, because the code calls to some functions with unavailable source code with no `noexcept` information. This 'potential Unknown' information is propagated properly and can be queried separately. Reviewers: lebedev.ri, aaron.ballman, baloghadamsoftware, alexfh Reviewed By: lebedev.ri, baloghadamsoftware Subscribers: xazax.hun, rnkovacs, a.sidorin, Szelethus, donat.nagy, dkrupp, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D57883 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354517 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/ExceptionEscapeCheck.cpp | 4 +- clang-tidy/utils/ExceptionAnalyzer.cpp | 223 ++++++++++++++++++--------- clang-tidy/utils/ExceptionAnalyzer.h | 127 +++++++++++++-- 3 files changed, 271 insertions(+), 83 deletions(-) diff --git a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp index 0849e2e7..951c6f1e 100644 --- a/clang-tidy/bugprone/ExceptionEscapeCheck.cpp +++ b/clang-tidy/bugprone/ExceptionEscapeCheck.cpp @@ -42,6 +42,7 @@ ExceptionEscapeCheck::ExceptionEscapeCheck(StringRef Name, IgnoredExceptions.insert(IgnoredExceptionsVec.begin(), IgnoredExceptionsVec.end()); Tracer.ignoreExceptions(std::move(IgnoredExceptions)); + Tracer.ignoreBadAlloc(true); } void ExceptionEscapeCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { @@ -70,7 +71,8 @@ void ExceptionEscapeCheck::check(const MatchFinder::MatchResult &Result) { if (!MatchedDecl) return; - if (Tracer.throwsException(MatchedDecl)) + if (Tracer.analyze(MatchedDecl).getBehaviour() == + utils::ExceptionAnalyzer::State::Throwing) // FIXME: We should provide more information about the exact location where // the exception is thrown, maybe the full path the exception escapes diag(MatchedDecl->getLocation(), diff --git a/clang-tidy/utils/ExceptionAnalyzer.cpp b/clang-tidy/utils/ExceptionAnalyzer.cpp index 7f1ca529..9614cebd 100644 --- a/clang-tidy/utils/ExceptionAnalyzer.cpp +++ b/clang-tidy/utils/ExceptionAnalyzer.cpp @@ -8,10 +8,44 @@ #include "ExceptionAnalyzer.h" -#include "clang/AST/ASTContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" - namespace clang { +namespace tidy { +namespace utils { + +void ExceptionAnalyzer::ExceptionInfo::registerException( + const Type *ExceptionType) { + assert(ExceptionType != nullptr && "Only valid types are accepted"); + Behaviour = State::Throwing; + ThrownExceptions.insert(ExceptionType); +} + +void ExceptionAnalyzer::ExceptionInfo::registerExceptions( + const Throwables &Exceptions) { + if (Exceptions.size() == 0) + return; + Behaviour = State::Throwing; + ThrownExceptions.insert(Exceptions.begin(), Exceptions.end()); +} + +ExceptionAnalyzer::ExceptionInfo &ExceptionAnalyzer::ExceptionInfo::merge( + const ExceptionAnalyzer::ExceptionInfo &Other) { + // Only the following two cases require an update to the local + // 'Behaviour'. If the local entity is already throwing there will be no + // change and if the other entity is throwing the merged entity will throw + // as well. + // If one of both entities is 'Unknown' and the other one does not throw + // the merged entity is 'Unknown' as well. + if (Other.Behaviour == State::Throwing) + Behaviour = State::Throwing; + else if (Other.Behaviour == State::Unknown && Behaviour == State::NotThrowing) + Behaviour = State::Unknown; + + ContainsUnknown = ContainsUnknown || Other.ContainsUnknown; + ThrownExceptions.insert(Other.ThrownExceptions.begin(), + Other.ThrownExceptions.end()); + return *this; +} + static bool isBaseOf(const Type *DerivedType, const Type *BaseType) { const auto *DerivedClass = DerivedType->getAsCXXRecordDecl(); const auto *BaseClass = BaseType->getAsCXXRecordDecl(); @@ -22,36 +56,87 @@ static bool isBaseOf(const Type *DerivedType, const Type *BaseType) { [BaseClass](const CXXRecordDecl *Cur) { return Cur != BaseClass; }); } -namespace tidy { -namespace utils { +bool ExceptionAnalyzer::ExceptionInfo::filterByCatch(const Type *BaseClass) { + llvm::SmallVector TypesToDelete; + for (const Type *T : ThrownExceptions) { + if (T == BaseClass || isBaseOf(T, BaseClass)) + TypesToDelete.push_back(T); + } + + for (const Type *T : TypesToDelete) + ThrownExceptions.erase(T); + + reevaluateBehaviour(); + return TypesToDelete.size() > 0; +} + +ExceptionAnalyzer::ExceptionInfo & +ExceptionAnalyzer::ExceptionInfo::filterIgnoredExceptions( + const llvm::StringSet<> &IgnoredTypes, bool IgnoreBadAlloc) { + llvm::SmallVector TypesToDelete; + // Note: Using a 'SmallSet' with 'llvm::remove_if()' is not possible. + // Therefore this slightly hacky implementation is required. + for (const Type *T : ThrownExceptions) { + if (const auto *TD = T->getAsTagDecl()) { + if (TD->getDeclName().isIdentifier()) { + if ((IgnoreBadAlloc && + (TD->getName() == "bad_alloc" && TD->isInStdNamespace())) || + (IgnoredTypes.count(TD->getName()) > 0)) + TypesToDelete.push_back(T); + } + } + } + for (const Type *T : TypesToDelete) + ThrownExceptions.erase(T); -ExceptionAnalyzer::TypeVec ExceptionAnalyzer::throwsException( + reevaluateBehaviour(); + return *this; +} + +void ExceptionAnalyzer::ExceptionInfo::clear() { + Behaviour = State::NotThrowing; + ContainsUnknown = false; + ThrownExceptions.clear(); +} + +void ExceptionAnalyzer::ExceptionInfo::reevaluateBehaviour() { + if (ThrownExceptions.size() == 0) + if (ContainsUnknown) + Behaviour = State::Unknown; + else + Behaviour = State::NotThrowing; + else + Behaviour = State::Throwing; +} + +ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException( const FunctionDecl *Func, llvm::SmallSet &CallStack) { if (CallStack.count(Func)) - return TypeVec(); + return ExceptionInfo::createNonThrowing(); if (const Stmt *Body = Func->getBody()) { CallStack.insert(Func); - const TypeVec Result = throwsException(Body, TypeVec(), CallStack); + ExceptionInfo Result = + throwsException(Body, ExceptionInfo::Throwables(), CallStack); CallStack.erase(Func); return Result; } - TypeVec Result; + auto Result = ExceptionInfo::createUnknown(); if (const auto *FPT = Func->getType()->getAs()) { - for (const QualType Ex : FPT->exceptions()) { - Result.push_back(Ex.getTypePtr()); - } + for (const QualType Ex : FPT->exceptions()) + Result.registerException(Ex.getTypePtr()); } return Result; } -ExceptionAnalyzer::TypeVec ExceptionAnalyzer::throwsException( - const Stmt *St, const TypeVec &Caught, +/// Analyzes a single statment on it's throwing behaviour. This is in principle +/// possible except some 'Unknown' functions are called. +ExceptionAnalyzer::ExceptionInfo ExceptionAnalyzer::throwsException( + const Stmt *St, const ExceptionInfo::Throwables &Caught, llvm::SmallSet &CallStack) { - TypeVec Results; - + auto Results = ExceptionInfo::createNonThrowing(); if (!St) return Results; @@ -59,28 +144,28 @@ ExceptionAnalyzer::TypeVec ExceptionAnalyzer::throwsException( if (const auto *ThrownExpr = Throw->getSubExpr()) { const auto *ThrownType = ThrownExpr->getType()->getUnqualifiedDesugaredType(); - if (ThrownType->isReferenceType()) { + if (ThrownType->isReferenceType()) ThrownType = ThrownType->castAs() ->getPointeeType() ->getUnqualifiedDesugaredType(); - } - if (const auto *TD = ThrownType->getAsTagDecl()) { - if (TD->getDeclName().isIdentifier() && TD->getName() == "bad_alloc" && - TD->isInStdNamespace()) - return Results; - } - Results.push_back(ThrownExpr->getType()->getUnqualifiedDesugaredType()); - } else { - Results.append(Caught.begin(), Caught.end()); - } + Results.registerException( + ThrownExpr->getType()->getUnqualifiedDesugaredType()); + } else + // A rethrow of a caught exception happens which makes it possible + // to throw all exception that are caught in the 'catch' clause of + // the parent try-catch block. + Results.registerExceptions(Caught); } else if (const auto *Try = dyn_cast(St)) { - TypeVec Uncaught = throwsException(Try->getTryBlock(), Caught, CallStack); + ExceptionInfo Uncaught = + throwsException(Try->getTryBlock(), Caught, CallStack); for (unsigned i = 0; i < Try->getNumHandlers(); ++i) { const CXXCatchStmt *Catch = Try->getHandler(i); + + // Everything is catched through 'catch(...)'. if (!Catch->getExceptionDecl()) { - const TypeVec Rethrown = - throwsException(Catch->getHandlerBlock(), Uncaught, CallStack); - Results.append(Rethrown.begin(), Rethrown.end()); + ExceptionInfo Rethrown = throwsException( + Catch->getHandlerBlock(), Uncaught.getExceptionTypes(), CallStack); + Results.merge(Rethrown); Uncaught.clear(); } else { const auto *CaughtType = @@ -90,64 +175,62 @@ ExceptionAnalyzer::TypeVec ExceptionAnalyzer::throwsException( ->getPointeeType() ->getUnqualifiedDesugaredType(); } - auto NewEnd = - llvm::remove_if(Uncaught, [&CaughtType](const Type *ThrownType) { - return ThrownType == CaughtType || - isBaseOf(ThrownType, CaughtType); - }); - if (NewEnd != Uncaught.end()) { - Uncaught.erase(NewEnd, Uncaught.end()); - const TypeVec Rethrown = throwsException( - Catch->getHandlerBlock(), TypeVec(1, CaughtType), CallStack); - Results.append(Rethrown.begin(), Rethrown.end()); + + // If the caught exception will catch multiple previously potential + // thrown types (because it's sensitive to inheritance) the throwing + // situation changes. First of all filter the exception types and + // analyze if the baseclass-exception is rethrown. + if (Uncaught.filterByCatch(CaughtType)) { + ExceptionInfo::Throwables CaughtExceptions; + CaughtExceptions.insert(CaughtType); + ExceptionInfo Rethrown = throwsException(Catch->getHandlerBlock(), + CaughtExceptions, CallStack); + Results.merge(Rethrown); } } } - Results.append(Uncaught.begin(), Uncaught.end()); + Results.merge(Uncaught); } else if (const auto *Call = dyn_cast(St)) { if (const FunctionDecl *Func = Call->getDirectCallee()) { - TypeVec Excs = throwsException(Func, CallStack); - Results.append(Excs.begin(), Excs.end()); + ExceptionInfo Excs = throwsException(Func, CallStack); + Results.merge(Excs); } } else { for (const Stmt *Child : St->children()) { - TypeVec Excs = throwsException(Child, Caught, CallStack); - Results.append(Excs.begin(), Excs.end()); + ExceptionInfo Excs = throwsException(Child, Caught, CallStack); + Results.merge(Excs); } } return Results; } -bool ExceptionAnalyzer::throwsException(const FunctionDecl *Func) { - // Check if the function has already been analyzed and reuse that result. - if (FunctionCache.count(Func) > 0) - return FunctionCache[Func]; +ExceptionAnalyzer::ExceptionInfo +ExceptionAnalyzer::analyze(const FunctionDecl *Func) { + ExceptionInfo ExceptionList; - llvm::SmallSet CallStack; - TypeVec ExceptionList = throwsException(Func, CallStack); + // Check if the function has already been analyzed and reuse that result. + if (FunctionCache.count(Func) == 0) { + llvm::SmallSet CallStack; + ExceptionList = throwsException(Func, CallStack); + + // Cache the result of the analysis. This is done prior to filtering + // because it is best to keep as much information as possible. + // The results here might be relevant to different analysis passes + // with different needs as well. + FunctionCache.insert(std::make_pair(Func, ExceptionList)); + } else + ExceptionList = FunctionCache[Func]; + + if (ExceptionList.getBehaviour() == State::NotThrowing || + ExceptionList.getBehaviour() == State::Unknown) + return ExceptionList; // Remove all ignored exceptions from the list of exceptions that can be // thrown. - auto NewEnd = llvm::remove_if(ExceptionList, [this](const Type *Exception) { - return isIgnoredExceptionType(Exception); - }); - ExceptionList.erase(NewEnd, ExceptionList.end()); + ExceptionList.filterIgnoredExceptions(IgnoredExceptions, IgnoreBadAlloc); - // Cache the result of the analysis. - bool FunctionThrows = ExceptionList.size() > 0; - FunctionCache.insert(std::make_pair(Func, FunctionThrows)); - - return FunctionThrows; + return ExceptionList; } - -bool ExceptionAnalyzer::isIgnoredExceptionType(const Type *Exception) { - if (const auto *TD = Exception->getAsTagDecl()) { - if (TD->getDeclName().isIdentifier()) - return IgnoredExceptions.count(TD->getName()) > 0; - } - return false; -} - } // namespace utils } // namespace tidy diff --git a/clang-tidy/utils/ExceptionAnalyzer.h b/clang-tidy/utils/ExceptionAnalyzer.h index 327da300..53a6aebd 100644 --- a/clang-tidy/utils/ExceptionAnalyzer.h +++ b/clang-tidy/utils/ExceptionAnalyzer.h @@ -10,6 +10,7 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_UTILS_EXCEPTION_ANALYZER_H #include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringSet.h" @@ -17,29 +18,131 @@ namespace clang { namespace tidy { namespace utils { -/// This class analysis if a `FunctionDecl` can in principle throw an exception, -/// either directly or indirectly. -/// It can be configured to ignore custom exception types. +/// This class analysis if a `FunctionDecl` can in principle throw an +/// exception, either directly or indirectly. It can be configured to ignore +/// custom exception types. class ExceptionAnalyzer { public: + enum class State : std::int8_t { + Throwing = 0, ///< The function can definitly throw given an AST. + NotThrowing = 1, ///< This function can not throw, given an AST. + Unknown = 2, ///< This can happen for extern functions without available + ///< definition. + }; + + /// Bundle the gathered information about an entity like a function regarding + /// it's exception behaviour. The 'NonThrowing'-state can be considered as the + /// neutral element in terms of information propagation. + /// In the case of 'Throwing' state it is possible that 'getExceptionTypes' + /// does not include *ALL* possible types as there is the possibility that + /// an 'Unknown' function is called that might throw a previously unknown + /// exception at runtime. + class ExceptionInfo { + public: + using Throwables = llvm::SmallSet; + static ExceptionInfo createUnknown() { + return ExceptionInfo(State::Unknown); + } + static ExceptionInfo createNonThrowing() { + return ExceptionInfo(State::Throwing); + } + + /// By default the exception situation is unknown and must be + /// clarified step-wise. + ExceptionInfo() : Behaviour(State::NotThrowing), ContainsUnknown(false) {} + ExceptionInfo(State S) + : Behaviour(S), ContainsUnknown(S == State::Unknown) {} + + ExceptionInfo(const ExceptionInfo &) = default; + ExceptionInfo &operator=(const ExceptionInfo &) = default; + ExceptionInfo(ExceptionInfo &&) = default; + ExceptionInfo &operator=(ExceptionInfo &&) = default; + + State getBehaviour() const { return Behaviour; } + + /// Register a single exception type as recognized potential exception to be + /// thrown. + void registerException(const Type *ExceptionType); + + /// Registers a `SmallVector` of exception types as recognized potential + /// exceptions to be thrown. + void registerExceptions(const Throwables &Exceptions); + + /// Updates the local state according to the other state. That means if + /// for example a function contains multiple statements the 'ExceptionInfo' + /// for the final function is the merged result of each statement. + /// If one of these statements throws the whole function throws and if one + /// part is unknown and the rest is non-throwing the result will be + /// unknown. + ExceptionInfo &merge(const ExceptionInfo &Other); + + /// This method is useful in case 'catch' clauses are analyzed as it is + /// possible to catch multiple exception types by one 'catch' if they + /// are a subclass of the 'catch'ed exception type. + /// Returns 'true' if some exceptions were filtered, otherwise 'false'. + bool filterByCatch(const Type *BaseClass); + + /// Filter the set of thrown exception type against a set of ignored + /// types that shall not be considered in the exception analysis. + /// This includes explicit `std::bad_alloc` ignoring as separate option. + ExceptionInfo & + filterIgnoredExceptions(const llvm::StringSet<> &IgnoredTypes, + bool IgnoreBadAlloc); + + /// Clear the state to 'NonThrowing' to make the corresponding entity + /// neutral. + void clear(); + + /// References the set of known exception types that can escape from the + /// corresponding entity. + const Throwables &getExceptionTypes() const { return ThrownExceptions; } + + /// Signal if the there is any 'Unknown' element within the scope of + /// the related entity. This might be relevant if the entity is 'Throwing' + /// and to ensure that no other exception then 'getExceptionTypes' can + /// occur. If there is an 'Unknown' element this can not be guaranteed. + bool containsUnknownElements() const { return ContainsUnknown; } + + private: + /// Recalculate the 'Behaviour' for example after filtering. + void reevaluateBehaviour(); + + /// Keep track if the entity related to this 'ExceptionInfo' can in princple + /// throw, if it's unknown or if it won't throw. + enum State Behaviour : 2; + + /// Keep track if the entity contains any unknown elements to keep track + /// of the certainty of decisions and/or correct 'Behaviour' transition + /// after filtering. + bool ContainsUnknown : 1; + + /// 'ThrownException' is empty if the 'Behaviour' is either 'NotThrowing' or + /// 'Unknown'. + Throwables ThrownExceptions; + }; + static_assert(sizeof(ExceptionInfo) <= 64u, + "size of exceptioninfo shall be at max one cache line"); + ExceptionAnalyzer() = default; - bool throwsException(const FunctionDecl *Func); + void ignoreBadAlloc(bool ShallIgnore) { IgnoreBadAlloc = ShallIgnore; } void ignoreExceptions(llvm::StringSet<> ExceptionNames) { IgnoredExceptions = std::move(ExceptionNames); } -private: - using TypeVec = llvm::SmallVector; + ExceptionInfo analyze(const FunctionDecl *Func); - TypeVec throwsException(const FunctionDecl *Func, - llvm::SmallSet &CallStack); - TypeVec throwsException(const Stmt *St, const TypeVec &Caught, - llvm::SmallSet &CallStack); - bool isIgnoredExceptionType(const Type *Exception); +private: + ExceptionInfo + throwsException(const FunctionDecl *Func, + llvm::SmallSet &CallStack); + ExceptionInfo + throwsException(const Stmt *St, const ExceptionInfo::Throwables &Caught, + llvm::SmallSet &CallStack); + bool IgnoreBadAlloc = true; llvm::StringSet<> IgnoredExceptions; - llvm::DenseMap FunctionCache; + std::map FunctionCache; }; } // namespace utils } // namespace tidy -- cgit v1.2.3 From 825b9e04e3e40e17851da1b59b0b9b435876cf34 Mon Sep 17 00:00:00 2001 From: Stephane Moore Date: Thu, 21 Feb 2019 00:34:01 +0000 Subject: =?UTF-8?q?[clang-tidy]=20Make=20google-objc-function-naming=20ign?= =?UTF-8?q?ore=20implicit=20functions=20=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: Implicit functions are outside the control of source authors and should be exempt from style restrictions. Tested via running clang tools tests. This is an amended followup to https://reviews.llvm.org/D57207 Reviewers: aaron.ballman Reviewed By: aaron.ballman Subscribers: jdoerfert, xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58095 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354534 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/google/FunctionNamingCheck.cpp | 10 +++++++--- test/clang-tidy/Inputs/Headers/stdio.h | 18 ++++++++++++++++++ test/clang-tidy/google-objc-function-naming.m | 10 +++++++++- 3 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 test/clang-tidy/Inputs/Headers/stdio.h diff --git a/clang-tidy/google/FunctionNamingCheck.cpp b/clang-tidy/google/FunctionNamingCheck.cpp index 3eeb6fa6..8096d65d 100644 --- a/clang-tidy/google/FunctionNamingCheck.cpp +++ b/clang-tidy/google/FunctionNamingCheck.cpp @@ -93,12 +93,16 @@ void FunctionNamingCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().ObjC) return; - // Match function declarations that are not in system headers and are not - // main. + // Enforce Objective-C function naming conventions on all functions except: + // • Functions defined in system headers. + // • C++ member functions. + // • Namespaced functions. + // • Implicitly defined functions. + // • The main function. Finder->addMatcher( functionDecl( unless(anyOf(isExpansionInSystemHeader(), cxxMethodDecl(), - hasAncestor(namespaceDecl()), isMain(), + hasAncestor(namespaceDecl()), isMain(), isImplicit(), matchesName(validFunctionNameRegex(true)), allOf(isStaticStorageClass(), matchesName(validFunctionNameRegex(false)))))) diff --git a/test/clang-tidy/Inputs/Headers/stdio.h b/test/clang-tidy/Inputs/Headers/stdio.h new file mode 100644 index 00000000..eebe9fd9 --- /dev/null +++ b/test/clang-tidy/Inputs/Headers/stdio.h @@ -0,0 +1,18 @@ +//===--- stdio.h - Stub header for tests ------------------------*- 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 _STDIO_H_ +#define _STDIO_H_ + +// A header intended to contain C standard input and output library +// declarations. + +int printf(const char *, ...); + +#endif // _STDIO_H_ + diff --git a/test/clang-tidy/google-objc-function-naming.m b/test/clang-tidy/google-objc-function-naming.m index d0336d26..01433d9f 100644 --- a/test/clang-tidy/google-objc-function-naming.m +++ b/test/clang-tidy/google-objc-function-naming.m @@ -1,4 +1,12 @@ -// RUN: %check_clang_tidy %s google-objc-function-naming %t +// RUN: %check_clang_tidy %s google-objc-function-naming %t -- -- -isystem %S/Inputs/Headers + +#include + +static void TestImplicitFunctionDeclaration(int a) { + // Call a builtin function so that the compiler generates an implicit + // function declaration. + printf("%d", a); +} typedef _Bool bool; -- cgit v1.2.3 From dd72064bd0fa476220c53ef0d6d70623d6b64ae8 Mon Sep 17 00:00:00 2001 From: Douglas Yung Date: Thu, 21 Feb 2019 04:55:31 +0000 Subject: Attempt to fix VS2015 build breakage from r354517. NFCI. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354545 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/utils/ExceptionAnalyzer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang-tidy/utils/ExceptionAnalyzer.h b/clang-tidy/utils/ExceptionAnalyzer.h index 53a6aebd..ac196976 100644 --- a/clang-tidy/utils/ExceptionAnalyzer.h +++ b/clang-tidy/utils/ExceptionAnalyzer.h @@ -109,7 +109,7 @@ public: /// Keep track if the entity related to this 'ExceptionInfo' can in princple /// throw, if it's unknown or if it won't throw. - enum State Behaviour : 2; + State Behaviour : 2; /// Keep track if the entity contains any unknown elements to keep track /// of the certainty of decisions and/or correct 'Behaviour' transition -- cgit v1.2.3 From dd4c2717f1dc2e9b42fa4c08caf258ff706e37ea Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Thu, 21 Feb 2019 09:33:49 +0000 Subject: [clangd] Handle another incomplete-type diagnostic case in IncludeFixer. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354558 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/IncludeFixer.cpp | 1 + unittests/clangd/DiagnosticsTests.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index b04cf21a..a90a8467 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -67,6 +67,7 @@ std::vector IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel, case diag::err_incomplete_type: case diag::err_incomplete_member_access: case diag::err_incomplete_base_class: + case diag::err_incomplete_nested_name_spec: // Incomplete type diagnostics should have a QualType argument for the // incomplete type. for (unsigned Idx = 0; Idx < Info.getNumArgs(); ++Idx) { diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index f6f6de39..bbd94b80 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -311,6 +311,7 @@ TEST(IncludeFixerTest, IncompleteType) { Annotations Test(R"cpp( $insert[[]]namespace ns { class X; + $nested[[X::]]Nested n; } class Y : $base[[public ns::X]] {}; int main() { @@ -326,6 +327,10 @@ int main() { EXPECT_THAT( TU.build().getDiagnostics(), UnorderedElementsAre( + AllOf(Diag(Test.range("nested"), + "incomplete type 'ns::X' named in nested name specifier"), + WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", + "Add include \"x.h\" for symbol ns::X"))), AllOf(Diag(Test.range("base"), "base class has incomplete type"), WithFix(Fix(Test.range("insert"), "#include \"x.h\"\n", "Add include \"x.h\" for symbol ns::X"))), -- cgit v1.2.3 From 564363bdadb17fbb29728e13f52620f314ba7c53 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Thu, 21 Feb 2019 09:55:00 +0000 Subject: [clangd] Enable indexing of template type parameters Summary: Fixes https://bugs.llvm.org/show_bug.cgi?id=36285 Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58294 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354561 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 5 ++++- unittests/clangd/SymbolInfoTests.cpp | 4 ++-- unittests/clangd/XRefsTests.cpp | 10 +++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index b296a056..9d470779 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -39,7 +39,8 @@ const Decl *getDefinition(const Decl *D) { if (const auto *FD = dyn_cast(D)) return FD->getDefinition(); // Only a single declaration is allowed. - if (isa(D)) // except cases above + if (isa(D) || isa(D) || + isa(D)) // except cases above return D; // Multiple definitions are allowed. return nullptr; // except cases above @@ -243,6 +244,7 @@ IdentifiedSymbol getSymbolAtPosition(ParsedAST &AST, SourceLocation Pos) { index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; IndexOpts.IndexParametersInDeclarations = true; + IndexOpts.IndexTemplateParameters = true; indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(), AST.getLocalTopLevelDecls(), DeclMacrosFinder, IndexOpts); @@ -441,6 +443,7 @@ findRefs(const std::vector &Decls, ParsedAST &AST) { index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; IndexOpts.IndexParametersInDeclarations = true; + IndexOpts.IndexTemplateParameters = true; indexTopLevelDecls(AST.getASTContext(), AST.getPreprocessor(), AST.getLocalTopLevelDecls(), RefFinder, IndexOpts); return std::move(RefFinder).take(); diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp index ed34c036..7494d90c 100644 --- a/unittests/clangd/SymbolInfoTests.cpp +++ b/unittests/clangd/SymbolInfoTests.cpp @@ -213,14 +213,14 @@ TEST(SymbolInfoTests, All) { T^T t; }; )cpp", - {/* not implemented */}}, + {CreateExpectedSymbolDetails("TT", "bar::", "c:TestTU.cpp@65")}}, { R"cpp( // Template parameter reference - type param template struct bar { int a = N^N; }; )cpp", - {/* not implemented */}}, + {CreateExpectedSymbolDetails("NN", "bar::", "c:TestTU.cpp@65")}}, { R"cpp( // Class member reference - objec struct foo { diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index 3b9610cb..f721cf94 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -285,11 +285,15 @@ TEST(LocateSymbol, All) { } )cpp", - /* FIXME: clangIndex doesn't handle template type parameters R"cpp(// Template type parameter - template <[[typename T]]> + template void foo() { ^T t; } - )cpp", */ + )cpp", + + R"cpp(// Template template type parameter + template class [[T]]> + void foo() { ^T t; } + )cpp", R"cpp(// Namespace namespace $decl[[ns]] { -- cgit v1.2.3 From b648010272332496c8b66c9d412e47562dcee038 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Thu, 21 Feb 2019 14:48:33 +0000 Subject: [clangd] Only report explicitly typed symbols during code navigation Summary: Clangd was reporting implicit symbols, like results of implicit cast expressions during code navigation, which is not desired. For example: ``` struct Foo{ Foo(int); }; void bar(Foo); vod foo() { int x; bar(^x); } ``` Performing a GoTo on the point specified by ^ would give two results one pointing to line `int x` and the other for definition of `Foo(int);` Reviewers: ilya-biryukov, sammccall Subscribers: ioeric, MaskRay, jkorous, mgrang, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58495 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354585 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 73 +++++++++++------------------------- unittests/clangd/SymbolInfoTests.cpp | 8 +--- unittests/clangd/XRefsTests.cpp | 31 +++++++++++---- 3 files changed, 47 insertions(+), 65 deletions(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 9d470779..216d78d0 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -110,20 +110,10 @@ struct MacroDecl { const MacroInfo *Info; }; -struct DeclInfo { - const Decl *D; - // Indicates the declaration is referenced by an explicit AST node. - bool IsReferencedExplicitly = false; -}; - /// Finds declarations locations that a given source location refers to. class DeclarationAndMacrosFinder : public index::IndexDataConsumer { std::vector MacroInfos; - // The value of the map indicates whether the declaration has been referenced - // explicitly in the code. - // True means the declaration is explicitly referenced at least once; false - // otherwise. - llvm::DenseMap Decls; + llvm::DenseSet Decls; const SourceLocation &SearchedLocation; const ASTContext &AST; Preprocessor &PP; @@ -133,22 +123,14 @@ public: ASTContext &AST, Preprocessor &PP) : SearchedLocation(SearchedLocation), AST(AST), PP(PP) {} - // Get all DeclInfo of the found declarations. - // The results are sorted by "IsReferencedExplicitly" and declaration - // location. - std::vector getFoundDecls() const { - std::vector Result; - for (auto It : Decls) { - Result.emplace_back(); - Result.back().D = It.first; - Result.back().IsReferencedExplicitly = It.second; - } + // The results are sorted by declaration location. + std::vector getFoundDecls() const { + std::vector Result; + for (const Decl *D : Decls) + Result.push_back(D); - // Sort results. Declarations being referenced explicitly come first. - llvm::sort(Result, [](const DeclInfo &L, const DeclInfo &R) { - if (L.IsReferencedExplicitly != R.IsReferencedExplicitly) - return L.IsReferencedExplicitly > R.IsReferencedExplicitly; - return L.D->getBeginLoc() < R.D->getBeginLoc(); + llvm::sort(Result, [](const Decl *L, const Decl *R) { + return L->getBeginLoc() < R->getBeginLoc(); }); return Result; } @@ -180,21 +162,21 @@ public: // clang) if it has an invalid paren/brace location, since such // experssion is impossible to write down. if (const auto *CtorExpr = dyn_cast(E)) - return CtorExpr->getNumArgs() > 0 && - CtorExpr->getParenOrBraceRange().isInvalid(); + return CtorExpr->getParenOrBraceRange().isInvalid(); return isa(E); }; - bool IsExplicit = !IsImplicitExpr(ASTNode.OrigE); + if (IsImplicitExpr(ASTNode.OrigE)) + return true; // Find and add definition declarations (for GoToDefinition). // We don't use parameter `D`, as Parameter `D` is the canonical // declaration, which is the first declaration of a redeclarable // declaration, and it could be a forward declaration. if (const auto *Def = getDefinition(D)) { - Decls[Def] |= IsExplicit; + Decls.insert(Def); } else { // Couldn't find a definition, fall back to use `D`. - Decls[D] |= IsExplicit; + Decls.insert(D); } } return true; @@ -232,7 +214,7 @@ private: }; struct IdentifiedSymbol { - std::vector Decls; + std::vector Decls; std::vector Macros; }; @@ -329,8 +311,7 @@ std::vector locateSymbolAt(ParsedAST &AST, Position Pos, llvm::DenseMap ResultIndex; // Emit all symbol locations (declaration or definition) from AST. - for (const DeclInfo &DI : Symbols.Decls) { - const Decl *D = DI.D; + for (const Decl *D : Symbols.Decls) { auto Loc = makeLocation(AST, findNameLoc(D), *MainFilePath); if (!Loc) continue; @@ -456,11 +437,7 @@ std::vector findDocumentHighlights(ParsedAST &AST, const SourceManager &SM = AST.getASTContext().getSourceManager(); auto Symbols = getSymbolAtPosition( AST, getBeginningOfIdentifier(AST, Pos, SM.getMainFileID())); - std::vector TargetDecls; - for (const DeclInfo &DI : Symbols.Decls) { - TargetDecls.push_back(DI.D); - } - auto References = findRefs(TargetDecls, AST); + auto References = findRefs(Symbols.Decls, AST); std::vector Result; for (const auto &Ref : References) { @@ -714,7 +691,7 @@ llvm::Optional getHover(ParsedAST &AST, Position Pos) { return getHoverContents(Symbols.Macros[0].Name); if (!Symbols.Decls.empty()) - return getHoverContents(Symbols.Decls[0].D); + return getHoverContents(Symbols.Decls[0]); auto DeducedType = getDeducedType(AST, SourceLocationBeg); if (DeducedType && !DeducedType->isNull()) @@ -738,15 +715,9 @@ std::vector findReferences(ParsedAST &AST, Position Pos, auto Loc = getBeginningOfIdentifier(AST, Pos, SM.getMainFileID()); auto Symbols = getSymbolAtPosition(AST, Loc); - std::vector TargetDecls; - for (const DeclInfo &DI : Symbols.Decls) { - if (DI.IsReferencedExplicitly) - TargetDecls.push_back(DI.D); - } - // We traverse the AST to find references in the main file. // TODO: should we handle macros, too? - auto MainFileRefs = findRefs(TargetDecls, AST); + auto MainFileRefs = findRefs(Symbols.Decls, AST); for (const auto &Ref : MainFileRefs) { Location Result; Result.range = getTokenRange(AST, Ref.Loc); @@ -759,7 +730,7 @@ std::vector findReferences(ParsedAST &AST, Position Pos, RefsRequest Req; Req.Limit = Limit; - for (const Decl *D : TargetDecls) { + for (const Decl *D : Symbols.Decls) { // Not all symbols can be referenced from outside (e.g. function-locals). // TODO: we could skip TU-scoped symbols here (e.g. static functions) if // we know this file isn't a header. The details might be tricky. @@ -790,9 +761,9 @@ std::vector getSymbolInfo(ParsedAST &AST, Position Pos) { std::vector Results; - for (const auto &Sym : Symbols.Decls) { + for (const Decl *D : Symbols.Decls) { SymbolDetails NewSymbol; - if (const NamedDecl *ND = dyn_cast(Sym.D)) { + if (const NamedDecl *ND = dyn_cast(D)) { std::string QName = printQualifiedName(*ND); std::tie(NewSymbol.containerName, NewSymbol.name) = splitQualifiedName(QName); @@ -804,7 +775,7 @@ std::vector getSymbolInfo(ParsedAST &AST, Position Pos) { } } llvm::SmallString<32> USR; - if (!index::generateUSRForDecl(Sym.D, USR)) { + if (!index::generateUSRForDecl(D, USR)) { NewSymbol.USR = USR.str(); NewSymbol.ID = SymbolID(NewSymbol.USR); } diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp index 7494d90c..4a7e4147 100644 --- a/unittests/clangd/SymbolInfoTests.cpp +++ b/unittests/clangd/SymbolInfoTests.cpp @@ -180,12 +180,8 @@ TEST(SymbolInfoTests, All) { func_baz1(f^f); } )cpp", - { - CreateExpectedSymbolDetails( - "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff"), - CreateExpectedSymbolDetails( - "bar", "bar::", "c:@S@bar@F@bar#&1$@S@foo#"), - }}, + {CreateExpectedSymbolDetails( + "ff", "func_baz2", "c:TestTU.cpp@218@F@func_baz2#@ff")}}, { R"cpp( // Type reference - declaration struct foo; diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index f721cf94..c1a253c5 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -406,6 +406,16 @@ TEST(LocateSymbol, All) { double y = va^r; )cpp", + + R"cpp(// No implicit constructors + class X { + X(X&& x) = default; + }; + X [[makeX]]() {} + void foo() { + auto x = m^akeX(); + } + )cpp", }; for (const char *Test : Tests) { Annotations T(Test); @@ -453,20 +463,25 @@ TEST(LocateSymbol, Ambiguous) { Foo c = $3^f(); $4^g($5^f()); g($6^str); + Foo ab$7^c; + Foo ab$8^cd("asdf"); + Foo foox = Fo$9^o("asdf"); } )cpp"); auto AST = TestTU::withCode(T.code()).build(); // Ordered assertions are deliberate: we expect a predictable order. - EXPECT_THAT(locateSymbolAt(AST, T.point("1")), - ElementsAre(Sym("str"), Sym("Foo"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("1")), ElementsAre(Sym("str"))); EXPECT_THAT(locateSymbolAt(AST, T.point("2")), ElementsAre(Sym("str"))); - EXPECT_THAT(locateSymbolAt(AST, T.point("3")), - ElementsAre(Sym("f"), Sym("Foo"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("3")), ElementsAre(Sym("f"))); EXPECT_THAT(locateSymbolAt(AST, T.point("4")), ElementsAre(Sym("g"))); - EXPECT_THAT(locateSymbolAt(AST, T.point("5")), - ElementsAre(Sym("f"), Sym("Foo"))); - EXPECT_THAT(locateSymbolAt(AST, T.point("6")), - ElementsAre(Sym("str"), Sym("Foo"), Sym("Foo"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("5")), ElementsAre(Sym("f"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("6")), ElementsAre(Sym("str"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("7")), ElementsAre(Sym("abc"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("8")), + ElementsAre(Sym("Foo"), Sym("abcd"))); + EXPECT_THAT(locateSymbolAt(AST, T.point("9")), + // First one is class definition, second is the constructor. + ElementsAre(Sym("Foo"), Sym("Foo"))); } TEST(LocateSymbol, RelPathsInCompileCommand) { -- cgit v1.2.3 From 4e3108933f42d2d017b8e9ba092eacfceb364b64 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 22 Feb 2019 09:43:56 +0000 Subject: [clangd] Don't attach FixIt to the source code in macro. Summary: We are less certain it is the correct fix. Also, clang doesn't apply FixIt to the source code in macro. Reviewers: ilya-biryukov Reviewed By: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58525 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354664 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Diagnostics.cpp | 5 +++++ unittests/clangd/DiagnosticsTests.cpp | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index 186ab066..21053953 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -335,6 +335,11 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, llvm::SmallVector Edits; for (auto &FixIt : Info.getFixItHints()) { + // Follow clang's behavior, don't apply FixIt to the code in macros, + // we are less certain it is the right fix. + if (FixIt.RemoveRange.getBegin().isMacroID() || + FixIt.RemoveRange.getEnd().isMacroID()) + return false; if (!isInsideMainFile(FixIt.RemoveRange.getBegin(), Info.getSourceManager())) return false; diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index bbd94b80..4bbc7c74 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -215,6 +215,18 @@ TEST(DiagnosticsTest, InsideMacros) { "'int *' with an rvalue of type 'int'"))); } +TEST(DiagnosticsTest, NoFixItInMacro) { + Annotations Test(R"cpp( + #define Define(name) void name() {} + + [[Define]](main) + )cpp"); + auto TU = TestTU::withCode(Test.code()); + EXPECT_THAT(TU.build().getDiagnostics(), + ElementsAre(AllOf(Diag(Test.range(), "'main' must return 'int'"), + Not(WithFix(_))))); +} + TEST(DiagnosticsTest, ToLSP) { clangd::Diag D; D.Message = "something terrible happened"; -- cgit v1.2.3 From ba602224342b45aaf7e5030c4a67e45982948a9b Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Sun, 24 Feb 2019 23:47:03 +0000 Subject: [clangd] Enhance macro hover to see full definition Summary: Signed-off-by: Marc-Andre Laperle Reviewers: simark, ilya-biryukov, sammccall, ioeric, hokein Reviewed By: ilya-biryukov Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D55250 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354761 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 31 ++++++++++++++++++++++++------- unittests/clangd/XRefsTests.cpp | 20 +++++++++++++++++++- 2 files changed, 43 insertions(+), 8 deletions(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index 216d78d0..edb1f7cb 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -558,13 +558,30 @@ static Hover getHoverContents(QualType T, ASTContext &ASTCtx) { return H; } -/// Generate a \p Hover object given the macro \p MacroInf. -static Hover getHoverContents(llvm::StringRef MacroName) { - Hover H; - - H.contents.value = "#define "; - H.contents.value += MacroName; +/// Generate a \p Hover object given the macro \p MacroDecl. +static Hover getHoverContents(MacroDecl Decl, ParsedAST &AST) { + SourceManager &SM = AST.getASTContext().getSourceManager(); + std::string Definition = Decl.Name; + + // Try to get the full definition, not just the name + SourceLocation StartLoc = Decl.Info->getDefinitionLoc(); + SourceLocation EndLoc = Decl.Info->getDefinitionEndLoc(); + if (EndLoc.isValid()) { + EndLoc = Lexer::getLocForEndOfToken(EndLoc, 0, SM, + AST.getASTContext().getLangOpts()); + bool Invalid; + StringRef Buffer = SM.getBufferData(SM.getFileID(StartLoc), &Invalid); + if (!Invalid) { + unsigned StartOffset = SM.getFileOffset(StartLoc); + unsigned EndOffset = SM.getFileOffset(EndLoc); + if (EndOffset <= Buffer.size() && StartOffset < EndOffset) + Definition = Buffer.substr(StartOffset, EndOffset - StartOffset).str(); + } + } + Hover H; + H.contents.kind = MarkupKind::PlainText; + H.contents.value = "#define " + Definition; return H; } @@ -688,7 +705,7 @@ llvm::Optional getHover(ParsedAST &AST, Position Pos) { auto Symbols = getSymbolAtPosition(AST, SourceLocationBeg); if (!Symbols.Macros.empty()) - return getHoverContents(Symbols.Macros[0].Name); + return getHoverContents(Symbols.Macros[0], AST); if (!Symbols.Decls.empty()) return getHoverContents(Symbols.Decls[0]); diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index c1a253c5..df795b1c 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -743,7 +743,25 @@ TEST(Hover, All) { #define MACRO 2 #undef macro )cpp", - "#define MACRO", + "#define MACRO 1", + }, + { + R"cpp(// Macro + #define MACRO 0 + #define MACRO2 ^MACRO + )cpp", + "#define MACRO 0", + }, + { + R"cpp(// Macro + #define MACRO {\ + return 0;\ + } + int main() ^MACRO + )cpp", + R"cpp(#define MACRO {\ + return 0;\ + })cpp", }, { R"cpp(// Forward class declaration -- cgit v1.2.3 From d93176fde22272c83c80dd5593d2b19965a2c6f9 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 25 Feb 2019 09:19:26 +0000 Subject: [clangd] Add thread priority lowering for MacOS as well Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58492 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354765 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Threading.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clangd/Threading.cpp b/clangd/Threading.cpp index 139fcc2f..695e30d8 100644 --- a/clangd/Threading.cpp +++ b/clangd/Threading.cpp @@ -7,6 +7,8 @@ #include #ifdef __USE_POSIX #include +#elif defined(__APPLE__) +#include #endif namespace clang { @@ -121,6 +123,12 @@ void setCurrentThreadPriority(ThreadPriority Priority) { Priority == ThreadPriority::Low && !AvoidThreadStarvation ? SCHED_IDLE : SCHED_OTHER, &priority); +#elif defined(__APPLE__) + // https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/getpriority.2.html + setpriority(PRIO_DARWIN_THREAD, 0, + Priority == ThreadPriority::Low && !AvoidThreadStarvation + ? PRIO_DARWIN_BG + : 0); #endif } -- cgit v1.2.3 From f96217fa1da2b9d13165d388790d4bf8c9f6333a Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 25 Feb 2019 12:48:52 +0000 Subject: Removed an unhelpful comment in index.rst Reviewers: ilya-biryukov Subscribers: arphaman, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58602 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354777 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/index.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 8e6beb35..e2152862 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,3 @@ -.. Extra Clang Tools documentation master file, created by - sphinx-quickstart on Wed Feb 13 10:00:18 2013. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - .. title:: Welcome to Extra Clang Tools's documentation! Introduction -- cgit v1.2.3 From 318481fd22289592b2325944f1e7e91542e48fb6 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 25 Feb 2019 12:49:27 +0000 Subject: Fixed grammar in index.rst Subscribers: arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58601 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354778 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/index.rst b/docs/index.rst index e2152862..e1b8a4e1 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -3,7 +3,7 @@ Introduction ============ Welcome to the clang-tools-extra project which contains extra tools built using -Clang's tooling API's. +Clang's tooling APIs. .. toctree:: :maxdepth: 1 -- cgit v1.2.3 From 9c3c00e4760e1975b16af74f7cf94239d941d403 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 25 Feb 2019 13:03:44 +0000 Subject: Updated the documentation build instructions for the current CMake build system Reviewers: ilya-biryukov Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58603 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354779 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/README.txt | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/README.txt b/docs/README.txt index 4b607775..cebbf63b 100644 --- a/docs/README.txt +++ b/docs/README.txt @@ -1,11 +1,10 @@ -------------------------------------------------------------- -Documentation for the tools of clang-tools-extra repo project -------------------------------------------------------------- +---------------------------------- +Documentation in clang-tools-extra +---------------------------------- -Sphinx and doxygen documentation is generated by executing make. +To generate documentation in HTML format from files in clang-tools-extra/docs, +build the docs-clang-tools-html target. -Sphinx html files can be generated separately using make html. +To generate documentation from the source code using Doxygen, build the +doxygen-clang-tools target. -Doxygen html files can also be generated using make doxygen. - -The generated documentation will be placed in _build/html. -- cgit v1.2.3 From 614c5f63c1ef53b796e09bdb337cd0892079d6cb Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Mon, 25 Feb 2019 13:09:02 +0000 Subject: [clang-tidy] misc-string-integer-assignment: ignore toupper/tolower Summary: Tis represents ~20% of false positives. See PR27723. Reviewers: xazax.hun, alexfh Subscribers: rnkovacs, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58604 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354780 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp | 13 +++++++++---- test/clang-tidy/bugprone-string-integer-assignment.cpp | 9 +++++++++ 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index cce0de9f..e9bde2a7 100644 --- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -27,10 +27,15 @@ void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { callee(cxxMethodDecl(ofClass(classTemplateSpecializationDecl( hasName("::std::basic_string"), hasTemplateArgument(0, refersToType(qualType().bind("type"))))))), - hasArgument(1, - ignoringImpCasts(expr(hasType(isInteger()), - unless(hasType(isAnyCharacter()))) - .bind("expr"))), + hasArgument( + 1, + ignoringImpCasts( + expr(hasType(isInteger()), unless(hasType(isAnyCharacter())), + // Ignore calls to tolower/toupper (see PR27723). + unless(callExpr(callee(functionDecl( + hasAnyName("tolower", "std::tolower", "toupper", + "std::toupper")))))) + .bind("expr"))), unless(isInTemplateInstantiation())), this); } diff --git a/test/clang-tidy/bugprone-string-integer-assignment.cpp b/test/clang-tidy/bugprone-string-integer-assignment.cpp index c4e13fc4..0317354d 100644 --- a/test/clang-tidy/bugprone-string-integer-assignment.cpp +++ b/test/clang-tidy/bugprone-string-integer-assignment.cpp @@ -11,8 +11,14 @@ struct basic_string { typedef basic_string string; typedef basic_string wstring; + +int tolower(int i); +int toupper(int i); } +int tolower(int i); +int toupper(int i); + typedef int MyArcaneChar; int main() { @@ -50,4 +56,7 @@ int main() { // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara // CHECK-FIXES: {{^}} as = 6;{{$}} + s += toupper(x); + s += tolower(x); + s += std::tolower(x); } -- cgit v1.2.3 From fe5246b61ef21657fddbf55567ed88954e23e05c Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 25 Feb 2019 13:43:48 +0000 Subject: Moved clangd docs to a separate directory in preparation to restructure them into multiple files Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58607 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354786 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd.rst | 181 +------------------------------------------------- docs/clangd/index.rst | 180 +++++++++++++++++++++++++++++++++++++++++++++++++ docs/index.rst | 2 +- 3 files changed, 183 insertions(+), 180 deletions(-) create mode 100644 docs/clangd/index.rst diff --git a/docs/clangd.rst b/docs/clangd.rst index 0843bcaf..768c5da5 100644 --- a/docs/clangd.rst +++ b/docs/clangd.rst @@ -1,180 +1,3 @@ -============ -Clangd -============ +:orphan: -.. contents:: - -.. toctree:: - :maxdepth: 1 - -:program:`Clangd` is an implementation of the `Language Server Protocol -`_ leveraging Clang. -Clangd's goal is to provide language "smartness" features like code completion, -find references, etc. for clients such as C/C++ Editors. - -Using Clangd -================== - -:program:`Clangd` is not meant to be used by C/C++ developers directly but -rather from a client implementing the protocol. A client would be typically -implemented in an IDE or an editor. - -At the moment, `Visual Studio Code `_ is mainly -used in order to test :program:`Clangd` but more clients are likely to make -use of :program:`Clangd` in the future as it matures and becomes a production -quality tool. If you are interested in trying :program:`Clangd` in combination -with Visual Studio Code, you can start by `installing Clangd`_ or -`building Clangd`_, then open Visual Studio Code in the clangd-vscode folder and -launch the extension. - -Installing Clangd -================== - -Packages are available for debian-based distributions, see the `LLVM packages -page `_. :program:`Clangd` is included in the -`clang-tools` package. -However, it is a good idea to check your distribution's packaging system first -as it might already be available. - -Otherwise, you can install :program:`Clangd` by `building Clangd`_ first. - -Building Clangd -================== - -You can follow the instructions for `building Clang -`_ but "extra Clang tools" is **not** -optional. - -Current Status -================== - -Many features could be implemented in :program:`Clangd`. -Here is a list of features that could be useful with the status of whether or -not they are already implemented in :program:`Clangd` and specified in the -Language Server Protocol. Note that for some of the features, it is not clear -whether or not they should be part of the Language Server Protocol, so those -features might be eventually developed outside :program:`Clangd` or as an -extension to the protocol. - -+-------------------------------------+------------+----------+ -| C/C++ Editor feature | LSP | Clangd | -+=====================================+============+==========+ -| Formatting | Yes | Yes | -+-------------------------------------+------------+----------+ -| Completion | Yes | Yes | -+-------------------------------------+------------+----------+ -| Diagnostics | Yes | Yes | -+-------------------------------------+------------+----------+ -| Fix-its | Yes | Yes | -+-------------------------------------+------------+----------+ -| Go to Definition | Yes | Yes | -+-------------------------------------+------------+----------+ -| Signature Help | Yes | Yes | -+-------------------------------------+------------+----------+ -| Document Highlights | Yes | Yes | -+-------------------------------------+------------+----------+ -| Rename | Yes | Yes | -+-------------------------------------+------------+----------+ -| Source hover | Yes | Yes | -+-------------------------------------+------------+----------+ -| Find References | Yes | No | -+-------------------------------------+------------+----------+ -| Code Lens | Yes | No | -+-------------------------------------+------------+----------+ -| Document Symbols | Yes | Yes | -+-------------------------------------+------------+----------+ -| Workspace Symbols | Yes | Yes | -+-------------------------------------+------------+----------+ -| Syntax and Semantic Coloring | No | No | -+-------------------------------------+------------+----------+ -| Code folding | No | No | -+-------------------------------------+------------+----------+ -| Call hierarchy | No | No | -+-------------------------------------+------------+----------+ -| Type hierarchy | No | No | -+-------------------------------------+------------+----------+ -| Organize Includes | No | No | -+-------------------------------------+------------+----------+ -| Quick Assist | No | No | -+-------------------------------------+------------+----------+ -| Extract Local Variable | No | No | -+-------------------------------------+------------+----------+ -| Extract Function/Method | No | No | -+-------------------------------------+------------+----------+ -| Hide Method | No | No | -+-------------------------------------+------------+----------+ -| Implement Method | No | No | -+-------------------------------------+------------+----------+ -| Gen. Getters/Setters | No | No | -+-------------------------------------+------------+----------+ - -Editor Integration -================== - -Any full-featured Language Server Protocol Client implementation should work -with :program:`Clangd`. This `list -`_ contains information about -extensions and plugins that are known to work for different editors. - -Vim Integration ---------------- - -LanguageClient-neovim -~~~~~~~~~~~~~~~~~~~~~ - -One of the options of using :program:`Clangd` in :program:`vim` (or -:program:`nvim`) is to utilize `LanguageClient-neovim -`_ plugin. Please see the -`Clangd Wiki page -`_ for -instructions. - -VSCode Integration ------------------- - -:program:`VSCode` provides `vscode-clangd -`_ -which is published in Visual Studio Marketplace and can be installed direcetly -from :program:`VSCode`. - -Emacs Integration ------------------ - -:program:`Emacs` provides `lsp-mode `_ and -`Eglot `_ plugins for LSP integration. - -Project-wide Index -================== - -By default :program:`Clangd` only has a view on symbols coming from files you -are currently editing. You can extend this view to whole project by providing a -project-wide index to :program:`Clangd`. - -There are two ways you can generate a project-wide index for clangd: - -- Passing experimental `-background-index` commandline argument, which will - incrementally build an index of projects that you work on and make use of that - in clangd automatically. -- Generate an index file using `clangd-indexer - `_ - Afterwards you can pass generated index file to clangd using - `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't included - alongside clangd in the standard clang-tools package. You will likely have to - build from source to use this option* - -Getting Involved -================== - -A good place for interested contributors is the `Clangd developer mailing list -`_. For discussions with the -broader community on topics not only related to Clangd, use -`Clang developer mailing list -`_. -If you're also interested in contributing patches to :program:`Clangd`, take a -look at the `LLVM Developer Policy -`_ and `Code Reviews -`_ page. Contributions of new features -to the `Language Server Protocol -`_ itself would also be -very useful, so that :program:`Clangd` can eventually implement them in a -conforming way. +All :program:`clangd` documentation was moved to the :doc:`clangd/index` pages. diff --git a/docs/clangd/index.rst b/docs/clangd/index.rst new file mode 100644 index 00000000..0843bcaf --- /dev/null +++ b/docs/clangd/index.rst @@ -0,0 +1,180 @@ +============ +Clangd +============ + +.. contents:: + +.. toctree:: + :maxdepth: 1 + +:program:`Clangd` is an implementation of the `Language Server Protocol +`_ leveraging Clang. +Clangd's goal is to provide language "smartness" features like code completion, +find references, etc. for clients such as C/C++ Editors. + +Using Clangd +================== + +:program:`Clangd` is not meant to be used by C/C++ developers directly but +rather from a client implementing the protocol. A client would be typically +implemented in an IDE or an editor. + +At the moment, `Visual Studio Code `_ is mainly +used in order to test :program:`Clangd` but more clients are likely to make +use of :program:`Clangd` in the future as it matures and becomes a production +quality tool. If you are interested in trying :program:`Clangd` in combination +with Visual Studio Code, you can start by `installing Clangd`_ or +`building Clangd`_, then open Visual Studio Code in the clangd-vscode folder and +launch the extension. + +Installing Clangd +================== + +Packages are available for debian-based distributions, see the `LLVM packages +page `_. :program:`Clangd` is included in the +`clang-tools` package. +However, it is a good idea to check your distribution's packaging system first +as it might already be available. + +Otherwise, you can install :program:`Clangd` by `building Clangd`_ first. + +Building Clangd +================== + +You can follow the instructions for `building Clang +`_ but "extra Clang tools" is **not** +optional. + +Current Status +================== + +Many features could be implemented in :program:`Clangd`. +Here is a list of features that could be useful with the status of whether or +not they are already implemented in :program:`Clangd` and specified in the +Language Server Protocol. Note that for some of the features, it is not clear +whether or not they should be part of the Language Server Protocol, so those +features might be eventually developed outside :program:`Clangd` or as an +extension to the protocol. + ++-------------------------------------+------------+----------+ +| C/C++ Editor feature | LSP | Clangd | ++=====================================+============+==========+ +| Formatting | Yes | Yes | ++-------------------------------------+------------+----------+ +| Completion | Yes | Yes | ++-------------------------------------+------------+----------+ +| Diagnostics | Yes | Yes | ++-------------------------------------+------------+----------+ +| Fix-its | Yes | Yes | ++-------------------------------------+------------+----------+ +| Go to Definition | Yes | Yes | ++-------------------------------------+------------+----------+ +| Signature Help | Yes | Yes | ++-------------------------------------+------------+----------+ +| Document Highlights | Yes | Yes | ++-------------------------------------+------------+----------+ +| Rename | Yes | Yes | ++-------------------------------------+------------+----------+ +| Source hover | Yes | Yes | ++-------------------------------------+------------+----------+ +| Find References | Yes | No | ++-------------------------------------+------------+----------+ +| Code Lens | Yes | No | ++-------------------------------------+------------+----------+ +| Document Symbols | Yes | Yes | ++-------------------------------------+------------+----------+ +| Workspace Symbols | Yes | Yes | ++-------------------------------------+------------+----------+ +| Syntax and Semantic Coloring | No | No | ++-------------------------------------+------------+----------+ +| Code folding | No | No | ++-------------------------------------+------------+----------+ +| Call hierarchy | No | No | ++-------------------------------------+------------+----------+ +| Type hierarchy | No | No | ++-------------------------------------+------------+----------+ +| Organize Includes | No | No | ++-------------------------------------+------------+----------+ +| Quick Assist | No | No | ++-------------------------------------+------------+----------+ +| Extract Local Variable | No | No | ++-------------------------------------+------------+----------+ +| Extract Function/Method | No | No | ++-------------------------------------+------------+----------+ +| Hide Method | No | No | ++-------------------------------------+------------+----------+ +| Implement Method | No | No | ++-------------------------------------+------------+----------+ +| Gen. Getters/Setters | No | No | ++-------------------------------------+------------+----------+ + +Editor Integration +================== + +Any full-featured Language Server Protocol Client implementation should work +with :program:`Clangd`. This `list +`_ contains information about +extensions and plugins that are known to work for different editors. + +Vim Integration +--------------- + +LanguageClient-neovim +~~~~~~~~~~~~~~~~~~~~~ + +One of the options of using :program:`Clangd` in :program:`vim` (or +:program:`nvim`) is to utilize `LanguageClient-neovim +`_ plugin. Please see the +`Clangd Wiki page +`_ for +instructions. + +VSCode Integration +------------------ + +:program:`VSCode` provides `vscode-clangd +`_ +which is published in Visual Studio Marketplace and can be installed direcetly +from :program:`VSCode`. + +Emacs Integration +----------------- + +:program:`Emacs` provides `lsp-mode `_ and +`Eglot `_ plugins for LSP integration. + +Project-wide Index +================== + +By default :program:`Clangd` only has a view on symbols coming from files you +are currently editing. You can extend this view to whole project by providing a +project-wide index to :program:`Clangd`. + +There are two ways you can generate a project-wide index for clangd: + +- Passing experimental `-background-index` commandline argument, which will + incrementally build an index of projects that you work on and make use of that + in clangd automatically. +- Generate an index file using `clangd-indexer + `_ + Afterwards you can pass generated index file to clangd using + `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't included + alongside clangd in the standard clang-tools package. You will likely have to + build from source to use this option* + +Getting Involved +================== + +A good place for interested contributors is the `Clangd developer mailing list +`_. For discussions with the +broader community on topics not only related to Clangd, use +`Clang developer mailing list +`_. +If you're also interested in contributing patches to :program:`Clangd`, take a +look at the `LLVM Developer Policy +`_ and `Code Reviews +`_ page. Contributions of new features +to the `Language Server Protocol +`_ itself would also be +very useful, so that :program:`Clangd` can eventually implement them in a +conforming way. diff --git a/docs/index.rst b/docs/index.rst index e1b8a4e1..8fae25c4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -20,7 +20,7 @@ Contents modularize pp-trace clang-rename - clangd + clangd/index clang-doc -- cgit v1.2.3 From c133b07de98b70989d9377e0dd0286dcf5af9e27 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 25 Feb 2019 16:00:00 +0000 Subject: [clangd] Drop documentation in static index if symbols are not indexed for completion. Summary: This is a further optimization of r350803, we drop docs in static index for symbols not being indexed for completion, while keeping the docs in dynamic index (we rely on dynamic index to get docs for class members). Reviewers: ilya-biryukov Reviewed By: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Differential Revision: https://reviews.llvm.org/D56539 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354792 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/FileIndex.cpp | 4 ++++ clangd/index/IndexAction.cpp | 1 + clangd/index/SymbolCollector.cpp | 11 +++-------- clangd/index/SymbolCollector.h | 4 ++++ unittests/clangd/SymbolCollectorTests.cpp | 31 +++++++++++++++++++++++++++++++ 5 files changed, 43 insertions(+), 8 deletions(-) diff --git a/clangd/index/FileIndex.cpp b/clangd/index/FileIndex.cpp index bc102d29..37fd031e 100644 --- a/clangd/index/FileIndex.cpp +++ b/clangd/index/FileIndex.cpp @@ -45,9 +45,13 @@ indexSymbols(ASTContext &AST, std::shared_ptr PP, if (IsIndexMainAST) { // We only collect refs when indexing main AST. CollectorOpts.RefFilter = RefKind::All; + // Comments for main file can always be obtained from sema, do not store + // them in the index. + CollectorOpts.StoreAllDocumentation = false; } else { IndexOpts.IndexMacrosInPreprocessor = true; CollectorOpts.CollectMacro = true; + CollectorOpts.StoreAllDocumentation = true; } SymbolCollector Collector(std::move(CollectorOpts)); diff --git a/clangd/index/IndexAction.cpp b/clangd/index/IndexAction.cpp index a6df64b7..b9b7ef2d 100644 --- a/clangd/index/IndexAction.cpp +++ b/clangd/index/IndexAction.cpp @@ -175,6 +175,7 @@ std::unique_ptr createStaticIndexingAction( Opts.CollectIncludePath = true; Opts.CountReferences = true; Opts.Origin = SymbolOrigin::Static; + Opts.StoreAllDocumentation = false; if (RefsCallback != nullptr) { Opts.RefFilter = RefKind::All; Opts.RefsInHeaders = true; diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index cbbbd505..23fcc5c5 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -566,18 +566,13 @@ const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, std::string Documentation = formatDocumentation(*CCS, getDocComment(Ctx, SymbolCompletion, /*CommentsFromHeaders=*/true)); - // For symbols not indexed for completion (class members), we also store their - // docs in the index, because Sema doesn't load the docs from the preamble, we - // rely on the index to get the docs. - // FIXME: this can be optimized by only storing the docs in dynamic index -- - // dynamic index should index these symbols when Sema completes a member - // completion. - S.Documentation = Documentation; if (!(S.Flags & Symbol::IndexedForCodeCompletion)) { + if (Opts.StoreAllDocumentation) + S.Documentation = Documentation; Symbols.insert(S); return Symbols.find(S.ID); } - + S.Documentation = Documentation; std::string Signature; std::string SnippetSuffix; getSignature(*CCS, &Signature, &SnippetSuffix); diff --git a/clangd/index/SymbolCollector.h b/clangd/index/SymbolCollector.h index 1b10df4c..0261bf7c 100644 --- a/clangd/index/SymbolCollector.h +++ b/clangd/index/SymbolCollector.h @@ -75,6 +75,10 @@ public: /// Collect symbols local to main-files, such as static functions /// and symbols inside an anonymous namespace. bool CollectMainFileSymbols = true; + /// If set to true, SymbolCollector will collect doc for all symbols. + /// Note that documents of symbols being indexed for completion will always + /// be collected regardless of this option. + bool StoreAllDocumentation = false; /// If this is set, only collect symbols/references from a file if /// `FileFilter(SM, FID)` is true. If not set, all files are indexed. std::function FileFilter = nullptr; diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index 258cfa9d..a9e1f2e6 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -212,6 +212,12 @@ public: return WrapperFrontendAction::CreateASTConsumer(CI, InFile); } + bool BeginInvocation(CompilerInstance &CI) override { + // Make the compiler parse all comments. + CI.getLangOpts().CommentOpts.ParseAllComments = true; + return WrapperFrontendAction::BeginInvocation(CI); + } + private: index::IndexingOptions IndexOpts; CommentHandler *PragmaHandler; @@ -710,6 +716,31 @@ TEST_F(SymbolCollectorTest, SymbolsInMainFile) { QName("main_f"))); } +TEST_F(SymbolCollectorTest, Documentation) { + const std::string Header = R"( + // Doc Foo + class Foo { + // Doc f + int f(); + }; + )"; + CollectorOpts.StoreAllDocumentation = false; + runSymbolCollector(Header, /* Main */ ""); + EXPECT_THAT(Symbols, + UnorderedElementsAre( + AllOf(QName("Foo"), Doc("Doc Foo"), ForCodeCompletion(true)), + AllOf(QName("Foo::f"), Doc(""), ReturnType(""), + ForCodeCompletion(false)))); + + CollectorOpts.StoreAllDocumentation = true; + runSymbolCollector(Header, /* Main */ ""); + EXPECT_THAT(Symbols, + UnorderedElementsAre( + AllOf(QName("Foo"), Doc("Doc Foo"), ForCodeCompletion(true)), + AllOf(QName("Foo::f"), Doc("Doc f"), ReturnType(""), + ForCodeCompletion(false)))); +} + TEST_F(SymbolCollectorTest, ClassMembers) { const std::string Header = R"( class Foo { -- cgit v1.2.3 From a3bc339ae08cabd992c4fbd08ea3d7a96fa21e07 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 26 Feb 2019 11:08:04 +0000 Subject: [clangd] Update docs to mention YCM integration and new LSP features Reviewers: gribozavr Reviewed By: gribozavr Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D56718 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354865 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd/index.rst | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/clangd/index.rst b/docs/clangd/index.rst index 0843bcaf..c8719059 100644 --- a/docs/clangd/index.rst +++ b/docs/clangd/index.rst @@ -77,35 +77,35 @@ extension to the protocol. +-------------------------------------+------------+----------+ | Source hover | Yes | Yes | +-------------------------------------+------------+----------+ -| Find References | Yes | No | -+-------------------------------------+------------+----------+ -| Code Lens | Yes | No | +| Find References | Yes | Yes | +-------------------------------------+------------+----------+ | Document Symbols | Yes | Yes | +-------------------------------------+------------+----------+ | Workspace Symbols | Yes | Yes | +-------------------------------------+------------+----------+ -| Syntax and Semantic Coloring | No | No | +| Code Lens | Yes | No | +-------------------------------------+------------+----------+ -| Code folding | No | No | +| Code folding | Yes | No | +-------------------------------------+------------+----------+ -| Call hierarchy | No | No | +| Extract Local Variable | Yes | No | +-------------------------------------+------------+----------+ -| Type hierarchy | No | No | +| Extract Function/Method | Yes | No | +-------------------------------------+------------+----------+ -| Organize Includes | No | No | +| Quick Assist | Yes | No | ++-------------------------------------+------------+----------+ +| Hide Method | Yes | No | +-------------------------------------+------------+----------+ -| Quick Assist | No | No | +| Implement Method | Yes | No | +-------------------------------------+------------+----------+ -| Extract Local Variable | No | No | +| Gen. Getters/Setters | Yes | No | +-------------------------------------+------------+----------+ -| Extract Function/Method | No | No | +| Syntax and Semantic Coloring | No | No | +-------------------------------------+------------+----------+ -| Hide Method | No | No | +| Call hierarchy | No | No | +-------------------------------------+------------+----------+ -| Implement Method | No | No | +| Type hierarchy | No | No | +-------------------------------------+------------+----------+ -| Gen. Getters/Setters | No | No | +| Organize Includes | No | No | +-------------------------------------+------------+----------+ Editor Integration -- cgit v1.2.3 From 817f87451361131c193245b33e323031e7aeec0c Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 26 Feb 2019 14:23:47 +0000 Subject: [clangd] Index UsingDecls Summary: D58340 enables indexing of USRs, this makes sure test in clangd are aligned with the change Reviewers: hokein Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58341 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354879 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/CodeCompleteTests.cpp | 21 +++++++++++++++++++++ unittests/clangd/FindSymbolsTests.cpp | 5 +---- unittests/clangd/SymbolCollectorTests.cpp | 14 +++++++++++--- unittests/clangd/SymbolInfoTests.cpp | 3 ++- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp index 3a0082a2..df7c8ef1 100644 --- a/unittests/clangd/CodeCompleteTests.cpp +++ b/unittests/clangd/CodeCompleteTests.cpp @@ -17,6 +17,7 @@ #include "SyncAPI.h" #include "TestFS.h" #include "TestIndex.h" +#include "TestTU.h" #include "index/MemIndex.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "llvm/Support/Error.h" @@ -2314,6 +2315,26 @@ TEST(CompletionTest, WorksWithNullType) { EXPECT_THAT(R.Completions, ElementsAre(Named("loopVar"))); } +TEST(CompletionTest, UsingDecl) { + const char *Header(R"cpp( + void foo(int); + namespace std { + using ::foo; + })cpp"); + const char *Source(R"cpp( + void bar() { + std::^; + })cpp"); + auto Index = TestTU::withHeaderCode(Header).index(); + clangd::CodeCompleteOptions Opts; + Opts.Index = Index.get(); + Opts.AllScopes = true; + auto R = completions(Source, {}, Opts); + EXPECT_THAT(R.Completions, + ElementsAre(AllOf(Scope("std::"), Named("foo"), + Kind(CompletionItemKind::Reference)))); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/unittests/clangd/FindSymbolsTests.cpp b/unittests/clangd/FindSymbolsTests.cpp index 78447f35..05fa42e9 100644 --- a/unittests/clangd/FindSymbolsTests.cpp +++ b/unittests/clangd/FindSymbolsTests.cpp @@ -368,9 +368,6 @@ TEST_F(DocumentSymbolsTest, BasicSymbols) { // Namespace alias namespace baz = bar; - // FIXME: using declaration is not supported as the IndexAction will ignore - // implicit declarations (the implicit using shadow declaration) by default, - // and there is no way to customize this behavior at the moment. using bar::v2; } // namespace foo )"); @@ -415,7 +412,7 @@ TEST_F(DocumentSymbolsTest, BasicSymbols) { Children()))), AllOf(WithName("baz"), WithKind(SymbolKind::Namespace), Children()), - AllOf(WithName("v2"), WithKind(SymbolKind::Variable))))})); + AllOf(WithName("v2"), WithKind(SymbolKind::Namespace))))})); } TEST_F(DocumentSymbolsTest, DeclarationDefinition) { diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index a9e1f2e6..d795286f 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -331,9 +331,6 @@ TEST_F(SymbolCollectorTest, CollectSymbols) { // Namespace alias namespace baz = bar; - // FIXME: using declaration is not supported as the IndexAction will ignore - // implicit declarations (the implicit using shadow declaration) by default, - // and there is no way to customize this behavior at the moment. using bar::v2; } // namespace foo )"; @@ -360,6 +357,7 @@ TEST_F(SymbolCollectorTest, CollectSymbols) { AllOf(QName("foo::int32_t"), ForCodeCompletion(true)), AllOf(QName("foo::v1"), ForCodeCompletion(true)), AllOf(QName("foo::bar::v2"), ForCodeCompletion(true)), + AllOf(QName("foo::v2"), ForCodeCompletion(true)), AllOf(QName("foo::baz"), ForCodeCompletion(true))})); } @@ -1149,6 +1147,16 @@ TEST_F(SymbolCollectorTest, ImplementationDetail) { AllOf(QName("Public"), Not(ImplementationDetail())))); } +TEST_F(SymbolCollectorTest, UsingDecl) { + const char *Header = R"( + void foo(); + namespace std { + using ::foo; + })"; + runSymbolCollector(Header, /**/ ""); + EXPECT_THAT(Symbols, Contains(QName("std::foo"))); +} + } // namespace } // namespace clangd } // namespace clang diff --git a/unittests/clangd/SymbolInfoTests.cpp b/unittests/clangd/SymbolInfoTests.cpp index 4a7e4147..e0a9ecdc 100644 --- a/unittests/clangd/SymbolInfoTests.cpp +++ b/unittests/clangd/SymbolInfoTests.cpp @@ -167,7 +167,8 @@ TEST(SymbolInfoTests, All) { )cpp", {CreateExpectedSymbolDetails("foo", "", "c:@F@foo#"), CreateExpectedSymbolDetails("foo", "", "c:@F@foo#b#"), - CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#")}}, + CreateExpectedSymbolDetails("foo", "", "c:@F@foo#I#"), + CreateExpectedSymbolDetails("foo", "bar::", "c:@N@bar@UD@foo")}}, { R"cpp( // Multiple symbols returned - implicit conversion struct foo {}; -- cgit v1.2.3 From 42b306729f440f334089a774e29d51ba5a0e5d66 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Tue, 26 Feb 2019 18:15:17 +0000 Subject: [clang-tidy] undo bitfields in ExceptionAnalyzer Scoped enums do induce some problems with some MSVC and GCC versions if used as bitfields. Therefor this is deactivated for now. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354903 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/utils/ExceptionAnalyzer.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/clang-tidy/utils/ExceptionAnalyzer.h b/clang-tidy/utils/ExceptionAnalyzer.h index ac196976..5902e5af 100644 --- a/clang-tidy/utils/ExceptionAnalyzer.h +++ b/clang-tidy/utils/ExceptionAnalyzer.h @@ -109,19 +109,17 @@ public: /// Keep track if the entity related to this 'ExceptionInfo' can in princple /// throw, if it's unknown or if it won't throw. - State Behaviour : 2; + State Behaviour; /// Keep track if the entity contains any unknown elements to keep track /// of the certainty of decisions and/or correct 'Behaviour' transition /// after filtering. - bool ContainsUnknown : 1; + bool ContainsUnknown; /// 'ThrownException' is empty if the 'Behaviour' is either 'NotThrowing' or /// 'Unknown'. Throwables ThrownExceptions; }; - static_assert(sizeof(ExceptionInfo) <= 64u, - "size of exceptioninfo shall be at max one cache line"); ExceptionAnalyzer() = default; -- cgit v1.2.3 From de38e8f6c2ea100c62cd3124dbab98d7729b3cec Mon Sep 17 00:00:00 2001 From: Jan Korous Date: Wed, 27 Feb 2019 02:37:44 +0000 Subject: [clangd] Library dependencies in XPC Patch by Nicholas Allegra Differential Revision: https://reviews.llvm.org/D58089 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354949 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/xpc/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clangd/xpc/CMakeLists.txt b/clangd/xpc/CMakeLists.txt index 788a66f5..f05767c8 100644 --- a/clangd/xpc/CMakeLists.txt +++ b/clangd/xpc/CMakeLists.txt @@ -20,10 +20,10 @@ set(LLVM_OPTIONAL_SOURCES Conversion.cpp XPCTransport.cpp) add_clang_library(clangdXpcJsonConversions Conversion.cpp + LINK_LIBS clangDaemon ) add_clang_library(clangdXpcTransport XPCTransport.cpp - DEPENDS clangdXpcJsonConversions - LINK_LIBS clangdXpcJsonConversions + LINK_LIBS clangDaemon clangdXpcJsonConversions ) -- cgit v1.2.3 From f091bc3a2bb1c34977fccec6807d5dd4377ce5b7 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Wed, 27 Feb 2019 10:16:03 +0000 Subject: [clangd] Set thread priority on Windows Reviewers: kadircet, gribozavr Reviewed By: kadircet, gribozavr Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58683 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354957 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/Threading.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clangd/Threading.cpp b/clangd/Threading.cpp index 695e30d8..733267c0 100644 --- a/clangd/Threading.cpp +++ b/clangd/Threading.cpp @@ -9,6 +9,8 @@ #include #elif defined(__APPLE__) #include +#elif defined (_WIN32) +#include #endif namespace clang { @@ -129,6 +131,11 @@ void setCurrentThreadPriority(ThreadPriority Priority) { Priority == ThreadPriority::Low && !AvoidThreadStarvation ? PRIO_DARWIN_BG : 0); +#elif defined(_WIN32) + SetThreadPriority(GetCurrentThread(), + Priority == ThreadPriority::Low && !AvoidThreadStarvation + ? THREAD_MODE_BACKGROUND_BEGIN + : THREAD_MODE_BACKGROUND_END); #endif } -- cgit v1.2.3 From 858f095942024724b4af42ee2eb375e896886ec2 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Wed, 27 Feb 2019 11:42:37 +0000 Subject: [clangd] Improve global code completion when scope specifier is unresolved. Summary: Suppose `clangd::` is unresolved in the following example. Currently, we simply use "clangd::" as the query scope. We can do better by combining with accessible scopes in the context. The query scopes can be `{clangd::, clang::clangd::}`. ``` namespace clang { clangd::^ } ``` Reviewers: ilya-biryukov, sammccall, hokein, kadircet Reviewed By: kadircet Subscribers: MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58448 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354963 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CodeComplete.cpp | 18 ++++++++--------- unittests/clangd/CodeCompleteTests.cpp | 35 ++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 11 deletions(-) diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index b059216a..8cbff88c 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -48,6 +48,7 @@ #include "llvm/ADT/None.h" #include "llvm/ADT/Optional.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" @@ -526,7 +527,7 @@ struct SpecifiedScope { std::set Results; for (llvm::StringRef AS : AccessibleScopes) Results.insert( - ((UnresolvedQualifier ? *UnresolvedQualifier : "") + AS).str()); + (AS + (UnresolvedQualifier ? *UnresolvedQualifier : "")).str()); return {Results.begin(), Results.end()}; } }; @@ -570,16 +571,15 @@ getQueryScopes(CodeCompletionContext &CCContext, const Sema &CCSema, } // Unresolved qualifier. - // FIXME: When Sema can resolve part of a scope chain (e.g. - // "known::unknown::id"), we should expand the known part ("known::") rather - // than treating the whole thing as unknown. - SpecifiedScope Info; - Info.AccessibleScopes.push_back(""); // global namespace + SpecifiedScope Info = GetAllAccessibleScopes(CCContext); + Info.AccessibleScopes.push_back(""); // Make sure global scope is included. - Info.UnresolvedQualifier = + llvm::StringRef SpelledSpecifier = Lexer::getSourceText(CharSourceRange::getCharRange((*SS)->getRange()), - CCSema.SourceMgr, clang::LangOptions()) - .ltrim("::"); + CCSema.SourceMgr, clang::LangOptions()); + if (SpelledSpecifier.consume_front("::")) + Info.AccessibleScopes = {""}; + Info.UnresolvedQualifier = SpelledSpecifier; // Sema excludes the trailing "::". if (!Info.UnresolvedQualifier->empty()) *Info.UnresolvedQualifier += "::"; diff --git a/unittests/clangd/CodeCompleteTests.cpp b/unittests/clangd/CodeCompleteTests.cpp index df7c8ef1..16d8efcf 100644 --- a/unittests/clangd/CodeCompleteTests.cpp +++ b/unittests/clangd/CodeCompleteTests.cpp @@ -1095,8 +1095,10 @@ TEST(CompletionTest, UnresolvedQualifierIdQuery) { } // namespace ns )cpp"); - EXPECT_THAT(Requests, ElementsAre(Field(&FuzzyFindRequest::Scopes, - UnorderedElementsAre("bar::")))); + EXPECT_THAT(Requests, + ElementsAre(Field( + &FuzzyFindRequest::Scopes, + UnorderedElementsAre("a::bar::", "ns::bar::", "bar::")))); } TEST(CompletionTest, UnresolvedNestedQualifierIdQuery) { @@ -2335,6 +2337,35 @@ TEST(CompletionTest, UsingDecl) { Kind(CompletionItemKind::Reference)))); } +TEST(CompletionTest, ScopeIsUnresolved) { + clangd::CodeCompleteOptions Opts = {}; + Opts.AllScopes = true; + + auto Results = completions(R"cpp( + namespace a { + void f() { b::X^ } + } + )cpp", + {cls("a::b::XYZ")}, Opts); + EXPECT_THAT(Results.Completions, + UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ")))); +} + +TEST(CompletionTest, NestedScopeIsUnresolved) { + clangd::CodeCompleteOptions Opts = {}; + Opts.AllScopes = true; + + auto Results = completions(R"cpp( + namespace a { + namespace b {} + void f() { b::c::X^ } + } + )cpp", + {cls("a::b::c::XYZ")}, Opts); + EXPECT_THAT(Results.Completions, + UnorderedElementsAre(AllOf(Qualifier(""), Named("XYZ")))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From 59f908a0ea70a8aa7b0cd24604c79a68abf90e96 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Wed, 27 Feb 2019 15:53:05 +0000 Subject: Added more detailed documentation for clangd Summary: The text was written mostly by Sam McCall, screenshots are mostly made by me. Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58710 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354992 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/_static/clang-tools-extra-styles.css | 23 ++ docs/_templates/layout.html | 3 + docs/clangd/ApplyClangTidyFixInVSCode.gif | Bin 0 -> 95232 bytes docs/clangd/ApplyFixInVSCode.gif | Bin 0 -> 73814 bytes docs/clangd/CodeCompletionInEmacsCompanyMode.png | Bin 0 -> 10480 bytes docs/clangd/CodeCompletionInSublimeText.png | Bin 0 -> 19894 bytes docs/clangd/CodeCompletionInVSCode.png | Bin 0 -> 15094 bytes docs/clangd/CodeCompletionInYCM.png | Bin 0 -> 17028 bytes ...ompletionInsertsNamespaceQualifiersInVSCode.gif | Bin 0 -> 110759 bytes docs/clangd/DeveloperDocumentation.rst | 29 ++ docs/clangd/DiagnosticsInEmacsEglot.png | Bin 0 -> 16634 bytes docs/clangd/ErrorsInVSCode.png | Bin 0 -> 76993 bytes docs/clangd/Extensions.rst | 173 ++++++++++ docs/clangd/Features.rst | 231 +++++++++++++ docs/clangd/FindAllReferencesInVSCode.gif | Bin 0 -> 76027 bytes docs/clangd/FormatSelectionInVSCode.gif | Bin 0 -> 167887 bytes docs/clangd/GoToDefinitionInVSCode.gif | Bin 0 -> 123395 bytes docs/clangd/Installation.rst | 369 +++++++++++++++++++++ docs/clangd/NavigationWithBreadcrumbsInVSCode.gif | Bin 0 -> 123365 bytes docs/clangd/OutlineInVSCode.png | Bin 0 -> 15443 bytes docs/clangd/SignatureHelpInVSCode.gif | Bin 0 -> 36923 bytes docs/clangd/index.rst | 189 +---------- docs/conf.py | 2 +- docs/index.rst | 1 + 24 files changed, 848 insertions(+), 172 deletions(-) create mode 100644 docs/_static/clang-tools-extra-styles.css create mode 100644 docs/_templates/layout.html create mode 100644 docs/clangd/ApplyClangTidyFixInVSCode.gif create mode 100644 docs/clangd/ApplyFixInVSCode.gif create mode 100644 docs/clangd/CodeCompletionInEmacsCompanyMode.png create mode 100644 docs/clangd/CodeCompletionInSublimeText.png create mode 100644 docs/clangd/CodeCompletionInVSCode.png create mode 100644 docs/clangd/CodeCompletionInYCM.png create mode 100644 docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif create mode 100644 docs/clangd/DeveloperDocumentation.rst create mode 100644 docs/clangd/DiagnosticsInEmacsEglot.png create mode 100644 docs/clangd/ErrorsInVSCode.png create mode 100644 docs/clangd/Extensions.rst create mode 100644 docs/clangd/Features.rst create mode 100644 docs/clangd/FindAllReferencesInVSCode.gif create mode 100644 docs/clangd/FormatSelectionInVSCode.gif create mode 100644 docs/clangd/GoToDefinitionInVSCode.gif create mode 100644 docs/clangd/Installation.rst create mode 100644 docs/clangd/NavigationWithBreadcrumbsInVSCode.gif create mode 100644 docs/clangd/OutlineInVSCode.png create mode 100644 docs/clangd/SignatureHelpInVSCode.gif diff --git a/docs/_static/clang-tools-extra-styles.css b/docs/_static/clang-tools-extra-styles.css new file mode 100644 index 00000000..1a6cd710 --- /dev/null +++ b/docs/_static/clang-tools-extra-styles.css @@ -0,0 +1,23 @@ +details { + background-color: rgba(50, 150, 220, 0.08); + margin-bottom: 0.5em; + padding: 0 1em; + overflow-y: hidden; /* Suppress margin-collapsing */ +} +details[open] { + border-bottom: 1px solid rgba(0, 0, 128, 0.2); + margin-bottom: 1em; +} +details summary { + font-weight: bold; + background-color: rgba(50, 150, 220, 0.1); + border-color: rgba(0, 0, 128, 0.2); + border-width: 1px; + border-style: solid none; + padding: 0.2em; + margin: 0 -1em; +} +details summary:hover { + background-color: rgba(50, 150, 220, 0.2); + cursor: pointer; +} diff --git a/docs/_templates/layout.html b/docs/_templates/layout.html new file mode 100644 index 00000000..b4f5b4e1 --- /dev/null +++ b/docs/_templates/layout.html @@ -0,0 +1,3 @@ +{% extends "!layout.html" %} + +{% set css_files = css_files + ['_static/clang-tools-extra-styles.css'] %} diff --git a/docs/clangd/ApplyClangTidyFixInVSCode.gif b/docs/clangd/ApplyClangTidyFixInVSCode.gif new file mode 100644 index 00000000..b07bdeb4 Binary files /dev/null and b/docs/clangd/ApplyClangTidyFixInVSCode.gif differ diff --git a/docs/clangd/ApplyFixInVSCode.gif b/docs/clangd/ApplyFixInVSCode.gif new file mode 100644 index 00000000..929a98c3 Binary files /dev/null and b/docs/clangd/ApplyFixInVSCode.gif differ diff --git a/docs/clangd/CodeCompletionInEmacsCompanyMode.png b/docs/clangd/CodeCompletionInEmacsCompanyMode.png new file mode 100644 index 00000000..1accc5af Binary files /dev/null and b/docs/clangd/CodeCompletionInEmacsCompanyMode.png differ diff --git a/docs/clangd/CodeCompletionInSublimeText.png b/docs/clangd/CodeCompletionInSublimeText.png new file mode 100644 index 00000000..b09fed3b Binary files /dev/null and b/docs/clangd/CodeCompletionInSublimeText.png differ diff --git a/docs/clangd/CodeCompletionInVSCode.png b/docs/clangd/CodeCompletionInVSCode.png new file mode 100644 index 00000000..bc42e9dd Binary files /dev/null and b/docs/clangd/CodeCompletionInVSCode.png differ diff --git a/docs/clangd/CodeCompletionInYCM.png b/docs/clangd/CodeCompletionInYCM.png new file mode 100644 index 00000000..b74508d6 Binary files /dev/null and b/docs/clangd/CodeCompletionInYCM.png differ diff --git a/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif b/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif new file mode 100644 index 00000000..f0d49d63 Binary files /dev/null and b/docs/clangd/CodeCompletionInsertsNamespaceQualifiersInVSCode.gif differ diff --git a/docs/clangd/DeveloperDocumentation.rst b/docs/clangd/DeveloperDocumentation.rst new file mode 100644 index 00000000..75843279 --- /dev/null +++ b/docs/clangd/DeveloperDocumentation.rst @@ -0,0 +1,29 @@ +================================== +Developer documentation for clangd +================================== + +.. toctree:: + :maxdepth: 1 + + Extensions + +Compiling clangd +================ + +To build clangd from source, please follow the instructions for `building Clang +`_ and include LLVM, Clang, and the +"extra Clang tools" in your build. + +Contributing to clangd +====================== + +A good place for interested contributors is the `Clangd developer mailing list +`_. For discussions with +the broader community on topics not only related to Clangd, use `Clang +developer mailing list `_. If +you're also interested in contributing patches to clangd, take a look at the +`LLVM Developer Policy `_ and `Code +Reviews `_ page. Contributions of new +features to the `Language Server Protocol +`_ itself would also be +very useful, so that clangd can eventually implement them in a conforming way. diff --git a/docs/clangd/DiagnosticsInEmacsEglot.png b/docs/clangd/DiagnosticsInEmacsEglot.png new file mode 100644 index 00000000..f5be84bf Binary files /dev/null and b/docs/clangd/DiagnosticsInEmacsEglot.png differ diff --git a/docs/clangd/ErrorsInVSCode.png b/docs/clangd/ErrorsInVSCode.png new file mode 100644 index 00000000..52de4029 Binary files /dev/null and b/docs/clangd/ErrorsInVSCode.png differ diff --git a/docs/clangd/Extensions.rst b/docs/clangd/Extensions.rst new file mode 100644 index 00000000..4ff05250 --- /dev/null +++ b/docs/clangd/Extensions.rst @@ -0,0 +1,173 @@ +=================== +Protocol extensions +=================== + +clangd supports some features that are not in the official +`Language Server Protocol specification +`__. + +We cautious about adding extensions. The most important considerations are: + +- **Editor support**: How many users will the feature be available to? +- **Standardization**: Is the feature stable? Is it likely to be adopted by more + editors over time? +- **Utility**: Does the feature provide a lot of value? +- **Complexity**: Is this hard to implement in clangd, or constrain future work? + Is the protocol complicated? + +These extensions may evolve or disappear over time. If you use them, try to +recover gracefully if the structures aren't what's expected. + +Switch between the implementation file and the header +===================================================== + +*This extension is supported in clangd 6 and newer.* + +Switching between the implementation file and the header is an important +feature for C++. A language server that understands C++ can do a better job +than the editor. + +**New client->server request**: ``textDocument/switchSourceHeader``. + +Lets editors switch between the main source file (``*.cpp``) and header (``*.h``). + +Parameter: ``TextDocumentIdentifier``: an open file. + +Result: ``string``: the URI of the corresponding header (if a source file was +provided) or source file (if a header was provided). + +If the corresponding file can't be determined, ``""`` is returned. + +File status +=========== + +*This extension is supported in clangd 8 and newer.* + +It is important to provide feedback to the user when the UI is not responsive. + +This extension provides information about activity on clangd's per-file worker +thread. This information can be displayed to users to let them know that the +language server is busy with something. For example, in clangd, building the +AST blocks many other operations. + +**New server->client notification**: ``textDocument/clangd.fileStatus`` + +Sent when the current activity for a file changes. Replaces previous activity +for that file. + +Parameter: ``FileStatus`` object with properties: + +- ``uri : string``: the document whose status is being updated. +- ``state : string``: human-readable information about current activity. + +**New initialization option**: ``initializationOptions.clangdFileStatus : bool`` + +Enables receiving ``textDocument/clangd.fileStatus`` notifications. + +Compilation commands +==================== + +*This extension is supported in clangd 8 and newer.* + +clangd relies on knowing accurate compilation options to correctly interpret a +file. Typically they are found in a ``compile_commands.json`` file in a +directory that contains the file, or an ancestor directory. The following +extensions allow editors to supply the commands over LSP instead. + +**New initialization option**: ``initializationOptions.compilationDatabasePath : string`` + +Specifies the directory containing the compilation database (e.g., +``compile_commands.json``). This path will be used for all files, instead of +searching their ancestor directories. + +**New initialization option**: ``initializationOptions.fallbackFlags : string[]`` + +Controls the flags used when no specific compile command is found. The compile +command will be approximately ``clang $FILE $fallbackFlags`` in this case. + +**New configuration setting**: ``settings.compilationDatabaseChanges : {string: CompileCommand}`` + +Provides compile commands for files. This can also be provided on startup as +``initializationOptions.compilationDatabaseChanges``. + +Keys are file paths (Not URIs!) + +Values are ``{workingDirectory: string, compilationCommand: string[]}``. + +Force diagnostics generation +============================ + +*This extension is supported in clangd 7 and newer.* + +Clangd does not regenerate diagnostics for every version of a file (e.g., after +every keystroke), as that would be too slow. Its heuristics ensure: + +- diagnostics do not get too stale, +- if you stop editing, diagnostics will catch up. + +This extension allows editors to force diagnostics to be generated or not +generated at a particular revision. + +**New property of** ``textDocument/didChange`` **request**: ``wantDiagnostics : bool`` + +- if true, diagnostics will be produced for exactly this version. +- if false, diagnostics will not be produced for this version, even if there + are no further edits. +- if unset, diagnostics will be produced for this version or some subsequent + one in a bounded amount of time. + +Diagnostic categories +===================== + +*This extension is supported in clangd 8 and newer.* + +Clang compiler groups diagnostics into categories (e.g., "Inline Assembly +Issue"). Clangd can emit these categories for interested editors. + +**New property of** ``Diagnostic`` **object**: ``category : string``: + +A human-readable name for a group of related diagnostics. Diagnostics with the +same code will always have the same category. + +**New client capability**: ``textDocument.publishDiagnostics.categorySupport``: + +Requests that clangd send ``Diagnostic.category``. + +Inline fixes for diagnostics +============================ + +*This extension is supported in clangd 8 and newer.* + +LSP specifies that code actions for diagnostics (fixes) are retrieved +asynchronously using ``textDocument/codeAction``. clangd always computes fixes +eagerly. Providing them alongside diagnostics can improve the UX in editors. + +**New property of** ``Diagnostic`` **object**: ``codeActions : CodeAction[]``: + +All the code actions that address this diagnostic. + +**New client capability**: ``textDocument.publishDiagnostics.codeActionsInline : bool`` + +Requests clangd to send ``Diagnostic.codeActions``. + +Symbol info request +=================== + +*This extension is supported in clangd 8 and newer.* + +**New client->server request**: ``textDocument/symbolInfo``: + +This request attempts to resolve the symbol under the cursor, without +retrieving further information (like definition location, which may require +consulting an index). This request was added to support integration with +indexes outside clangd. + +Parameter: ``TextDocumentPositionParams`` + +Response: ``SymbolDetails``, an object with properties: + +- ``name : string`` the unqualified name of the symbol +- ``containerName : string`` the enclosing namespace, class etc (without + trailing ``::``) +- ``usr : string``: the clang-specific "unified symbol resolution" identifier +- ``id : string?``: the clangd-specific opaque symbol ID diff --git a/docs/clangd/Features.rst b/docs/clangd/Features.rst new file mode 100644 index 00000000..f6a8c501 --- /dev/null +++ b/docs/clangd/Features.rst @@ -0,0 +1,231 @@ +======== +Features +======== + +.. role:: raw-html(raw) + :format: html + +Here is what clangd can do for you. Screenshots below show `VSCode +`__; the available features and UI depend on +the editor. + +Errors and warnings +=================== + +clangd runs the clang compiler on your code as you type, and shows errors and +warnings in-place. Some errors are suppressed: diagnostics that require +expanding templates in headers are disabled for performance reasons. + +:raw-html:`
Screenshot` + +.. image:: ErrorsInVSCode.png + :align: center + :alt: Demonstration of errors + +:raw-html:`
` + +Fixes in errors and warnings +---------------------------- + +The compiler can suggest fixes for many common problems automatically, and +clangd can update the code for you. + +:raw-html:`
Animated demo` + +.. image:: ApplyFixInVSCode.gif + :align: center + :alt: Applying a fix suggested by the compiler + +:raw-html:`
` + +Code completion +=============== + +You'll see suggestions as you type based on what methods, variables, etc are +available in this context. + +:raw-html:`
Screenshot` + +.. image:: CodeCompletionInVSCode.png + :align: center + :alt: Code completion demonstration + +:raw-html:`
` + +Abbreviating words may help you find the right result faster. If you type in +``camelCase`` but the function you're looking for is ``snake_case``, that's OK. + +Insertion of namespace qualifiers and includes +---------------------------------------------- + +**(New in v8)** +clangd will sometimes suggest results from other files and namespaces. In this +case the correct qualifier and ``#include`` directive will be inserted. + +:raw-html:`
Animated demo` + +.. image:: CodeCompletionInsertsNamespaceQualifiersInVSCode.gif + :align: center + :alt: Code completion inserts namespace qualifiers + +:raw-html:`
` + +Signature help +-------------- + +Some editors will show you the parameters of the function you're calling, as +you fill them in. + +:raw-html:`
Animated demo` + +.. image:: SignatureHelpInVSCode.gif + :align: center + :alt: Demonstration of the signature help feature + +:raw-html:`
` + +Cross-references +================ + +The following features let you navigate your codebase. + +If there is no project-wide index, cross-references work across the files +you have opened. + +Find definition/declaration +--------------------------- + +Jump to the definition or declaration of a symbol under the cursor. + +:raw-html:`
Animated demo` + +.. image:: GoToDefinitionInVSCode.gif + :align: center + :alt: Demonstration of the "Go to definition" feature + +:raw-html:`
` + +Find references +--------------- + +Show all references to a symbol under the cursor. + +:raw-html:`
Animated demo` + +.. image:: FindAllReferencesInVSCode.gif + :align: center + :alt: Demonstration of the "Find all references" feature + +:raw-html:`
` + +Some editors will automatically highlight local references to the selected +symbol as you move around a file. + +Navigation +========== + +clangd informs the editor of the code structure in the current file. +Some editors use this to present an outline view: + +:raw-html:`
Screenshot` + +.. image:: OutlineInVSCode.png + :align: center + :alt: Outline of a file + +:raw-html:`
` + +In VSCode, the outline is also presented as breadcrumbs that allow jumping to a +symbol within the current file. Searching for symbols within the scope of the +whole project is also possible. + +:raw-html:`
Animated demo` + +.. image:: NavigationWithBreadcrumbsInVSCode.gif + :align: center + :alt: Navigation with breadcrumbs + +:raw-html:`
` + +Formatting +========== + +clangd embeds `clang-format `__, +which can reformat your code: fixing indentation, breaking lines, and reflowing +comments. + +:raw-html:`
Animated demo` + +.. image:: FormatSelectionInVSCode.gif + :align: center + :alt: Formatting selected code + +:raw-html:`
` + +clangd respects your project's ``.clang-format`` file which controls styling +options. + +Format-as-you-type is experimental and doesn't work well yet. + +Complete list of features +========================= + +Here is a list of features that could be useful for editors, together with the +implementation status in clangd, and specification in the Language Server +Protocol. + +It is not clear whether or not some of the features mentioned below should be a +part of the Language Server Protocol; those features might be eventually +developed outside clangd or become clangd extensions to LSP. + ++-------------------------------------+------------+----------+ +| C/C++ Editor feature | LSP | Clangd | ++=====================================+============+==========+ +| Formatting | Yes | Yes | ++-------------------------------------+------------+----------+ +| Completion | Yes | Yes | ++-------------------------------------+------------+----------+ +| Diagnostics | Yes | Yes | ++-------------------------------------+------------+----------+ +| Fix-its | Yes | Yes | ++-------------------------------------+------------+----------+ +| Go to Definition | Yes | Yes | ++-------------------------------------+------------+----------+ +| Signature Help | Yes | Yes | ++-------------------------------------+------------+----------+ +| Document Highlights | Yes | Yes | ++-------------------------------------+------------+----------+ +| Rename | Yes | Yes | ++-------------------------------------+------------+----------+ +| Source hover | Yes | Yes | ++-------------------------------------+------------+----------+ +| Find References | Yes | Yes | ++-------------------------------------+------------+----------+ +| Document Symbols | Yes | Yes | ++-------------------------------------+------------+----------+ +| Workspace Symbols | Yes | Yes | ++-------------------------------------+------------+----------+ +| Code Lens | Yes | No | ++-------------------------------------+------------+----------+ +| Code folding | Yes | No | ++-------------------------------------+------------+----------+ +| Extract Local Variable | Yes | No | ++-------------------------------------+------------+----------+ +| Extract Function/Method | Yes | No | ++-------------------------------------+------------+----------+ +| Quick Assist | Yes | No | ++-------------------------------------+------------+----------+ +| Hide Method | Yes | No | ++-------------------------------------+------------+----------+ +| Implement Method | Yes | No | ++-------------------------------------+------------+----------+ +| Gen. Getters/Setters | Yes | No | ++-------------------------------------+------------+----------+ +| Syntax and Semantic Coloring | No | No | ++-------------------------------------+------------+----------+ +| Call hierarchy | No | No | ++-------------------------------------+------------+----------+ +| Type hierarchy | No | No | ++-------------------------------------+------------+----------+ +| Organize Includes | No | No | ++-------------------------------------+------------+----------+ diff --git a/docs/clangd/FindAllReferencesInVSCode.gif b/docs/clangd/FindAllReferencesInVSCode.gif new file mode 100644 index 00000000..b9eecf3c Binary files /dev/null and b/docs/clangd/FindAllReferencesInVSCode.gif differ diff --git a/docs/clangd/FormatSelectionInVSCode.gif b/docs/clangd/FormatSelectionInVSCode.gif new file mode 100644 index 00000000..1d4be410 Binary files /dev/null and b/docs/clangd/FormatSelectionInVSCode.gif differ diff --git a/docs/clangd/GoToDefinitionInVSCode.gif b/docs/clangd/GoToDefinitionInVSCode.gif new file mode 100644 index 00000000..396966f7 Binary files /dev/null and b/docs/clangd/GoToDefinitionInVSCode.gif differ diff --git a/docs/clangd/Installation.rst b/docs/clangd/Installation.rst new file mode 100644 index 00000000..2daf42ba --- /dev/null +++ b/docs/clangd/Installation.rst @@ -0,0 +1,369 @@ +=========================== +Getting started with clangd +=========================== + +.. role:: raw-html(raw) + :format: html + +To use clangd, you need to: + +- install clangd, +- install a plugin for your editor, +- tell clangd how your project is built. + +Installing clangd +================= + +You need a **recent** version of clangd: 7.0 was the first usable release, and +8.0 is much better. + +After installing, ``clangd --version`` should print ``clangd version 7.0.0`` or +later. + +:raw-html:`
macOS` + +`Homebrew `__ can install clangd along with LLVM: + +.. code-block:: console + + $ brew install llvm + +If you don't want to use Homebrew, you can download the a binary release of +LLVM from `releases.llvm.org `__. +Alongside ``bin/clangd`` you will need at least ``lib/clang/*/include``: + +.. code-block:: console + + $ cp clang+llvm-7.0.0/bin/clangd /usr/local/bin/clangd + $ cp -r clang+llvm-7.0.0/lib/clang/ /usr/local/lib/ + +:raw-html:`
` + +:raw-html:`
Windows` + +Download and run the LLVM installer from `releases.llvm.org +`__. + +:raw-html:`
` + +:raw-html:`
Debian/Ubuntu` + +The ``clang-tools`` package usually contains an old version of clangd. + +Try to install the latest release (8.0): + +.. code-block:: console + + $ sudo apt-get install clang-tools-8 + +If that is not found, at least ``clang-tools-7`` should be available. + +The ``clangd`` executable will be installed as ``/usr/bin/clangd-8``. Make it +the default ``clangd``: + +.. code-block:: console + + $ sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-8 100 + +:raw-html:`
` + +:raw-html:`
Other systems` + +Most distributions include clangd in a ``clang-tools`` package, or in the full +``llvm`` distribution. + +For some platforms, binaries are also avaliable at `releases.llvm.org +`__. + +:raw-html:`
` + +Editor plugins +============== + +Language Server plugins are available for many editors. In principle, clangd +should work with any of them, though the feature set and UI may vary. + +Here are some plugins we know work well with clangd. + +:raw-html:`
YouCompleteMe for Vim` + +`YouCompleteMe `__ supports clangd. +However, clangd support is not turned on by default, so you must install +YouCompleteMe with ``install.py --clangd-completer``. + +We recommend changing a couple of YCM's default settings. In ``.vimrc`` add: + +:: + + " Let clangd fully control code completion + let g:ycm_clangd_uses_ycmd_caching = 0 + " Use installed clangd, not YCM-bundled clangd which doesn't get updates. + let g:ycm_clangd_binary_path = exepath("clangd") + +You should see errors highlighted and code completions as you type. + +.. image:: CodeCompletionInYCM.png + :align: center + :alt: Code completion in YouCompleteMe + +YouCompleteMe supports many of clangd's features: + +- code completion, +- diagnostics and fixes (``:YcmCompleter FixIt``), +- find declarations, references, and definitions (``:YcmCompleter GoTo`` etc), +- rename symbol (``:YcmCompleter RefactorRename``). + +**Under the hood** + +- **Debug logs**: run ``:YcmDebugInfo`` to see clangd status, and ``:YcmToggleLogs`` + to view clangd's debug logs. +- **Command-line flags**: Set ``g:ycm_clangd_args`` in ``.vimrc``, e.g.: + + :: + + let g:ycm_clangd_args = ['-log=verbose', '-pretty'] + +- **Alternate clangd binary**: set ``g:ycm_clangd_binary_path`` in ``.vimrc``. + +:raw-html:`
` + +:raw-html:`
LanguageClient for Vim and Neovim` + +`LanguageClient-neovim `__ +has `instructions for using clangd +`__, and **may** +be easier to install than YouCompleteMe. + +:raw-html:`
` + +:raw-html:`
Eglot for Emacs` + +`eglot `__ can be configured to work with +clangd. + +Install eglot with ``M-x package-install RET eglot RET``. + +Add the following to ``~/.emacs`` to enable clangd: + +:: + + (require 'eglot) + (add-to-list 'eglot-server-programs '((c++-mode c-mode) "clangd")) + (add-hook 'c-mode-hook 'eglot-ensure) + (add-hook 'c++-mode-hook 'eglot-ensure) + +After restarting you should see diagnostics for errors in your code, and ``M-x +completion-at-point`` should work. + +.. image:: DiagnosticsInEmacsEglot.png + :align: center + :alt: Diagnostics in Emacs + +eglot supports many of clangd's features, with caveats: + +- code completion, though the interaction is quite poor (even with + ``company-mode``, see below), +- diagnostics and fixes, +- find definitions and references (``M-x xref-find-definitions`` etc), +- hover and highlights, +- code actions (``M-x eglot-code-actions``). + +**company-mode** + +eglot does have basic integration with company-mode, which provides a more +fluent completion UI. + +You can install it with ``M-x package-install RET company RET``, and enable it +with ``M-x company-mode``. + +**company-clang is enabled by default**, and will interfere with clangd. +Disable it in ``M-x customize-variable RET company-backends RET``. + +Completion still has some major limitations: + +- completions are alphabetically sorted, not ranked. +- only pure-prefix completions are shown - no fuzzy matches. +- completion triggering seems to be a bit hit-and-miss. + +.. image:: CodeCompletionInEmacsCompanyMode.png + :align: center + :alt: Completion in company-mode + +**Under the hood** + +- **Debug logs**: available in the ``EGLOT stderr`` buffer. +- **Command-line flags and alternate binary**: instead of adding ``"clangd"`` + to ``eglot-server-programs``, add ``("/path/to/clangd" "-log=verbose")`` etc. + +:raw-html:`
` + +:raw-html:`
Visual Studio Code` + +The official extension is `vscode-clangd +`__ +and can be installed from within VSCode. + +Choose **View** --> **Extensions**, then search for "clangd". (Make sure the +Microsoft C/C++ extension is **not** installed). + +After restarting, you should see red underlines underneath errors, and you +should get rich code completions including e.g. function parameters. + +.. image:: CodeCompletionInVSCode.png + :align: center + :alt: Code completion in VSCode + +vscode-clangd has excellent support for all clangd features, including: + +- code completion +- diagnostics and fixes +- find declarations, references, and definitions +- find symbol in file (``Ctrl-P @foo``) or workspace (``Ctrl-P #foo``) +- hover and highlights +- code actions + +**Under the hood** + +- **Debug logs**: when clangd is running, you should see "Clang Language + Server" in the dropdown of the Output panel (**View** -> **Output**). + +- **Command-line flags**: these can be passed in the ``clangd.arguments`` array + in your ``settings.json``. (**File** -> **Preferences** -> **Settings**). + +- **Alternate clangd binary**: set the ``clangd.path`` string in + ``settings.json``. + +:raw-html:`
` + +:raw-html:`
Sublime Text` + +`tomv564/LSP `__ works with clangd out of the box. + +Select **Tools** --> **Install Package Control** (if you haven't installed it +yet). + +Press ``Ctrl-Shift-P`` and select **Package Control: Install Package**. Select +**LSP**. + +Press ``Ctrl-Shift-P`` and select **LSP: Enable Language Server Globally**. +Select **clangd**. + +Open a C++ file, and you should see diagnostics and completion: + +.. image:: CodeCompletionInSublimeText.png + :align: center + :alt: Code completion in Sublime Text + + +The LSP package has excellent support for all most clangd features, including: + +- code completion (a bit noisy due to how snippets are presented) +- diagnostics and fixes +- find definition and references +- hover and highlights +- code actions + +**Under the hood** + +Settings can be tweaked under **Preferences** --> **Package Settings** --> +**LSP**. + +- **Debug logs**: add ``"log_stderr": true`` +- **Command-line flags and alternate clangd binary**: inside the ``"clients": + {"clangd": { ... } }`` section, add ``"command": ["/path/to/clangd", + "-log=verbose"]`` etc. + +:raw-html:`
` + +:raw-html:`
Other editors` + +There is a directory of LSP clients at `langserver.org +`__. + +A generic client should be configured to run the command ``clangd``, and +communicate via the language server protocol on standard input/output. + +If you don't have strong feelings about an editor, we suggest you try out +`VSCode `__, it has excellent language server +support and most faithfully demonstrates what clangd can do. + +:raw-html:`
` + +Project setup +============= + +To understand source code in your project, clangd needs to know the build +flags. (This is just a fact of life in C++, source files are not +self-contained.) + +By default, clangd will assume that source code is built as ``clang +some_file.cc``, and you'll probably get spurious errors about missing +``#include``\ d files, etc. There are a couple of ways to fix this. + +``compile_commands.json`` +------------------------- + +``compile_commands.json`` file provides compile commands for all source files +in the project. This file is usually generated by the build system, or tools +integrated with the build system. Clangd will look for this file in the parent +directories of the files you edit. + +:raw-html:`
CMake-based projects` + +If your project builds with CMake, it can generate ``compile_commands.json``. +You should enable it with: + +:: + + $ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=1 + +``compile_commands.json`` will be written to your build directory. You should +symlink it (or copy it) to the root of your source tree, if they are different. + +:: + + $ ln -s ~/myproject/compile_commands.json ~/myproject-build/ + +:raw-html:`
` + +:raw-html:`
Other build systems, using Bear` + +`Bear `__ is a tool that generates a +``compile_commands.json`` file by recording a complete build. + +For a ``make``-based build, you can run ``make clean; bear make`` to generate the +file (and run a clean build!) + +:raw-html:`
` + +Other tools can also generate this file. See `the compile_commands.json +specification `__. + +``compile_flags.txt`` +--------------------- + +If all files in a project use the same build flags, you can put those flags, +one flag per line, in ``compile_flags.txt`` in your source root. + +Clangd will assume the compile command is ``clang $FLAGS some_file.cc``. + +Creating this file by hand is a reasonable place to start if your project is +quite simple. + +Project-wide Index +================== + +By default clangd only has a view on symbols coming from files you are +currently editing. You can extend this view to whole project by providing a +project-wide index to clangd. There are two ways to do this. + +- Pass an experimental `-background-index` command line argument. With + this feature enabled, clangd incrementally builds an index of projects + that you work on and uses the just-built index automatically. + +- Generate an index file using `clangd-indexer + `__ + Then you can pass generated index file to clangd using + `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't + included alongside clangd in the Debian clang-tools package. You will + likely have to build clangd from source to use this option.* diff --git a/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif b/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif new file mode 100644 index 00000000..499f5c1a Binary files /dev/null and b/docs/clangd/NavigationWithBreadcrumbsInVSCode.gif differ diff --git a/docs/clangd/OutlineInVSCode.png b/docs/clangd/OutlineInVSCode.png new file mode 100644 index 00000000..570a80de Binary files /dev/null and b/docs/clangd/OutlineInVSCode.png differ diff --git a/docs/clangd/SignatureHelpInVSCode.gif b/docs/clangd/SignatureHelpInVSCode.gif new file mode 100644 index 00000000..e5700f22 Binary files /dev/null and b/docs/clangd/SignatureHelpInVSCode.gif differ diff --git a/docs/clangd/index.rst b/docs/clangd/index.rst index c8719059..46939062 100644 --- a/docs/clangd/index.rst +++ b/docs/clangd/index.rst @@ -1,180 +1,27 @@ -============ -Clangd -============ - -.. contents:: +====== +clangd +====== .. toctree:: :maxdepth: 1 -:program:`Clangd` is an implementation of the `Language Server Protocol -`_ leveraging Clang. -Clangd's goal is to provide language "smartness" features like code completion, -find references, etc. for clients such as C/C++ Editors. - -Using Clangd -================== - -:program:`Clangd` is not meant to be used by C/C++ developers directly but -rather from a client implementing the protocol. A client would be typically -implemented in an IDE or an editor. - -At the moment, `Visual Studio Code `_ is mainly -used in order to test :program:`Clangd` but more clients are likely to make -use of :program:`Clangd` in the future as it matures and becomes a production -quality tool. If you are interested in trying :program:`Clangd` in combination -with Visual Studio Code, you can start by `installing Clangd`_ or -`building Clangd`_, then open Visual Studio Code in the clangd-vscode folder and -launch the extension. - -Installing Clangd -================== - -Packages are available for debian-based distributions, see the `LLVM packages -page `_. :program:`Clangd` is included in the -`clang-tools` package. -However, it is a good idea to check your distribution's packaging system first -as it might already be available. - -Otherwise, you can install :program:`Clangd` by `building Clangd`_ first. - -Building Clangd -================== - -You can follow the instructions for `building Clang -`_ but "extra Clang tools" is **not** -optional. - -Current Status -================== - -Many features could be implemented in :program:`Clangd`. -Here is a list of features that could be useful with the status of whether or -not they are already implemented in :program:`Clangd` and specified in the -Language Server Protocol. Note that for some of the features, it is not clear -whether or not they should be part of the Language Server Protocol, so those -features might be eventually developed outside :program:`Clangd` or as an -extension to the protocol. - -+-------------------------------------+------------+----------+ -| C/C++ Editor feature | LSP | Clangd | -+=====================================+============+==========+ -| Formatting | Yes | Yes | -+-------------------------------------+------------+----------+ -| Completion | Yes | Yes | -+-------------------------------------+------------+----------+ -| Diagnostics | Yes | Yes | -+-------------------------------------+------------+----------+ -| Fix-its | Yes | Yes | -+-------------------------------------+------------+----------+ -| Go to Definition | Yes | Yes | -+-------------------------------------+------------+----------+ -| Signature Help | Yes | Yes | -+-------------------------------------+------------+----------+ -| Document Highlights | Yes | Yes | -+-------------------------------------+------------+----------+ -| Rename | Yes | Yes | -+-------------------------------------+------------+----------+ -| Source hover | Yes | Yes | -+-------------------------------------+------------+----------+ -| Find References | Yes | Yes | -+-------------------------------------+------------+----------+ -| Document Symbols | Yes | Yes | -+-------------------------------------+------------+----------+ -| Workspace Symbols | Yes | Yes | -+-------------------------------------+------------+----------+ -| Code Lens | Yes | No | -+-------------------------------------+------------+----------+ -| Code folding | Yes | No | -+-------------------------------------+------------+----------+ -| Extract Local Variable | Yes | No | -+-------------------------------------+------------+----------+ -| Extract Function/Method | Yes | No | -+-------------------------------------+------------+----------+ -| Quick Assist | Yes | No | -+-------------------------------------+------------+----------+ -| Hide Method | Yes | No | -+-------------------------------------+------------+----------+ -| Implement Method | Yes | No | -+-------------------------------------+------------+----------+ -| Gen. Getters/Setters | Yes | No | -+-------------------------------------+------------+----------+ -| Syntax and Semantic Coloring | No | No | -+-------------------------------------+------------+----------+ -| Call hierarchy | No | No | -+-------------------------------------+------------+----------+ -| Type hierarchy | No | No | -+-------------------------------------+------------+----------+ -| Organize Includes | No | No | -+-------------------------------------+------------+----------+ - -Editor Integration -================== - -Any full-featured Language Server Protocol Client implementation should work -with :program:`Clangd`. This `list -`_ contains information about -extensions and plugins that are known to work for different editors. - -Vim Integration ---------------- - -LanguageClient-neovim -~~~~~~~~~~~~~~~~~~~~~ - -One of the options of using :program:`Clangd` in :program:`vim` (or -:program:`nvim`) is to utilize `LanguageClient-neovim -`_ plugin. Please see the -`Clangd Wiki page -`_ for -instructions. - -VSCode Integration ------------------- - -:program:`VSCode` provides `vscode-clangd -`_ -which is published in Visual Studio Marketplace and can be installed direcetly -from :program:`VSCode`. - -Emacs Integration ------------------ - -:program:`Emacs` provides `lsp-mode `_ and -`Eglot `_ plugins for LSP integration. - -Project-wide Index -================== + Installation + Features -By default :program:`Clangd` only has a view on symbols coming from files you -are currently editing. You can extend this view to whole project by providing a -project-wide index to :program:`Clangd`. +What is clangd? +=============== -There are two ways you can generate a project-wide index for clangd: +clangd understands your C++ code and adds smart features to your editor: code +completion, compile errors, go-to-definition and more. -- Passing experimental `-background-index` commandline argument, which will - incrementally build an index of projects that you work on and make use of that - in clangd automatically. -- Generate an index file using `clangd-indexer - `_ - Afterwards you can pass generated index file to clangd using - `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't included - alongside clangd in the standard clang-tools package. You will likely have to - build from source to use this option* +clangd is a language server that implements the `Language Server Protocol +`__; it can work with +many editors through a plugin. Here's Visual Studio Code with the clangd +plugin, demonstrating code completion: -Getting Involved -================== +.. image:: CodeCompletionInVSCode.png + :align: center + :alt: Code completion in VSCode -A good place for interested contributors is the `Clangd developer mailing list -`_. For discussions with the -broader community on topics not only related to Clangd, use -`Clang developer mailing list -`_. -If you're also interested in contributing patches to :program:`Clangd`, take a -look at the `LLVM Developer Policy -`_ and `Code Reviews -`_ page. Contributions of new features -to the `Language Server Protocol -`_ itself would also be -very useful, so that :program:`Clangd` can eventually implement them in a -conforming way. +clangd is based on the `Clang `__ C++ compiler, and is +part of the `LLVM `__ project. diff --git a/docs/conf.py b/docs/conf.py index a79558f0..16e81051 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -121,7 +121,7 @@ html_theme = 'haiku' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = [] +html_static_path = ['_static'] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. diff --git a/docs/index.rst b/docs/index.rst index 8fae25c4..86ba5cb7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -21,6 +21,7 @@ Contents pp-trace clang-rename clangd/index + clangd/DeveloperDocumentation clang-doc -- cgit v1.2.3 From 0b9bba1a26c3862a0d6ac24bba7fb8b1a15f5c80 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Wed, 27 Feb 2019 16:08:04 +0000 Subject: Added documentation for clangd v9+ features Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58717 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@354994 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd/Features.rst | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/clangd/Features.rst b/docs/clangd/Features.rst index f6a8c501..cb7a6251 100644 --- a/docs/clangd/Features.rst +++ b/docs/clangd/Features.rst @@ -38,6 +38,30 @@ clangd can update the code for you. :raw-html:`` +**(New in v9)** +If a missing symbol was seen in a file you've edited recently, clangd will +suggest inserting it. + +clang-tidy checks +----------------- + +**(New in v9)** +clangd embeds `clang-tidy `__ +which provides extra hints about code problems: bug-prone patterns, +performance traps, and style issues. + +:raw-html:`
Animated demo` + +.. image:: ApplyClangTidyFixInVSCode.gif + :align: center + :alt: Applying a fix suggested by the compiler + +:raw-html:`
` + +clangd respects your project's ``.clang-tidy`` file which controls the checks +to run. Not all checks work within clangd. You must pass the ``-clang-tidy`` +flag to enable this feature. + Code completion =============== @@ -92,6 +116,9 @@ The following features let you navigate your codebase. If there is no project-wide index, cross-references work across the files you have opened. +**(New in v9)** +clangd will also automatically index your whole project. + Find definition/declaration --------------------------- @@ -105,6 +132,13 @@ Jump to the definition or declaration of a symbol under the cursor. :raw-html:`` +**(New in v9)** +Some editors only expose "find definition"; use "find definition" on the +definition to jump to the declaration. + +"Find definition" also works on ``#include`` lines, to jump to the included +file. + Find references --------------- -- cgit v1.2.3 From fc6d17626bf9e96abae3d5465923e321ea568c2b Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Wed, 27 Feb 2019 20:08:50 +0000 Subject: [clang-tidy] Add the abseil-time-subtraction check Differential Revision: https://reviews.llvm.org/D58137 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355024 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/AbseilTidyModule.cpp | 3 + clang-tidy/abseil/CMakeLists.txt | 1 + clang-tidy/abseil/DurationRewriter.cpp | 52 ++++++ clang-tidy/abseil/DurationRewriter.h | 10 ++ clang-tidy/abseil/TimeSubtractionCheck.cpp | 181 +++++++++++++++++++++ clang-tidy/abseil/TimeSubtractionCheck.h | 38 +++++ docs/ReleaseNotes.rst | 6 + docs/clang-tidy/checks/abseil-time-subtraction.rst | 37 +++++ docs/clang-tidy/checks/list.rst | 1 + test/clang-tidy/Inputs/absl/time/time.h | 2 + test/clang-tidy/abseil-time-subtraction.cpp | 117 +++++++++++++ 11 files changed, 448 insertions(+) create mode 100644 clang-tidy/abseil/TimeSubtractionCheck.cpp create mode 100644 clang-tidy/abseil/TimeSubtractionCheck.h create mode 100644 docs/clang-tidy/checks/abseil-time-subtraction.rst create mode 100644 test/clang-tidy/abseil-time-subtraction.cpp diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp index 1489b48b..514b7f78 100644 --- a/clang-tidy/abseil/AbseilTidyModule.cpp +++ b/clang-tidy/abseil/AbseilTidyModule.cpp @@ -23,6 +23,7 @@ #include "RedundantStrcatCallsCheck.h" #include "StringFindStartswithCheck.h" #include "StrCatAppendCheck.h" +#include "TimeSubtractionCheck.h" #include "UpgradeDurationConversionsCheck.h" namespace clang { @@ -59,6 +60,8 @@ public: "abseil-str-cat-append"); CheckFactories.registerCheck( "abseil-string-find-startswith"); + CheckFactories.registerCheck( + "abseil-time-subtraction"); CheckFactories.registerCheck( "abseil-upgrade-duration-conversions"); } diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt index 578dd57d..f0616030 100644 --- a/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tidy/abseil/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangTidyAbseilModule RedundantStrcatCallsCheck.cpp StrCatAppendCheck.cpp StringFindStartswithCheck.cpp + TimeSubtractionCheck.cpp UpgradeDurationConversionsCheck.cpp LINK_LIBS diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index c3e40789..ceee2ec8 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -84,6 +84,22 @@ rewriteInverseDurationCall(const MatchFinder::MatchResult &Result, return llvm::None; } +/// If `Node` is a call to the inverse of `Scale`, return that inverse's +/// argument, otherwise None. +static llvm::Optional +rewriteInverseTimeCall(const MatchFinder::MatchResult &Result, + DurationScale Scale, const Expr &Node) { + llvm::StringRef InverseFunction = getTimeInverseForScale(Scale); + if (const auto *MaybeCallArg = selectFirst( + "e", match(callExpr(callee(functionDecl(hasName(InverseFunction))), + hasArgument(0, expr().bind("e"))), + Node, *Result.Context))) { + return tooling::fixit::getText(*MaybeCallArg, *Result.Context).str(); + } + + return llvm::None; +} + /// Returns the factory function name for a given `Scale`. llvm::StringRef getDurationFactoryForScale(DurationScale Scale) { switch (Scale) { @@ -103,6 +119,24 @@ llvm::StringRef getDurationFactoryForScale(DurationScale Scale) { llvm_unreachable("unknown scaling factor"); } +llvm::StringRef getTimeFactoryForScale(DurationScale Scale) { + switch (Scale) { + case DurationScale::Hours: + return "absl::FromUnixHours"; + case DurationScale::Minutes: + return "absl::FromUnixMinutes"; + case DurationScale::Seconds: + return "absl::FromUnixSeconds"; + case DurationScale::Milliseconds: + return "absl::FromUnixMillis"; + case DurationScale::Microseconds: + return "absl::FromUnixMicros"; + case DurationScale::Nanoseconds: + return "absl::FromUnixNanos"; + } + llvm_unreachable("unknown scaling factor"); +} + /// Returns the Time factory function name for a given `Scale`. llvm::StringRef getTimeInverseForScale(DurationScale scale) { switch (scale) { @@ -250,6 +284,24 @@ std::string rewriteExprFromNumberToDuration( .str(); } +std::string rewriteExprFromNumberToTime( + const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, + const Expr *Node) { + const Expr &RootNode = *Node->IgnoreParenImpCasts(); + + // First check to see if we can undo a complimentary function call. + if (llvm::Optional MaybeRewrite = + rewriteInverseTimeCall(Result, Scale, RootNode)) + return *MaybeRewrite; + + if (IsLiteralZero(Result, RootNode)) + return std::string("absl::UnixEpoch()"); + + return (llvm::Twine(getTimeFactoryForScale(Scale)) + "(" + + tooling::fixit::getText(RootNode, *Result.Context) + ")") + .str(); +} + bool isNotInMacro(const MatchFinder::MatchResult &Result, const Expr *E) { if (!E->getBeginLoc().isMacroID()) return true; diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index 54a60f60..5b4689f3 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -31,6 +31,10 @@ enum class DurationScale : std::uint8_t { /// constructing a `Duration` for that scale. llvm::StringRef getDurationFactoryForScale(DurationScale Scale); +/// Given a 'Scale', return the appropriate factory function call for +/// constructing a `Time` for that scale. +llvm::StringRef getTimeFactoryForScale(DurationScale scale); + // Determine if `Node` represents a literal floating point or integral zero. bool IsLiteralZero(const ast_matchers::MatchFinder::MatchResult &Result, const Expr &Node); @@ -81,6 +85,12 @@ std::string rewriteExprFromNumberToDuration( const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, const Expr *Node); +/// Assuming `Node` has a type `int` representing a time instant of `Scale` +/// since The Epoch, return the expression to make it a suitable `Time`. +std::string rewriteExprFromNumberToTime( + const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, + const Expr *Node); + /// Return `true` if `E` is a either: not a macro at all; or an argument to /// one. In the both cases, we often want to do the transformation. bool isNotInMacro(const ast_matchers::MatchFinder::MatchResult &Result, diff --git a/clang-tidy/abseil/TimeSubtractionCheck.cpp b/clang-tidy/abseil/TimeSubtractionCheck.cpp new file mode 100644 index 00000000..0a7c4016 --- /dev/null +++ b/clang-tidy/abseil/TimeSubtractionCheck.cpp @@ -0,0 +1,181 @@ +//===--- TimeSubtractionCheck.cpp - clang-tidy ----------------------------===// +// +// 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 "TimeSubtractionCheck.h" +#include "DurationRewriter.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace abseil { + +// Returns `true` if `Range` is inside a macro definition. +static bool InsideMacroDefinition(const MatchFinder::MatchResult &Result, + SourceRange Range) { + return !clang::Lexer::makeFileCharRange( + clang::CharSourceRange::getCharRange(Range), + *Result.SourceManager, Result.Context->getLangOpts()) + .isValid(); +} + +static bool isConstructorAssignment(const MatchFinder::MatchResult &Result, + const Expr *Node) { + return selectFirst( + "e", match(expr(hasParent(materializeTemporaryExpr(hasParent( + cxxConstructExpr(hasParent(exprWithCleanups( + hasParent(varDecl())))))))) + .bind("e"), + *Node, *Result.Context)) != nullptr; +} + +static bool isArgument(const MatchFinder::MatchResult &Result, + const Expr *Node) { + return selectFirst( + "e", + match(expr(hasParent( + materializeTemporaryExpr(hasParent(cxxConstructExpr( + hasParent(callExpr()), + unless(hasParent(cxxOperatorCallExpr()))))))) + .bind("e"), + *Node, *Result.Context)) != nullptr; +} + +static bool isReturn(const MatchFinder::MatchResult &Result, const Expr *Node) { + return selectFirst( + "e", match(expr(hasParent(materializeTemporaryExpr(hasParent( + cxxConstructExpr(hasParent(exprWithCleanups( + hasParent(returnStmt())))))))) + .bind("e"), + *Node, *Result.Context)) != nullptr; +} + +static bool parensRequired(const MatchFinder::MatchResult &Result, + const Expr *Node) { + // TODO: Figure out any more contexts in which we can omit the surrounding + // parentheses. + return !(isConstructorAssignment(Result, Node) || isArgument(Result, Node) || + isReturn(Result, Node)); +} + +void TimeSubtractionCheck::emitDiagnostic(const Expr *Node, + llvm::StringRef Replacement) { + diag(Node->getBeginLoc(), "perform subtraction in the time domain") + << FixItHint::CreateReplacement(Node->getSourceRange(), Replacement); +} + +void TimeSubtractionCheck::registerMatchers(MatchFinder *Finder) { + for (auto ScaleName : + {"Hours", "Minutes", "Seconds", "Millis", "Micros", "Nanos"}) { + std::string TimeInverse = (llvm::Twine("ToUnix") + ScaleName).str(); + llvm::Optional Scale = getScaleForTimeInverse(TimeInverse); + assert(Scale && "Unknow scale encountered"); + + auto TimeInverseMatcher = callExpr(callee( + functionDecl(hasName((llvm::Twine("::absl::") + TimeInverse).str())) + .bind("func_decl"))); + + // Match the cases where we know that the result is a 'Duration' and the + // first argument is a 'Time'. Just knowing the type of the first operand + // is not sufficient, since the second operand could be either a 'Time' or + // a 'Duration'. If we know the result is a 'Duration', we can then infer + // that the second operand must be a 'Time'. + auto CallMatcher = + callExpr( + callee(functionDecl(hasName(getDurationFactoryForScale(*Scale)))), + hasArgument(0, binaryOperator(hasOperatorName("-"), + hasLHS(TimeInverseMatcher)) + .bind("binop"))) + .bind("outer_call"); + Finder->addMatcher(CallMatcher, this); + + // Match cases where we know the second operand is a 'Time'. Since + // subtracting a 'Time' from a 'Duration' is not defined, in these cases, + // we always know the first operand is a 'Time' if the second is a 'Time'. + auto OperandMatcher = + binaryOperator(hasOperatorName("-"), hasRHS(TimeInverseMatcher)) + .bind("binop"); + Finder->addMatcher(OperandMatcher, this); + } +} + +void TimeSubtractionCheck::check(const MatchFinder::MatchResult &Result) { + const auto *BinOp = Result.Nodes.getNodeAs("binop"); + std::string InverseName = + Result.Nodes.getNodeAs("func_decl")->getNameAsString(); + if (InsideMacroDefinition(Result, BinOp->getSourceRange())) + return; + + llvm::Optional Scale = getScaleForTimeInverse(InverseName); + if (!Scale) + return; + + const auto *OuterCall = Result.Nodes.getNodeAs("outer_call"); + if (OuterCall) { + if (InsideMacroDefinition(Result, OuterCall->getSourceRange())) + return; + + // We're working with the first case of matcher, and need to replace the + // entire 'Duration' factory call. (Which also means being careful about + // our order-of-operations and optionally putting in some parenthesis. + bool NeedParens = parensRequired(Result, OuterCall); + + emitDiagnostic( + OuterCall, + (llvm::Twine(NeedParens ? "(" : "") + + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getLHS()) + " - " + + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getRHS()) + + (NeedParens ? ")" : "")) + .str()); + } else { + // We're working with the second case of matcher, and either just need to + // change the arguments, or perhaps remove an outer function call. In the + // latter case (addressed first), we also need to worry about parenthesis. + const auto *MaybeCallArg = selectFirst( + "arg", match(expr(hasAncestor( + callExpr(callee(functionDecl(hasName( + getDurationFactoryForScale(*Scale))))) + .bind("arg"))), + *BinOp, *Result.Context)); + if (MaybeCallArg && MaybeCallArg->getArg(0)->IgnoreImpCasts() == BinOp && + !InsideMacroDefinition(Result, MaybeCallArg->getSourceRange())) { + // Handle the case where the matched expression is inside a call which + // converts it from the inverse to a Duration. In this case, we replace + // the outer with just the subtraction expresison, which gives the right + // type and scale, taking care again about parenthesis. + bool NeedParens = parensRequired(Result, MaybeCallArg); + + emitDiagnostic( + MaybeCallArg, + (llvm::Twine(NeedParens ? "(" : "") + + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getLHS()) + + " - " + + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getRHS()) + + (NeedParens ? ")" : "")) + .str()); + } else { + // In the last case, just convert the arguments and wrap the result in + // the correct inverse function. + emitDiagnostic( + BinOp, + (llvm::Twine( + getDurationInverseForScale(*Scale).second.str().substr(2)) + + "(" + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getLHS()) + + " - " + + rewriteExprFromNumberToTime(Result, *Scale, BinOp->getRHS()) + ")") + .str()); + } + } +} + +} // namespace abseil +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/abseil/TimeSubtractionCheck.h b/clang-tidy/abseil/TimeSubtractionCheck.h new file mode 100644 index 00000000..4e3cd3b5 --- /dev/null +++ b/clang-tidy/abseil/TimeSubtractionCheck.h @@ -0,0 +1,38 @@ +//===--- TimeSubtractionCheck.h - clang-tidy --------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace abseil { + +/// Finds and fixes `absl::Time` subtraction expressions to do subtraction +/// in the time domain instead of the numeric domain. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-time-subtraction.html +class TimeSubtractionCheck : public ClangTidyCheck { +public: + TimeSubtractionCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + +private: + void emitDiagnostic(const Expr* Node, llvm::StringRef Replacement); +}; + +} // namespace abseil +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMESUBTRACTIONCHECK_H diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index d92cda0b..8d0c8f0a 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -85,6 +85,12 @@ Improvements to clang-tidy Finds and fixes cases where ``absl::Duration`` values are being converted to numeric types and back again. +- New :doc:`abseil-time-subtraction + ` check. + + Finds and fixes ``absl::Time`` subtraction expressions to do subtraction + in the Time domain instead of the numeric domain. + - New :doc:`google-readability-avoid-underscore-in-googletest-name ` check. diff --git a/docs/clang-tidy/checks/abseil-time-subtraction.rst b/docs/clang-tidy/checks/abseil-time-subtraction.rst new file mode 100644 index 00000000..1b68d7c0 --- /dev/null +++ b/docs/clang-tidy/checks/abseil-time-subtraction.rst @@ -0,0 +1,37 @@ +.. title:: clang-tidy - abseil-time-subtraction + +abseil-time-subtraction +======================= + +Finds and fixes ``absl::Time`` subtraction expressions to do subtraction +in the Time domain instead of the numeric domain. + +There are two cases of Time subtraction in which deduce additional type +information: + - When the result is an ``absl::Duration`` and the first argument is an + ``absl::Time``. + - When the second argument is a ``absl::Time``. + +In the first case, we must know the result of the operation, since without that +the second operand could be either an ``absl::Time`` or an ``absl::Duration``. +In the second case, the first operand *must* be an ``absl::Time``, because +subtracting an ``absl::Time`` from an ``absl::Duration`` is not defined. + +Examples: + +.. code-block:: c++ + int x; + absl::Time t; + + // Original - absl::Duration result and first operand is a absl::Time. + absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x); + + // Suggestion - Perform subtraction in the Time domain instead. + absl::Duration d = t - absl::FromUnixSeconds(x); + + + // Original - Second operand is an absl::Time. + int i = x - absl::ToUnixSeconds(t); + + // Suggestion - Perform subtraction in the Time domain instead. + int i = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t); diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 13d8f6fb..42318a53 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -18,6 +18,7 @@ Clang-Tidy Checks abseil-redundant-strcat-calls abseil-str-cat-append abseil-string-find-startswith + abseil-time-subtraction abseil-upgrade-duration-conversions android-cloexec-accept android-cloexec-accept4 diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h index 8da3c2c3..9c6c3aee 100644 --- a/test/clang-tidy/Inputs/absl/time/time.h +++ b/test/clang-tidy/Inputs/absl/time/time.h @@ -70,6 +70,8 @@ Time FromUnixMillis(int64_t); Time FromUnixMicros(int64_t); Time FromUnixNanos(int64_t); +Time Now(); + // Relational Operators constexpr bool operator<(Duration lhs, Duration rhs); constexpr bool operator>(Duration lhs, Duration rhs); diff --git a/test/clang-tidy/abseil-time-subtraction.cpp b/test/clang-tidy/abseil-time-subtraction.cpp new file mode 100644 index 00000000..6f5d4b45 --- /dev/null +++ b/test/clang-tidy/abseil-time-subtraction.cpp @@ -0,0 +1,117 @@ +// RUN: %check_clang_tidy %s abseil-time-subtraction %t -- -- -I%S/Inputs + +#include "absl/time/time.h" + +void g(absl::Duration d); + +void f() { + absl::Time t; + int x, y; + absl::Duration d; + + d = absl::Hours(absl::ToUnixHours(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixHours(x)); + d = absl::Minutes(absl::ToUnixMinutes(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixMinutes(x)); + d = absl::Seconds(absl::ToUnixSeconds(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x)); + d = absl::Milliseconds(absl::ToUnixMillis(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixMillis(x)); + d = absl::Microseconds(absl::ToUnixMicros(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixMicros(x)); + d = absl::Nanoseconds(absl::ToUnixNanos(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixNanos(x)); + + y = x - absl::ToUnixHours(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: y = absl::ToInt64Hours(absl::FromUnixHours(x) - t); + y = x - absl::ToUnixMinutes(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: y = absl::ToInt64Minutes(absl::FromUnixMinutes(x) - t); + y = x - absl::ToUnixSeconds(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: y = absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t); + y = x - absl::ToUnixMillis(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: y = absl::ToInt64Milliseconds(absl::FromUnixMillis(x) - t); + y = x - absl::ToUnixMicros(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: y = absl::ToInt64Microseconds(absl::FromUnixMicros(x) - t); + y = x - absl::ToUnixNanos(t); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: y = absl::ToInt64Nanoseconds(absl::FromUnixNanos(x) - t); + + // Check parenthesis placement + d = 5 * absl::Seconds(absl::ToUnixSeconds(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = 5 * (t - absl::FromUnixSeconds(x)); + d = absl::Seconds(absl::ToUnixSeconds(t) - x) / 5; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixSeconds(x)) / 5; + + // No extra parens around arguments + g(absl::Seconds(absl::ToUnixSeconds(t) - x)); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: g(t - absl::FromUnixSeconds(x)); + g(absl::Seconds(x - absl::ToUnixSeconds(t))); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: g(absl::FromUnixSeconds(x) - t); + + // More complex subexpressions + d = absl::Hours(absl::ToUnixHours(t) - 5 * x); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: d = (t - absl::FromUnixHours(5 * x)); + + // These should not trigger; they are likely bugs + d = absl::Milliseconds(absl::ToUnixSeconds(t) - x); + d = absl::Seconds(absl::ToUnixMicros(t) - x); + + // Various macro scenarios +#define SUB(z, t1) z - absl::ToUnixSeconds(t1) + y = SUB(x, t); +#undef SUB + +#define MILLIS(t1) absl::ToUnixMillis(t1) + y = x - MILLIS(t); +#undef MILLIS + +#define HOURS(z) absl::Hours(z) + d = HOURS(absl::ToUnixHours(t) - x); +#undef HOURS + + // This should match the expression inside the macro invocation. +#define SECONDS(z) absl::Seconds(z) + d = SECONDS(x - absl::ToUnixSeconds(t)); + // CHECK-MESSAGES: [[@LINE-1]]:15: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: SECONDS(absl::ToInt64Seconds(absl::FromUnixSeconds(x) - t)) +#undef SECONDS +} + +template +void func(absl::Time t, T x) { + absl::Duration d = absl::Seconds(absl::ToUnixSeconds(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:22: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: absl::Duration d = t - absl::FromUnixSeconds(x); +} + +void g() { + func(absl::Now(), 5); +} + +absl::Duration parens_in_return() { + absl::Time t; + int x; + + return absl::Seconds(absl::ToUnixSeconds(t) - x); + // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: return t - absl::FromUnixSeconds(x); + return absl::Seconds(x - absl::ToUnixSeconds(t)); + // CHECK-MESSAGES: [[@LINE-1]]:10: warning: perform subtraction in the time domain [abseil-time-subtraction] + // CHECK-FIXES: return absl::FromUnixSeconds(x) - t; +} -- cgit v1.2.3 From 4def74ee85c5dd1ba9f72bb3547df27e839a1162 Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Thu, 28 Feb 2019 10:33:32 +0000 Subject: [clang-tidy] misc-string-integer-assignment: fix false positive Summary: using CodePoint = uint32_t; CodePoint cp; basic_string s; s += cp; See PR27723. Reviewers: xazax.hun, alexfh Subscribers: rnkovacs, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58606 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355076 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp | 9 +++++++-- test/clang-tidy/bugprone-string-integer-assignment.cpp | 4 ++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index e9bde2a7..4288c2db 100644 --- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -26,7 +26,8 @@ void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { hasOverloadedOperatorName("+=")), callee(cxxMethodDecl(ofClass(classTemplateSpecializationDecl( hasName("::std::basic_string"), - hasTemplateArgument(0, refersToType(qualType().bind("type"))))))), + hasTemplateArgument(0, refersToType(hasCanonicalType( + qualType().bind("type")))))))), hasArgument( 1, ignoringImpCasts( @@ -34,7 +35,11 @@ void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { // Ignore calls to tolower/toupper (see PR27723). unless(callExpr(callee(functionDecl( hasAnyName("tolower", "std::tolower", "toupper", - "std::toupper")))))) + "std::toupper"))))), + // Do not warn if assigning e.g. `CodePoint` to + // `basic_string` + unless(hasType(qualType( + hasCanonicalType(equalsBoundNode("type")))))) .bind("expr"))), unless(isInTemplateInstantiation())), this); diff --git a/test/clang-tidy/bugprone-string-integer-assignment.cpp b/test/clang-tidy/bugprone-string-integer-assignment.cpp index 0317354d..2b73f89b 100644 --- a/test/clang-tidy/bugprone-string-integer-assignment.cpp +++ b/test/clang-tidy/bugprone-string-integer-assignment.cpp @@ -53,8 +53,8 @@ int main() { std::basic_string as; as = 6; -// CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara -// CHECK-FIXES: {{^}} as = 6;{{$}} + as = static_cast(6); + as = 'a'; s += toupper(x); s += tolower(x); -- cgit v1.2.3 From e18b9b92f4b905e5669a8b252f4be564037e65ba Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 11:00:44 +0000 Subject: Moved DenseMap support for SymbolID into SymbolID.h git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355081 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Index.h | 25 ------------------------- clangd/index/SymbolID.h | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 25 deletions(-) diff --git a/clangd/index/Index.h b/clangd/index/Index.h index 4f6feb93..8eac4913 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -94,31 +94,6 @@ inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) { } llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &); -} // namespace clangd -} // namespace clang -namespace llvm { -// Support SymbolIDs as DenseMap keys. -template <> struct DenseMapInfo { - static inline clang::clangd::SymbolID getEmptyKey() { - static clang::clangd::SymbolID EmptyKey("EMPTYKEY"); - return EmptyKey; - } - static inline clang::clangd::SymbolID getTombstoneKey() { - static clang::clangd::SymbolID TombstoneKey("TOMBSTONEKEY"); - return TombstoneKey; - } - static unsigned getHashValue(const clang::clangd::SymbolID &Sym) { - return hash_value(Sym); - } - static bool isEqual(const clang::clangd::SymbolID &LHS, - const clang::clangd::SymbolID &RHS) { - return LHS == RHS; - } -}; -} // namespace llvm -namespace clang { -namespace clangd { - // Describes the source of information about a symbol. // Mainly useful for debugging, e.g. understanding code completion reuslts. // This is a bitfield as information can be combined from several sources. diff --git a/clangd/index/SymbolID.h b/clangd/index/SymbolID.h index 0e4fc663..d715f4d0 100644 --- a/clangd/index/SymbolID.h +++ b/clangd/index/SymbolID.h @@ -9,6 +9,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLID_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLID_H +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" @@ -61,4 +62,25 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolID &ID); } // namespace clangd } // namespace clang +namespace llvm { +// Support SymbolIDs as DenseMap keys. +template <> struct DenseMapInfo { + static inline clang::clangd::SymbolID getEmptyKey() { + static clang::clangd::SymbolID EmptyKey("EMPTYKEY"); + return EmptyKey; + } + static inline clang::clangd::SymbolID getTombstoneKey() { + static clang::clangd::SymbolID TombstoneKey("TOMBSTONEKEY"); + return TombstoneKey; + } + static unsigned getHashValue(const clang::clangd::SymbolID &Sym) { + return hash_value(Sym); + } + static bool isEqual(const clang::clangd::SymbolID &LHS, + const clang::clangd::SymbolID &RHS) { + return LHS == RHS; + } +}; +} // namespace llvm + #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOLID_H -- cgit v1.2.3 From 1c13427d411c0721460cab3537fd99f7add477eb Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 11:02:01 +0000 Subject: Moved SymbolLocation into its own header and implementation file Reviewers: ioeric Subscribers: mgorny, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58768 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355082 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 1 + clangd/XRefs.cpp | 2 +- clangd/index/Index.cpp | 24 ----------- clangd/index/Index.h | 65 +--------------------------- clangd/index/Merge.cpp | 2 +- clangd/index/Serialization.cpp | 2 +- clangd/index/Serialization.h | 1 + clangd/index/SymbolCollector.cpp | 1 + clangd/index/SymbolLocation.cpp | 40 +++++++++++++++++ clangd/index/SymbolLocation.h | 88 ++++++++++++++++++++++++++++++++++++++ clangd/index/YAMLSerialization.cpp | 1 + 11 files changed, 136 insertions(+), 91 deletions(-) create mode 100644 clangd/index/SymbolLocation.cpp create mode 100644 clangd/index/SymbolLocation.h diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index 6db78920..474b84ea 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -63,6 +63,7 @@ add_clang_library(clangDaemon index/MemIndex.cpp index/Merge.cpp index/SymbolID.cpp + index/SymbolLocation.cpp index/Serialization.cpp index/SymbolCollector.cpp index/YAMLSerialization.cpp diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index edb1f7cb..be4df73b 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -10,8 +10,8 @@ #include "Logger.h" #include "SourceCode.h" #include "URI.h" -#include "index/Index.h" #include "index/Merge.h" +#include "index/SymbolLocation.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Index/IndexDataConsumer.h" diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index 36c591d9..ac04d5d6 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -16,30 +16,6 @@ namespace clang { namespace clangd { -constexpr uint32_t SymbolLocation::Position::MaxLine; -constexpr uint32_t SymbolLocation::Position::MaxColumn; -void SymbolLocation::Position::setLine(uint32_t L) { - if (L > MaxLine) { - Line = MaxLine; - return; - } - Line = L; -} -void SymbolLocation::Position::setColumn(uint32_t Col) { - if (Col > MaxColumn) { - Column = MaxColumn; - return; - } - Column = Col; -} - -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolLocation &L) { - if (!L) - return OS << "(none)"; - return OS << L.FileURI << "[" << L.Start.line() << ":" << L.Start.column() - << "-" << L.End.line() << ":" << L.End.column() << ")"; -} - llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) { if (O == SymbolOrigin::Unknown) return OS << "unknown"; diff --git a/clangd/index/Index.h b/clangd/index/Index.h index 8eac4913..1d98d922 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -11,6 +11,7 @@ #include "ExpectedTypes.h" #include "SymbolID.h" +#include "SymbolLocation.h" #include "clang/Index/IndexSymbol.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/DenseMap.h" @@ -30,70 +31,6 @@ namespace clang { namespace clangd { -struct SymbolLocation { - // Specify a position (Line, Column) of symbol. Using Line/Column allows us to - // build LSP responses without reading the file content. - // - // Position is encoded into 32 bits to save space. - // If Line/Column overflow, the value will be their maximum value. - struct Position { - Position() : Line(0), Column(0) {} - void setLine(uint32_t Line); - uint32_t line() const { return Line; } - void setColumn(uint32_t Column); - uint32_t column() const { return Column; } - - bool hasOverflow() const { - return Line >= MaxLine || Column >= MaxColumn; - } - - static constexpr uint32_t MaxLine = (1 << 20) - 1; - static constexpr uint32_t MaxColumn = (1 << 12) - 1; - - private: - uint32_t Line : 20; // 0-based - // Using UTF-16 code units. - uint32_t Column : 12; // 0-based - }; - - /// The symbol range, using half-open range [Start, End). - Position Start; - Position End; - - explicit operator bool() const { return !StringRef(FileURI).empty(); } - - // The URI of the source file where a symbol occurs. - // The string must be null-terminated. - // - // We avoid using llvm::StringRef here to save memory. - // WARNING: unless you know what you are doing, it is recommended to use it - // via llvm::StringRef. - const char *FileURI = ""; -}; -inline bool operator==(const SymbolLocation::Position &L, - const SymbolLocation::Position &R) { - return std::make_tuple(L.line(), L.column()) == - std::make_tuple(R.line(), R.column()); -} -inline bool operator<(const SymbolLocation::Position &L, - const SymbolLocation::Position &R) { - return std::make_tuple(L.line(), L.column()) < - std::make_tuple(R.line(), R.column()); -} -inline bool operator==(const SymbolLocation &L, const SymbolLocation &R) { - assert(L.FileURI && R.FileURI); - return !std::strcmp(L.FileURI, R.FileURI) && - std::tie(L.Start, L.End) == std::tie(R.Start, R.End); -} -inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) { - assert(L.FileURI && R.FileURI); - int Cmp = std::strcmp(L.FileURI, R.FileURI); - if (Cmp != 0) - return Cmp < 0; - return std::tie(L.Start, L.End) < std::tie(R.Start, R.End); -} -llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &); - // Describes the source of information about a symbol. // Mainly useful for debugging, e.g. understanding code completion reuslts. // This is a bitfield as information can be combined from several sources. diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp index 65e9b86d..58270cee 100644 --- a/clangd/index/Merge.cpp +++ b/clangd/index/Merge.cpp @@ -9,7 +9,7 @@ #include "Merge.h" #include "Logger.h" #include "Trace.h" -#include "index/Index.h" +#include "index/SymbolLocation.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" diff --git a/clangd/index/Serialization.cpp b/clangd/index/Serialization.cpp index 20c43ab0..86ff2bb1 100644 --- a/clangd/index/Serialization.cpp +++ b/clangd/index/Serialization.cpp @@ -7,9 +7,9 @@ //===----------------------------------------------------------------------===// #include "Serialization.h" -#include "Index.h" #include "Logger.h" #include "RIFF.h" +#include "SymbolLocation.h" #include "Trace.h" #include "dex/Dex.h" #include "llvm/Support/Compression.h" diff --git a/clangd/index/Serialization.h b/clangd/index/Serialization.h index d81b8968..4a1646b5 100644 --- a/clangd/index/Serialization.h +++ b/clangd/index/Serialization.h @@ -23,6 +23,7 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RIFF_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_RIFF_H + #include "Headers.h" #include "Index.h" #include "llvm/Support/Error.h" diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index 23fcc5c5..80b5c5b0 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -13,6 +13,7 @@ #include "CodeCompletionStrings.h" #include "Logger.h" #include "SourceCode.h" +#include "SymbolLocation.h" #include "URI.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" diff --git a/clangd/index/SymbolLocation.cpp b/clangd/index/SymbolLocation.cpp new file mode 100644 index 00000000..aac55703 --- /dev/null +++ b/clangd/index/SymbolLocation.cpp @@ -0,0 +1,40 @@ +//===--- SymbolLocation.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 "SymbolLocation.h" + +namespace clang { +namespace clangd { + +constexpr uint32_t SymbolLocation::Position::MaxLine; +constexpr uint32_t SymbolLocation::Position::MaxColumn; + +void SymbolLocation::Position::setLine(uint32_t L) { + if (L > MaxLine) { + Line = MaxLine; + return; + } + Line = L; +} +void SymbolLocation::Position::setColumn(uint32_t Col) { + if (Col > MaxColumn) { + Column = MaxColumn; + return; + } + Column = Col; +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const SymbolLocation &L) { + if (!L) + return OS << "(none)"; + return OS << L.FileURI << "[" << L.Start.line() << ":" << L.Start.column() + << "-" << L.End.line() << ":" << L.End.column() << ")"; +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/index/SymbolLocation.h b/clangd/index/SymbolLocation.h new file mode 100644 index 00000000..f1b7ffd5 --- /dev/null +++ b/clangd/index/SymbolLocation.h @@ -0,0 +1,88 @@ +//===--- SymbolLocation.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_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_LOCATION_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_LOCATION_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/raw_ostream.h" +#include + +namespace clang { +namespace clangd { + +struct SymbolLocation { + // Specify a position (Line, Column) of symbol. Using Line/Column allows us to + // build LSP responses without reading the file content. + // + // Position is encoded into 32 bits to save space. + // If Line/Column overflow, the value will be their maximum value. + struct Position { + Position() : Line(0), Column(0) {} + void setLine(uint32_t Line); + uint32_t line() const { return Line; } + void setColumn(uint32_t Column); + uint32_t column() const { return Column; } + + bool hasOverflow() const { + return Line >= MaxLine || Column >= MaxColumn; + } + + static constexpr uint32_t MaxLine = (1 << 20) - 1; + static constexpr uint32_t MaxColumn = (1 << 12) - 1; + + private: + uint32_t Line : 20; // 0-based + // Using UTF-16 code units. + uint32_t Column : 12; // 0-based + }; + + /// The symbol range, using half-open range [Start, End). + Position Start; + Position End; + + explicit operator bool() const { return !llvm::StringRef(FileURI).empty(); } + + // The URI of the source file where a symbol occurs. + // The string must be null-terminated. + // + // We avoid using llvm::StringRef here to save memory. + // WARNING: unless you know what you are doing, it is recommended to use it + // via llvm::StringRef. + const char *FileURI = ""; +}; + +inline bool operator==(const SymbolLocation::Position &L, + const SymbolLocation::Position &R) { + return std::make_tuple(L.line(), L.column()) == + std::make_tuple(R.line(), R.column()); +} +inline bool operator<(const SymbolLocation::Position &L, + const SymbolLocation::Position &R) { + return std::make_tuple(L.line(), L.column()) < + std::make_tuple(R.line(), R.column()); +} +inline bool operator==(const SymbolLocation &L, const SymbolLocation &R) { + assert(L.FileURI && R.FileURI); + return !std::strcmp(L.FileURI, R.FileURI) && + std::tie(L.Start, L.End) == std::tie(R.Start, R.End); +} +inline bool operator<(const SymbolLocation &L, const SymbolLocation &R) { + assert(L.FileURI && R.FileURI); + int Cmp = std::strcmp(L.FileURI, R.FileURI); + if (Cmp != 0) + return Cmp < 0; + return std::tie(L.Start, L.End) < std::tie(R.Start, R.End); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &, const SymbolLocation &); + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_LOCATION_H diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp index 7aab39f4..f05d6147 100644 --- a/clangd/index/YAMLSerialization.cpp +++ b/clangd/index/YAMLSerialization.cpp @@ -14,6 +14,7 @@ #include "Index.h" #include "Serialization.h" +#include "SymbolLocation.h" #include "Trace.h" #include "dex/Dex.h" #include "llvm/ADT/Optional.h" -- cgit v1.2.3 From c6f58c37de0b413fbd6aff717fee49b5ad1b44e3 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 12:31:49 +0000 Subject: Moved SymbolOrigin into its own header and implementation file Reviewers: ioeric Subscribers: mgorny, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58773 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355086 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 5 ++-- clangd/CodeComplete.h | 1 + clangd/index/FileIndex.cpp | 1 + clangd/index/Index.cpp | 10 -------- clangd/index/Index.h | 25 +------------------- clangd/index/IndexAction.cpp | 2 ++ clangd/index/Merge.cpp | 1 + clangd/index/Serialization.cpp | 1 + clangd/index/SymbolCollector.h | 2 ++ clangd/index/SymbolOrigin.cpp | 25 ++++++++++++++++++++ clangd/index/SymbolOrigin.h | 47 ++++++++++++++++++++++++++++++++++++++ clangd/index/YAMLSerialization.cpp | 1 + 12 files changed, 85 insertions(+), 36 deletions(-) create mode 100644 clangd/index/SymbolOrigin.cpp create mode 100644 clangd/index/SymbolOrigin.h diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index 474b84ea..e2808c0e 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -62,10 +62,11 @@ add_clang_library(clangDaemon index/IndexAction.cpp index/MemIndex.cpp index/Merge.cpp - index/SymbolID.cpp - index/SymbolLocation.cpp index/Serialization.cpp index/SymbolCollector.cpp + index/SymbolID.cpp + index/SymbolLocation.cpp + index/SymbolOrigin.cpp index/YAMLSerialization.cpp index/dex/Dex.cpp diff --git a/clangd/CodeComplete.h b/clangd/CodeComplete.h index 08151379..3b5f8346 100644 --- a/clangd/CodeComplete.h +++ b/clangd/CodeComplete.h @@ -21,6 +21,7 @@ #include "Path.h" #include "Protocol.h" #include "index/Index.h" +#include "index/SymbolOrigin.h" #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/CodeCompleteOptions.h" diff --git a/clangd/index/FileIndex.cpp b/clangd/index/FileIndex.cpp index 37fd031e..7eca85e2 100644 --- a/clangd/index/FileIndex.cpp +++ b/clangd/index/FileIndex.cpp @@ -14,6 +14,7 @@ #include "index/Index.h" #include "index/MemIndex.h" #include "index/Merge.h" +#include "index/SymbolOrigin.h" #include "index/dex/Dex.h" #include "clang/Index/IndexingAction.h" #include "clang/Lex/MacroInfo.h" diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index ac04d5d6..10982e69 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -16,16 +16,6 @@ namespace clang { namespace clangd { -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) { - if (O == SymbolOrigin::Unknown) - return OS << "unknown"; - constexpr static char Sigils[] = "ADSM4567"; - for (unsigned I = 0; I < sizeof(Sigils); ++I) - if (static_cast(O) & 1u << I) - OS << Sigils[I]; - return OS; -} - llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) { if (F == Symbol::None) return OS << "None"; diff --git a/clangd/index/Index.h b/clangd/index/Index.h index 1d98d922..8641ee77 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -12,6 +12,7 @@ #include "ExpectedTypes.h" #include "SymbolID.h" #include "SymbolLocation.h" +#include "SymbolOrigin.h" #include "clang/Index/IndexSymbol.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/DenseMap.h" @@ -31,30 +32,6 @@ namespace clang { namespace clangd { -// Describes the source of information about a symbol. -// Mainly useful for debugging, e.g. understanding code completion reuslts. -// This is a bitfield as information can be combined from several sources. -enum class SymbolOrigin : uint8_t { - Unknown = 0, - AST = 1 << 0, // Directly from the AST (indexes should not set this). - Dynamic = 1 << 1, // From the dynamic index of opened files. - Static = 1 << 2, // From the static, externally-built index. - Merge = 1 << 3, // A non-trivial index merge was performed. - // Remaining bits reserved for index implementations. -}; -inline SymbolOrigin operator|(SymbolOrigin A, SymbolOrigin B) { - return static_cast(static_cast(A) | - static_cast(B)); -} -inline SymbolOrigin &operator|=(SymbolOrigin &A, SymbolOrigin B) { - return A = A | B; -} -inline SymbolOrigin operator&(SymbolOrigin A, SymbolOrigin B) { - return static_cast(static_cast(A) & - static_cast(B)); -} -raw_ostream &operator<<(raw_ostream &, SymbolOrigin); - // The class presents a C++ symbol, e.g. class, function. // // WARNING: Symbols do not own much of their underlying data - typically strings diff --git a/clangd/index/IndexAction.cpp b/clangd/index/IndexAction.cpp index b9b7ef2d..a88eca09 100644 --- a/clangd/index/IndexAction.cpp +++ b/clangd/index/IndexAction.cpp @@ -1,4 +1,6 @@ #include "IndexAction.h" + +#include "index/SymbolOrigin.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Index/IndexDataConsumer.h" #include "clang/Index/IndexingAction.h" diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp index 58270cee..a7e658be 100644 --- a/clangd/index/Merge.cpp +++ b/clangd/index/Merge.cpp @@ -10,6 +10,7 @@ #include "Logger.h" #include "Trace.h" #include "index/SymbolLocation.h" +#include "index/SymbolOrigin.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" diff --git a/clangd/index/Serialization.cpp b/clangd/index/Serialization.cpp index 86ff2bb1..c7c23c27 100644 --- a/clangd/index/Serialization.cpp +++ b/clangd/index/Serialization.cpp @@ -10,6 +10,7 @@ #include "Logger.h" #include "RIFF.h" #include "SymbolLocation.h" +#include "SymbolOrigin.h" #include "Trace.h" #include "dex/Dex.h" #include "llvm/Support/Compression.h" diff --git a/clangd/index/SymbolCollector.h b/clangd/index/SymbolCollector.h index 0261bf7c..e6d479d2 100644 --- a/clangd/index/SymbolCollector.h +++ b/clangd/index/SymbolCollector.h @@ -10,6 +10,7 @@ #include "CanonicalIncludes.h" #include "Index.h" +#include "SymbolOrigin.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/Basic/SourceLocation.h" @@ -143,4 +144,5 @@ private: } // namespace clangd } // namespace clang + #endif diff --git a/clangd/index/SymbolOrigin.cpp b/clangd/index/SymbolOrigin.cpp new file mode 100644 index 00000000..93fc69f0 --- /dev/null +++ b/clangd/index/SymbolOrigin.cpp @@ -0,0 +1,25 @@ +//===--- SymbolOrigin.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 "SymbolOrigin.h" + +namespace clang { +namespace clangd { + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, SymbolOrigin O) { + if (O == SymbolOrigin::Unknown) + return OS << "unknown"; + constexpr static char Sigils[] = "ADSM4567"; + for (unsigned I = 0; I < sizeof(Sigils); ++I) + if (static_cast(O) & 1u << I) + OS << Sigils[I]; + return OS; +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/index/SymbolOrigin.h b/clangd/index/SymbolOrigin.h new file mode 100644 index 00000000..4541e4c7 --- /dev/null +++ b/clangd/index/SymbolOrigin.h @@ -0,0 +1,47 @@ +//===--- SymbolOrigin.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_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_ORIGIN_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_ORIGIN_H + +#include "llvm/Support/raw_ostream.h" +#include + +namespace clang { +namespace clangd { + +// Describes the source of information about a symbol. +// Mainly useful for debugging, e.g. understanding code completion reuslts. +// This is a bitfield as information can be combined from several sources. +enum class SymbolOrigin : uint8_t { + Unknown = 0, + AST = 1 << 0, // Directly from the AST (indexes should not set this). + Dynamic = 1 << 1, // From the dynamic index of opened files. + Static = 1 << 2, // From the static, externally-built index. + Merge = 1 << 3, // A non-trivial index merge was performed. + // Remaining bits reserved for index implementations. +}; + +inline SymbolOrigin operator|(SymbolOrigin A, SymbolOrigin B) { + return static_cast(static_cast(A) | + static_cast(B)); +} +inline SymbolOrigin &operator|=(SymbolOrigin &A, SymbolOrigin B) { + return A = A | B; +} +inline SymbolOrigin operator&(SymbolOrigin A, SymbolOrigin B) { + return static_cast(static_cast(A) & + static_cast(B)); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &, SymbolOrigin); + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_ORIGIN_H diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp index f05d6147..733f4c4b 100644 --- a/clangd/index/YAMLSerialization.cpp +++ b/clangd/index/YAMLSerialization.cpp @@ -15,6 +15,7 @@ #include "Index.h" #include "Serialization.h" #include "SymbolLocation.h" +#include "SymbolOrigin.h" #include "Trace.h" #include "dex/Dex.h" #include "llvm/ADT/Optional.h" -- cgit v1.2.3 From d54fc41cf2386c9665815113f540855d8fe081d0 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 13:23:03 +0000 Subject: Moved Symbol into its own header and implementation file Reviewers: ioeric Subscribers: mgorny, jkorous, arphaman, kadircet, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58774 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355088 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CMakeLists.txt | 1 + clangd/CodeComplete.cpp | 1 + clangd/CodeComplete.h | 1 + clangd/Headers.h | 2 +- clangd/IncludeFixer.cpp | 1 + clangd/IncludeFixer.h | 1 + clangd/index/Background.cpp | 1 + clangd/index/FileIndex.h | 1 + clangd/index/Index.cpp | 61 ------------ clangd/index/Index.h | 204 +------------------------------------- clangd/index/Merge.cpp | 1 + clangd/index/Serialization.h | 1 + clangd/index/Symbol.cpp | 76 ++++++++++++++ clangd/index/Symbol.h | 231 +++++++++++++++++++++++++++++++++++++++++++ 14 files changed, 318 insertions(+), 265 deletions(-) create mode 100644 clangd/index/Symbol.cpp create mode 100644 clangd/index/Symbol.h diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index e2808c0e..2005c51d 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -63,6 +63,7 @@ add_clang_library(clangDaemon index/MemIndex.cpp index/Merge.cpp index/Serialization.cpp + index/Symbol.cpp index/SymbolCollector.cpp index/SymbolID.cpp index/SymbolLocation.cpp diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 8cbff88c..91a5dac5 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -34,6 +34,7 @@ #include "Trace.h" #include "URI.h" #include "index/Index.h" +#include "index/Symbol.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/Basic/LangOptions.h" diff --git a/clangd/CodeComplete.h b/clangd/CodeComplete.h index 3b5f8346..c57a2afb 100644 --- a/clangd/CodeComplete.h +++ b/clangd/CodeComplete.h @@ -21,6 +21,7 @@ #include "Path.h" #include "Protocol.h" #include "index/Index.h" +#include "index/Symbol.h" #include "index/SymbolOrigin.h" #include "clang/Frontend/PrecompiledPreamble.h" #include "clang/Sema/CodeCompleteConsumer.h" diff --git a/clangd/Headers.h b/clangd/Headers.h index e29f7f6b..ab44191d 100644 --- a/clangd/Headers.h +++ b/clangd/Headers.h @@ -12,7 +12,7 @@ #include "Path.h" #include "Protocol.h" #include "SourceCode.h" -#include "index/Index.h" +#include "index/Symbol.h" #include "clang/Format/Format.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PPCallbacks.h" diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index a90a8467..8b934d17 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -13,6 +13,7 @@ #include "SourceCode.h" #include "Trace.h" #include "index/Index.h" +#include "index/Symbol.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/NestedNameSpecifier.h" diff --git a/clangd/IncludeFixer.h b/clangd/IncludeFixer.h index f1eac45d..aafb384b 100644 --- a/clangd/IncludeFixer.h +++ b/clangd/IncludeFixer.h @@ -12,6 +12,7 @@ #include "Diagnostics.h" #include "Headers.h" #include "index/Index.h" +#include "index/Symbol.h" #include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceLocation.h" diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp index ddb0ec43..40ff8d7e 100644 --- a/clangd/index/Background.cpp +++ b/clangd/index/Background.cpp @@ -11,6 +11,7 @@ #include "Compiler.h" #include "Logger.h" #include "SourceCode.h" +#include "Symbol.h" #include "Threading.h" #include "Trace.h" #include "URI.h" diff --git a/clangd/index/FileIndex.h b/clangd/index/FileIndex.h index f1e37c33..d9bee888 100644 --- a/clangd/index/FileIndex.h +++ b/clangd/index/FileIndex.h @@ -20,6 +20,7 @@ #include "MemIndex.h" #include "Merge.h" #include "index/CanonicalIncludes.h" +#include "index/Symbol.h" #include "clang/Lex/Preprocessor.h" #include diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index 10982e69..6080066b 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -16,67 +16,6 @@ namespace clang { namespace clangd { -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) { - if (F == Symbol::None) - return OS << "None"; - std::string S; - if (F & Symbol::Deprecated) - S += "deprecated|"; - if (F & Symbol::IndexedForCodeCompletion) - S += "completion|"; - return OS << llvm::StringRef(S).rtrim('|'); -} - -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) { - return OS << S.Scope << S.Name; -} - -float quality(const Symbol &S) { - // This avoids a sharp gradient for tail symbols, and also neatly avoids the - // question of whether 0 references means a bad symbol or missing data. - if (S.References < 3) - return 1; - return std::log(S.References); -} - -SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const { - auto It = std::lower_bound( - Symbols.begin(), Symbols.end(), ID, - [](const Symbol &S, const SymbolID &I) { return S.ID < I; }); - if (It != Symbols.end() && It->ID == ID) - return It; - return Symbols.end(); -} - -// Copy the underlying data of the symbol into the owned arena. -static void own(Symbol &S, llvm::UniqueStringSaver &Strings) { - visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); }); -} - -void SymbolSlab::Builder::insert(const Symbol &S) { - auto R = SymbolIndex.try_emplace(S.ID, Symbols.size()); - if (R.second) { - Symbols.push_back(S); - own(Symbols.back(), UniqueStrings); - } else { - auto &Copy = Symbols[R.first->second] = S; - own(Copy, UniqueStrings); - } -} - -SymbolSlab SymbolSlab::Builder::build() && { - Symbols = {Symbols.begin(), Symbols.end()}; // Force shrink-to-fit. - // Sort symbols so the slab can binary search over them. - llvm::sort(Symbols, - [](const Symbol &L, const Symbol &R) { return L.ID < R.ID; }); - // We may have unused strings from overwritten symbols. Build a new arena. - llvm::BumpPtrAllocator NewArena; - llvm::UniqueStringSaver Strings(NewArena); - for (auto &S : Symbols) - own(S, Strings); - return SymbolSlab(std::move(NewArena), std::move(Symbols)); -} - llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) { if (K == RefKind::Unknown) return OS << "Unknown"; diff --git a/clangd/index/Index.h b/clangd/index/Index.h index 8641ee77..f9541a6a 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -10,9 +10,9 @@ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H #include "ExpectedTypes.h" +#include "Symbol.h" #include "SymbolID.h" #include "SymbolLocation.h" -#include "SymbolOrigin.h" #include "clang/Index/IndexSymbol.h" #include "clang/Lex/Lexer.h" #include "llvm/ADT/DenseMap.h" @@ -22,7 +22,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" -#include "llvm/Support/StringSaver.h" #include #include #include @@ -32,207 +31,6 @@ namespace clang { namespace clangd { -// The class presents a C++ symbol, e.g. class, function. -// -// WARNING: Symbols do not own much of their underlying data - typically strings -// are owned by a SymbolSlab. They should be treated as non-owning references. -// Copies are shallow. -// When adding new unowned data fields to Symbol, remember to update: -// - SymbolSlab::Builder in Index.cpp, to copy them to the slab's storage. -// - mergeSymbol in Merge.cpp, to properly combine two Symbols. -// -// A fully documented symbol can be split as: -// size_type std::map::count(const K& key) const -// | Return | Scope |Name| Signature | -// We split up these components to allow display flexibility later. -struct Symbol { - // The ID of the symbol. - SymbolID ID; - // The symbol information, like symbol kind. - index::SymbolInfo SymInfo; - // The unqualified name of the symbol, e.g. "bar" (for ns::bar). - llvm::StringRef Name; - // The containing namespace. e.g. "" (global), "ns::" (top-level namespace). - llvm::StringRef Scope; - // The location of the symbol's definition, if one was found. - // This just covers the symbol name (e.g. without class/function body). - SymbolLocation Definition; - // The location of the preferred declaration of the symbol. - // This just covers the symbol name. - // This may be the same as Definition. - // - // A C++ symbol may have multiple declarations, and we pick one to prefer. - // * For classes, the canonical declaration should be the definition. - // * For non-inline functions, the canonical declaration typically appears - // in the ".h" file corresponding to the definition. - SymbolLocation CanonicalDeclaration; - // The number of translation units that reference this symbol from their main - // file. This number is only meaningful if aggregated in an index. - unsigned References = 0; - /// Where this symbol came from. Usually an index provides a constant value. - SymbolOrigin Origin = SymbolOrigin::Unknown; - /// A brief description of the symbol that can be appended in the completion - /// candidate list. For example, "(X x, Y y) const" is a function signature. - /// Only set when the symbol is indexed for completion. - llvm::StringRef Signature; - /// What to insert when completing this symbol, after the symbol name. - /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function). - /// (When snippets are disabled, the symbol name alone is used). - /// Only set when the symbol is indexed for completion. - llvm::StringRef CompletionSnippetSuffix; - /// Documentation including comment for the symbol declaration. - llvm::StringRef Documentation; - /// Type when this symbol is used in an expression. (Short display form). - /// e.g. return type of a function, or type of a variable. - /// Only set when the symbol is indexed for completion. - llvm::StringRef ReturnType; - - /// Raw representation of the OpaqueType of the symbol, used for scoring - /// purposes. - /// Only set when the symbol is indexed for completion. - llvm::StringRef Type; - - struct IncludeHeaderWithReferences { - IncludeHeaderWithReferences() = default; - - IncludeHeaderWithReferences(llvm::StringRef IncludeHeader, - unsigned References) - : IncludeHeader(IncludeHeader), References(References) {} - - /// This can be either a URI of the header to be #include'd - /// for this symbol, or a literal header quoted with <> or "" that is - /// suitable to be included directly. When it is a URI, the exact #include - /// path needs to be calculated according to the URI scheme. - /// - /// Note that the include header is a canonical include for the symbol and - /// can be different from FileURI in the CanonicalDeclaration. - llvm::StringRef IncludeHeader = ""; - /// The number of translation units that reference this symbol and include - /// this header. This number is only meaningful if aggregated in an index. - unsigned References = 0; - }; - /// One Symbol can potentially be incuded via different headers. - /// - If we haven't seen a definition, this covers all declarations. - /// - If we have seen a definition, this covers declarations visible from - /// any definition. - /// Only set when the symbol is indexed for completion. - llvm::SmallVector IncludeHeaders; - - enum SymbolFlag : uint8_t { - None = 0, - /// Whether or not this symbol is meant to be used for the code completion. - /// See also isIndexedForCodeCompletion(). - /// Note that we don't store completion information (signature, snippet, - /// type, inclues) if the symbol is not indexed for code completion. - IndexedForCodeCompletion = 1 << 0, - /// Indicates if the symbol is deprecated. - Deprecated = 1 << 1, - // Symbol is an implementation detail. - ImplementationDetail = 1 << 2, - // Symbol is visible to other files (not e.g. a static helper function). - VisibleOutsideFile = 1 << 3, - }; - - SymbolFlag Flags = SymbolFlag::None; - /// FIXME: also add deprecation message and fixit? -}; -inline Symbol::SymbolFlag operator|(Symbol::SymbolFlag A, Symbol::SymbolFlag B) { - return static_cast(static_cast(A) | - static_cast(B)); -} -inline Symbol::SymbolFlag &operator|=(Symbol::SymbolFlag &A, Symbol::SymbolFlag B) { - return A = A | B; -} -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S); -raw_ostream &operator<<(raw_ostream &, Symbol::SymbolFlag); - -// Invokes Callback with each StringRef& contained in the Symbol. -// Useful for deduplicating backing strings. -template void visitStrings(Symbol &S, const Callback &CB) { - CB(S.Name); - CB(S.Scope); - CB(S.Signature); - CB(S.CompletionSnippetSuffix); - CB(S.Documentation); - CB(S.ReturnType); - CB(S.Type); - auto RawCharPointerCB = [&CB](const char *&P) { - llvm::StringRef S(P); - CB(S); - assert(!S.data()[S.size()] && "Visited StringRef must be null-terminated"); - P = S.data(); - }; - RawCharPointerCB(S.CanonicalDeclaration.FileURI); - RawCharPointerCB(S.Definition.FileURI); - - for (auto &Include : S.IncludeHeaders) - CB(Include.IncludeHeader); -} - -// Computes query-independent quality score for a Symbol. -// This currently falls in the range [1, ln(#indexed documents)]. -// FIXME: this should probably be split into symbol -> signals -// and signals -> score, so it can be reused for Sema completions. -float quality(const Symbol &S); - -// An immutable symbol container that stores a set of symbols. -// The container will maintain the lifetime of the symbols. -class SymbolSlab { -public: - using const_iterator = std::vector::const_iterator; - using iterator = const_iterator; - using value_type = Symbol; - - SymbolSlab() = default; - - const_iterator begin() const { return Symbols.begin(); } - const_iterator end() const { return Symbols.end(); } - const_iterator find(const SymbolID &SymID) const; - - size_t size() const { return Symbols.size(); } - bool empty() const { return Symbols.empty(); } - // Estimates the total memory usage. - size_t bytes() const { - return sizeof(*this) + Arena.getTotalMemory() + - Symbols.capacity() * sizeof(Symbol); - } - - // SymbolSlab::Builder is a mutable container that can 'freeze' to SymbolSlab. - // The frozen SymbolSlab will use less memory. - class Builder { - public: - Builder() : UniqueStrings(Arena) {} - - // Adds a symbol, overwriting any existing one with the same ID. - // This is a deep copy: underlying strings will be owned by the slab. - void insert(const Symbol &S); - - // Returns the symbol with an ID, if it exists. Valid until next insert(). - const Symbol *find(const SymbolID &ID) { - auto I = SymbolIndex.find(ID); - return I == SymbolIndex.end() ? nullptr : &Symbols[I->second]; - } - - // Consumes the builder to finalize the slab. - SymbolSlab build() &&; - - private: - llvm::BumpPtrAllocator Arena; - // Intern table for strings. Contents are on the arena. - llvm::UniqueStringSaver UniqueStrings; - std::vector Symbols; - // Values are indices into Symbols vector. - llvm::DenseMap SymbolIndex; - }; - -private: - SymbolSlab(llvm::BumpPtrAllocator Arena, std::vector Symbols) - : Arena(std::move(Arena)), Symbols(std::move(Symbols)) {} - - llvm::BumpPtrAllocator Arena; // Owns Symbol data that the Symbols do not. - std::vector Symbols; // Sorted by SymbolID to allow lookup. -}; - // Describes the kind of a cross-reference. // // This is a bitfield which can be combined from different kinds. diff --git a/clangd/index/Merge.cpp b/clangd/index/Merge.cpp index a7e658be..a5945a7d 100644 --- a/clangd/index/Merge.cpp +++ b/clangd/index/Merge.cpp @@ -9,6 +9,7 @@ #include "Merge.h" #include "Logger.h" #include "Trace.h" +#include "index/Symbol.h" #include "index/SymbolLocation.h" #include "index/SymbolOrigin.h" #include "llvm/ADT/STLExtras.h" diff --git a/clangd/index/Serialization.h b/clangd/index/Serialization.h index 4a1646b5..3788693e 100644 --- a/clangd/index/Serialization.h +++ b/clangd/index/Serialization.h @@ -26,6 +26,7 @@ #include "Headers.h" #include "Index.h" +#include "index/Symbol.h" #include "llvm/Support/Error.h" namespace clang { diff --git a/clangd/index/Symbol.cpp b/clangd/index/Symbol.cpp new file mode 100644 index 00000000..57535716 --- /dev/null +++ b/clangd/index/Symbol.cpp @@ -0,0 +1,76 @@ +//===--- Symbol.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 "Symbol.h" + +namespace clang { +namespace clangd { + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag F) { + if (F == Symbol::None) + return OS << "None"; + std::string S; + if (F & Symbol::Deprecated) + S += "deprecated|"; + if (F & Symbol::IndexedForCodeCompletion) + S += "completion|"; + return OS << llvm::StringRef(S).rtrim('|'); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S) { + return OS << S.Scope << S.Name; +} + +float quality(const Symbol &S) { + // This avoids a sharp gradient for tail symbols, and also neatly avoids the + // question of whether 0 references means a bad symbol or missing data. + if (S.References < 3) + return 1; + return std::log(S.References); +} + +SymbolSlab::const_iterator SymbolSlab::find(const SymbolID &ID) const { + auto It = std::lower_bound( + Symbols.begin(), Symbols.end(), ID, + [](const Symbol &S, const SymbolID &I) { return S.ID < I; }); + if (It != Symbols.end() && It->ID == ID) + return It; + return Symbols.end(); +} + +// Copy the underlying data of the symbol into the owned arena. +static void own(Symbol &S, llvm::UniqueStringSaver &Strings) { + visitStrings(S, [&](llvm::StringRef &V) { V = Strings.save(V); }); +} + +void SymbolSlab::Builder::insert(const Symbol &S) { + auto R = SymbolIndex.try_emplace(S.ID, Symbols.size()); + if (R.second) { + Symbols.push_back(S); + own(Symbols.back(), UniqueStrings); + } else { + auto &Copy = Symbols[R.first->second] = S; + own(Copy, UniqueStrings); + } +} + +SymbolSlab SymbolSlab::Builder::build() && { + Symbols = {Symbols.begin(), Symbols.end()}; // Force shrink-to-fit. + // Sort symbols so the slab can binary search over them. + llvm::sort(Symbols, + [](const Symbol &L, const Symbol &R) { return L.ID < R.ID; }); + // We may have unused strings from overwritten symbols. Build a new arena. + llvm::BumpPtrAllocator NewArena; + llvm::UniqueStringSaver Strings(NewArena); + for (auto &S : Symbols) + own(S, Strings); + return SymbolSlab(std::move(NewArena), std::move(Symbols)); +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/index/Symbol.h b/clangd/index/Symbol.h new file mode 100644 index 00000000..a3e4fb91 --- /dev/null +++ b/clangd/index/Symbol.h @@ -0,0 +1,231 @@ +//===--- Symbol.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_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H + +#include "SymbolID.h" +#include "SymbolLocation.h" +#include "SymbolOrigin.h" +#include "clang/Index/IndexSymbol.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/StringSaver.h" + +namespace clang { +namespace clangd { + +/// The class presents a C++ symbol, e.g. class, function. +/// +/// WARNING: Symbols do not own much of their underlying data - typically +/// strings are owned by a SymbolSlab. They should be treated as non-owning +/// references. Copies are shallow. +/// +/// When adding new unowned data fields to Symbol, remember to update: +/// - SymbolSlab::Builder in Index.cpp, to copy them to the slab's storage. +/// - mergeSymbol in Merge.cpp, to properly combine two Symbols. +/// +/// A fully documented symbol can be split as: +/// size_type std::map::count(const K& key) const +/// | Return | Scope |Name| Signature | +/// We split up these components to allow display flexibility later. +struct Symbol { + /// The ID of the symbol. + SymbolID ID; + /// The symbol information, like symbol kind. + index::SymbolInfo SymInfo; + /// The unqualified name of the symbol, e.g. "bar" (for ns::bar). + llvm::StringRef Name; + /// The containing namespace. e.g. "" (global), "ns::" (top-level namespace). + llvm::StringRef Scope; + /// The location of the symbol's definition, if one was found. + /// This just covers the symbol name (e.g. without class/function body). + SymbolLocation Definition; + /// The location of the preferred declaration of the symbol. + /// This just covers the symbol name. + /// This may be the same as Definition. + /// + /// A C++ symbol may have multiple declarations, and we pick one to prefer. + /// * For classes, the canonical declaration should be the definition. + /// * For non-inline functions, the canonical declaration typically appears + /// in the ".h" file corresponding to the definition. + SymbolLocation CanonicalDeclaration; + /// The number of translation units that reference this symbol from their main + /// file. This number is only meaningful if aggregated in an index. + unsigned References = 0; + /// Where this symbol came from. Usually an index provides a constant value. + SymbolOrigin Origin = SymbolOrigin::Unknown; + /// A brief description of the symbol that can be appended in the completion + /// candidate list. For example, "(X x, Y y) const" is a function signature. + /// Only set when the symbol is indexed for completion. + llvm::StringRef Signature; + /// What to insert when completing this symbol, after the symbol name. + /// This is in LSP snippet syntax (e.g. "({$0})" for a no-args function). + /// (When snippets are disabled, the symbol name alone is used). + /// Only set when the symbol is indexed for completion. + llvm::StringRef CompletionSnippetSuffix; + /// Documentation including comment for the symbol declaration. + llvm::StringRef Documentation; + /// Type when this symbol is used in an expression. (Short display form). + /// e.g. return type of a function, or type of a variable. + /// Only set when the symbol is indexed for completion. + llvm::StringRef ReturnType; + + /// Raw representation of the OpaqueType of the symbol, used for scoring + /// purposes. + /// Only set when the symbol is indexed for completion. + llvm::StringRef Type; + + struct IncludeHeaderWithReferences { + IncludeHeaderWithReferences() = default; + + IncludeHeaderWithReferences(llvm::StringRef IncludeHeader, + unsigned References) + : IncludeHeader(IncludeHeader), References(References) {} + + /// This can be either a URI of the header to be #include'd + /// for this symbol, or a literal header quoted with <> or "" that is + /// suitable to be included directly. When it is a URI, the exact #include + /// path needs to be calculated according to the URI scheme. + /// + /// Note that the include header is a canonical include for the symbol and + /// can be different from FileURI in the CanonicalDeclaration. + llvm::StringRef IncludeHeader = ""; + /// The number of translation units that reference this symbol and include + /// this header. This number is only meaningful if aggregated in an index. + unsigned References = 0; + }; + /// One Symbol can potentially be incuded via different headers. + /// - If we haven't seen a definition, this covers all declarations. + /// - If we have seen a definition, this covers declarations visible from + /// any definition. + /// Only set when the symbol is indexed for completion. + llvm::SmallVector IncludeHeaders; + + enum SymbolFlag : uint8_t { + None = 0, + /// Whether or not this symbol is meant to be used for the code completion. + /// See also isIndexedForCodeCompletion(). + /// Note that we don't store completion information (signature, snippet, + /// type, inclues) if the symbol is not indexed for code completion. + IndexedForCodeCompletion = 1 << 0, + /// Indicates if the symbol is deprecated. + Deprecated = 1 << 1, + /// Symbol is an implementation detail. + ImplementationDetail = 1 << 2, + /// Symbol is visible to other files (not e.g. a static helper function). + VisibleOutsideFile = 1 << 3, + }; + + SymbolFlag Flags = SymbolFlag::None; + /// FIXME: also add deprecation message and fixit? +}; + +inline Symbol::SymbolFlag operator|(Symbol::SymbolFlag A, + Symbol::SymbolFlag B) { + return static_cast(static_cast(A) | + static_cast(B)); +} +inline Symbol::SymbolFlag &operator|=(Symbol::SymbolFlag &A, + Symbol::SymbolFlag B) { + return A = A | B; +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Symbol &S); +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, Symbol::SymbolFlag); + +/// Invokes Callback with each StringRef& contained in the Symbol. +/// Useful for deduplicating backing strings. +template void visitStrings(Symbol &S, const Callback &CB) { + CB(S.Name); + CB(S.Scope); + CB(S.Signature); + CB(S.CompletionSnippetSuffix); + CB(S.Documentation); + CB(S.ReturnType); + CB(S.Type); + auto RawCharPointerCB = [&CB](const char *&P) { + llvm::StringRef S(P); + CB(S); + assert(!S.data()[S.size()] && "Visited StringRef must be null-terminated"); + P = S.data(); + }; + RawCharPointerCB(S.CanonicalDeclaration.FileURI); + RawCharPointerCB(S.Definition.FileURI); + + for (auto &Include : S.IncludeHeaders) + CB(Include.IncludeHeader); +} + +/// Computes query-independent quality score for a Symbol. +/// This currently falls in the range [1, ln(#indexed documents)]. +/// FIXME: this should probably be split into symbol -> signals +/// and signals -> score, so it can be reused for Sema completions. +float quality(const Symbol &S); + +/// An immutable symbol container that stores a set of symbols. +/// The container will maintain the lifetime of the symbols. +class SymbolSlab { +public: + using const_iterator = std::vector::const_iterator; + using iterator = const_iterator; + using value_type = Symbol; + + SymbolSlab() = default; + + const_iterator begin() const { return Symbols.begin(); } + const_iterator end() const { return Symbols.end(); } + const_iterator find(const SymbolID &SymID) const; + + size_t size() const { return Symbols.size(); } + bool empty() const { return Symbols.empty(); } + // Estimates the total memory usage. + size_t bytes() const { + return sizeof(*this) + Arena.getTotalMemory() + + Symbols.capacity() * sizeof(Symbol); + } + + /// SymbolSlab::Builder is a mutable container that can 'freeze' to + /// SymbolSlab. The frozen SymbolSlab will use less memory. + class Builder { + public: + Builder() : UniqueStrings(Arena) {} + + /// Adds a symbol, overwriting any existing one with the same ID. + /// This is a deep copy: underlying strings will be owned by the slab. + void insert(const Symbol &S); + + /// Returns the symbol with an ID, if it exists. Valid until next insert(). + const Symbol *find(const SymbolID &ID) { + auto I = SymbolIndex.find(ID); + return I == SymbolIndex.end() ? nullptr : &Symbols[I->second]; + } + + /// Consumes the builder to finalize the slab. + SymbolSlab build() &&; + + private: + llvm::BumpPtrAllocator Arena; + /// Intern table for strings. Contents are on the arena. + llvm::UniqueStringSaver UniqueStrings; + std::vector Symbols; + /// Values are indices into Symbols vector. + llvm::DenseMap SymbolIndex; + }; + +private: + SymbolSlab(llvm::BumpPtrAllocator Arena, std::vector Symbols) + : Arena(std::move(Arena)), Symbols(std::move(Symbols)) {} + + llvm::BumpPtrAllocator Arena; // Owns Symbol data that the Symbols do not. + std::vector Symbols; // Sorted by SymbolID to allow lookup. +}; + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_SYMBOL_H -- cgit v1.2.3 From 5bb7e107484b928499e7150300eeb688c829dc0e Mon Sep 17 00:00:00 2001 From: Clement Courbet Date: Thu, 28 Feb 2019 13:39:01 +0000 Subject: [clang-tidy] bugprone-string-integer-assignment: Reduce false positives. Summary: Detect a few expressions as likely character expressions, see PR27723. Reviewers: xazax.hun, alexfh Subscribers: rnkovacs, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58609 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355089 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../bugprone/StringIntegerAssignmentCheck.cpp | 29 ++++++++++++++++++++++ .../bugprone-string-integer-assignment.cpp | 7 ++++++ 2 files changed, 36 insertions(+) diff --git a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp index 4288c2db..389ddc1c 100644 --- a/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp +++ b/clang-tidy/bugprone/StringIntegerAssignmentCheck.cpp @@ -45,11 +45,40 @@ void StringIntegerAssignmentCheck::registerMatchers(MatchFinder *Finder) { this); } +static bool isLikelyCharExpression(const Expr *Argument, + const ASTContext &Ctx) { + const auto *BinOp = dyn_cast(Argument); + if (!BinOp) + return false; + const auto *LHS = BinOp->getLHS()->IgnoreParenImpCasts(); + const auto *RHS = BinOp->getRHS()->IgnoreParenImpCasts(); + // & , mask is a compile time constant. + Expr::EvalResult RHSVal; + if (BinOp->getOpcode() == BO_And && + (RHS->EvaluateAsInt(RHSVal, Ctx, Expr::SE_AllowSideEffects) || + LHS->EvaluateAsInt(RHSVal, Ctx, Expr::SE_AllowSideEffects))) + return true; + // + ( % ), where is a char literal. + const auto IsCharPlusModExpr = [](const Expr *L, const Expr *R) { + const auto *ROp = dyn_cast(R); + return ROp && ROp->getOpcode() == BO_Rem && isa(L); + }; + if (BinOp->getOpcode() == BO_Add) { + if (IsCharPlusModExpr(LHS, RHS) || IsCharPlusModExpr(RHS, LHS)) + return true; + } + return false; +} + void StringIntegerAssignmentCheck::check( const MatchFinder::MatchResult &Result) { const auto *Argument = Result.Nodes.getNodeAs("expr"); SourceLocation Loc = Argument->getBeginLoc(); + // Try to detect a few common expressions to reduce false positives. + if (isLikelyCharExpression(Argument, *Result.Context)) + return; + auto Diag = diag(Loc, "an integer is interpreted as a character code when assigning " "it to a string; if this is intended, cast the integer to the " diff --git a/test/clang-tidy/bugprone-string-integer-assignment.cpp b/test/clang-tidy/bugprone-string-integer-assignment.cpp index 2b73f89b..dbf3a5c5 100644 --- a/test/clang-tidy/bugprone-string-integer-assignment.cpp +++ b/test/clang-tidy/bugprone-string-integer-assignment.cpp @@ -59,4 +59,11 @@ int main() { s += toupper(x); s += tolower(x); s += std::tolower(x); + + // Likely character expressions. + s += x & 0xff; + s += 0xff & x; + + s += 'a' + (x % 26); + s += (x % 10) + 'b'; } -- cgit v1.2.3 From 6914553317a3031ee3341d2006d9522d65c24e7a Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 13:49:25 +0000 Subject: Moved Ref into its own header and implementation file Reviewers: ioeric Subscribers: mgorny, jkorous, mgrang, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58778 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355090 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/AST.h | 3 +- clangd/CMakeLists.txt | 1 + clangd/IncludeFixer.cpp | 1 + clangd/Protocol.cpp | 1 - clangd/Quality.cpp | 3 +- clangd/index/Index.cpp | 48 +--------------- clangd/index/Index.h | 99 +------------------------------- clangd/index/Ref.cpp | 62 ++++++++++++++++++++ clangd/index/Ref.h | 119 +++++++++++++++++++++++++++++++++++++++ clangd/index/SymbolCollector.cpp | 1 + clangd/indexer/IndexerMain.cpp | 3 +- 11 files changed, 192 insertions(+), 149 deletions(-) create mode 100644 clangd/index/Ref.cpp create mode 100644 clangd/index/Ref.h diff --git a/clangd/AST.h b/clangd/AST.h index 15c46a4f..7798f1fe 100644 --- a/clangd/AST.h +++ b/clangd/AST.h @@ -13,9 +13,10 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_ #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_AST_H_ -#include "index/Index.h" +#include "index/SymbolID.h" #include "clang/AST/Decl.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Lex/MacroInfo.h" namespace clang { class SourceManager; diff --git a/clangd/CMakeLists.txt b/clangd/CMakeLists.txt index 2005c51d..5152d5fc 100644 --- a/clangd/CMakeLists.txt +++ b/clangd/CMakeLists.txt @@ -62,6 +62,7 @@ add_clang_library(clangDaemon index/IndexAction.cpp index/MemIndex.cpp index/Merge.cpp + index/Ref.cpp index/Serialization.cpp index/Symbol.cpp index/SymbolCollector.cpp diff --git a/clangd/IncludeFixer.cpp b/clangd/IncludeFixer.cpp index 8b934d17..978e35f7 100644 --- a/clangd/IncludeFixer.cpp +++ b/clangd/IncludeFixer.cpp @@ -24,6 +24,7 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TokenKinds.h" +#include "clang/Lex/Lexer.h" #include "clang/Sema/DeclSpec.h" #include "clang/Sema/Lookup.h" #include "clang/Sema/Scope.h" diff --git a/clangd/Protocol.cpp b/clangd/Protocol.cpp index ef6f491a..4864eedc 100644 --- a/clangd/Protocol.cpp +++ b/clangd/Protocol.cpp @@ -13,7 +13,6 @@ #include "Protocol.h" #include "Logger.h" #include "URI.h" -#include "index/Index.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/Hashing.h" #include "llvm/ADT/SmallString.h" diff --git a/clangd/Quality.cpp b/clangd/Quality.cpp index 50e3f7ee..124ae4c1 100644 --- a/clangd/Quality.cpp +++ b/clangd/Quality.cpp @@ -5,11 +5,12 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + #include "Quality.h" #include "AST.h" #include "FileDistance.h" #include "URI.h" -#include "index/Index.h" +#include "index/Symbol.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" diff --git a/clangd/index/Index.cpp b/clangd/index/Index.cpp index 6080066b..a5bfc672 100644 --- a/clangd/index/Index.cpp +++ b/clangd/index/Index.cpp @@ -12,57 +12,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" +#include namespace clang { namespace clangd { -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) { - if (K == RefKind::Unknown) - return OS << "Unknown"; - static const std::vector Messages = {"Decl", "Def", "Ref"}; - bool VisitedOnce = false; - for (unsigned I = 0; I < Messages.size(); ++I) { - if (static_cast(K) & 1u << I) { - if (VisitedOnce) - OS << ", "; - OS << Messages[I]; - VisitedOnce = true; - } - } - return OS; -} - -llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) { - return OS << R.Location << ":" << R.Kind; -} - -void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) { - auto &M = Refs[ID]; - M.push_back(S); - M.back().Location.FileURI = - UniqueStrings.save(M.back().Location.FileURI).data(); -} - -RefSlab RefSlab::Builder::build() && { - // We can reuse the arena, as it only has unique strings and we need them all. - // Reallocate refs on the arena to reduce waste and indirections when reading. - std::vector>> Result; - Result.reserve(Refs.size()); - size_t NumRefs = 0; - for (auto &Sym : Refs) { - auto &SymRefs = Sym.second; - llvm::sort(SymRefs); - // FIXME: do we really need to dedup? - SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end()); - - NumRefs += SymRefs.size(); - auto *Array = Arena.Allocate(SymRefs.size()); - std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array); - Result.emplace_back(Sym.first, llvm::ArrayRef(Array, SymRefs.size())); - } - return RefSlab(std::move(Result), std::move(Arena), NumRefs); -} - void SwapIndex::reset(std::unique_ptr Index) { // Keep the old index alive, so we don't destroy it under lock (may be slow). std::shared_ptr Pin; diff --git a/clangd/index/Index.h b/clangd/index/Index.h index f9541a6a..2954b387 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -9,116 +9,19 @@ #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_INDEX_H -#include "ExpectedTypes.h" +#include "Ref.h" #include "Symbol.h" #include "SymbolID.h" -#include "SymbolLocation.h" -#include "clang/Index/IndexSymbol.h" -#include "clang/Lex/Lexer.h" -#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Optional.h" -#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/StringRef.h" #include "llvm/Support/JSON.h" -#include -#include #include #include -#include namespace clang { namespace clangd { -// Describes the kind of a cross-reference. -// -// This is a bitfield which can be combined from different kinds. -enum class RefKind : uint8_t { - Unknown = 0, - Declaration = static_cast(index::SymbolRole::Declaration), - Definition = static_cast(index::SymbolRole::Definition), - Reference = static_cast(index::SymbolRole::Reference), - All = Declaration | Definition | Reference, -}; -inline RefKind operator|(RefKind L, RefKind R) { - return static_cast(static_cast(L) | - static_cast(R)); -} -inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; } -inline RefKind operator&(RefKind A, RefKind B) { - return static_cast(static_cast(A) & - static_cast(B)); -} -llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind); - -// Represents a symbol occurrence in the source file. -// Despite the name, it could be a declaration/definition/reference. -// -// WARNING: Location does not own the underlying data - Copies are shallow. -struct Ref { - // The source location where the symbol is named. - SymbolLocation Location; - RefKind Kind = RefKind::Unknown; -}; -inline bool operator<(const Ref &L, const Ref &R) { - return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind); -} -inline bool operator==(const Ref &L, const Ref &R) { - return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind); -} -llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &); - -// An efficient structure of storing large set of symbol references in memory. -// Filenames are deduplicated. -class RefSlab { -public: - using value_type = std::pair>; - using const_iterator = std::vector::const_iterator; - using iterator = const_iterator; - - RefSlab() = default; - RefSlab(RefSlab &&Slab) = default; - RefSlab &operator=(RefSlab &&RHS) = default; - - const_iterator begin() const { return Refs.begin(); } - const_iterator end() const { return Refs.end(); } - /// Gets the number of symbols. - size_t size() const { return Refs.size(); } - size_t numRefs() const { return NumRefs; } - bool empty() const { return Refs.empty(); } - - size_t bytes() const { - return sizeof(*this) + Arena.getTotalMemory() + - sizeof(value_type) * Refs.size(); - } - - // RefSlab::Builder is a mutable container that can 'freeze' to RefSlab. - class Builder { - public: - Builder() : UniqueStrings(Arena) {} - // Adds a ref to the slab. Deep copy: Strings will be owned by the slab. - void insert(const SymbolID &ID, const Ref &S); - // Consumes the builder to finalize the slab. - RefSlab build() &&; - - private: - llvm::BumpPtrAllocator Arena; - llvm::UniqueStringSaver UniqueStrings; // Contents on the arena. - llvm::DenseMap> Refs; - }; - -private: - RefSlab(std::vector Refs, llvm::BumpPtrAllocator Arena, - size_t NumRefs) - : Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {} - - llvm::BumpPtrAllocator Arena; - std::vector Refs; - // Number of all references. - size_t NumRefs = 0; -}; - struct FuzzyFindRequest { /// \brief A query string for the fuzzy find. This is matched against symbols' /// un-qualified identifiers and should not contain qualifiers like "::". diff --git a/clangd/index/Ref.cpp b/clangd/index/Ref.cpp new file mode 100644 index 00000000..9eb64505 --- /dev/null +++ b/clangd/index/Ref.cpp @@ -0,0 +1,62 @@ +//===--- Ref.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 "Ref.h" + +namespace clang { +namespace clangd { + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, RefKind K) { + if (K == RefKind::Unknown) + return OS << "Unknown"; + static const std::vector Messages = {"Decl", "Def", "Ref"}; + bool VisitedOnce = false; + for (unsigned I = 0; I < Messages.size(); ++I) { + if (static_cast(K) & 1u << I) { + if (VisitedOnce) + OS << ", "; + OS << Messages[I]; + VisitedOnce = true; + } + } + return OS; +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) { + return OS << R.Location << ":" << R.Kind; +} + +void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) { + auto &M = Refs[ID]; + M.push_back(S); + M.back().Location.FileURI = + UniqueStrings.save(M.back().Location.FileURI).data(); +} + +RefSlab RefSlab::Builder::build() && { + // We can reuse the arena, as it only has unique strings and we need them all. + // Reallocate refs on the arena to reduce waste and indirections when reading. + std::vector>> Result; + Result.reserve(Refs.size()); + size_t NumRefs = 0; + for (auto &Sym : Refs) { + auto &SymRefs = Sym.second; + llvm::sort(SymRefs); + // FIXME: do we really need to dedup? + SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end()); + + NumRefs += SymRefs.size(); + auto *Array = Arena.Allocate(SymRefs.size()); + std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array); + Result.emplace_back(Sym.first, llvm::ArrayRef(Array, SymRefs.size())); + } + return RefSlab(std::move(Result), std::move(Arena), NumRefs); +} + +} // namespace clangd +} // namespace clang diff --git a/clangd/index/Ref.h b/clangd/index/Ref.h new file mode 100644 index 00000000..738be7b9 --- /dev/null +++ b/clangd/index/Ref.h @@ -0,0 +1,119 @@ +//===--- Ref.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_TOOLS_EXTRA_CLANGD_INDEX_REF_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H + +#include "SymbolID.h" +#include "SymbolLocation.h" +#include "clang/Index/IndexSymbol.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Support/StringSaver.h" +#include "llvm/Support/raw_ostream.h" +#include +#include + +namespace clang { +namespace clangd { + +/// Describes the kind of a cross-reference. +/// +/// This is a bitfield which can be combined from different kinds. +enum class RefKind : uint8_t { + Unknown = 0, + Declaration = static_cast(index::SymbolRole::Declaration), + Definition = static_cast(index::SymbolRole::Definition), + Reference = static_cast(index::SymbolRole::Reference), + All = Declaration | Definition | Reference, +}; + +inline RefKind operator|(RefKind L, RefKind R) { + return static_cast(static_cast(L) | + static_cast(R)); +} +inline RefKind &operator|=(RefKind &L, RefKind R) { return L = L | R; } +inline RefKind operator&(RefKind A, RefKind B) { + return static_cast(static_cast(A) & + static_cast(B)); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &, RefKind); + +/// Represents a symbol occurrence in the source file. +/// Despite the name, it could be a declaration/definition/reference. +/// +/// WARNING: Location does not own the underlying data - Copies are shallow. +struct Ref { + /// The source location where the symbol is named. + SymbolLocation Location; + RefKind Kind = RefKind::Unknown; +}; + +inline bool operator<(const Ref &L, const Ref &R) { + return std::tie(L.Location, L.Kind) < std::tie(R.Location, R.Kind); +} +inline bool operator==(const Ref &L, const Ref &R) { + return std::tie(L.Location, L.Kind) == std::tie(R.Location, R.Kind); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &); + +/// An efficient structure of storing large set of symbol references in memory. +/// Filenames are deduplicated. +class RefSlab { +public: + using value_type = std::pair>; + using const_iterator = std::vector::const_iterator; + using iterator = const_iterator; + + RefSlab() = default; + RefSlab(RefSlab &&Slab) = default; + RefSlab &operator=(RefSlab &&RHS) = default; + + const_iterator begin() const { return Refs.begin(); } + const_iterator end() const { return Refs.end(); } + /// Gets the number of symbols. + size_t size() const { return Refs.size(); } + size_t numRefs() const { return NumRefs; } + bool empty() const { return Refs.empty(); } + + size_t bytes() const { + return sizeof(*this) + Arena.getTotalMemory() + + sizeof(value_type) * Refs.size(); + } + + /// RefSlab::Builder is a mutable container that can 'freeze' to RefSlab. + class Builder { + public: + Builder() : UniqueStrings(Arena) {} + /// Adds a ref to the slab. Deep copy: Strings will be owned by the slab. + void insert(const SymbolID &ID, const Ref &S); + /// Consumes the builder to finalize the slab. + RefSlab build() &&; + + private: + llvm::BumpPtrAllocator Arena; + llvm::UniqueStringSaver UniqueStrings; // Contents on the arena. + llvm::DenseMap> Refs; + }; + +private: + RefSlab(std::vector Refs, llvm::BumpPtrAllocator Arena, + size_t NumRefs) + : Arena(std::move(Arena)), Refs(std::move(Refs)), NumRefs(NumRefs) {} + + llvm::BumpPtrAllocator Arena; + std::vector Refs; + /// Number of all references. + size_t NumRefs = 0; +}; + +} // namespace clangd +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REF_H diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index 80b5c5b0..686b67b2 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -11,6 +11,7 @@ #include "CanonicalIncludes.h" #include "CodeComplete.h" #include "CodeCompletionStrings.h" +#include "ExpectedTypes.h" #include "Logger.h" #include "SourceCode.h" #include "SymbolLocation.h" diff --git a/clangd/indexer/IndexerMain.cpp b/clangd/indexer/IndexerMain.cpp index 1621e8f9..de29fc36 100644 --- a/clangd/indexer/IndexerMain.cpp +++ b/clangd/indexer/IndexerMain.cpp @@ -10,10 +10,11 @@ // //===----------------------------------------------------------------------===// -#include "index/Index.h" #include "index/IndexAction.h" #include "index/Merge.h" +#include "index/Ref.h" #include "index/Serialization.h" +#include "index/Symbol.h" #include "index/SymbolCollector.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Execution.h" -- cgit v1.2.3 From 17bf91eca4049c1b9fda644fd3a6869d6b4a5e12 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 14:00:26 +0000 Subject: Use ArrayRef::copy, instead of copying data manually Reviewers: ioeric Subscribers: jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58782 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355091 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Ref.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clangd/index/Ref.cpp b/clangd/index/Ref.cpp index 9eb64505..3f0fea56 100644 --- a/clangd/index/Ref.cpp +++ b/clangd/index/Ref.cpp @@ -51,9 +51,7 @@ RefSlab RefSlab::Builder::build() && { SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end()); NumRefs += SymRefs.size(); - auto *Array = Arena.Allocate(SymRefs.size()); - std::uninitialized_copy(SymRefs.begin(), SymRefs.end(), Array); - Result.emplace_back(Sym.first, llvm::ArrayRef(Array, SymRefs.size())); + Result.emplace_back(Sym.first, llvm::ArrayRef(SymRefs).copy(Arena)); } return RefSlab(std::move(Result), std::move(Arena), NumRefs); } -- cgit v1.2.3 From 0a4e1b1c0f68490e28af159dc0e6742c422e5204 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Thu, 28 Feb 2019 14:01:11 +0000 Subject: Added missing license headers Reviewers: ioeric Subscribers: jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58781 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355092 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ExpectedTypes.cpp | 8 ++++++++ clangd/index/IndexAction.cpp | 9 ++++++++- clangd/xpc/framework/ClangdXPC.cpp | 7 +++++++ clangd/xpc/test-client/ClangdXPCTestClient.cpp | 8 ++++++++ 4 files changed, 31 insertions(+), 1 deletion(-) diff --git a/clangd/ExpectedTypes.cpp b/clangd/ExpectedTypes.cpp index 59d9e149..886b5db0 100644 --- a/clangd/ExpectedTypes.cpp +++ b/clangd/ExpectedTypes.cpp @@ -1,3 +1,11 @@ +//===--- ExpectedTypes.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 "ExpectedTypes.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Type.h" diff --git a/clangd/index/IndexAction.cpp b/clangd/index/IndexAction.cpp index a88eca09..96c007d4 100644 --- a/clangd/index/IndexAction.cpp +++ b/clangd/index/IndexAction.cpp @@ -1,5 +1,12 @@ -#include "IndexAction.h" +//===--- IndexAction.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 "IndexAction.h" #include "index/SymbolOrigin.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Index/IndexDataConsumer.h" diff --git a/clangd/xpc/framework/ClangdXPC.cpp b/clangd/xpc/framework/ClangdXPC.cpp index 6c68f5cd..ceae0a78 100644 --- a/clangd/xpc/framework/ClangdXPC.cpp +++ b/clangd/xpc/framework/ClangdXPC.cpp @@ -1,3 +1,10 @@ +//===--- ClangXPC.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 +// +//===----------------------------------------------------------------------===// /// Returns the bundle identifier of the Clangd XPC service. extern "C" const char *clangd_xpc_get_bundle_identifier() { diff --git a/clangd/xpc/test-client/ClangdXPCTestClient.cpp b/clangd/xpc/test-client/ClangdXPCTestClient.cpp index da204a69..cf544280 100644 --- a/clangd/xpc/test-client/ClangdXPCTestClient.cpp +++ b/clangd/xpc/test-client/ClangdXPCTestClient.cpp @@ -1,3 +1,11 @@ +//===--- ClangXPCTestClient.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 "xpc/Conversion.h" #include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallString.h" -- cgit v1.2.3 From e7cea81418327e94141d699392c627a7d3a9686a Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 14:55:12 +0000 Subject: [clang-tidy] added cppcoreguidelines-explicit-virtual-functions Addresses the bugzilla bug #30397. (https://bugs.llvm.org/show_bug.cgi?id=30397) modernize-use-override suggests that destructors require the override specifier and the CPP core guidelines do not recommend this. Patch by lewmpk. Differential Revision: https://reviews.llvm.org/D58731 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355093 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp | 6 ++++++ clang-tidy/modernize/UseOverrideCheck.cpp | 13 ++++++++++++- clang-tidy/modernize/UseOverrideCheck.h | 7 ++++++- docs/ReleaseNotes.rst | 5 +++++ .../cppcoreguidelines-explicit-virtual-functions.rst | 10 ++++++++++ docs/clang-tidy/checks/modernize-use-override.rst | 8 +++++++- .../clang-tidy/modernize-use-override-no-destructors.cpp | 16 ++++++++++++++++ 7 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst create mode 100644 test/clang-tidy/modernize-use-override-no-destructors.cpp diff --git a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index fdf2880b..fc3a2ed3 100644 --- a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -12,6 +12,7 @@ #include "../misc/NonPrivateMemberVariablesInClassesCheck.h" #include "../misc/UnconventionalAssignOperatorCheck.h" #include "../modernize/AvoidCArraysCheck.h" +#include "../modernize/UseOverrideCheck.h" #include "../readability/MagicNumbersCheck.h" #include "AvoidGotoCheck.h" #include "InterfacesGlobalInitCheck.h" @@ -46,6 +47,8 @@ public: "cppcoreguidelines-avoid-goto"); CheckFactories.registerCheck( "cppcoreguidelines-avoid-magic-numbers"); + CheckFactories.registerCheck( + "cppcoreguidelines-explicit-virtual-functions"); CheckFactories.registerCheck( "cppcoreguidelines-interfaces-global-init"); CheckFactories.registerCheck( @@ -91,6 +94,9 @@ public: Opts["cppcoreguidelines-non-private-member-variables-in-classes." "IgnoreClassesWithAllMemberVariablesBeingPublic"] = "1"; + Opts["cppcoreguidelines-explicit-virtual-functions." + "IgnoreDestructors"] = "1"; + return Options; } }; diff --git a/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tidy/modernize/UseOverrideCheck.cpp index 6b065955..cd7ed6c1 100644 --- a/clang-tidy/modernize/UseOverrideCheck.cpp +++ b/clang-tidy/modernize/UseOverrideCheck.cpp @@ -17,9 +17,20 @@ namespace clang { namespace tidy { namespace modernize { +void UseOverrideCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IgnoreDestructors", IgnoreDestructors); +} + void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { // Only register the matcher for C++11. - if (getLangOpts().CPlusPlus11) + if (!getLangOpts().CPlusPlus11) + return; + + if (IgnoreDestructors) + Finder->addMatcher( + cxxMethodDecl(isOverride(), unless(cxxDestructorDecl())).bind("method"), + this); + else Finder->addMatcher(cxxMethodDecl(isOverride()).bind("method"), this); } diff --git a/clang-tidy/modernize/UseOverrideCheck.h b/clang-tidy/modernize/UseOverrideCheck.h index 0f316095..dc6c9184 100644 --- a/clang-tidy/modernize/UseOverrideCheck.h +++ b/clang-tidy/modernize/UseOverrideCheck.h @@ -19,9 +19,14 @@ namespace modernize { class UseOverrideCheck : public ClangTidyCheck { public: UseOverrideCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context) {} + : ClangTidyCheck(Name, Context), + IgnoreDestructors(Options.get("IgnoreDestructors", false)) {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + +private: + const bool IgnoreDestructors; }; } // namespace modernize diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 8d0c8f0a..698997b5 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -98,6 +98,11 @@ Improvements to clang-tidy Checks whether there are underscores in googletest test and test case names in test macros, which is prohibited by the Googletest FAQ. +- New alias :doc:`cppcoreguidelines-explicit-virtual-functions + ` to + :doc:`modernize-use-override + ` was added. + - The :doc:`bugprone-argument-comment ` now supports `CommentBoolLiterals`, `CommentIntegerLiterals`, `CommentFloatLiterals`, diff --git a/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst b/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst new file mode 100644 index 00000000..1af48ffd --- /dev/null +++ b/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst @@ -0,0 +1,10 @@ +.. title:: clang-tidy - cppcoreguidelines-explicit-virtual-functions +.. meta:: + :http-equiv=refresh: 5;URL=cppcoreguidelines-explicit-virtual-functions.html + +cppcoreguidelines-explicit-virtual-functions +============================================ + +The cppcoreguidelines-explicit-virtual-functions check is an alias, please see +`modernize-use-override `_ +for more information. diff --git a/docs/clang-tidy/checks/modernize-use-override.rst b/docs/clang-tidy/checks/modernize-use-override.rst index f2c778aa..54538b50 100644 --- a/docs/clang-tidy/checks/modernize-use-override.rst +++ b/docs/clang-tidy/checks/modernize-use-override.rst @@ -3,5 +3,11 @@ modernize-use-override ====================== - Use C++11's ``override`` and remove ``virtual`` where applicable. + +Options +------- + +.. option:: IgnoreDestructors + + If set to non-zero, this check will not diagnose destructors. Default is `0`. diff --git a/test/clang-tidy/modernize-use-override-no-destructors.cpp b/test/clang-tidy/modernize-use-override-no-destructors.cpp new file mode 100644 index 00000000..eaadb07b --- /dev/null +++ b/test/clang-tidy/modernize-use-override-no-destructors.cpp @@ -0,0 +1,16 @@ +// RUN: %check_clang_tidy %s modernize-use-override %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-override.IgnoreDestructors, value: 1}]}" \ +// RUN: -- -std=c++11 + +struct Base { + virtual ~Base(); + virtual void f(); +}; + +struct Simple : public Base { + virtual ~Simple(); + // CHECK-MESSAGES-NOT: warning: + virtual void f(); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void f() override; +}; -- cgit v1.2.3 From a230a9c1664e9d0cc356d0a7960f105b2c436971 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 15:01:17 +0000 Subject: [clang-tidy] attempt to fix documentation build-error git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355094 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/abseil-time-subtraction.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/clang-tidy/checks/abseil-time-subtraction.rst b/docs/clang-tidy/checks/abseil-time-subtraction.rst index 1b68d7c0..486a5ec6 100644 --- a/docs/clang-tidy/checks/abseil-time-subtraction.rst +++ b/docs/clang-tidy/checks/abseil-time-subtraction.rst @@ -8,9 +8,10 @@ in the Time domain instead of the numeric domain. There are two cases of Time subtraction in which deduce additional type information: - - When the result is an ``absl::Duration`` and the first argument is an - ``absl::Time``. - - When the second argument is a ``absl::Time``. + +- When the result is an ``absl::Duration`` and the first argument is an + ``absl::Time``. +- When the second argument is a ``absl::Time``. In the first case, we must know the result of the operation, since without that the second operand could be either an ``absl::Time`` or an ``absl::Duration``. -- cgit v1.2.3 From fd20559c758a0efd6687a3269d47c9869bfac97d Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 15:18:54 +0000 Subject: [clang-tidy] another issue in documentation, double empty line seemed to confuse code-block git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355095 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/abseil-duration-subtraction.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/clang-tidy/checks/abseil-duration-subtraction.rst b/docs/clang-tidy/checks/abseil-duration-subtraction.rst index 884eeb2c..5f11394b 100644 --- a/docs/clang-tidy/checks/abseil-duration-subtraction.rst +++ b/docs/clang-tidy/checks/abseil-duration-subtraction.rst @@ -21,7 +21,6 @@ Examples: // Suggestion - Subtraction in the absl::Duration domain instead double result = absl::ToDoubleSeconds(d - absl::Seconds(x)); - // Original - Subtraction of two Durations in the double domain absl::Duration d1, d2; double result = absl::ToDoubleSeconds(d1) - absl::ToDoubleSeconds(d2); -- cgit v1.2.3 From c1e090cb3d4bf6265f0039ee7735e4e0fd34a415 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 15:28:36 +0000 Subject: [clang-tidy] tryfix documenation continued git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355097 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/abseil-duration-subtraction.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/clang-tidy/checks/abseil-duration-subtraction.rst b/docs/clang-tidy/checks/abseil-duration-subtraction.rst index 5f11394b..b570931b 100644 --- a/docs/clang-tidy/checks/abseil-duration-subtraction.rst +++ b/docs/clang-tidy/checks/abseil-duration-subtraction.rst @@ -28,6 +28,7 @@ Examples: // Suggestion - Subtraction in the absl::Duration domain instead double result = absl::ToDoubleSeconds(d1 - d2); + Note: As with other ``clang-tidy`` checks, it is possible that multiple fixes may overlap (as in the case of nested expressions), so not all occurences can be transformed in one run. In particular, this may occur for nested subtraction -- cgit v1.2.3 From bc749d07fb2f3b1eaa1c8b987890666136b987b7 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 15:39:47 +0000 Subject: [clang-tidy] documentation fixing the actual correct file git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355098 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/abseil-time-subtraction.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/clang-tidy/checks/abseil-time-subtraction.rst b/docs/clang-tidy/checks/abseil-time-subtraction.rst index 486a5ec6..196c0736 100644 --- a/docs/clang-tidy/checks/abseil-time-subtraction.rst +++ b/docs/clang-tidy/checks/abseil-time-subtraction.rst @@ -21,6 +21,7 @@ subtracting an ``absl::Time`` from an ``absl::Duration`` is not defined. Examples: .. code-block:: c++ + int x; absl::Time t; -- cgit v1.2.3 From b21bf418e9c5df7aeed4a8504d5fa6ea33aefa71 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 15:47:10 +0000 Subject: [clang-tidy] include cppcoreguidelines-explicit-virtual-functions in list of checks and fix redirection git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355100 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst | 2 +- docs/clang-tidy/checks/list.rst | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst b/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst index 1af48ffd..87a8fe2d 100644 --- a/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst +++ b/docs/clang-tidy/checks/cppcoreguidelines-explicit-virtual-functions.rst @@ -1,6 +1,6 @@ .. title:: clang-tidy - cppcoreguidelines-explicit-virtual-functions .. meta:: - :http-equiv=refresh: 5;URL=cppcoreguidelines-explicit-virtual-functions.html + :http-equiv=refresh: 5;URL=modernize-use-override.html cppcoreguidelines-explicit-virtual-functions ============================================ diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 42318a53..2c89f47f 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -99,6 +99,7 @@ Clang-Tidy Checks cppcoreguidelines-avoid-goto cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) + cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) cppcoreguidelines-interfaces-global-init cppcoreguidelines-macro-usage cppcoreguidelines-narrowing-conversions -- cgit v1.2.3 From 564b8a1bf0ccc599e44827c1383789a448220f98 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 15:56:40 +0000 Subject: [clang-tidy] redirection in list of checks adjusted git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355102 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/list.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 2c89f47f..7ec509a0 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -99,7 +99,7 @@ Clang-Tidy Checks cppcoreguidelines-avoid-goto cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) - cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) + cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) cppcoreguidelines-interfaces-global-init cppcoreguidelines-macro-usage cppcoreguidelines-narrowing-conversions -- cgit v1.2.3 From be92837154090c6fc4b15cf558095b91211c6307 Mon Sep 17 00:00:00 2001 From: Jonas Toth Date: Thu, 28 Feb 2019 17:53:51 +0000 Subject: [clang-tidy] fix documentation link in list of clang-tidy checks git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355108 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/list.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 7ec509a0..353ea376 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -99,7 +99,7 @@ Clang-Tidy Checks cppcoreguidelines-avoid-goto cppcoreguidelines-avoid-magic-numbers (redirects to readability-magic-numbers) cppcoreguidelines-c-copy-assignment-signature (redirects to misc-unconventional-assign-operator) - cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) + cppcoreguidelines-explicit-virtual-functions (redirects to modernize-use-override) cppcoreguidelines-interfaces-global-init cppcoreguidelines-macro-usage cppcoreguidelines-narrowing-conversions -- cgit v1.2.3 From 7bf55cd6b2f2858f10edf38a76946ce744b8f65d Mon Sep 17 00:00:00 2001 From: Paul Hoad Date: Thu, 28 Feb 2019 20:00:48 +0000 Subject: [clang-tidy] add OverrideMacro to modernize-use-override check Summary: The usefulness of **modernize-use-override** can be reduced if you have to live in an environment where you support multiple compilers, some of which sadly are not yet fully C++11 compliant some codebases have to use override as a macro OVERRIDE e.g. ``` // GCC 4.7 supports explicit virtual overrides when C++11 support is enabled. ``` This allows code to be compiled with C++11 compliant compilers and get warnings and errors that clang, MSVC,gcc can give, while still allowing other legacy pre C++11 compilers to compile the code. This can be an important step towards modernizing C++ code whilst living in a legacy codebase. When it comes to clang tidy, the use of the **modernize-use-override** is one of the most useful checks, but the messages reported are inaccurate for that codebase if the standard approach is to use the macros OVERRIDE and/or FINAL. When combined with fix-its that introduce the C++11 override keyword, they become fatal, resulting in the modernize-use-override check being turned off to prevent the introduction of such errors. This revision, allows the possibility for the replacement **override **to be a macro instead, Allowing the clang-tidy check to be run on both pre and post C++11 code, and allowing fix-its to be applied. Reviewers: alexfh, JonasToth, hokein, Eugene.Zelenko, aaron.ballman Reviewed By: alexfh, JonasToth Subscribers: lewmpk, malcolm.parsons, jdoerfert, xazax.hun, cfe-commits, llvm-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D57087 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355132 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/modernize/UseOverrideCheck.cpp | 50 ++++++++++------ clang-tidy/modernize/UseOverrideCheck.h | 7 ++- docs/ReleaseNotes.rst | 6 +- docs/clang-tidy/checks/modernize-use-override.rst | 33 +++++++++- .../modernize-use-override-with-macro.cpp | 70 ++++++++++++++++++++++ ...odernize-use-override-with-no-macro-inscope.cpp | 28 +++++++++ 6 files changed, 172 insertions(+), 22 deletions(-) create mode 100644 test/clang-tidy/modernize-use-override-with-macro.cpp create mode 100644 test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp diff --git a/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tidy/modernize/UseOverrideCheck.cpp index cd7ed6c1..2f15213d 100644 --- a/clang-tidy/modernize/UseOverrideCheck.cpp +++ b/clang-tidy/modernize/UseOverrideCheck.cpp @@ -17,8 +17,16 @@ namespace clang { namespace tidy { namespace modernize { +UseOverrideCheck::UseOverrideCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IgnoreDestructors(Options.get("IgnoreDestructors", false)), + OverrideSpelling(Options.get("OverrideSpelling", "override")), + FinalSpelling(Options.get("FinalSpelling", "final")) {} + void UseOverrideCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreDestructors", IgnoreDestructors); + Options.store(Opts, "OverrideSpelling", OverrideSpelling); + Options.store(Opts, "FinalSpelling", FinalSpelling); } void UseOverrideCheck::registerMatchers(MatchFinder *Finder) { @@ -78,6 +86,8 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { const auto *Method = Result.Nodes.getNodeAs("method"); const SourceManager &Sources = *Result.SourceManager; + ASTContext &Context = *Result.Context; + assert(Method != nullptr); if (Method->getInstantiatedFromMemberFunction() != nullptr) Method = Method->getInstantiatedFromMemberFunction(); @@ -97,25 +107,24 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { return; // Nothing to do. std::string Message; - if (OnlyVirtualSpecified) { - Message = - "prefer using 'override' or (rarely) 'final' instead of 'virtual'"; + Message = "prefer using '%0' or (rarely) '%1' instead of 'virtual'"; } else if (KeywordCount == 0) { - Message = "annotate this function with 'override' or (rarely) 'final'"; + Message = "annotate this function with '%0' or (rarely) '%1'"; } else { StringRef Redundant = - HasVirtual ? (HasOverride && HasFinal ? "'virtual' and 'override' are" + HasVirtual ? (HasOverride && HasFinal ? "'virtual' and '%0' are" : "'virtual' is") - : "'override' is"; - StringRef Correct = HasFinal ? "'final'" : "'override'"; + : "'%0' is"; + StringRef Correct = HasFinal ? "'%1'" : "'%0'"; Message = (llvm::Twine(Redundant) + " redundant since the function is already declared " + Correct) .str(); } - DiagnosticBuilder Diag = diag(Method->getLocation(), Message); + auto Diag = diag(Method->getLocation(), Message) + << OverrideSpelling << FinalSpelling; CharSourceRange FileRange = Lexer::makeFileCharRange( CharSourceRange::getTokenRange(Method->getSourceRange()), Sources, @@ -132,7 +141,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { // Add 'override' on inline declarations that don't already have it. if (!HasFinal && !HasOverride) { SourceLocation InsertLoc; - StringRef ReplacementText = "override "; + std::string ReplacementText = OverrideSpelling + " "; SourceLocation MethodLoc = Method->getLocation(); for (Token T : Tokens) { @@ -162,7 +171,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { // end of the declaration of the function, but prefer to put it on the // same line as the declaration if the beginning brace for the start of // the body falls on the next line. - ReplacementText = " override"; + ReplacementText = " " + OverrideSpelling; auto LastTokenIter = std::prev(Tokens.end()); // When try statement is used instead of compound statement as // method body - insert override keyword before it. @@ -175,23 +184,30 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) { // For declarations marked with "= 0" or "= [default|delete]", the end // location will point until after those markings. Therefore, the override // keyword shouldn't be inserted at the end, but before the '='. - if (Tokens.size() > 2 && (GetText(Tokens.back(), Sources) == "0" || - Tokens.back().is(tok::kw_default) || - Tokens.back().is(tok::kw_delete)) && + if (Tokens.size() > 2 && + (GetText(Tokens.back(), Sources) == "0" || + Tokens.back().is(tok::kw_default) || + Tokens.back().is(tok::kw_delete)) && GetText(Tokens[Tokens.size() - 2], Sources) == "=") { InsertLoc = Tokens[Tokens.size() - 2].getLocation(); // Check if we need to insert a space. if ((Tokens[Tokens.size() - 2].getFlags() & Token::LeadingSpace) == 0) - ReplacementText = " override "; - } else if (GetText(Tokens.back(), Sources) == "ABSTRACT") { + ReplacementText = " " + OverrideSpelling + " "; + } else if (GetText(Tokens.back(), Sources) == "ABSTRACT") InsertLoc = Tokens.back().getLocation(); - } } if (!InsertLoc.isValid()) { InsertLoc = FileRange.getEnd(); - ReplacementText = " override"; + ReplacementText = " " + OverrideSpelling; } + + // If the override macro has been specified just ensure it exists, + // if not don't apply a fixit but keep the warning. + if (OverrideSpelling != "override" && + !Context.Idents.get(OverrideSpelling).hasMacroDefinition()) + return; + Diag << FixItHint::CreateInsertion(InsertLoc, ReplacementText); } diff --git a/clang-tidy/modernize/UseOverrideCheck.h b/clang-tidy/modernize/UseOverrideCheck.h index dc6c9184..976a7ae8 100644 --- a/clang-tidy/modernize/UseOverrideCheck.h +++ b/clang-tidy/modernize/UseOverrideCheck.h @@ -18,15 +18,16 @@ namespace modernize { /// Use C++11's `override` and remove `virtual` where applicable. class UseOverrideCheck : public ClangTidyCheck { public: - UseOverrideCheck(StringRef Name, ClangTidyContext *Context) - : ClangTidyCheck(Name, Context), - IgnoreDestructors(Options.get("IgnoreDestructors", false)) {} + UseOverrideCheck(StringRef Name, ClangTidyContext *Context); + void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; void storeOptions(ClangTidyOptions::OptionMap &Opts) override; private: const bool IgnoreDestructors; + const std::string OverrideSpelling; + const std::string FinalSpelling; }; } // namespace modernize diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 698997b5..3d3edef3 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -105,7 +105,7 @@ Improvements to clang-tidy - The :doc:`bugprone-argument-comment ` now supports - `CommentBoolLiterals`, `CommentIntegerLiterals`, `CommentFloatLiterals`, + `CommentBoolLiterals`, `CommentIntegerLiterals`, `CommentFloatLiterals`, `CommentUserDefiniedLiterals`, `CommentStringLiterals`, `CommentCharacterLiterals` & `CommentNullPtrs` options. @@ -113,6 +113,10 @@ Improvements to clang-tidy :doc:`objc-property-declaration ` check have been removed. +- The :doc:`modernize-use-override + ` now supports `OverrideSpelling` + and `FinalSpelling` options. + Improvements to include-fixer ----------------------------- diff --git a/docs/clang-tidy/checks/modernize-use-override.rst b/docs/clang-tidy/checks/modernize-use-override.rst index 54538b50..4273c6e5 100644 --- a/docs/clang-tidy/checks/modernize-use-override.rst +++ b/docs/clang-tidy/checks/modernize-use-override.rst @@ -3,7 +3,22 @@ modernize-use-override ====================== -Use C++11's ``override`` and remove ``virtual`` where applicable. +Adds ``override`` (introduced in C++11) to overridden virtual functions and +removes ``virtual`` from those functions as it is not required. + +``virtual`` on non base class implementations was used to help indiciate to the +user that a function was virtual. C++ compilers did not use the presence of +this to signify an overriden function. + +In C++ 11 ``override`` and ``final`` keywords were introduced to allow +overridden functions to be marked appropriately. Their presence allows +compilers to verify that an overridden function correctly overrides a base +class implementation. + +This can be useful as compilers can generate a compile time error when: + + - The base class implementation function signature changes. + - The user has not created the override with the correct signature. Options ------- @@ -11,3 +26,19 @@ Options .. option:: IgnoreDestructors If set to non-zero, this check will not diagnose destructors. Default is `0`. + +.. option:: OverrideSpelling + + Specifies a macro to use instead of ``override``. This is useful when + maintaining source code that also needs to compile with a pre-C++11 + compiler. + +.. option:: FinalSpelling + + Specifies a macro to use instead of ``final``. This is useful when + maintaining source code that also needs to compile with a pre-C++11 + compiler. + +.. note:: + + For more information on the use of ``override`` see https://en.cppreference.com/w/cpp/language/override diff --git a/test/clang-tidy/modernize-use-override-with-macro.cpp b/test/clang-tidy/modernize-use-override-with-macro.cpp new file mode 100644 index 00000000..ad682f15 --- /dev/null +++ b/test/clang-tidy/modernize-use-override-with-macro.cpp @@ -0,0 +1,70 @@ +// RUN: %check_clang_tidy %s modernize-use-override %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-override.OverrideSpelling, value: 'OVERRIDE'},{key: modernize-use-override.FinalSpelling, value: 'FINAL'}]}" \ +// RUN: -- -std=c++11 + +#define ABSTRACT = 0 + +#define OVERRIDE override +#define FINAL final +#define VIRTUAL virtual +#define NOT_VIRTUAL +#define NOT_OVERRIDE + +#define MUST_USE_RESULT __attribute__((warn_unused_result)) +#define UNUSED __attribute__((unused)) + +struct Base { + virtual ~Base() {} + virtual void a(); + virtual void b(); + virtual void c(); + virtual void e() = 0; + virtual void f2() const = 0; + virtual void g() = 0; + virtual void j() const; + virtual void k() = 0; + virtual void l() const; +}; + +struct SimpleCases : public Base { +public: + virtual ~SimpleCases(); + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'OVERRIDE' or (rarely) 'FINAL' instead of 'virtual' [modernize-use-override] + // CHECK-FIXES: {{^}} ~SimpleCases() OVERRIDE; + + void a(); + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this function with 'OVERRIDE' or (rarely) 'FINAL' [modernize-use-override] + // CHECK-FIXES: {{^}} void a() OVERRIDE; + + virtual void b(); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'OVERRIDE' or (rarely) 'FINAL' instead of 'virtual' [modernize-use-override] + // CHECK-FIXES: {{^}} void b() OVERRIDE; + + virtual void c(); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void c() OVERRIDE; + + virtual void e() = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void e() OVERRIDE = 0; + + virtual void f2() const = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void f2() const OVERRIDE = 0; + + virtual void g() ABSTRACT; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void g() OVERRIDE ABSTRACT; + + virtual void j() const; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void j() const OVERRIDE; + + virtual void k() OVERRIDE; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'OVERRIDE' [modernize-use-override] + // CHECK-FIXES: {{^}} void k() OVERRIDE; + + virtual void l() const OVERRIDE; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'OVERRIDE' [modernize-use-override] + // CHECK-FIXES: {{^}} void l() const OVERRIDE; +}; diff --git a/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp b/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp new file mode 100644 index 00000000..97b71053 --- /dev/null +++ b/test/clang-tidy/modernize-use-override-with-no-macro-inscope.cpp @@ -0,0 +1,28 @@ +// RUN: %check_clang_tidy %s modernize-use-override %t -- \ +// RUN: -config="{CheckOptions: [{key: modernize-use-override.OverrideSpelling, value: 'CUSTOM_OVERRIDE'},{key: modernize-use-override.FinalSpelling, value: 'CUSTOM_FINAL'}]}" \ +// RUN: -- -std=c++11 + +// As if the macro was not defined. +//#define CUSTOM_OVERRIDE override +//#define CUSTOM_FINAL override + +struct Base { + virtual ~Base() {} + virtual void a(); + virtual void b(); +}; + +struct SimpleCases : public Base { +public: + virtual ~SimpleCases(); + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' instead of 'virtual' [modernize-use-override] + // CHECK-FIXES: {{^}} virtual ~SimpleCases(); + + void a(); + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this function with 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' [modernize-use-override] + // CHECK-FIXES: {{^}} void a(); + + virtual void b(); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using 'CUSTOM_OVERRIDE' or (rarely) 'CUSTOM_FINAL' instead of 'virtual' [modernize-use-override] + // CHECK-FIXES: {{^}} virtual void b(); +}; -- cgit v1.2.3 From 6bf32fdbd5d7ac460c5c491d264dc1ba1c8c4346 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Fri, 1 Mar 2019 09:52:53 +0000 Subject: Fix file headers. NFC git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355188 91177308-0d34-0410-b5e6-96231b3b80d8 --- change-namespace/tool/ClangChangeNamespace.cpp | 2 +- clang-doc/Generators.cpp | 2 +- clang-doc/Serialize.cpp | 2 +- clang-doc/YAMLGenerator.cpp | 2 +- clang-move/HelperDeclRefGraph.cpp | 2 +- clang-tidy/cert/CommandProcessorCheck.cpp | 2 +- clang-tidy/cert/StrToNumCheck.cpp | 2 +- clang-tidy/cert/VariadicFunctionDefCheck.cpp | 2 +- clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp | 2 +- clang-tidy/performance/PerformanceTidyModule.cpp | 2 +- clang-tidy/readability/FunctionSizeCheck.cpp | 2 +- clang-tidy/readability/SimplifyBooleanExprCheck.cpp | 2 +- clang-tidy/readability/StringCompareCheck.cpp | 2 +- clang-tidy/utils/OptionsUtils.cpp | 2 +- clangd/index/YAMLSerialization.cpp | 2 +- clangd/xpc/framework/ClangdXPC.cpp | 2 +- clangd/xpc/test-client/ClangdXPCTestClient.cpp | 2 +- unittests/clang-move/ClangMoveTests.cpp | 2 +- unittests/clang-query/QueryEngineTest.cpp | 2 +- unittests/clangd/FunctionTests.cpp | 2 +- unittests/clangd/QualityTests.cpp | 2 +- unittests/clangd/TestIndex.cpp | 2 +- 22 files changed, 22 insertions(+), 22 deletions(-) diff --git a/change-namespace/tool/ClangChangeNamespace.cpp b/change-namespace/tool/ClangChangeNamespace.cpp index 0d515029..d5f06552 100644 --- a/change-namespace/tool/ClangChangeNamespace.cpp +++ b/change-namespace/tool/ClangChangeNamespace.cpp @@ -1,4 +1,4 @@ -//===-- ClangIncludeFixer.cpp - Standalone change namespace ---------------===// +//===-- ClangChangeNamespace.cpp - Standalone change namespace ------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-doc/Generators.cpp b/clang-doc/Generators.cpp index e57a2617..e3b672ad 100644 --- a/clang-doc/Generators.cpp +++ b/clang-doc/Generators.cpp @@ -1,4 +1,4 @@ -//===---- Generator.cpp - Generator Registry ---------------------*- C++-*-===// +//===-- Generators.cpp - Generator Registry ----------------------*- C++-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-doc/Serialize.cpp b/clang-doc/Serialize.cpp index 897fed56..2bd54cf2 100644 --- a/clang-doc/Serialize.cpp +++ b/clang-doc/Serialize.cpp @@ -1,4 +1,4 @@ -//===-- Serializer.cpp - ClangDoc Serializer --------------------*- C++ -*-===// +//===-- Serialize.cpp - ClangDoc Serializer ---------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-doc/YAMLGenerator.cpp b/clang-doc/YAMLGenerator.cpp index ceb42153..94fb9f98 100644 --- a/clang-doc/YAMLGenerator.cpp +++ b/clang-doc/YAMLGenerator.cpp @@ -1,4 +1,4 @@ -//===-- ClangDocYAML.cpp - ClangDoc YAML -----------------------*- C++ -*-===// +//===-- YAMLGenerator.cpp - ClangDoc YAML -----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-move/HelperDeclRefGraph.cpp b/clang-move/HelperDeclRefGraph.cpp index 93a0f879..205a42dc 100644 --- a/clang-move/HelperDeclRefGraph.cpp +++ b/clang-move/HelperDeclRefGraph.cpp @@ -1,4 +1,4 @@ -//===-- UsedHelperDeclFinder.cpp - AST-based call graph for helper decls --===// +//===-- HelperDeclRefGraph.cpp - AST-based call graph for helper decls ----===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/cert/CommandProcessorCheck.cpp b/clang-tidy/cert/CommandProcessorCheck.cpp index cfc2f373..72b39d18 100644 --- a/clang-tidy/cert/CommandProcessorCheck.cpp +++ b/clang-tidy/cert/CommandProcessorCheck.cpp @@ -1,4 +1,4 @@ -//===--- Env33CCheck.cpp - clang-tidy--------------------------------------===// +//===-- CommandProcessorCheck.cpp - clang-tidy ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/cert/StrToNumCheck.cpp b/clang-tidy/cert/StrToNumCheck.cpp index 38e2dc00..9d26060c 100644 --- a/clang-tidy/cert/StrToNumCheck.cpp +++ b/clang-tidy/cert/StrToNumCheck.cpp @@ -1,4 +1,4 @@ -//===--- Err34CCheck.cpp - clang-tidy--------------------------------------===// +//===-- StrToNumCheck.cpp - clang-tidy ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/cert/VariadicFunctionDefCheck.cpp b/clang-tidy/cert/VariadicFunctionDefCheck.cpp index 4fe6b7af..8ee67f91 100644 --- a/clang-tidy/cert/VariadicFunctionDefCheck.cpp +++ b/clang-tidy/cert/VariadicFunctionDefCheck.cpp @@ -1,4 +1,4 @@ -//===--- VariadicfunctiondefCheck.cpp - clang-tidy-------------------------===// +//===-- VariadicFunctionDefCheck.cpp - clang-tidy -------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp index fc3a2ed3..7c7fd1b7 100644 --- a/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp +++ b/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp @@ -1,4 +1,4 @@ -//===--- CppCoreGuidelinesModule.cpp - clang-tidy -------------------------===// +//===-- CppCoreGuidelinesTidyModule.cpp - clang-tidy ----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/performance/PerformanceTidyModule.cpp b/clang-tidy/performance/PerformanceTidyModule.cpp index 0a5a0be2..f4b620a1 100644 --- a/clang-tidy/performance/PerformanceTidyModule.cpp +++ b/clang-tidy/performance/PerformanceTidyModule.cpp @@ -1,4 +1,4 @@ -//===--- PeformanceTidyModule.cpp - clang-tidy ----------------------------===// +//===-- PerformanceTidyModule.cpp - clang-tidy ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/readability/FunctionSizeCheck.cpp b/clang-tidy/readability/FunctionSizeCheck.cpp index 7be502bf..d98bec2e 100644 --- a/clang-tidy/readability/FunctionSizeCheck.cpp +++ b/clang-tidy/readability/FunctionSizeCheck.cpp @@ -1,4 +1,4 @@ -//===--- FunctionSize.cpp - clang-tidy ------------------------------------===// +//===-- FunctionSizeCheck.cpp - clang-tidy --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp index aa58ad11..ef88d44f 100644 --- a/clang-tidy/readability/SimplifyBooleanExprCheck.cpp +++ b/clang-tidy/readability/SimplifyBooleanExprCheck.cpp @@ -1,4 +1,4 @@ -//===--- SimplifyBooleanExpr.cpp clang-tidy ---------------------*- C++ -*-===// +//===-- SimplifyBooleanExprCheck.cpp - clang-tidy -------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/readability/StringCompareCheck.cpp b/clang-tidy/readability/StringCompareCheck.cpp index 395f406a..1064c3a8 100644 --- a/clang-tidy/readability/StringCompareCheck.cpp +++ b/clang-tidy/readability/StringCompareCheck.cpp @@ -1,4 +1,4 @@ -//===--- MiscStringCompare.cpp - clang-tidy--------------------------------===// +//===-- StringCompareCheck.cpp - clang-tidy--------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clang-tidy/utils/OptionsUtils.cpp b/clang-tidy/utils/OptionsUtils.cpp index 30b76643..36f4b6fc 100644 --- a/clang-tidy/utils/OptionsUtils.cpp +++ b/clang-tidy/utils/OptionsUtils.cpp @@ -1,4 +1,4 @@ -//===--- DanglingHandleCheck.cpp - clang-tidy------------------------------===// +//===-- OptionsUtils.cpp - clang-tidy -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/clangd/index/YAMLSerialization.cpp b/clangd/index/YAMLSerialization.cpp index 733f4c4b..84d6cd99 100644 --- a/clangd/index/YAMLSerialization.cpp +++ b/clangd/index/YAMLSerialization.cpp @@ -1,4 +1,4 @@ -//===--- SymbolYAML.cpp ------------------------------------------*- C++-*-===// +//===-- YAMLSerialization.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. diff --git a/clangd/xpc/framework/ClangdXPC.cpp b/clangd/xpc/framework/ClangdXPC.cpp index ceae0a78..3b86164e 100644 --- a/clangd/xpc/framework/ClangdXPC.cpp +++ b/clangd/xpc/framework/ClangdXPC.cpp @@ -1,4 +1,4 @@ -//===--- ClangXPC.cpp --------------------------------------------*- C++-*-===// +//===-- ClangdXPC.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. diff --git a/clangd/xpc/test-client/ClangdXPCTestClient.cpp b/clangd/xpc/test-client/ClangdXPCTestClient.cpp index cf544280..06ecddec 100644 --- a/clangd/xpc/test-client/ClangdXPCTestClient.cpp +++ b/clangd/xpc/test-client/ClangdXPCTestClient.cpp @@ -1,4 +1,4 @@ -//===--- ClangXPCTestClient.cpp ----------------------------------*- C++-*-===// +//===-- ClangdXPCTestClient.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. diff --git a/unittests/clang-move/ClangMoveTests.cpp b/unittests/clang-move/ClangMoveTests.cpp index 0385a799..7b005cdd 100644 --- a/unittests/clang-move/ClangMoveTests.cpp +++ b/unittests/clang-move/ClangMoveTests.cpp @@ -1,4 +1,4 @@ -//===-- ClangMoveTest.cpp - clang-move unit tests -------------------------===// +//===-- ClangMoveTests.cpp - clang-move unit tests ------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/unittests/clang-query/QueryEngineTest.cpp b/unittests/clang-query/QueryEngineTest.cpp index df3be130..6d728cee 100644 --- a/unittests/clang-query/QueryEngineTest.cpp +++ b/unittests/clang-query/QueryEngineTest.cpp @@ -1,4 +1,4 @@ -//===---- QueryTest.cpp - clang-query test --------------------------------===// +//===-- QueryEngineTest.cpp - clang-query test ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/unittests/clangd/FunctionTests.cpp b/unittests/clangd/FunctionTests.cpp index dc12186d..0cd8b791 100644 --- a/unittests/clangd/FunctionTests.cpp +++ b/unittests/clangd/FunctionTests.cpp @@ -1,4 +1,4 @@ -//===-- FunctionsTests.cpp ------------------------------------------------===// +//===-- FunctionTests.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/unittests/clangd/QualityTests.cpp b/unittests/clangd/QualityTests.cpp index e2fe8f3a..b797a48f 100644 --- a/unittests/clangd/QualityTests.cpp +++ b/unittests/clangd/QualityTests.cpp @@ -1,4 +1,4 @@ -//===-- SourceCodeTests.cpp ------------------------------------*- C++ -*-===// +//===-- QualityTests.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. diff --git a/unittests/clangd/TestIndex.cpp b/unittests/clangd/TestIndex.cpp index 877bb75e..89e9646f 100644 --- a/unittests/clangd/TestIndex.cpp +++ b/unittests/clangd/TestIndex.cpp @@ -1,4 +1,4 @@ -//===-- IndexHelpers.cpp ----------------------------------------*- C++ -*-===// +//===-- TestIndex.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. -- cgit v1.2.3 From a075b9fc3fe7356875c9e33e7303e9872bd59e47 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Fri, 1 Mar 2019 14:17:55 +0000 Subject: [clangd] Enable SuggestMissingIncludes by default. Summary: This seems to work stably now. Turn on by default. Reviewers: kadircet Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58772 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355200 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/tool/ClangdMain.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/tool/ClangdMain.cpp b/clangd/tool/ClangdMain.cpp index 2e2fcbd1..53f7264e 100644 --- a/clangd/tool/ClangdMain.cpp +++ b/clangd/tool/ClangdMain.cpp @@ -217,7 +217,7 @@ static llvm::cl::opt SuggestMissingIncludes( "suggest-missing-includes", llvm::cl::desc("Attempts to fix diagnostic errors caused by missing " "includes using index."), - llvm::cl::init(false)); + llvm::cl::init(true)); namespace { -- cgit v1.2.3 From b8e003b6b87fd2b42ba652f672010675ad7e47cc Mon Sep 17 00:00:00 2001 From: Shoaib Meenai Date: Mon, 4 Mar 2019 21:19:53 +0000 Subject: [build] Rename clang-headers to clang-resource-headers Summary: The current install-clang-headers target installs clang's resource directory headers. This is different from the install-llvm-headers target, which installs LLVM's API headers. We want to introduce the corresponding target to clang, and the natural name for that new target would be install-clang-headers. Rename the existing target to install-clang-resource-headers to free up the install-clang-headers name for the new target, following the discussion on cfe-dev [1]. I didn't find any bots on zorg referencing install-clang-headers. I'll send out another PSA to cfe-dev to accompany this rename. [1] http://lists.llvm.org/pipermail/cfe-dev/2019-February/061365.html Reviewers: beanz, phosek, tstellar, rnk, dim, serge-sans-paille Subscribers: mgorny, javed.absar, jdoerfert, #sanitizers, openmp-commits, lldb-commits, cfe-commits, llvm-commits Tags: #clang, #sanitizers, #lldb, #openmp, #llvm Differential Revision: https://reviews.llvm.org/D58791 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355340 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/tool/CMakeLists.txt | 2 +- test/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang-tidy/tool/CMakeLists.txt b/clang-tidy/tool/CMakeLists.txt index f58cfea5..41107355 100644 --- a/clang-tidy/tool/CMakeLists.txt +++ b/clang-tidy/tool/CMakeLists.txt @@ -9,7 +9,7 @@ add_clang_tool(clang-tidy ClangTidyMain.cpp ) add_dependencies(clang-tidy - clang-headers + clang-resource-headers ) target_link_libraries(clang-tidy PRIVATE diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index adeb0368..ac8d459b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -59,7 +59,7 @@ set(CLANG_TOOLS_TEST_DEPS # For the clang-tidy libclang integration test. c-index-test # clang-tidy tests require it. - clang-headers + clang-resource-headers clang-tidy ) -- cgit v1.2.3 From ea151b04ebdb07c5e7722e7b6659a14dc2a0abc2 Mon Sep 17 00:00:00 2001 From: Alexander Kornienko Date: Tue, 5 Mar 2019 14:09:57 +0000 Subject: [clang-tidy] Fix bugprone-string-constructor crash git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355401 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/bugprone/StringConstructorCheck.cpp | 3 ++- test/clang-tidy/bugprone-string-constructor.cpp | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/clang-tidy/bugprone/StringConstructorCheck.cpp b/clang-tidy/bugprone/StringConstructorCheck.cpp index 3a4e75bc..a4b83ada 100644 --- a/clang-tidy/bugprone/StringConstructorCheck.cpp +++ b/clang-tidy/bugprone/StringConstructorCheck.cpp @@ -138,7 +138,8 @@ void StringConstructorCheck::check(const MatchFinder::MatchResult &Result) { } } else if (const auto *Ptr = Result.Nodes.getNodeAs("from-ptr")) { Expr::EvalResult ConstPtr; - if (Ptr->EvaluateAsRValue(ConstPtr, Ctx) && + if (!Ptr->isInstantiationDependent() && + Ptr->EvaluateAsRValue(ConstPtr, Ctx) && ((ConstPtr.Val.isInt() && ConstPtr.Val.getInt().isNullValue()) || (ConstPtr.Val.isLValue() && ConstPtr.Val.isNullPointer()))) { diag(Loc, "constructing string from nullptr is undefined behaviour"); diff --git a/test/clang-tidy/bugprone-string-constructor.cpp b/test/clang-tidy/bugprone-string-constructor.cpp index 3ab4f424..9e11a32a 100644 --- a/test/clang-tidy/bugprone-string-constructor.cpp +++ b/test/clang-tidy/bugprone-string-constructor.cpp @@ -65,3 +65,11 @@ void Valid() { std::string s2("test", 3); std::string s3("test"); } + +namespace instantiation_dependent_exprs { +template +struct S { + bool x; + std::string f() { return x ? "a" : "b"; } +}; +} -- cgit v1.2.3 From 4bff9e7bc96ac495d7b6b2e8cc6c6f629e824022 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 6 Mar 2019 10:51:38 +0000 Subject: [clangd] Add Source to clangd::Diagnostic. Summary: clangd embedder can distinguish diagnostics from clang or clang-tidy. Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58600 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355493 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdUnit.cpp | 9 ++++++++- clangd/Diagnostics.cpp | 1 + clangd/Diagnostics.h | 8 ++++++++ unittests/clangd/DiagnosticsTests.cpp | 17 +++++++++++++++++ 4 files changed, 34 insertions(+), 1 deletion(-) diff --git a/clangd/ClangdUnit.cpp b/clangd/ClangdUnit.cpp index b07abd9a..71d7bc1a 100644 --- a/clangd/ClangdUnit.cpp +++ b/clangd/ClangdUnit.cpp @@ -372,6 +372,10 @@ ParsedAST::build(std::unique_ptr CI, Clang->getPreprocessor().EndSourceFile(); std::vector Diags = ASTDiags.take(); + // Populate diagnostic source. + for (auto &D : Diags) + D.S = + !CTContext->getCheckName(D.ID).empty() ? Diag::ClangTidy : Diag::Clang; // Add diagnostics from the preamble, if any. if (Preamble) Diags.insert(Diags.begin(), Preamble->Diags.begin(), Preamble->Diags.end()); @@ -539,8 +543,11 @@ buildPreamble(PathRef FileName, CompilerInvocation &CI, if (BuiltPreamble) { vlog("Built preamble of size {0} for file {1}", BuiltPreamble->getSize(), FileName); + std::vector Diags = PreambleDiagnostics.take(); + for (auto &Diag : Diags) + Diag.S = Diag::Clang; return std::make_shared( - std::move(*BuiltPreamble), PreambleDiagnostics.take(), + std::move(*BuiltPreamble), std::move(Diags), SerializedDeclsCollector.takeIncludes(), std::move(StatCache), SerializedDeclsCollector.takeCanonicalIncludes()); } else { diff --git a/clangd/Diagnostics.cpp b/clangd/Diagnostics.cpp index 21053953..9f7161ba 100644 --- a/clangd/Diagnostics.cpp +++ b/clangd/Diagnostics.cpp @@ -377,6 +377,7 @@ void StoreDiags::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, flushLastDiag(); LastDiag = Diag(); + LastDiag->ID = Info.getID(); FillDiagBase(*LastDiag); if (!Info.getFixItHints().empty()) diff --git a/clangd/Diagnostics.h b/clangd/Diagnostics.h index 095590b9..9b8d80fd 100644 --- a/clangd/Diagnostics.h +++ b/clangd/Diagnostics.h @@ -68,6 +68,14 @@ struct Note : DiagBase {}; /// A top-level diagnostic that may have Notes and Fixes. struct Diag : DiagBase { + // Diagnostic enum ID. + unsigned ID; + // The source of this diagnostic. + enum Source { + Clang, + ClangTidy, + }; + Source S = Clang; /// Elaborate on the problem, usually pointing to a related piece of code. std::vector Notes; /// *Alternative* fixes for this diagnostic, one should be chosen. diff --git a/unittests/clangd/DiagnosticsTests.cpp b/unittests/clangd/DiagnosticsTests.cpp index 4bbc7c74..469a6727 100644 --- a/unittests/clangd/DiagnosticsTests.cpp +++ b/unittests/clangd/DiagnosticsTests.cpp @@ -58,6 +58,8 @@ MATCHER_P(EqualToLSPDiag, LSPDiag, std::tie(LSPDiag.range, LSPDiag.severity, LSPDiag.message); } +MATCHER_P(DiagSource, Source, "") { return arg.S == Source; } + MATCHER_P(EqualToFix, Fix, "LSP fix " + llvm::to_string(Fix)) { if (arg.Message != Fix.Message) return false; @@ -102,6 +104,7 @@ o]](); // This range spans lines. AllOf(Diag(Test.range("typo"), "use of undeclared identifier 'goo'; did you mean 'foo'?"), + DiagSource(Diag::Clang), WithFix( Fix(Test.range("typo"), "foo", "change 'go\\ o' to 'foo'")), // This is a pretty normal range. @@ -137,6 +140,18 @@ TEST(DiagnosticsTest, FlagsMatter) { WithFix(Fix(Test.range(), "int", "change return type to 'int'"))))); } +TEST(DiagnosticsTest, DiagnosticPreamble) { + Annotations Test(R"cpp( + #include $[["not-found.h"]] + )cpp"); + + auto TU = TestTU::withCode(Test.code()); + EXPECT_THAT(TU.build().getDiagnostics(), + ElementsAre(testing::AllOf( + Diag(Test.range(), "'not-found.h' file not found"), + DiagSource(Diag::Clang)))); +} + TEST(DiagnosticsTest, ClangTidy) { Annotations Test(R"cpp( #include $deprecated[["assert.h"]] @@ -159,6 +174,7 @@ TEST(DiagnosticsTest, ClangTidy) { AllOf(Diag(Test.range("deprecated"), "inclusion of deprecated C++ header 'assert.h'; consider " "using 'cassert' instead [modernize-deprecated-headers]"), + DiagSource(Diag::ClangTidy), WithFix(Fix(Test.range("deprecated"), "", "change '\"assert.h\"' to ''"))), Diag(Test.range("doubled"), @@ -168,6 +184,7 @@ TEST(DiagnosticsTest, ClangTidy) { Diag(Test.range("macroarg"), "side effects in the 1st macro argument 'X' are repeated in " "macro expansion [bugprone-macro-repeated-side-effects]"), + DiagSource(Diag::ClangTidy), WithNote(Diag(Test.range("macrodef"), "macro 'SQUARE' defined here " "[bugprone-macro-repeated-side-effects]"))), -- cgit v1.2.3 From 64990a4948395d82f315cd264f2907716ffc70b3 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 7 Mar 2019 14:47:17 +0000 Subject: [clangd] Strip plugin arguments in clangd-indexer. Summary: This would allow clangd-indexer runs on chromium repo. Reviewers: kadircet Reviewed By: kadircet Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59022 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355599 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/indexer/IndexerMain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clangd/indexer/IndexerMain.cpp b/clangd/indexer/IndexerMain.cpp index de29fc36..2ad98677 100644 --- a/clangd/indexer/IndexerMain.cpp +++ b/clangd/indexer/IndexerMain.cpp @@ -16,6 +16,7 @@ #include "index/Serialization.h" #include "index/Symbol.h" #include "index/SymbolCollector.h" +#include "clang/Tooling/ArgumentsAdjusters.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Execution.h" #include "clang/Tooling/Tooling.h" @@ -110,7 +111,8 @@ int main(int argc, const char **argv) { // Collect symbols found in each translation unit, merging as we go. clang::clangd::IndexFileIn Data; auto Err = Executor->get()->execute( - llvm::make_unique(Data)); + llvm::make_unique(Data), + clang::tooling::getStripPluginsAdjuster()); if (Err) { llvm::errs() << llvm::toString(std::move(Err)) << "\n"; } -- cgit v1.2.3 From 2810fc137c7a5f0f3f2f9d737bf269b3165d2484 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Fri, 8 Mar 2019 08:38:25 +0000 Subject: [clangd] Adjust compile commands to be applicable for tooling Summary: As can be seen in https://github.com/llvm-mirror/clang/blob/master/lib/Tooling/Tooling.cpp#L385 clang tool invocations adjust commands normally like this. In clangd we have different code paths for invoking a frontend action(preamble builds, ast builds, background index, clangd-indexer) they all work on the same GlobalCompilationDatabase abstraction, but later on are subject to different modifications. This patch makes sure all of the clangd actions make use of the same compile commands before invocation. Enables background-index to work on chromium codebase(since they had dependency file output in their compile commands). Reviewers: gribozavr, hokein Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59086 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355669 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/GlobalCompilationDatabase.cpp | 16 ++++--- .../clangd/GlobalCompilationDatabaseTests.cpp | 49 ++++++++++++++++++---- 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/clangd/GlobalCompilationDatabase.cpp b/clangd/GlobalCompilationDatabase.cpp index a9161972..f024821e 100644 --- a/clangd/GlobalCompilationDatabase.cpp +++ b/clangd/GlobalCompilationDatabase.cpp @@ -21,11 +21,17 @@ namespace { void adjustArguments(tooling::CompileCommand &Cmd, llvm::StringRef ResourceDir) { - // Strip plugin related command line arguments. Clangd does - // not support plugins currently. Therefore it breaks if - // compiler tries to load plugins. - Cmd.CommandLine = - tooling::getStripPluginsAdjuster()(Cmd.CommandLine, Cmd.Filename); + tooling::ArgumentsAdjuster ArgsAdjuster = tooling::combineAdjusters( + // clangd should not write files to disk, including dependency files + // requested on the command line. + tooling::getClangStripDependencyFileAdjuster(), + // Strip plugin related command line arguments. Clangd does + // not support plugins currently. Therefore it breaks if + // compiler tries to load plugins. + tooling::combineAdjusters(tooling::getStripPluginsAdjuster(), + tooling::getClangSyntaxOnlyAdjuster())); + + Cmd.CommandLine = ArgsAdjuster(Cmd.CommandLine, Cmd.Filename); // Inject the resource dir. // FIXME: Don't overwrite it if it's already there. if (!ResourceDir.empty()) diff --git a/unittests/clangd/GlobalCompilationDatabaseTests.cpp b/unittests/clangd/GlobalCompilationDatabaseTests.cpp index a1b696f6..7c7993cc 100644 --- a/unittests/clangd/GlobalCompilationDatabaseTests.cpp +++ b/unittests/clangd/GlobalCompilationDatabaseTests.cpp @@ -16,15 +16,18 @@ namespace clang { namespace clangd { namespace { +using ::testing::AllOf; +using ::testing::Contains; using ::testing::ElementsAre; using ::testing::EndsWith; +using ::testing::Not; TEST(GlobalCompilationDatabaseTest, FallbackCommand) { DirectoryBasedGlobalCompilationDatabase DB(None); auto Cmd = DB.getFallbackCommand(testPath("foo/bar.cc")); EXPECT_EQ(Cmd.Directory, testPath("foo")); - EXPECT_THAT(Cmd.CommandLine, ElementsAre( - EndsWith("clang"), testPath("foo/bar.cc"))); + EXPECT_THAT(Cmd.CommandLine, + ElementsAre(EndsWith("clang"), testPath("foo/bar.cc"))); EXPECT_EQ(Cmd.Output, ""); // .h files have unknown language, so they are parsed liberally as obj-c++. @@ -65,16 +68,18 @@ protected: TEST_F(OverlayCDBTest, GetCompileCommand) { OverlayCDB CDB(Base.get(), {}, std::string("")); - EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")), - Base->getCompileCommand(testPath("foo.cc"))); + EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine, + AllOf(Contains(testPath("foo.cc")), Contains("-DA=1"))); EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None); auto Override = cmd(testPath("foo.cc"), "-DA=3"); CDB.setCompileCommand(testPath("foo.cc"), Override); - EXPECT_EQ(CDB.getCompileCommand(testPath("foo.cc")), Override); + EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine, + Contains("-DA=3")); EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), llvm::None); CDB.setCompileCommand(testPath("missing.cc"), Override); - EXPECT_EQ(CDB.getCompileCommand(testPath("missing.cc")), Override); + EXPECT_THAT(CDB.getCompileCommand(testPath("missing.cc"))->CommandLine, + Contains("-DA=3")); } TEST_F(OverlayCDBTest, GetFallbackCommand) { @@ -88,7 +93,8 @@ TEST_F(OverlayCDBTest, NoBase) { EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), None); auto Override = cmd(testPath("bar.cc"), "-DA=5"); CDB.setCompileCommand(testPath("bar.cc"), Override); - EXPECT_EQ(CDB.getCompileCommand(testPath("bar.cc")), Override); + EXPECT_THAT(CDB.getCompileCommand(testPath("bar.cc"))->CommandLine, + Contains("-DA=5")); EXPECT_THAT(CDB.getFallbackCommand(testPath("foo.cc")).CommandLine, ElementsAre(EndsWith("clang"), testPath("foo.cc"), "-DA=6")); @@ -111,6 +117,35 @@ TEST_F(OverlayCDBTest, Watch) { ElementsAre("A.cpp"), ElementsAre("C.cpp"))); } +TEST_F(OverlayCDBTest, Adjustments) { + OverlayCDB CDB(Base.get(), {}, std::string("")); + auto Cmd = CDB.getCompileCommand(testPath("foo.cc")).getValue(); + // Delete the file name. + Cmd.CommandLine.pop_back(); + + // Check dependency file commands are dropped. + Cmd.CommandLine.push_back("-MF"); + Cmd.CommandLine.push_back("random-dependency"); + + // Check plugin-related commands are dropped. + Cmd.CommandLine.push_back("-Xclang"); + Cmd.CommandLine.push_back("-load"); + Cmd.CommandLine.push_back("-Xclang"); + Cmd.CommandLine.push_back("random-plugin"); + + Cmd.CommandLine.push_back("-DA=5"); + Cmd.CommandLine.push_back(Cmd.Filename); + + CDB.setCompileCommand(testPath("foo.cc"), Cmd); + + EXPECT_THAT(CDB.getCompileCommand(testPath("foo.cc"))->CommandLine, + AllOf(Contains("-fsyntax-only"), Contains("-DA=5"), + Contains(testPath("foo.cc")), Not(Contains("-MF")), + Not(Contains("random-dependency")), + Not(Contains("-Xclang")), Not(Contains("-load")), + Not(Contains("random-plugin")))); +} + } // namespace } // namespace clangd } // namespace clang -- cgit v1.2.3 From 8ef5a82ffb47c3b304ab966e0295dde3f839e916 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 8 Mar 2019 09:26:30 +0000 Subject: [clangd] Deduplicate Refs on the fly. Summary: Currently, we only do deduplication when we flush final results. We may have huge duplications (refs from headers) during the indexing period (running clangd-indexer on Chromium). With this change, clangd-indexer can index the whole chromium projects (48 threads, 40 GB peak memory usage). Reviewers: kadircet Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59092 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355676 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Ref.cpp | 15 +++++++-------- clangd/index/Ref.h | 4 +++- clangd/indexer/IndexerMain.cpp | 2 +- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/clangd/index/Ref.cpp b/clangd/index/Ref.cpp index 3f0fea56..2b21f3cb 100644 --- a/clangd/index/Ref.cpp +++ b/clangd/index/Ref.cpp @@ -33,9 +33,12 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const Ref &R) { void RefSlab::Builder::insert(const SymbolID &ID, const Ref &S) { auto &M = Refs[ID]; - M.push_back(S); - M.back().Location.FileURI = - UniqueStrings.save(M.back().Location.FileURI).data(); + if (M.count(S)) + return; + Ref R = S; + R.Location.FileURI = + UniqueStrings.save(R.Location.FileURI).data(); + M.insert(std::move(R)); } RefSlab RefSlab::Builder::build() && { @@ -45,11 +48,7 @@ RefSlab RefSlab::Builder::build() && { Result.reserve(Refs.size()); size_t NumRefs = 0; for (auto &Sym : Refs) { - auto &SymRefs = Sym.second; - llvm::sort(SymRefs); - // FIXME: do we really need to dedup? - SymRefs.erase(std::unique(SymRefs.begin(), SymRefs.end()), SymRefs.end()); - + std::vector SymRefs(Sym.second.begin(), Sym.second.end()); NumRefs += SymRefs.size(); Result.emplace_back(Sym.first, llvm::ArrayRef(SymRefs).copy(Arena)); } diff --git a/clangd/index/Ref.h b/clangd/index/Ref.h index 738be7b9..389e276b 100644 --- a/clangd/index/Ref.h +++ b/clangd/index/Ref.h @@ -16,6 +16,7 @@ #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" #include +#include #include namespace clang { @@ -67,6 +68,7 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &, const Ref &); /// Filenames are deduplicated. class RefSlab { public: + // Refs are stored in order. using value_type = std::pair>; using const_iterator = std::vector::const_iterator; using iterator = const_iterator; @@ -99,7 +101,7 @@ public: private: llvm::BumpPtrAllocator Arena; llvm::UniqueStringSaver UniqueStrings; // Contents on the arena. - llvm::DenseMap> Refs; + llvm::DenseMap> Refs; }; private: diff --git a/clangd/indexer/IndexerMain.cpp b/clangd/indexer/IndexerMain.cpp index 2ad98677..d0128251 100644 --- a/clangd/indexer/IndexerMain.cpp +++ b/clangd/indexer/IndexerMain.cpp @@ -56,7 +56,7 @@ public: [&](RefSlab S) { std::lock_guard Lock(SymbolsMu); for (const auto &Sym : S) { - // No need to merge as currently all Refs are from main file. + // Deduplication happens during insertion. for (const auto &Ref : Sym.second) Refs.insert(Sym.first, Ref); } -- cgit v1.2.3 From cc02f3d4bc235e1dc454e586fb50877e0e568cfd Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Fri, 8 Mar 2019 09:54:37 +0000 Subject: [clangd] Make sure constructors do not reference class Reviewers: gribozavr Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D58815 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355679 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/XRefs.cpp | 5 +++++ clangd/index/SymbolCollector.cpp | 6 +++++- unittests/clangd/XRefsTests.cpp | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index be4df73b..a099fb90 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Index/IndexDataConsumer.h" +#include "clang/Index/IndexSymbol.h" #include "clang/Index/IndexingAction.h" #include "clang/Index/USRGeneration.h" #include "llvm/Support/Path.h" @@ -154,6 +155,10 @@ public: llvm::ArrayRef Relations, SourceLocation Loc, index::IndexDataConsumer::ASTNodeInfo ASTNode) override { + // Skip non-semantic references. + if (Roles & static_cast(index::SymbolRole::NameReference)) + return true; + if (Loc == SearchedLocation) { auto IsImplicitExpr = [](const Expr *E) { if (!E) diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index 686b67b2..7fae0795 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -211,7 +211,7 @@ getTokenLocation(SourceLocation TokLoc, const SourceManager &SM, // the first seen declaration as canonical declaration is not a good enough // heuristic. bool isPreferredDeclaration(const NamedDecl &ND, index::SymbolRoleSet Roles) { - const auto& SM = ND.getASTContext().getSourceManager(); + const auto &SM = ND.getASTContext().getSourceManager(); return (Roles & static_cast(index::SymbolRole::Definition)) && isa(&ND) && !SM.isWrittenInMainFile(SM.getExpansionLoc(ND.getLocation())); @@ -305,6 +305,10 @@ bool SymbolCollector::handleDeclOccurence( Decl::FriendObjectKind::FOK_None) && !(Roles & static_cast(index::SymbolRole::Definition))) return true; + // Skip non-semantic references, we should start processing these when we + // decide to implement renaming with index support. + if ((Roles & static_cast(index::SymbolRole::NameReference))) + return true; // A declaration created for a friend declaration should not be used as the // canonical declaration in the index. Use OrigD instead, unless we've already // picked a replacement for D diff --git a/unittests/clangd/XRefsTests.cpp b/unittests/clangd/XRefsTests.cpp index df795b1c..1f0f808b 100644 --- a/unittests/clangd/XRefsTests.cpp +++ b/unittests/clangd/XRefsTests.cpp @@ -1337,6 +1337,15 @@ TEST(FindReferences, WithinAST) { } )cpp", + R"cpp(// Constructor + struct Foo { + [[F^oo]](int); + }; + void foo() { + Foo f = [[Foo]](42); + } + )cpp", + R"cpp(// Typedef typedef int [[Foo]]; int main() { -- cgit v1.2.3 From f72531709f1b4d062f21f31f3472c3d6e855428e Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Fri, 8 Mar 2019 09:56:42 +0000 Subject: [clangd] Redirect clangd page. Reviewers: gribozavr Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59128 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355680 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/clangd.rst b/docs/clangd.rst index 768c5da5..7910fac3 100644 --- a/docs/clangd.rst +++ b/docs/clangd.rst @@ -1,3 +1,6 @@ :orphan: +.. meta:: + :http-equiv=refresh: 0;URL='clangd/' + All :program:`clangd` documentation was moved to the :doc:`clangd/index` pages. -- cgit v1.2.3 From e7a5f0855dc9f2658cde8b52f834c7a2074a21c0 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Fri, 8 Mar 2019 09:57:33 +0000 Subject: [clangd] Remove ./ and ../ in the file paths Reviewers: hokein Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59084 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355681 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Background.cpp | 1 + unittests/clangd/BackgroundIndexTests.cpp | 33 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp index 40ff8d7e..79f21253 100644 --- a/clangd/index/Background.cpp +++ b/clangd/index/Background.cpp @@ -121,6 +121,7 @@ llvm::SmallString<128> getAbsolutePath(const tooling::CompileCommand &Cmd) { } else { AbsolutePath = Cmd.Directory; llvm::sys::path::append(AbsolutePath, Cmd.Filename); + llvm::sys::path::remove_dots(AbsolutePath, true); } return AbsolutePath; } diff --git a/unittests/clangd/BackgroundIndexTests.cpp b/unittests/clangd/BackgroundIndexTests.cpp index 09a117db..5f20cb0f 100644 --- a/unittests/clangd/BackgroundIndexTests.cpp +++ b/unittests/clangd/BackgroundIndexTests.cpp @@ -44,12 +44,14 @@ public: llvm::Error storeShard(llvm::StringRef ShardIdentifier, IndexFileOut Shard) const override { std::lock_guard Lock(StorageMu); + AccessedPaths.insert(ShardIdentifier); Storage[ShardIdentifier] = llvm::to_string(Shard); return llvm::Error::success(); } std::unique_ptr loadShard(llvm::StringRef ShardIdentifier) const override { std::lock_guard Lock(StorageMu); + AccessedPaths.insert(ShardIdentifier); if (Storage.find(ShardIdentifier) == Storage.end()) { return nullptr; } @@ -62,6 +64,8 @@ public: CacheHits++; return llvm::make_unique(std::move(*IndexFile)); } + + mutable llvm::StringSet<> AccessedPaths; }; class BackgroundIndexTest : public ::testing::Test { @@ -428,5 +432,34 @@ TEST_F(BackgroundIndexTest, ShardStorageEmptyFile) { Contains(AllOf(Named("new_func"), Declared(), Not(Defined())))); } +TEST_F(BackgroundIndexTest, NoDotsInAbsPath) { + MockFSProvider FS; + llvm::StringMap Storage; + size_t CacheHits = 0; + MemoryShardStorage MSS(Storage, CacheHits); + OverlayCDB CDB(/*Base=*/nullptr); + BackgroundIndex Idx(Context::empty(), FS, CDB, + [&](llvm::StringRef) { return &MSS; }); + + tooling::CompileCommand Cmd; + FS.Files[testPath("root/A.cc")] = ""; + Cmd.Filename = "../A.cc"; + Cmd.Directory = testPath("root/build"); + Cmd.CommandLine = {"clang++", "../A.cc"}; + CDB.setCompileCommand(testPath("root/build/../A.cc"), Cmd); + + FS.Files[testPath("root/B.cc")] = ""; + Cmd.Filename = "./B.cc"; + Cmd.Directory = testPath("root"); + Cmd.CommandLine = {"clang++", "./B.cc"}; + CDB.setCompileCommand(testPath("root/./B.cc"), Cmd); + + ASSERT_TRUE(Idx.blockUntilIdleForTest()); + for (llvm::StringRef AbsPath : MSS.AccessedPaths.keys()) { + EXPECT_FALSE(AbsPath.contains("./")) << AbsPath; + EXPECT_FALSE(AbsPath.contains("../")) << AbsPath; + } +} + } // namespace clangd } // namespace clang -- cgit v1.2.3 From 01ba2c16490dee2edcbea3b0b8fffd91f11f87d3 Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Fri, 8 Mar 2019 15:37:15 +0000 Subject: [clang-tidy] NFC: Negate the name and semantics of the isNotInMacro function. This function is always used in a context where its result was also negated, which made for confusing naming and code. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355702 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/DurationComparisonCheck.cpp | 3 +-- clang-tidy/abseil/DurationConversionCastCheck.cpp | 2 +- clang-tidy/abseil/DurationRewriter.cpp | 6 +++--- clang-tidy/abseil/DurationRewriter.h | 6 +++--- clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp | 2 +- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tidy/abseil/DurationComparisonCheck.cpp index 337f2ca0..3b19e5fd 100644 --- a/clang-tidy/abseil/DurationComparisonCheck.cpp +++ b/clang-tidy/abseil/DurationComparisonCheck.cpp @@ -43,8 +43,7 @@ void DurationComparisonCheck::check(const MatchFinder::MatchResult &Result) { // want to handle the case of rewriting both sides. This is much simpler if // we unconditionally try and rewrite both, and let the rewriter determine // if nothing needs to be done. - if (!isNotInMacro(Result, Binop->getLHS()) || - !isNotInMacro(Result, Binop->getRHS())) + if (isInMacro(Result, Binop->getLHS()) || isInMacro(Result, Binop->getRHS())) return; std::string LhsReplacement = rewriteExprFromNumberToDuration(Result, *Scale, Binop->getLHS()); diff --git a/clang-tidy/abseil/DurationConversionCastCheck.cpp b/clang-tidy/abseil/DurationConversionCastCheck.cpp index f0ae82c0..d9e91554 100644 --- a/clang-tidy/abseil/DurationConversionCastCheck.cpp +++ b/clang-tidy/abseil/DurationConversionCastCheck.cpp @@ -37,7 +37,7 @@ void DurationConversionCastCheck::check( const auto *MatchedCast = Result.Nodes.getNodeAs("cast_expr"); - if (!isNotInMacro(Result, MatchedCast)) + if (isInMacro(Result, MatchedCast)) return; const auto *FuncDecl = Result.Nodes.getNodeAs("func_decl"); diff --git a/clang-tidy/abseil/DurationRewriter.cpp b/clang-tidy/abseil/DurationRewriter.cpp index ceee2ec8..3466cdbb 100644 --- a/clang-tidy/abseil/DurationRewriter.cpp +++ b/clang-tidy/abseil/DurationRewriter.cpp @@ -302,9 +302,9 @@ std::string rewriteExprFromNumberToTime( .str(); } -bool isNotInMacro(const MatchFinder::MatchResult &Result, const Expr *E) { +bool isInMacro(const MatchFinder::MatchResult &Result, const Expr *E) { if (!E->getBeginLoc().isMacroID()) - return true; + return false; SourceLocation Loc = E->getBeginLoc(); // We want to get closer towards the initial macro typed into the source only @@ -316,7 +316,7 @@ bool isNotInMacro(const MatchFinder::MatchResult &Result, const Expr *E) { // because Clang comment says it "should not generally be used by clients." Loc = Result.SourceManager->getImmediateMacroCallerLoc(Loc); } - return !Loc.isMacroID(); + return Loc.isMacroID(); } } // namespace abseil diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index 5b4689f3..32f8167c 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -91,10 +91,10 @@ std::string rewriteExprFromNumberToTime( const ast_matchers::MatchFinder::MatchResult &Result, DurationScale Scale, const Expr *Node); -/// Return `true` if `E` is a either: not a macro at all; or an argument to +/// Return `false` if `E` is a either: not a macro at all; or an argument to /// one. In the both cases, we often want to do the transformation. -bool isNotInMacro(const ast_matchers::MatchFinder::MatchResult &Result, - const Expr *E); +bool isInMacro(const ast_matchers::MatchFinder::MatchResult &Result, + const Expr *E); AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, DurationConversionFunction) { diff --git a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp index 83650cd1..ae761997 100644 --- a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp +++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp @@ -44,7 +44,7 @@ void DurationUnnecessaryConversionCheck::check( const auto *OuterCall = Result.Nodes.getNodeAs("call"); const auto *Arg = Result.Nodes.getNodeAs("arg"); - if (!isNotInMacro(Result, OuterCall)) + if (isInMacro(Result, OuterCall)) return; diag(OuterCall->getBeginLoc(), "remove unnecessary absl::Duration conversions") -- cgit v1.2.3 From ad89bdaadb1ea7a3d38c43c75c1110d865048205 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Mon, 11 Mar 2019 08:45:56 +0000 Subject: [clangd] Add TOC section to clangd doc. Reviewers: gribozavr Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59132 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355811 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd/Extensions.rst | 2 ++ docs/clangd/Features.rst | 2 ++ docs/clangd/Installation.rst | 2 ++ 3 files changed, 6 insertions(+) diff --git a/docs/clangd/Extensions.rst b/docs/clangd/Extensions.rst index 4ff05250..6c972ebd 100644 --- a/docs/clangd/Extensions.rst +++ b/docs/clangd/Extensions.rst @@ -2,6 +2,8 @@ Protocol extensions =================== +.. contents:: + clangd supports some features that are not in the official `Language Server Protocol specification `__. diff --git a/docs/clangd/Features.rst b/docs/clangd/Features.rst index cb7a6251..3e6e745a 100644 --- a/docs/clangd/Features.rst +++ b/docs/clangd/Features.rst @@ -2,6 +2,8 @@ Features ======== +.. contents:: + .. role:: raw-html(raw) :format: html diff --git a/docs/clangd/Installation.rst b/docs/clangd/Installation.rst index 2daf42ba..6dca5f0a 100644 --- a/docs/clangd/Installation.rst +++ b/docs/clangd/Installation.rst @@ -2,6 +2,8 @@ Getting started with clangd =========================== +.. contents:: + .. role:: raw-html(raw) :format: html -- cgit v1.2.3 From 19daaf139bca5e305c2efed3cd0fae7bf10a0b73 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Mon, 11 Mar 2019 11:01:14 +0000 Subject: [clangd] Respect Origin option in createStaticIndexingAction Summary: Currently createStaticIndexingAction always set Origin to Static, which makes it hard to change it later on by different indexers(One needs to go over each symbol making a new copy). This patch changes that behavior to rather respect it if set by user. Reviewers: ioeric Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59205 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355820 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/IndexAction.cpp | 3 ++- clangd/index/IndexAction.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/clangd/index/IndexAction.cpp b/clangd/index/IndexAction.cpp index 96c007d4..61db161b 100644 --- a/clangd/index/IndexAction.cpp +++ b/clangd/index/IndexAction.cpp @@ -183,7 +183,8 @@ std::unique_ptr createStaticIndexingAction( index::IndexingOptions::SystemSymbolFilterKind::All; Opts.CollectIncludePath = true; Opts.CountReferences = true; - Opts.Origin = SymbolOrigin::Static; + if (Opts.Origin == SymbolOrigin::Unknown) + Opts.Origin = SymbolOrigin::Static; Opts.StoreAllDocumentation = false; if (RefsCallback != nullptr) { Opts.RefFilter = RefKind::All; diff --git a/clangd/index/IndexAction.h b/clangd/index/IndexAction.h index 748b26e1..f2b45deb 100644 --- a/clangd/index/IndexAction.h +++ b/clangd/index/IndexAction.h @@ -22,7 +22,7 @@ namespace clangd { // - include paths are always collected, and canonicalized appropriately // - references are always counted // - all references are collected (if RefsCallback is non-null) -// - the symbol origin is always Static +// - the symbol origin is set to Static if not specified by caller std::unique_ptr createStaticIndexingAction( SymbolCollector::Options Opts, std::function SymbolsCallback, -- cgit v1.2.3 From bb8fbdd017ba9c02420327862bd133a193224f45 Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Mon, 11 Mar 2019 16:47:45 +0000 Subject: [clang-tidy] Add the abseil-time-compare check This is an analog of the abseil-duration-comparison check, but for the absl::Time domain. It has a similar implementation and tests. Differential Revision: https://reviews.llvm.org/D58977 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355835 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/abseil/AbseilTidyModule.cpp | 3 + clang-tidy/abseil/CMakeLists.txt | 1 + clang-tidy/abseil/DurationComparisonCheck.cpp | 12 +- clang-tidy/abseil/DurationRewriter.h | 10 ++ clang-tidy/abseil/TimeComparisonCheck.cpp | 61 ++++++++++ clang-tidy/abseil/TimeComparisonCheck.h | 35 ++++++ docs/ReleaseNotes.rst | 6 + docs/clang-tidy/checks/abseil-time-comparison.rst | 23 ++++ docs/clang-tidy/checks/list.rst | 1 + test/clang-tidy/abseil-time-comparison.cpp | 129 ++++++++++++++++++++++ 10 files changed, 273 insertions(+), 8 deletions(-) create mode 100644 clang-tidy/abseil/TimeComparisonCheck.cpp create mode 100644 clang-tidy/abseil/TimeComparisonCheck.h create mode 100644 docs/clang-tidy/checks/abseil-time-comparison.rst create mode 100644 test/clang-tidy/abseil-time-comparison.cpp diff --git a/clang-tidy/abseil/AbseilTidyModule.cpp b/clang-tidy/abseil/AbseilTidyModule.cpp index 514b7f78..c70ef900 100644 --- a/clang-tidy/abseil/AbseilTidyModule.cpp +++ b/clang-tidy/abseil/AbseilTidyModule.cpp @@ -23,6 +23,7 @@ #include "RedundantStrcatCallsCheck.h" #include "StringFindStartswithCheck.h" #include "StrCatAppendCheck.h" +#include "TimeComparisonCheck.h" #include "TimeSubtractionCheck.h" #include "UpgradeDurationConversionsCheck.h" @@ -60,6 +61,8 @@ public: "abseil-str-cat-append"); CheckFactories.registerCheck( "abseil-string-find-startswith"); + CheckFactories.registerCheck( + "abseil-time-comparison"); CheckFactories.registerCheck( "abseil-time-subtraction"); CheckFactories.registerCheck( diff --git a/clang-tidy/abseil/CMakeLists.txt b/clang-tidy/abseil/CMakeLists.txt index f0616030..3f88da62 100644 --- a/clang-tidy/abseil/CMakeLists.txt +++ b/clang-tidy/abseil/CMakeLists.txt @@ -17,6 +17,7 @@ add_clang_library(clangTidyAbseilModule RedundantStrcatCallsCheck.cpp StrCatAppendCheck.cpp StringFindStartswithCheck.cpp + TimeComparisonCheck.cpp TimeSubtractionCheck.cpp UpgradeDurationConversionsCheck.cpp diff --git a/clang-tidy/abseil/DurationComparisonCheck.cpp b/clang-tidy/abseil/DurationComparisonCheck.cpp index 3b19e5fd..a6e12dd8 100644 --- a/clang-tidy/abseil/DurationComparisonCheck.cpp +++ b/clang-tidy/abseil/DurationComparisonCheck.cpp @@ -19,14 +19,10 @@ namespace tidy { namespace abseil { void DurationComparisonCheck::registerMatchers(MatchFinder *Finder) { - auto Matcher = - binaryOperator(anyOf(hasOperatorName(">"), hasOperatorName(">="), - hasOperatorName("=="), hasOperatorName("<="), - hasOperatorName("<")), - hasEitherOperand(ignoringImpCasts(callExpr( - callee(functionDecl(DurationConversionFunction()) - .bind("function_decl")))))) - .bind("binop"); + auto Matcher = expr(comparisonOperatorWithCallee(functionDecl( + functionDecl(DurationConversionFunction()) + .bind("function_decl")))) + .bind("binop"); Finder->addMatcher(Matcher, this); } diff --git a/clang-tidy/abseil/DurationRewriter.h b/clang-tidy/abseil/DurationRewriter.h index 32f8167c..1ae312c6 100644 --- a/clang-tidy/abseil/DurationRewriter.h +++ b/clang-tidy/abseil/DurationRewriter.h @@ -124,6 +124,16 @@ AST_MATCHER_FUNCTION(ast_matchers::internal::Matcher, "::absl::ToUnixMillis", "::absl::ToUnixMicros", "::absl::ToUnixNanos")); } +AST_MATCHER_FUNCTION_P(ast_matchers::internal::Matcher, + comparisonOperatorWithCallee, + ast_matchers::internal::Matcher, funcDecl) { + using namespace clang::ast_matchers; + return binaryOperator( + anyOf(hasOperatorName(">"), hasOperatorName(">="), hasOperatorName("=="), + hasOperatorName("<="), hasOperatorName("<")), + hasEitherOperand(ignoringImpCasts(callExpr(callee(funcDecl))))); +} + } // namespace abseil } // namespace tidy } // namespace clang diff --git a/clang-tidy/abseil/TimeComparisonCheck.cpp b/clang-tidy/abseil/TimeComparisonCheck.cpp new file mode 100644 index 00000000..391f38f1 --- /dev/null +++ b/clang-tidy/abseil/TimeComparisonCheck.cpp @@ -0,0 +1,61 @@ +//===--- TimeComparisonCheck.cpp - clang-tidy +//--------------------------------===// +// +// 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 "TimeComparisonCheck.h" +#include "DurationRewriter.h" +#include "clang/AST/ASTContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Tooling/FixIt.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace tidy { +namespace abseil { + +void TimeComparisonCheck::registerMatchers(MatchFinder *Finder) { + auto Matcher = + expr(comparisonOperatorWithCallee(functionDecl( + functionDecl(TimeConversionFunction()).bind("function_decl")))) + .bind("binop"); + + Finder->addMatcher(Matcher, this); +} + +void TimeComparisonCheck::check(const MatchFinder::MatchResult &Result) { + const auto *Binop = Result.Nodes.getNodeAs("binop"); + + llvm::Optional Scale = getScaleForTimeInverse( + Result.Nodes.getNodeAs("function_decl")->getName()); + if (!Scale) + return; + + if (isInMacro(Result, Binop->getLHS()) || isInMacro(Result, Binop->getRHS())) + return; + + // In most cases, we'll only need to rewrite one of the sides, but we also + // want to handle the case of rewriting both sides. This is much simpler if + // we unconditionally try and rewrite both, and let the rewriter determine + // if nothing needs to be done. + std::string LhsReplacement = + rewriteExprFromNumberToTime(Result, *Scale, Binop->getLHS()); + std::string RhsReplacement = + rewriteExprFromNumberToTime(Result, *Scale, Binop->getRHS()); + + diag(Binop->getBeginLoc(), "perform comparison in the time domain") + << FixItHint::CreateReplacement(Binop->getSourceRange(), + (llvm::Twine(LhsReplacement) + " " + + Binop->getOpcodeStr() + " " + + RhsReplacement) + .str()); +} + +} // namespace abseil +} // namespace tidy +} // namespace clang diff --git a/clang-tidy/abseil/TimeComparisonCheck.h b/clang-tidy/abseil/TimeComparisonCheck.h new file mode 100644 index 00000000..55984338 --- /dev/null +++ b/clang-tidy/abseil/TimeComparisonCheck.h @@ -0,0 +1,35 @@ +//===--- TimeComparisonCheck.h - clang-tidy ---------------------*- 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_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H + +#include "../ClangTidy.h" + +namespace clang { +namespace tidy { +namespace abseil { + +/// Prefer comparison in the `absl::Time` domain instead of the numeric +/// domain. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/abseil-time-comparison.html +class TimeComparisonCheck : public ClangTidyCheck { +public: + TimeComparisonCheck(StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context) {} + void registerMatchers(ast_matchers::MatchFinder *Finder) override; + void check(const ast_matchers::MatchFinder::MatchResult &Result) override; +}; + +} // namespace abseil +} // namespace tidy +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_ABSEIL_TIMECOMPARECHECK_H diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 3d3edef3..9f464f97 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -85,6 +85,12 @@ Improvements to clang-tidy Finds and fixes cases where ``absl::Duration`` values are being converted to numeric types and back again. +- New :doc:`abseil-time-comparison + ` check. + + Prefer comparisons in the ``absl::Time`` domain instead of the integer + domain. + - New :doc:`abseil-time-subtraction ` check. diff --git a/docs/clang-tidy/checks/abseil-time-comparison.rst b/docs/clang-tidy/checks/abseil-time-comparison.rst new file mode 100644 index 00000000..130459be --- /dev/null +++ b/docs/clang-tidy/checks/abseil-time-comparison.rst @@ -0,0 +1,23 @@ +.. title:: clang-tidy - abseil-time-comparison + +abseil-time-comparison +====================== + +Prefer comparisons in the ``absl::Time`` domain instead of the integer domain. + +N.B.: In cases where an ``absl::Time`` is being converted to an integer, +alignment may occur. If the comparison depends on this alingment, doing the +comparison in the ``absl::Time`` domain may yield a different result. In +practice this is very rare, and still indicates a bug which should be fixed. + +Examples: + +.. code-block:: c++ + + // Original - Comparison in the integer domain + int x; + absl::Time t; + if (x < absl::ToUnixSeconds(t)) ... + + // Suggested - Compare in the absl::Time domain instead + if (absl::FromUnixSeconds(x) < t) ... diff --git a/docs/clang-tidy/checks/list.rst b/docs/clang-tidy/checks/list.rst index 353ea376..80aba4a0 100644 --- a/docs/clang-tidy/checks/list.rst +++ b/docs/clang-tidy/checks/list.rst @@ -18,6 +18,7 @@ Clang-Tidy Checks abseil-redundant-strcat-calls abseil-str-cat-append abseil-string-find-startswith + abseil-time-comparison abseil-time-subtraction abseil-upgrade-duration-conversions android-cloexec-accept diff --git a/test/clang-tidy/abseil-time-comparison.cpp b/test/clang-tidy/abseil-time-comparison.cpp new file mode 100644 index 00000000..ab03020c --- /dev/null +++ b/test/clang-tidy/abseil-time-comparison.cpp @@ -0,0 +1,129 @@ +// RUN: %check_clang_tidy %s abseil-time-comparison %t -- -- -I%S/Inputs + +#include "absl/time/time.h" + +void f() { + double x; + absl::Duration d1, d2; + bool b; + absl::Time t1, t2; + + // Check against the RHS + b = x > absl::ToUnixSeconds(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixSeconds(x) > t1; + b = x >= absl::ToUnixSeconds(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixSeconds(x) >= t1; + b = x == absl::ToUnixSeconds(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixSeconds(x) == t1; + b = x <= absl::ToUnixSeconds(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixSeconds(x) <= t1; + b = x < absl::ToUnixSeconds(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixSeconds(x) < t1; + b = x == absl::ToUnixSeconds(t1 - d2); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixSeconds(x) == t1 - d2; + b = absl::ToUnixSeconds(t1) > absl::ToUnixSeconds(t2); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 > t2; + + // Check against the LHS + b = absl::ToUnixSeconds(t1) < x; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 < absl::FromUnixSeconds(x); + b = absl::ToUnixSeconds(t1) <= x; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 <= absl::FromUnixSeconds(x); + b = absl::ToUnixSeconds(t1) == x; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 == absl::FromUnixSeconds(x); + b = absl::ToUnixSeconds(t1) >= x; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 >= absl::FromUnixSeconds(x); + b = absl::ToUnixSeconds(t1) > x; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 > absl::FromUnixSeconds(x); + + // Comparison against zero + b = absl::ToUnixSeconds(t1) < 0.0; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 < absl::UnixEpoch(); + b = absl::ToUnixSeconds(t1) < 0; + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: t1 < absl::UnixEpoch(); + + // Scales other than Seconds + b = x > absl::ToUnixMicros(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixMicros(x) > t1; + b = x >= absl::ToUnixMillis(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixMillis(x) >= t1; + b = x == absl::ToUnixNanos(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixNanos(x) == t1; + b = x <= absl::ToUnixMinutes(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixMinutes(x) <= t1; + b = x < absl::ToUnixHours(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixHours(x) < t1; + + // A long expression + bool some_condition; + int very_very_very_very_long_variable_name; + absl::Time SomeTime; + if (some_condition && very_very_very_very_long_variable_name + < absl::ToUnixSeconds(SomeTime)) { + // CHECK-MESSAGES: [[@LINE-2]]:25: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: if (some_condition && absl::FromUnixSeconds(very_very_very_very_long_variable_name) < SomeTime) { + return; + } + + // A complex expression + int y; + b = (y + 5) * 10 > absl::ToUnixMillis(t1); + // CHECK-MESSAGES: [[@LINE-1]]:7: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: absl::FromUnixMillis((y + 5) * 10) > t1; + + // We should still transform the expression inside this macro invocation +#define VALUE_IF(v, e) v ? (e) : 0 + int a = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1)); + // CHECK-MESSAGES: [[@LINE-1]]:23: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1); +#undef VALUE_IF + +#define VALUE_IF_2(e) (e) +#define VALUE_IF(v, e) v ? VALUE_IF_2(e) : VALUE_IF_2(0) + int a2 = VALUE_IF(1, 5 > absl::ToUnixSeconds(t1)); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: perform comparison in the time domain [abseil-time-comparison] + // CHECK-FIXES: VALUE_IF(1, absl::FromUnixSeconds(5) > t1); +#undef VALUE_IF +#undef VALUE_IF_2 + +#define VALUE_IF_2(e) (e) +#define VALUE_IF(v, e, type) (v ? VALUE_IF_2(absl::To##type##Seconds(e)) : 0) + int a3 = VALUE_IF(1, t1, Unix); +#undef VALUE_IF +#undef VALUE_IF_2 + +#define VALUE_IF_2(e) (e) +#define VALUE_IF(v, e, type) (v ? (5 > VALUE_IF_2(absl::To##type##Seconds(e))) : 0) + int a4 = VALUE_IF(1, t1, Unix); +#undef VALUE_IF +#undef VALUE_IF_2 + + // These should not match + b = 6 < 4; + +#define TODOUBLE(x) absl::ToUnixSeconds(x) + b = 5.0 > TODOUBLE(t1); +#undef TODOUBLE +#define THIRTY 30.0 + b = THIRTY > absl::ToUnixSeconds(t1); +#undef THIRTY +} -- cgit v1.2.3 From 9745e433f1797e3b605815a2a9f63fde09638f6a Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Tue, 12 Mar 2019 16:11:46 +0000 Subject: [clang-tidy] NOLINT support for "clang-diagnostic-*". Reviewers: alexfh, aaron.ballman Reviewed By: alexfh Subscribers: xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59255 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@355934 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/ClangTidyDiagnosticConsumer.cpp | 16 +++++++--------- clang-tidy/ClangTidyDiagnosticConsumer.h | 2 +- test/clang-tidy/nolint.cpp | 3 ++- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tidy/ClangTidyDiagnosticConsumer.cpp index 637addf2..0d6c0a94 100644 --- a/clang-tidy/ClangTidyDiagnosticConsumer.cpp +++ b/clang-tidy/ClangTidyDiagnosticConsumer.cpp @@ -254,7 +254,11 @@ bool ClangTidyContext::treatAsError(StringRef CheckName) const { return WarningAsErrorFilter->contains(CheckName); } -StringRef ClangTidyContext::getCheckName(unsigned DiagnosticID) const { +std::string ClangTidyContext::getCheckName(unsigned DiagnosticID) const { + std::string ClangWarningOption = + DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag(DiagnosticID); + if (!ClangWarningOption.empty()) + return "clang-diagnostic-" + ClangWarningOption; llvm::DenseMap::const_iterator I = CheckNamesByDiagnosticID.find(DiagnosticID); if (I != CheckNamesByDiagnosticID.end()) @@ -305,7 +309,7 @@ static bool IsNOLINTFound(StringRef NolintDirectiveText, StringRef Line, Line.substr(BracketIndex, BracketEndIndex - BracketIndex); // Allow disabling all the checks with "*". if (ChecksStr != "*") { - StringRef CheckName = Context.getCheckName(DiagID); + std::string CheckName = Context.getCheckName(DiagID); // Allow specifying a few check names, delimited with comma. SmallVector Checks; ChecksStr.split(Checks, ',', -1, false); @@ -402,13 +406,7 @@ void ClangTidyDiagnosticConsumer::HandleDiagnostic( "A diagnostic note can only be appended to a message."); } else { finalizeLastError(); - StringRef WarningOption = - Context.DiagEngine->getDiagnosticIDs()->getWarningOptionForDiag( - Info.getID()); - std::string CheckName = !WarningOption.empty() - ? ("clang-diagnostic-" + WarningOption).str() - : Context.getCheckName(Info.getID()).str(); - + std::string CheckName = Context.getCheckName(Info.getID()); if (CheckName.empty()) { // This is a compiler diagnostic without a warning option. Assign check // name based on its level. diff --git a/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tidy/ClangTidyDiagnosticConsumer.h index 63dbd526..400f0dc6 100644 --- a/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -138,7 +138,7 @@ public: /// \brief Returns the name of the clang-tidy check which produced this /// diagnostic ID. - StringRef getCheckName(unsigned DiagnosticID) const; + std::string getCheckName(unsigned DiagnosticID) const; /// \brief Returns \c true if the check is enabled for the \c CurrentFile. /// diff --git a/test/clang-tidy/nolint.cpp b/test/clang-tidy/nolint.cpp index 24c37228..a2d2c10a 100644 --- a/test/clang-tidy/nolint.cpp +++ b/test/clang-tidy/nolint.cpp @@ -31,6 +31,7 @@ void f() { int i; // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: unused variable 'i' [clang-diagnostic-unused-variable] int j; // NOLINT + int k; // NOLINT(clang-diagnostic-unused-variable) } #define MACRO(X) class X { X(int i); }; @@ -47,4 +48,4 @@ MACRO_NOLINT #define DOUBLE_MACRO MACRO(H) // NOLINT DOUBLE_MACRO -// CHECK-MESSAGES: Suppressed 12 warnings (12 NOLINT) +// CHECK-MESSAGES: Suppressed 13 warnings (13 NOLINT) -- cgit v1.2.3 From e739b49a995cb7d486ddb09e73b87c8e2deb09f2 Mon Sep 17 00:00:00 2001 From: Paul Hoad Date: Wed, 13 Mar 2019 08:07:46 +0000 Subject: [clang-format] [PR25010] AllowShortIfStatementsOnASingleLine not working if an "else" statement is present Summary: Addressing: PR25010 - https://bugs.llvm.org/show_bug.cgi?id=25010 Code like: ``` if(true) var++; else { var--; } ``` is reformatted to be ``` if (true) var++; else { var--; } ``` Even when `AllowShortIfStatementsOnASingleLine` is true The following revision comes from a +1'd suggestion in the PR to support AllowShortIfElseStatementsOnASingleLine This suppresses the clause prevents the merging of the if when there is a compound else Reviewers: klimek, djasper, JonasToth, alexfh, krasimir, reuk Reviewed By: reuk Subscribers: reuk, Higuoxing, jdoerfert, cfe-commits Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D59087 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356029 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/readability-identifier-naming.rst | 2 +- docs/conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/clang-tidy/checks/readability-identifier-naming.rst b/docs/clang-tidy/checks/readability-identifier-naming.rst index d7e88593..83546c6c 100644 --- a/docs/clang-tidy/checks/readability-identifier-naming.rst +++ b/docs/clang-tidy/checks/readability-identifier-naming.rst @@ -9,7 +9,7 @@ This check will try to enforce coding guidelines on the identifiers naming. It supports one of the following casing types and tries to convert from one to another if a mismatch is detected -Casing types inclde: +Casing types include: - ``lower_case``, - ``UPPER_CASE``, diff --git a/docs/conf.py b/docs/conf.py index 16e81051..3741fdf5 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ from datetime import date # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.todo', 'sphinx.ext.mathjax'] +extensions = ['sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinxcontrib.spelling' ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] -- cgit v1.2.3 From 3a6744c6aa764fe429acf45fbeb65b0965a9cfae Mon Sep 17 00:00:00 2001 From: Paul Hoad Date: Wed, 13 Mar 2019 08:15:03 +0000 Subject: Revert "[clang-format] [PR25010] AllowShortIfStatementsOnASingleLine not working if an "else" statement is present" This reverts commit b358cbb9b78389e20f7be36e1a98e26515c3ecce. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356030 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clang-tidy/checks/readability-identifier-naming.rst | 2 +- docs/conf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/clang-tidy/checks/readability-identifier-naming.rst b/docs/clang-tidy/checks/readability-identifier-naming.rst index 83546c6c..d7e88593 100644 --- a/docs/clang-tidy/checks/readability-identifier-naming.rst +++ b/docs/clang-tidy/checks/readability-identifier-naming.rst @@ -9,7 +9,7 @@ This check will try to enforce coding guidelines on the identifiers naming. It supports one of the following casing types and tries to convert from one to another if a mismatch is detected -Casing types include: +Casing types inclde: - ``lower_case``, - ``UPPER_CASE``, diff --git a/docs/conf.py b/docs/conf.py index 3741fdf5..16e81051 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ from datetime import date # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinxcontrib.spelling' ] +extensions = ['sphinx.ext.todo', 'sphinx.ext.mathjax'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] -- cgit v1.2.3 From a6a9b2d28edf038e2027aa7f5de16ee63ee2f300 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Wed, 13 Mar 2019 08:42:15 +0000 Subject: [clangd] Default initialize SymInfo git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356032 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Symbol.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clangd/index/Symbol.h b/clangd/index/Symbol.h index a3e4fb91..ae4f6bc6 100644 --- a/clangd/index/Symbol.h +++ b/clangd/index/Symbol.h @@ -37,7 +37,7 @@ struct Symbol { /// The ID of the symbol. SymbolID ID; /// The symbol information, like symbol kind. - index::SymbolInfo SymInfo; + index::SymbolInfo SymInfo = index::SymbolInfo(); /// The unqualified name of the symbol, e.g. "bar" (for ns::bar). llvm::StringRef Name; /// The containing namespace. e.g. "" (global), "ns::" (top-level namespace). -- cgit v1.2.3 From b25829aeb8d4a590659b40ff6a4def521dcd9c5b Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Wed, 13 Mar 2019 15:22:31 +0000 Subject: [clangd] Fix a typo in doc. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356055 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/clangd/Installation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/clangd/Installation.rst b/docs/clangd/Installation.rst index 6dca5f0a..1552efce 100644 --- a/docs/clangd/Installation.rst +++ b/docs/clangd/Installation.rst @@ -368,4 +368,4 @@ project-wide index to clangd. There are two ways to do this. Then you can pass generated index file to clangd using `-index-file=/path/to/index_file`. *Note that clangd-indexer isn't included alongside clangd in the Debian clang-tools package. You will - likely have to build clangd from source to use this option.* + likely have to build it from source to use this option.* -- cgit v1.2.3 From 3d6a75c7a420de9fc20b5d5de2fa23c1f76dc28b Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Thu, 14 Mar 2019 08:35:17 +0000 Subject: [clangd] Store explicit template specializations in index for code navigation purposes Summary: This introduces ~4k new symbols, and ~10k refs for LLVM. We need that information for providing better code navigation support: - When references for a class template is requested, we should return these specializations as well. - When children of a specialization is requested, we should be able to query for those symbols(instead of just class template) Number of symbols: 378574 -> 382784 Number of refs: 5098857 -> 5110689 Reviewers: hokein, gribozavr Reviewed By: gribozavr Subscribers: nridge, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, jdoerfert, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59083 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356125 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/CodeComplete.cpp | 14 ++++++++++++ clangd/index/MemIndex.cpp | 10 +++++++++ clangd/index/SymbolCollector.cpp | 11 --------- clangd/index/dex/Dex.cpp | 9 ++++++++ unittests/clangd/DexTests.cpp | 35 +++++++++++++++++++++++++++++ unittests/clangd/IndexTests.cpp | 37 +++++++++++++++++++++++++++++++ unittests/clangd/SymbolCollectorTests.cpp | 24 +++++++++++++------- 7 files changed, 121 insertions(+), 19 deletions(-) diff --git a/clangd/CodeComplete.cpp b/clangd/CodeComplete.cpp index 91a5dac5..c9859b2f 100644 --- a/clangd/CodeComplete.cpp +++ b/clangd/CodeComplete.cpp @@ -1510,6 +1510,13 @@ private: } }; +template bool isExplicitTemplateSpecialization(const NamedDecl &ND) { + if (const auto *TD = dyn_cast(&ND)) + if (TD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + return true; + return false; +} + } // namespace clang::CodeCompleteOptions CodeCompleteOptions::getClangCompleteOpts() const { @@ -1603,6 +1610,13 @@ bool isIndexedForCodeCompletion(const NamedDecl &ND, ASTContext &ASTCtx) { }; return false; }; + // We only complete symbol's name, which is the same as the name of the + // *primary* template in case of template specializations. + if (isExplicitTemplateSpecialization(ND) || + isExplicitTemplateSpecialization(ND) || + isExplicitTemplateSpecialization(ND)) + return false; + if (InTopLevelScope(ND)) return true; diff --git a/clangd/index/MemIndex.cpp b/clangd/index/MemIndex.cpp index 531d1f6d..ddd9a867 100644 --- a/clangd/index/MemIndex.cpp +++ b/clangd/index/MemIndex.cpp @@ -11,6 +11,7 @@ #include "Logger.h" #include "Quality.h" #include "Trace.h" +#include "clang/Index/IndexSymbol.h" namespace clang { namespace clangd { @@ -37,6 +38,15 @@ bool MemIndex::fuzzyFind( for (const auto Pair : Index) { const Symbol *Sym = Pair.second; + // FIXME: Enable fuzzy find on template specializations once we start + // storing template arguments in the name. Currently we only store name for + // class template, which would cause duplication in the results. + if (Sym->SymInfo.Properties & + (static_cast( + index::SymbolProperty::TemplateSpecialization) | + static_cast( + index::SymbolProperty::TemplatePartialSpecialization))) + continue; // Exact match against all possible scopes. if (!Req.AnyScope && !llvm::is_contained(Req.Scopes, Sym->Scope)) continue; diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index 7fae0795..eee32004 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -221,13 +221,6 @@ RefKind toRefKind(index::SymbolRoleSet Roles) { return static_cast(static_cast(RefKind::All) & Roles); } -template bool explicitTemplateSpecialization(const NamedDecl &ND) { - if (const auto *TD = dyn_cast(&ND)) - if (TD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) - return true; - return false; -} - } // namespace SymbolCollector::SymbolCollector(Options Opts) : Opts(std::move(Opts)) {} @@ -279,10 +272,6 @@ bool SymbolCollector::shouldCollectSymbol(const NamedDecl &ND, if (!isa(DeclCtx)) return false; } - if (explicitTemplateSpecialization(ND) || - explicitTemplateSpecialization(ND) || - explicitTemplateSpecialization(ND)) - return false; // Avoid indexing internal symbols in protobuf generated headers. if (isPrivateProtoDecl(ND)) diff --git a/clangd/index/dex/Dex.cpp b/clangd/index/dex/Dex.cpp index d767bb51..dd004f5f 100644 --- a/clangd/index/dex/Dex.cpp +++ b/clangd/index/dex/Dex.cpp @@ -86,6 +86,15 @@ void Dex::buildIndex() { llvm::DenseMap> TempInvertedIndex; for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank) { const auto *Sym = Symbols[SymbolRank]; + // FIXME: Enable fuzzy find on template specializations once we start + // storing template arguments in the name. Currently we only store name for + // class template, which would cause duplication in the results. + if (Sym->SymInfo.Properties & + (static_cast( + index::SymbolProperty::TemplateSpecialization) | + static_cast( + index::SymbolProperty::TemplatePartialSpecialization))) + continue; for (const auto &Token : generateSearchTokens(*Sym)) TempInvertedIndex[Token].push_back(SymbolRank); } diff --git a/unittests/clangd/DexTests.cpp b/unittests/clangd/DexTests.cpp index cd52daac..bd757d08 100644 --- a/unittests/clangd/DexTests.cpp +++ b/unittests/clangd/DexTests.cpp @@ -710,6 +710,41 @@ TEST(DexTest, PreferredTypesBoosting) { EXPECT_THAT(match(I, Req), ElementsAre("t2")); } +TEST(DexTest, TemplateSpecialization) { + SymbolSlab::Builder B; + + Symbol S = symbol("TempSpec"); + S.ID = SymbolID("0"); + B.insert(S); + + S = symbol("TempSpec"); + S.ID = SymbolID("1"); + S.SymInfo.Properties = static_cast( + index::SymbolProperty::TemplateSpecialization); + B.insert(S); + + S = symbol("TempSpec"); + S.ID = SymbolID("2"); + S.SymInfo.Properties = static_cast( + index::SymbolProperty::TemplatePartialSpecialization); + B.insert(S); + + auto I = dex::Dex::build(std::move(B).build(), RefSlab()); + FuzzyFindRequest Req; + Req.Query = "TempSpec"; + Req.AnyScope = true; + + std::vector Symbols; + I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); }); + EXPECT_EQ(Symbols.size(), 1U); + EXPECT_FALSE(Symbols.front().SymInfo.Properties & + static_cast( + index::SymbolProperty::TemplateSpecialization)); + EXPECT_FALSE(Symbols.front().SymInfo.Properties & + static_cast( + index::SymbolProperty::TemplatePartialSpecialization)); +} + } // namespace } // namespace dex } // namespace clangd diff --git a/unittests/clangd/IndexTests.cpp b/unittests/clangd/IndexTests.cpp index 7d60ede1..3a159279 100644 --- a/unittests/clangd/IndexTests.cpp +++ b/unittests/clangd/IndexTests.cpp @@ -13,6 +13,8 @@ #include "index/Index.h" #include "index/MemIndex.h" #include "index/Merge.h" +#include "index/Symbol.h" +#include "clang/Index/IndexSymbol.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -181,6 +183,41 @@ TEST(MemIndexTest, Lookup) { EXPECT_THAT(lookup(*I, SymbolID("ns::nonono")), UnorderedElementsAre()); } +TEST(MemIndexTest, TemplateSpecialization) { + SymbolSlab::Builder B; + + Symbol S = symbol("TempSpec"); + S.ID = SymbolID("0"); + B.insert(S); + + S = symbol("TempSpec"); + S.ID = SymbolID("1"); + S.SymInfo.Properties = static_cast( + index::SymbolProperty::TemplateSpecialization); + B.insert(S); + + S = symbol("TempSpec"); + S.ID = SymbolID("2"); + S.SymInfo.Properties = static_cast( + index::SymbolProperty::TemplatePartialSpecialization); + B.insert(S); + + auto I = MemIndex::build(std::move(B).build(), RefSlab()); + FuzzyFindRequest Req; + Req.Query = "TempSpec"; + Req.AnyScope = true; + + std::vector Symbols; + I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); }); + EXPECT_EQ(Symbols.size(), 1U); + EXPECT_FALSE(Symbols.front().SymInfo.Properties & + static_cast( + index::SymbolProperty::TemplateSpecialization)); + EXPECT_FALSE(Symbols.front().SymInfo.Properties & + static_cast( + index::SymbolProperty::TemplatePartialSpecialization)); +} + TEST(MergeIndexTest, Lookup) { auto I = MemIndex::build(generateSymbols({"ns::A", "ns::B"}), RefSlab()), J = MemIndex::build(generateSymbols({"ns::B", "ns::C"}), RefSlab()); diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index d795286f..f7b125b9 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -392,17 +392,25 @@ TEST_F(SymbolCollectorTest, FileLocal) { TEST_F(SymbolCollectorTest, Template) { Annotations Header(R"( - // Template is indexed, specialization and instantiation is not. - template struct [[Tmpl]] {T $xdecl[[x]] = 0;}; - template <> struct Tmpl {}; - extern template struct Tmpl; - template struct Tmpl; + // Primary template and explicit specialization are indexed, instantiation + // is not. + template struct [[Tmpl]] {T $xdecl[[x]] = 0;}; + template <> struct $specdecl[[Tmpl]] {}; + template struct $partspecdecl[[Tmpl]] {}; + extern template struct Tmpl; + template struct Tmpl; )"); runSymbolCollector(Header.code(), /*Main=*/""); EXPECT_THAT(Symbols, - UnorderedElementsAreArray( - {AllOf(QName("Tmpl"), DeclRange(Header.range())), - AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")))})); + UnorderedElementsAre( + AllOf(QName("Tmpl"), DeclRange(Header.range()), + ForCodeCompletion(true)), + AllOf(QName("Tmpl"), DeclRange(Header.range("specdecl")), + ForCodeCompletion(false)), + AllOf(QName("Tmpl"), DeclRange(Header.range("partspecdecl")), + ForCodeCompletion(false)), + AllOf(QName("Tmpl::x"), DeclRange(Header.range("xdecl")), + ForCodeCompletion(false)))); } TEST_F(SymbolCollectorTest, ObjCSymbols) { -- cgit v1.2.3 From 8d37eb626a8acb4aae4bfc567bc99f94e4cd7d56 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 14 Mar 2019 09:57:10 +0000 Subject: [clangd] Build Dex index after loading all shards in BackgroundIndex. Summary: Currently after loadding all shards, we use MemIndex which has poor query performance, we should use Dex. Reviewers: kadircet Subscribers: ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59350 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356126 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Background.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/clangd/index/Background.cpp b/clangd/index/Background.cpp index 79f21253..8aa59824 100644 --- a/clangd/index/Background.cpp +++ b/clangd/index/Background.cpp @@ -374,7 +374,9 @@ void BackgroundIndex::buildIndex() { // extra index build. reset( IndexedSymbols.buildIndex(IndexType::Heavy, DuplicateHandling::Merge)); - log("BackgroundIndex: rebuilt symbol index."); + log("BackgroundIndex: rebuilt symbol index with estimated memory {0} " + "bytes.", + estimateMemoryUsage()); } } @@ -603,8 +605,10 @@ BackgroundIndex::loadShards(std::vector ChangedFiles) { } } vlog("Loaded all shards"); - reset(IndexedSymbols.buildIndex(IndexType::Light, DuplicateHandling::Merge)); - + reset(IndexedSymbols.buildIndex(IndexType::Heavy, DuplicateHandling::Merge)); + vlog("BackgroundIndex: built symbol index with estimated memory {0} " + "bytes.", + estimateMemoryUsage()); return NeedsReIndexing; } -- cgit v1.2.3 From e7ecb98423711052e91aa133ce2bed9c8cbd5588 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 14 Mar 2019 10:01:07 +0000 Subject: [clangd] Fix an out-of-date FIXME, NFC. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356127 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/index/Index.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/clangd/index/Index.h b/clangd/index/Index.h index 2954b387..0a271a7c 100644 --- a/clangd/index/Index.h +++ b/clangd/index/Index.h @@ -103,9 +103,6 @@ public: llvm::function_ref Callback) const = 0; /// Returns estimated size of index (in bytes). - // FIXME(kbobyrev): Currently, this only returns the size of index itself - // excluding the size of actual symbol slab index refers to. We should include - // both. virtual size_t estimateMemoryUsage() const = 0; }; -- cgit v1.2.3 From 2ca3c0a92ebc01fccfa4c86a85ac623cc2b49665 Mon Sep 17 00:00:00 2001 From: Haojian Wu Date: Thu, 14 Mar 2019 11:25:26 +0000 Subject: [clangd] Using symbol name to map includes for STL symbols. Summary: Using suffix path mapping relies on the STL implementations, and it is not portable. This patch is using symbol name mapping, which should work with different STL implementations, fix clangd/clangd#9. To generate the symbol mapping, we parse the cppreference symbol index page to build a lookup table. The mapping is not completed, a few TODOs: - support symbols from different headers (e.g. std::move) - support STL macros - support symbols from std's sub-namespaces (e.g. chrono) Reviewers: ioeric, jfb, serge-sans-paille Reviewed By: ioeric Subscribers: sammccall, klimek, ilya-biryukov, ioeric, MaskRay, jkorous, mgrang, arphaman, kadircet, jfb, jdoerfert, cfe-commits Tags: #clang-tools-extra, #clang Differential Revision: https://reviews.llvm.org/D58345 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356134 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/StdSymbolMap.inc | 1226 ++++++++++++++++++++++++++++++++++++ clangd/include-mapping/gen_std.py | 149 +++++ clangd/include-mapping/test.py | 101 +++ clangd/index/CanonicalIncludes.cpp | 43 +- 4 files changed, 1484 insertions(+), 35 deletions(-) create mode 100644 clangd/StdSymbolMap.inc create mode 100755 clangd/include-mapping/gen_std.py create mode 100755 clangd/include-mapping/test.py diff --git a/clangd/StdSymbolMap.inc b/clangd/StdSymbolMap.inc new file mode 100644 index 00000000..fa9bf318 --- /dev/null +++ b/clangd/StdSymbolMap.inc @@ -0,0 +1,1226 @@ +//===-- gen_std.py generated file -------------------------------*- C++ -*-===// +// +// Used to build a lookup table (qualified names => include headers) for C++ +// Standard Library symbols. +// +// Automatically generated file, DO NOT EDIT! +// +// Generated from cppreference offline HTML book (modified on 2018-10-28). +//===----------------------------------------------------------------------===// + +SYMBOL(Assignable, std::, ) +SYMBOL(Boolean, std::, ) +SYMBOL(Common, std::, ) +SYMBOL(CommonReference, std::, ) +SYMBOL(Constructible, std::, ) +SYMBOL(ConvertibleTo, std::, ) +SYMBOL(CopyConstructible, std::, ) +SYMBOL(Copyable, std::, ) +SYMBOL(DefaultConstructible, std::, ) +SYMBOL(DerivedFrom, std::, ) +SYMBOL(Destructible, std::, ) +SYMBOL(EqualityComparable, std::, ) +SYMBOL(EqualityComparableWith, std::, ) +SYMBOL(FILE, std::, ) +SYMBOL(Integral, std::, ) +SYMBOL(Invocable, std::, ) +SYMBOL(Movable, std::, ) +SYMBOL(MoveConstructible, std::, ) +SYMBOL(Predicate, std::, ) +SYMBOL(Regular, std::, ) +SYMBOL(RegularInvocable, std::, ) +SYMBOL(Relation, std::, ) +SYMBOL(Same, std::, ) +SYMBOL(Semiregular, std::, ) +SYMBOL(SignedIntegral, std::, ) +SYMBOL(StrictTotallyOrdered, std::, ) +SYMBOL(StrictTotallyOrderedWith, std::, ) +SYMBOL(StrictWeakOrder, std::, ) +SYMBOL(Swappable, std::, ) +SYMBOL(SwappableWith, std::, ) +SYMBOL(UniformRandomBitGenerator, std::, ) +SYMBOL(UnsignedIntegral, std::, ) +SYMBOL(_Exit, std::, ) +SYMBOL(accumulate, std::, ) +SYMBOL(add_const, std::, ) +SYMBOL(add_const_t, std::, ) +SYMBOL(add_cv, std::, ) +SYMBOL(add_cv_t, std::, ) +SYMBOL(add_lvalue_reference, std::, ) +SYMBOL(add_lvalue_reference_t, std::, ) +SYMBOL(add_pointer, std::, ) +SYMBOL(add_pointer_t, std::, ) +SYMBOL(add_rvalue_reference, std::, ) +SYMBOL(add_rvalue_reference_t, std::, ) +SYMBOL(add_volatile, std::, ) +SYMBOL(add_volatile_t, std::, ) +SYMBOL(addressof, std::, ) +SYMBOL(adjacent_difference, std::, ) +SYMBOL(adjacent_find, std::, ) +SYMBOL(adopt_lock, std::, ) +SYMBOL(adopt_lock_t, std::, ) +SYMBOL(advance, std::, ) +SYMBOL(align, std::, ) +SYMBOL(align_val_t, std::, ) +SYMBOL(aligned_alloc, std::, ) +SYMBOL(aligned_storage, std::, ) +SYMBOL(aligned_storage_t, std::, ) +SYMBOL(aligned_union, std::, ) +SYMBOL(aligned_union_t, std::, ) +SYMBOL(alignment_of, std::, ) +SYMBOL(alignment_of_v, std::, ) +SYMBOL(all_of, std::, ) +SYMBOL(allocate_shared, std::, ) +SYMBOL(allocator, std::, ) +SYMBOL(allocator_arg, std::, ) +SYMBOL(allocator_arg_t, std::, ) +SYMBOL(allocator_traits, std::, ) +SYMBOL(any, std::, ) +SYMBOL(any_of, std::, ) +SYMBOL(apply, std::, ) +SYMBOL(arg, std::, ) +SYMBOL(array, std::, ) +SYMBOL(as_const, std::, ) +SYMBOL(asctime, std::, ) +SYMBOL(async, std::, ) +SYMBOL(at_quick_exit, std::, ) +SYMBOL(atexit, std::, ) +SYMBOL(atof, std::, ) +SYMBOL(atoi, std::, ) +SYMBOL(atol, std::, ) +SYMBOL(atoll, std::, ) +SYMBOL(atomic_compare_exchange_strong, std::, ) +SYMBOL(atomic_compare_exchange_strong_explicit, std::, ) +SYMBOL(atomic_compare_exchange_weak, std::, ) +SYMBOL(atomic_compare_exchange_weak_explicit, std::, ) +SYMBOL(atomic_exchange, std::, ) +SYMBOL(atomic_exchange_explicit, std::, ) +SYMBOL(atomic_fetch_add, std::, ) +SYMBOL(atomic_fetch_add_explicit, std::, ) +SYMBOL(atomic_fetch_and, std::, ) +SYMBOL(atomic_fetch_and_explicit, std::, ) +SYMBOL(atomic_fetch_or, std::, ) +SYMBOL(atomic_fetch_or_explicit, std::, ) +SYMBOL(atomic_fetch_sub, std::, ) +SYMBOL(atomic_fetch_sub_explicit, std::, ) +SYMBOL(atomic_fetch_xor, std::, ) +SYMBOL(atomic_fetch_xor_explicit, std::, ) +SYMBOL(atomic_flag, std::, ) +SYMBOL(atomic_flag_clear, std::, ) +SYMBOL(atomic_flag_clear_explicit, std::, ) +SYMBOL(atomic_flag_test_and_set, std::, ) +SYMBOL(atomic_flag_test_and_set_explicit, std::, ) +SYMBOL(atomic_init, std::, ) +SYMBOL(atomic_is_lockfree, std::, ) +SYMBOL(atomic_load, std::, ) +SYMBOL(atomic_load_explicit, std::, ) +SYMBOL(atomic_ref, std::, ) +SYMBOL(atomic_signal_fence, std::, ) +SYMBOL(atomic_store, std::, ) +SYMBOL(atomic_store_explicit, std::, ) +SYMBOL(atomic_thread_fence, std::, ) +SYMBOL(atto, std::, ) +SYMBOL(auto_ptr, std::, ) +SYMBOL(back_insert_iterator, std::, ) +SYMBOL(back_inserter, std::, ) +SYMBOL(bad_alloc, std::, ) +SYMBOL(bad_any_cast, std::, ) +SYMBOL(bad_array_new_length, std::, ) +SYMBOL(bad_cast, std::, ) +SYMBOL(bad_exception, std::, ) +SYMBOL(bad_function_call, std::, ) +SYMBOL(bad_optional_access, std::, ) +SYMBOL(bad_typeid, std::, ) +SYMBOL(bad_variant_access, std::, ) +SYMBOL(bad_weak_ptr, std::, ) +SYMBOL(basic_common_reference, std::, ) +SYMBOL(basic_fstream, std::, ) +SYMBOL(basic_ifstream, std::, ) +SYMBOL(basic_ios, std::, ) +SYMBOL(basic_iostream, std::, ) +SYMBOL(basic_istringstream, std::, ) +SYMBOL(basic_ofstream, std::, ) +SYMBOL(basic_ostringstream, std::, ) +SYMBOL(basic_osyncstream, std::, ) +SYMBOL(basic_regex, std::, ) +SYMBOL(basic_streambuf, std::, ) +SYMBOL(basic_string, std::, ) +SYMBOL(basic_string_view, std::, ) +SYMBOL(basic_stringbuf, std::, ) +SYMBOL(basic_stringstream, std::, ) +SYMBOL(basic_syncbuf, std::, ) +SYMBOL(begin, std::, ) +SYMBOL(bernoulli_distribution, std::, ) +SYMBOL(bidirectional_iterator_tag, std::, ) +SYMBOL(binary_search, std::, ) +SYMBOL(bind, std::, ) +SYMBOL(binomial_distribution, std::, ) +SYMBOL(bit_and, std::, ) +SYMBOL(bit_cast, std::, ) +SYMBOL(bit_not, std::, ) +SYMBOL(bit_or, std::, ) +SYMBOL(bit_xor, std::, ) +SYMBOL(bitset, std::, ) +SYMBOL(bool_constant, std::, ) +SYMBOL(boolalpha, std::, ) +SYMBOL(boyer_moore_horspool_searcher, std::, ) +SYMBOL(boyer_moore_searcher, std::, ) +SYMBOL(bsearch, std::, ) +SYMBOL(btowc, std::, ) +SYMBOL(byte, std::, ) +SYMBOL(c16rtomb, std::, ) +SYMBOL(c32rtomb, std::, ) +SYMBOL(call_once, std::, ) +SYMBOL(calloc, std::, ) +SYMBOL(cauchy_distribution, std::, ) +SYMBOL(cbegin, std::, ) +SYMBOL(cbrt, std::, ) +SYMBOL(ceil, std::, ) +SYMBOL(ceil2, std::, ) +SYMBOL(cend, std::, ) +SYMBOL(centi, std::, ) +SYMBOL(cerr, std::, ) +SYMBOL(char_traits, std::, ) +SYMBOL(chars_format, std::, ) +SYMBOL(chi_squared_distribution, std::, ) +SYMBOL(cin, std::, ) +SYMBOL(clamp, std::, ) +SYMBOL(clearerr, std::, ) +SYMBOL(clock, std::, ) +SYMBOL(clock_t, std::, ) +SYMBOL(clog, std::, ) +SYMBOL(cmatch, std::, ) +SYMBOL(codecvt, std::, ) +SYMBOL(codecvt_base, std::, ) +SYMBOL(codecvt_byname, std::, ) +SYMBOL(codecvt_utf16, std::, ) +SYMBOL(codecvt_utf8, std::, ) +SYMBOL(codecvt_utf8_utf16, std::, ) +SYMBOL(collate, std::, ) +SYMBOL(collate_byname, std::, ) +SYMBOL(common_comparison_category, std::, ) +SYMBOL(common_comparison_category_t, std::, ) +SYMBOL(common_reference, std::, ) +SYMBOL(common_reference_t, std::, ) +SYMBOL(common_type, std::, ) +SYMBOL(common_type_t, std::, ) +SYMBOL(compare_3way, std::, ) +SYMBOL(complex, std::, ) +SYMBOL(condition_variable, std::, ) +SYMBOL(condition_variable_any, std::, ) +SYMBOL(conditional, std::, ) +SYMBOL(conditional_t, std::, ) +SYMBOL(conj, std::, ) +SYMBOL(conjunction, std::, ) +SYMBOL(conjunction_v, std::, ) +SYMBOL(const_pointer_cast, std::, ) +SYMBOL(contract_violation, std::, ) +SYMBOL(copy, std::, ) +SYMBOL(copy_backward, std::, ) +SYMBOL(copy_if, std::, ) +SYMBOL(copy_n, std::, ) +SYMBOL(copysign, std::, ) +SYMBOL(count, std::, ) +SYMBOL(count_if, std::, ) +SYMBOL(cout, std::, ) +SYMBOL(crbegin, std::, ) +SYMBOL(cref, std::, ) +SYMBOL(cregex_iterator, std::, ) +SYMBOL(cregex_token_iterator, std::, ) +SYMBOL(crend, std::, ) +SYMBOL(csub_match, std::, ) +SYMBOL(ctime, std::, ) +SYMBOL(ctype, std::, ) +SYMBOL(ctype_base, std::, ) +SYMBOL(ctype_byname, std::, ) +SYMBOL(current_exception, std::, ) +SYMBOL(cv_status, std::, ) +SYMBOL(data, std::, ) +SYMBOL(dec, std::, ) +SYMBOL(deca, std::, ) +SYMBOL(decay, std::, ) +SYMBOL(decay_t, std::, ) +SYMBOL(deci, std::, ) +SYMBOL(declare_no_pointers, std::, ) +SYMBOL(declare_reachable, std::, ) +SYMBOL(declval, std::, ) +SYMBOL(default_delete, std::, ) +SYMBOL(default_searcher, std::, ) +SYMBOL(defaultfloat, std::, ) +SYMBOL(defer_lock, std::, ) +SYMBOL(defer_lock_t, std::, ) +SYMBOL(denorm_absent, std::, ) +SYMBOL(denorm_indeterminate, std::, ) +SYMBOL(denorm_present, std::, ) +SYMBOL(deque, std::, ) +SYMBOL(destroy, std::, ) +SYMBOL(destroy_at, std::, ) +SYMBOL(destroy_n, std::, ) +SYMBOL(destroying_delete, std::, ) +SYMBOL(destroying_delete_t, std::, ) +SYMBOL(difftime, std::, ) +SYMBOL(discard_block_engine, std::, ) +SYMBOL(discrete_distribution, std::, ) +SYMBOL(disjunction, std::, ) +SYMBOL(disjunction_v, std::, ) +SYMBOL(distance, std::, ) +SYMBOL(divides, std::, ) +SYMBOL(domain_error, std::, ) +SYMBOL(dynamic_extent, std::, ) +SYMBOL(dynamic_pointer_cast, std::, ) +SYMBOL(emit_on_flush, std::, ) +SYMBOL(empty, std::, ) +SYMBOL(enable_if, std::, ) +SYMBOL(enable_if_t, std::, ) +SYMBOL(enable_shared_from_this, std::, ) +SYMBOL(end, std::, ) +SYMBOL(endian, std::, ) +SYMBOL(endl, std::, ) +SYMBOL(ends, std::, ) +SYMBOL(equal, std::, ) +SYMBOL(equal_range, std::, ) +SYMBOL(equal_to, std::, ) +SYMBOL(erf, std::, ) +SYMBOL(erfc, std::, ) +SYMBOL(errc, std::, ) +SYMBOL(error_category, std::, ) +SYMBOL(error_code, std::, ) +SYMBOL(error_condition, std::, ) +SYMBOL(exa, std::, ) +SYMBOL(exception, std::, ) +SYMBOL(exception_ptr, std::, ) +SYMBOL(exchange, std::, ) +SYMBOL(exclusive_scan, std::, ) +SYMBOL(exit, std::, ) +SYMBOL(exp2, std::, ) +SYMBOL(expm1, std::, ) +SYMBOL(exponential_distribution, std::, ) +SYMBOL(extent, std::, ) +SYMBOL(extent_v, std::, ) +SYMBOL(extreme_value_distribution, std::, ) +SYMBOL(false_type, std::, ) +SYMBOL(fclose, std::, ) +SYMBOL(fdim, std::, ) +SYMBOL(feclearexcept, std::, ) +SYMBOL(fegetenv, std::, ) +SYMBOL(fegetexceptflag, std::, ) +SYMBOL(fegetround, std::, ) +SYMBOL(feholdexcept, std::, ) +SYMBOL(femto, std::, ) +SYMBOL(fenv_t, std::, ) +SYMBOL(feof, std::, ) +SYMBOL(feraiseexcept, std::, ) +SYMBOL(ferror, std::, ) +SYMBOL(fesetenv, std::, ) +SYMBOL(fesetexceptflag, std::, ) +SYMBOL(fesetround, std::, ) +SYMBOL(fetestexcept, std::, ) +SYMBOL(feupdateenv, std::, ) +SYMBOL(fexcept_t, std::, ) +SYMBOL(fflush, std::, ) +SYMBOL(fgetc, std::, ) +SYMBOL(fgetpos, std::, ) +SYMBOL(fgets, std::, ) +SYMBOL(fgetwc, std::, ) +SYMBOL(fgetws, std::, ) +SYMBOL(fill, std::, ) +SYMBOL(fill_n, std::, ) +SYMBOL(find, std::, ) +SYMBOL(find_end, std::, ) +SYMBOL(find_first_of, std::, ) +SYMBOL(find_if, std::, ) +SYMBOL(find_if_not, std::, ) +SYMBOL(fisher_f_distribution, std::, ) +SYMBOL(fixed, std::, ) +SYMBOL(float_denorm_style, std::, ) +SYMBOL(float_round_style, std::, ) +SYMBOL(floor, std::, ) +SYMBOL(floor2, std::, ) +SYMBOL(flush, std::, ) +SYMBOL(flush_emit, std::, ) +SYMBOL(fma, std::, ) +SYMBOL(fmax, std::, ) +SYMBOL(fmin, std::, ) +SYMBOL(fmod, std::, ) +SYMBOL(fopen, std::, ) +SYMBOL(for_each, std::, ) +SYMBOL(for_each_n, std::, ) +SYMBOL(forward, std::, ) +SYMBOL(forward_as_tuple, std::, ) +SYMBOL(forward_iterator_tag, std::, ) +SYMBOL(forward_list, std::, ) +SYMBOL(fpclassify, std::, ) +SYMBOL(fpos, std::, ) +SYMBOL(fpos_t, std::, ) +SYMBOL(fprintf, std::, ) +SYMBOL(fputc, std::, ) +SYMBOL(fputs, std::, ) +SYMBOL(fputwc, std::, ) +SYMBOL(fputws, std::, ) +SYMBOL(fread, std::, ) +SYMBOL(free, std::, ) +SYMBOL(freopen, std::, ) +SYMBOL(frexp, std::, ) +SYMBOL(from_chars, std::, ) +SYMBOL(front_insert_iterator, std::, ) +SYMBOL(front_inserter, std::, ) +SYMBOL(fscanf, std::, ) +SYMBOL(fseek, std::, ) +SYMBOL(fsetpos, std::, ) +SYMBOL(fstream, std::, ) +SYMBOL(ftell, std::, ) +SYMBOL(function, std::, ) +SYMBOL(future, std::, ) +SYMBOL(future_category, std::, ) +SYMBOL(future_errc, std::, ) +SYMBOL(future_error, std::, ) +SYMBOL(future_status, std::, ) +SYMBOL(fwide, std::, ) +SYMBOL(fwprintf, std::, ) +SYMBOL(fwrite, std::, ) +SYMBOL(fwscanf, std::, ) +SYMBOL(gamma_distribution, std::, ) +SYMBOL(gcd, std::, ) +SYMBOL(generate, std::, ) +SYMBOL(generate_canonical, std::, ) +SYMBOL(generate_n, std::, ) +SYMBOL(generic_category, std::, ) +SYMBOL(geometric_distribution, std::, ) +SYMBOL(get_if, std::, ) +SYMBOL(get_money, std::, ) +SYMBOL(get_new_handler, std::, ) +SYMBOL(get_pointer_safety, std::, ) +SYMBOL(get_terminate, std::, ) +SYMBOL(get_time, std::, ) +SYMBOL(getc, std::, ) +SYMBOL(getchar, std::, ) +SYMBOL(getenv, std::, ) +SYMBOL(gets, std::, ) +SYMBOL(getwc, std::, ) +SYMBOL(getwchar, std::, ) +SYMBOL(giga, std::, ) +SYMBOL(gmtime, std::, ) +SYMBOL(greater, std::, ) +SYMBOL(greater_equal, std::, ) +SYMBOL(gslice, std::, ) +SYMBOL(gslice_array, std::, ) +SYMBOL(hardware_constructive_interference_size, std::, ) +SYMBOL(hardware_destructive_interference_size, std::, ) +SYMBOL(has_facet, std::, ) +SYMBOL(has_unique_object_representations, std::, ) +SYMBOL(has_unique_object_representations_v, std::, ) +SYMBOL(has_virtual_destructor, std::, ) +SYMBOL(has_virtual_destructor_v, std::, ) +SYMBOL(hash, std::, ) +SYMBOL(hecto, std::, ) +SYMBOL(hex, std::, ) +SYMBOL(hexfloat, std::, ) +SYMBOL(holds_alternative, std::, ) +SYMBOL(hypot, std::, ) +SYMBOL(identity, std::, ) +SYMBOL(ifstream, std::, ) +SYMBOL(ignore, std::, ) +SYMBOL(ilogb, std::, ) +SYMBOL(imag, std::, ) +SYMBOL(in_place, std::, ) +SYMBOL(in_place_index, std::, ) +SYMBOL(in_place_index_t, std::, ) +SYMBOL(in_place_t, std::, ) +SYMBOL(in_place_type, std::, ) +SYMBOL(in_place_type_t, std::, ) +SYMBOL(includes, std::, ) +SYMBOL(inclusive_scan, std::, ) +SYMBOL(independent_bits_engine, std::, ) +SYMBOL(indirect_array, std::, ) +SYMBOL(inner_product, std::, ) +SYMBOL(inplace_merge, std::, ) +SYMBOL(input_iterator_tag, std::, ) +SYMBOL(insert_iterator, std::, ) +SYMBOL(inserter, std::, ) +SYMBOL(integer_sequence, std::, ) +SYMBOL(integral_constant, std::, ) +SYMBOL(internal, std::, ) +SYMBOL(invalid_argument, std::, ) +SYMBOL(invoke, std::, ) +SYMBOL(invoke_result, std::, ) +SYMBOL(invoke_result_t, std::, ) +SYMBOL(io_errc, std::, ) +SYMBOL(ios, std::, ) +SYMBOL(ios_base, std::, ) +SYMBOL(iostream, std::, ) +SYMBOL(iostream_category, std::, ) +SYMBOL(iota, std::, ) +SYMBOL(is_abstract, std::, ) +SYMBOL(is_abstract_v, std::, ) +SYMBOL(is_aggregate, std::, ) +SYMBOL(is_aggregate_v, std::, ) +SYMBOL(is_arithmetic, std::, ) +SYMBOL(is_arithmetic_v, std::, ) +SYMBOL(is_array, std::, ) +SYMBOL(is_array_v, std::, ) +SYMBOL(is_assignable, std::, ) +SYMBOL(is_assignable_v, std::, ) +SYMBOL(is_base_of, std::, ) +SYMBOL(is_base_of_v, std::, ) +SYMBOL(is_bind_expression, std::, ) +SYMBOL(is_bind_expression_v, std::, ) +SYMBOL(is_class, std::, ) +SYMBOL(is_class_v, std::, ) +SYMBOL(is_compound, std::, ) +SYMBOL(is_compound_v, std::, ) +SYMBOL(is_const, std::, ) +SYMBOL(is_const_v, std::, ) +SYMBOL(is_constructible, std::, ) +SYMBOL(is_constructible_v, std::, ) +SYMBOL(is_convertible, std::, ) +SYMBOL(is_convertible_v, std::, ) +SYMBOL(is_copy_assignable, std::, ) +SYMBOL(is_copy_assignable_v, std::, ) +SYMBOL(is_copy_constructible, std::, ) +SYMBOL(is_copy_constructible_v, std::, ) +SYMBOL(is_default_constructible, std::, ) +SYMBOL(is_default_constructible_v, std::, ) +SYMBOL(is_destructible, std::, ) +SYMBOL(is_destructible_v, std::, ) +SYMBOL(is_empty, std::, ) +SYMBOL(is_empty_v, std::, ) +SYMBOL(is_enum, std::, ) +SYMBOL(is_enum_v, std::, ) +SYMBOL(is_eq, std::, ) +SYMBOL(is_error_code_enum, std::, ) +SYMBOL(is_error_condition_enum, std::, ) +SYMBOL(is_error_condition_enum_v, std::, ) +SYMBOL(is_execution_policy, std::, ) +SYMBOL(is_execution_policy_v, std::, ) +SYMBOL(is_final, std::, ) +SYMBOL(is_final_v, std::, ) +SYMBOL(is_floating_point, std::, ) +SYMBOL(is_floating_point_v, std::, ) +SYMBOL(is_function, std::, ) +SYMBOL(is_function_v, std::, ) +SYMBOL(is_fundamental, std::, ) +SYMBOL(is_fundamental_v, std::, ) +SYMBOL(is_gt, std::, ) +SYMBOL(is_gteq, std::, ) +SYMBOL(is_heap, std::, ) +SYMBOL(is_heap_until, std::, ) +SYMBOL(is_integral, std::, ) +SYMBOL(is_integral_v, std::, ) +SYMBOL(is_invocable, std::, ) +SYMBOL(is_invocable_r, std::, ) +SYMBOL(is_invocable_r_v, std::, ) +SYMBOL(is_invocable_v, std::, ) +SYMBOL(is_lt, std::, ) +SYMBOL(is_lteq, std::, ) +SYMBOL(is_lvalue_reference, std::, ) +SYMBOL(is_lvalue_reference_v, std::, ) +SYMBOL(is_member_function_pointer, std::, ) +SYMBOL(is_member_function_pointer_v, std::, ) +SYMBOL(is_member_object_pointer, std::, ) +SYMBOL(is_member_object_pointer_v, std::, ) +SYMBOL(is_member_pointer, std::, ) +SYMBOL(is_member_pointer_v, std::, ) +SYMBOL(is_move_assignable, std::, ) +SYMBOL(is_move_assignable_v, std::, ) +SYMBOL(is_move_constructible, std::, ) +SYMBOL(is_move_constructible_v, std::, ) +SYMBOL(is_neq, std::, ) +SYMBOL(is_nothrow_assignable, std::, ) +SYMBOL(is_nothrow_assignable_v, std::, ) +SYMBOL(is_nothrow_constructible, std::, ) +SYMBOL(is_nothrow_constructible_v, std::, ) +SYMBOL(is_nothrow_copy_assignable, std::, ) +SYMBOL(is_nothrow_copy_assignable_v, std::, ) +SYMBOL(is_nothrow_copy_constructible, std::, ) +SYMBOL(is_nothrow_copy_constructible_v, std::, ) +SYMBOL(is_nothrow_default_constructible, std::, ) +SYMBOL(is_nothrow_default_constructible_v, std::, ) +SYMBOL(is_nothrow_destructible, std::, ) +SYMBOL(is_nothrow_destructible_v, std::, ) +SYMBOL(is_nothrow_invocable, std::, ) +SYMBOL(is_nothrow_invocable_r, std::, ) +SYMBOL(is_nothrow_invocable_r_v, std::, ) +SYMBOL(is_nothrow_invocable_v, std::, ) +SYMBOL(is_nothrow_move_assignable, std::, ) +SYMBOL(is_nothrow_move_assignable_v, std::, ) +SYMBOL(is_nothrow_move_constructible, std::, ) +SYMBOL(is_nothrow_move_constructible_v, std::, ) +SYMBOL(is_nothrow_swappable, std::, ) +SYMBOL(is_nothrow_swappable_v, std::, ) +SYMBOL(is_nothrow_swappable_with, std::, ) +SYMBOL(is_nothrow_swappable_with_v, std::, ) +SYMBOL(is_null_pointer, std::, ) +SYMBOL(is_null_pointer_v, std::, ) +SYMBOL(is_object, std::, ) +SYMBOL(is_object_v, std::, ) +SYMBOL(is_partitioned, std::, ) +SYMBOL(is_permutation, std::, ) +SYMBOL(is_placeholder, std::, ) +SYMBOL(is_placeholder_v, std::, ) +SYMBOL(is_pod, std::, ) +SYMBOL(is_pod_v, std::, ) +SYMBOL(is_pointer, std::, ) +SYMBOL(is_pointer_v, std::, ) +SYMBOL(is_polymorphic, std::, ) +SYMBOL(is_polymorphic_v, std::, ) +SYMBOL(is_reference, std::, ) +SYMBOL(is_reference_v, std::, ) +SYMBOL(is_rvalue_reference, std::, ) +SYMBOL(is_rvalue_reference_v, std::, ) +SYMBOL(is_same, std::, ) +SYMBOL(is_same_v, std::, ) +SYMBOL(is_scalar, std::, ) +SYMBOL(is_scalar_v, std::, ) +SYMBOL(is_signed, std::, ) +SYMBOL(is_signed_v, std::, ) +SYMBOL(is_sorted, std::, ) +SYMBOL(is_sorted_until, std::, ) +SYMBOL(is_standard_layout, std::, ) +SYMBOL(is_standard_layout_v, std::, ) +SYMBOL(is_swappable, std::, ) +SYMBOL(is_swappable_v, std::, ) +SYMBOL(is_swappable_with, std::, ) +SYMBOL(is_swappable_with_v, std::, ) +SYMBOL(is_trivial, std::, ) +SYMBOL(is_trivial_v, std::, ) +SYMBOL(is_trivially_assignable, std::, ) +SYMBOL(is_trivially_assignable_v, std::, ) +SYMBOL(is_trivially_constructible, std::, ) +SYMBOL(is_trivially_constructible_v, std::, ) +SYMBOL(is_trivially_copy_assignable, std::, ) +SYMBOL(is_trivially_copy_assignable_v, std::, ) +SYMBOL(is_trivially_copy_constructible, std::, ) +SYMBOL(is_trivially_copy_constructible_v, std::, ) +SYMBOL(is_trivially_copyable, std::, ) +SYMBOL(is_trivially_copyable_v, std::, ) +SYMBOL(is_trivially_default_constructible, std::, ) +SYMBOL(is_trivially_default_constructible_v, std::, ) +SYMBOL(is_trivially_destructible, std::, ) +SYMBOL(is_trivially_destructible_v, std::, ) +SYMBOL(is_trivially_move_assignable, std::, ) +SYMBOL(is_trivially_move_assignable_v, std::, ) +SYMBOL(is_trivially_move_constructible, std::, ) +SYMBOL(is_trivially_move_constructible_v, std::, ) +SYMBOL(is_union, std::, ) +SYMBOL(is_union_v, std::, ) +SYMBOL(is_unsigned, std::, ) +SYMBOL(is_unsigned_v, std::, ) +SYMBOL(is_void, std::, ) +SYMBOL(is_void_v, std::, ) +SYMBOL(is_volatile, std::, ) +SYMBOL(is_volatile_v, std::, ) +SYMBOL(isfinite, std::, ) +SYMBOL(isgreater, std::, ) +SYMBOL(isgreaterequal, std::, ) +SYMBOL(isinf, std::, ) +SYMBOL(isless, std::, ) +SYMBOL(islessequal, std::, ) +SYMBOL(islessgreater, std::, ) +SYMBOL(isnan, std::, ) +SYMBOL(isnormal, std::, ) +SYMBOL(ispow2, std::, ) +SYMBOL(istream_iterator, std::, ) +SYMBOL(istreambuf_iterator, std::, ) +SYMBOL(istringstream, std::, ) +SYMBOL(isunordered, std::, ) +SYMBOL(iswalnum, std::, ) +SYMBOL(iswalpha, std::, ) +SYMBOL(iswblank, std::, ) +SYMBOL(iswcntrl, std::, ) +SYMBOL(iswctype, std::, ) +SYMBOL(iswdigit, std::, ) +SYMBOL(iswgraph, std::, ) +SYMBOL(iswlower, std::, ) +SYMBOL(iswprint, std::, ) +SYMBOL(iswpunct, std::, ) +SYMBOL(iswspace, std::, ) +SYMBOL(iswupper, std::, ) +SYMBOL(iswxdigit, std::, ) +SYMBOL(iter_swap, std::, ) +SYMBOL(iterator, std::, ) +SYMBOL(iterator_traits, std::, ) +SYMBOL(jmp_buf, std::, ) +SYMBOL(kill_dependency, std::, ) +SYMBOL(kilo, std::, ) +SYMBOL(launch, std::, ) +SYMBOL(launder, std::, ) +SYMBOL(lcm, std::, ) +SYMBOL(lconv, std::, ) +SYMBOL(ldexp, std::, ) +SYMBOL(left, std::, ) +SYMBOL(length_error, std::, ) +SYMBOL(less, std::, ) +SYMBOL(less_equal, std::, ) +SYMBOL(lexicographical_compare, std::, ) +SYMBOL(lexicographical_compare_3way, std::, ) +SYMBOL(lgamma, std::, ) +SYMBOL(linear_congruential_engine, std::, ) +SYMBOL(list, std::, ) +SYMBOL(llrint, std::, ) +SYMBOL(llround, std::, ) +SYMBOL(locale, std::, ) +SYMBOL(localeconv, std::, ) +SYMBOL(localtime, std::, ) +SYMBOL(lock, std::, ) +SYMBOL(lock_guard, std::, ) +SYMBOL(log1p, std::, ) +SYMBOL(log2, std::, ) +SYMBOL(log2p1, std::, ) +SYMBOL(logb, std::, ) +SYMBOL(logic_error, std::, ) +SYMBOL(logical_and, std::, ) +SYMBOL(logical_not, std::, ) +SYMBOL(logical_or, std::, ) +SYMBOL(lognormal_distribution, std::, ) +SYMBOL(longjmp, std::, ) +SYMBOL(lower_bound, std::, ) +SYMBOL(lrint, std::, ) +SYMBOL(lround, std::, ) +SYMBOL(make_exception_ptr, std::, ) +SYMBOL(make_from_tuple, std::, ) +SYMBOL(make_heap, std::, ) +SYMBOL(make_move_iterator, std::, ) +SYMBOL(make_optional, std::, ) +SYMBOL(make_pair, std::, ) +SYMBOL(make_reverse_iterator, std::, ) +SYMBOL(make_shared, std::, ) +SYMBOL(make_signed, std::, ) +SYMBOL(make_signed_t, std::, ) +SYMBOL(make_tuple, std::, ) +SYMBOL(make_unique, std::, ) +SYMBOL(make_unsigned, std::, ) +SYMBOL(make_unsigned_t, std::, ) +SYMBOL(malloc, std::, ) +SYMBOL(map, std::, ) +SYMBOL(mask_array, std::, ) +SYMBOL(match_results, std::, ) +SYMBOL(max, std::, ) +SYMBOL(max_align_t, std::, ) +SYMBOL(max_element, std::, ) +SYMBOL(mblen, std::, ) +SYMBOL(mbrlen, std::, ) +SYMBOL(mbrtoc16, std::, ) +SYMBOL(mbrtoc32, std::, ) +SYMBOL(mbrtowc, std::, ) +SYMBOL(mbsinit, std::, ) +SYMBOL(mbsrtowcs, std::, ) +SYMBOL(mbstowcs, std::, ) +SYMBOL(mbtowc, std::, ) +SYMBOL(mega, std::, ) +SYMBOL(mem_fn, std::, ) +SYMBOL(memchr, std::, ) +SYMBOL(memcmp, std::, ) +SYMBOL(memcpy, std::, ) +SYMBOL(memmove, std::, ) +SYMBOL(memory_order, std::, ) +SYMBOL(memory_order_acq_rel, std::, ) +SYMBOL(memory_order_acquire, std::, ) +SYMBOL(memory_order_consume, std::, ) +SYMBOL(memory_order_relaxed, std::, ) +SYMBOL(memory_order_release, std::, ) +SYMBOL(memory_order_seq_cst, std::, ) +SYMBOL(memset, std::, ) +SYMBOL(merge, std::, ) +SYMBOL(mersenne_twister_engine, std::, ) +SYMBOL(messages, std::, ) +SYMBOL(messages_base, std::, ) +SYMBOL(messages_byname, std::, ) +SYMBOL(micro, std::, ) +SYMBOL(milli, std::, ) +SYMBOL(min, std::, ) +SYMBOL(min_element, std::, ) +SYMBOL(minmax, std::, ) +SYMBOL(minmax_element, std::, ) +SYMBOL(minus, std::, ) +SYMBOL(mismatch, std::, ) +SYMBOL(mktime, std::, ) +SYMBOL(modf, std::, ) +SYMBOL(modulus, std::, ) +SYMBOL(money_base, std::, ) +SYMBOL(money_get, std::, ) +SYMBOL(money_put, std::, ) +SYMBOL(moneypunct, std::, ) +SYMBOL(moneypunct_byname, std::, ) +SYMBOL(monostate, std::, ) +SYMBOL(move_backward, std::, ) +SYMBOL(move_if_noexcept, std::, ) +SYMBOL(move_iterator, std::, ) +SYMBOL(multimap, std::, ) +SYMBOL(multiplies, std::, ) +SYMBOL(multiset, std::, ) +SYMBOL(mutex, std::, ) +SYMBOL(nan, std::, ) +SYMBOL(nanf, std::, ) +SYMBOL(nanl, std::, ) +SYMBOL(nano, std::, ) +SYMBOL(nearbyint, std::, ) +SYMBOL(negate, std::, ) +SYMBOL(negation, std::, ) +SYMBOL(negation_v, std::, ) +SYMBOL(negative_binomial_distribution, std::, ) +SYMBOL(nested_exception, std::, ) +SYMBOL(new_handler, std::, ) +SYMBOL(next, std::, ) +SYMBOL(next_permutation, std::, ) +SYMBOL(nextafter, std::, ) +SYMBOL(nexttoward, std::, ) +SYMBOL(no_emit_on_flush, std::, ) +SYMBOL(noboolalpha, std::, ) +SYMBOL(none_of, std::, ) +SYMBOL(norm, std::, ) +SYMBOL(normal_distribution, std::, ) +SYMBOL(noshowbase, std::, ) +SYMBOL(noshowpoint, std::, ) +SYMBOL(noshowpos, std::, ) +SYMBOL(noskipws, std::, ) +SYMBOL(not_equal_to, std::, ) +SYMBOL(not_fn, std::, ) +SYMBOL(nothrow, std::, ) +SYMBOL(nothrow_t, std::, ) +SYMBOL(notify_all_at_thread_exit, std::, ) +SYMBOL(nounitbuf, std::, ) +SYMBOL(nouppercase, std::, ) +SYMBOL(nth_element, std::, ) +SYMBOL(nullopt, std::, ) +SYMBOL(nullopt_t, std::, ) +SYMBOL(nullptr_t, std::, ) +SYMBOL(num_get, std::, ) +SYMBOL(num_put, std::, ) +SYMBOL(numeric_limits, std::, ) +SYMBOL(numpunct, std::, ) +SYMBOL(numpunct_byname, std::, ) +SYMBOL(oct, std::, ) +SYMBOL(ofstream, std::, ) +SYMBOL(once_flag, std::, ) +SYMBOL(optional, std::, ) +SYMBOL(ostream_iterator, std::, ) +SYMBOL(ostreambuf_iterator, std::, ) +SYMBOL(ostringstream, std::, ) +SYMBOL(osyncstream, std::, ) +SYMBOL(out_of_range, std::, ) +SYMBOL(output_iterator_tag, std::, ) +SYMBOL(overflow_error, std::, ) +SYMBOL(owner_less, std::, ) +SYMBOL(packaged_task, std::, ) +SYMBOL(pair, std::, ) +SYMBOL(partial_order, std::, ) +SYMBOL(partial_ordering, std::, ) +SYMBOL(partial_sort, std::, ) +SYMBOL(partial_sort_copy, std::, ) +SYMBOL(partial_sum, std::, ) +SYMBOL(partition, std::, ) +SYMBOL(partition_copy, std::, ) +SYMBOL(partition_point, std::, ) +SYMBOL(perror, std::, ) +SYMBOL(peta, std::, ) +SYMBOL(pico, std::, ) +SYMBOL(piecewise_constant_distribution, std::, ) +SYMBOL(piecewise_construct_t, std::, ) +SYMBOL(piecewise_linear_distribution, std::, ) +SYMBOL(plus, std::, ) +SYMBOL(pointer_safety, std::, ) +SYMBOL(pointer_traits, std::, ) +SYMBOL(poisson_distribution, std::, ) +SYMBOL(polar, std::, ) +SYMBOL(polymorphic_allocator, std::, ) +SYMBOL(pop_heap, std::, ) +SYMBOL(prev, std::, ) +SYMBOL(prev_permutation, std::, ) +SYMBOL(printf, std::, ) +SYMBOL(priority_queue, std::, ) +SYMBOL(proj, std::, ) +SYMBOL(promise, std::, ) +SYMBOL(ptrdiff_t, std::, ) +SYMBOL(push_heap, std::, ) +SYMBOL(put_money, std::, ) +SYMBOL(put_time, std::, ) +SYMBOL(putc, std::, ) +SYMBOL(putchar, std::, ) +SYMBOL(puts, std::, ) +SYMBOL(putwc, std::, ) +SYMBOL(putwchar, std::, ) +SYMBOL(qsort, std::, ) +SYMBOL(queue, std::, ) +SYMBOL(quick_exit, std::, ) +SYMBOL(quoted, std::, ) +SYMBOL(raise, std::, ) +SYMBOL(rand, std::, ) +SYMBOL(random_access_iterator_tag, std::, ) +SYMBOL(random_device, std::, ) +SYMBOL(random_shuffle, std::, ) +SYMBOL(range_error, std::, ) +SYMBOL(rank, std::, ) +SYMBOL(rank_v, std::, ) +SYMBOL(ratio, std::, ) +SYMBOL(ratio_add, std::, ) +SYMBOL(ratio_divide, std::, ) +SYMBOL(ratio_equal, std::, ) +SYMBOL(ratio_equal_v, std::, ) +SYMBOL(ratio_greater, std::, ) +SYMBOL(ratio_greater_equal, std::, ) +SYMBOL(ratio_greater_equal_v, std::, ) +SYMBOL(ratio_greater_v, std::, ) +SYMBOL(ratio_less, std::, ) +SYMBOL(ratio_less_equal, std::, ) +SYMBOL(ratio_less_equal_v, std::, ) +SYMBOL(ratio_less_v, std::, ) +SYMBOL(ratio_multiply, std::, ) +SYMBOL(ratio_not_equal, std::, ) +SYMBOL(ratio_not_equal_v, std::, ) +SYMBOL(ratio_subtract, std::, ) +SYMBOL(rbegin, std::, ) +SYMBOL(real, std::, ) +SYMBOL(realloc, std::, ) +SYMBOL(recursive_mutex, std::, ) +SYMBOL(recursive_timed_mutex, std::, ) +SYMBOL(reduce, std::, ) +SYMBOL(ref, std::, ) +SYMBOL(reference_wrapper, std::, ) +SYMBOL(regex, std::, ) +SYMBOL(regex_error, std::, ) +SYMBOL(regex_iterator, std::, ) +SYMBOL(regex_match, std::, ) +SYMBOL(regex_replace, std::, ) +SYMBOL(regex_search, std::, ) +SYMBOL(regex_token_iterator, std::, ) +SYMBOL(regex_traits, std::, ) +SYMBOL(reinterpret_pointer_cast, std::, ) +SYMBOL(remainder, std::, ) +SYMBOL(remove_all_extents, std::, ) +SYMBOL(remove_all_extents_t, std::, ) +SYMBOL(remove_const, std::, ) +SYMBOL(remove_const_t, std::, ) +SYMBOL(remove_copy, std::, ) +SYMBOL(remove_copy_if, std::, ) +SYMBOL(remove_cv, std::, ) +SYMBOL(remove_cv_t, std::, ) +SYMBOL(remove_cvref, std::, ) +SYMBOL(remove_cvref_t, std::, ) +SYMBOL(remove_extent, std::, ) +SYMBOL(remove_extent_t, std::, ) +SYMBOL(remove_pointer, std::, ) +SYMBOL(remove_pointer_t, std::, ) +SYMBOL(remove_reference, std::, ) +SYMBOL(remove_reference_t, std::, ) +SYMBOL(remove_volatile, std::, ) +SYMBOL(remove_volatile_t, std::, ) +SYMBOL(remquo, std::, ) +SYMBOL(rename, std::, ) +SYMBOL(rend, std::, ) +SYMBOL(replace, std::, ) +SYMBOL(replace_copy, std::, ) +SYMBOL(replace_copy_if, std::, ) +SYMBOL(replace_if, std::, ) +SYMBOL(resetiosflags, std::, ) +SYMBOL(result_of, std::, ) +SYMBOL(result_of_t, std::, ) +SYMBOL(rethrow_exception, std::, ) +SYMBOL(rethrow_if_nested, std::, ) +SYMBOL(reverse, std::, ) +SYMBOL(reverse_copy, std::, ) +SYMBOL(reverse_iterator, std::, ) +SYMBOL(rewind, std::, ) +SYMBOL(right, std::, ) +SYMBOL(rint, std::, ) +SYMBOL(rotate, std::, ) +SYMBOL(rotate_copy, std::, ) +SYMBOL(round, std::, ) +SYMBOL(round_indeterminate, std::, ) +SYMBOL(round_to_nearest, std::, ) +SYMBOL(round_toward_infinity, std::, ) +SYMBOL(round_toward_neg_infinity, std::, ) +SYMBOL(round_toward_zero, std::, ) +SYMBOL(runtime_error, std::, ) +SYMBOL(sample, std::, ) +SYMBOL(scalbln, std::, ) +SYMBOL(scalbn, std::, ) +SYMBOL(scanf, std::, ) +SYMBOL(scientific, std::, ) +SYMBOL(scoped_allocator_adaptor, std::, ) +SYMBOL(search, std::, ) +SYMBOL(search_n, std::, ) +SYMBOL(seed_seq, std::, ) +SYMBOL(set, std::, ) +SYMBOL(set_difference, std::, ) +SYMBOL(set_intersection, std::, ) +SYMBOL(set_new_handler, std::, ) +SYMBOL(set_symmetric_difference, std::, ) +SYMBOL(set_terminate, std::, ) +SYMBOL(set_union, std::, ) +SYMBOL(setbase, std::, ) +SYMBOL(setbuf, std::, ) +SYMBOL(setfill, std::, ) +SYMBOL(setiosflags, std::, ) +SYMBOL(setlocale, std::, ) +SYMBOL(setprecision, std::, ) +SYMBOL(setvbuf, std::, ) +SYMBOL(setw, std::, ) +SYMBOL(shared_future, std::, ) +SYMBOL(shared_lock, std::, ) +SYMBOL(shared_mutex, std::, ) +SYMBOL(shared_ptr, std::, ) +SYMBOL(shared_timed_mutex, std::, ) +SYMBOL(shift_left, std::, ) +SYMBOL(shift_right, std::, ) +SYMBOL(showbase, std::, ) +SYMBOL(showpoint, std::, ) +SYMBOL(showpos, std::, ) +SYMBOL(shuffle, std::, ) +SYMBOL(shuffle_order_engine, std::, ) +SYMBOL(sig_atomic_t, std::, ) +SYMBOL(signal, std::, ) +SYMBOL(signbit, std::, ) +SYMBOL(size, std::, ) +SYMBOL(skipws, std::, ) +SYMBOL(slice, std::, ) +SYMBOL(slice_array, std::, ) +SYMBOL(smatch, std::, ) +SYMBOL(snprintf, std::, ) +SYMBOL(sort, std::, ) +SYMBOL(sort_heap, std::, ) +SYMBOL(span, std::, ) +SYMBOL(sprintf, std::, ) +SYMBOL(srand, std::, ) +SYMBOL(sregex_iterator, std::, ) +SYMBOL(sregex_token_iterator, std::, ) +SYMBOL(sscanf, std::, ) +SYMBOL(ssub_match, std::, ) +SYMBOL(stable_partition, std::, ) +SYMBOL(stable_sort, std::, ) +SYMBOL(stack, std::, ) +SYMBOL(static_pointer_cast, std::, ) +SYMBOL(strcat, std::, ) +SYMBOL(strchr, std::, ) +SYMBOL(strcmp, std::, ) +SYMBOL(strcoll, std::, ) +SYMBOL(strcpy, std::, ) +SYMBOL(strcspn, std::, ) +SYMBOL(streambuf, std::, ) +SYMBOL(streamoff, std::, ) +SYMBOL(streampos, std::, ) +SYMBOL(streamsize, std::, ) +SYMBOL(strerror, std::, ) +SYMBOL(strftime, std::, ) +SYMBOL(string, std::, ) +SYMBOL(string_view, std::, ) +SYMBOL(stringbuf, std::, ) +SYMBOL(stringstream, std::, ) +SYMBOL(strlen, std::, ) +SYMBOL(strncat, std::, ) +SYMBOL(strncmp, std::, ) +SYMBOL(strncpy, std::, ) +SYMBOL(strong_equal, std::, ) +SYMBOL(strong_equality, std::, ) +SYMBOL(strong_order, std::, ) +SYMBOL(strong_ordering, std::, ) +SYMBOL(strpbrk, std::, ) +SYMBOL(strrchr, std::, ) +SYMBOL(strspn, std::, ) +SYMBOL(strstr, std::, ) +SYMBOL(strtod, std::, ) +SYMBOL(strtof, std::, ) +SYMBOL(strtoimax, std::, ) +SYMBOL(strtok, std::, ) +SYMBOL(strtol, std::, ) +SYMBOL(strtold, std::, ) +SYMBOL(strtoll, std::, ) +SYMBOL(strtoul, std::, ) +SYMBOL(strtoull, std::, ) +SYMBOL(strtoumax, std::, ) +SYMBOL(strxfrm, std::, ) +SYMBOL(student_t_distribution, std::, ) +SYMBOL(sub_match, std::, ) +SYMBOL(subtract_with_carry_engine, std::, ) +SYMBOL(swap_ranges, std::, ) +SYMBOL(swprintf, std::, ) +SYMBOL(swscanf, std::, ) +SYMBOL(syncbuf, std::, ) +SYMBOL(system, std::, ) +SYMBOL(system_category, std::, ) +SYMBOL(system_error, std::, ) +SYMBOL(tera, std::, ) +SYMBOL(terminate, std::, ) +SYMBOL(terminate_handler, std::, ) +SYMBOL(tgamma, std::, ) +SYMBOL(thread, std::, ) +SYMBOL(throw_with_nested, std::, ) +SYMBOL(tie, std::, ) +SYMBOL(time, std::, ) +SYMBOL(time_base, std::, ) +SYMBOL(time_get, std::, ) +SYMBOL(time_get_byname, std::, ) +SYMBOL(time_put, std::, ) +SYMBOL(time_put_byname, std::, ) +SYMBOL(time_t, std::, ) +SYMBOL(timed_mutex, std::, ) +SYMBOL(timespec, std::, ) +SYMBOL(timespec_get, std::, ) +SYMBOL(tm, std::, ) +SYMBOL(tmpfile, std::, ) +SYMBOL(tmpnam, std::, ) +SYMBOL(to_address, std::, ) +SYMBOL(to_chars, std::, ) +SYMBOL(to_integer, std::, ) +SYMBOL(to_string, std::, ) +SYMBOL(towctrans, std::, ) +SYMBOL(towlower, std::, ) +SYMBOL(towupper, std::, ) +SYMBOL(transform, std::, ) +SYMBOL(transform_exclusive_scan, std::, ) +SYMBOL(transform_inclusive_scan, std::, ) +SYMBOL(transform_reduce, std::, ) +SYMBOL(true_type, std::, ) +SYMBOL(trunc, std::, ) +SYMBOL(try_lock, std::, ) +SYMBOL(try_to_lock, std::, ) +SYMBOL(try_to_lock_t, std::, ) +SYMBOL(tuple, std::, ) +SYMBOL(tuple_cat, std::, ) +SYMBOL(type_identity, std::, ) +SYMBOL(type_identity_t, std::, ) +SYMBOL(type_index, std::, ) +SYMBOL(type_info, std::, ) +SYMBOL(u16streampos, std::, ) +SYMBOL(u16string, std::, ) +SYMBOL(u16string_view, std::, ) +SYMBOL(u32streampos, std::, ) +SYMBOL(u32string, std::, ) +SYMBOL(u32string_view, std::, ) +SYMBOL(uncaught_exceptions, std::, ) +SYMBOL(undeclare_no_pointers, std::, ) +SYMBOL(undeclare_reachable, std::, ) +SYMBOL(underflow_error, std::, ) +SYMBOL(underlying_type, std::, ) +SYMBOL(underlying_type_t, std::, ) +SYMBOL(ungetc, std::, ) +SYMBOL(ungetwc, std::, ) +SYMBOL(uniform_int_distribution, std::, ) +SYMBOL(uniform_real_distribution, std::, ) +SYMBOL(uninitialized_copy, std::, ) +SYMBOL(uninitialized_copy_n, std::, ) +SYMBOL(uninitialized_default_construct, std::, ) +SYMBOL(uninitialized_default_construct_n, std::, ) +SYMBOL(uninitialized_fill, std::, ) +SYMBOL(uninitialized_fill_n, std::, ) +SYMBOL(uninitialized_move, std::, ) +SYMBOL(uninitialized_move_n, std::, ) +SYMBOL(uninitialized_value_construct, std::, ) +SYMBOL(uninitialized_value_construct_n, std::, ) +SYMBOL(unique, std::, ) +SYMBOL(unique_copy, std::, ) +SYMBOL(unique_lock, std::, ) +SYMBOL(unique_ptr, std::, ) +SYMBOL(unitbuf, std::, ) +SYMBOL(unordered_map, std::, ) +SYMBOL(unordered_multimap, std::, ) +SYMBOL(unordered_multiset, std::, ) +SYMBOL(unordered_set, std::, ) +SYMBOL(upper_bound, std::, ) +SYMBOL(uppercase, std::, ) +SYMBOL(use_facet, std::, ) +SYMBOL(uses_allocator_v, std::, ) +SYMBOL(va_list, std::, ) +SYMBOL(valarray, std::, ) +SYMBOL(variant, std::, ) +SYMBOL(variant_alternative, std::, ) +SYMBOL(variant_alternative_t, std::, ) +SYMBOL(variant_npos, std::, ) +SYMBOL(variant_size, std::, ) +SYMBOL(variant_size_v, std::, ) +SYMBOL(vector, std::, ) +SYMBOL(vfprintf, std::, ) +SYMBOL(vfscanf, std::, ) +SYMBOL(vfwprintf, std::, ) +SYMBOL(vfwscanf, std::, ) +SYMBOL(visit, std::, ) +SYMBOL(void_t, std::, ) +SYMBOL(vprintf, std::, ) +SYMBOL(vscanf, std::, ) +SYMBOL(vsnprintf, std::, ) +SYMBOL(vsprintf, std::, ) +SYMBOL(vsscanf, std::, ) +SYMBOL(vswprintf, std::, ) +SYMBOL(vswscanf, std::, ) +SYMBOL(vwprintf, std::, ) +SYMBOL(vwscanf, std::, ) +SYMBOL(wbuffer_convert, std::, ) +SYMBOL(wcerr, std::, ) +SYMBOL(wcin, std::, ) +SYMBOL(wclog, std::, ) +SYMBOL(wcmatch, std::, ) +SYMBOL(wcout, std::, ) +SYMBOL(wcregex_iterator, std::, ) +SYMBOL(wcregex_token_iterator, std::, ) +SYMBOL(wcrtomb, std::, ) +SYMBOL(wcscat, std::, ) +SYMBOL(wcschr, std::, ) +SYMBOL(wcscmp, std::, ) +SYMBOL(wcscoll, std::, ) +SYMBOL(wcscpy, std::, ) +SYMBOL(wcscspn, std::, ) +SYMBOL(wcsftime, std::, ) +SYMBOL(wcslen, std::, ) +SYMBOL(wcsncat, std::, ) +SYMBOL(wcsncmp, std::, ) +SYMBOL(wcsncpy, std::, ) +SYMBOL(wcspbrk, std::, ) +SYMBOL(wcsrchr, std::, ) +SYMBOL(wcsrtombs, std::, ) +SYMBOL(wcsspn, std::, ) +SYMBOL(wcsstr, std::, ) +SYMBOL(wcstod, std::, ) +SYMBOL(wcstof, std::, ) +SYMBOL(wcstoimax, std::, ) +SYMBOL(wcstok, std::, ) +SYMBOL(wcstol, std::, ) +SYMBOL(wcstold, std::, ) +SYMBOL(wcstoll, std::, ) +SYMBOL(wcstombs, std::, ) +SYMBOL(wcstoul, std::, ) +SYMBOL(wcstoull, std::, ) +SYMBOL(wcstoumax, std::, ) +SYMBOL(wcsub_match, std::, ) +SYMBOL(wcsxfrm, std::, ) +SYMBOL(wctob, std::, ) +SYMBOL(wctomb, std::, ) +SYMBOL(wctrans, std::, ) +SYMBOL(wctype, std::, ) +SYMBOL(weak_equal, std::, ) +SYMBOL(weak_equality, std::, ) +SYMBOL(weak_order, std::, ) +SYMBOL(weak_ordering, std::, ) +SYMBOL(weak_ptr, std::, ) +SYMBOL(weibull_distribution, std::, ) +SYMBOL(wfstream, std::, ) +SYMBOL(wifstream, std::, ) +SYMBOL(wios, std::, ) +SYMBOL(wiostream, std::, ) +SYMBOL(wistringstream, std::, ) +SYMBOL(wmemchr, std::, ) +SYMBOL(wmemcmp, std::, ) +SYMBOL(wmemcpy, std::, ) +SYMBOL(wmemmove, std::, ) +SYMBOL(wmemset, std::, ) +SYMBOL(wofstream, std::, ) +SYMBOL(wostringstream, std::, ) +SYMBOL(wosyncstream, std::, ) +SYMBOL(wprintf, std::, ) +SYMBOL(wregex, std::, ) +SYMBOL(ws, std::, ) +SYMBOL(wscanf, std::, ) +SYMBOL(wsmatch, std::, ) +SYMBOL(wsregex_iterator, std::, ) +SYMBOL(wsregex_token_iterator, std::, ) +SYMBOL(wssub_match, std::, ) +SYMBOL(wstreambuf, std::, ) +SYMBOL(wstreampos, std::, ) +SYMBOL(wstring, std::, ) +SYMBOL(wstring_convert, std::, ) +SYMBOL(wstring_view, std::, ) +SYMBOL(wstringbuf, std::, ) +SYMBOL(wstringstream, std::, ) +SYMBOL(wsyncbuf, std::, ) +SYMBOL(yocto, std::, ) +SYMBOL(yotta, std::, ) +SYMBOL(zepto, std::, ) +SYMBOL(zetta, std::, ) diff --git a/clangd/include-mapping/gen_std.py b/clangd/include-mapping/gen_std.py new file mode 100755 index 00000000..251fe643 --- /dev/null +++ b/clangd/include-mapping/gen_std.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python +#===- gen_std.py - ------------------------------------------*- python -*--===# +# +# 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 +# +#===------------------------------------------------------------------------===# + +"""gen_std.py is a tool to generate a lookup table (from qualified names to +include headers) for C++ Standard Library symbols by parsing archieved HTML +files from cppreference. + +Caveats and FIXMEs: + - only symbols directly in "std" namespace are added, we should also add std's + subnamespace symbols (e.g. chrono). + - symbols with multiple variants or defined in multiple headers aren't added, + e.g. std::move, std::swap + +Usage: + 1. Install BeautifulSoup dependency, see instruction: + https://www.crummy.com/software/BeautifulSoup/bs4/doc/#installing-beautiful-soup + 2. Download cppreference offline HTML files (e.g. html_book_20181028.zip) at + https://en.cppreference.com/w/Cppreference:Archives + 3. Unzip the zip file from step 2 to directory , you should + get a "reference" directory in + 4. Run the command: + gen_std.py -cppreference > StdSymbolMap.inc +""" + +from bs4 import BeautifulSoup + +import argparse +import datetime +import os +import sys + +STDGEN_CODE_PREFIX = """\ +//===-- gen_std.py generated file -------------------------------*- C++ -*-===// +// +// Used to build a lookup table (qualified names => include headers) for C++ +// Standard Library symbols. +// +// Automatically generated file, DO NOT EDIT! +// +// Generated from cppreference offline HTML book (modified on %s). +//===----------------------------------------------------------------------===// +""" + +def ParseSymbolPage(symbol_page_html): + """Parse symbol page and retrieve the include header defined in this page. + The symbol page provides header for the symbol, specifically in + "Defined in header
" section. An example: + + +
Defined in header <ratio>
+ + + Returns a list of headers. + """ + headers = [] + + soup = BeautifulSoup(symbol_page_html, "html.parser") + # "Defined in header " are defined in or + # . + for header_tr in soup.select('tr.t-dcl-header,tr.t-dsc-header'): + if "Defined in header " in header_tr.text: + # The interesting header content (e.g. ) is wrapped in . + for header_code in header_tr.find_all("code"): + headers.append(header_code.text) + return headers + + +def ParseIndexPage(index_page_html): + """Parse index page. + The index page lists all std symbols and hrefs to their detailed pages + (which contain the defined header). An example: + + abs() (int)
+ acos()
+ + Returns a list of tuple (symbol_name, relative_path_to_symbol_page). + """ + symbols = [] + soup = BeautifulSoup(index_page_html, "html.parser") + for symbol_href in soup.select("a[title]"): + symbol_tt = symbol_href.find("tt") + if symbol_tt: + symbols.append((symbol_tt.text.rstrip("<>()"), # strip any trailing <>() + symbol_href["href"])) + return symbols + + +def ParseArg(): + parser = argparse.ArgumentParser(description='Generate StdGen file') + parser.add_argument('-cppreference', metavar='PATH', + default='', + help='path to the cppreference offline HTML directory', + required=True + ) + return parser.parse_args() + + +def main(): + args = ParseArg() + cpp_reference_root = args.cppreference + cpp_symbol_root = os.path.join(cpp_reference_root, "en", "cpp") + index_page_path = os.path.join(cpp_symbol_root, "symbol_index.html") + if not os.path.exists(index_page_path): + exit("Path %s doesn't exist!" % index_page_path) + + # We don't have version information from the unzipped offline HTML files. + # so we use the modified time of the symbol_index.html as the version. + cppreference_modified_date = datetime.datetime.fromtimestamp( + os.stat(index_page_path).st_mtime).strftime('%Y-%m-%d') + + # Workflow steps: + # 1. Parse index page which lists all symbols to get symbol + # name (unqualified name) and its href link to the symbol page which + # contains the defined header. + # 2. Parse the symbol page to get the defined header. + + # A map from symbol name to a set of headers. + symbols = {} + with open(index_page_path, "r") as f: + for symbol_name, symbol_page_path in ParseIndexPage(f.read()): + with open(os.path.join(cpp_symbol_root, symbol_page_path), "r") as f: + headers = ParseSymbolPage(f.read()) + if not headers: + sys.stderr.write("No header found for symbol %s at %s\n" % (symbol_name, + symbol_page_path)) + continue + + if symbol_name not in symbols: + symbols[symbol_name] = set() + symbols[symbol_name].update(headers) + + # Emit results to stdout. + print STDGEN_CODE_PREFIX % cppreference_modified_date + for name, headers in sorted(symbols.items(), key=lambda t : t[0]): + if len(headers) > 1: + # FIXME: support symbols with multiple headers (e.g. std::move). + continue + # SYMBOL(unqualified_name, namespace, header) + print "SYMBOL(%s, %s, %s)" % (name, "std::", list(headers)[0]) + + +if __name__ == '__main__': + main() diff --git a/clangd/include-mapping/test.py b/clangd/include-mapping/test.py new file mode 100755 index 00000000..89fa3591 --- /dev/null +++ b/clangd/include-mapping/test.py @@ -0,0 +1,101 @@ +#!/usr/bin/env python +#===- test.py - ---------------------------------------------*- python -*--===# +# +# 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 +# +#===------------------------------------------------------------------------===# + +from gen_std import ParseSymbolPage, ParseIndexPage + +import unittest + +class TestStdGen(unittest.TestCase): + + def testParseIndexPage(self): + html = """ + abs() (int)
+ abs<>() (std::complex)
+ acos()
+ acosh() (since C++11)
+ as_bytes<>() (since C++20)
+ """ + + actual = ParseIndexPage(html) + expected = [ + ("abs", "abs.html"), + ("abs", "complex/abs.html"), + ("acos", "acos.html"), + ("acosh", "acosh.html"), + ("as_bytes", "as_bytes.html"), + ] + self.assertEqual(len(actual), len(expected)) + for i in range(0, len(actual)): + self.assertEqual(expected[i][0], actual[i][0]) + self.assertTrue(actual[i][1].endswith(expected[i][1])) + + + def testParseSymbolPage_SingleHeader(self): + # Defined in header + html = """ + + + + + + +
Defined in header <cmath> +
+""" + self.assertEqual(ParseSymbolPage(html), ['']) + + + def testParseSymbolPage_MulHeaders(self): + # Defined in header + # Defined in header + # Defined in header + html = """ + + + + + + + + + + + + + + + + +
Defined in header <cstddef> +
Defined in header <cstdio> +
Defined in header <cstdlib> +
+""" + self.assertEqual(ParseSymbolPage(html), + ['', '', '']) + + + def testParseSymbolPage_MulHeadersInSameDiv(self): + # Multile blocks in a Div. + # Defined in header + # Defined in header + html = """ + +
+ Defined in header <algorithm>
+ Defined in header <utility> +
+ + +""" + self.assertEqual(ParseSymbolPage(html), ['', '']) + + +if __name__ == '__main__': + unittest.main() diff --git a/clangd/index/CanonicalIncludes.cpp b/clangd/index/CanonicalIncludes.cpp index 6fa366d4..1ec515e5 100644 --- a/clangd/index/CanonicalIncludes.cpp +++ b/clangd/index/CanonicalIncludes.cpp @@ -107,57 +107,30 @@ collectIWYUHeaderMaps(CanonicalIncludes *Includes) { void addSystemHeadersMapping(CanonicalIncludes *Includes) { static const std::vector> SymbolMap = { - {"std::addressof", ""}, // Map symbols in to their preferred includes. {"std::basic_filebuf", ""}, - {"std::basic_fstream", ""}, - {"std::basic_ifstream", ""}, - {"std::basic_ofstream", ""}, {"std::filebuf", ""}, - {"std::fstream", ""}, - {"std::ifstream", ""}, - {"std::ofstream", ""}, {"std::wfilebuf", ""}, - {"std::wfstream", ""}, - {"std::wifstream", ""}, - {"std::wofstream", ""}, - {"std::basic_ios", ""}, - {"std::ios", ""}, - {"std::wios", ""}, - {"std::basic_iostream", ""}, - {"std::iostream", ""}, - {"std::wiostream", ""}, {"std::basic_istream", ""}, {"std::istream", ""}, {"std::wistream", ""}, - {"std::istreambuf_iterator", ""}, - {"std::ostreambuf_iterator", ""}, {"std::basic_ostream", ""}, {"std::ostream", ""}, {"std::wostream", ""}, - {"std::basic_istringstream", ""}, - {"std::basic_ostringstream", ""}, - {"std::basic_stringbuf", ""}, - {"std::basic_stringstream", ""}, - {"std::istringstream", ""}, - {"std::ostringstream", ""}, - {"std::string", ""}, - {"std::stringbuf", ""}, - {"std::stringstream", ""}, - {"std::wistringstream", ""}, - {"std::wostringstream", ""}, - {"std::wstringbuf", ""}, - {"std::wstringstream", ""}, - {"std::basic_streambuf", ""}, - {"std::streambuf", ""}, - {"std::wstreambuf", ""}, {"std::uint_least16_t", ""}, // redeclares these {"std::uint_least32_t", ""}, - {"std::declval", ""}, +#define SYMBOL(Name, NameSpace, Header) { #NameSpace#Name, #Header }, + #include "StdSymbolMap.inc" +#undef SYMBOL }; for (const auto &Pair : SymbolMap) Includes->addSymbolMapping(Pair.first, Pair.second); + // FIXME: remove the std header mapping once we support ambiguous symbols, now + // it serves as a fallback to disambiguate: + // - symbols with mulitiple headers (e.g. std::move) + // - symbols with a primary template in one header and a specialization in + // another (std::abs) static const std::vector> SystemHeaderMap = { {"include/__stddef_max_align_t.h", ""}, -- cgit v1.2.3 From 0090bda750f181e1387eb2b0ac985a51882ee364 Mon Sep 17 00:00:00 2001 From: Hyrum Wright Date: Thu, 14 Mar 2019 13:38:16 +0000 Subject: [clang-tidy] Add additional patterns to the abseil-duration-unnecessary-conversion check. Differential Revision: https://reviews.llvm.org/D59183 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356141 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../abseil/DurationUnnecessaryConversionCheck.cpp | 36 ++++++++++-- .../abseil-duration-unnecessary-conversion.rst | 17 +++++- test/clang-tidy/Inputs/absl/time/time.h | 3 + .../abseil-duration-unnecessary-conversion.cpp | 66 ++++++++++++++++++---- 4 files changed, 103 insertions(+), 19 deletions(-) diff --git a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp index ae761997..2ba90eec 100644 --- a/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp +++ b/clang-tidy/abseil/DurationUnnecessaryConversionCheck.cpp @@ -28,12 +28,35 @@ void DurationUnnecessaryConversionCheck::registerMatchers(MatchFinder *Finder) { std::string IntegerConversion = (llvm::Twine("::absl::ToInt64") + Scale).str(); + // Matcher which matches the current scale's factory with a `1` argument, + // e.g. `absl::Seconds(1)`. + auto factory_matcher = cxxConstructExpr(hasArgument( + 0, + callExpr(callee(functionDecl(hasName(DurationFactory))), + hasArgument(0, ignoringImpCasts(integerLiteral(equals(1))))))); + + // Matcher which matches either inverse function and binds its argument, + // e.g. `absl::ToDoubleSeconds(dur)`. + auto inverse_function_matcher = callExpr( + callee(functionDecl(hasAnyName(FloatConversion, IntegerConversion))), + hasArgument(0, expr().bind("arg"))); + + // Matcher which matches a duration divided by the factory_matcher above, + // e.g. `dur / absl::Seconds(1)`. + auto division_operator_matcher = cxxOperatorCallExpr( + hasOverloadedOperatorName("/"), hasArgument(0, expr().bind("arg")), + hasArgument(1, factory_matcher)); + + // Matcher which matches a duration argument to `FDivDuration`, + // e.g. `absl::FDivDuration(dur, absl::Seconds(1))` + auto fdiv_matcher = callExpr( + callee(functionDecl(hasName("::absl::FDivDuration"))), + hasArgument(0, expr().bind("arg")), hasArgument(1, factory_matcher)); + Finder->addMatcher( - callExpr( - callee(functionDecl(hasName(DurationFactory))), - hasArgument(0, callExpr(callee(functionDecl(hasAnyName( - FloatConversion, IntegerConversion))), - hasArgument(0, expr().bind("arg"))))) + callExpr(callee(functionDecl(hasName(DurationFactory))), + hasArgument(0, anyOf(inverse_function_matcher, + division_operator_matcher, fdiv_matcher))) .bind("call"), this); } @@ -47,7 +70,8 @@ void DurationUnnecessaryConversionCheck::check( if (isInMacro(Result, OuterCall)) return; - diag(OuterCall->getBeginLoc(), "remove unnecessary absl::Duration conversions") + diag(OuterCall->getBeginLoc(), + "remove unnecessary absl::Duration conversions") << FixItHint::CreateReplacement( OuterCall->getSourceRange(), tooling::fixit::getText(*Arg, *Result.Context)); diff --git a/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst index 938c46d5..2f978f4d 100644 --- a/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst +++ b/docs/clang-tidy/checks/abseil-duration-unnecessary-conversion.rst @@ -6,7 +6,7 @@ abseil-duration-unnecessary-conversion Finds and fixes cases where ``absl::Duration`` values are being converted to numeric types and back again. -Examples: +Floating-point examples: .. code-block:: c++ @@ -17,6 +17,15 @@ Examples: // Suggestion - Remove unnecessary conversions absl::Duration d2 = d1; + // Original - Division to convert to double and back again + absl::Duration d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1))); + + // Suggestion - Remove division and conversion + absl::Duration d2 = d1; + +Integer examples: + +.. code-block:: c++ // Original - Conversion to integer and back again absl::Duration d1; @@ -25,6 +34,12 @@ Examples: // Suggestion - Remove unnecessary conversions absl::Duration d2 = d1; + // Original - Integer division followed by conversion + absl::Duration d2 = absl::Seconds(d1 / absl::Seconds(1)); + + // Suggestion - Remove division and conversion + absl::Duration d2 = d1; + Note: Converting to an integer and back to an ``absl::Duration`` might be a truncating operation if the value is not aligned to the scale of conversion. In the rare case where this is the intended result, callers should use diff --git a/test/clang-tidy/Inputs/absl/time/time.h b/test/clang-tidy/Inputs/absl/time/time.h index 9c6c3aee..5454f978 100644 --- a/test/clang-tidy/Inputs/absl/time/time.h +++ b/test/clang-tidy/Inputs/absl/time/time.h @@ -21,6 +21,7 @@ public: template Duration operator*(Duration lhs, T rhs); template Duration operator*(T lhs, Duration rhs); template Duration operator/(Duration lhs, T rhs); +int64_t operator/(Duration lhs, Duration rhs); class Time{}; @@ -86,4 +87,6 @@ inline Time operator+(Duration lhs, Time rhs); inline Time operator-(Time lhs, Duration rhs); inline Duration operator-(Time lhs, Time rhs); +double FDivDuration(Duration num, Duration den); + } // namespace absl diff --git a/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp index 9414182c..d32837f8 100644 --- a/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp +++ b/test/clang-tidy/abseil-duration-unnecessary-conversion.cpp @@ -8,42 +8,80 @@ void f() { // Floating point d2 = absl::Hours(absl::ToDoubleHours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Minutes(absl::ToDoubleMinutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Seconds(absl::ToDoubleSeconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Milliseconds(absl::ToDoubleMilliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Microseconds(absl::ToDoubleMicroseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Nanoseconds(absl::ToDoubleNanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 // Integer point d2 = absl::Hours(absl::ToInt64Hours(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Minutes(absl::ToInt64Minutes(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Seconds(absl::ToInt64Seconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Milliseconds(absl::ToInt64Milliseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Microseconds(absl::ToInt64Microseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 d2 = absl::Nanoseconds(absl::ToInt64Nanoseconds(d1)); // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] - // CHECK-FIXES: d1 + // CHECK-FIXES: d2 = d1 + + d2 = absl::Hours(d1 / absl::Hours(1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Minutes(d1 / absl::Minutes(1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Seconds(d1 / absl::Seconds(1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Milliseconds(d1 / absl::Milliseconds(1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Microseconds(d1 / absl::Microseconds(1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Nanoseconds(d1 / absl::Nanoseconds(1)); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + + d2 = absl::Hours(absl::FDivDuration(d1, absl::Hours(1))); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Minutes(absl::FDivDuration(d1, absl::Minutes(1))); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Seconds(absl::FDivDuration(d1, absl::Seconds(1))); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(1))); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Microseconds(absl::FDivDuration(d1, absl::Microseconds(1))); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 + d2 = absl::Nanoseconds(absl::FDivDuration(d1, absl::Nanoseconds(1))); + // CHECK-MESSAGES: [[@LINE-1]]:8: warning: remove unnecessary absl::Duration conversions [abseil-duration-unnecessary-conversion] + // CHECK-FIXES: d2 = d1 // As macro argument #define PLUS_FIVE_S(x) x + absl::Seconds(5) @@ -66,4 +104,8 @@ void f() { d2 = absl::Seconds(absl::ToDoubleMilliseconds(d1)); d2 = absl::Seconds(4); int i = absl::ToInt64Milliseconds(d1); + d2 = absl::Hours(d1 / absl::Minutes(1)); + d2 = absl::Seconds(d1 / absl::Seconds(30)); + d2 = absl::Hours(absl::FDivDuration(d1, absl::Minutes(1))); + d2 = absl::Milliseconds(absl::FDivDuration(d1, absl::Milliseconds(20))); } -- cgit v1.2.3 From 0b54c48100cf916ec8e1b0846647bf2a7a0c3618 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 14 Mar 2019 18:12:17 +0000 Subject: Add PragmaHandler for MSVC pragma execution_character_set __pragma(execution_character_set(push, "UTF-8")) is used in TraceLoggingProvider.h. This commit implements a no-op handler for compatability, similar to how the flag -fexec_charset is handled. Patch by Matt Gardner! Differential Revision: https://reviews.llvm.org/D58530 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356185 91177308-0d34-0410-b5e6-96231b3b80d8 --- pp-trace/PPCallbacksTracker.cpp | 16 ++++++++++++++++ pp-trace/PPCallbacksTracker.h | 3 +++ 2 files changed, 19 insertions(+) diff --git a/pp-trace/PPCallbacksTracker.cpp b/pp-trace/PPCallbacksTracker.cpp index 4ed40b38..e2d8738e 100644 --- a/pp-trace/PPCallbacksTracker.cpp +++ b/pp-trace/PPCallbacksTracker.cpp @@ -297,6 +297,22 @@ void PPCallbacksTracker::PragmaWarningPop(clang::SourceLocation Loc) { appendArgument("Loc", Loc); } +// Callback invoked when a #pragma execution_character_set(push) directive +// is read. +void PPCallbacksTracker::PragmaExecCharsetPush(clang::SourceLocation Loc, + clang::StringRef Str) { + beginCallback("PragmaExecCharsetPush"); + appendArgument("Loc", Loc); + appendArgument("Charset", Str); +} + +// Callback invoked when a #pragma execution_character_set(pop) directive +// is read. +void PPCallbacksTracker::PragmaExecCharsetPop(clang::SourceLocation Loc) { + beginCallback("PragmaExecCharsetPop"); + appendArgument("Loc", Loc); +} + // Called by Preprocessor::HandleMacroExpandedIdentifier when a // macro invocation is found. void diff --git a/pp-trace/PPCallbacksTracker.h b/pp-trace/PPCallbacksTracker.h index ec52feec..afb8d37a 100644 --- a/pp-trace/PPCallbacksTracker.h +++ b/pp-trace/PPCallbacksTracker.h @@ -134,6 +134,9 @@ public: llvm::ArrayRef Ids) override; void PragmaWarningPush(clang::SourceLocation Loc, int Level) override; void PragmaWarningPop(clang::SourceLocation Loc) override; + void PragmaExecCharsetPush(clang::SourceLocation Loc, + clang::StringRef Str) override; + void PragmaExecCharsetPop(clang::SourceLocation Loc) override; void MacroExpands(const clang::Token &MacroNameTok, const clang::MacroDefinition &MD, clang::SourceRange Range, const clang::MacroArgs *Args) override; -- cgit v1.2.3 From df8f02951643946298b2626218f071551451f773 Mon Sep 17 00:00:00 2001 From: Yan Zhang Date: Fri, 15 Mar 2019 00:17:41 +0000 Subject: Fixed global constant/variable naming check on C++ class for ObjC++ files. Subscribers: cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59283 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356220 91177308-0d34-0410-b5e6-96231b3b80d8 --- clang-tidy/google/GlobalVariableDeclarationCheck.cpp | 4 ++++ test/clang-tidy/google-objc-global-variable-declaration.mm | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100644 test/clang-tidy/google-objc-global-variable-declaration.mm diff --git a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp index b2ad2764..ce833906 100644 --- a/clang-tidy/google/GlobalVariableDeclarationCheck.cpp +++ b/clang-tidy/google/GlobalVariableDeclarationCheck.cpp @@ -79,12 +79,16 @@ void GlobalVariableDeclarationCheck::registerMatchers(MatchFinder *Finder) { void GlobalVariableDeclarationCheck::check( const MatchFinder::MatchResult &Result) { if (const auto *Decl = Result.Nodes.getNodeAs("global_var")) { + if (Decl->isStaticDataMember()) + return; diag(Decl->getLocation(), "non-const global variable '%0' must have a name which starts with " "'g[A-Z]'") << Decl->getName() << generateFixItHint(Decl, false); } if (const auto *Decl = Result.Nodes.getNodeAs("global_const")) { + if (Decl->isStaticDataMember()) + return; diag(Decl->getLocation(), "const global variable '%0' must have a name which starts with " "an appropriate prefix") diff --git a/test/clang-tidy/google-objc-global-variable-declaration.mm b/test/clang-tidy/google-objc-global-variable-declaration.mm new file mode 100644 index 00000000..a6b0f6ee --- /dev/null +++ b/test/clang-tidy/google-objc-global-variable-declaration.mm @@ -0,0 +1,10 @@ +// RUN: %check_clang_tidy %s google-objc-global-variable-declaration %t + +@class NSString; +static NSString* const myConstString = @"hello"; +// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'myConstString' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration] +// CHECK-FIXES: static NSString* const kMyConstString = @"hello"; + +class MyTest { + static int not_objc_style; +}; -- cgit v1.2.3 From 48d73809af23060d483d5b1a3b2aec424606a504 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 15 Mar 2019 11:54:01 +0000 Subject: Rename directory housing clang-change-namespace to be eponymous Makes the name of this directory consistent with the names of the other directories in clang-tools-extra. Differential Revision: https://reviews.llvm.org/D59382 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356254 91177308-0d34-0410-b5e6-96231b3b80d8 --- CMakeLists.txt | 2 +- change-namespace/CMakeLists.txt | 20 - change-namespace/ChangeNamespace.cpp | 1042 --------- change-namespace/ChangeNamespace.h | 175 -- change-namespace/tool/CMakeLists.txt | 25 - change-namespace/tool/ClangChangeNamespace.cpp | 177 -- clang-change-namespace/CMakeLists.txt | 20 + clang-change-namespace/ChangeNamespace.cpp | 1042 +++++++++ clang-change-namespace/ChangeNamespace.h | 175 ++ clang-change-namespace/tool/CMakeLists.txt | 25 + .../tool/ClangChangeNamespace.cpp | 177 ++ test/change-namespace/Inputs/fake-std.h | 5 - test/change-namespace/lambda-function.cpp | 37 - test/change-namespace/macro.cpp | 29 - test/change-namespace/simple-move.cpp | 10 - test/change-namespace/white-list.cpp | 19 - test/clang-change-namespace/Inputs/fake-std.h | 5 + test/clang-change-namespace/lambda-function.cpp | 37 + test/clang-change-namespace/macro.cpp | 29 + test/clang-change-namespace/simple-move.cpp | 10 + test/clang-change-namespace/white-list.cpp | 19 + unittests/CMakeLists.txt | 2 +- unittests/change-namespace/CMakeLists.txt | 30 - .../change-namespace/ChangeNamespaceTests.cpp | 2281 -------------------- unittests/clang-change-namespace/CMakeLists.txt | 30 + .../ChangeNamespaceTests.cpp | 2281 ++++++++++++++++++++ 26 files changed, 3852 insertions(+), 3852 deletions(-) delete mode 100644 change-namespace/CMakeLists.txt delete mode 100644 change-namespace/ChangeNamespace.cpp delete mode 100644 change-namespace/ChangeNamespace.h delete mode 100644 change-namespace/tool/CMakeLists.txt delete mode 100644 change-namespace/tool/ClangChangeNamespace.cpp create mode 100644 clang-change-namespace/CMakeLists.txt create mode 100644 clang-change-namespace/ChangeNamespace.cpp create mode 100644 clang-change-namespace/ChangeNamespace.h create mode 100644 clang-change-namespace/tool/CMakeLists.txt create mode 100644 clang-change-namespace/tool/ClangChangeNamespace.cpp delete mode 100644 test/change-namespace/Inputs/fake-std.h delete mode 100644 test/change-namespace/lambda-function.cpp delete mode 100644 test/change-namespace/macro.cpp delete mode 100644 test/change-namespace/simple-move.cpp delete mode 100644 test/change-namespace/white-list.cpp create mode 100644 test/clang-change-namespace/Inputs/fake-std.h create mode 100644 test/clang-change-namespace/lambda-function.cpp create mode 100644 test/clang-change-namespace/macro.cpp create mode 100644 test/clang-change-namespace/simple-move.cpp create mode 100644 test/clang-change-namespace/white-list.cpp delete mode 100644 unittests/change-namespace/CMakeLists.txt delete mode 100644 unittests/change-namespace/ChangeNamespaceTests.cpp create mode 100644 unittests/clang-change-namespace/CMakeLists.txt create mode 100644 unittests/clang-change-namespace/ChangeNamespaceTests.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 37e3e87e..bb453330 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,7 @@ add_subdirectory(modularize) add_subdirectory(clang-tidy) add_subdirectory(clang-tidy-vs) -add_subdirectory(change-namespace) +add_subdirectory(clang-change-namespace) add_subdirectory(clang-doc) add_subdirectory(clang-query) add_subdirectory(clang-move) diff --git a/change-namespace/CMakeLists.txt b/change-namespace/CMakeLists.txt deleted file mode 100644 index 17830642..00000000 --- a/change-namespace/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(LLVM_LINK_COMPONENTS - support - ) - -add_clang_library(clangChangeNamespace - ChangeNamespace.cpp - - LINK_LIBS - clangAST - clangASTMatchers - clangBasic - clangFormat - clangFrontend - clangLex - clangSerialization - clangTooling - clangToolingCore - ) - -add_subdirectory(tool) diff --git a/change-namespace/ChangeNamespace.cpp b/change-namespace/ChangeNamespace.cpp deleted file mode 100644 index eb732639..00000000 --- a/change-namespace/ChangeNamespace.cpp +++ /dev/null @@ -1,1042 +0,0 @@ -//===-- ChangeNamespace.cpp - Change namespace implementation -------------===// -// -// 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 "ChangeNamespace.h" -#include "clang/AST/ASTContext.h" -#include "clang/Format/Format.h" -#include "clang/Lex/Lexer.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/ErrorHandling.h" - -using namespace clang::ast_matchers; - -namespace clang { -namespace change_namespace { - -namespace { - -inline std::string -joinNamespaces(const llvm::SmallVectorImpl &Namespaces) { - if (Namespaces.empty()) - return ""; - std::string Result = Namespaces.front(); - for (auto I = Namespaces.begin() + 1, E = Namespaces.end(); I != E; ++I) - Result += ("::" + *I).str(); - return Result; -} - -// Given "a::b::c", returns {"a", "b", "c"}. -llvm::SmallVector splitSymbolName(llvm::StringRef Name) { - llvm::SmallVector Splitted; - Name.split(Splitted, "::", /*MaxSplit=*/-1, - /*KeepEmpty=*/false); - return Splitted; -} - -SourceLocation startLocationForType(TypeLoc TLoc) { - // For elaborated types (e.g. `struct a::A`) we want the portion after the - // `struct` but including the namespace qualifier, `a::`. - if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) { - NestedNameSpecifierLoc NestedNameSpecifier = - TLoc.castAs().getQualifierLoc(); - if (NestedNameSpecifier.getNestedNameSpecifier()) - return NestedNameSpecifier.getBeginLoc(); - TLoc = TLoc.getNextTypeLoc(); - } - return TLoc.getBeginLoc(); -} - -SourceLocation endLocationForType(TypeLoc TLoc) { - // Dig past any namespace or keyword qualifications. - while (TLoc.getTypeLocClass() == TypeLoc::Elaborated || - TLoc.getTypeLocClass() == TypeLoc::Qualified) - TLoc = TLoc.getNextTypeLoc(); - - // The location for template specializations (e.g. Foo) includes the - // templated types in its location range. We want to restrict this to just - // before the `<` character. - if (TLoc.getTypeLocClass() == TypeLoc::TemplateSpecialization) - return TLoc.castAs() - .getLAngleLoc() - .getLocWithOffset(-1); - return TLoc.getEndLoc(); -} - -// Returns the containing namespace of `InnerNs` by skipping `PartialNsName`. -// If the `InnerNs` does not have `PartialNsName` as suffix, or `PartialNsName` -// is empty, nullptr is returned. -// For example, if `InnerNs` is "a::b::c" and `PartialNsName` is "b::c", then -// the NamespaceDecl of namespace "a" will be returned. -const NamespaceDecl *getOuterNamespace(const NamespaceDecl *InnerNs, - llvm::StringRef PartialNsName) { - if (!InnerNs || PartialNsName.empty()) - return nullptr; - const auto *CurrentContext = llvm::cast(InnerNs); - const auto *CurrentNs = InnerNs; - auto PartialNsNameSplitted = splitSymbolName(PartialNsName); - while (!PartialNsNameSplitted.empty()) { - // Get the inner-most namespace in CurrentContext. - while (CurrentContext && !llvm::isa(CurrentContext)) - CurrentContext = CurrentContext->getParent(); - if (!CurrentContext) - return nullptr; - CurrentNs = llvm::cast(CurrentContext); - if (PartialNsNameSplitted.back() != CurrentNs->getNameAsString()) - return nullptr; - PartialNsNameSplitted.pop_back(); - CurrentContext = CurrentContext->getParent(); - } - return CurrentNs; -} - -static std::unique_ptr -getLexerStartingFromLoc(SourceLocation Loc, const SourceManager &SM, - const LangOptions &LangOpts) { - if (Loc.isMacroID() && - !Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc)) - return nullptr; - // Break down the source location. - std::pair LocInfo = SM.getDecomposedLoc(Loc); - // Try to load the file buffer. - bool InvalidTemp = false; - llvm::StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp); - if (InvalidTemp) - return nullptr; - - const char *TokBegin = File.data() + LocInfo.second; - // Lex from the start of the given location. - return llvm::make_unique(SM.getLocForStartOfFile(LocInfo.first), - LangOpts, File.begin(), TokBegin, File.end()); -} - -// FIXME: get rid of this helper function if this is supported in clang-refactor -// library. -static SourceLocation getStartOfNextLine(SourceLocation Loc, - const SourceManager &SM, - const LangOptions &LangOpts) { - std::unique_ptr Lex = getLexerStartingFromLoc(Loc, SM, LangOpts); - if (!Lex.get()) - return SourceLocation(); - llvm::SmallVector Line; - // FIXME: this is a bit hacky to get ReadToEndOfLine work. - Lex->setParsingPreprocessorDirective(true); - Lex->ReadToEndOfLine(&Line); - auto End = Loc.getLocWithOffset(Line.size()); - return SM.getLocForEndOfFile(SM.getDecomposedLoc(Loc).first) == End - ? End - : End.getLocWithOffset(1); -} - -// Returns `R` with new range that refers to code after `Replaces` being -// applied. -tooling::Replacement -getReplacementInChangedCode(const tooling::Replacements &Replaces, - const tooling::Replacement &R) { - unsigned NewStart = Replaces.getShiftedCodePosition(R.getOffset()); - unsigned NewEnd = - Replaces.getShiftedCodePosition(R.getOffset() + R.getLength()); - return tooling::Replacement(R.getFilePath(), NewStart, NewEnd - NewStart, - R.getReplacementText()); -} - -// Adds a replacement `R` into `Replaces` or merges it into `Replaces` by -// applying all existing Replaces first if there is conflict. -void addOrMergeReplacement(const tooling::Replacement &R, - tooling::Replacements *Replaces) { - auto Err = Replaces->add(R); - if (Err) { - llvm::consumeError(std::move(Err)); - auto Replace = getReplacementInChangedCode(*Replaces, R); - *Replaces = Replaces->merge(tooling::Replacements(Replace)); - } -} - -tooling::Replacement createReplacement(SourceLocation Start, SourceLocation End, - llvm::StringRef ReplacementText, - const SourceManager &SM) { - if (!Start.isValid() || !End.isValid()) { - llvm::errs() << "start or end location were invalid\n"; - return tooling::Replacement(); - } - if (SM.getDecomposedLoc(Start).first != SM.getDecomposedLoc(End).first) { - llvm::errs() - << "start or end location were in different macro expansions\n"; - return tooling::Replacement(); - } - Start = SM.getSpellingLoc(Start); - End = SM.getSpellingLoc(End); - if (SM.getFileID(Start) != SM.getFileID(End)) { - llvm::errs() << "start or end location were in different files\n"; - return tooling::Replacement(); - } - return tooling::Replacement( - SM, CharSourceRange::getTokenRange(SM.getSpellingLoc(Start), - SM.getSpellingLoc(End)), - ReplacementText); -} - -void addReplacementOrDie( - SourceLocation Start, SourceLocation End, llvm::StringRef ReplacementText, - const SourceManager &SM, - std::map *FileToReplacements) { - const auto R = createReplacement(Start, End, ReplacementText, SM); - auto Err = (*FileToReplacements)[R.getFilePath()].add(R); - if (Err) - llvm_unreachable(llvm::toString(std::move(Err)).c_str()); -} - -tooling::Replacement createInsertion(SourceLocation Loc, - llvm::StringRef InsertText, - const SourceManager &SM) { - if (Loc.isInvalid()) { - llvm::errs() << "insert Location is invalid.\n"; - return tooling::Replacement(); - } - Loc = SM.getSpellingLoc(Loc); - return tooling::Replacement(SM, Loc, 0, InsertText); -} - -// Returns the shortest qualified name for declaration `DeclName` in the -// namespace `NsName`. For example, if `DeclName` is "a::b::X" and `NsName` -// is "a::c::d", then "b::X" will be returned. -// Note that if `DeclName` is `::b::X` and `NsName` is `::a::b`, this returns -// "::b::X" instead of "b::X" since there will be a name conflict otherwise. -// \param DeclName A fully qualified name, "::a::b::X" or "a::b::X". -// \param NsName A fully qualified name, "::a::b" or "a::b". Global namespace -// will have empty name. -std::string getShortestQualifiedNameInNamespace(llvm::StringRef DeclName, - llvm::StringRef NsName) { - DeclName = DeclName.ltrim(':'); - NsName = NsName.ltrim(':'); - if (DeclName.find(':') == llvm::StringRef::npos) - return DeclName; - - auto NsNameSplitted = splitSymbolName(NsName); - auto DeclNsSplitted = splitSymbolName(DeclName); - llvm::StringRef UnqualifiedDeclName = DeclNsSplitted.pop_back_val(); - // If the Decl is in global namespace, there is no need to shorten it. - if (DeclNsSplitted.empty()) - return UnqualifiedDeclName; - // If NsName is the global namespace, we can simply use the DeclName sans - // leading "::". - if (NsNameSplitted.empty()) - return DeclName; - - if (NsNameSplitted.front() != DeclNsSplitted.front()) { - // The DeclName must be fully-qualified, but we still need to decide if a - // leading "::" is necessary. For example, if `NsName` is "a::b::c" and the - // `DeclName` is "b::X", then the reference must be qualified as "::b::X" - // to avoid conflict. - if (llvm::is_contained(NsNameSplitted, DeclNsSplitted.front())) - return ("::" + DeclName).str(); - return DeclName; - } - // Since there is already an overlap namespace, we know that `DeclName` can be - // shortened, so we reduce the longest common prefix. - auto DeclI = DeclNsSplitted.begin(); - auto DeclE = DeclNsSplitted.end(); - auto NsI = NsNameSplitted.begin(); - auto NsE = NsNameSplitted.end(); - for (; DeclI != DeclE && NsI != NsE && *DeclI == *NsI; ++DeclI, ++NsI) { - } - return (DeclI == DeclE) - ? UnqualifiedDeclName.str() - : (llvm::join(DeclI, DeclE, "::") + "::" + UnqualifiedDeclName) - .str(); -} - -std::string wrapCodeInNamespace(StringRef NestedNs, std::string Code) { - if (Code.back() != '\n') - Code += "\n"; - auto NsSplitted = splitSymbolName(NestedNs); - while (!NsSplitted.empty()) { - // FIXME: consider code style for comments. - Code = ("namespace " + NsSplitted.back() + " {\n" + Code + - "} // namespace " + NsSplitted.back() + "\n") - .str(); - NsSplitted.pop_back(); - } - return Code; -} - -// Returns true if \p D is a nested DeclContext in \p Context -bool isNestedDeclContext(const DeclContext *D, const DeclContext *Context) { - while (D) { - if (D == Context) - return true; - D = D->getParent(); - } - return false; -} - -// Returns true if \p D is visible at \p Loc with DeclContext \p DeclCtx. -bool isDeclVisibleAtLocation(const SourceManager &SM, const Decl *D, - const DeclContext *DeclCtx, SourceLocation Loc) { - SourceLocation DeclLoc = SM.getSpellingLoc(D->getBeginLoc()); - Loc = SM.getSpellingLoc(Loc); - return SM.isBeforeInTranslationUnit(DeclLoc, Loc) && - (SM.getFileID(DeclLoc) == SM.getFileID(Loc) && - isNestedDeclContext(DeclCtx, D->getDeclContext())); -} - -// Given a qualified symbol name, returns true if the symbol will be -// incorrectly qualified without leading "::". For example, a symbol -// "nx::ny::Foo" in namespace "na::nx::ny" without leading "::"; a symbol -// "util::X" in namespace "na" can potentially conflict with "na::util" (if this -// exists). -bool conflictInNamespace(const ASTContext &AST, llvm::StringRef QualifiedSymbol, - llvm::StringRef Namespace) { - auto SymbolSplitted = splitSymbolName(QualifiedSymbol.trim(":")); - assert(!SymbolSplitted.empty()); - SymbolSplitted.pop_back(); // We are only interested in namespaces. - - if (SymbolSplitted.size() >= 1 && !Namespace.empty()) { - auto SymbolTopNs = SymbolSplitted.front(); - auto NsSplitted = splitSymbolName(Namespace.trim(":")); - assert(!NsSplitted.empty()); - - auto LookupDecl = [&AST](const Decl &Scope, - llvm::StringRef Name) -> const NamedDecl * { - const auto *DC = llvm::dyn_cast(&Scope); - if (!DC) - return nullptr; - auto LookupRes = DC->lookup(DeclarationName(&AST.Idents.get(Name))); - if (LookupRes.empty()) - return nullptr; - return LookupRes.front(); - }; - // We do not check the outermost namespace since it would not be a - // conflict if it equals to the symbol's outermost namespace and the - // symbol name would have been shortened. - const NamedDecl *Scope = - LookupDecl(*AST.getTranslationUnitDecl(), NsSplitted.front()); - for (auto I = NsSplitted.begin() + 1, E = NsSplitted.end(); I != E; ++I) { - if (*I == SymbolTopNs) // Handles "::ny" in "::nx::ny" case. - return true; - // Handles "::util" and "::nx::util" conflicts. - if (Scope) { - if (LookupDecl(*Scope, SymbolTopNs)) - return true; - Scope = LookupDecl(*Scope, *I); - } - } - if (Scope && LookupDecl(*Scope, SymbolTopNs)) - return true; - } - return false; -} - -AST_MATCHER(EnumDecl, isScoped) { - return Node.isScoped(); -} - -bool isTemplateParameter(TypeLoc Type) { - while (!Type.isNull()) { - if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm) - return true; - Type = Type.getNextTypeLoc(); - } - return false; -} - -} // anonymous namespace - -ChangeNamespaceTool::ChangeNamespaceTool( - llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern, - llvm::ArrayRef WhiteListedSymbolPatterns, - std::map *FileToReplacements, - llvm::StringRef FallbackStyle) - : FallbackStyle(FallbackStyle), FileToReplacements(*FileToReplacements), - OldNamespace(OldNs.ltrim(':')), NewNamespace(NewNs.ltrim(':')), - FilePattern(FilePattern), FilePatternRE(FilePattern) { - FileToReplacements->clear(); - auto OldNsSplitted = splitSymbolName(OldNamespace); - auto NewNsSplitted = splitSymbolName(NewNamespace); - // Calculates `DiffOldNamespace` and `DiffNewNamespace`. - while (!OldNsSplitted.empty() && !NewNsSplitted.empty() && - OldNsSplitted.front() == NewNsSplitted.front()) { - OldNsSplitted.erase(OldNsSplitted.begin()); - NewNsSplitted.erase(NewNsSplitted.begin()); - } - DiffOldNamespace = joinNamespaces(OldNsSplitted); - DiffNewNamespace = joinNamespaces(NewNsSplitted); - - for (const auto &Pattern : WhiteListedSymbolPatterns) - WhiteListedSymbolRegexes.emplace_back(Pattern); -} - -void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) { - std::string FullOldNs = "::" + OldNamespace; - // Prefix is the outer-most namespace in DiffOldNamespace. For example, if the - // OldNamespace is "a::b::c" and DiffOldNamespace is "b::c", then Prefix will - // be "a::b". Declarations in this namespace will not be visible in the new - // namespace. If DiffOldNamespace is empty, Prefix will be a invalid name "-". - llvm::SmallVector DiffOldNsSplitted; - llvm::StringRef(DiffOldNamespace) - .split(DiffOldNsSplitted, "::", /*MaxSplit=*/-1, - /*KeepEmpty=*/false); - std::string Prefix = "-"; - if (!DiffOldNsSplitted.empty()) - Prefix = (StringRef(FullOldNs).drop_back(DiffOldNamespace.size()) + - DiffOldNsSplitted.front()) - .str(); - auto IsInMovedNs = - allOf(hasAncestor(namespaceDecl(hasName(FullOldNs)).bind("ns_decl")), - isExpansionInFileMatching(FilePattern)); - auto IsVisibleInNewNs = anyOf( - IsInMovedNs, unless(hasAncestor(namespaceDecl(hasName(Prefix))))); - // Match using declarations. - Finder->addMatcher( - usingDecl(isExpansionInFileMatching(FilePattern), IsVisibleInNewNs) - .bind("using"), - this); - // Match using namespace declarations. - Finder->addMatcher(usingDirectiveDecl(isExpansionInFileMatching(FilePattern), - IsVisibleInNewNs) - .bind("using_namespace"), - this); - // Match namespace alias declarations. - Finder->addMatcher(namespaceAliasDecl(isExpansionInFileMatching(FilePattern), - IsVisibleInNewNs) - .bind("namespace_alias"), - this); - - // Match old namespace blocks. - Finder->addMatcher( - namespaceDecl(hasName(FullOldNs), isExpansionInFileMatching(FilePattern)) - .bind("old_ns"), - this); - - // Match class forward-declarations in the old namespace. - // Note that forward-declarations in classes are not matched. - Finder->addMatcher(cxxRecordDecl(unless(anyOf(isImplicit(), isDefinition())), - IsInMovedNs, hasParent(namespaceDecl())) - .bind("class_fwd_decl"), - this); - - // Match template class forward-declarations in the old namespace. - Finder->addMatcher( - classTemplateDecl(unless(hasDescendant(cxxRecordDecl(isDefinition()))), - IsInMovedNs, hasParent(namespaceDecl())) - .bind("template_class_fwd_decl"), - this); - - // Match references to types that are not defined in the old namespace. - // Forward-declarations in the old namespace are also matched since they will - // be moved back to the old namespace. - auto DeclMatcher = namedDecl( - hasAncestor(namespaceDecl()), - unless(anyOf( - isImplicit(), hasAncestor(namespaceDecl(isAnonymous())), - hasAncestor(cxxRecordDecl()), - allOf(IsInMovedNs, unless(cxxRecordDecl(unless(isDefinition()))))))); - - // Using shadow declarations in classes always refers to base class, which - // does not need to be qualified since it can be inferred from inheritance. - // Note that this does not match using alias declarations. - auto UsingShadowDeclInClass = - usingDecl(hasAnyUsingShadowDecl(decl()), hasParent(cxxRecordDecl())); - - // Match TypeLocs on the declaration. Carefully match only the outermost - // TypeLoc and template specialization arguments (which are not outermost) - // that are directly linked to types matching `DeclMatcher`. Nested name - // specifier locs are handled separately below. - Finder->addMatcher( - typeLoc(IsInMovedNs, - loc(qualType(hasDeclaration(DeclMatcher.bind("from_decl")))), - unless(anyOf(hasParent(typeLoc(loc(qualType( - hasDeclaration(DeclMatcher), - unless(templateSpecializationType()))))), - hasParent(nestedNameSpecifierLoc()), - hasAncestor(isImplicit()), - hasAncestor(UsingShadowDeclInClass), - hasAncestor(functionDecl(isDefaulted())))), - hasAncestor(decl().bind("dc"))) - .bind("type"), - this); - - // Types in `UsingShadowDecl` is not matched by `typeLoc` above, so we need to - // special case it. - // Since using declarations inside classes must have the base class in the - // nested name specifier, we leave it to the nested name specifier matcher. - Finder->addMatcher(usingDecl(IsInMovedNs, hasAnyUsingShadowDecl(decl()), - unless(UsingShadowDeclInClass)) - .bind("using_with_shadow"), - this); - - // Handle types in nested name specifier. Specifiers that are in a TypeLoc - // matched above are not matched, e.g. "A::" in "A::A" is not matched since - // "A::A" would have already been fixed. - Finder->addMatcher( - nestedNameSpecifierLoc( - hasAncestor(decl(IsInMovedNs).bind("dc")), - loc(nestedNameSpecifier( - specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"))))), - unless(anyOf(hasAncestor(isImplicit()), - hasAncestor(UsingShadowDeclInClass), - hasAncestor(functionDecl(isDefaulted())), - hasAncestor(typeLoc(loc(qualType(hasDeclaration( - decl(equalsBoundNode("from_decl")))))))))) - .bind("nested_specifier_loc"), - this); - - // Matches base class initializers in constructors. TypeLocs of base class - // initializers do not need to be fixed. For example, - // class X : public a::b::Y { - // public: - // X() : Y::Y() {} // Y::Y do not need namespace specifier. - // }; - Finder->addMatcher( - cxxCtorInitializer(isBaseInitializer()).bind("base_initializer"), this); - - // Handle function. - // Only handle functions that are defined in a namespace excluding member - // function, static methods (qualified by nested specifier), and functions - // defined in the global namespace. - // Note that the matcher does not exclude calls to out-of-line static method - // definitions, so we need to exclude them in the callback handler. - auto FuncMatcher = - functionDecl(unless(anyOf(cxxMethodDecl(), IsInMovedNs, - hasAncestor(namespaceDecl(isAnonymous())), - hasAncestor(cxxRecordDecl()))), - hasParent(namespaceDecl())); - Finder->addMatcher(expr(hasAncestor(decl().bind("dc")), IsInMovedNs, - unless(hasAncestor(isImplicit())), - anyOf(callExpr(callee(FuncMatcher)).bind("call"), - declRefExpr(to(FuncMatcher.bind("func_decl"))) - .bind("func_ref"))), - this); - - auto GlobalVarMatcher = varDecl( - hasGlobalStorage(), hasParent(namespaceDecl()), - unless(anyOf(IsInMovedNs, hasAncestor(namespaceDecl(isAnonymous()))))); - Finder->addMatcher(declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")), - to(GlobalVarMatcher.bind("var_decl"))) - .bind("var_ref"), - this); - - // Handle unscoped enum constant. - auto UnscopedEnumMatcher = enumConstantDecl(hasParent(enumDecl( - hasParent(namespaceDecl()), - unless(anyOf(isScoped(), IsInMovedNs, hasAncestor(cxxRecordDecl()), - hasAncestor(namespaceDecl(isAnonymous()))))))); - Finder->addMatcher( - declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")), - to(UnscopedEnumMatcher.bind("enum_const_decl"))) - .bind("enum_const_ref"), - this); -} - -void ChangeNamespaceTool::run( - const ast_matchers::MatchFinder::MatchResult &Result) { - if (const auto *Using = Result.Nodes.getNodeAs("using")) { - UsingDecls.insert(Using); - } else if (const auto *UsingNamespace = - Result.Nodes.getNodeAs( - "using_namespace")) { - UsingNamespaceDecls.insert(UsingNamespace); - } else if (const auto *NamespaceAlias = - Result.Nodes.getNodeAs( - "namespace_alias")) { - NamespaceAliasDecls.insert(NamespaceAlias); - } else if (const auto *NsDecl = - Result.Nodes.getNodeAs("old_ns")) { - moveOldNamespace(Result, NsDecl); - } else if (const auto *FwdDecl = - Result.Nodes.getNodeAs("class_fwd_decl")) { - moveClassForwardDeclaration(Result, cast(FwdDecl)); - } else if (const auto *TemplateFwdDecl = - Result.Nodes.getNodeAs( - "template_class_fwd_decl")) { - moveClassForwardDeclaration(Result, cast(TemplateFwdDecl)); - } else if (const auto *UsingWithShadow = - Result.Nodes.getNodeAs("using_with_shadow")) { - fixUsingShadowDecl(Result, UsingWithShadow); - } else if (const auto *Specifier = - Result.Nodes.getNodeAs( - "nested_specifier_loc")) { - SourceLocation Start = Specifier->getBeginLoc(); - SourceLocation End = endLocationForType(Specifier->getTypeLoc()); - fixTypeLoc(Result, Start, End, Specifier->getTypeLoc()); - } else if (const auto *BaseInitializer = - Result.Nodes.getNodeAs( - "base_initializer")) { - BaseCtorInitializerTypeLocs.push_back( - BaseInitializer->getTypeSourceInfo()->getTypeLoc()); - } else if (const auto *TLoc = Result.Nodes.getNodeAs("type")) { - // This avoids fixing types with record types as qualifier, which is not - // filtered by matchers in some cases, e.g. the type is templated. We should - // handle the record type qualifier instead. - TypeLoc Loc = *TLoc; - while (Loc.getTypeLocClass() == TypeLoc::Qualified) - Loc = Loc.getNextTypeLoc(); - if (Loc.getTypeLocClass() == TypeLoc::Elaborated) { - NestedNameSpecifierLoc NestedNameSpecifier = - Loc.castAs().getQualifierLoc(); - // This happens for friend declaration of a base class with injected class - // name. - if (!NestedNameSpecifier.getNestedNameSpecifier()) - return; - const Type *SpecifierType = - NestedNameSpecifier.getNestedNameSpecifier()->getAsType(); - if (SpecifierType && SpecifierType->isRecordType()) - return; - } - fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc); - } else if (const auto *VarRef = - Result.Nodes.getNodeAs("var_ref")) { - const auto *Var = Result.Nodes.getNodeAs("var_decl"); - assert(Var); - if (Var->getCanonicalDecl()->isStaticDataMember()) - return; - const auto *Context = Result.Nodes.getNodeAs("dc"); - assert(Context && "Empty decl context."); - fixDeclRefExpr(Result, Context->getDeclContext(), - llvm::cast(Var), VarRef); - } else if (const auto *EnumConstRef = - Result.Nodes.getNodeAs("enum_const_ref")) { - // Do not rename the reference if it is already scoped by the EnumDecl name. - if (EnumConstRef->hasQualifier() && - EnumConstRef->getQualifier()->getKind() == - NestedNameSpecifier::SpecifierKind::TypeSpec && - EnumConstRef->getQualifier()->getAsType()->isEnumeralType()) - return; - const auto *EnumConstDecl = - Result.Nodes.getNodeAs("enum_const_decl"); - assert(EnumConstDecl); - const auto *Context = Result.Nodes.getNodeAs("dc"); - assert(Context && "Empty decl context."); - // FIXME: this would qualify "ns::VALUE" as "ns::EnumValue::VALUE". Fix it - // if it turns out to be an issue. - fixDeclRefExpr(Result, Context->getDeclContext(), - llvm::cast(EnumConstDecl), EnumConstRef); - } else if (const auto *FuncRef = - Result.Nodes.getNodeAs("func_ref")) { - // If this reference has been processed as a function call, we do not - // process it again. - if (ProcessedFuncRefs.count(FuncRef)) - return; - ProcessedFuncRefs.insert(FuncRef); - const auto *Func = Result.Nodes.getNodeAs("func_decl"); - assert(Func); - const auto *Context = Result.Nodes.getNodeAs("dc"); - assert(Context && "Empty decl context."); - fixDeclRefExpr(Result, Context->getDeclContext(), - llvm::cast(Func), FuncRef); - } else { - const auto *Call = Result.Nodes.getNodeAs("call"); - assert(Call != nullptr && "Expecting callback for CallExpr."); - const auto *CalleeFuncRef = - llvm::cast(Call->getCallee()->IgnoreImplicit()); - ProcessedFuncRefs.insert(CalleeFuncRef); - const FunctionDecl *Func = Call->getDirectCallee(); - assert(Func != nullptr); - // FIXME: ignore overloaded operators. This would miss cases where operators - // are called by qualified names (i.e. "ns::operator <"). Ignore such - // cases for now. - if (Func->isOverloadedOperator()) - return; - // Ignore out-of-line static methods since they will be handled by nested - // name specifiers. - if (Func->getCanonicalDecl()->getStorageClass() == - StorageClass::SC_Static && - Func->isOutOfLine()) - return; - const auto *Context = Result.Nodes.getNodeAs("dc"); - assert(Context && "Empty decl context."); - SourceRange CalleeRange = Call->getCallee()->getSourceRange(); - replaceQualifiedSymbolInDeclContext( - Result, Context->getDeclContext(), CalleeRange.getBegin(), - CalleeRange.getEnd(), llvm::cast(Func)); - } -} - -static SourceLocation getLocAfterNamespaceLBrace(const NamespaceDecl *NsDecl, - const SourceManager &SM, - const LangOptions &LangOpts) { - std::unique_ptr Lex = - getLexerStartingFromLoc(NsDecl->getBeginLoc(), SM, LangOpts); - assert(Lex.get() && - "Failed to create lexer from the beginning of namespace."); - if (!Lex.get()) - return SourceLocation(); - Token Tok; - while (!Lex->LexFromRawLexer(Tok) && Tok.isNot(tok::TokenKind::l_brace)) { - } - return Tok.isNot(tok::TokenKind::l_brace) - ? SourceLocation() - : Tok.getEndLoc().getLocWithOffset(1); -} - -// Stores information about a moved namespace in `MoveNamespaces` and leaves -// the actual movement to `onEndOfTranslationUnit()`. -void ChangeNamespaceTool::moveOldNamespace( - const ast_matchers::MatchFinder::MatchResult &Result, - const NamespaceDecl *NsDecl) { - // If the namespace is empty, do nothing. - if (Decl::castToDeclContext(NsDecl)->decls_empty()) - return; - - const SourceManager &SM = *Result.SourceManager; - // Get the range of the code in the old namespace. - SourceLocation Start = - getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts()); - assert(Start.isValid() && "Can't find l_brace for namespace."); - MoveNamespace MoveNs; - MoveNs.Offset = SM.getFileOffset(Start); - // The range of the moved namespace is from the location just past the left - // brace to the location right before the right brace. - MoveNs.Length = SM.getFileOffset(NsDecl->getRBraceLoc()) - MoveNs.Offset; - - // Insert the new namespace after `DiffOldNamespace`. For example, if - // `OldNamespace` is "a::b::c" and `NewNamespace` is `a::x::y`, then - // "x::y" will be inserted inside the existing namespace "a" and after "a::b". - // `OuterNs` is the first namespace in `DiffOldNamespace`, e.g. "namespace b" - // in the above example. - // If there is no outer namespace (i.e. DiffOldNamespace is empty), the new - // namespace will be a nested namespace in the old namespace. - const NamespaceDecl *OuterNs = getOuterNamespace(NsDecl, DiffOldNamespace); - SourceLocation InsertionLoc = Start; - if (OuterNs) { - SourceLocation LocAfterNs = getStartOfNextLine( - OuterNs->getRBraceLoc(), SM, Result.Context->getLangOpts()); - assert(LocAfterNs.isValid() && - "Failed to get location after DiffOldNamespace"); - InsertionLoc = LocAfterNs; - } - MoveNs.InsertionOffset = SM.getFileOffset(SM.getSpellingLoc(InsertionLoc)); - MoveNs.FID = SM.getFileID(Start); - MoveNs.SourceMgr = Result.SourceManager; - MoveNamespaces[SM.getFilename(Start)].push_back(MoveNs); -} - -// Removes a class forward declaration from the code in the moved namespace and -// creates an `InsertForwardDeclaration` to insert the forward declaration back -// into the old namespace after moving code from the old namespace to the new -// namespace. -// For example, changing "a" to "x": -// Old code: -// namespace a { -// class FWD; -// class A { FWD *fwd; } -// } // a -// New code: -// namespace a { -// class FWD; -// } // a -// namespace x { -// class A { a::FWD *fwd; } -// } // x -void ChangeNamespaceTool::moveClassForwardDeclaration( - const ast_matchers::MatchFinder::MatchResult &Result, - const NamedDecl *FwdDecl) { - SourceLocation Start = FwdDecl->getBeginLoc(); - SourceLocation End = FwdDecl->getEndLoc(); - const SourceManager &SM = *Result.SourceManager; - SourceLocation AfterSemi = Lexer::findLocationAfterToken( - End, tok::semi, SM, Result.Context->getLangOpts(), - /*SkipTrailingWhitespaceAndNewLine=*/true); - if (AfterSemi.isValid()) - End = AfterSemi.getLocWithOffset(-1); - // Delete the forward declaration from the code to be moved. - addReplacementOrDie(Start, End, "", SM, &FileToReplacements); - llvm::StringRef Code = Lexer::getSourceText( - CharSourceRange::getTokenRange(SM.getSpellingLoc(Start), - SM.getSpellingLoc(End)), - SM, Result.Context->getLangOpts()); - // Insert the forward declaration back into the old namespace after moving the - // code from old namespace to new namespace. - // Insertion information is stored in `InsertFwdDecls` and actual - // insertion will be performed in `onEndOfTranslationUnit`. - // Get the (old) namespace that contains the forward declaration. - const auto *NsDecl = Result.Nodes.getNodeAs("ns_decl"); - // The namespace contains the forward declaration, so it must not be empty. - assert(!NsDecl->decls_empty()); - const auto Insertion = createInsertion( - getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts()), - Code, SM); - InsertForwardDeclaration InsertFwd; - InsertFwd.InsertionOffset = Insertion.getOffset(); - InsertFwd.ForwardDeclText = Insertion.getReplacementText().str(); - InsertFwdDecls[Insertion.getFilePath()].push_back(InsertFwd); -} - -// Replaces a qualified symbol (in \p DeclCtx) that refers to a declaration \p -// FromDecl with the shortest qualified name possible when the reference is in -// `NewNamespace`. -void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( - const ast_matchers::MatchFinder::MatchResult &Result, - const DeclContext *DeclCtx, SourceLocation Start, SourceLocation End, - const NamedDecl *FromDecl) { - const auto *NsDeclContext = DeclCtx->getEnclosingNamespaceContext(); - if (llvm::isa(NsDeclContext)) { - // This should not happen in usual unless the TypeLoc is in function type - // parameters, e.g `std::function`. In this case, DeclContext of - // `T` will be the translation unit. We simply use fully-qualified name - // here. - // Note that `FromDecl` must not be defined in the old namespace (according - // to `DeclMatcher`), so its fully-qualified name will not change after - // changing the namespace. - addReplacementOrDie(Start, End, FromDecl->getQualifiedNameAsString(), - *Result.SourceManager, &FileToReplacements); - return; - } - const auto *NsDecl = llvm::cast(NsDeclContext); - // Calculate the name of the `NsDecl` after it is moved to new namespace. - std::string OldNs = NsDecl->getQualifiedNameAsString(); - llvm::StringRef Postfix = OldNs; - bool Consumed = Postfix.consume_front(OldNamespace); - assert(Consumed && "Expect OldNS to start with OldNamespace."); - (void)Consumed; - const std::string NewNs = (NewNamespace + Postfix).str(); - - llvm::StringRef NestedName = Lexer::getSourceText( - CharSourceRange::getTokenRange( - Result.SourceManager->getSpellingLoc(Start), - Result.SourceManager->getSpellingLoc(End)), - *Result.SourceManager, Result.Context->getLangOpts()); - std::string FromDeclName = FromDecl->getQualifiedNameAsString(); - for (llvm::Regex &RE : WhiteListedSymbolRegexes) - if (RE.match(FromDeclName)) - return; - std::string ReplaceName = - getShortestQualifiedNameInNamespace(FromDeclName, NewNs); - // Checks if there is any using namespace declarations that can shorten the - // qualified name. - for (const auto *UsingNamespace : UsingNamespaceDecls) { - if (!isDeclVisibleAtLocation(*Result.SourceManager, UsingNamespace, DeclCtx, - Start)) - continue; - StringRef FromDeclNameRef = FromDeclName; - if (FromDeclNameRef.consume_front(UsingNamespace->getNominatedNamespace() - ->getQualifiedNameAsString())) { - FromDeclNameRef = FromDeclNameRef.drop_front(2); - if (FromDeclNameRef.size() < ReplaceName.size()) - ReplaceName = FromDeclNameRef; - } - } - // Checks if there is any namespace alias declarations that can shorten the - // qualified name. - for (const auto *NamespaceAlias : NamespaceAliasDecls) { - if (!isDeclVisibleAtLocation(*Result.SourceManager, NamespaceAlias, DeclCtx, - Start)) - continue; - StringRef FromDeclNameRef = FromDeclName; - if (FromDeclNameRef.consume_front( - NamespaceAlias->getNamespace()->getQualifiedNameAsString() + - "::")) { - std::string AliasName = NamespaceAlias->getNameAsString(); - std::string AliasQualifiedName = - NamespaceAlias->getQualifiedNameAsString(); - // We only consider namespace aliases define in the global namepspace or - // in namespaces that are directly visible from the reference, i.e. - // ancestor of the `OldNs`. Note that declarations in ancestor namespaces - // but not visible in the new namespace is filtered out by - // "IsVisibleInNewNs" matcher. - if (AliasQualifiedName != AliasName) { - // The alias is defined in some namespace. - assert(StringRef(AliasQualifiedName).endswith("::" + AliasName)); - llvm::StringRef AliasNs = - StringRef(AliasQualifiedName).drop_back(AliasName.size() + 2); - if (!llvm::StringRef(OldNs).startswith(AliasNs)) - continue; - } - std::string NameWithAliasNamespace = - (AliasName + "::" + FromDeclNameRef).str(); - if (NameWithAliasNamespace.size() < ReplaceName.size()) - ReplaceName = NameWithAliasNamespace; - } - } - // Checks if there is any using shadow declarations that can shorten the - // qualified name. - bool Matched = false; - for (const UsingDecl *Using : UsingDecls) { - if (Matched) - break; - if (isDeclVisibleAtLocation(*Result.SourceManager, Using, DeclCtx, Start)) { - for (const auto *UsingShadow : Using->shadows()) { - const auto *TargetDecl = UsingShadow->getTargetDecl(); - if (TargetDecl->getQualifiedNameAsString() == - FromDecl->getQualifiedNameAsString()) { - ReplaceName = FromDecl->getNameAsString(); - Matched = true; - break; - } - } - } - } - bool Conflict = conflictInNamespace(DeclCtx->getParentASTContext(), - ReplaceName, NewNamespace); - // If the new nested name in the new namespace is the same as it was in the - // old namespace, we don't create replacement unless there can be ambiguity. - if ((NestedName == ReplaceName && !Conflict) || - (NestedName.startswith("::") && NestedName.drop_front(2) == ReplaceName)) - return; - // If the reference need to be fully-qualified, add a leading "::" unless - // NewNamespace is the global namespace. - if (ReplaceName == FromDeclName && !NewNamespace.empty() && Conflict) - ReplaceName = "::" + ReplaceName; - addReplacementOrDie(Start, End, ReplaceName, *Result.SourceManager, - &FileToReplacements); -} - -// Replace the [Start, End] of `Type` with the shortest qualified name when the -// `Type` is in `NewNamespace`. -void ChangeNamespaceTool::fixTypeLoc( - const ast_matchers::MatchFinder::MatchResult &Result, SourceLocation Start, - SourceLocation End, TypeLoc Type) { - // FIXME: do not rename template parameter. - if (Start.isInvalid() || End.isInvalid()) - return; - // Types of CXXCtorInitializers do not need to be fixed. - if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type)) - return; - if (isTemplateParameter(Type)) - return; - // The declaration which this TypeLoc refers to. - const auto *FromDecl = Result.Nodes.getNodeAs("from_decl"); - // `hasDeclaration` gives underlying declaration, but if the type is - // a typedef type, we need to use the typedef type instead. - auto IsInMovedNs = [&](const NamedDecl *D) { - if (!llvm::StringRef(D->getQualifiedNameAsString()) - .startswith(OldNamespace + "::")) - return false; - auto ExpansionLoc = Result.SourceManager->getExpansionLoc(D->getBeginLoc()); - if (ExpansionLoc.isInvalid()) - return false; - llvm::StringRef Filename = Result.SourceManager->getFilename(ExpansionLoc); - return FilePatternRE.match(Filename); - }; - // Make `FromDecl` the immediate declaration that `Type` refers to, i.e. if - // `Type` is an alias type, we make `FromDecl` the type alias declaration. - // Also, don't fix the \p Type if it refers to a type alias decl in the moved - // namespace since the alias decl will be moved along with the type reference. - if (auto *Typedef = Type.getType()->getAs()) { - FromDecl = Typedef->getDecl(); - if (IsInMovedNs(FromDecl)) - return; - } else if (auto *TemplateType = - Type.getType()->getAs()) { - if (TemplateType->isTypeAlias()) { - FromDecl = TemplateType->getTemplateName().getAsTemplateDecl(); - if (IsInMovedNs(FromDecl)) - return; - } - } - const auto *DeclCtx = Result.Nodes.getNodeAs("dc"); - assert(DeclCtx && "Empty decl context."); - replaceQualifiedSymbolInDeclContext(Result, DeclCtx->getDeclContext(), Start, - End, FromDecl); -} - -void ChangeNamespaceTool::fixUsingShadowDecl( - const ast_matchers::MatchFinder::MatchResult &Result, - const UsingDecl *UsingDeclaration) { - SourceLocation Start = UsingDeclaration->getBeginLoc(); - SourceLocation End = UsingDeclaration->getEndLoc(); - if (Start.isInvalid() || End.isInvalid()) - return; - - assert(UsingDeclaration->shadow_size() > 0); - // FIXME: it might not be always accurate to use the first using-decl. - const NamedDecl *TargetDecl = - UsingDeclaration->shadow_begin()->getTargetDecl(); - std::string TargetDeclName = TargetDecl->getQualifiedNameAsString(); - // FIXME: check if target_decl_name is in moved ns, which doesn't make much - // sense. If this happens, we need to use name with the new namespace. - // Use fully qualified name in UsingDecl for now. - addReplacementOrDie(Start, End, "using ::" + TargetDeclName, - *Result.SourceManager, &FileToReplacements); -} - -void ChangeNamespaceTool::fixDeclRefExpr( - const ast_matchers::MatchFinder::MatchResult &Result, - const DeclContext *UseContext, const NamedDecl *From, - const DeclRefExpr *Ref) { - SourceRange RefRange = Ref->getSourceRange(); - replaceQualifiedSymbolInDeclContext(Result, UseContext, RefRange.getBegin(), - RefRange.getEnd(), From); -} - -void ChangeNamespaceTool::onEndOfTranslationUnit() { - // Move namespace blocks and insert forward declaration to old namespace. - for (const auto &FileAndNsMoves : MoveNamespaces) { - auto &NsMoves = FileAndNsMoves.second; - if (NsMoves.empty()) - continue; - const std::string &FilePath = FileAndNsMoves.first; - auto &Replaces = FileToReplacements[FilePath]; - auto &SM = *NsMoves.begin()->SourceMgr; - llvm::StringRef Code = SM.getBufferData(NsMoves.begin()->FID); - auto ChangedCode = tooling::applyAllReplacements(Code, Replaces); - if (!ChangedCode) { - llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n"; - continue; - } - // Replacements on the changed code for moving namespaces and inserting - // forward declarations to old namespaces. - tooling::Replacements NewReplacements; - // Cut the changed code from the old namespace and paste the code in the new - // namespace. - for (const auto &NsMove : NsMoves) { - // Calculate the range of the old namespace block in the changed - // code. - const unsigned NewOffset = Replaces.getShiftedCodePosition(NsMove.Offset); - const unsigned NewLength = - Replaces.getShiftedCodePosition(NsMove.Offset + NsMove.Length) - - NewOffset; - tooling::Replacement Deletion(FilePath, NewOffset, NewLength, ""); - std::string MovedCode = ChangedCode->substr(NewOffset, NewLength); - std::string MovedCodeWrappedInNewNs = - wrapCodeInNamespace(DiffNewNamespace, MovedCode); - // Calculate the new offset at which the code will be inserted in the - // changed code. - unsigned NewInsertionOffset = - Replaces.getShiftedCodePosition(NsMove.InsertionOffset); - tooling::Replacement Insertion(FilePath, NewInsertionOffset, 0, - MovedCodeWrappedInNewNs); - addOrMergeReplacement(Deletion, &NewReplacements); - addOrMergeReplacement(Insertion, &NewReplacements); - } - // After moving namespaces, insert forward declarations back to old - // namespaces. - const auto &FwdDeclInsertions = InsertFwdDecls[FilePath]; - for (const auto &FwdDeclInsertion : FwdDeclInsertions) { - unsigned NewInsertionOffset = - Replaces.getShiftedCodePosition(FwdDeclInsertion.InsertionOffset); - tooling::Replacement Insertion(FilePath, NewInsertionOffset, 0, - FwdDeclInsertion.ForwardDeclText); - addOrMergeReplacement(Insertion, &NewReplacements); - } - // Add replacements referring to the changed code to existing replacements, - // which refers to the original code. - Replaces = Replaces.merge(NewReplacements); - auto Style = - format::getStyle(format::DefaultFormatStyle, FilePath, FallbackStyle); - if (!Style) { - llvm::errs() << llvm::toString(Style.takeError()) << "\n"; - continue; - } - // Clean up old namespaces if there is nothing in it after moving. - auto CleanReplacements = - format::cleanupAroundReplacements(Code, Replaces, *Style); - if (!CleanReplacements) { - llvm::errs() << llvm::toString(CleanReplacements.takeError()) << "\n"; - continue; - } - FileToReplacements[FilePath] = *CleanReplacements; - } - - // Make sure we don't generate replacements for files that do not match - // FilePattern. - for (auto &Entry : FileToReplacements) - if (!FilePatternRE.match(Entry.first)) - Entry.second.clear(); -} - -} // namespace change_namespace -} // namespace clang diff --git a/change-namespace/ChangeNamespace.h b/change-namespace/ChangeNamespace.h deleted file mode 100644 index 293d5ce8..00000000 --- a/change-namespace/ChangeNamespace.h +++ /dev/null @@ -1,175 +0,0 @@ -//===-- ChangeNamespace.h -- Change namespace ------------------*- 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_TOOLS_EXTRA_CHANGE_NAMESPACE_CHANGENAMESPACE_H -#define LLVM_CLANG_TOOLS_EXTRA_CHANGE_NAMESPACE_CHANGENAMESPACE_H - -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Format/Format.h" -#include "clang/Tooling/Core/Replacement.h" -#include "llvm/Support/Regex.h" -#include - -namespace clang { -namespace change_namespace { - -// This tool can be used to change the surrounding namespaces of class/function -// definitions. Classes/functions in the moved namespace will have new -// namespaces while references to symbols (e.g. types, functions) which are not -// defined in the changed namespace will be correctly qualified by prepending -// namespace specifiers before them. -// This will try to add shortest namespace specifiers possible. When a symbol -// reference needs to be fully-qualified, this adds a "::" prefix to the -// namespace specifiers unless the new namespace is the global namespace. -// For classes, only classes that are declared/defined in the given namespace in -// speficifed files will be moved: forward declarations will remain in the old -// namespace. -// For example, changing "a" to "x": -// Old code: -// namespace a { -// class FWD; -// class A { FWD *fwd; } -// } // a -// New code: -// namespace a { -// class FWD; -// } // a -// namespace x { -// class A { ::a::FWD *fwd; } -// } // x -// FIXME: support moving typedef, enums across namespaces. -class ChangeNamespaceTool : public ast_matchers::MatchFinder::MatchCallback { -public: - // Moves code in the old namespace `OldNs` to the new namespace `NewNs` in - // files matching `FilePattern`. - ChangeNamespaceTool( - llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern, - llvm::ArrayRef WhiteListedSymbolPatterns, - std::map *FileToReplacements, - llvm::StringRef FallbackStyle = "LLVM"); - - void registerMatchers(ast_matchers::MatchFinder *Finder); - - void run(const ast_matchers::MatchFinder::MatchResult &Result) override; - - // Moves the changed code in old namespaces but leaves class forward - // declarations behind. - void onEndOfTranslationUnit() override; - -private: - void moveOldNamespace(const ast_matchers::MatchFinder::MatchResult &Result, - const NamespaceDecl *NsDecl); - - void moveClassForwardDeclaration( - const ast_matchers::MatchFinder::MatchResult &Result, - const NamedDecl *FwdDecl); - - void replaceQualifiedSymbolInDeclContext( - const ast_matchers::MatchFinder::MatchResult &Result, - const DeclContext *DeclContext, SourceLocation Start, SourceLocation End, - const NamedDecl *FromDecl); - - void fixTypeLoc(const ast_matchers::MatchFinder::MatchResult &Result, - SourceLocation Start, SourceLocation End, TypeLoc Type); - - void fixUsingShadowDecl(const ast_matchers::MatchFinder::MatchResult &Result, - const UsingDecl *UsingDeclaration); - - void fixDeclRefExpr(const ast_matchers::MatchFinder::MatchResult &Result, - const DeclContext *UseContext, const NamedDecl *From, - const DeclRefExpr *Ref); - - // Information about moving an old namespace. - struct MoveNamespace { - // The start offset of the namespace block being moved in the original - // code. - unsigned Offset; - // The length of the namespace block in the original code. - unsigned Length; - // The offset at which the new namespace block will be inserted in the - // original code. - unsigned InsertionOffset; - // The file in which the namespace is declared. - FileID FID; - SourceManager *SourceMgr; - }; - - // Information about inserting a class forward declaration. - struct InsertForwardDeclaration { - // The offset at while the forward declaration will be inserted in the - // original code. - unsigned InsertionOffset; - // The code to be inserted. - std::string ForwardDeclText; - }; - - std::string FallbackStyle; - // In match callbacks, this contains replacements for replacing `typeLoc`s in - // and deleting forward declarations in the moved namespace blocks. - // In `onEndOfTranslationUnit` callback, the previous added replacements are - // applied (on the moved namespace blocks), and then changed code in old - // namespaces re moved to new namespaces, and previously deleted forward - // declarations are inserted back to old namespaces, from which they are - // deleted. - std::map &FileToReplacements; - // A fully qualified name of the old namespace without "::" prefix, e.g. - // "a::b::c". - std::string OldNamespace; - // A fully qualified name of the new namespace without "::" prefix, e.g. - // "x::y::z". - std::string NewNamespace; - // The longest suffix in the old namespace that does not overlap the new - // namespace. - // For example, if `OldNamespace` is "a::b::c" and `NewNamespace` is - // "a::x::y", then `DiffOldNamespace` will be "b::c". - std::string DiffOldNamespace; - // The longest suffix in the new namespace that does not overlap the old - // namespace. - // For example, if `OldNamespace` is "a::b::c" and `NewNamespace` is - // "a::x::y", then `DiffNewNamespace` will be "x::y". - std::string DiffNewNamespace; - // A regex pattern that matches files to be processed. - std::string FilePattern; - llvm::Regex FilePatternRE; - // Information about moved namespaces grouped by file. - // Since we are modifying code in old namespaces (e.g. add namespace - // spedifiers) as well as moving them, we store information about namespaces - // to be moved and only move them after all modifications are finished (i.e. - // in `onEndOfTranslationUnit`). - std::map> MoveNamespaces; - // Information about forward declaration insertions grouped by files. - // A class forward declaration is not moved, so it will be deleted from the - // moved code block and inserted back into the old namespace. The insertion - // will be done after removing the code from the old namespace and before - // inserting it to the new namespace. - std::map> InsertFwdDecls; - // Records all using declarations, which can be used to shorten namespace - // specifiers. - llvm::SmallPtrSet UsingDecls; - // Records all using namespace declarations, which can be used to shorten - // namespace specifiers. - llvm::SmallPtrSet UsingNamespaceDecls; - // Records all namespace alias declarations, which can be used to shorten - // namespace specifiers. - llvm::SmallPtrSet NamespaceAliasDecls; - // TypeLocs of CXXCtorInitializer. Types of CXXCtorInitializers do not need to - // be fixed. - llvm::SmallVector BaseCtorInitializerTypeLocs; - // Since a DeclRefExpr for a function call can be matched twice (one as - // CallExpr and one as DeclRefExpr), we record all DeclRefExpr's that have - // been processed so that we don't handle them twice. - llvm::SmallPtrSet ProcessedFuncRefs; - // Patterns of symbol names whose references are not expected to be updated - // when changing namespaces around them. - std::vector WhiteListedSymbolRegexes; -}; - -} // namespace change_namespace -} // namespace clang - -#endif // LLVM_CLANG_TOOLS_EXTRA_CHANGE_NAMESPACE_CHANGENAMESPACE_H diff --git a/change-namespace/tool/CMakeLists.txt b/change-namespace/tool/CMakeLists.txt deleted file mode 100644 index be4b830e..00000000 --- a/change-namespace/tool/CMakeLists.txt +++ /dev/null @@ -1,25 +0,0 @@ -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) - -set(LLVM_LINK_COMPONENTS - Support - ) - -add_clang_executable(clang-change-namespace - ClangChangeNamespace.cpp - ) -target_link_libraries(clang-change-namespace - PRIVATE - clangAST - clangASTMatchers - clangBasic - clangChangeNamespace - clangFormat - clangFrontend - clangRewrite - clangSerialization - clangTooling - clangToolingCore - ) - -install(TARGETS clang-change-namespace - RUNTIME DESTINATION bin) diff --git a/change-namespace/tool/ClangChangeNamespace.cpp b/change-namespace/tool/ClangChangeNamespace.cpp deleted file mode 100644 index d5f06552..00000000 --- a/change-namespace/tool/ClangChangeNamespace.cpp +++ /dev/null @@ -1,177 +0,0 @@ -//===-- ClangChangeNamespace.cpp - Standalone change namespace ------------===// -// -// 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 tool can be used to change the surrounding namespaces of class/function -// definitions. -// -// Example: test.cc -// namespace na { -// class X {}; -// namespace nb { -// class Y { X x; }; -// } // namespace nb -// } // namespace na -// To move the definition of class Y from namespace "na::nb" to "x::y", run: -// clang-change-namespace --old_namespace "na::nb" \ -// --new_namespace "x::y" --file_pattern "test.cc" test.cc -- -// Output: -// namespace na { -// class X {}; -// } // namespace na -// namespace x { -// namespace y { -// class Y { na::X x; }; -// } // namespace y -// } // namespace x - -#include "ChangeNamespace.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Frontend/FrontendActions.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" -#include "clang/Rewrite/Core/Rewriter.h" -#include "clang/Tooling/CommonOptionsParser.h" -#include "clang/Tooling/Refactoring.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Signals.h" -#include "llvm/Support/YAMLTraits.h" - -using namespace clang; -using namespace llvm; - -namespace { - -cl::OptionCategory ChangeNamespaceCategory("Change namespace."); - -cl::opt OldNamespace("old_namespace", cl::Required, - cl::desc("Old namespace."), - cl::cat(ChangeNamespaceCategory)); - -cl::opt NewNamespace("new_namespace", cl::Required, - cl::desc("New namespace."), - cl::cat(ChangeNamespaceCategory)); - -cl::opt FilePattern( - "file_pattern", cl::Required, - cl::desc("Only rename namespaces in files that match the given pattern."), - cl::cat(ChangeNamespaceCategory)); - -cl::opt Inplace("i", cl::desc("Inplace edit s, if specified."), - cl::cat(ChangeNamespaceCategory)); - -cl::opt - DumpYAML("dump_result", - cl::desc("Dump new file contents in YAML, if specified."), - cl::cat(ChangeNamespaceCategory)); - -cl::opt Style("style", - cl::desc("The style name used for reformatting."), - cl::init("LLVM"), cl::cat(ChangeNamespaceCategory)); - -cl::opt WhiteListFile( - "whitelist_file", - cl::desc("A file containing regexes of symbol names that are not expected " - "to be updated when changing namespaces around them."), - cl::init(""), cl::cat(ChangeNamespaceCategory)); - -llvm::ErrorOr> GetWhiteListedSymbolPatterns() { - std::vector Patterns; - if (WhiteListFile.empty()) - return Patterns; - - llvm::SmallVector Lines; - llvm::ErrorOr> File = - llvm::MemoryBuffer::getFile(WhiteListFile); - if (!File) - return File.getError(); - llvm::StringRef Content = File.get()->getBuffer(); - Content.split(Lines, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false); - for (auto Line : Lines) - Patterns.push_back(Line.trim()); - return Patterns; -} - -} // anonymous namespace - -int main(int argc, const char **argv) { - llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - tooling::CommonOptionsParser OptionsParser(argc, argv, - ChangeNamespaceCategory); - const auto &Files = OptionsParser.getSourcePathList(); - tooling::RefactoringTool Tool(OptionsParser.getCompilations(), Files); - llvm::ErrorOr> WhiteListPatterns = - GetWhiteListedSymbolPatterns(); - if (!WhiteListPatterns) { - llvm::errs() << "Failed to open whitelist file " << WhiteListFile << ". " - << WhiteListPatterns.getError().message() << "\n"; - return 1; - } - change_namespace::ChangeNamespaceTool NamespaceTool( - OldNamespace, NewNamespace, FilePattern, *WhiteListPatterns, - &Tool.getReplacements(), Style); - ast_matchers::MatchFinder Finder; - NamespaceTool.registerMatchers(&Finder); - std::unique_ptr Factory = - tooling::newFrontendActionFactory(&Finder); - - if (int Result = Tool.run(Factory.get())) - return Result; - LangOptions DefaultLangOptions; - IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); - clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts); - DiagnosticsEngine Diagnostics( - IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, - &DiagnosticPrinter, false); - auto &FileMgr = Tool.getFiles(); - SourceManager Sources(Diagnostics, FileMgr); - Rewriter Rewrite(Sources, DefaultLangOptions); - - if (!formatAndApplyAllReplacements(Tool.getReplacements(), Rewrite, Style)) { - llvm::errs() << "Failed applying all replacements.\n"; - return 1; - } - if (Inplace) - return Rewrite.overwriteChangedFiles(); - - std::set ChangedFiles; - for (const auto &it : Tool.getReplacements()) - ChangedFiles.insert(it.first); - - if (DumpYAML) { - auto WriteToYAML = [&](llvm::raw_ostream &OS) { - OS << "[\n"; - for (auto I = ChangedFiles.begin(), E = ChangedFiles.end(); I != E; ++I) { - OS << " {\n"; - OS << " \"FilePath\": \"" << *I << "\",\n"; - const auto *Entry = FileMgr.getFile(*I); - auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User); - std::string Content; - llvm::raw_string_ostream ContentStream(Content); - Rewrite.getEditBuffer(ID).write(ContentStream); - OS << " \"SourceText\": \"" - << llvm::yaml::escape(ContentStream.str()) << "\"\n"; - OS << " }"; - if (I != std::prev(E)) - OS << ",\n"; - } - OS << "\n]\n"; - }; - WriteToYAML(llvm::outs()); - return 0; - } - - for (const auto &File : ChangedFiles) { - const auto *Entry = FileMgr.getFile(File); - - auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User); - outs() << "============== " << File << " ==============\n"; - Rewrite.getEditBuffer(ID).write(llvm::outs()); - outs() << "\n============================================\n"; - } - - return 0; -} diff --git a/clang-change-namespace/CMakeLists.txt b/clang-change-namespace/CMakeLists.txt new file mode 100644 index 00000000..17830642 --- /dev/null +++ b/clang-change-namespace/CMakeLists.txt @@ -0,0 +1,20 @@ +set(LLVM_LINK_COMPONENTS + support + ) + +add_clang_library(clangChangeNamespace + ChangeNamespace.cpp + + LINK_LIBS + clangAST + clangASTMatchers + clangBasic + clangFormat + clangFrontend + clangLex + clangSerialization + clangTooling + clangToolingCore + ) + +add_subdirectory(tool) diff --git a/clang-change-namespace/ChangeNamespace.cpp b/clang-change-namespace/ChangeNamespace.cpp new file mode 100644 index 00000000..eb732639 --- /dev/null +++ b/clang-change-namespace/ChangeNamespace.cpp @@ -0,0 +1,1042 @@ +//===-- ChangeNamespace.cpp - Change namespace implementation -------------===// +// +// 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 "ChangeNamespace.h" +#include "clang/AST/ASTContext.h" +#include "clang/Format/Format.h" +#include "clang/Lex/Lexer.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace clang::ast_matchers; + +namespace clang { +namespace change_namespace { + +namespace { + +inline std::string +joinNamespaces(const llvm::SmallVectorImpl &Namespaces) { + if (Namespaces.empty()) + return ""; + std::string Result = Namespaces.front(); + for (auto I = Namespaces.begin() + 1, E = Namespaces.end(); I != E; ++I) + Result += ("::" + *I).str(); + return Result; +} + +// Given "a::b::c", returns {"a", "b", "c"}. +llvm::SmallVector splitSymbolName(llvm::StringRef Name) { + llvm::SmallVector Splitted; + Name.split(Splitted, "::", /*MaxSplit=*/-1, + /*KeepEmpty=*/false); + return Splitted; +} + +SourceLocation startLocationForType(TypeLoc TLoc) { + // For elaborated types (e.g. `struct a::A`) we want the portion after the + // `struct` but including the namespace qualifier, `a::`. + if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) { + NestedNameSpecifierLoc NestedNameSpecifier = + TLoc.castAs().getQualifierLoc(); + if (NestedNameSpecifier.getNestedNameSpecifier()) + return NestedNameSpecifier.getBeginLoc(); + TLoc = TLoc.getNextTypeLoc(); + } + return TLoc.getBeginLoc(); +} + +SourceLocation endLocationForType(TypeLoc TLoc) { + // Dig past any namespace or keyword qualifications. + while (TLoc.getTypeLocClass() == TypeLoc::Elaborated || + TLoc.getTypeLocClass() == TypeLoc::Qualified) + TLoc = TLoc.getNextTypeLoc(); + + // The location for template specializations (e.g. Foo) includes the + // templated types in its location range. We want to restrict this to just + // before the `<` character. + if (TLoc.getTypeLocClass() == TypeLoc::TemplateSpecialization) + return TLoc.castAs() + .getLAngleLoc() + .getLocWithOffset(-1); + return TLoc.getEndLoc(); +} + +// Returns the containing namespace of `InnerNs` by skipping `PartialNsName`. +// If the `InnerNs` does not have `PartialNsName` as suffix, or `PartialNsName` +// is empty, nullptr is returned. +// For example, if `InnerNs` is "a::b::c" and `PartialNsName` is "b::c", then +// the NamespaceDecl of namespace "a" will be returned. +const NamespaceDecl *getOuterNamespace(const NamespaceDecl *InnerNs, + llvm::StringRef PartialNsName) { + if (!InnerNs || PartialNsName.empty()) + return nullptr; + const auto *CurrentContext = llvm::cast(InnerNs); + const auto *CurrentNs = InnerNs; + auto PartialNsNameSplitted = splitSymbolName(PartialNsName); + while (!PartialNsNameSplitted.empty()) { + // Get the inner-most namespace in CurrentContext. + while (CurrentContext && !llvm::isa(CurrentContext)) + CurrentContext = CurrentContext->getParent(); + if (!CurrentContext) + return nullptr; + CurrentNs = llvm::cast(CurrentContext); + if (PartialNsNameSplitted.back() != CurrentNs->getNameAsString()) + return nullptr; + PartialNsNameSplitted.pop_back(); + CurrentContext = CurrentContext->getParent(); + } + return CurrentNs; +} + +static std::unique_ptr +getLexerStartingFromLoc(SourceLocation Loc, const SourceManager &SM, + const LangOptions &LangOpts) { + if (Loc.isMacroID() && + !Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc)) + return nullptr; + // Break down the source location. + std::pair LocInfo = SM.getDecomposedLoc(Loc); + // Try to load the file buffer. + bool InvalidTemp = false; + llvm::StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp); + if (InvalidTemp) + return nullptr; + + const char *TokBegin = File.data() + LocInfo.second; + // Lex from the start of the given location. + return llvm::make_unique(SM.getLocForStartOfFile(LocInfo.first), + LangOpts, File.begin(), TokBegin, File.end()); +} + +// FIXME: get rid of this helper function if this is supported in clang-refactor +// library. +static SourceLocation getStartOfNextLine(SourceLocation Loc, + const SourceManager &SM, + const LangOptions &LangOpts) { + std::unique_ptr Lex = getLexerStartingFromLoc(Loc, SM, LangOpts); + if (!Lex.get()) + return SourceLocation(); + llvm::SmallVector Line; + // FIXME: this is a bit hacky to get ReadToEndOfLine work. + Lex->setParsingPreprocessorDirective(true); + Lex->ReadToEndOfLine(&Line); + auto End = Loc.getLocWithOffset(Line.size()); + return SM.getLocForEndOfFile(SM.getDecomposedLoc(Loc).first) == End + ? End + : End.getLocWithOffset(1); +} + +// Returns `R` with new range that refers to code after `Replaces` being +// applied. +tooling::Replacement +getReplacementInChangedCode(const tooling::Replacements &Replaces, + const tooling::Replacement &R) { + unsigned NewStart = Replaces.getShiftedCodePosition(R.getOffset()); + unsigned NewEnd = + Replaces.getShiftedCodePosition(R.getOffset() + R.getLength()); + return tooling::Replacement(R.getFilePath(), NewStart, NewEnd - NewStart, + R.getReplacementText()); +} + +// Adds a replacement `R` into `Replaces` or merges it into `Replaces` by +// applying all existing Replaces first if there is conflict. +void addOrMergeReplacement(const tooling::Replacement &R, + tooling::Replacements *Replaces) { + auto Err = Replaces->add(R); + if (Err) { + llvm::consumeError(std::move(Err)); + auto Replace = getReplacementInChangedCode(*Replaces, R); + *Replaces = Replaces->merge(tooling::Replacements(Replace)); + } +} + +tooling::Replacement createReplacement(SourceLocation Start, SourceLocation End, + llvm::StringRef ReplacementText, + const SourceManager &SM) { + if (!Start.isValid() || !End.isValid()) { + llvm::errs() << "start or end location were invalid\n"; + return tooling::Replacement(); + } + if (SM.getDecomposedLoc(Start).first != SM.getDecomposedLoc(End).first) { + llvm::errs() + << "start or end location were in different macro expansions\n"; + return tooling::Replacement(); + } + Start = SM.getSpellingLoc(Start); + End = SM.getSpellingLoc(End); + if (SM.getFileID(Start) != SM.getFileID(End)) { + llvm::errs() << "start or end location were in different files\n"; + return tooling::Replacement(); + } + return tooling::Replacement( + SM, CharSourceRange::getTokenRange(SM.getSpellingLoc(Start), + SM.getSpellingLoc(End)), + ReplacementText); +} + +void addReplacementOrDie( + SourceLocation Start, SourceLocation End, llvm::StringRef ReplacementText, + const SourceManager &SM, + std::map *FileToReplacements) { + const auto R = createReplacement(Start, End, ReplacementText, SM); + auto Err = (*FileToReplacements)[R.getFilePath()].add(R); + if (Err) + llvm_unreachable(llvm::toString(std::move(Err)).c_str()); +} + +tooling::Replacement createInsertion(SourceLocation Loc, + llvm::StringRef InsertText, + const SourceManager &SM) { + if (Loc.isInvalid()) { + llvm::errs() << "insert Location is invalid.\n"; + return tooling::Replacement(); + } + Loc = SM.getSpellingLoc(Loc); + return tooling::Replacement(SM, Loc, 0, InsertText); +} + +// Returns the shortest qualified name for declaration `DeclName` in the +// namespace `NsName`. For example, if `DeclName` is "a::b::X" and `NsName` +// is "a::c::d", then "b::X" will be returned. +// Note that if `DeclName` is `::b::X` and `NsName` is `::a::b`, this returns +// "::b::X" instead of "b::X" since there will be a name conflict otherwise. +// \param DeclName A fully qualified name, "::a::b::X" or "a::b::X". +// \param NsName A fully qualified name, "::a::b" or "a::b". Global namespace +// will have empty name. +std::string getShortestQualifiedNameInNamespace(llvm::StringRef DeclName, + llvm::StringRef NsName) { + DeclName = DeclName.ltrim(':'); + NsName = NsName.ltrim(':'); + if (DeclName.find(':') == llvm::StringRef::npos) + return DeclName; + + auto NsNameSplitted = splitSymbolName(NsName); + auto DeclNsSplitted = splitSymbolName(DeclName); + llvm::StringRef UnqualifiedDeclName = DeclNsSplitted.pop_back_val(); + // If the Decl is in global namespace, there is no need to shorten it. + if (DeclNsSplitted.empty()) + return UnqualifiedDeclName; + // If NsName is the global namespace, we can simply use the DeclName sans + // leading "::". + if (NsNameSplitted.empty()) + return DeclName; + + if (NsNameSplitted.front() != DeclNsSplitted.front()) { + // The DeclName must be fully-qualified, but we still need to decide if a + // leading "::" is necessary. For example, if `NsName` is "a::b::c" and the + // `DeclName` is "b::X", then the reference must be qualified as "::b::X" + // to avoid conflict. + if (llvm::is_contained(NsNameSplitted, DeclNsSplitted.front())) + return ("::" + DeclName).str(); + return DeclName; + } + // Since there is already an overlap namespace, we know that `DeclName` can be + // shortened, so we reduce the longest common prefix. + auto DeclI = DeclNsSplitted.begin(); + auto DeclE = DeclNsSplitted.end(); + auto NsI = NsNameSplitted.begin(); + auto NsE = NsNameSplitted.end(); + for (; DeclI != DeclE && NsI != NsE && *DeclI == *NsI; ++DeclI, ++NsI) { + } + return (DeclI == DeclE) + ? UnqualifiedDeclName.str() + : (llvm::join(DeclI, DeclE, "::") + "::" + UnqualifiedDeclName) + .str(); +} + +std::string wrapCodeInNamespace(StringRef NestedNs, std::string Code) { + if (Code.back() != '\n') + Code += "\n"; + auto NsSplitted = splitSymbolName(NestedNs); + while (!NsSplitted.empty()) { + // FIXME: consider code style for comments. + Code = ("namespace " + NsSplitted.back() + " {\n" + Code + + "} // namespace " + NsSplitted.back() + "\n") + .str(); + NsSplitted.pop_back(); + } + return Code; +} + +// Returns true if \p D is a nested DeclContext in \p Context +bool isNestedDeclContext(const DeclContext *D, const DeclContext *Context) { + while (D) { + if (D == Context) + return true; + D = D->getParent(); + } + return false; +} + +// Returns true if \p D is visible at \p Loc with DeclContext \p DeclCtx. +bool isDeclVisibleAtLocation(const SourceManager &SM, const Decl *D, + const DeclContext *DeclCtx, SourceLocation Loc) { + SourceLocation DeclLoc = SM.getSpellingLoc(D->getBeginLoc()); + Loc = SM.getSpellingLoc(Loc); + return SM.isBeforeInTranslationUnit(DeclLoc, Loc) && + (SM.getFileID(DeclLoc) == SM.getFileID(Loc) && + isNestedDeclContext(DeclCtx, D->getDeclContext())); +} + +// Given a qualified symbol name, returns true if the symbol will be +// incorrectly qualified without leading "::". For example, a symbol +// "nx::ny::Foo" in namespace "na::nx::ny" without leading "::"; a symbol +// "util::X" in namespace "na" can potentially conflict with "na::util" (if this +// exists). +bool conflictInNamespace(const ASTContext &AST, llvm::StringRef QualifiedSymbol, + llvm::StringRef Namespace) { + auto SymbolSplitted = splitSymbolName(QualifiedSymbol.trim(":")); + assert(!SymbolSplitted.empty()); + SymbolSplitted.pop_back(); // We are only interested in namespaces. + + if (SymbolSplitted.size() >= 1 && !Namespace.empty()) { + auto SymbolTopNs = SymbolSplitted.front(); + auto NsSplitted = splitSymbolName(Namespace.trim(":")); + assert(!NsSplitted.empty()); + + auto LookupDecl = [&AST](const Decl &Scope, + llvm::StringRef Name) -> const NamedDecl * { + const auto *DC = llvm::dyn_cast(&Scope); + if (!DC) + return nullptr; + auto LookupRes = DC->lookup(DeclarationName(&AST.Idents.get(Name))); + if (LookupRes.empty()) + return nullptr; + return LookupRes.front(); + }; + // We do not check the outermost namespace since it would not be a + // conflict if it equals to the symbol's outermost namespace and the + // symbol name would have been shortened. + const NamedDecl *Scope = + LookupDecl(*AST.getTranslationUnitDecl(), NsSplitted.front()); + for (auto I = NsSplitted.begin() + 1, E = NsSplitted.end(); I != E; ++I) { + if (*I == SymbolTopNs) // Handles "::ny" in "::nx::ny" case. + return true; + // Handles "::util" and "::nx::util" conflicts. + if (Scope) { + if (LookupDecl(*Scope, SymbolTopNs)) + return true; + Scope = LookupDecl(*Scope, *I); + } + } + if (Scope && LookupDecl(*Scope, SymbolTopNs)) + return true; + } + return false; +} + +AST_MATCHER(EnumDecl, isScoped) { + return Node.isScoped(); +} + +bool isTemplateParameter(TypeLoc Type) { + while (!Type.isNull()) { + if (Type.getTypeLocClass() == TypeLoc::SubstTemplateTypeParm) + return true; + Type = Type.getNextTypeLoc(); + } + return false; +} + +} // anonymous namespace + +ChangeNamespaceTool::ChangeNamespaceTool( + llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern, + llvm::ArrayRef WhiteListedSymbolPatterns, + std::map *FileToReplacements, + llvm::StringRef FallbackStyle) + : FallbackStyle(FallbackStyle), FileToReplacements(*FileToReplacements), + OldNamespace(OldNs.ltrim(':')), NewNamespace(NewNs.ltrim(':')), + FilePattern(FilePattern), FilePatternRE(FilePattern) { + FileToReplacements->clear(); + auto OldNsSplitted = splitSymbolName(OldNamespace); + auto NewNsSplitted = splitSymbolName(NewNamespace); + // Calculates `DiffOldNamespace` and `DiffNewNamespace`. + while (!OldNsSplitted.empty() && !NewNsSplitted.empty() && + OldNsSplitted.front() == NewNsSplitted.front()) { + OldNsSplitted.erase(OldNsSplitted.begin()); + NewNsSplitted.erase(NewNsSplitted.begin()); + } + DiffOldNamespace = joinNamespaces(OldNsSplitted); + DiffNewNamespace = joinNamespaces(NewNsSplitted); + + for (const auto &Pattern : WhiteListedSymbolPatterns) + WhiteListedSymbolRegexes.emplace_back(Pattern); +} + +void ChangeNamespaceTool::registerMatchers(ast_matchers::MatchFinder *Finder) { + std::string FullOldNs = "::" + OldNamespace; + // Prefix is the outer-most namespace in DiffOldNamespace. For example, if the + // OldNamespace is "a::b::c" and DiffOldNamespace is "b::c", then Prefix will + // be "a::b". Declarations in this namespace will not be visible in the new + // namespace. If DiffOldNamespace is empty, Prefix will be a invalid name "-". + llvm::SmallVector DiffOldNsSplitted; + llvm::StringRef(DiffOldNamespace) + .split(DiffOldNsSplitted, "::", /*MaxSplit=*/-1, + /*KeepEmpty=*/false); + std::string Prefix = "-"; + if (!DiffOldNsSplitted.empty()) + Prefix = (StringRef(FullOldNs).drop_back(DiffOldNamespace.size()) + + DiffOldNsSplitted.front()) + .str(); + auto IsInMovedNs = + allOf(hasAncestor(namespaceDecl(hasName(FullOldNs)).bind("ns_decl")), + isExpansionInFileMatching(FilePattern)); + auto IsVisibleInNewNs = anyOf( + IsInMovedNs, unless(hasAncestor(namespaceDecl(hasName(Prefix))))); + // Match using declarations. + Finder->addMatcher( + usingDecl(isExpansionInFileMatching(FilePattern), IsVisibleInNewNs) + .bind("using"), + this); + // Match using namespace declarations. + Finder->addMatcher(usingDirectiveDecl(isExpansionInFileMatching(FilePattern), + IsVisibleInNewNs) + .bind("using_namespace"), + this); + // Match namespace alias declarations. + Finder->addMatcher(namespaceAliasDecl(isExpansionInFileMatching(FilePattern), + IsVisibleInNewNs) + .bind("namespace_alias"), + this); + + // Match old namespace blocks. + Finder->addMatcher( + namespaceDecl(hasName(FullOldNs), isExpansionInFileMatching(FilePattern)) + .bind("old_ns"), + this); + + // Match class forward-declarations in the old namespace. + // Note that forward-declarations in classes are not matched. + Finder->addMatcher(cxxRecordDecl(unless(anyOf(isImplicit(), isDefinition())), + IsInMovedNs, hasParent(namespaceDecl())) + .bind("class_fwd_decl"), + this); + + // Match template class forward-declarations in the old namespace. + Finder->addMatcher( + classTemplateDecl(unless(hasDescendant(cxxRecordDecl(isDefinition()))), + IsInMovedNs, hasParent(namespaceDecl())) + .bind("template_class_fwd_decl"), + this); + + // Match references to types that are not defined in the old namespace. + // Forward-declarations in the old namespace are also matched since they will + // be moved back to the old namespace. + auto DeclMatcher = namedDecl( + hasAncestor(namespaceDecl()), + unless(anyOf( + isImplicit(), hasAncestor(namespaceDecl(isAnonymous())), + hasAncestor(cxxRecordDecl()), + allOf(IsInMovedNs, unless(cxxRecordDecl(unless(isDefinition()))))))); + + // Using shadow declarations in classes always refers to base class, which + // does not need to be qualified since it can be inferred from inheritance. + // Note that this does not match using alias declarations. + auto UsingShadowDeclInClass = + usingDecl(hasAnyUsingShadowDecl(decl()), hasParent(cxxRecordDecl())); + + // Match TypeLocs on the declaration. Carefully match only the outermost + // TypeLoc and template specialization arguments (which are not outermost) + // that are directly linked to types matching `DeclMatcher`. Nested name + // specifier locs are handled separately below. + Finder->addMatcher( + typeLoc(IsInMovedNs, + loc(qualType(hasDeclaration(DeclMatcher.bind("from_decl")))), + unless(anyOf(hasParent(typeLoc(loc(qualType( + hasDeclaration(DeclMatcher), + unless(templateSpecializationType()))))), + hasParent(nestedNameSpecifierLoc()), + hasAncestor(isImplicit()), + hasAncestor(UsingShadowDeclInClass), + hasAncestor(functionDecl(isDefaulted())))), + hasAncestor(decl().bind("dc"))) + .bind("type"), + this); + + // Types in `UsingShadowDecl` is not matched by `typeLoc` above, so we need to + // special case it. + // Since using declarations inside classes must have the base class in the + // nested name specifier, we leave it to the nested name specifier matcher. + Finder->addMatcher(usingDecl(IsInMovedNs, hasAnyUsingShadowDecl(decl()), + unless(UsingShadowDeclInClass)) + .bind("using_with_shadow"), + this); + + // Handle types in nested name specifier. Specifiers that are in a TypeLoc + // matched above are not matched, e.g. "A::" in "A::A" is not matched since + // "A::A" would have already been fixed. + Finder->addMatcher( + nestedNameSpecifierLoc( + hasAncestor(decl(IsInMovedNs).bind("dc")), + loc(nestedNameSpecifier( + specifiesType(hasDeclaration(DeclMatcher.bind("from_decl"))))), + unless(anyOf(hasAncestor(isImplicit()), + hasAncestor(UsingShadowDeclInClass), + hasAncestor(functionDecl(isDefaulted())), + hasAncestor(typeLoc(loc(qualType(hasDeclaration( + decl(equalsBoundNode("from_decl")))))))))) + .bind("nested_specifier_loc"), + this); + + // Matches base class initializers in constructors. TypeLocs of base class + // initializers do not need to be fixed. For example, + // class X : public a::b::Y { + // public: + // X() : Y::Y() {} // Y::Y do not need namespace specifier. + // }; + Finder->addMatcher( + cxxCtorInitializer(isBaseInitializer()).bind("base_initializer"), this); + + // Handle function. + // Only handle functions that are defined in a namespace excluding member + // function, static methods (qualified by nested specifier), and functions + // defined in the global namespace. + // Note that the matcher does not exclude calls to out-of-line static method + // definitions, so we need to exclude them in the callback handler. + auto FuncMatcher = + functionDecl(unless(anyOf(cxxMethodDecl(), IsInMovedNs, + hasAncestor(namespaceDecl(isAnonymous())), + hasAncestor(cxxRecordDecl()))), + hasParent(namespaceDecl())); + Finder->addMatcher(expr(hasAncestor(decl().bind("dc")), IsInMovedNs, + unless(hasAncestor(isImplicit())), + anyOf(callExpr(callee(FuncMatcher)).bind("call"), + declRefExpr(to(FuncMatcher.bind("func_decl"))) + .bind("func_ref"))), + this); + + auto GlobalVarMatcher = varDecl( + hasGlobalStorage(), hasParent(namespaceDecl()), + unless(anyOf(IsInMovedNs, hasAncestor(namespaceDecl(isAnonymous()))))); + Finder->addMatcher(declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")), + to(GlobalVarMatcher.bind("var_decl"))) + .bind("var_ref"), + this); + + // Handle unscoped enum constant. + auto UnscopedEnumMatcher = enumConstantDecl(hasParent(enumDecl( + hasParent(namespaceDecl()), + unless(anyOf(isScoped(), IsInMovedNs, hasAncestor(cxxRecordDecl()), + hasAncestor(namespaceDecl(isAnonymous()))))))); + Finder->addMatcher( + declRefExpr(IsInMovedNs, hasAncestor(decl().bind("dc")), + to(UnscopedEnumMatcher.bind("enum_const_decl"))) + .bind("enum_const_ref"), + this); +} + +void ChangeNamespaceTool::run( + const ast_matchers::MatchFinder::MatchResult &Result) { + if (const auto *Using = Result.Nodes.getNodeAs("using")) { + UsingDecls.insert(Using); + } else if (const auto *UsingNamespace = + Result.Nodes.getNodeAs( + "using_namespace")) { + UsingNamespaceDecls.insert(UsingNamespace); + } else if (const auto *NamespaceAlias = + Result.Nodes.getNodeAs( + "namespace_alias")) { + NamespaceAliasDecls.insert(NamespaceAlias); + } else if (const auto *NsDecl = + Result.Nodes.getNodeAs("old_ns")) { + moveOldNamespace(Result, NsDecl); + } else if (const auto *FwdDecl = + Result.Nodes.getNodeAs("class_fwd_decl")) { + moveClassForwardDeclaration(Result, cast(FwdDecl)); + } else if (const auto *TemplateFwdDecl = + Result.Nodes.getNodeAs( + "template_class_fwd_decl")) { + moveClassForwardDeclaration(Result, cast(TemplateFwdDecl)); + } else if (const auto *UsingWithShadow = + Result.Nodes.getNodeAs("using_with_shadow")) { + fixUsingShadowDecl(Result, UsingWithShadow); + } else if (const auto *Specifier = + Result.Nodes.getNodeAs( + "nested_specifier_loc")) { + SourceLocation Start = Specifier->getBeginLoc(); + SourceLocation End = endLocationForType(Specifier->getTypeLoc()); + fixTypeLoc(Result, Start, End, Specifier->getTypeLoc()); + } else if (const auto *BaseInitializer = + Result.Nodes.getNodeAs( + "base_initializer")) { + BaseCtorInitializerTypeLocs.push_back( + BaseInitializer->getTypeSourceInfo()->getTypeLoc()); + } else if (const auto *TLoc = Result.Nodes.getNodeAs("type")) { + // This avoids fixing types with record types as qualifier, which is not + // filtered by matchers in some cases, e.g. the type is templated. We should + // handle the record type qualifier instead. + TypeLoc Loc = *TLoc; + while (Loc.getTypeLocClass() == TypeLoc::Qualified) + Loc = Loc.getNextTypeLoc(); + if (Loc.getTypeLocClass() == TypeLoc::Elaborated) { + NestedNameSpecifierLoc NestedNameSpecifier = + Loc.castAs().getQualifierLoc(); + // This happens for friend declaration of a base class with injected class + // name. + if (!NestedNameSpecifier.getNestedNameSpecifier()) + return; + const Type *SpecifierType = + NestedNameSpecifier.getNestedNameSpecifier()->getAsType(); + if (SpecifierType && SpecifierType->isRecordType()) + return; + } + fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc); + } else if (const auto *VarRef = + Result.Nodes.getNodeAs("var_ref")) { + const auto *Var = Result.Nodes.getNodeAs("var_decl"); + assert(Var); + if (Var->getCanonicalDecl()->isStaticDataMember()) + return; + const auto *Context = Result.Nodes.getNodeAs("dc"); + assert(Context && "Empty decl context."); + fixDeclRefExpr(Result, Context->getDeclContext(), + llvm::cast(Var), VarRef); + } else if (const auto *EnumConstRef = + Result.Nodes.getNodeAs("enum_const_ref")) { + // Do not rename the reference if it is already scoped by the EnumDecl name. + if (EnumConstRef->hasQualifier() && + EnumConstRef->getQualifier()->getKind() == + NestedNameSpecifier::SpecifierKind::TypeSpec && + EnumConstRef->getQualifier()->getAsType()->isEnumeralType()) + return; + const auto *EnumConstDecl = + Result.Nodes.getNodeAs("enum_const_decl"); + assert(EnumConstDecl); + const auto *Context = Result.Nodes.getNodeAs("dc"); + assert(Context && "Empty decl context."); + // FIXME: this would qualify "ns::VALUE" as "ns::EnumValue::VALUE". Fix it + // if it turns out to be an issue. + fixDeclRefExpr(Result, Context->getDeclContext(), + llvm::cast(EnumConstDecl), EnumConstRef); + } else if (const auto *FuncRef = + Result.Nodes.getNodeAs("func_ref")) { + // If this reference has been processed as a function call, we do not + // process it again. + if (ProcessedFuncRefs.count(FuncRef)) + return; + ProcessedFuncRefs.insert(FuncRef); + const auto *Func = Result.Nodes.getNodeAs("func_decl"); + assert(Func); + const auto *Context = Result.Nodes.getNodeAs("dc"); + assert(Context && "Empty decl context."); + fixDeclRefExpr(Result, Context->getDeclContext(), + llvm::cast(Func), FuncRef); + } else { + const auto *Call = Result.Nodes.getNodeAs("call"); + assert(Call != nullptr && "Expecting callback for CallExpr."); + const auto *CalleeFuncRef = + llvm::cast(Call->getCallee()->IgnoreImplicit()); + ProcessedFuncRefs.insert(CalleeFuncRef); + const FunctionDecl *Func = Call->getDirectCallee(); + assert(Func != nullptr); + // FIXME: ignore overloaded operators. This would miss cases where operators + // are called by qualified names (i.e. "ns::operator <"). Ignore such + // cases for now. + if (Func->isOverloadedOperator()) + return; + // Ignore out-of-line static methods since they will be handled by nested + // name specifiers. + if (Func->getCanonicalDecl()->getStorageClass() == + StorageClass::SC_Static && + Func->isOutOfLine()) + return; + const auto *Context = Result.Nodes.getNodeAs("dc"); + assert(Context && "Empty decl context."); + SourceRange CalleeRange = Call->getCallee()->getSourceRange(); + replaceQualifiedSymbolInDeclContext( + Result, Context->getDeclContext(), CalleeRange.getBegin(), + CalleeRange.getEnd(), llvm::cast(Func)); + } +} + +static SourceLocation getLocAfterNamespaceLBrace(const NamespaceDecl *NsDecl, + const SourceManager &SM, + const LangOptions &LangOpts) { + std::unique_ptr Lex = + getLexerStartingFromLoc(NsDecl->getBeginLoc(), SM, LangOpts); + assert(Lex.get() && + "Failed to create lexer from the beginning of namespace."); + if (!Lex.get()) + return SourceLocation(); + Token Tok; + while (!Lex->LexFromRawLexer(Tok) && Tok.isNot(tok::TokenKind::l_brace)) { + } + return Tok.isNot(tok::TokenKind::l_brace) + ? SourceLocation() + : Tok.getEndLoc().getLocWithOffset(1); +} + +// Stores information about a moved namespace in `MoveNamespaces` and leaves +// the actual movement to `onEndOfTranslationUnit()`. +void ChangeNamespaceTool::moveOldNamespace( + const ast_matchers::MatchFinder::MatchResult &Result, + const NamespaceDecl *NsDecl) { + // If the namespace is empty, do nothing. + if (Decl::castToDeclContext(NsDecl)->decls_empty()) + return; + + const SourceManager &SM = *Result.SourceManager; + // Get the range of the code in the old namespace. + SourceLocation Start = + getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts()); + assert(Start.isValid() && "Can't find l_brace for namespace."); + MoveNamespace MoveNs; + MoveNs.Offset = SM.getFileOffset(Start); + // The range of the moved namespace is from the location just past the left + // brace to the location right before the right brace. + MoveNs.Length = SM.getFileOffset(NsDecl->getRBraceLoc()) - MoveNs.Offset; + + // Insert the new namespace after `DiffOldNamespace`. For example, if + // `OldNamespace` is "a::b::c" and `NewNamespace` is `a::x::y`, then + // "x::y" will be inserted inside the existing namespace "a" and after "a::b". + // `OuterNs` is the first namespace in `DiffOldNamespace`, e.g. "namespace b" + // in the above example. + // If there is no outer namespace (i.e. DiffOldNamespace is empty), the new + // namespace will be a nested namespace in the old namespace. + const NamespaceDecl *OuterNs = getOuterNamespace(NsDecl, DiffOldNamespace); + SourceLocation InsertionLoc = Start; + if (OuterNs) { + SourceLocation LocAfterNs = getStartOfNextLine( + OuterNs->getRBraceLoc(), SM, Result.Context->getLangOpts()); + assert(LocAfterNs.isValid() && + "Failed to get location after DiffOldNamespace"); + InsertionLoc = LocAfterNs; + } + MoveNs.InsertionOffset = SM.getFileOffset(SM.getSpellingLoc(InsertionLoc)); + MoveNs.FID = SM.getFileID(Start); + MoveNs.SourceMgr = Result.SourceManager; + MoveNamespaces[SM.getFilename(Start)].push_back(MoveNs); +} + +// Removes a class forward declaration from the code in the moved namespace and +// creates an `InsertForwardDeclaration` to insert the forward declaration back +// into the old namespace after moving code from the old namespace to the new +// namespace. +// For example, changing "a" to "x": +// Old code: +// namespace a { +// class FWD; +// class A { FWD *fwd; } +// } // a +// New code: +// namespace a { +// class FWD; +// } // a +// namespace x { +// class A { a::FWD *fwd; } +// } // x +void ChangeNamespaceTool::moveClassForwardDeclaration( + const ast_matchers::MatchFinder::MatchResult &Result, + const NamedDecl *FwdDecl) { + SourceLocation Start = FwdDecl->getBeginLoc(); + SourceLocation End = FwdDecl->getEndLoc(); + const SourceManager &SM = *Result.SourceManager; + SourceLocation AfterSemi = Lexer::findLocationAfterToken( + End, tok::semi, SM, Result.Context->getLangOpts(), + /*SkipTrailingWhitespaceAndNewLine=*/true); + if (AfterSemi.isValid()) + End = AfterSemi.getLocWithOffset(-1); + // Delete the forward declaration from the code to be moved. + addReplacementOrDie(Start, End, "", SM, &FileToReplacements); + llvm::StringRef Code = Lexer::getSourceText( + CharSourceRange::getTokenRange(SM.getSpellingLoc(Start), + SM.getSpellingLoc(End)), + SM, Result.Context->getLangOpts()); + // Insert the forward declaration back into the old namespace after moving the + // code from old namespace to new namespace. + // Insertion information is stored in `InsertFwdDecls` and actual + // insertion will be performed in `onEndOfTranslationUnit`. + // Get the (old) namespace that contains the forward declaration. + const auto *NsDecl = Result.Nodes.getNodeAs("ns_decl"); + // The namespace contains the forward declaration, so it must not be empty. + assert(!NsDecl->decls_empty()); + const auto Insertion = createInsertion( + getLocAfterNamespaceLBrace(NsDecl, SM, Result.Context->getLangOpts()), + Code, SM); + InsertForwardDeclaration InsertFwd; + InsertFwd.InsertionOffset = Insertion.getOffset(); + InsertFwd.ForwardDeclText = Insertion.getReplacementText().str(); + InsertFwdDecls[Insertion.getFilePath()].push_back(InsertFwd); +} + +// Replaces a qualified symbol (in \p DeclCtx) that refers to a declaration \p +// FromDecl with the shortest qualified name possible when the reference is in +// `NewNamespace`. +void ChangeNamespaceTool::replaceQualifiedSymbolInDeclContext( + const ast_matchers::MatchFinder::MatchResult &Result, + const DeclContext *DeclCtx, SourceLocation Start, SourceLocation End, + const NamedDecl *FromDecl) { + const auto *NsDeclContext = DeclCtx->getEnclosingNamespaceContext(); + if (llvm::isa(NsDeclContext)) { + // This should not happen in usual unless the TypeLoc is in function type + // parameters, e.g `std::function`. In this case, DeclContext of + // `T` will be the translation unit. We simply use fully-qualified name + // here. + // Note that `FromDecl` must not be defined in the old namespace (according + // to `DeclMatcher`), so its fully-qualified name will not change after + // changing the namespace. + addReplacementOrDie(Start, End, FromDecl->getQualifiedNameAsString(), + *Result.SourceManager, &FileToReplacements); + return; + } + const auto *NsDecl = llvm::cast(NsDeclContext); + // Calculate the name of the `NsDecl` after it is moved to new namespace. + std::string OldNs = NsDecl->getQualifiedNameAsString(); + llvm::StringRef Postfix = OldNs; + bool Consumed = Postfix.consume_front(OldNamespace); + assert(Consumed && "Expect OldNS to start with OldNamespace."); + (void)Consumed; + const std::string NewNs = (NewNamespace + Postfix).str(); + + llvm::StringRef NestedName = Lexer::getSourceText( + CharSourceRange::getTokenRange( + Result.SourceManager->getSpellingLoc(Start), + Result.SourceManager->getSpellingLoc(End)), + *Result.SourceManager, Result.Context->getLangOpts()); + std::string FromDeclName = FromDecl->getQualifiedNameAsString(); + for (llvm::Regex &RE : WhiteListedSymbolRegexes) + if (RE.match(FromDeclName)) + return; + std::string ReplaceName = + getShortestQualifiedNameInNamespace(FromDeclName, NewNs); + // Checks if there is any using namespace declarations that can shorten the + // qualified name. + for (const auto *UsingNamespace : UsingNamespaceDecls) { + if (!isDeclVisibleAtLocation(*Result.SourceManager, UsingNamespace, DeclCtx, + Start)) + continue; + StringRef FromDeclNameRef = FromDeclName; + if (FromDeclNameRef.consume_front(UsingNamespace->getNominatedNamespace() + ->getQualifiedNameAsString())) { + FromDeclNameRef = FromDeclNameRef.drop_front(2); + if (FromDeclNameRef.size() < ReplaceName.size()) + ReplaceName = FromDeclNameRef; + } + } + // Checks if there is any namespace alias declarations that can shorten the + // qualified name. + for (const auto *NamespaceAlias : NamespaceAliasDecls) { + if (!isDeclVisibleAtLocation(*Result.SourceManager, NamespaceAlias, DeclCtx, + Start)) + continue; + StringRef FromDeclNameRef = FromDeclName; + if (FromDeclNameRef.consume_front( + NamespaceAlias->getNamespace()->getQualifiedNameAsString() + + "::")) { + std::string AliasName = NamespaceAlias->getNameAsString(); + std::string AliasQualifiedName = + NamespaceAlias->getQualifiedNameAsString(); + // We only consider namespace aliases define in the global namepspace or + // in namespaces that are directly visible from the reference, i.e. + // ancestor of the `OldNs`. Note that declarations in ancestor namespaces + // but not visible in the new namespace is filtered out by + // "IsVisibleInNewNs" matcher. + if (AliasQualifiedName != AliasName) { + // The alias is defined in some namespace. + assert(StringRef(AliasQualifiedName).endswith("::" + AliasName)); + llvm::StringRef AliasNs = + StringRef(AliasQualifiedName).drop_back(AliasName.size() + 2); + if (!llvm::StringRef(OldNs).startswith(AliasNs)) + continue; + } + std::string NameWithAliasNamespace = + (AliasName + "::" + FromDeclNameRef).str(); + if (NameWithAliasNamespace.size() < ReplaceName.size()) + ReplaceName = NameWithAliasNamespace; + } + } + // Checks if there is any using shadow declarations that can shorten the + // qualified name. + bool Matched = false; + for (const UsingDecl *Using : UsingDecls) { + if (Matched) + break; + if (isDeclVisibleAtLocation(*Result.SourceManager, Using, DeclCtx, Start)) { + for (const auto *UsingShadow : Using->shadows()) { + const auto *TargetDecl = UsingShadow->getTargetDecl(); + if (TargetDecl->getQualifiedNameAsString() == + FromDecl->getQualifiedNameAsString()) { + ReplaceName = FromDecl->getNameAsString(); + Matched = true; + break; + } + } + } + } + bool Conflict = conflictInNamespace(DeclCtx->getParentASTContext(), + ReplaceName, NewNamespace); + // If the new nested name in the new namespace is the same as it was in the + // old namespace, we don't create replacement unless there can be ambiguity. + if ((NestedName == ReplaceName && !Conflict) || + (NestedName.startswith("::") && NestedName.drop_front(2) == ReplaceName)) + return; + // If the reference need to be fully-qualified, add a leading "::" unless + // NewNamespace is the global namespace. + if (ReplaceName == FromDeclName && !NewNamespace.empty() && Conflict) + ReplaceName = "::" + ReplaceName; + addReplacementOrDie(Start, End, ReplaceName, *Result.SourceManager, + &FileToReplacements); +} + +// Replace the [Start, End] of `Type` with the shortest qualified name when the +// `Type` is in `NewNamespace`. +void ChangeNamespaceTool::fixTypeLoc( + const ast_matchers::MatchFinder::MatchResult &Result, SourceLocation Start, + SourceLocation End, TypeLoc Type) { + // FIXME: do not rename template parameter. + if (Start.isInvalid() || End.isInvalid()) + return; + // Types of CXXCtorInitializers do not need to be fixed. + if (llvm::is_contained(BaseCtorInitializerTypeLocs, Type)) + return; + if (isTemplateParameter(Type)) + return; + // The declaration which this TypeLoc refers to. + const auto *FromDecl = Result.Nodes.getNodeAs("from_decl"); + // `hasDeclaration` gives underlying declaration, but if the type is + // a typedef type, we need to use the typedef type instead. + auto IsInMovedNs = [&](const NamedDecl *D) { + if (!llvm::StringRef(D->getQualifiedNameAsString()) + .startswith(OldNamespace + "::")) + return false; + auto ExpansionLoc = Result.SourceManager->getExpansionLoc(D->getBeginLoc()); + if (ExpansionLoc.isInvalid()) + return false; + llvm::StringRef Filename = Result.SourceManager->getFilename(ExpansionLoc); + return FilePatternRE.match(Filename); + }; + // Make `FromDecl` the immediate declaration that `Type` refers to, i.e. if + // `Type` is an alias type, we make `FromDecl` the type alias declaration. + // Also, don't fix the \p Type if it refers to a type alias decl in the moved + // namespace since the alias decl will be moved along with the type reference. + if (auto *Typedef = Type.getType()->getAs()) { + FromDecl = Typedef->getDecl(); + if (IsInMovedNs(FromDecl)) + return; + } else if (auto *TemplateType = + Type.getType()->getAs()) { + if (TemplateType->isTypeAlias()) { + FromDecl = TemplateType->getTemplateName().getAsTemplateDecl(); + if (IsInMovedNs(FromDecl)) + return; + } + } + const auto *DeclCtx = Result.Nodes.getNodeAs("dc"); + assert(DeclCtx && "Empty decl context."); + replaceQualifiedSymbolInDeclContext(Result, DeclCtx->getDeclContext(), Start, + End, FromDecl); +} + +void ChangeNamespaceTool::fixUsingShadowDecl( + const ast_matchers::MatchFinder::MatchResult &Result, + const UsingDecl *UsingDeclaration) { + SourceLocation Start = UsingDeclaration->getBeginLoc(); + SourceLocation End = UsingDeclaration->getEndLoc(); + if (Start.isInvalid() || End.isInvalid()) + return; + + assert(UsingDeclaration->shadow_size() > 0); + // FIXME: it might not be always accurate to use the first using-decl. + const NamedDecl *TargetDecl = + UsingDeclaration->shadow_begin()->getTargetDecl(); + std::string TargetDeclName = TargetDecl->getQualifiedNameAsString(); + // FIXME: check if target_decl_name is in moved ns, which doesn't make much + // sense. If this happens, we need to use name with the new namespace. + // Use fully qualified name in UsingDecl for now. + addReplacementOrDie(Start, End, "using ::" + TargetDeclName, + *Result.SourceManager, &FileToReplacements); +} + +void ChangeNamespaceTool::fixDeclRefExpr( + const ast_matchers::MatchFinder::MatchResult &Result, + const DeclContext *UseContext, const NamedDecl *From, + const DeclRefExpr *Ref) { + SourceRange RefRange = Ref->getSourceRange(); + replaceQualifiedSymbolInDeclContext(Result, UseContext, RefRange.getBegin(), + RefRange.getEnd(), From); +} + +void ChangeNamespaceTool::onEndOfTranslationUnit() { + // Move namespace blocks and insert forward declaration to old namespace. + for (const auto &FileAndNsMoves : MoveNamespaces) { + auto &NsMoves = FileAndNsMoves.second; + if (NsMoves.empty()) + continue; + const std::string &FilePath = FileAndNsMoves.first; + auto &Replaces = FileToReplacements[FilePath]; + auto &SM = *NsMoves.begin()->SourceMgr; + llvm::StringRef Code = SM.getBufferData(NsMoves.begin()->FID); + auto ChangedCode = tooling::applyAllReplacements(Code, Replaces); + if (!ChangedCode) { + llvm::errs() << llvm::toString(ChangedCode.takeError()) << "\n"; + continue; + } + // Replacements on the changed code for moving namespaces and inserting + // forward declarations to old namespaces. + tooling::Replacements NewReplacements; + // Cut the changed code from the old namespace and paste the code in the new + // namespace. + for (const auto &NsMove : NsMoves) { + // Calculate the range of the old namespace block in the changed + // code. + const unsigned NewOffset = Replaces.getShiftedCodePosition(NsMove.Offset); + const unsigned NewLength = + Replaces.getShiftedCodePosition(NsMove.Offset + NsMove.Length) - + NewOffset; + tooling::Replacement Deletion(FilePath, NewOffset, NewLength, ""); + std::string MovedCode = ChangedCode->substr(NewOffset, NewLength); + std::string MovedCodeWrappedInNewNs = + wrapCodeInNamespace(DiffNewNamespace, MovedCode); + // Calculate the new offset at which the code will be inserted in the + // changed code. + unsigned NewInsertionOffset = + Replaces.getShiftedCodePosition(NsMove.InsertionOffset); + tooling::Replacement Insertion(FilePath, NewInsertionOffset, 0, + MovedCodeWrappedInNewNs); + addOrMergeReplacement(Deletion, &NewReplacements); + addOrMergeReplacement(Insertion, &NewReplacements); + } + // After moving namespaces, insert forward declarations back to old + // namespaces. + const auto &FwdDeclInsertions = InsertFwdDecls[FilePath]; + for (const auto &FwdDeclInsertion : FwdDeclInsertions) { + unsigned NewInsertionOffset = + Replaces.getShiftedCodePosition(FwdDeclInsertion.InsertionOffset); + tooling::Replacement Insertion(FilePath, NewInsertionOffset, 0, + FwdDeclInsertion.ForwardDeclText); + addOrMergeReplacement(Insertion, &NewReplacements); + } + // Add replacements referring to the changed code to existing replacements, + // which refers to the original code. + Replaces = Replaces.merge(NewReplacements); + auto Style = + format::getStyle(format::DefaultFormatStyle, FilePath, FallbackStyle); + if (!Style) { + llvm::errs() << llvm::toString(Style.takeError()) << "\n"; + continue; + } + // Clean up old namespaces if there is nothing in it after moving. + auto CleanReplacements = + format::cleanupAroundReplacements(Code, Replaces, *Style); + if (!CleanReplacements) { + llvm::errs() << llvm::toString(CleanReplacements.takeError()) << "\n"; + continue; + } + FileToReplacements[FilePath] = *CleanReplacements; + } + + // Make sure we don't generate replacements for files that do not match + // FilePattern. + for (auto &Entry : FileToReplacements) + if (!FilePatternRE.match(Entry.first)) + Entry.second.clear(); +} + +} // namespace change_namespace +} // namespace clang diff --git a/clang-change-namespace/ChangeNamespace.h b/clang-change-namespace/ChangeNamespace.h new file mode 100644 index 00000000..293d5ce8 --- /dev/null +++ b/clang-change-namespace/ChangeNamespace.h @@ -0,0 +1,175 @@ +//===-- ChangeNamespace.h -- Change namespace ------------------*- 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_TOOLS_EXTRA_CHANGE_NAMESPACE_CHANGENAMESPACE_H +#define LLVM_CLANG_TOOLS_EXTRA_CHANGE_NAMESPACE_CHANGENAMESPACE_H + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Format/Format.h" +#include "clang/Tooling/Core/Replacement.h" +#include "llvm/Support/Regex.h" +#include + +namespace clang { +namespace change_namespace { + +// This tool can be used to change the surrounding namespaces of class/function +// definitions. Classes/functions in the moved namespace will have new +// namespaces while references to symbols (e.g. types, functions) which are not +// defined in the changed namespace will be correctly qualified by prepending +// namespace specifiers before them. +// This will try to add shortest namespace specifiers possible. When a symbol +// reference needs to be fully-qualified, this adds a "::" prefix to the +// namespace specifiers unless the new namespace is the global namespace. +// For classes, only classes that are declared/defined in the given namespace in +// speficifed files will be moved: forward declarations will remain in the old +// namespace. +// For example, changing "a" to "x": +// Old code: +// namespace a { +// class FWD; +// class A { FWD *fwd; } +// } // a +// New code: +// namespace a { +// class FWD; +// } // a +// namespace x { +// class A { ::a::FWD *fwd; } +// } // x +// FIXME: support moving typedef, enums across namespaces. +class ChangeNamespaceTool : public ast_matchers::MatchFinder::MatchCallback { +public: + // Moves code in the old namespace `OldNs` to the new namespace `NewNs` in + // files matching `FilePattern`. + ChangeNamespaceTool( + llvm::StringRef OldNs, llvm::StringRef NewNs, llvm::StringRef FilePattern, + llvm::ArrayRef WhiteListedSymbolPatterns, + std::map *FileToReplacements, + llvm::StringRef FallbackStyle = "LLVM"); + + void registerMatchers(ast_matchers::MatchFinder *Finder); + + void run(const ast_matchers::MatchFinder::MatchResult &Result) override; + + // Moves the changed code in old namespaces but leaves class forward + // declarations behind. + void onEndOfTranslationUnit() override; + +private: + void moveOldNamespace(const ast_matchers::MatchFinder::MatchResult &Result, + const NamespaceDecl *NsDecl); + + void moveClassForwardDeclaration( + const ast_matchers::MatchFinder::MatchResult &Result, + const NamedDecl *FwdDecl); + + void replaceQualifiedSymbolInDeclContext( + const ast_matchers::MatchFinder::MatchResult &Result, + const DeclContext *DeclContext, SourceLocation Start, SourceLocation End, + const NamedDecl *FromDecl); + + void fixTypeLoc(const ast_matchers::MatchFinder::MatchResult &Result, + SourceLocation Start, SourceLocation End, TypeLoc Type); + + void fixUsingShadowDecl(const ast_matchers::MatchFinder::MatchResult &Result, + const UsingDecl *UsingDeclaration); + + void fixDeclRefExpr(const ast_matchers::MatchFinder::MatchResult &Result, + const DeclContext *UseContext, const NamedDecl *From, + const DeclRefExpr *Ref); + + // Information about moving an old namespace. + struct MoveNamespace { + // The start offset of the namespace block being moved in the original + // code. + unsigned Offset; + // The length of the namespace block in the original code. + unsigned Length; + // The offset at which the new namespace block will be inserted in the + // original code. + unsigned InsertionOffset; + // The file in which the namespace is declared. + FileID FID; + SourceManager *SourceMgr; + }; + + // Information about inserting a class forward declaration. + struct InsertForwardDeclaration { + // The offset at while the forward declaration will be inserted in the + // original code. + unsigned InsertionOffset; + // The code to be inserted. + std::string ForwardDeclText; + }; + + std::string FallbackStyle; + // In match callbacks, this contains replacements for replacing `typeLoc`s in + // and deleting forward declarations in the moved namespace blocks. + // In `onEndOfTranslationUnit` callback, the previous added replacements are + // applied (on the moved namespace blocks), and then changed code in old + // namespaces re moved to new namespaces, and previously deleted forward + // declarations are inserted back to old namespaces, from which they are + // deleted. + std::map &FileToReplacements; + // A fully qualified name of the old namespace without "::" prefix, e.g. + // "a::b::c". + std::string OldNamespace; + // A fully qualified name of the new namespace without "::" prefix, e.g. + // "x::y::z". + std::string NewNamespace; + // The longest suffix in the old namespace that does not overlap the new + // namespace. + // For example, if `OldNamespace` is "a::b::c" and `NewNamespace` is + // "a::x::y", then `DiffOldNamespace` will be "b::c". + std::string DiffOldNamespace; + // The longest suffix in the new namespace that does not overlap the old + // namespace. + // For example, if `OldNamespace` is "a::b::c" and `NewNamespace` is + // "a::x::y", then `DiffNewNamespace` will be "x::y". + std::string DiffNewNamespace; + // A regex pattern that matches files to be processed. + std::string FilePattern; + llvm::Regex FilePatternRE; + // Information about moved namespaces grouped by file. + // Since we are modifying code in old namespaces (e.g. add namespace + // spedifiers) as well as moving them, we store information about namespaces + // to be moved and only move them after all modifications are finished (i.e. + // in `onEndOfTranslationUnit`). + std::map> MoveNamespaces; + // Information about forward declaration insertions grouped by files. + // A class forward declaration is not moved, so it will be deleted from the + // moved code block and inserted back into the old namespace. The insertion + // will be done after removing the code from the old namespace and before + // inserting it to the new namespace. + std::map> InsertFwdDecls; + // Records all using declarations, which can be used to shorten namespace + // specifiers. + llvm::SmallPtrSet UsingDecls; + // Records all using namespace declarations, which can be used to shorten + // namespace specifiers. + llvm::SmallPtrSet UsingNamespaceDecls; + // Records all namespace alias declarations, which can be used to shorten + // namespace specifiers. + llvm::SmallPtrSet NamespaceAliasDecls; + // TypeLocs of CXXCtorInitializer. Types of CXXCtorInitializers do not need to + // be fixed. + llvm::SmallVector BaseCtorInitializerTypeLocs; + // Since a DeclRefExpr for a function call can be matched twice (one as + // CallExpr and one as DeclRefExpr), we record all DeclRefExpr's that have + // been processed so that we don't handle them twice. + llvm::SmallPtrSet ProcessedFuncRefs; + // Patterns of symbol names whose references are not expected to be updated + // when changing namespaces around them. + std::vector WhiteListedSymbolRegexes; +}; + +} // namespace change_namespace +} // namespace clang + +#endif // LLVM_CLANG_TOOLS_EXTRA_CHANGE_NAMESPACE_CHANGENAMESPACE_H diff --git a/clang-change-namespace/tool/CMakeLists.txt b/clang-change-namespace/tool/CMakeLists.txt new file mode 100644 index 00000000..be4b830e --- /dev/null +++ b/clang-change-namespace/tool/CMakeLists.txt @@ -0,0 +1,25 @@ +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/..) + +set(LLVM_LINK_COMPONENTS + Support + ) + +add_clang_executable(clang-change-namespace + ClangChangeNamespace.cpp + ) +target_link_libraries(clang-change-namespace + PRIVATE + clangAST + clangASTMatchers + clangBasic + clangChangeNamespace + clangFormat + clangFrontend + clangRewrite + clangSerialization + clangTooling + clangToolingCore + ) + +install(TARGETS clang-change-namespace + RUNTIME DESTINATION bin) diff --git a/clang-change-namespace/tool/ClangChangeNamespace.cpp b/clang-change-namespace/tool/ClangChangeNamespace.cpp new file mode 100644 index 00000000..d5f06552 --- /dev/null +++ b/clang-change-namespace/tool/ClangChangeNamespace.cpp @@ -0,0 +1,177 @@ +//===-- ClangChangeNamespace.cpp - Standalone change namespace ------------===// +// +// 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 tool can be used to change the surrounding namespaces of class/function +// definitions. +// +// Example: test.cc +// namespace na { +// class X {}; +// namespace nb { +// class Y { X x; }; +// } // namespace nb +// } // namespace na +// To move the definition of class Y from namespace "na::nb" to "x::y", run: +// clang-change-namespace --old_namespace "na::nb" \ +// --new_namespace "x::y" --file_pattern "test.cc" test.cc -- +// Output: +// namespace na { +// class X {}; +// } // namespace na +// namespace x { +// namespace y { +// class Y { na::X x; }; +// } // namespace y +// } // namespace x + +#include "ChangeNamespace.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Frontend/TextDiagnosticPrinter.h" +#include "clang/Rewrite/Core/Rewriter.h" +#include "clang/Tooling/CommonOptionsParser.h" +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/YAMLTraits.h" + +using namespace clang; +using namespace llvm; + +namespace { + +cl::OptionCategory ChangeNamespaceCategory("Change namespace."); + +cl::opt OldNamespace("old_namespace", cl::Required, + cl::desc("Old namespace."), + cl::cat(ChangeNamespaceCategory)); + +cl::opt NewNamespace("new_namespace", cl::Required, + cl::desc("New namespace."), + cl::cat(ChangeNamespaceCategory)); + +cl::opt FilePattern( + "file_pattern", cl::Required, + cl::desc("Only rename namespaces in files that match the given pattern."), + cl::cat(ChangeNamespaceCategory)); + +cl::opt Inplace("i", cl::desc("Inplace edit s, if specified."), + cl::cat(ChangeNamespaceCategory)); + +cl::opt + DumpYAML("dump_result", + cl::desc("Dump new file contents in YAML, if specified."), + cl::cat(ChangeNamespaceCategory)); + +cl::opt Style("style", + cl::desc("The style name used for reformatting."), + cl::init("LLVM"), cl::cat(ChangeNamespaceCategory)); + +cl::opt WhiteListFile( + "whitelist_file", + cl::desc("A file containing regexes of symbol names that are not expected " + "to be updated when changing namespaces around them."), + cl::init(""), cl::cat(ChangeNamespaceCategory)); + +llvm::ErrorOr> GetWhiteListedSymbolPatterns() { + std::vector Patterns; + if (WhiteListFile.empty()) + return Patterns; + + llvm::SmallVector Lines; + llvm::ErrorOr> File = + llvm::MemoryBuffer::getFile(WhiteListFile); + if (!File) + return File.getError(); + llvm::StringRef Content = File.get()->getBuffer(); + Content.split(Lines, '\n', /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (auto Line : Lines) + Patterns.push_back(Line.trim()); + return Patterns; +} + +} // anonymous namespace + +int main(int argc, const char **argv) { + llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); + tooling::CommonOptionsParser OptionsParser(argc, argv, + ChangeNamespaceCategory); + const auto &Files = OptionsParser.getSourcePathList(); + tooling::RefactoringTool Tool(OptionsParser.getCompilations(), Files); + llvm::ErrorOr> WhiteListPatterns = + GetWhiteListedSymbolPatterns(); + if (!WhiteListPatterns) { + llvm::errs() << "Failed to open whitelist file " << WhiteListFile << ". " + << WhiteListPatterns.getError().message() << "\n"; + return 1; + } + change_namespace::ChangeNamespaceTool NamespaceTool( + OldNamespace, NewNamespace, FilePattern, *WhiteListPatterns, + &Tool.getReplacements(), Style); + ast_matchers::MatchFinder Finder; + NamespaceTool.registerMatchers(&Finder); + std::unique_ptr Factory = + tooling::newFrontendActionFactory(&Finder); + + if (int Result = Tool.run(Factory.get())) + return Result; + LangOptions DefaultLangOptions; + IntrusiveRefCntPtr DiagOpts = new DiagnosticOptions(); + clang::TextDiagnosticPrinter DiagnosticPrinter(errs(), &*DiagOpts); + DiagnosticsEngine Diagnostics( + IntrusiveRefCntPtr(new DiagnosticIDs()), &*DiagOpts, + &DiagnosticPrinter, false); + auto &FileMgr = Tool.getFiles(); + SourceManager Sources(Diagnostics, FileMgr); + Rewriter Rewrite(Sources, DefaultLangOptions); + + if (!formatAndApplyAllReplacements(Tool.getReplacements(), Rewrite, Style)) { + llvm::errs() << "Failed applying all replacements.\n"; + return 1; + } + if (Inplace) + return Rewrite.overwriteChangedFiles(); + + std::set ChangedFiles; + for (const auto &it : Tool.getReplacements()) + ChangedFiles.insert(it.first); + + if (DumpYAML) { + auto WriteToYAML = [&](llvm::raw_ostream &OS) { + OS << "[\n"; + for (auto I = ChangedFiles.begin(), E = ChangedFiles.end(); I != E; ++I) { + OS << " {\n"; + OS << " \"FilePath\": \"" << *I << "\",\n"; + const auto *Entry = FileMgr.getFile(*I); + auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User); + std::string Content; + llvm::raw_string_ostream ContentStream(Content); + Rewrite.getEditBuffer(ID).write(ContentStream); + OS << " \"SourceText\": \"" + << llvm::yaml::escape(ContentStream.str()) << "\"\n"; + OS << " }"; + if (I != std::prev(E)) + OS << ",\n"; + } + OS << "\n]\n"; + }; + WriteToYAML(llvm::outs()); + return 0; + } + + for (const auto &File : ChangedFiles) { + const auto *Entry = FileMgr.getFile(File); + + auto ID = Sources.getOrCreateFileID(Entry, SrcMgr::C_User); + outs() << "============== " << File << " ==============\n"; + Rewrite.getEditBuffer(ID).write(llvm::outs()); + outs() << "\n============================================\n"; + } + + return 0; +} diff --git a/test/change-namespace/Inputs/fake-std.h b/test/change-namespace/Inputs/fake-std.h deleted file mode 100644 index 24d3f977..00000000 --- a/test/change-namespace/Inputs/fake-std.h +++ /dev/null @@ -1,5 +0,0 @@ -namespace std { - class STD {}; -} - -using namespace std; diff --git a/test/change-namespace/lambda-function.cpp b/test/change-namespace/lambda-function.cpp deleted file mode 100644 index 452983ea..00000000 --- a/test/change-namespace/lambda-function.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- -std=c++11 | sed 's,// CHECK.*,,' | FileCheck %s - -template -class function; -template -class function { -public: - template - function(Functor f) {} - R operator()(ArgTypes...) const {} -}; - -namespace x { -// CHECK: namespace x { -class X {}; -} - -namespace na { -namespace nb { -// CHECK: namespace x { -// CHECK-NEXT: namespace y { -void f(function func, int param) { func(param); } -void g() { f([](int x) {}, 1); } - -// x::X in function type parameter list will have translation unit context, so -// we simply replace it with fully-qualified name. -using TX = function; -// CHECK: using TX = function; - -class A {}; -using TA = function; -// CHECK: using TA = function; - -// CHECK: } // namespace y -// CHECK-NEXT: } // namespace x -} -} diff --git a/test/change-namespace/macro.cpp b/test/change-namespace/macro.cpp deleted file mode 100644 index ba47de60..00000000 --- a/test/change-namespace/macro.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// RUN: cp %S/macro.cpp %T/macro.cpp -// RUN: echo "#define USING using na::nc::X" > %T/macro.h -// -// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern "macro.cpp" --i %T/macro.cpp -- -// RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s -// RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-HEADER %s -// -// RUN: cp %S/macro.cpp %T/macro.cpp -// RUN: echo "#define USING using na::nc::X" > %T/macro.h -// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --i %T/macro.cpp -- -// RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s -// RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-CHANGED-HEADER %s -#include "macro.h" -namespace na { namespace nc { class X{}; } } - -namespace na { -namespace nb { -USING; -} -} -// CHECK-CC: namespace x { -// CHECK-CC: namespace y { -// CHECK-CC: USING; -// CHECK-CC: } // namespace y -// CHECK-CC: } // namespace x - -// CHECK-HEADER: #define USING using na::nc::X - -// CHECK-CHANGED-HEADER: #define USING using ::na::nc::X diff --git a/test/change-namespace/simple-move.cpp b/test/change-namespace/simple-move.cpp deleted file mode 100644 index ea3c3d33..00000000 --- a/test/change-namespace/simple-move.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- | sed 's,// CHECK.*,,' | FileCheck %s -// CHECK: namespace x { -// CHECK-NEXT: namespace y { -namespace na { -namespace nb { -class A {}; -// CHECK: } // namespace y -// CHECK-NEXT: } // namespace x -} -} diff --git a/test/change-namespace/white-list.cpp b/test/change-namespace/white-list.cpp deleted file mode 100644 index 48e3a78a..00000000 --- a/test/change-namespace/white-list.cpp +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: echo "^std::.*$" > %T/white-list.txt -// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --whitelist_file %T/white-list.txt %s -- | sed 's,// CHECK.*,,' | FileCheck %s - -#include "Inputs/fake-std.h" - -// CHECK: namespace x { -// CHECK-NEXT: namespace y { -namespace na { -namespace nb { -void f() { - std::STD x1; - STD x2; -// CHECK: {{^}} std::STD x1;{{$}} -// CHECK-NEXT: {{^}} STD x2;{{$}} -} -// CHECK: } // namespace y -// CHECK-NEXT: } // namespace x -} -} diff --git a/test/clang-change-namespace/Inputs/fake-std.h b/test/clang-change-namespace/Inputs/fake-std.h new file mode 100644 index 00000000..24d3f977 --- /dev/null +++ b/test/clang-change-namespace/Inputs/fake-std.h @@ -0,0 +1,5 @@ +namespace std { + class STD {}; +} + +using namespace std; diff --git a/test/clang-change-namespace/lambda-function.cpp b/test/clang-change-namespace/lambda-function.cpp new file mode 100644 index 00000000..452983ea --- /dev/null +++ b/test/clang-change-namespace/lambda-function.cpp @@ -0,0 +1,37 @@ +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- -std=c++11 | sed 's,// CHECK.*,,' | FileCheck %s + +template +class function; +template +class function { +public: + template + function(Functor f) {} + R operator()(ArgTypes...) const {} +}; + +namespace x { +// CHECK: namespace x { +class X {}; +} + +namespace na { +namespace nb { +// CHECK: namespace x { +// CHECK-NEXT: namespace y { +void f(function func, int param) { func(param); } +void g() { f([](int x) {}, 1); } + +// x::X in function type parameter list will have translation unit context, so +// we simply replace it with fully-qualified name. +using TX = function; +// CHECK: using TX = function; + +class A {}; +using TA = function; +// CHECK: using TA = function; + +// CHECK: } // namespace y +// CHECK-NEXT: } // namespace x +} +} diff --git a/test/clang-change-namespace/macro.cpp b/test/clang-change-namespace/macro.cpp new file mode 100644 index 00000000..ba47de60 --- /dev/null +++ b/test/clang-change-namespace/macro.cpp @@ -0,0 +1,29 @@ +// RUN: cp %S/macro.cpp %T/macro.cpp +// RUN: echo "#define USING using na::nc::X" > %T/macro.h +// +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern "macro.cpp" --i %T/macro.cpp -- +// RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s +// RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-HEADER %s +// +// RUN: cp %S/macro.cpp %T/macro.cpp +// RUN: echo "#define USING using na::nc::X" > %T/macro.h +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --i %T/macro.cpp -- +// RUN: FileCheck -input-file=%T/macro.cpp -check-prefix=CHECK-CC %s +// RUN: FileCheck -input-file=%T/macro.h -check-prefix=CHECK-CHANGED-HEADER %s +#include "macro.h" +namespace na { namespace nc { class X{}; } } + +namespace na { +namespace nb { +USING; +} +} +// CHECK-CC: namespace x { +// CHECK-CC: namespace y { +// CHECK-CC: USING; +// CHECK-CC: } // namespace y +// CHECK-CC: } // namespace x + +// CHECK-HEADER: #define USING using na::nc::X + +// CHECK-CHANGED-HEADER: #define USING using ::na::nc::X diff --git a/test/clang-change-namespace/simple-move.cpp b/test/clang-change-namespace/simple-move.cpp new file mode 100644 index 00000000..ea3c3d33 --- /dev/null +++ b/test/clang-change-namespace/simple-move.cpp @@ -0,0 +1,10 @@ +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" %s -- | sed 's,// CHECK.*,,' | FileCheck %s +// CHECK: namespace x { +// CHECK-NEXT: namespace y { +namespace na { +namespace nb { +class A {}; +// CHECK: } // namespace y +// CHECK-NEXT: } // namespace x +} +} diff --git a/test/clang-change-namespace/white-list.cpp b/test/clang-change-namespace/white-list.cpp new file mode 100644 index 00000000..48e3a78a --- /dev/null +++ b/test/clang-change-namespace/white-list.cpp @@ -0,0 +1,19 @@ +// RUN: echo "^std::.*$" > %T/white-list.txt +// RUN: clang-change-namespace -old_namespace "na::nb" -new_namespace "x::y" --file_pattern ".*" --whitelist_file %T/white-list.txt %s -- | sed 's,// CHECK.*,,' | FileCheck %s + +#include "Inputs/fake-std.h" + +// CHECK: namespace x { +// CHECK-NEXT: namespace y { +namespace na { +namespace nb { +void f() { + std::STD x1; + STD x2; +// CHECK: {{^}} std::STD x1;{{$}} +// CHECK-NEXT: {{^}} STD x2;{{$}} +} +// CHECK: } // namespace y +// CHECK-NEXT: } // namespace x +} +} diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 9e01473d..40087377 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -14,8 +14,8 @@ if(CLANG_BUILT_STANDALONE) endif() endif() -add_subdirectory(change-namespace) add_subdirectory(clang-apply-replacements) +add_subdirectory(clang-change-namespace) add_subdirectory(clang-doc) add_subdirectory(clang-move) add_subdirectory(clang-query) diff --git a/unittests/change-namespace/CMakeLists.txt b/unittests/change-namespace/CMakeLists.txt deleted file mode 100644 index dc5f59d9..00000000 --- a/unittests/change-namespace/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -set(LLVM_LINK_COMPONENTS - support - ) - -get_filename_component(CHANGE_NAMESPACE_SOURCE_DIR - ${CMAKE_CURRENT_SOURCE_DIR}/../../change-namespace REALPATH) -include_directories( - ${CHANGE_NAMESPACE_SOURCE_DIR} - ) - -# We'd like clang/unittests/Tooling/RewriterTestContext.h in the test. -include_directories(${CLANG_SOURCE_DIR}) - -add_extra_unittest(ChangeNamespaceTests - ChangeNamespaceTests.cpp - ) - -target_link_libraries(ChangeNamespaceTests - PRIVATE - clangAST - clangASTMatchers - clangBasic - clangChangeNamespace - clangFormat - clangFrontend - clangRewrite - clangSerialization - clangTooling - clangToolingCore - ) diff --git a/unittests/change-namespace/ChangeNamespaceTests.cpp b/unittests/change-namespace/ChangeNamespaceTests.cpp deleted file mode 100644 index d66fede2..00000000 --- a/unittests/change-namespace/ChangeNamespaceTests.cpp +++ /dev/null @@ -1,2281 +0,0 @@ -//===-- ChangeNamespaceTests.cpp - Change namespace unit tests ---*- 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 "ChangeNamespace.h" -#include "unittests/Tooling/RewriterTestContext.h" -#include "clang/ASTMatchers/ASTMatchFinder.h" -#include "clang/Basic/FileManager.h" -#include "clang/Basic/FileSystemOptions.h" -#include "clang/Format/Format.h" -#include "clang/Frontend/CompilerInstance.h" -#include "clang/Frontend/PCHContainerOperations.h" -#include "clang/Tooling/Refactoring.h" -#include "clang/Tooling/Tooling.h" -#include "llvm/ADT/IntrusiveRefCntPtr.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/VirtualFileSystem.h" -#include "gtest/gtest.h" -#include -#include -#include - -namespace clang { -namespace change_namespace { -namespace { - -class ChangeNamespaceTest : public ::testing::Test { -public: - std::string runChangeNamespaceOnCode(llvm::StringRef Code) { - clang::RewriterTestContext Context; - clang::FileID ID = Context.createInMemoryFile(FileName, Code); - - std::map FileToReplacements; - change_namespace::ChangeNamespaceTool NamespaceTool( - OldNamespace, NewNamespace, FilePattern, - /*WhiteListedSymbolPatterns*/ {}, &FileToReplacements); - ast_matchers::MatchFinder Finder; - NamespaceTool.registerMatchers(&Finder); - std::unique_ptr Factory = - tooling::newFrontendActionFactory(&Finder); - if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, {"-std=c++11"}, - FileName)) - return ""; - formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite); - return format(Context.getRewrittenText(ID)); - } - - std::string format(llvm::StringRef Code) { - tooling::Replacements Replaces = format::reformat( - format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())}); - auto ChangedCode = tooling::applyAllReplacements(Code, Replaces); - EXPECT_TRUE(static_cast(ChangedCode)); - if (!ChangedCode) { - llvm::errs() << llvm::toString(ChangedCode.takeError()); - return ""; - } - return *ChangedCode; - } - -protected: - std::string FileName = "input.cc"; - std::string OldNamespace = "na::nb"; - std::string NewNamespace = "x::y"; - std::string FilePattern = "input.cc"; -}; - -TEST_F(ChangeNamespaceTest, NoMatchingNamespace) { - std::string Code = "namespace na {\n" - "namespace nx {\n" - "class A {};\n" - "} // namespace nx\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "namespace nx {\n" - "class A {};\n" - "} // namespace nx\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, SimpleMoveWithoutTypeRefs) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class A {};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "\n\n" - "namespace x {\n" - "namespace y {\n" - "class A {};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NewNsNestedInOldNs) { - NewNamespace = "na::nb::nc"; - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class A {};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "namespace nb {\n" - "namespace nc {\n" - "class A {};\n" - "} // namespace nc\n" - "} // namespace nb\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithSurroundingNewLines) { - NewNamespace = "na::nb::nc"; - std::string Code = "namespace na {\n" - "namespace nb {\n" - "\n" - "class A {};\n" - "\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "namespace nb {\n" - "namespace nc {\n" - "\n" - "class A {};\n" - "\n" - "} // namespace nc\n" - "} // namespace nb\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, MoveOldNsWithSurroundingNewLines) { - NewNamespace = "nx::ny"; - std::string Code = "namespace na {\n" - "namespace nb {\n" - "\n" - "class A {};\n" - "\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "\n\n" - "namespace nx {\n" - "namespace ny {\n" - "\n" - "class A {};\n" - "\n" - "} // namespace ny\n" - "} // namespace nx\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithRefs) { - NewNamespace = "na::nb::nc"; - std::string Code = "namespace na {\n" - "class A {};\n" - "namespace nb {\n" - "class B {};\n" - "class C {};\n" - "void f() { A a; B b; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "class A {};\n" - "namespace nb {\n" - "namespace nc {\n" - "class B {};\n" - "class C {};\n" - "void f() { A a; B b; }\n" - "} // namespace nc\n" - "} // namespace nb\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, SimpleMoveIntoAnotherNestedNamespace) { - NewNamespace = "na::nc"; - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class A {};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "\n" - "namespace nc {\n" - "class A {};\n" - "} // namespace nc\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) { - NewNamespace = "na::nc"; - std::string Code = "namespace na {\n" - "class A {};\n" - "namespace nb {\n" - "class X { A a; };\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "class A {};\n" - "\n" - "namespace nc {\n" - "class X { A a; };\n" - "} // namespace nc\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, MoveIntoExistingNamespaceAndShortenRefs) { - std::string Code = "namespace x {\n" - "namespace z {\n" - "class Z {};\n" - "} // namespace z\n" - "namespace y {\n" - "class T {};\n" - "} // namespace y\n" - "} // namespace x\n" - "namespace na {\n" - "class A{};\n" - "namespace nb {\n" - "class X { A a; x::z::Z zz; x::y::T t; };\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace x {\n" - "namespace z {\n" - "class Z {};\n" - "} // namespace z\n" - "namespace y {\n" - "class T {};\n" - "} // namespace y\n" - "} // namespace x\n" - "namespace na {\n" - "class A {};\n\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "class X { na::A a; z::Z zz; T t; };\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) { - NewNamespace = "na::x::y"; - std::string Code = "namespace na {\n" - "class A {};\n" - "namespace nb {\n" - "class B {};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "class A {};\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "class B {};\n" - "} // namespace y\n" - "} // namespace x\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) { - std::string Code = "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "namespace nb {\n" - "class C_X {\n" - "public:\n" - " C_A a;\n" - " nc::C_C c;\n" - "};\n" - "class C_Y {\n" - " C_X x;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "class C_X {\n" - "public:\n" - " na::C_A a;\n" - " na::nc::C_C c;\n" - "};\n" - "class C_Y {\n" - " C_X x;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) { - std::string Code = "namespace na {\n" - "class A {};\n" - "template \n" - "class B {};\n" - "template \n" - "class Two {};\n" - "namespace nc { class C {}; }\n" - "} // na\n" - "\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " B b;\n" - " B b_c;\n" - " Two two;\n" - "}\n" - "} // nb\n" - "} // na\n"; - std::string Expected = "namespace na {\n" - "class A {};\n" - "template \n" - "class B {};\n" - "template \n" - "class Two {};\n" - "namespace nc { class C {}; }\n" - "} // na\n" - "\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " na::B b;\n" - " na::B b_c;\n" - " na::Two two;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class FWD;\n" - "class FWD2;\n" - "class A {\n" - " FWD *fwd;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "namespace nb {\n" - "class FWD;\n" - "class FWD2;\n" - "} // namespace nb\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "\n" - "class A {\n" - " na::nb::FWD *fwd;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, InsertForwardDeclsProperly) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "\n" - "class FWD;\n" - "class FWD2;\n" - "class A {\n" - " FWD *fwd;\n" - "};\n" - "\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "namespace nb {\n" - "class FWD;\n" - "class FWD2;\n" - "} // namespace nb\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "\n" - "class A {\n" - " na::nb::FWD *fwd;\n" - "};\n" - "\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, TemplateClassForwardDeclaration) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class FWD;\n" - "template class FWD_TEMP;\n" - "class A {\n" - " FWD *fwd;\n" - "};\n" - "template class TEMP {};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "namespace nb {\n" - "class FWD;\n" - "template class FWD_TEMP;\n" - "} // namespace nb\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "\n" - "class A {\n" - " na::nb::FWD *fwd;\n" - "};\n" - "template class TEMP {};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DontMoveForwardDeclarationInClass) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class A {\n" - " class FWD;\n" - " FWD *fwd;\n" - " template class FWD_TEMP;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "\n\n" - "namespace x {\n" - "namespace y {\n" - "class A {\n" - " class FWD;\n" - " FWD *fwd;\n" - " template class FWD_TEMP;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, MoveFunctions) { - std::string Code = "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "namespace nb {\n" - "void fwd();\n" - "void f(C_A ca, nc::C_C cc) {\n" - " C_A ca_1 = ca;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void fwd();\n" - "void f(na::C_A ca, na::nc::C_C cc) {\n" - " na::C_A ca_1 = ca;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) { - std::string Code = "class GLOB {};\n" - "using BLOG = GLOB;\n" - "namespace na {\n" - "namespace nc {\n" - "class SAME {};\n" - "}\n" - "namespace nd {\n" - "class SAME {};\n" - "}\n" - "namespace nb {\n" - "using nc::SAME;\n" - "using YO = nd::SAME;\n" - "typedef nd::SAME IDENTICAL;\n" - "void f(nd::SAME Same) {}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "class GLOB {};\n" - "using BLOG = GLOB;\n" - "namespace na {\n" - "namespace nc {\n" - "class SAME {};\n" - "}\n" - "namespace nd {\n" - "class SAME {};\n" - "}\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "using ::na::nc::SAME;\n" - "using YO = na::nd::SAME;\n" - "typedef na::nd::SAME IDENTICAL;\n" - "void f(na::nd::SAME Same) {}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DontFixUsingShadowDeclInClasses) { - std::string Code = "namespace na {\n" - "class A {};\n" - "class Base { public: Base() {} void m() {} };\n" - "namespace nb {\n" - "class D : public Base {\n" - "public:\n" - " using AA = A; using B = Base;\n" - " using Base::m; using Base::Base;\n" - "};" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace na {\n" - "class A {};\n" - "class Base { public: Base() {} void m() {} };\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "class D : public na::Base {\n" - "public:\n" - " using AA = na::A; using B = na::Base;\n" - " using Base::m; using Base::Base;\n" - "};" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) { - std::string Code = - "namespace na {\n" - "class C_A {\n" - "public:\n" - " class Nested {\n" - " public:\n" - " static int NestedX;\n" - " static void nestedFunc() {}\n" - " };\n" - "};\n" - "namespace nb {\n" - "class C_X {\n" - " C_A na;\n" - " C_A::Nested nested;\n" - " void f() {\n" - " C_A::Nested::nestedFunc();\n" - " int X = C_A::Nested::NestedX;\n" - " }\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace na {\n" - "class C_A {\n" - "public:\n" - " class Nested {\n" - " public:\n" - " static int NestedX;\n" - " static void nestedFunc() {}\n" - " };\n" - "};\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "class C_X {\n" - " na::C_A na;\n" - " na::C_A::Nested nested;\n" - " void f() {\n" - " na::C_A::Nested::nestedFunc();\n" - " int X = na::C_A::Nested::NestedX;\n" - " }\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) { - std::string Code = - "namespace na {\n" - "class A {\n" - "public:\n" - " static void f() {}\n" - " static void g();\n" - "};\n" - "void A::g() {}" - "void a_f() {}\n" - "static void static_f() {}\n" - "namespace nb {\n" - "void f() { a_f(); static_f(); A::f(); }\n" - "void g() { f(); A::g(); }\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace na {\n" - "class A {\n" - "public:\n" - " static void f() {}\n" - " static void g();\n" - "};\n" - "void A::g() {}" - "void a_f() {}\n" - "static void static_f() {}\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void f() { na::a_f(); na::static_f(); na::A::f(); }\n" - "void g() { f(); na::A::g(); }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, FixOverloadedOperatorFunctionNameSpecifiers) { - std::string Code = - "namespace na {\n" - "class A {\n" - "public:\n" - " int x;\n" - " bool operator==(const A &RHS) const { return x == RHS.x; }\n" - "};\n" - "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n" - "namespace nb {\n" - "bool f() {\n" - " A x, y;\n" - " auto f = operator<;\n" - " return (x == y) && (x < y) && (operator<(x, y));\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace na {\n" - "class A {\n" - "public:\n" - " int x;\n" - " bool operator==(const A &RHS) const { return x == RHS.x; }\n" - "};\n" - "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "bool f() {\n" - " na::A x, y;\n" - " auto f = na::operator<;\n" - // FIXME: function calls to overloaded operators are not fixed now even if - // they are referenced by qualified names. - " return (x == y) && (x < y) && (operator<(x,y));\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) { - std::string Code = "namespace na {\n" - "class A {\n" - "public:\n" - " static void f() {}\n" - "};\n" - "void a_f() {}\n" - "static void s_f() {}\n" - "namespace nb {\n" - "void f() {\n" - " auto *ref1 = A::f;\n" - " auto *ref2 = a_f;\n" - " auto *ref3 = s_f;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace na {\n" - "class A {\n" - "public:\n" - " static void f() {}\n" - "};\n" - "void a_f() {}\n" - "static void s_f() {}\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " auto *ref1 = na::A::f;\n" - " auto *ref2 = na::a_f;\n" - " auto *ref3 = na::s_f;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) { - std::string Code = "namespace na {\n" - "int GlobA;\n" - "static int GlobAStatic = 0;\n" - "namespace nc { int GlobC; }\n" - "namespace nb {\n" - "int GlobB;\n" - "void f() {\n" - " int a = GlobA;\n" - " int b = GlobAStatic;\n" - " int c = nc::GlobC;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace na {\n" - "int GlobA;\n" - "static int GlobAStatic = 0;\n" - "namespace nc { int GlobC; }\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "int GlobB;\n" - "void f() {\n" - " int a = na::GlobA;\n" - " int b = na::GlobAStatic;\n" - " int c = na::nc::GlobC;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) { - std::string Code = "namespace na {\n" - "class A {\n" - "public:\n" - "static int A1;\n" - "static int A2;\n" - "};\n" - "int A::A1 = 0;\n" - "namespace nb {\n" - "void f() {\n" - " int a = A::A1; int b = A::A2;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace na {\n" - "class A {\n" - "public:\n" - "static int A1;\n" - "static int A2;\n" - "};\n" - "int A::A1 = 0;\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " int a = na::A::A1; int b = na::A::A2;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "class A;\n" - "class B {};\n" - "}" - "}"; - std::string Expected = "namespace na {\n" - "namespace nb {\n" - "class A;\n" - "}\n" - "}\n" - "namespace x {\n" - "namespace y {\n" - "\n" - "class B {};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "\n\n" - "// Wild comments.\n" - "\n" - "// Comments.\n" - "// More comments.\n" - "class B {\n" - " // Private comments.\n" - " int a;\n" - "};\n" - "}\n" - "}"; - std::string Expected = "\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "\n\n" - "// Wild comments.\n" - "\n" - "// Comments.\n" - "// More comments.\n" - "class B {\n" - " // Private comments.\n" - " int a;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "void GFunc() {}\n" - "}\n" - "using glob::Glob;\n" - "using glob::GFunc;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { Glob g; GFunc(); }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "void GFunc() {}\n" - "}\n" - "using glob::Glob;\n" - "using glob::GFunc;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { Glob g; GFunc(); }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclsInAnonymousNamespaces) { - std::string Code = "namespace util {\n" - "class Util {};\n" - "void func() {}\n" - "}\n" - "namespace na {\n" - "namespace nb {\n" - "namespace {\n" - "using ::util::Util;\n" - "using ::util::func;\n" - "void f() { Util u; func(); }\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace util {\n" - "class Util {};\n" - "void func() {}\n" - "} // namespace util\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "namespace {\n" - "using ::util::Util;\n" - "using ::util::func;\n" - "void f() { Util u; func(); }\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "using namespace glob;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { Glob g; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "using namespace glob;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { Glob g; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NamespaceAliasInGlobal) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace glob2 { class Glob2 {}; }\n" - "namespace gl = glob;\n" - "namespace gl2 = glob2;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { gl::Glob g; gl2::Glob2 g2; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = - "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace glob2 { class Glob2 {}; }\n" - "namespace gl = glob;\n" - "namespace gl2 = glob2;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { gl::Glob g; gl2::Glob2 g2; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NamespaceAliasInNamespace) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace na {\n" - "namespace nb {\n" - "namespace gl = glob;\n" - "void f() { gl::Glob g; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "namespace gl = glob;\n" - "void f() { gl::Glob g; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NamespaceAliasInAncestorNamespace) { - NewNamespace = "na::nx"; - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace other { namespace gl = glob; }\n" - "namespace na {\n" - "namespace ga = glob;\n" - "namespace nb {\n" - "void f() { ga::Glob g; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace other { namespace gl = glob; }\n" - "namespace na {\n" - "namespace ga = glob;\n" - "\n" - "namespace nx {\n" - "void f() { ga::Glob g; }\n" - "} // namespace nx\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NamespaceAliasInOtherNamespace) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace other { namespace gl = glob; }\n" - "namespace na {\n" - "namespace ga = glob;\n" - "namespace nb {\n" - "void f() { glob::Glob g; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace other { namespace gl = glob; }\n" - "namespace na {\n" - "namespace ga = glob;\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void f() { glob::Glob g; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { glob::Glob g; }\n" - "} // namespace nb\n" - "} // namespace na\n" - "using glob::Glob;\n" - "using namespace glob;\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { glob::Glob g; }\n" - "} // namespace y\n" - "} // namespace x\n" - "using glob::Glob;\n" - "using namespace glob;\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) { - NewNamespace = "na::nc"; - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { glob::Glob g; }\n" - "} // namespace nb\n" - "using namespace glob;\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace na {\n" - "\n" - "namespace nc {\n" - "void f() { glob::Glob g; }\n" - "} // namespace nc\n" - "using namespace glob;\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) { - std::string Code = "namespace glob1 {\n" - "namespace glob2 {\n" - "class Glob {};\n" - "}\n" - "}\n" - "using glob1::glob2::Glob;\n" - "using namespace glob1;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { Glob g; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob1 {\n" - "namespace glob2 {\n" - "class Glob {};\n" - "}\n" - "}\n" - "using glob1::glob2::Glob;\n" - "using namespace glob1;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { Glob g; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "using GLB = glob::Glob;\n" - "using BLG = glob::Glob;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { GLB g; BLG blg; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "using GLB = glob::Glob;\n" - "using BLG = glob::Glob;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { GLB g; BLG blg; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) { - std::string Code = "namespace na { class C_A {};\n }\n" - "using na::C_A;\n" - "namespace na {\n" - "namespace nb {\n" - "class C_X {\n" - "public:\n" - " C_A a;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na { class C_A {};\n }\n" - "using na::C_A;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "class C_X {\n" - "public:\n" - " C_A a;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) { - std::string Code = "namespace na { class C_A {};\n }\n" - "using namespace na;\n" - "namespace na {\n" - "namespace nb {\n" - "class C_X {\n" - "public:\n" - " C_A ca;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na { class C_A {};\n }\n" - "using namespace na;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "class C_X {\n" - "public:\n" - " C_A ca;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) { - std::string Code = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " using glob::Glob;\n" - " Glob g;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace glob {\n" - "class Glob {};\n" - "}\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " using ::glob::Glob;\n" - " Glob g;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) { - std::string Code = "namespace na { class C_A {}; }\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " using ::na::C_A;\n" - " C_A ca;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na { class C_A {}; }\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " using ::na::C_A;\n" - " C_A ca;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) { - std::string Code = "namespace nx { void f(); }\n" - "namespace na {\n" - "using nx::f;\n" - "namespace nb {\n" - "void d() { f(); }\n" - "} // nb\n" - "} // na\n"; - - std::string Expected = "namespace nx { void f(); }\n" - "namespace na {\n" - "using nx::f;\n" - "\n" - "} // na\n" - "namespace x {\n" - "namespace y {\n" - "void d() { nx::f(); }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) { - OldNamespace = "na"; - std::string Code = "namespace nx { void f(); }\n" - "namespace na {\n" - "using ::nx::f;\n" - "void d() { f(); }\n" - "} // na\n"; - - std::string Expected = "namespace nx { void f(); }\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "using ::nx::f;\n" - "void d() { f(); }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) { - OldNamespace = "a::b::c::d"; - NewNamespace = "a::b::x::y"; - std::string Code = "namespace nx { void f(); void g(); }\n" - "namespace a {\n" - "namespace b {\n" - "using ::nx::f;\n" - "namespace c {\n" - "using ::nx::g;\n" - "namespace d {\n" - "void d() { f(); g(); }\n" - "} // d\n" - "} // c\n" - "} // b\n" - "} // a\n"; - - std::string Expected = "namespace nx { void f(); void g(); }\n" - "namespace a {\n" - "namespace b {\n" - "using ::nx::f;\n" - "namespace c {\n" - "using ::nx::g;\n" - "\n" - "} // c\n" - "namespace x {\n" - "namespace y {\n" - "void d() { f(); nx::g(); }\n" - "} // namespace y\n" - "} // namespace x\n" - "} // b\n" - "} // a\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclInTheParentOfOldNamespace) { - OldNamespace = "nb::nc"; - NewNamespace = "nb::nd"; - std::string Code = "namespace na { class A {}; }\n" - "namespace nb {\n" - "using na::A;\n" - "namespace nc {\n" - "void d() { A a; }\n" - "} // nc\n" - "} // nb\n"; - - std::string Expected = "namespace na { class A {}; }\n" - "namespace nb {\n" - "using na::A;\n" - "\n" - "namespace nd {\n" - "void d() { A a; }\n" - "} // namespace nd\n" - "} // nb\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclInOldNamespace) { - OldNamespace = "nb"; - NewNamespace = "nc"; - std::string Code = "namespace na { class A {}; }\n" - "namespace nb {\n" - "using na::A;\n" - "void d() { A a; }\n" - "struct X { A a; };\n" - "} // nb\n"; - - std::string Expected = "namespace na { class A {}; }\n" - "\n" - "namespace nc {\n" - "using ::na::A;\n" - "void d() { A a; }\n" - "struct X { A a; };\n" - "} // namespace nc\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateClass) { - OldNamespace = "nb"; - NewNamespace = "nc"; - std::string Code = "namespace na {\n" - "template \n" - "class A { T t; };\n" - "} // namespace na\n" - "namespace nb {\n" - "using na::A;\n" - "void d() { A a; }\n" - "} // nb\n"; - - std::string Expected = "namespace na {\n" - "template \n" - "class A { T t; };\n" - "} // namespace na\n" - "\n" - "namespace nc {\n" - "using ::na::A;\n" - "void d() { A a; }\n" - "} // namespace nc\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateFunction) { - OldNamespace = "nb"; - NewNamespace = "nc"; - std::string Code = "namespace na {\n" - "template \n" - "void f() { T t; };\n" - "} // namespace na\n" - "namespace nb {\n" - "using na::f;\n" - "void d() { f(); }\n" - "} // nb\n"; - - std::string Expected = "namespace na {\n" - "template \n" - "void f() { T t; };\n" - "} // namespace na\n" - "\n" - "namespace nc {\n" - "using ::na::f;\n" - "void d() { f(); }\n" - "} // namespace nc\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingAliasDecl) { - std::string Code = - "namespace nx { namespace ny { class X {}; } }\n" - "namespace na {\n" - "namespace nb {\n" - "using Y = nx::ny::X;\n" - "void f() { Y y; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "using Y = nx::ny::X;\n" - "void f() { Y y; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingAliasDeclInGlobal) { - std::string Code = - "namespace nx { namespace ny { class X {}; } }\n" - "using Y = nx::ny::X;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() { Y y; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" - "using Y = nx::ny::X;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() { Y y; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - - -TEST_F(ChangeNamespaceTest, TypedefAliasDecl) { - std::string Code = - "namespace nx { namespace ny { class X {}; } }\n" - "namespace na {\n" - "namespace nb {\n" - "typedef nx::ny::X Y;\n" - "void f() { Y y; }\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "typedef nx::ny::X Y;\n" - "void f() { Y y; }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) { - std::string Code = - "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" - "namespace na {\n" - "namespace nb {\n" - "class A : public nx::ny::X {\n" - "public:\n" - " A() : X(0) {}\n" - " A(int i);\n" - "};\n" - "A::A(int i) : X(i) {}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" - "\n\n" - "namespace x {\n" - "namespace y {\n" - "class A : public nx::ny::X {\n" - "public:\n" - " A() : X(0) {}\n" - " A(int i);\n" - "};\n" - "A::A(int i) : X(i) {}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DerivedClassWithQualifiedConstructors) { - std::string Code = - "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" - "namespace na {\n" - "namespace nb {\n" - "class A : public nx::ny::X {\n" - "public:\n" - " A() : X::X(0) {}\n" - " A(int i);\n" - "};\n" - "A::A(int i) : X::X(i) {}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" - "\n\n" - "namespace x {\n" - "namespace y {\n" - "class A : public nx::ny::X {\n" - "public:\n" - " A() : X::X(0) {}\n" - " A(int i);\n" - "};\n" - "A::A(int i) : X::X(i) {}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndTypeRefs) { - std::string Code = - "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" - "namespace na {\n" - "namespace nb {\n" - "class A : public nx::ny::X {\n" - "public:\n" - " A() : X(0) {}\n" - " A(int i);\n" - "};\n" - "A::A(int i) : X(i) { X x(1);}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = - "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" - "\n\n" - "namespace x {\n" - "namespace y {\n" - "class A : public nx::ny::X {\n" - "public:\n" - " A() : X(0) {}\n" - " A(int i);\n" - "};\n" - "A::A(int i) : X(i) { nx::ny::X x(1);}\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, MoveToGlobalNamespace) { - NewNamespace = ""; - std::string Code = "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "namespace nb {\n" - "class C_X {\n" - "public:\n" - " C_A a;\n" - " nc::C_C c;\n" - "};\n" - "class C_Y {\n" - " C_X x;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "\n" - "} // namespace na\n" - "class C_X {\n" - "public:\n" - " na::C_A a;\n" - " na::nc::C_C c;\n" - "};\n" - "class C_Y {\n" - " C_X x;\n" - "};\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, KeepGlobalSpecifier) { - std::string Code = "class Glob {};\n" - "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "namespace nb {\n" - "class C_X {\n" - "public:\n" - " ::Glob glob_1;\n" - " Glob glob_2;\n" - " C_A a_1;\n" - " ::na::C_A a_2;\n" - " nc::C_C c;\n" - "};\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "class Glob {};\n" - "namespace na {\n" - "class C_A {};\n" - "namespace nc {\n" - "class C_C {};" - "} // namespace nc\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "class C_X {\n" - "public:\n" - " ::Glob glob_1;\n" - " Glob glob_2;\n" - " na::C_A a_1;\n" - " ::na::C_A a_2;\n" - " na::nc::C_C c;\n" - "};\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, UsingAliasInTemplate) { - NewNamespace = "na::nb::nc"; - std::string Code = "namespace some_ns {\n" - "template \n" - "class G {};\n" - "} // namespace some_ns\n" - "namespace na {\n" - "template\n" - "using GG = some_ns::G;\n" - "} // namespace na\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " GG g;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace some_ns {\n" - "template \n" - "class G {};\n" - "} // namespace some_ns\n" - "namespace na {\n" - "template\n" - "using GG = some_ns::G;\n" - "} // namespace na\n" - "namespace na {\n" - "namespace nb {\n" - "namespace nc {\n" - "void f() {\n" - " GG g;\n" - "}\n" - "} // namespace nc\n" - "} // namespace nb\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) { - NewNamespace = "na::nb::nc"; - std::string Code = "namespace some_ns {\n" - "template \n" - "class G {};\n" - "} // namespace some_ns\n" - "namespace na {\n" - "class Base {\n" - "public:\n" - " template\n" - " using GG = some_ns::G;\n" - "\n" - " struct Nested {};\n" - "};\n" - "class Derived : public Base {};\n" - "} // namespace na\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " Derived::GG g;\n" - " const Derived::GG gg;\n" - " const Derived::GG* gg_ptr;\n" - " struct Derived::Nested nested;\n" - " const struct Derived::Nested *nested_ptr;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace some_ns {\n" - "template \n" - "class G {};\n" - "} // namespace some_ns\n" - "namespace na {\n" - "class Base {\n" - "public:\n" - " template\n" - " using GG = some_ns::G;\n" - "\n" - " struct Nested {};\n" - "};\n" - "class Derived : public Base {};\n" - "} // namespace na\n" - "namespace na {\n" - "namespace nb {\n" - "namespace nc {\n" - "void f() {\n" - " Derived::GG g;\n" - " const Derived::GG gg;\n" - " const Derived::GG* gg_ptr;\n" - " struct Derived::Nested nested;\n" - " const struct Derived::Nested *nested_ptr;\n" - "}\n" - "} // namespace nc\n" - "} // namespace nb\n" - "} // namespace na\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, ExistingNamespaceConflictWithNewNamespace) { - OldNamespace = "nx"; - NewNamespace = "ny::na::nc"; - std::string Code = "namespace na {\n" - "class A {};\n" - "} // namespace na\n" - "namespace nb {\n" - "class B {};\n" - "} // namespace nb\n" - "namespace nx {\n" - "class X {\n" - " na::A a; nb::B b;\n" - "};\n" - "} // namespace nx\n"; - std::string Expected = "namespace na {\n" - "class A {};\n" - "} // namespace na\n" - "namespace nb {\n" - "class B {};\n" - "} // namespace nb\n" - "\n" - "namespace ny {\n" - "namespace na {\n" - "namespace nc {\n" - "class X {\n" - " ::na::A a; nb::B b;\n" - "};\n" - "} // namespace nc\n" - "} // namespace na\n" - "} // namespace ny\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, SymbolConflictWithNewNamespace) { - OldNamespace = "nx"; - NewNamespace = "ny::na::nc"; - std::string Code = "namespace na {\n" - "class A {};\n" - "namespace nb {\n" - "class B {};\n" - "} // namespace nb\n" - "} // namespace na\n" - "namespace ny {\n" - "class Y {};\n" - "}\n" - "namespace nx {\n" - "class X {\n" - " na::A a; na::nb::B b;\n" - " ny::Y y;" - "};\n" - "} // namespace nx\n"; - std::string Expected = "namespace na {\n" - "class A {};\n" - "namespace nb {\n" - "class B {};\n" - "} // namespace nb\n" - "} // namespace na\n" - "namespace ny {\n" - "class Y {};\n" - "}\n" - "\n" - "namespace ny {\n" - "namespace na {\n" - "namespace nc {\n" - "class X {\n" - " ::na::A a; ::na::nb::B b;\n" - " Y y;\n" - "};\n" - "} // namespace nc\n" - "} // namespace na\n" - "} // namespace ny\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, ShortenNamespaceSpecifier) { - OldNamespace = "nx"; - NewNamespace = "ny::na"; - std::string Code = "class G {};\n" - "namespace ny {\n" - "class Y {};\n" - "namespace na {\n" - "class A {};\n" - "namespace nc { class C {}; } // namespace nc\n" - "}\n // namespace na\n" - "}\n // namespace ny\n" - "namespace nx {\n" - "class X {\n" - " G g; ny::Y y; ny::na::A a; ny::na::nc::C c;\n" - "};\n" - "} // namespace nx\n"; - std::string Expected = "class G {};\n" - "namespace ny {\n" - "class Y {};\n" - "namespace na {\n" - "class A {};\n" - "namespace nc { class C {}; } // namespace nc\n" - "}\n // namespace na\n" - "}\n // namespace ny\n" - "\n" - "namespace ny {\n" - "namespace na {\n" - "class X {\n" - " G g; Y y; A a; nc::C c;\n" - "};\n" - "} // namespace na\n" - "} // namespace ny\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, ShortenNamespaceSpecifierInAnonymousNamespace) { - OldNamespace = "nx"; - NewNamespace = "ny::na"; - std::string Code = "class G {};\n" - "namespace ny {\n" - "class Y {};\n" - "namespace na {\n" - "class A {};\n" - "namespace nc { class C {}; } // namespace nc\n" - "}\n // namespace na\n" - "}\n // namespace ny\n" - "namespace nx {\n" - "namespace {\n" - "class X {\n" - " G g; ::ny::Y y; ::ny::na::A a; ::ny::na::nc::C c;\n" - "};\n" - "} // namespace\n" - "} // namespace nx\n"; - std::string Expected = "class G {};\n" - "namespace ny {\n" - "class Y {};\n" - "namespace na {\n" - "class A {};\n" - "namespace nc { class C {}; } // namespace nc\n" - "}\n // namespace na\n" - "}\n // namespace ny\n" - "\n" - "namespace ny {\n" - "namespace na {\n" - "namespace {\n" - "class X {\n" - " G g; Y y; A a; nc::C c;\n" - "};\n" - "} // namespace\n" - "} // namespace na\n" - "} // namespace ny\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, SimpleMoveEnum) { - std::string Code = "namespace na {\n" - "namespace nb {\n" - "enum class X { X1, X2 };\n" - "enum Y { Y1, Y2 };\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "\n\nnamespace x {\n" - "namespace y {\n" - "enum class X { X1, X2 };\n" - "enum Y { Y1, Y2 };\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, ReferencesToEnums) { - std::string Code = "enum Glob { G1, G2 };\n" - "namespace na {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2 };\n" - "namespace nb {\n" - "void f() {\n" - " Glob g1 = Glob::G1;\n" - " Glob g2 = G2;\n" - " X x1 = X::X1;\n" - " Y y1 = Y::Y1;\n" - " Y y2 = Y2;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "enum Glob { G1, G2 };\n" - "namespace na {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2 };\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " Glob g1 = Glob::G1;\n" - " Glob g2 = G2;\n" - " na::X x1 = na::X::X1;\n" - " na::Y y1 = na::Y::Y1;\n" - " na::Y y2 = na::Y2;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, NoRedundantEnumUpdate) { - std::string Code = "namespace ns {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2 };\n" - "} // namespace ns\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " ns::X x1 = ns::X::X1;\n" - " ns::Y y1 = ns::Y::Y1;\n" - " ns::Y y2 = ns::Y2;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace ns {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2 };\n" - "} // namespace ns\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " ns::X x1 = ns::X::X1;\n" - " ns::Y y1 = ns::Y::Y1;\n" - " ns::Y y2 = ns::Y2;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - ; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, EnumsAndUsingShadows) { - std::string Code = "namespace ns {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2, Y3 };\n" - "} // namespace ns\n" - "using ns::X;\n" - "using ns::Y;\n" - "using ns::Y::Y2;\n" - "using ns::Y::Y3;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " X x1 = X::X1;\n" - " Y y1 = Y::Y1;\n" - " Y y2 = Y2;\n" - " Y y3 = Y3;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace ns {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2, Y3 };\n" - "} // namespace ns\n" - "using ns::X;\n" - "using ns::Y;\n" - "using ns::Y::Y2;\n" - "using ns::Y::Y3;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " X x1 = X::X1;\n" - " Y y1 = Y::Y1;\n" - " Y y2 = Y2;\n" - " Y y3 = Y3;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, EnumsAndAliases) { - std::string Code = "namespace ns {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2, Y3 };\n" - "} // namespace ns\n" - "typedef ns::X TX;\n" - "typedef ns::Y TY;\n" - "using UX = ns::X;\n" - "using UY = ns::Y;\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " ns::X x1 = ns::X::X1;\n" - " TX tx1 = TX::X1;\n" - " UX ux1 = UX::X1;\n" - " ns::Y y1 = ns::Y::Y1;\n" - " TY ty1 = TY::Y1;\n" - " UY uy1 = UY::Y1;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace ns {\n" - "enum class X { X1 };\n" - "enum Y { Y1, Y2, Y3 };\n" - "} // namespace ns\n" - "typedef ns::X TX;\n" - "typedef ns::Y TY;\n" - "using UX = ns::X;\n" - "using UY = ns::Y;\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " ns::X x1 = ns::X::X1;\n" - " TX tx1 = TX::X1;\n" - " UX ux1 = UX::X1;\n" - " ns::Y y1 = ns::Y::Y1;\n" - " TY ty1 = TY::Y1;\n" - " UY uy1 = UY::Y1;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, EnumInClass) { - std::string Code = "namespace na {\n" - "struct X { enum E { E1 }; };\n" - "namespace nb {\n" - "void f() {\n" - " X::E e = X::E1;\n" - " X::E ee = X::E::E1;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "struct X { enum E { E1 }; };\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " na::X::E e = na::X::E1;\n" - " na::X::E ee = na::X::E::E1;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) { - std::string Code = "namespace na {\n" - "struct X {};\n" - "namespace nb {\n" - "template \n" - "void TempTemp(const TT& t) {\n" - " TT tmp;\n" - "}\n" - "template \n" - "void Temp(const T& t) {\n" - " T tmp = t;\n" - " TempTemp(tmp);\n" - " TempTemp(t);\n" - "}\n" - "void f() {\n" - " X x;\n" - " Temp(x);\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "struct X {};\n" - "\n" - "} // namespace na\n" - "namespace x {\n" - "namespace y {\n" - "template \n" - "void TempTemp(const TT& t) {\n" - " TT tmp;\n" - "}\n" - "template \n" - "void Temp(const T& t) {\n" - " T tmp = t;\n" - " TempTemp(tmp);\n" - " TempTemp(t);\n" - "}\n" - "void f() {\n" - " na::X x;\n" - " Temp(x);\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, DefaultMoveConstructors) { - std::string Code = "namespace na {\n" - "class B {\n" - " public:\n" - " B() = default;\n" - " // Allow move only.\n" - " B(B&&) = default;\n" - " B& operator=(B&&) = default;\n" - " B(const B&) = delete;\n" - " B& operator=(const B&) = delete;\n" - " private:\n" - " int ref_;\n" - "};\n" - "} // namespace na\n" - "namespace na {\n" - "namespace nb {\n" - "class A {\n" - "public:\n" - " A() = default;\n" - " A(A&&) = default;\n" - " A& operator=(A&&) = default;\n" - "private:\n" - " B b;\n" - " A(const A&) = delete;\n" - " A& operator=(const A&) = delete;\n" - "};\n" - "void f() { A a; a = A(); A aa = A(); }\n" - "} // namespace nb\n" - "} // namespace na\n"; - std::string Expected = "namespace na {\n" - "class B {\n" - " public:\n" - " B() = default;\n" - " // Allow move only.\n" - " B(B&&) = default;\n" - " B& operator=(B&&) = default;\n" - " B(const B&) = delete;\n" - " B& operator=(const B&) = delete;\n" - " private:\n" - " int ref_;\n" - "};\n" - "} // namespace na\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "class A {\n" - "public:\n" - " A() = default;\n" - " A(A&&) = default;\n" - " A& operator=(A&&) = default;\n" - "private:\n" - " na::B b;\n" - " A(const A&) = delete;\n" - " A& operator=(const A&) = delete;\n" - "};\n" - "void f() { A a; a = A(); A aa = A(); }\n" - "} // namespace y\n" - "} // namespace x\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, InjectedClassNameInFriendDecl) { - OldNamespace = "d"; - NewNamespace = "e"; - std::string Code = "namespace a{\n" - "template \n" - "class Base {\n" - " public:\n" - " void f() {\n" - " T t;\n" - " t.priv();\n" - " }\n" - "};\n" - "} // namespace a\n" - "namespace d {\n" - "class D : public a::Base {\n" - " private:\n" - " friend class Base;\n" - " void priv() {}\n" - " Base b;\n" - "};\n" - "\n" - "void f() {\n" - " D d;\n" - " a:: Base b;\n" - " b.f();\n" - "}\n" - "} // namespace d\n"; - std::string Expected = "namespace a{\n" - "template \n" - "class Base {\n" - " public:\n" - " void f() {\n" - " T t;\n" - " t.priv();\n" - " }\n" - "};\n" - "} // namespace a\n" - "\n" - "namespace e {\n" - "class D : public a::Base {\n" - " private:\n" - " friend class Base;\n" - " void priv() {}\n" - " a::Base b;\n" - "};\n" - "\n" - "void f() {\n" - " D d;\n" - " a::Base b;\n" - " b.f();\n" - "}\n" - "} // namespace e\n"; - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -TEST_F(ChangeNamespaceTest, FullyQualifyConflictNamespace) { - std::string Code = - "namespace x { namespace util { class Some {}; } }\n" - "namespace x { namespace y {namespace base { class Base {}; } } }\n" - "namespace util { class Status {}; }\n" - "namespace base { class Base {}; }\n" - "namespace na {\n" - "namespace nb {\n" - "void f() {\n" - " util::Status s1; x::util::Some s2;\n" - " base::Base b1; x::y::base::Base b2;\n" - "}\n" - "} // namespace nb\n" - "} // namespace na\n"; - - std::string Expected = - "namespace x { namespace util { class Some {}; } }\n" - "namespace x { namespace y {namespace base { class Base {}; } } }\n" - "namespace util { class Status {}; }\n" - "namespace base { class Base {}; }\n" - "\n" - "namespace x {\n" - "namespace y {\n" - "void f() {\n" - " ::util::Status s1; util::Some s2;\n" - " ::base::Base b1; base::Base b2;\n" - "}\n" - "} // namespace y\n" - "} // namespace x\n"; - - EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); -} - -} // anonymous namespace -} // namespace change_namespace -} // namespace clang diff --git a/unittests/clang-change-namespace/CMakeLists.txt b/unittests/clang-change-namespace/CMakeLists.txt new file mode 100644 index 00000000..05e2c599 --- /dev/null +++ b/unittests/clang-change-namespace/CMakeLists.txt @@ -0,0 +1,30 @@ +set(LLVM_LINK_COMPONENTS + support + ) + +get_filename_component(CHANGE_NAMESPACE_SOURCE_DIR + ${CMAKE_CURRENT_SOURCE_DIR}/../../clang-change-namespace REALPATH) +include_directories( + ${CHANGE_NAMESPACE_SOURCE_DIR} + ) + +# We'd like clang/unittests/Tooling/RewriterTestContext.h in the test. +include_directories(${CLANG_SOURCE_DIR}) + +add_extra_unittest(ChangeNamespaceTests + ChangeNamespaceTests.cpp + ) + +target_link_libraries(ChangeNamespaceTests + PRIVATE + clangAST + clangASTMatchers + clangBasic + clangChangeNamespace + clangFormat + clangFrontend + clangRewrite + clangSerialization + clangTooling + clangToolingCore + ) diff --git a/unittests/clang-change-namespace/ChangeNamespaceTests.cpp b/unittests/clang-change-namespace/ChangeNamespaceTests.cpp new file mode 100644 index 00000000..d66fede2 --- /dev/null +++ b/unittests/clang-change-namespace/ChangeNamespaceTests.cpp @@ -0,0 +1,2281 @@ +//===-- ChangeNamespaceTests.cpp - Change namespace unit tests ---*- 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 "ChangeNamespace.h" +#include "unittests/Tooling/RewriterTestContext.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Basic/FileManager.h" +#include "clang/Basic/FileSystemOptions.h" +#include "clang/Format/Format.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/PCHContainerOperations.h" +#include "clang/Tooling/Refactoring.h" +#include "clang/Tooling/Tooling.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/VirtualFileSystem.h" +#include "gtest/gtest.h" +#include +#include +#include + +namespace clang { +namespace change_namespace { +namespace { + +class ChangeNamespaceTest : public ::testing::Test { +public: + std::string runChangeNamespaceOnCode(llvm::StringRef Code) { + clang::RewriterTestContext Context; + clang::FileID ID = Context.createInMemoryFile(FileName, Code); + + std::map FileToReplacements; + change_namespace::ChangeNamespaceTool NamespaceTool( + OldNamespace, NewNamespace, FilePattern, + /*WhiteListedSymbolPatterns*/ {}, &FileToReplacements); + ast_matchers::MatchFinder Finder; + NamespaceTool.registerMatchers(&Finder); + std::unique_ptr Factory = + tooling::newFrontendActionFactory(&Finder); + if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, {"-std=c++11"}, + FileName)) + return ""; + formatAndApplyAllReplacements(FileToReplacements, Context.Rewrite); + return format(Context.getRewrittenText(ID)); + } + + std::string format(llvm::StringRef Code) { + tooling::Replacements Replaces = format::reformat( + format::getLLVMStyle(), Code, {tooling::Range(0, Code.size())}); + auto ChangedCode = tooling::applyAllReplacements(Code, Replaces); + EXPECT_TRUE(static_cast(ChangedCode)); + if (!ChangedCode) { + llvm::errs() << llvm::toString(ChangedCode.takeError()); + return ""; + } + return *ChangedCode; + } + +protected: + std::string FileName = "input.cc"; + std::string OldNamespace = "na::nb"; + std::string NewNamespace = "x::y"; + std::string FilePattern = "input.cc"; +}; + +TEST_F(ChangeNamespaceTest, NoMatchingNamespace) { + std::string Code = "namespace na {\n" + "namespace nx {\n" + "class A {};\n" + "} // namespace nx\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nx {\n" + "class A {};\n" + "} // namespace nx\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, SimpleMoveWithoutTypeRefs) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class A {};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A {};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NewNsNestedInOldNs) { + NewNamespace = "na::nb::nc"; + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class A {};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "namespace nc {\n" + "class A {};\n" + "} // namespace nc\n" + "} // namespace nb\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithSurroundingNewLines) { + NewNamespace = "na::nb::nc"; + std::string Code = "namespace na {\n" + "namespace nb {\n" + "\n" + "class A {};\n" + "\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "namespace nc {\n" + "\n" + "class A {};\n" + "\n" + "} // namespace nc\n" + "} // namespace nb\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, MoveOldNsWithSurroundingNewLines) { + NewNamespace = "nx::ny"; + std::string Code = "namespace na {\n" + "namespace nb {\n" + "\n" + "class A {};\n" + "\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "\n\n" + "namespace nx {\n" + "namespace ny {\n" + "\n" + "class A {};\n" + "\n" + "} // namespace ny\n" + "} // namespace nx\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NewNsNestedInOldNsWithRefs) { + NewNamespace = "na::nb::nc"; + std::string Code = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "class B {};\n" + "class C {};\n" + "void f() { A a; B b; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "namespace nc {\n" + "class B {};\n" + "class C {};\n" + "void f() { A a; B b; }\n" + "} // namespace nc\n" + "} // namespace nb\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, SimpleMoveIntoAnotherNestedNamespace) { + NewNamespace = "na::nc"; + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class A {};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "\n" + "namespace nc {\n" + "class A {};\n" + "} // namespace nc\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, MoveIntoAnotherNestedNamespaceWithRef) { + NewNamespace = "na::nc"; + std::string Code = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "class X { A a; };\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "\n" + "namespace nc {\n" + "class X { A a; };\n" + "} // namespace nc\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, MoveIntoExistingNamespaceAndShortenRefs) { + std::string Code = "namespace x {\n" + "namespace z {\n" + "class Z {};\n" + "} // namespace z\n" + "namespace y {\n" + "class T {};\n" + "} // namespace y\n" + "} // namespace x\n" + "namespace na {\n" + "class A{};\n" + "namespace nb {\n" + "class X { A a; x::z::Z zz; x::y::T t; };\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace x {\n" + "namespace z {\n" + "class Z {};\n" + "} // namespace z\n" + "namespace y {\n" + "class T {};\n" + "} // namespace y\n" + "} // namespace x\n" + "namespace na {\n" + "class A {};\n\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "class X { na::A a; z::Z zz; T t; };\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, SimpleMoveNestedNamespace) { + NewNamespace = "na::x::y"; + std::string Code = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "class B {};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "class B {};\n" + "} // namespace y\n" + "} // namespace x\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, SimpleMoveWithTypeRefs) { + std::string Code = "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "namespace nb {\n" + "class C_X {\n" + "public:\n" + " C_A a;\n" + " nc::C_C c;\n" + "};\n" + "class C_Y {\n" + " C_X x;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "class C_X {\n" + "public:\n" + " na::C_A a;\n" + " na::nc::C_C c;\n" + "};\n" + "class C_Y {\n" + " C_X x;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, TypeLocInTemplateSpecialization) { + std::string Code = "namespace na {\n" + "class A {};\n" + "template \n" + "class B {};\n" + "template \n" + "class Two {};\n" + "namespace nc { class C {}; }\n" + "} // na\n" + "\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " B b;\n" + " B b_c;\n" + " Two two;\n" + "}\n" + "} // nb\n" + "} // na\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "template \n" + "class B {};\n" + "template \n" + "class Two {};\n" + "namespace nc { class C {}; }\n" + "} // na\n" + "\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " na::B b;\n" + " na::B b_c;\n" + " na::Two two;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, LeaveForwardDeclarationBehind) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class FWD;\n" + "class FWD2;\n" + "class A {\n" + " FWD *fwd;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "class FWD;\n" + "class FWD2;\n" + "} // namespace nb\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "\n" + "class A {\n" + " na::nb::FWD *fwd;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, InsertForwardDeclsProperly) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "\n" + "class FWD;\n" + "class FWD2;\n" + "class A {\n" + " FWD *fwd;\n" + "};\n" + "\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "class FWD;\n" + "class FWD2;\n" + "} // namespace nb\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "\n" + "class A {\n" + " na::nb::FWD *fwd;\n" + "};\n" + "\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, TemplateClassForwardDeclaration) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class FWD;\n" + "template class FWD_TEMP;\n" + "class A {\n" + " FWD *fwd;\n" + "};\n" + "template class TEMP {};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "class FWD;\n" + "template class FWD_TEMP;\n" + "} // namespace nb\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "\n" + "class A {\n" + " na::nb::FWD *fwd;\n" + "};\n" + "template class TEMP {};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DontMoveForwardDeclarationInClass) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class A {\n" + " class FWD;\n" + " FWD *fwd;\n" + " template class FWD_TEMP;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A {\n" + " class FWD;\n" + " FWD *fwd;\n" + " template class FWD_TEMP;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, MoveFunctions) { + std::string Code = "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "namespace nb {\n" + "void fwd();\n" + "void f(C_A ca, nc::C_C cc) {\n" + " C_A ca_1 = ca;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void fwd();\n" + "void f(na::C_A ca, na::nc::C_C cc) {\n" + " na::C_A ca_1 = ca;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, FixUsingShadowDecl) { + std::string Code = "class GLOB {};\n" + "using BLOG = GLOB;\n" + "namespace na {\n" + "namespace nc {\n" + "class SAME {};\n" + "}\n" + "namespace nd {\n" + "class SAME {};\n" + "}\n" + "namespace nb {\n" + "using nc::SAME;\n" + "using YO = nd::SAME;\n" + "typedef nd::SAME IDENTICAL;\n" + "void f(nd::SAME Same) {}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "class GLOB {};\n" + "using BLOG = GLOB;\n" + "namespace na {\n" + "namespace nc {\n" + "class SAME {};\n" + "}\n" + "namespace nd {\n" + "class SAME {};\n" + "}\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "using ::na::nc::SAME;\n" + "using YO = na::nd::SAME;\n" + "typedef na::nd::SAME IDENTICAL;\n" + "void f(na::nd::SAME Same) {}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DontFixUsingShadowDeclInClasses) { + std::string Code = "namespace na {\n" + "class A {};\n" + "class Base { public: Base() {} void m() {} };\n" + "namespace nb {\n" + "class D : public Base {\n" + "public:\n" + " using AA = A; using B = Base;\n" + " using Base::m; using Base::Base;\n" + "};" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace na {\n" + "class A {};\n" + "class Base { public: Base() {} void m() {} };\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "class D : public na::Base {\n" + "public:\n" + " using AA = na::A; using B = na::Base;\n" + " using Base::m; using Base::Base;\n" + "};" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, TypeInNestedNameSpecifier) { + std::string Code = + "namespace na {\n" + "class C_A {\n" + "public:\n" + " class Nested {\n" + " public:\n" + " static int NestedX;\n" + " static void nestedFunc() {}\n" + " };\n" + "};\n" + "namespace nb {\n" + "class C_X {\n" + " C_A na;\n" + " C_A::Nested nested;\n" + " void f() {\n" + " C_A::Nested::nestedFunc();\n" + " int X = C_A::Nested::NestedX;\n" + " }\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace na {\n" + "class C_A {\n" + "public:\n" + " class Nested {\n" + " public:\n" + " static int NestedX;\n" + " static void nestedFunc() {}\n" + " };\n" + "};\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "class C_X {\n" + " na::C_A na;\n" + " na::C_A::Nested nested;\n" + " void f() {\n" + " na::C_A::Nested::nestedFunc();\n" + " int X = na::C_A::Nested::NestedX;\n" + " }\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, FixFunctionNameSpecifiers) { + std::string Code = + "namespace na {\n" + "class A {\n" + "public:\n" + " static void f() {}\n" + " static void g();\n" + "};\n" + "void A::g() {}" + "void a_f() {}\n" + "static void static_f() {}\n" + "namespace nb {\n" + "void f() { a_f(); static_f(); A::f(); }\n" + "void g() { f(); A::g(); }\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace na {\n" + "class A {\n" + "public:\n" + " static void f() {}\n" + " static void g();\n" + "};\n" + "void A::g() {}" + "void a_f() {}\n" + "static void static_f() {}\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void f() { na::a_f(); na::static_f(); na::A::f(); }\n" + "void g() { f(); na::A::g(); }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, FixOverloadedOperatorFunctionNameSpecifiers) { + std::string Code = + "namespace na {\n" + "class A {\n" + "public:\n" + " int x;\n" + " bool operator==(const A &RHS) const { return x == RHS.x; }\n" + "};\n" + "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n" + "namespace nb {\n" + "bool f() {\n" + " A x, y;\n" + " auto f = operator<;\n" + " return (x == y) && (x < y) && (operator<(x, y));\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace na {\n" + "class A {\n" + "public:\n" + " int x;\n" + " bool operator==(const A &RHS) const { return x == RHS.x; }\n" + "};\n" + "bool operator<(const A &LHS, const A &RHS) { return LHS.x == RHS.x; }\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "bool f() {\n" + " na::A x, y;\n" + " auto f = na::operator<;\n" + // FIXME: function calls to overloaded operators are not fixed now even if + // they are referenced by qualified names. + " return (x == y) && (x < y) && (operator<(x,y));\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, FixNonCallingFunctionReferences) { + std::string Code = "namespace na {\n" + "class A {\n" + "public:\n" + " static void f() {}\n" + "};\n" + "void a_f() {}\n" + "static void s_f() {}\n" + "namespace nb {\n" + "void f() {\n" + " auto *ref1 = A::f;\n" + " auto *ref2 = a_f;\n" + " auto *ref3 = s_f;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace na {\n" + "class A {\n" + "public:\n" + " static void f() {}\n" + "};\n" + "void a_f() {}\n" + "static void s_f() {}\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " auto *ref1 = na::A::f;\n" + " auto *ref2 = na::a_f;\n" + " auto *ref3 = na::s_f;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, MoveAndFixGlobalVariables) { + std::string Code = "namespace na {\n" + "int GlobA;\n" + "static int GlobAStatic = 0;\n" + "namespace nc { int GlobC; }\n" + "namespace nb {\n" + "int GlobB;\n" + "void f() {\n" + " int a = GlobA;\n" + " int b = GlobAStatic;\n" + " int c = nc::GlobC;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace na {\n" + "int GlobA;\n" + "static int GlobAStatic = 0;\n" + "namespace nc { int GlobC; }\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "int GlobB;\n" + "void f() {\n" + " int a = na::GlobA;\n" + " int b = na::GlobAStatic;\n" + " int c = na::nc::GlobC;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DoNotFixStaticVariableOfClass) { + std::string Code = "namespace na {\n" + "class A {\n" + "public:\n" + "static int A1;\n" + "static int A2;\n" + "};\n" + "int A::A1 = 0;\n" + "namespace nb {\n" + "void f() {\n" + " int a = A::A1; int b = A::A2;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace na {\n" + "class A {\n" + "public:\n" + "static int A1;\n" + "static int A2;\n" + "};\n" + "int A::A1 = 0;\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " int a = na::A::A1; int b = na::A::A2;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NoMisplaceAtEOF) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "class A;\n" + "class B {};\n" + "}" + "}"; + std::string Expected = "namespace na {\n" + "namespace nb {\n" + "class A;\n" + "}\n" + "}\n" + "namespace x {\n" + "namespace y {\n" + "\n" + "class B {};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, CommentsBeforeMovedClass) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "\n\n" + "// Wild comments.\n" + "\n" + "// Comments.\n" + "// More comments.\n" + "class B {\n" + " // Private comments.\n" + " int a;\n" + "};\n" + "}\n" + "}"; + std::string Expected = "\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "\n\n" + "// Wild comments.\n" + "\n" + "// Comments.\n" + "// More comments.\n" + "class B {\n" + " // Private comments.\n" + " int a;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclInGlobal) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "void GFunc() {}\n" + "}\n" + "using glob::Glob;\n" + "using glob::GFunc;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { Glob g; GFunc(); }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "void GFunc() {}\n" + "}\n" + "using glob::Glob;\n" + "using glob::GFunc;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { Glob g; GFunc(); }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclsInAnonymousNamespaces) { + std::string Code = "namespace util {\n" + "class Util {};\n" + "void func() {}\n" + "}\n" + "namespace na {\n" + "namespace nb {\n" + "namespace {\n" + "using ::util::Util;\n" + "using ::util::func;\n" + "void f() { Util u; func(); }\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace util {\n" + "class Util {};\n" + "void func() {}\n" + "} // namespace util\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "namespace {\n" + "using ::util::Util;\n" + "using ::util::func;\n" + "void f() { Util u; func(); }\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingNamespaceInGlobal) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "using namespace glob;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { Glob g; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "using namespace glob;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { Glob g; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NamespaceAliasInGlobal) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace glob2 { class Glob2 {}; }\n" + "namespace gl = glob;\n" + "namespace gl2 = glob2;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { gl::Glob g; gl2::Glob2 g2; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = + "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace glob2 { class Glob2 {}; }\n" + "namespace gl = glob;\n" + "namespace gl2 = glob2;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { gl::Glob g; gl2::Glob2 g2; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NamespaceAliasInNamespace) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace na {\n" + "namespace nb {\n" + "namespace gl = glob;\n" + "void f() { gl::Glob g; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "namespace gl = glob;\n" + "void f() { gl::Glob g; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NamespaceAliasInAncestorNamespace) { + NewNamespace = "na::nx"; + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace other { namespace gl = glob; }\n" + "namespace na {\n" + "namespace ga = glob;\n" + "namespace nb {\n" + "void f() { ga::Glob g; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace other { namespace gl = glob; }\n" + "namespace na {\n" + "namespace ga = glob;\n" + "\n" + "namespace nx {\n" + "void f() { ga::Glob g; }\n" + "} // namespace nx\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NamespaceAliasInOtherNamespace) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace other { namespace gl = glob; }\n" + "namespace na {\n" + "namespace ga = glob;\n" + "namespace nb {\n" + "void f() { glob::Glob g; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace other { namespace gl = glob; }\n" + "namespace na {\n" + "namespace ga = glob;\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void f() { glob::Glob g; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingDeclAfterReference) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { glob::Glob g; }\n" + "} // namespace nb\n" + "} // namespace na\n" + "using glob::Glob;\n" + "using namespace glob;\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { glob::Glob g; }\n" + "} // namespace y\n" + "} // namespace x\n" + "using glob::Glob;\n" + "using namespace glob;\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingNamespaceAfterReference) { + NewNamespace = "na::nc"; + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { glob::Glob g; }\n" + "} // namespace nb\n" + "using namespace glob;\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace na {\n" + "\n" + "namespace nc {\n" + "void f() { glob::Glob g; }\n" + "} // namespace nc\n" + "using namespace glob;\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingNamespaceAndUsingShadowInGlobal) { + std::string Code = "namespace glob1 {\n" + "namespace glob2 {\n" + "class Glob {};\n" + "}\n" + "}\n" + "using glob1::glob2::Glob;\n" + "using namespace glob1;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { Glob g; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob1 {\n" + "namespace glob2 {\n" + "class Glob {};\n" + "}\n" + "}\n" + "using glob1::glob2::Glob;\n" + "using namespace glob1;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { Glob g; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingAliasInGlobal) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "using GLB = glob::Glob;\n" + "using BLG = glob::Glob;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { GLB g; BLG blg; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "using GLB = glob::Glob;\n" + "using BLG = glob::Glob;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { GLB g; BLG blg; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclAndMovedNamespace) { + std::string Code = "namespace na { class C_A {};\n }\n" + "using na::C_A;\n" + "namespace na {\n" + "namespace nb {\n" + "class C_X {\n" + "public:\n" + " C_A a;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na { class C_A {};\n }\n" + "using na::C_A;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "class C_X {\n" + "public:\n" + " C_A a;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingNamespaceDeclAndMovedNamespace) { + std::string Code = "namespace na { class C_A {};\n }\n" + "using namespace na;\n" + "namespace na {\n" + "namespace nb {\n" + "class C_X {\n" + "public:\n" + " C_A ca;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na { class C_A {};\n }\n" + "using namespace na;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "class C_X {\n" + "public:\n" + " C_A ca;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclInFunction) { + std::string Code = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " using glob::Glob;\n" + " Glob g;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace glob {\n" + "class Glob {};\n" + "}\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " using ::glob::Glob;\n" + " Glob g;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclInClass) { + std::string Code = "namespace na { class C_A {}; }\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " using ::na::C_A;\n" + " C_A ca;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na { class C_A {}; }\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " using ::na::C_A;\n" + " C_A ca;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespace) { + std::string Code = "namespace nx { void f(); }\n" + "namespace na {\n" + "using nx::f;\n" + "namespace nb {\n" + "void d() { f(); }\n" + "} // nb\n" + "} // na\n"; + + std::string Expected = "namespace nx { void f(); }\n" + "namespace na {\n" + "using nx::f;\n" + "\n" + "} // na\n" + "namespace x {\n" + "namespace y {\n" + "void d() { nx::f(); }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceNotNested) { + OldNamespace = "na"; + std::string Code = "namespace nx { void f(); }\n" + "namespace na {\n" + "using ::nx::f;\n" + "void d() { f(); }\n" + "} // na\n"; + + std::string Expected = "namespace nx { void f(); }\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "using ::nx::f;\n" + "void d() { f(); }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingDeclInMovedNamespaceMultiNested) { + OldNamespace = "a::b::c::d"; + NewNamespace = "a::b::x::y"; + std::string Code = "namespace nx { void f(); void g(); }\n" + "namespace a {\n" + "namespace b {\n" + "using ::nx::f;\n" + "namespace c {\n" + "using ::nx::g;\n" + "namespace d {\n" + "void d() { f(); g(); }\n" + "} // d\n" + "} // c\n" + "} // b\n" + "} // a\n"; + + std::string Expected = "namespace nx { void f(); void g(); }\n" + "namespace a {\n" + "namespace b {\n" + "using ::nx::f;\n" + "namespace c {\n" + "using ::nx::g;\n" + "\n" + "} // c\n" + "namespace x {\n" + "namespace y {\n" + "void d() { f(); nx::g(); }\n" + "} // namespace y\n" + "} // namespace x\n" + "} // b\n" + "} // a\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclInTheParentOfOldNamespace) { + OldNamespace = "nb::nc"; + NewNamespace = "nb::nd"; + std::string Code = "namespace na { class A {}; }\n" + "namespace nb {\n" + "using na::A;\n" + "namespace nc {\n" + "void d() { A a; }\n" + "} // nc\n" + "} // nb\n"; + + std::string Expected = "namespace na { class A {}; }\n" + "namespace nb {\n" + "using na::A;\n" + "\n" + "namespace nd {\n" + "void d() { A a; }\n" + "} // namespace nd\n" + "} // nb\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclInOldNamespace) { + OldNamespace = "nb"; + NewNamespace = "nc"; + std::string Code = "namespace na { class A {}; }\n" + "namespace nb {\n" + "using na::A;\n" + "void d() { A a; }\n" + "struct X { A a; };\n" + "} // nb\n"; + + std::string Expected = "namespace na { class A {}; }\n" + "\n" + "namespace nc {\n" + "using ::na::A;\n" + "void d() { A a; }\n" + "struct X { A a; };\n" + "} // namespace nc\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateClass) { + OldNamespace = "nb"; + NewNamespace = "nc"; + std::string Code = "namespace na {\n" + "template \n" + "class A { T t; };\n" + "} // namespace na\n" + "namespace nb {\n" + "using na::A;\n" + "void d() { A a; }\n" + "} // nb\n"; + + std::string Expected = "namespace na {\n" + "template \n" + "class A { T t; };\n" + "} // namespace na\n" + "\n" + "namespace nc {\n" + "using ::na::A;\n" + "void d() { A a; }\n" + "} // namespace nc\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingShadowDeclOfTemplateFunction) { + OldNamespace = "nb"; + NewNamespace = "nc"; + std::string Code = "namespace na {\n" + "template \n" + "void f() { T t; };\n" + "} // namespace na\n" + "namespace nb {\n" + "using na::f;\n" + "void d() { f(); }\n" + "} // nb\n"; + + std::string Expected = "namespace na {\n" + "template \n" + "void f() { T t; };\n" + "} // namespace na\n" + "\n" + "namespace nc {\n" + "using ::na::f;\n" + "void d() { f(); }\n" + "} // namespace nc\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingAliasDecl) { + std::string Code = + "namespace nx { namespace ny { class X {}; } }\n" + "namespace na {\n" + "namespace nb {\n" + "using Y = nx::ny::X;\n" + "void f() { Y y; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "using Y = nx::ny::X;\n" + "void f() { Y y; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingAliasDeclInGlobal) { + std::string Code = + "namespace nx { namespace ny { class X {}; } }\n" + "using Y = nx::ny::X;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() { Y y; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" + "using Y = nx::ny::X;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() { Y y; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + + +TEST_F(ChangeNamespaceTest, TypedefAliasDecl) { + std::string Code = + "namespace nx { namespace ny { class X {}; } }\n" + "namespace na {\n" + "namespace nb {\n" + "typedef nx::ny::X Y;\n" + "void f() { Y y; }\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = "namespace nx { namespace ny { class X {}; } }\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "typedef nx::ny::X Y;\n" + "void f() { Y y; }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DerivedClassWithConstructors) { + std::string Code = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "namespace na {\n" + "namespace nb {\n" + "class A : public nx::ny::X {\n" + "public:\n" + " A() : X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : X(i) {}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A : public nx::ny::X {\n" + "public:\n" + " A() : X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : X(i) {}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DerivedClassWithQualifiedConstructors) { + std::string Code = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "namespace na {\n" + "namespace nb {\n" + "class A : public nx::ny::X {\n" + "public:\n" + " A() : X::X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : X::X(i) {}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A : public nx::ny::X {\n" + "public:\n" + " A() : X::X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : X::X(i) {}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DerivedClassWithConstructorsAndTypeRefs) { + std::string Code = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "namespace na {\n" + "namespace nb {\n" + "class A : public nx::ny::X {\n" + "public:\n" + " A() : X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : X(i) { X x(1);}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = + "namespace nx { namespace ny { class X { public: X(int i) {} }; } }\n" + "\n\n" + "namespace x {\n" + "namespace y {\n" + "class A : public nx::ny::X {\n" + "public:\n" + " A() : X(0) {}\n" + " A(int i);\n" + "};\n" + "A::A(int i) : X(i) { nx::ny::X x(1);}\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, MoveToGlobalNamespace) { + NewNamespace = ""; + std::string Code = "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "namespace nb {\n" + "class C_X {\n" + "public:\n" + " C_A a;\n" + " nc::C_C c;\n" + "};\n" + "class C_Y {\n" + " C_X x;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "\n" + "} // namespace na\n" + "class C_X {\n" + "public:\n" + " na::C_A a;\n" + " na::nc::C_C c;\n" + "};\n" + "class C_Y {\n" + " C_X x;\n" + "};\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, KeepGlobalSpecifier) { + std::string Code = "class Glob {};\n" + "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "namespace nb {\n" + "class C_X {\n" + "public:\n" + " ::Glob glob_1;\n" + " Glob glob_2;\n" + " C_A a_1;\n" + " ::na::C_A a_2;\n" + " nc::C_C c;\n" + "};\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "class Glob {};\n" + "namespace na {\n" + "class C_A {};\n" + "namespace nc {\n" + "class C_C {};" + "} // namespace nc\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "class C_X {\n" + "public:\n" + " ::Glob glob_1;\n" + " Glob glob_2;\n" + " na::C_A a_1;\n" + " ::na::C_A a_2;\n" + " na::nc::C_C c;\n" + "};\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, UsingAliasInTemplate) { + NewNamespace = "na::nb::nc"; + std::string Code = "namespace some_ns {\n" + "template \n" + "class G {};\n" + "} // namespace some_ns\n" + "namespace na {\n" + "template\n" + "using GG = some_ns::G;\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " GG g;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace some_ns {\n" + "template \n" + "class G {};\n" + "} // namespace some_ns\n" + "namespace na {\n" + "template\n" + "using GG = some_ns::G;\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "namespace nc {\n" + "void f() {\n" + " GG g;\n" + "}\n" + "} // namespace nc\n" + "} // namespace nb\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, TemplateUsingAliasInBaseClass) { + NewNamespace = "na::nb::nc"; + std::string Code = "namespace some_ns {\n" + "template \n" + "class G {};\n" + "} // namespace some_ns\n" + "namespace na {\n" + "class Base {\n" + "public:\n" + " template\n" + " using GG = some_ns::G;\n" + "\n" + " struct Nested {};\n" + "};\n" + "class Derived : public Base {};\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " Derived::GG g;\n" + " const Derived::GG gg;\n" + " const Derived::GG* gg_ptr;\n" + " struct Derived::Nested nested;\n" + " const struct Derived::Nested *nested_ptr;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace some_ns {\n" + "template \n" + "class G {};\n" + "} // namespace some_ns\n" + "namespace na {\n" + "class Base {\n" + "public:\n" + " template\n" + " using GG = some_ns::G;\n" + "\n" + " struct Nested {};\n" + "};\n" + "class Derived : public Base {};\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "namespace nc {\n" + "void f() {\n" + " Derived::GG g;\n" + " const Derived::GG gg;\n" + " const Derived::GG* gg_ptr;\n" + " struct Derived::Nested nested;\n" + " const struct Derived::Nested *nested_ptr;\n" + "}\n" + "} // namespace nc\n" + "} // namespace nb\n" + "} // namespace na\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, ExistingNamespaceConflictWithNewNamespace) { + OldNamespace = "nx"; + NewNamespace = "ny::na::nc"; + std::string Code = "namespace na {\n" + "class A {};\n" + "} // namespace na\n" + "namespace nb {\n" + "class B {};\n" + "} // namespace nb\n" + "namespace nx {\n" + "class X {\n" + " na::A a; nb::B b;\n" + "};\n" + "} // namespace nx\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "} // namespace na\n" + "namespace nb {\n" + "class B {};\n" + "} // namespace nb\n" + "\n" + "namespace ny {\n" + "namespace na {\n" + "namespace nc {\n" + "class X {\n" + " ::na::A a; nb::B b;\n" + "};\n" + "} // namespace nc\n" + "} // namespace na\n" + "} // namespace ny\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, SymbolConflictWithNewNamespace) { + OldNamespace = "nx"; + NewNamespace = "ny::na::nc"; + std::string Code = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "class B {};\n" + "} // namespace nb\n" + "} // namespace na\n" + "namespace ny {\n" + "class Y {};\n" + "}\n" + "namespace nx {\n" + "class X {\n" + " na::A a; na::nb::B b;\n" + " ny::Y y;" + "};\n" + "} // namespace nx\n"; + std::string Expected = "namespace na {\n" + "class A {};\n" + "namespace nb {\n" + "class B {};\n" + "} // namespace nb\n" + "} // namespace na\n" + "namespace ny {\n" + "class Y {};\n" + "}\n" + "\n" + "namespace ny {\n" + "namespace na {\n" + "namespace nc {\n" + "class X {\n" + " ::na::A a; ::na::nb::B b;\n" + " Y y;\n" + "};\n" + "} // namespace nc\n" + "} // namespace na\n" + "} // namespace ny\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, ShortenNamespaceSpecifier) { + OldNamespace = "nx"; + NewNamespace = "ny::na"; + std::string Code = "class G {};\n" + "namespace ny {\n" + "class Y {};\n" + "namespace na {\n" + "class A {};\n" + "namespace nc { class C {}; } // namespace nc\n" + "}\n // namespace na\n" + "}\n // namespace ny\n" + "namespace nx {\n" + "class X {\n" + " G g; ny::Y y; ny::na::A a; ny::na::nc::C c;\n" + "};\n" + "} // namespace nx\n"; + std::string Expected = "class G {};\n" + "namespace ny {\n" + "class Y {};\n" + "namespace na {\n" + "class A {};\n" + "namespace nc { class C {}; } // namespace nc\n" + "}\n // namespace na\n" + "}\n // namespace ny\n" + "\n" + "namespace ny {\n" + "namespace na {\n" + "class X {\n" + " G g; Y y; A a; nc::C c;\n" + "};\n" + "} // namespace na\n" + "} // namespace ny\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, ShortenNamespaceSpecifierInAnonymousNamespace) { + OldNamespace = "nx"; + NewNamespace = "ny::na"; + std::string Code = "class G {};\n" + "namespace ny {\n" + "class Y {};\n" + "namespace na {\n" + "class A {};\n" + "namespace nc { class C {}; } // namespace nc\n" + "}\n // namespace na\n" + "}\n // namespace ny\n" + "namespace nx {\n" + "namespace {\n" + "class X {\n" + " G g; ::ny::Y y; ::ny::na::A a; ::ny::na::nc::C c;\n" + "};\n" + "} // namespace\n" + "} // namespace nx\n"; + std::string Expected = "class G {};\n" + "namespace ny {\n" + "class Y {};\n" + "namespace na {\n" + "class A {};\n" + "namespace nc { class C {}; } // namespace nc\n" + "}\n // namespace na\n" + "}\n // namespace ny\n" + "\n" + "namespace ny {\n" + "namespace na {\n" + "namespace {\n" + "class X {\n" + " G g; Y y; A a; nc::C c;\n" + "};\n" + "} // namespace\n" + "} // namespace na\n" + "} // namespace ny\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, SimpleMoveEnum) { + std::string Code = "namespace na {\n" + "namespace nb {\n" + "enum class X { X1, X2 };\n" + "enum Y { Y1, Y2 };\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "\n\nnamespace x {\n" + "namespace y {\n" + "enum class X { X1, X2 };\n" + "enum Y { Y1, Y2 };\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, ReferencesToEnums) { + std::string Code = "enum Glob { G1, G2 };\n" + "namespace na {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2 };\n" + "namespace nb {\n" + "void f() {\n" + " Glob g1 = Glob::G1;\n" + " Glob g2 = G2;\n" + " X x1 = X::X1;\n" + " Y y1 = Y::Y1;\n" + " Y y2 = Y2;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "enum Glob { G1, G2 };\n" + "namespace na {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2 };\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " Glob g1 = Glob::G1;\n" + " Glob g2 = G2;\n" + " na::X x1 = na::X::X1;\n" + " na::Y y1 = na::Y::Y1;\n" + " na::Y y2 = na::Y2;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, NoRedundantEnumUpdate) { + std::string Code = "namespace ns {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2 };\n" + "} // namespace ns\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " ns::X x1 = ns::X::X1;\n" + " ns::Y y1 = ns::Y::Y1;\n" + " ns::Y y2 = ns::Y2;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace ns {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2 };\n" + "} // namespace ns\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " ns::X x1 = ns::X::X1;\n" + " ns::Y y1 = ns::Y::Y1;\n" + " ns::Y y2 = ns::Y2;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + ; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, EnumsAndUsingShadows) { + std::string Code = "namespace ns {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2, Y3 };\n" + "} // namespace ns\n" + "using ns::X;\n" + "using ns::Y;\n" + "using ns::Y::Y2;\n" + "using ns::Y::Y3;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " X x1 = X::X1;\n" + " Y y1 = Y::Y1;\n" + " Y y2 = Y2;\n" + " Y y3 = Y3;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace ns {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2, Y3 };\n" + "} // namespace ns\n" + "using ns::X;\n" + "using ns::Y;\n" + "using ns::Y::Y2;\n" + "using ns::Y::Y3;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " X x1 = X::X1;\n" + " Y y1 = Y::Y1;\n" + " Y y2 = Y2;\n" + " Y y3 = Y3;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, EnumsAndAliases) { + std::string Code = "namespace ns {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2, Y3 };\n" + "} // namespace ns\n" + "typedef ns::X TX;\n" + "typedef ns::Y TY;\n" + "using UX = ns::X;\n" + "using UY = ns::Y;\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " ns::X x1 = ns::X::X1;\n" + " TX tx1 = TX::X1;\n" + " UX ux1 = UX::X1;\n" + " ns::Y y1 = ns::Y::Y1;\n" + " TY ty1 = TY::Y1;\n" + " UY uy1 = UY::Y1;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace ns {\n" + "enum class X { X1 };\n" + "enum Y { Y1, Y2, Y3 };\n" + "} // namespace ns\n" + "typedef ns::X TX;\n" + "typedef ns::Y TY;\n" + "using UX = ns::X;\n" + "using UY = ns::Y;\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " ns::X x1 = ns::X::X1;\n" + " TX tx1 = TX::X1;\n" + " UX ux1 = UX::X1;\n" + " ns::Y y1 = ns::Y::Y1;\n" + " TY ty1 = TY::Y1;\n" + " UY uy1 = UY::Y1;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, EnumInClass) { + std::string Code = "namespace na {\n" + "struct X { enum E { E1 }; };\n" + "namespace nb {\n" + "void f() {\n" + " X::E e = X::E1;\n" + " X::E ee = X::E::E1;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "struct X { enum E { E1 }; };\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " na::X::E e = na::X::E1;\n" + " na::X::E ee = na::X::E::E1;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, TypeAsTemplateParameter) { + std::string Code = "namespace na {\n" + "struct X {};\n" + "namespace nb {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "struct X {};\n" + "\n" + "} // namespace na\n" + "namespace x {\n" + "namespace y {\n" + "template \n" + "void TempTemp(const TT& t) {\n" + " TT tmp;\n" + "}\n" + "template \n" + "void Temp(const T& t) {\n" + " T tmp = t;\n" + " TempTemp(tmp);\n" + " TempTemp(t);\n" + "}\n" + "void f() {\n" + " na::X x;\n" + " Temp(x);\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, DefaultMoveConstructors) { + std::string Code = "namespace na {\n" + "class B {\n" + " public:\n" + " B() = default;\n" + " // Allow move only.\n" + " B(B&&) = default;\n" + " B& operator=(B&&) = default;\n" + " B(const B&) = delete;\n" + " B& operator=(const B&) = delete;\n" + " private:\n" + " int ref_;\n" + "};\n" + "} // namespace na\n" + "namespace na {\n" + "namespace nb {\n" + "class A {\n" + "public:\n" + " A() = default;\n" + " A(A&&) = default;\n" + " A& operator=(A&&) = default;\n" + "private:\n" + " B b;\n" + " A(const A&) = delete;\n" + " A& operator=(const A&) = delete;\n" + "};\n" + "void f() { A a; a = A(); A aa = A(); }\n" + "} // namespace nb\n" + "} // namespace na\n"; + std::string Expected = "namespace na {\n" + "class B {\n" + " public:\n" + " B() = default;\n" + " // Allow move only.\n" + " B(B&&) = default;\n" + " B& operator=(B&&) = default;\n" + " B(const B&) = delete;\n" + " B& operator=(const B&) = delete;\n" + " private:\n" + " int ref_;\n" + "};\n" + "} // namespace na\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "class A {\n" + "public:\n" + " A() = default;\n" + " A(A&&) = default;\n" + " A& operator=(A&&) = default;\n" + "private:\n" + " na::B b;\n" + " A(const A&) = delete;\n" + " A& operator=(const A&) = delete;\n" + "};\n" + "void f() { A a; a = A(); A aa = A(); }\n" + "} // namespace y\n" + "} // namespace x\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, InjectedClassNameInFriendDecl) { + OldNamespace = "d"; + NewNamespace = "e"; + std::string Code = "namespace a{\n" + "template \n" + "class Base {\n" + " public:\n" + " void f() {\n" + " T t;\n" + " t.priv();\n" + " }\n" + "};\n" + "} // namespace a\n" + "namespace d {\n" + "class D : public a::Base {\n" + " private:\n" + " friend class Base;\n" + " void priv() {}\n" + " Base b;\n" + "};\n" + "\n" + "void f() {\n" + " D d;\n" + " a:: Base b;\n" + " b.f();\n" + "}\n" + "} // namespace d\n"; + std::string Expected = "namespace a{\n" + "template \n" + "class Base {\n" + " public:\n" + " void f() {\n" + " T t;\n" + " t.priv();\n" + " }\n" + "};\n" + "} // namespace a\n" + "\n" + "namespace e {\n" + "class D : public a::Base {\n" + " private:\n" + " friend class Base;\n" + " void priv() {}\n" + " a::Base b;\n" + "};\n" + "\n" + "void f() {\n" + " D d;\n" + " a::Base b;\n" + " b.f();\n" + "}\n" + "} // namespace e\n"; + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +TEST_F(ChangeNamespaceTest, FullyQualifyConflictNamespace) { + std::string Code = + "namespace x { namespace util { class Some {}; } }\n" + "namespace x { namespace y {namespace base { class Base {}; } } }\n" + "namespace util { class Status {}; }\n" + "namespace base { class Base {}; }\n" + "namespace na {\n" + "namespace nb {\n" + "void f() {\n" + " util::Status s1; x::util::Some s2;\n" + " base::Base b1; x::y::base::Base b2;\n" + "}\n" + "} // namespace nb\n" + "} // namespace na\n"; + + std::string Expected = + "namespace x { namespace util { class Some {}; } }\n" + "namespace x { namespace y {namespace base { class Base {}; } } }\n" + "namespace util { class Status {}; }\n" + "namespace base { class Base {}; }\n" + "\n" + "namespace x {\n" + "namespace y {\n" + "void f() {\n" + " ::util::Status s1; util::Some s2;\n" + " ::base::Base b1; base::Base b2;\n" + "}\n" + "} // namespace y\n" + "} // namespace x\n"; + + EXPECT_EQ(format(Expected), runChangeNamespaceOnCode(Code)); +} + +} // anonymous namespace +} // namespace change_namespace +} // namespace clang -- cgit v1.2.3 From e6e8ff97f19c941d64de6a6fd32f929d0e7a2bc1 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Fri, 15 Mar 2019 14:00:49 +0000 Subject: [clangd] Tune the fuzzy-matching algorithm Summary: To reduce the gap between prefix and initialism matches. The motivation is producing better scoring in one particular example, but the change does not seem to cause large regressions in other cases. The examples is matching 'up' against 'unique_ptr' and 'upper_bound'. Before the change, we had: - "[u]nique_[p]tr" with a score of 0.3, - "[up]per_bound" with a score of 1.0. A 3x difference meant that symbol quality signals were almost always ignored and 'upper_bound' was always ranked higher. However, intuitively, the match scores should be very close for the two. After the change we have the following scores: - "[u]nique_[p]tr" with a score of 0.75, - "[up]per_bound" with a score of 1.0. Reviewers: ioeric Reviewed By: ioeric Subscribers: MaskRay, jkorous, arphaman, kadircet, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59300 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356261 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/FuzzyMatch.cpp | 29 ++++++++++++++++++----------- unittests/clangd/FuzzyMatchTests.cpp | 11 ++++++++++- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/clangd/FuzzyMatch.cpp b/clangd/FuzzyMatch.cpp index bc613868..57f9554a 100644 --- a/clangd/FuzzyMatch.cpp +++ b/clangd/FuzzyMatch.cpp @@ -71,7 +71,7 @@ static char lower(char C) { return C >= 'A' && C <= 'Z' ? C + ('a' - 'A') : C; } // Score field is 15 bits wide, min value is -2^14, we use half of that. static constexpr int AwfulScore = -(1 << 13); static bool isAwful(int S) { return S < AwfulScore / 2; } -static constexpr int PerfectBonus = 3; // Perfect per-pattern-char score. +static constexpr int PerfectBonus = 4; // Perfect per-pattern-char score. FuzzyMatcher::FuzzyMatcher(llvm::StringRef Pattern) : PatN(std::min(MaxPat, Pattern.size())), @@ -267,24 +267,31 @@ bool FuzzyMatcher::allowMatch(int P, int W, Action Last) const { } int FuzzyMatcher::skipPenalty(int W, Action Last) const { - int S = 0; + if (W == 0) // Skipping the first character. + return 3; if (WordRole[W] == Head) // Skipping a segment. - S += 1; - if (Last == Match) // Non-consecutive match. - S += 2; // We'd rather skip a segment than split our match. - return S; + return 1; // We want to keep this lower than a consecutive match bonus. + // Instead of penalizing non-consecutive matches, we give a bonus to a + // consecutive match in matchBonus. This produces a better score distribution + // than penalties in case of small patterns, e.g. 'up' for 'unique_ptr'. + return 0; } int FuzzyMatcher::matchBonus(int P, int W, Action Last) const { assert(LowPat[P] == LowWord[W]); int S = 1; - // Bonus: pattern so far is a (case-insensitive) prefix of the word. - if (P == W) // We can't skip pattern characters, so we must have matched all. - ++S; + bool IsPatSingleCase = + (PatTypeSet == 1 << Lower) || (PatTypeSet == 1 << Upper); // Bonus: case matches, or a Head in the pattern aligns with one in the word. - if ((Pat[P] == Word[W] && ((PatTypeSet & 1 << Upper) || P == W)) || - (PatRole[P] == Head && WordRole[W] == Head)) + // Single-case patterns lack segmentation signals and we assume any character + // can be a head of a segment. + if (Pat[P] == Word[W] || + (WordRole[W] == Head && (IsPatSingleCase || PatRole[P] == Head))) ++S; + // Bonus: a consecutive match. First character match also gets a bonus to + // ensure prefix final match score normalizes to 1.0. + if (W == 0 || Last == Match) + S += 2; // Penalty: matching inside a segment (and previous char wasn't matched). if (WordRole[W] == Tail && P && Last == Miss) S -= 3; diff --git a/unittests/clangd/FuzzyMatchTests.cpp b/unittests/clangd/FuzzyMatchTests.cpp index d2ddbdaf..bd77b1c1 100644 --- a/unittests/clangd/FuzzyMatchTests.cpp +++ b/unittests/clangd/FuzzyMatchTests.cpp @@ -9,6 +9,7 @@ #include "FuzzyMatch.h" #include "llvm/ADT/StringExtras.h" +#include "gmock/gmock-matchers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" @@ -247,6 +248,8 @@ TEST(FuzzyMatch, Ranking) { EXPECT_THAT("foo", ranks("[foo]", "[Foo]")); EXPECT_THAT("onMes", ranks("[onMes]sage", "[onmes]sage", "[on]This[M]ega[Es]capes")); + EXPECT_THAT("onmes", + ranks("[onmes]sage", "[onMes]sage", "[on]This[M]ega[Es]capes")); EXPECT_THAT("CC", ranks("[C]amel[C]ase", "[c]amel[C]ase")); EXPECT_THAT("cC", ranks("[c]amel[C]ase", "[C]amel[C]ase")); EXPECT_THAT("p", ranks("[p]", "[p]arse", "[p]osix", "[p]afdsa", "[p]ath")); @@ -270,12 +273,18 @@ TEST(FuzzyMatch, Ranking) { // Verify some bounds so we know scores fall in the right range. // Testing exact scores is fragile, so we prefer Ranking tests. TEST(FuzzyMatch, Scoring) { - EXPECT_THAT("abs", matches("[a]w[B]xYz[S]", 0.f)); + EXPECT_THAT("abs", matches("[a]w[B]xYz[S]", 7.f / 12.f)); EXPECT_THAT("abs", matches("[abs]l", 1.f)); EXPECT_THAT("abs", matches("[abs]", 2.f)); EXPECT_THAT("Abs", matches("[abs]", 2.f)); } +TEST(FuzzyMatch, InitialismAndPrefix) { + // We want these scores to be roughly the same. + EXPECT_THAT("up", matches("[u]nique_[p]tr", 3.f / 4.f)); + EXPECT_THAT("up", matches("[up]per_bound", 1.f)); +} + // Returns pretty-printed segmentation of Text. // e.g. std::basic_string --> +-- +---- +----- std::string segment(llvm::StringRef Text) { -- cgit v1.2.3 From e71a1e9e22924107df1abad75035e762ad10aaa8 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Fri, 15 Mar 2019 14:30:07 +0000 Subject: [clangd] Remove includes of "gmock-matchers.h". NFC For consistency with most of the test code. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356264 91177308-0d34-0410-b5e6-96231b3b80d8 --- unittests/clangd/ExpectedTypeTest.cpp | 1 - unittests/clangd/FuzzyMatchTests.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/unittests/clangd/ExpectedTypeTest.cpp b/unittests/clangd/ExpectedTypeTest.cpp index d109c790..8d2d60eb 100644 --- a/unittests/clangd/ExpectedTypeTest.cpp +++ b/unittests/clangd/ExpectedTypeTest.cpp @@ -12,7 +12,6 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "llvm/ADT/StringRef.h" -#include "gmock/gmock-matchers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" diff --git a/unittests/clangd/FuzzyMatchTests.cpp b/unittests/clangd/FuzzyMatchTests.cpp index bd77b1c1..6d5d88c0 100644 --- a/unittests/clangd/FuzzyMatchTests.cpp +++ b/unittests/clangd/FuzzyMatchTests.cpp @@ -9,7 +9,6 @@ #include "FuzzyMatch.h" #include "llvm/ADT/StringExtras.h" -#include "gmock/gmock-matchers.h" #include "gmock/gmock.h" #include "gtest/gtest.h" -- cgit v1.2.3 From 3efd5ed8f122709bdfe64890123b24af9e71ecd2 Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Mon, 18 Mar 2019 13:30:17 +0000 Subject: [pp-trace] Delete -ignore and add a new option -callbacks Summary: -ignore specifies a list of PP callbacks to ignore. It cannot express a whitelist, which may be more useful than a blacklist. Add a new option -callbacks to replace it. -ignore= (default) => -callbacks='*' (default) -ignore=FileChanged,FileSkipped => -callbacks='*,-FileChanged,-FileSkipped' -callbacks='Macro*' : print only MacroDefined,MacroExpands,MacroUndefined,... Reviewers: juliehockett, aaron.ballman, alexfh, ioeric Reviewed By: aaron.ballman Subscribers: nemanjai, kbarton, jsji, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59296 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356366 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/ReleaseNotes.rst | 6 +++ docs/pp-trace.rst | 10 ++-- pp-trace/PPCallbacksTracker.cpp | 13 +++-- pp-trace/PPCallbacksTracker.h | 15 ++++-- pp-trace/PPTrace.cpp | 80 ++++++++++++++----------------- test/pp-trace/pp-trace-conditional.cpp | 2 +- test/pp-trace/pp-trace-filter.cpp | 17 +++++++ test/pp-trace/pp-trace-ident.cpp | 2 +- test/pp-trace/pp-trace-macro.cpp | 2 +- test/pp-trace/pp-trace-modules.cpp | 2 +- test/pp-trace/pp-trace-pragma-general.cpp | 2 +- test/pp-trace/pp-trace-pragma-ms.cpp | 2 +- test/pp-trace/pp-trace-pragma-opencl.cpp | 2 +- 13 files changed, 91 insertions(+), 64 deletions(-) create mode 100644 test/pp-trace/pp-trace-filter.cpp diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 9f464f97..76e85023 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -132,3 +132,9 @@ Improvements to modularize -------------------------- The improvements are... + +Improvements to pp-trace +------------------------ + +- Added a new option `-callbacks` to filter preprocessor callbacks. It replaces + the `-ignore` option. diff --git a/docs/pp-trace.rst b/docs/pp-trace.rst index 9cfbef59..8bfe1baf 100644 --- a/docs/pp-trace.rst +++ b/docs/pp-trace.rst @@ -40,12 +40,12 @@ which must follow the . Command Line Options -------------------- -.. option:: -ignore +.. option:: -callbacks - This option specifies a comma-separated list of names of callbacks - that shouldn't be traced. It can be used to eliminate unwanted - trace output. The callback names are the name of the actual - callback function names in the PPCallbacks class: + This option specifies a comma-separated list of globs describing the list of + callbacks that should be traced. Globs are processed in order of appearance. + Positive globs add matched callbacks to the set, netative globs (those with + the '-' prefix) remove callacks from the set. * FileChanged * FileSkipped diff --git a/pp-trace/PPCallbacksTracker.cpp b/pp-trace/PPCallbacksTracker.cpp index e2d8738e..a4eec949 100644 --- a/pp-trace/PPCallbacksTracker.cpp +++ b/pp-trace/PPCallbacksTracker.cpp @@ -88,10 +88,10 @@ static const char *const MappingStrings[] = { "0", "MAP_IGNORE", // PPCallbacksTracker functions. -PPCallbacksTracker::PPCallbacksTracker(llvm::SmallSet &Ignore, +PPCallbacksTracker::PPCallbacksTracker(const FilterType &Filters, std::vector &CallbackCalls, clang::Preprocessor &PP) - : CallbackCalls(CallbackCalls), Ignore(Ignore), PP(PP) {} + : CallbackCalls(CallbackCalls), Filters(Filters), PP(PP) {} PPCallbacksTracker::~PPCallbacksTracker() {} @@ -425,7 +425,14 @@ void PPCallbacksTracker::Endif(clang::SourceLocation Loc, // Start a new callback. void PPCallbacksTracker::beginCallback(const char *Name) { - DisableTrace = Ignore.count(std::string(Name)); + auto R = CallbackIsEnabled.try_emplace(Name, false); + if (R.second) { + llvm::StringRef N(Name); + for (const std::pair &Filter : Filters) + if (Filter.first.match(N)) + R.first->second = Filter.second; + } + DisableTrace = !R.first->second; if (DisableTrace) return; CallbackCalls.push_back(CallbackCall(Name)); diff --git a/pp-trace/PPCallbacksTracker.h b/pp-trace/PPCallbacksTracker.h index afb8d37a..acf2deff 100644 --- a/pp-trace/PPCallbacksTracker.h +++ b/pp-trace/PPCallbacksTracker.h @@ -26,7 +26,9 @@ #include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/GlobPattern.h" #include #include @@ -53,6 +55,8 @@ public: std::vector Arguments; }; +using FilterType = std::vector>; + /// \brief This class overrides the PPCallbacks class for tracking preprocessor /// activity by means of its callback functions. /// @@ -74,10 +78,10 @@ class PPCallbacksTracker : public clang::PPCallbacks { public: /// \brief Note that all of the arguments are references, and owned /// by the caller. - /// \param Ignore - Set of names of callbacks to ignore. + /// \param Filters - List of (Glob,Enabled) pairs used to filter callbacks. /// \param CallbackCalls - Trace buffer. /// \param PP - The preprocessor. Needed for getting some argument strings. - PPCallbacksTracker(llvm::SmallSet &Ignore, + PPCallbacksTracker(const FilterType &Filters, std::vector &CallbackCalls, clang::Preprocessor &PP); @@ -239,8 +243,11 @@ public: /// after this object is destructed. std::vector &CallbackCalls; - /// \brief Names of callbacks to ignore. - llvm::SmallSet &Ignore; + // List of (Glob,Enabled) pairs used to filter callbacks. + const FilterType &Filters; + + // Whether a callback should be printed. + llvm::StringMap CallbackIsEnabled; /// \brief Inhibit trace while this is set. bool DisableTrace; diff --git a/pp-trace/PPTrace.cpp b/pp-trace/PPTrace.cpp index 65248285..69b2adfe 100644 --- a/pp-trace/PPTrace.cpp +++ b/pp-trace/PPTrace.cpp @@ -22,27 +22,6 @@ // Basically you put the pp-trace options first, then the source file or files, // and then any options you want to pass to the compiler. // -// These are the pp-trace options: -// -// -ignore (callback list) Don't display output for a comma-separated -// list of callbacks, i.e.: -// -ignore "FileChanged,InclusionDirective" -// -// -output (file) Output trace to the given file in a YAML -// format, e.g.: -// -// --- -// - Callback: Name -// Argument1: Value1 -// Argument2: Value2 -// (etc.) -// ... -// -// Future Directions: -// -// 1. Add option opposite to "-ignore" that specifys a comma-separated option -// list of callbacs. Perhaps "-only" or "-exclusive". -// //===----------------------------------------------------------------------===// #include "PPCallbacksTracker.h" @@ -62,9 +41,11 @@ #include "llvm/Option/Option.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/GlobPattern.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/WithColor.h" #include #include #include @@ -82,10 +63,12 @@ static cl::list SourcePaths(cl::Positional, cl::desc(" [... ]"), cl::OneOrMore); -// Option to specify a list or one or more callback names to ignore. -static cl::opt IgnoreCallbacks( - "ignore", cl::init(""), - cl::desc("Ignore callbacks, i.e. \"Callback1, Callback2...\".")); +static cl::opt Callbacks( + "callbacks", cl::init("*"), + cl::desc("Comma-separated list of globs describing the list of callbacks " + "to output. Globs are processed in order of appearance. Globs " + "with the '-' prefix remove callbacks from the set. e.g. " + "'*,-Macro*'.")); // Option to specify the trace output file name. static cl::opt OutputFileName( @@ -103,44 +86,44 @@ namespace { // Consumer is responsible for setting up the callbacks. class PPTraceConsumer : public ASTConsumer { public: - PPTraceConsumer(SmallSet &Ignore, + PPTraceConsumer(const FilterType &Filters, std::vector &CallbackCalls, Preprocessor &PP) { // PP takes ownership. - PP.addPPCallbacks(llvm::make_unique(Ignore, - CallbackCalls, PP)); + PP.addPPCallbacks( + llvm::make_unique(Filters, CallbackCalls, PP)); } }; class PPTraceAction : public SyntaxOnlyAction { public: - PPTraceAction(SmallSet &Ignore, + PPTraceAction(const FilterType &Filters, std::vector &CallbackCalls) - : Ignore(Ignore), CallbackCalls(CallbackCalls) {} + : Filters(Filters), CallbackCalls(CallbackCalls) {} protected: std::unique_ptr CreateASTConsumer(CompilerInstance &CI, StringRef InFile) override { - return llvm::make_unique(Ignore, CallbackCalls, + return llvm::make_unique(Filters, CallbackCalls, CI.getPreprocessor()); } private: - SmallSet &Ignore; + const FilterType &Filters; std::vector &CallbackCalls; }; class PPTraceFrontendActionFactory : public FrontendActionFactory { public: - PPTraceFrontendActionFactory(SmallSet &Ignore, + PPTraceFrontendActionFactory(const FilterType &Filters, std::vector &CallbackCalls) - : Ignore(Ignore), CallbackCalls(CallbackCalls) {} + : Filters(Filters), CallbackCalls(CallbackCalls) {} PPTraceAction *create() override { - return new PPTraceAction(Ignore, CallbackCalls); + return new PPTraceAction(Filters, CallbackCalls); } private: - SmallSet &Ignore; + const FilterType &Filters; std::vector &CallbackCalls; }; } // namespace @@ -177,14 +160,21 @@ int main(int Argc, const char **Argv) { cl::ParseCommandLineOptions(Argc, Argv, "pp-trace.\n"); // Parse the IgnoreCallbacks list into strings. - SmallVector IgnoreCallbacksStrings; - StringRef(IgnoreCallbacks).split(IgnoreCallbacksStrings, ",", - /*MaxSplit=*/ -1, /*KeepEmpty=*/false); - SmallSet Ignore; - for (SmallVector::iterator I = IgnoreCallbacksStrings.begin(), - E = IgnoreCallbacksStrings.end(); - I != E; ++I) - Ignore.insert(*I); + SmallVector Patterns; + FilterType Filters; + StringRef(Callbacks).split(Patterns, ",", + /*MaxSplit=*/-1, /*KeepEmpty=*/false); + for (StringRef Pattern : Patterns) { + Pattern = Pattern.trim(); + bool Enabled = !Pattern.consume_front("-"); + if (Expected Pat = GlobPattern::create(Pattern)) + Filters.emplace_back(std::move(*Pat), Enabled); + else { + WithColor::error(llvm::errs(), "pp-trace") + << toString(Pat.takeError()) << '\n'; + return 1; + } + } // Create the compilation database. SmallString<256> PathBuf; @@ -198,7 +188,7 @@ int main(int Argc, const char **Argv) { // Create the tool and run the compilation. ClangTool Tool(*Compilations, SourcePaths); - PPTraceFrontendActionFactory Factory(Ignore, CallbackCalls); + PPTraceFrontendActionFactory Factory(Filters, CallbackCalls); int HadErrors = Tool.run(&Factory); // If we had errors, exit early. diff --git a/test/pp-trace/pp-trace-conditional.cpp b/test/pp-trace/pp-trace-conditional.cpp index 8e7ce887..7787c586 100644 --- a/test/pp-trace/pp-trace-conditional.cpp +++ b/test/pp-trace/pp-trace-conditional.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged' %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #if 1 #endif diff --git a/test/pp-trace/pp-trace-filter.cpp b/test/pp-trace/pp-trace-filter.cpp new file mode 100644 index 00000000..915945ea --- /dev/null +++ b/test/pp-trace/pp-trace-filter.cpp @@ -0,0 +1,17 @@ +// RUN: pp-trace -callbacks 'File*,Macro*,-MacroUndefined' %s | FileCheck %s +// RUN: pp-trace -callbacks ' File* , Macro* , -MacroUndefined ' %s | FileCheck %s +// RUN: not pp-trace -callbacks '[' %s 2>&1 | FileCheck --check-prefix=INVALID %s + +#define M 1 +int i = M; +#undef M + +// CHECK: --- +// CHECK: - Callback: FileChanged +// CHECK: - Callback: MacroDefined +// CHECK: - Callback: MacroExpands +// CHECK-NOT: - Callback: MacroUndefined +// CHECK-NOT: - Callback: EndOfMainFile +// CHECK: ... + +// INVALID: error: invalid glob pattern: [ diff --git a/test/pp-trace/pp-trace-ident.cpp b/test/pp-trace/pp-trace-ident.cpp index 9981c39e..8c93c728 100644 --- a/test/pp-trace/pp-trace-ident.cpp +++ b/test/pp-trace/pp-trace-ident.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #ident "$Id$" diff --git a/test/pp-trace/pp-trace-macro.cpp b/test/pp-trace/pp-trace-macro.cpp index 1202aa20..bd711e9e 100644 --- a/test/pp-trace/pp-trace-macro.cpp +++ b/test/pp-trace/pp-trace-macro.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged' %s -undef -target x86_64 -std=c++11 | FileCheck --strict-whitespace %s #define MACRO 1 int i = MACRO; diff --git a/test/pp-trace/pp-trace-modules.cpp b/test/pp-trace/pp-trace-modules.cpp index 5e9e1de3..bfe376e2 100644 --- a/test/pp-trace/pp-trace-modules.cpp +++ b/test/pp-trace/pp-trace-modules.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -x objective-c++ -undef -target x86_64 -std=c++11 -fmodules -fcxx-modules -fmodules-cache-path=%t -I%S -I%S/Input | FileCheck --strict-whitespace %s // CHECK: --- diff --git a/test/pp-trace/pp-trace-pragma-general.cpp b/test/pp-trace/pp-trace-pragma-general.cpp index 6caef0b6..75c53984 100644 --- a/test/pp-trace/pp-trace-pragma-general.cpp +++ b/test/pp-trace/pp-trace-pragma-general.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s | FileCheck --strict-whitespace %s #pragma clang diagnostic push #pragma clang diagnostic pop diff --git a/test/pp-trace/pp-trace-pragma-ms.cpp b/test/pp-trace/pp-trace-pragma-ms.cpp index 33c9f7fa..31a757b9 100644 --- a/test/pp-trace/pp-trace-pragma-ms.cpp +++ b/test/pp-trace/pp-trace-pragma-ms.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -target x86_64-unknown-windows-msvc -fms-extensions -w | FileCheck --strict-whitespace %s #pragma comment(compiler, "compiler comment") #pragma comment(exestr, "exestr comment") diff --git a/test/pp-trace/pp-trace-pragma-opencl.cpp b/test/pp-trace/pp-trace-pragma-opencl.cpp index cfd72c0d..413b5d07 100644 --- a/test/pp-trace/pp-trace-pragma-opencl.cpp +++ b/test/pp-trace/pp-trace-pragma-opencl.cpp @@ -1,4 +1,4 @@ -// RUN: pp-trace -ignore FileChanged,MacroDefined %s -x cl | FileCheck --strict-whitespace %s +// RUN: pp-trace -callbacks '*,-FileChanged,-MacroDefined' %s -x cl | FileCheck --strict-whitespace %s #pragma OPENCL EXTENSION all : disable #pragma OPENCL EXTENSION cl_khr_int64_base_atomics : disable -- cgit v1.2.3 From c3057fd21153945c573b5e60765b192df24235f9 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Tue, 19 Mar 2019 09:27:04 +0000 Subject: [clangd] Add support for type hierarchy (super types only for now) Summary: Patch by Nathan Ridge(@nridge)! This is an LSP extension proposed here: https://github.com/Microsoft/vscode-languageserver-node/pull/426 An example client implementation can be found here: https://github.com/theia-ide/theia/pull/3802 Reviewers: kadircet, sammccall Reviewed By: kadircet Subscribers: jdoerfert, sammccall, cfe-commits, mgorny, dschaefer, simark, ilya-biryukov, ioeric, MaskRay, jkorous, arphaman, kadircet Tags: #clang Differential Revision: https://reviews.llvm.org/D56370 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356445 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/ClangdLSPServer.cpp | 9 + clangd/ClangdLSPServer.h | 2 + clangd/ClangdServer.cpp | 18 +- clangd/ClangdServer.h | 5 + clangd/FindSymbols.cpp | 61 +---- clangd/FindSymbols.h | 7 +- clangd/Protocol.cpp | 115 ++++++++ clangd/Protocol.h | 68 +++++ clangd/XRefs.cpp | 133 +++++++++ clangd/XRefs.h | 11 + clangd/index/SymbolCollector.cpp | 7 +- clangd/index/SymbolCollector.h | 3 +- test/clangd/initialize-params.test | 1 + test/clangd/type-hierarchy.test | 92 +++++++ unittests/clangd/CMakeLists.txt | 1 + unittests/clangd/Matchers.h | 67 +++++ unittests/clangd/TypeHierarchyTests.cpp | 462 ++++++++++++++++++++++++++++++++ 17 files changed, 991 insertions(+), 71 deletions(-) create mode 100644 test/clangd/type-hierarchy.test create mode 100644 unittests/clangd/TypeHierarchyTests.cpp diff --git a/clangd/ClangdLSPServer.cpp b/clangd/ClangdLSPServer.cpp index 981c69df..bddea904 100644 --- a/clangd/ClangdLSPServer.cpp +++ b/clangd/ClangdLSPServer.cpp @@ -368,6 +368,7 @@ void ClangdLSPServer::onInitialize(const InitializeParams &Params, {ExecuteCommandParams::CLANGD_APPLY_FIX_COMMAND, ExecuteCommandParams::CLANGD_APPLY_TWEAK}}, }}, + {"typeHierarchyProvider", true}, }}}}); } @@ -806,6 +807,13 @@ void ClangdLSPServer::onHover(const TextDocumentPositionParams &Params, std::move(Reply)); } +void ClangdLSPServer::onTypeHierarchy( + const TypeHierarchyParams &Params, + Callback> Reply) { + Server->typeHierarchy(Params.textDocument.uri.file(), Params.position, + Params.resolve, Params.direction, std::move(Reply)); +} + void ClangdLSPServer::applyConfiguration( const ConfigurationSettings &Settings) { // Per-file update to the compilation database. @@ -885,6 +893,7 @@ ClangdLSPServer::ClangdLSPServer(class Transport &Transp, MsgHandler->bind("workspace/didChangeWatchedFiles", &ClangdLSPServer::onFileEvent); MsgHandler->bind("workspace/didChangeConfiguration", &ClangdLSPServer::onChangeConfiguration); MsgHandler->bind("textDocument/symbolInfo", &ClangdLSPServer::onSymbolInfo); + MsgHandler->bind("textDocument/typeHierarchy", &ClangdLSPServer::onTypeHierarchy); // clang-format on } diff --git a/clangd/ClangdLSPServer.h b/clangd/ClangdLSPServer.h index cda46ad1..90971bc8 100644 --- a/clangd/ClangdLSPServer.h +++ b/clangd/ClangdLSPServer.h @@ -93,6 +93,8 @@ private: void onRename(const RenameParams &, Callback); void onHover(const TextDocumentPositionParams &, Callback>); + void onTypeHierarchy(const TypeHierarchyParams &, + Callback>); void onChangeConfiguration(const DidChangeConfigurationParams &); void onSymbolInfo(const TextDocumentPositionParams &, Callback>); diff --git a/clangd/ClangdServer.cpp b/clangd/ClangdServer.cpp index 9dc33280..a265f372 100644 --- a/clangd/ClangdServer.cpp +++ b/clangd/ClangdServer.cpp @@ -362,9 +362,8 @@ void ClangdServer::enumerateTweaks(PathRef File, Range Sel, void ClangdServer::applyTweak(PathRef File, Range Sel, StringRef TweakID, Callback CB) { - auto Action = [Sel](decltype(CB) CB, std::string File, - std::string TweakID, - Expected InpAST) { + auto Action = [Sel](decltype(CB) CB, std::string File, std::string TweakID, + Expected InpAST) { if (!InpAST) return CB(InpAST.takeError()); auto Selection = tweakSelection(Sel, *InpAST); @@ -523,6 +522,19 @@ void ClangdServer::findHover(PathRef File, Position Pos, WorkScheduler.runWithAST("Hover", File, Bind(Action, std::move(CB))); } +void ClangdServer::typeHierarchy(PathRef File, Position Pos, int Resolve, + TypeHierarchyDirection Direction, + Callback> CB) { + auto Action = [Pos, Resolve, Direction](decltype(CB) CB, + Expected InpAST) { + if (!InpAST) + return CB(InpAST.takeError()); + CB(clangd::getTypeHierarchy(InpAST->AST, Pos, Resolve, Direction)); + }; + + WorkScheduler.runWithAST("Type Hierarchy", File, Bind(Action, std::move(CB))); +} + tooling::CompileCommand ClangdServer::getCompileCommand(PathRef File) { trace::Span Span("GetCompileCommand"); llvm::Optional C = CDB.getCompileCommand(File); diff --git a/clangd/ClangdServer.h b/clangd/ClangdServer.h index f3294186..e4e517c8 100644 --- a/clangd/ClangdServer.h +++ b/clangd/ClangdServer.h @@ -184,6 +184,11 @@ public: void findHover(PathRef File, Position Pos, Callback> CB); + /// Get information about type hierarchy for a given position. + void typeHierarchy(PathRef File, Position Pos, int Resolve, + TypeHierarchyDirection Direction, + Callback> CB); + /// Retrieve the top symbols from the workspace matching a query. void workspaceSymbols(StringRef Query, int Limit, Callback> CB); diff --git a/clangd/FindSymbols.cpp b/clangd/FindSymbols.cpp index 00819550..76874e4e 100644 --- a/clangd/FindSymbols.cpp +++ b/clangd/FindSymbols.cpp @@ -26,67 +26,8 @@ namespace clang { namespace clangd { -namespace { - -// Convert a index::SymbolKind to clangd::SymbolKind (LSP) -// Note, some are not perfect matches and should be improved when this LSP -// issue is addressed: -// https://github.com/Microsoft/language-server-protocol/issues/344 -SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind) { - switch (Kind) { - case index::SymbolKind::Unknown: - return SymbolKind::Variable; - case index::SymbolKind::Module: - return SymbolKind::Module; - case index::SymbolKind::Namespace: - return SymbolKind::Namespace; - case index::SymbolKind::NamespaceAlias: - return SymbolKind::Namespace; - case index::SymbolKind::Macro: - return SymbolKind::String; - case index::SymbolKind::Enum: - return SymbolKind::Enum; - case index::SymbolKind::Struct: - return SymbolKind::Struct; - case index::SymbolKind::Class: - return SymbolKind::Class; - case index::SymbolKind::Protocol: - return SymbolKind::Interface; - case index::SymbolKind::Extension: - return SymbolKind::Interface; - case index::SymbolKind::Union: - return SymbolKind::Class; - case index::SymbolKind::TypeAlias: - return SymbolKind::Class; - case index::SymbolKind::Function: - return SymbolKind::Function; - case index::SymbolKind::Variable: - return SymbolKind::Variable; - case index::SymbolKind::Field: - return SymbolKind::Field; - case index::SymbolKind::EnumConstant: - return SymbolKind::EnumMember; - case index::SymbolKind::InstanceMethod: - case index::SymbolKind::ClassMethod: - case index::SymbolKind::StaticMethod: - return SymbolKind::Method; - case index::SymbolKind::InstanceProperty: - case index::SymbolKind::ClassProperty: - case index::SymbolKind::StaticProperty: - return SymbolKind::Property; - case index::SymbolKind::Constructor: - case index::SymbolKind::Destructor: - return SymbolKind::Method; - case index::SymbolKind::ConversionFunction: - return SymbolKind::Function; - case index::SymbolKind::Parameter: - return SymbolKind::Variable; - case index::SymbolKind::Using: - return SymbolKind::Namespace; - } - llvm_unreachable("invalid symbol kind"); -} +namespace { using ScoredSymbolInfo = std::pair; struct ScoredSymbolGreater { bool operator()(const ScoredSymbolInfo &L, const ScoredSymbolInfo &R) { diff --git a/clangd/FindSymbols.h b/clangd/FindSymbols.h index 78bdbd33..e4980c97 100644 --- a/clangd/FindSymbols.h +++ b/clangd/FindSymbols.h @@ -21,9 +21,10 @@ class ParsedAST; class SymbolIndex; /// Searches for the symbols matching \p Query. The syntax of \p Query can be -/// the non-qualified name or fully qualified of a symbol. For example, "vector" -/// will match the symbol std::vector and "std::vector" would also match it. -/// Direct children of scopes (namepaces, etc) can be listed with a trailing +/// the non-qualified name or fully qualified of a symbol. For example, +/// "vector" will match the symbol std::vector and "std::vector" would also +/// match it. Direct children of scopes (namepaces, etc) can be listed with a +/// trailing /// "::". For example, "std::" will list all children of the std namespace and /// "::" alone will list all children of the global namespace. /// \p Limit limits the number of results returned (0 means no limit). diff --git a/clangd/Protocol.cpp b/clangd/Protocol.cpp index 4864eedc..dfd130a7 100644 --- a/clangd/Protocol.cpp +++ b/clangd/Protocol.cpp @@ -211,6 +211,61 @@ SymbolKind adjustKindToCapability(SymbolKind Kind, } } +SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind) { + switch (Kind) { + case index::SymbolKind::Unknown: + return SymbolKind::Variable; + case index::SymbolKind::Module: + return SymbolKind::Module; + case index::SymbolKind::Namespace: + return SymbolKind::Namespace; + case index::SymbolKind::NamespaceAlias: + return SymbolKind::Namespace; + case index::SymbolKind::Macro: + return SymbolKind::String; + case index::SymbolKind::Enum: + return SymbolKind::Enum; + case index::SymbolKind::Struct: + return SymbolKind::Struct; + case index::SymbolKind::Class: + return SymbolKind::Class; + case index::SymbolKind::Protocol: + return SymbolKind::Interface; + case index::SymbolKind::Extension: + return SymbolKind::Interface; + case index::SymbolKind::Union: + return SymbolKind::Class; + case index::SymbolKind::TypeAlias: + return SymbolKind::Class; + case index::SymbolKind::Function: + return SymbolKind::Function; + case index::SymbolKind::Variable: + return SymbolKind::Variable; + case index::SymbolKind::Field: + return SymbolKind::Field; + case index::SymbolKind::EnumConstant: + return SymbolKind::EnumMember; + case index::SymbolKind::InstanceMethod: + case index::SymbolKind::ClassMethod: + case index::SymbolKind::StaticMethod: + return SymbolKind::Method; + case index::SymbolKind::InstanceProperty: + case index::SymbolKind::ClassProperty: + case index::SymbolKind::StaticProperty: + return SymbolKind::Property; + case index::SymbolKind::Constructor: + case index::SymbolKind::Destructor: + return SymbolKind::Method; + case index::SymbolKind::ConversionFunction: + return SymbolKind::Function; + case index::SymbolKind::Parameter: + return SymbolKind::Variable; + case index::SymbolKind::Using: + return SymbolKind::Namespace; + } + llvm_unreachable("invalid symbol kind"); +} + bool fromJSON(const llvm::json::Value &Params, ClientCapabilities &R) { const llvm::json::Object *O = Params.getAsObject(); if (!O) @@ -812,6 +867,66 @@ bool fromJSON(const llvm::json::Value &Params, InitializationOptions &Opts) { return true; } +bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out) { + auto T = E.getAsInteger(); + if (!T) + return false; + if (*T < static_cast(TypeHierarchyDirection::Children) || + *T > static_cast(TypeHierarchyDirection::Both)) + return false; + Out = static_cast(*T); + return true; +} + +bool fromJSON(const llvm::json::Value &Params, TypeHierarchyParams &R) { + llvm::json::ObjectMapper O(Params); + return O && O.map("textDocument", R.textDocument) && + O.map("position", R.position) && O.map("resolve", R.resolve) && + O.map("direction", R.direction); +} + +llvm::raw_ostream &operator<<(llvm::raw_ostream &O, + const TypeHierarchyItem &I) { + return O << I.name << " - " << toJSON(I); +} + +llvm::json::Value toJSON(const TypeHierarchyItem &I) { + llvm::json::Object Result{{"name", I.name}, + {"kind", static_cast(I.kind)}, + {"range", I.range}, + {"selectionRange", I.selectionRange}, + {"uri", I.uri}}; + + if (I.detail) + Result["detail"] = I.detail; + if (I.deprecated) + Result["deprecated"] = I.deprecated; + if (I.parents) + Result["parents"] = I.parents; + if (I.children) + Result["children"] = I.children; + return std::move(Result); +} + +bool fromJSON(const llvm::json::Value &Params, TypeHierarchyItem &I) { + llvm::json::ObjectMapper O(Params); + + // Required fields. + if (!(O && O.map("name", I.name) && O.map("kind", I.kind) && + O.map("uri", I.uri) && O.map("range", I.range) && + O.map("selectionRange", I.selectionRange))) { + return false; + } + + // Optional fields. + O.map("detail", I.detail); + O.map("deprecated", I.deprecated); + O.map("parents", I.parents); + O.map("children", I.children); + + return true; +} + bool fromJSON(const llvm::json::Value &Params, ReferenceParams &R) { TextDocumentPositionParams &Base = R; return fromJSON(Params, Base); diff --git a/clangd/Protocol.h b/clangd/Protocol.h index 95a66711..468ead8d 100644 --- a/clangd/Protocol.h +++ b/clangd/Protocol.h @@ -25,6 +25,7 @@ #include "URI.h" #include "index/SymbolID.h" +#include "clang/Index/IndexSymbol.h" #include "llvm/ADT/Optional.h" #include "llvm/Support/JSON.h" #include @@ -331,6 +332,12 @@ bool fromJSON(const llvm::json::Value &, SymbolKindBitset &); SymbolKind adjustKindToCapability(SymbolKind Kind, SymbolKindBitset &supportedSymbolKinds); +// Convert a index::SymbolKind to clangd::SymbolKind (LSP) +// Note, some are not perfect matches and should be improved when this LSP +// issue is addressed: +// https://github.com/Microsoft/language-server-protocol/issues/344 +SymbolKind indexSymbolKindToSymbolKind(index::SymbolKind Kind); + // This struct doesn't mirror LSP! // The protocol defines deeply nested structures for client capabilities. // Instead of mapping them all, this just parses out the bits we care about. @@ -1014,6 +1021,67 @@ struct DocumentHighlight { llvm::json::Value toJSON(const DocumentHighlight &DH); llvm::raw_ostream &operator<<(llvm::raw_ostream &, const DocumentHighlight &); +enum class TypeHierarchyDirection { Children = 0, Parents = 1, Both = 2 }; +bool fromJSON(const llvm::json::Value &E, TypeHierarchyDirection &Out); + +/// The type hierarchy params is an extension of the +/// `TextDocumentPositionsParams` with optional properties which can be used to +/// eagerly resolve the item when requesting from the server. +struct TypeHierarchyParams : public TextDocumentPositionParams { + /// The hierarchy levels to resolve. `0` indicates no level. + int resolve = 0; + + /// The direction of the hierarchy levels to resolve. + TypeHierarchyDirection direction = TypeHierarchyDirection::Parents; +}; +bool fromJSON(const llvm::json::Value &, TypeHierarchyParams &); + +struct TypeHierarchyItem { + /// The human readable name of the hierarchy item. + std::string name; + + /// Optional detail for the hierarchy item. It can be, for instance, the + /// signature of a function or method. + llvm::Optional detail; + + /// The kind of the hierarchy item. For instance, class or interface. + SymbolKind kind; + + /// `true` if the hierarchy item is deprecated. Otherwise, `false`. + bool deprecated; + + /// The URI of the text document where this type hierarchy item belongs to. + URIForFile uri; + + /// The range enclosing this type hierarchy item not including + /// leading/trailing whitespace but everything else like comments. This + /// information is typically used to determine if the client's cursor is + /// inside the type hierarch item to reveal in the symbol in the UI. + Range range; + + /// The range that should be selected and revealed when this type hierarchy + /// item is being picked, e.g. the name of a function. Must be contained by + /// the `range`. + Range selectionRange; + + /// If this type hierarchy item is resolved, it contains the direct parents. + /// Could be empty if the item does not have direct parents. If not defined, + /// the parents have not been resolved yet. + llvm::Optional> parents; + + /// If this type hierarchy item is resolved, it contains the direct children + /// of the current item. Could be empty if the item does not have any + /// descendants. If not defined, the children have not been resolved. + llvm::Optional> children; + + /// The protocol has a slot here for an optional 'data' filed, which can + /// be used to identify a type hierarchy item in a resolve request. We don't + /// need this (the item itself is sufficient to identify what to resolve) + /// so don't declare it. +}; +llvm::json::Value toJSON(const TypeHierarchyItem &); +llvm::raw_ostream &operator<<(llvm::raw_ostream &, const TypeHierarchyItem &); + struct ReferenceParams : public TextDocumentPositionParams { // For now, no options like context.includeDeclaration are supported. }; diff --git a/clangd/XRefs.cpp b/clangd/XRefs.cpp index a099fb90..6ca65bea 100644 --- a/clangd/XRefs.cpp +++ b/clangd/XRefs.cpp @@ -7,13 +7,16 @@ //===----------------------------------------------------------------------===// #include "XRefs.h" #include "AST.h" +#include "FindSymbols.h" #include "Logger.h" #include "SourceCode.h" #include "URI.h" #include "index/Merge.h" +#include "index/SymbolCollector.h" #include "index/SymbolLocation.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/RecursiveASTVisitor.h" +#include "clang/AST/Type.h" #include "clang/Index/IndexDataConsumer.h" #include "clang/Index/IndexSymbol.h" #include "clang/Index/IndexingAction.h" @@ -826,5 +829,135 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const LocatedSymbol &S) { return OS; } +// FIXME(nridge): Reduce duplication between this function and declToSym(). +static llvm::Optional +declToTypeHierarchyItem(ASTContext &Ctx, const NamedDecl &ND) { + auto &SM = Ctx.getSourceManager(); + + SourceLocation NameLoc = findNameLoc(&ND); + // getFileLoc is a good choice for us, but we also need to make sure + // sourceLocToPosition won't switch files, so we call getSpellingLoc on top of + // that to make sure it does not switch files. + // FIXME: sourceLocToPosition should not switch files! + SourceLocation BeginLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getBeginLoc())); + SourceLocation EndLoc = SM.getSpellingLoc(SM.getFileLoc(ND.getEndLoc())); + if (NameLoc.isInvalid() || BeginLoc.isInvalid() || EndLoc.isInvalid()) + return llvm::None; + + Position NameBegin = sourceLocToPosition(SM, NameLoc); + Position NameEnd = sourceLocToPosition( + SM, Lexer::getLocForEndOfToken(NameLoc, 0, SM, Ctx.getLangOpts())); + + index::SymbolInfo SymInfo = index::getSymbolInfo(&ND); + // FIXME: this is not classifying constructors, destructors and operators + // correctly (they're all "methods"). + SymbolKind SK = indexSymbolKindToSymbolKind(SymInfo.Kind); + + TypeHierarchyItem THI; + THI.name = printName(Ctx, ND); + THI.kind = SK; + THI.deprecated = ND.isDeprecated(); + THI.range = + Range{sourceLocToPosition(SM, BeginLoc), sourceLocToPosition(SM, EndLoc)}; + THI.selectionRange = Range{NameBegin, NameEnd}; + if (!THI.range.contains(THI.selectionRange)) { + // 'selectionRange' must be contained in 'range', so in cases where clang + // reports unrelated ranges we need to reconcile somehow. + THI.range = THI.selectionRange; + } + + auto FilePath = + getCanonicalPath(SM.getFileEntryForID(SM.getFileID(BeginLoc)), SM); + auto TUPath = getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM); + if (!FilePath || !TUPath) + return llvm::None; // Not useful without a uri. + THI.uri = URIForFile::canonicalize(*FilePath, *TUPath); + + return THI; +} + +static Optional getTypeAncestors(const CXXRecordDecl &CXXRD, + ASTContext &ASTCtx) { + Optional Result = declToTypeHierarchyItem(ASTCtx, CXXRD); + if (!Result) + return Result; + + Result->parents.emplace(); + + for (const CXXRecordDecl *ParentDecl : typeParents(&CXXRD)) { + if (Optional ParentSym = + getTypeAncestors(*ParentDecl, ASTCtx)) { + Result->parents->emplace_back(std::move(*ParentSym)); + } + } + + return Result; +} + +const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos) { + ASTContext &ASTCtx = AST.getASTContext(); + const SourceManager &SourceMgr = ASTCtx.getSourceManager(); + SourceLocation SourceLocationBeg = + getBeginningOfIdentifier(AST, Pos, SourceMgr.getMainFileID()); + IdentifiedSymbol Symbols = getSymbolAtPosition(AST, SourceLocationBeg); + if (Symbols.Decls.empty()) + return nullptr; + + const Decl *D = Symbols.Decls[0]; + + if (const VarDecl *VD = dyn_cast(D)) { + // If this is a variable, use the type of the variable. + return VD->getType().getTypePtr()->getAsCXXRecordDecl(); + } + + if (const CXXMethodDecl *Method = dyn_cast(D)) { + // If this is a method, use the type of the class. + return Method->getParent(); + } + + // We don't handle FieldDecl because it's not clear what behaviour + // the user would expect: the enclosing class type (as with a + // method), or the field's type (as with a variable). + + return dyn_cast(D); +} + +std::vector typeParents(const CXXRecordDecl *CXXRD) { + std::vector Result; + + for (auto Base : CXXRD->bases()) { + const CXXRecordDecl *ParentDecl = nullptr; + + const Type *Type = Base.getType().getTypePtr(); + if (const RecordType *RT = Type->getAs()) { + ParentDecl = RT->getAsCXXRecordDecl(); + } + + // For now, do not handle dependent bases such as "Base". + // We would like to handle them by heuristically choosing the + // primary template declaration, but we need to take care to + // avoid infinite recursion. + + if (ParentDecl) + Result.push_back(ParentDecl); + } + + return Result; +} + +llvm::Optional +getTypeHierarchy(ParsedAST &AST, Position Pos, int ResolveLevels, + TypeHierarchyDirection Direction) { + const CXXRecordDecl *CXXRD = findRecordTypeAt(AST, Pos); + if (!CXXRD) + return llvm::None; + + Optional Result = + getTypeAncestors(*CXXRD, AST.getASTContext()); + // FIXME(nridge): Resolve type descendants if direction is Children or Both, + // and ResolveLevels > 0. + return Result; +} + } // namespace clangd } // namespace clang diff --git a/clangd/XRefs.h b/clangd/XRefs.h index 25e5d867..008bba50 100644 --- a/clangd/XRefs.h +++ b/clangd/XRefs.h @@ -58,6 +58,17 @@ std::vector findReferences(ParsedAST &AST, Position Pos, /// Get info about symbols at \p Pos. std::vector getSymbolInfo(ParsedAST &AST, Position Pos); +/// Find the record type references at \p Pos. +const CXXRecordDecl *findRecordTypeAt(ParsedAST &AST, Position Pos); + +/// Given a record type declaration, find its base (parent) types. +std::vector typeParents(const CXXRecordDecl *CXXRD); + +/// Get type hierarchy information at \p Pos. +llvm::Optional +getTypeHierarchy(ParsedAST &AST, Position Pos, int Resolve, + TypeHierarchyDirection Direction); + } // namespace clangd } // namespace clang diff --git a/clangd/index/SymbolCollector.cpp b/clangd/index/SymbolCollector.cpp index eee32004..302d46ad 100644 --- a/clangd/index/SymbolCollector.cpp +++ b/clangd/index/SymbolCollector.cpp @@ -326,8 +326,8 @@ bool SymbolCollector::handleDeclOccurence( // ND is the canonical (i.e. first) declaration. If it's in the main file, // then no public declaration was visible, so assume it's main-file only. - bool IsMainFileOnly = SM.isWrittenInMainFile(SM.getExpansionLoc( - ND->getBeginLoc())); + bool IsMainFileOnly = + SM.isWrittenInMainFile(SM.getExpansionLoc(ND->getBeginLoc())); if (!shouldCollectSymbol(*ND, *ASTCtx, Opts, IsMainFileOnly)) return true; // Do not store references to main-file symbols. @@ -516,8 +516,7 @@ void SymbolCollector::finish() { FilesToIndexCache.clear(); } -const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, - SymbolID ID, +const Symbol *SymbolCollector::addDeclaration(const NamedDecl &ND, SymbolID ID, bool IsMainFileOnly) { auto &Ctx = ND.getASTContext(); auto &SM = Ctx.getSourceManager(); diff --git a/clangd/index/SymbolCollector.h b/clangd/index/SymbolCollector.h index e6d479d2..551bfe85 100644 --- a/clangd/index/SymbolCollector.h +++ b/clangd/index/SymbolCollector.h @@ -113,7 +113,8 @@ public: void finish() override; private: - const Symbol *addDeclaration(const NamedDecl &, SymbolID, bool IsMainFileSymbol); + const Symbol *addDeclaration(const NamedDecl &, SymbolID, + bool IsMainFileSymbol); void addDefinition(const NamedDecl &, const Symbol &DeclSymbol); // All Symbols collected from the AST. diff --git a/test/clangd/initialize-params.test b/test/clangd/initialize-params.test index b9fec65e..488539d4 100644 --- a/test/clangd/initialize-params.test +++ b/test/clangd/initialize-params.test @@ -40,6 +40,7 @@ # CHECK-NEXT: ] # CHECK-NEXT: }, # CHECK-NEXT: "textDocumentSync": 2, +# CHECK-NEXT: "typeHierarchyProvider": true # CHECK-NEXT: "workspaceSymbolProvider": true # CHECK-NEXT: } # CHECK-NEXT: } diff --git a/test/clangd/type-hierarchy.test b/test/clangd/type-hierarchy.test new file mode 100644 index 00000000..420f7fbf --- /dev/null +++ b/test/clangd/type-hierarchy.test @@ -0,0 +1,92 @@ +# RUN: clangd -lit-test < %s | FileCheck -strict-whitespace %s +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"test:///main.cpp","languageId":"cpp","version":1,"text":"struct Parent {};\nstruct Child1 : Parent {};\nstruct Child2 : Child1 {};"}}} +--- +{"jsonrpc":"2.0","id":1,"method":"textDocument/typeHierarchy","params":{"textDocument":{"uri":"test:///main.cpp"},"position":{"line":2,"character":11},"direction":1,"resolve":1}} +# CHECK: "id": 1 +# CHECK-NEXT: "jsonrpc": "2.0", +# CHECK-NEXT: "result": { +# CHECK-NEXT: "kind": 23, +# CHECK-NEXT: "name": "Child2", +# CHECK-NEXT: "parents": [ +# CHECK-NEXT: { +# CHECK-NEXT: "kind": 23, +# CHECK-NEXT: "name": "Child1", +# CHECK-NEXT: "parents": [ +# CHECK-NEXT: { +# CHECK-NEXT: "kind": 23, +# CHECK-NEXT: "name": "Parent", +# CHECK-NEXT: "parents": [], +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 15, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "selectionRange": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 13, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 7, +# CHECK-NEXT: "line": 0 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file:///clangd-test/main.cpp" +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 24, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "selectionRange": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 13, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 7, +# CHECK-NEXT: "line": 1 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file:///clangd-test/main.cpp" +# CHECK-NEXT: } +# CHECK-NEXT: ], +# CHECK-NEXT: "range": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 24, +# CHECK-NEXT: "line": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 0, +# CHECK-NEXT: "line": 2 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "selectionRange": { +# CHECK-NEXT: "end": { +# CHECK-NEXT: "character": 13, +# CHECK-NEXT: "line": 2 +# CHECK-NEXT: }, +# CHECK-NEXT: "start": { +# CHECK-NEXT: "character": 7, +# CHECK-NEXT: "line": 2 +# CHECK-NEXT: } +# CHECK-NEXT: }, +# CHECK-NEXT: "uri": "file:///clangd-test/main.cpp" +# CHECK-NEXT: } +--- +{"jsonrpc":"2.0","id":2,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} diff --git a/unittests/clangd/CMakeLists.txt b/unittests/clangd/CMakeLists.txt index deae9ceb..6749468e 100644 --- a/unittests/clangd/CMakeLists.txt +++ b/unittests/clangd/CMakeLists.txt @@ -46,6 +46,7 @@ add_extra_unittest(ClangdTests TestTU.cpp ThreadingTests.cpp TraceTests.cpp + TypeHierarchyTests.cpp TweakTests.cpp URITests.cpp XRefsTests.cpp diff --git a/unittests/clangd/Matchers.h b/unittests/clangd/Matchers.h index 0ace9706..0946398d 100644 --- a/unittests/clangd/Matchers.h +++ b/unittests/clangd/Matchers.h @@ -127,6 +127,73 @@ PolySubsequenceMatcher HasSubsequence(Args &&... M) { llvm::consumeError(ComputedValue.takeError()); \ } while (false) +// Implements the HasValue(m) matcher for matching an Optional whose +// value matches matcher m. +template class OptionalMatcher { +public: + explicit OptionalMatcher(const InnerMatcher &matcher) : matcher_(matcher) {} + + // This type conversion operator template allows Optional(m) to be + // used as a matcher for any Optional type whose value type is + // compatible with the inner matcher. + // + // The reason we do this instead of relying on + // MakePolymorphicMatcher() is that the latter is not flexible + // enough for implementing the DescribeTo() method of Optional(). + template operator Matcher() const { + return MakeMatcher(new Impl(matcher_)); + } + +private: + // The monomorphic implementation that works for a particular optional type. + template + class Impl : public ::testing::MatcherInterface { + public: + using Value = typename std::remove_const< + typename std::remove_reference::type>::type::value_type; + + explicit Impl(const InnerMatcher &matcher) + : matcher_(::testing::MatcherCast(matcher)) {} + + virtual void DescribeTo(::std::ostream *os) const { + *os << "has a value that "; + matcher_.DescribeTo(os); + } + + virtual void DescribeNegationTo(::std::ostream *os) const { + *os << "does not have a value that "; + matcher_.DescribeTo(os); + } + + virtual bool + MatchAndExplain(Optional optional, + ::testing::MatchResultListener *listener) const { + if (!optional.hasValue()) + return false; + + *listener << "which has a value "; + return MatchPrintAndExplain(*optional, matcher_, listener); + } + + private: + const Matcher matcher_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const InnerMatcher matcher_; + + GTEST_DISALLOW_ASSIGN_(OptionalMatcher); +}; + +// Creates a matcher that matches an Optional that has a value +// that matches inner_matcher. +template +inline OptionalMatcher +HasValue(const InnerMatcher &inner_matcher) { + return OptionalMatcher(inner_matcher); +} + } // namespace clangd } // namespace clang #endif diff --git a/unittests/clangd/TypeHierarchyTests.cpp b/unittests/clangd/TypeHierarchyTests.cpp new file mode 100644 index 00000000..81a9ab43 --- /dev/null +++ b/unittests/clangd/TypeHierarchyTests.cpp @@ -0,0 +1,462 @@ +//===-- TypeHierarchyTests.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 "Annotations.h" +#include "ClangdUnit.h" +#include "Compiler.h" +#include "Matchers.h" +#include "SyncAPI.h" +#include "TestFS.h" +#include "TestTU.h" +#include "XRefs.h" +#include "index/FileIndex.h" +#include "index/SymbolCollector.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/Index/IndexingAction.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/ScopedPrinter.h" +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace clang { +namespace clangd { +namespace { + +using testing::AllOf; +using testing::ElementsAre; +using testing::Eq; +using testing::Field; +using testing::IsEmpty; +using testing::Matcher; +using testing::Pointee; +using testing::UnorderedElementsAreArray; + +// GMock helpers for matching TypeHierarchyItem. +MATCHER_P(WithName, N, "") { return arg.name == N; } +MATCHER_P(WithKind, Kind, "") { return arg.kind == Kind; } +MATCHER_P(SelectionRangeIs, R, "") { return arg.selectionRange == R; } +template +testing::Matcher Parents(ParentMatchers... ParentsM) { + return Field(&TypeHierarchyItem::parents, HasValue(ElementsAre(ParentsM...))); +} + +TEST(FindRecordTypeAt, TypeOrVariable) { + Annotations Source(R"cpp( +struct Ch^ild2 { + int c; +}; + +int main() { + Ch^ild2 ch^ild2; + ch^ild2.c = 1; +} +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + for (Position Pt : Source.points()) { + const CXXRecordDecl *RD = findRecordTypeAt(AST, Pt); + EXPECT_EQ(&findDecl(AST, "Child2"), static_cast(RD)); + } +} + +TEST(FindRecordTypeAt, Method) { + Annotations Source(R"cpp( +struct Child2 { + void met^hod (); + void met^hod (int x); +}; + +int main() { + Child2 child2; + child2.met^hod(5); +} +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + for (Position Pt : Source.points()) { + const CXXRecordDecl *RD = findRecordTypeAt(AST, Pt); + EXPECT_EQ(&findDecl(AST, "Child2"), static_cast(RD)); + } +} + +TEST(FindRecordTypeAt, Field) { + Annotations Source(R"cpp( +struct Child2 { + int fi^eld; +}; + +int main() { + Child2 child2; + child2.fi^eld = 5; +} +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + for (Position Pt : Source.points()) { + const CXXRecordDecl *RD = findRecordTypeAt(AST, Pt); + // A field does not unambiguously specify a record type + // (possible associated reocrd types could be the field's type, + // or the type of the record that the field is a member of). + EXPECT_EQ(nullptr, RD); + } +} + +TEST(TypeParents, SimpleInheritance) { + Annotations Source(R"cpp( +struct Parent { + int a; +}; + +struct Child1 : Parent { + int b; +}; + +struct Child2 : Child1 { + int c; +}; +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + const CXXRecordDecl *Parent = + dyn_cast(&findDecl(AST, "Parent")); + const CXXRecordDecl *Child1 = + dyn_cast(&findDecl(AST, "Child1")); + const CXXRecordDecl *Child2 = + dyn_cast(&findDecl(AST, "Child2")); + + EXPECT_THAT(typeParents(Parent), ElementsAre()); + EXPECT_THAT(typeParents(Child1), ElementsAre(Parent)); + EXPECT_THAT(typeParents(Child2), ElementsAre(Child1)); +} + +TEST(TypeParents, MultipleInheritance) { + Annotations Source(R"cpp( +struct Parent1 { + int a; +}; + +struct Parent2 { + int b; +}; + +struct Parent3 : Parent2 { + int c; +}; + +struct Child : Parent1, Parent3 { + int d; +}; +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + const CXXRecordDecl *Parent1 = + dyn_cast(&findDecl(AST, "Parent1")); + const CXXRecordDecl *Parent2 = + dyn_cast(&findDecl(AST, "Parent2")); + const CXXRecordDecl *Parent3 = + dyn_cast(&findDecl(AST, "Parent3")); + const CXXRecordDecl *Child = dyn_cast(&findDecl(AST, "Child")); + + EXPECT_THAT(typeParents(Parent1), ElementsAre()); + EXPECT_THAT(typeParents(Parent2), ElementsAre()); + EXPECT_THAT(typeParents(Parent3), ElementsAre(Parent2)); + EXPECT_THAT(typeParents(Child), ElementsAre(Parent1, Parent3)); +} + +TEST(TypeParents, ClassTemplate) { + Annotations Source(R"cpp( +struct Parent {}; + +template +struct Child : Parent {}; +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + const CXXRecordDecl *Parent = + dyn_cast(&findDecl(AST, "Parent")); + const CXXRecordDecl *Child = + dyn_cast(&findDecl(AST, "Child"))->getTemplatedDecl(); + + EXPECT_THAT(typeParents(Child), ElementsAre(Parent)); +} + +MATCHER_P(ImplicitSpecOf, ClassTemplate, "") { + const ClassTemplateSpecializationDecl *CTS = + dyn_cast(arg); + return CTS && + CTS->getSpecializedTemplate()->getTemplatedDecl() == ClassTemplate && + CTS->getSpecializationKind() == TSK_ImplicitInstantiation; +} + +// This is similar to findDecl(AST, QName), but supports using +// a template-id as a query. +const NamedDecl &findDeclWithTemplateArgs(ParsedAST &AST, + llvm::StringRef Query) { + return findDecl(AST, [&Query](const NamedDecl &ND) { + std::string QName; + llvm::raw_string_ostream OS(QName); + PrintingPolicy Policy(ND.getASTContext().getLangOpts()); + // Use getNameForDiagnostic() which includes the template + // arguments in the printed name. + ND.getNameForDiagnostic(OS, Policy, /*Qualified=*/true); + OS.flush(); + return QName == Query; + }); +} + +TEST(TypeParents, TemplateSpec1) { + Annotations Source(R"cpp( +template +struct Parent {}; + +template <> +struct Parent {}; + +struct Child1 : Parent {}; + +struct Child2 : Parent {}; +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + const CXXRecordDecl *Parent = + dyn_cast(&findDecl(AST, "Parent"))->getTemplatedDecl(); + const CXXRecordDecl *ParentSpec = + dyn_cast(&findDeclWithTemplateArgs(AST, "Parent")); + const CXXRecordDecl *Child1 = + dyn_cast(&findDecl(AST, "Child1")); + const CXXRecordDecl *Child2 = + dyn_cast(&findDecl(AST, "Child2")); + + EXPECT_THAT(typeParents(Child1), ElementsAre(ImplicitSpecOf(Parent))); + EXPECT_THAT(typeParents(Child2), ElementsAre(ParentSpec)); +} + +TEST(TypeParents, TemplateSpec2) { + Annotations Source(R"cpp( +struct Parent {}; + +template +struct Child {}; + +template <> +struct Child : Parent {}; +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + const CXXRecordDecl *Parent = + dyn_cast(&findDecl(AST, "Parent")); + const CXXRecordDecl *Child = + dyn_cast(&findDecl(AST, "Child"))->getTemplatedDecl(); + const CXXRecordDecl *ChildSpec = + dyn_cast(&findDeclWithTemplateArgs(AST, "Child")); + + EXPECT_THAT(typeParents(Child), ElementsAre()); + EXPECT_THAT(typeParents(ChildSpec), ElementsAre(Parent)); +} + +// This is disabled for now, because support for dependent bases +// requires additional measures to avoid infinite recursion. +TEST(DISABLED_TypeParents, DependentBase) { + Annotations Source(R"cpp( +template +struct Parent {}; + +template +struct Child1 : Parent {}; + +template +struct Child2 : Parent::Type {}; + +template +struct Child3 : T {}; +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + const CXXRecordDecl *Parent = + dyn_cast(&findDecl(AST, "Parent"))->getTemplatedDecl(); + const CXXRecordDecl *Child1 = + dyn_cast(&findDecl(AST, "Child1"))->getTemplatedDecl(); + const CXXRecordDecl *Child2 = + dyn_cast(&findDecl(AST, "Child2"))->getTemplatedDecl(); + const CXXRecordDecl *Child3 = + dyn_cast(&findDecl(AST, "Child3"))->getTemplatedDecl(); + + // For "Parent", use the primary template as a best-effort guess. + EXPECT_THAT(typeParents(Child1), ElementsAre(Parent)); + // For "Parent::Type", there is nothing we can do. + EXPECT_THAT(typeParents(Child2), ElementsAre()); + // Likewise for "T". + EXPECT_THAT(typeParents(Child3), ElementsAre()); +} + +// Parts of getTypeHierarchy() are tested in more detail by the +// FindRecordTypeAt.* and TypeParents.* tests above. This test exercises the +// entire operation. +TEST(TypeHierarchy, Parents) { + Annotations Source(R"cpp( +struct $Parent1Def[[Parent1]] { + int a; +}; + +struct $Parent2Def[[Parent2]] { + int b; +}; + +struct $Parent3Def[[Parent3]] : Parent2 { + int c; +}; + +struct Ch^ild : Parent1, Parent3 { + int d; +}; + +int main() { + Ch^ild ch^ild; + + ch^ild.a = 1; +} +)cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + for (Position Pt : Source.points()) { + // Set ResolveLevels to 0 because it's only used for Children; + // for Parents, getTypeHierarchy() always returns all levels. + llvm::Optional Result = getTypeHierarchy( + AST, Pt, /*ResolveLevels=*/0, TypeHierarchyDirection::Parents); + ASSERT_TRUE(bool(Result)); + EXPECT_THAT( + *Result, + AllOf( + WithName("Child"), WithKind(SymbolKind::Struct), + Parents(AllOf(WithName("Parent1"), WithKind(SymbolKind::Struct), + SelectionRangeIs(Source.range("Parent1Def")), + Parents()), + AllOf(WithName("Parent3"), WithKind(SymbolKind::Struct), + SelectionRangeIs(Source.range("Parent3Def")), + Parents(AllOf( + WithName("Parent2"), WithKind(SymbolKind::Struct), + SelectionRangeIs(Source.range("Parent2Def")), + Parents())))))); + } +} + +TEST(TypeHierarchy, RecursiveHierarchy1) { + Annotations Source(R"cpp( + template + struct S : S {}; + + S^<0> s; + )cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + // The compiler should produce a diagnostic for hitting the + // template instantiation depth. + ASSERT_TRUE(!AST.getDiagnostics().empty()); + + // Make sure getTypeHierarchy() doesn't get into an infinite recursion. + llvm::Optional Result = getTypeHierarchy( + AST, Source.points()[0], 0, TypeHierarchyDirection::Parents); + ASSERT_TRUE(bool(Result)); + EXPECT_THAT(*Result, + AllOf(WithName("S"), WithKind(SymbolKind::Struct), Parents())); +} + +TEST(TypeHierarchy, RecursiveHierarchy2) { + Annotations Source(R"cpp( + template + struct S : S {}; + + template <> + struct S<0>{}; + + S^<2> s; + )cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + // Make sure getTypeHierarchy() doesn't get into an infinite recursion. + llvm::Optional Result = getTypeHierarchy( + AST, Source.points()[0], 0, TypeHierarchyDirection::Parents); + ASSERT_TRUE(bool(Result)); + EXPECT_THAT(*Result, + AllOf(WithName("S"), WithKind(SymbolKind::Struct), Parents())); +} + +TEST(TypeHierarchy, RecursiveHierarchy3) { + Annotations Source(R"cpp( + template + struct S : S {}; + + template <> + struct S<0>{}; + + template + struct Foo { + S^ s; + }; + )cpp"); + + TestTU TU = TestTU::withCode(Source.code()); + auto AST = TU.build(); + + ASSERT_TRUE(AST.getDiagnostics().empty()); + + // Make sure getTypeHierarchy() doesn't get into an infinite recursion. + llvm::Optional Result = getTypeHierarchy( + AST, Source.points()[0], 0, TypeHierarchyDirection::Parents); + ASSERT_TRUE(bool(Result)); + EXPECT_THAT(*Result, + AllOf(WithName("S"), WithKind(SymbolKind::Struct), Parents())); +} + +} // namespace +} // namespace clangd +} // namespace clang -- cgit v1.2.3 From f1611cb91e7aad95f7e37ab222db28fa72c79193 Mon Sep 17 00:00:00 2001 From: Kadir Cetinkaya Date: Wed, 20 Mar 2019 09:43:38 +0000 Subject: [clangd] Print arguments in template specializations Reviewers: ilya-biryukov Subscribers: ioeric, MaskRay, jkorous, arphaman, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D59354 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@356541 91177308-0d34-0410-b5e6-96231b3b80d8 --- clangd/AST.cpp | 32 ++++++++++++ clangd/index/MemIndex.cpp | 9 ---- clangd/index/dex/Dex.cpp | 9 ---- unittests/clangd/DexTests.cpp | 25 ++++----- unittests/clangd/IndexTests.cpp | 25 ++++----- unittests/clangd/SymbolCollectorTests.cpp | 87 +++++++++++++++++++++++++------ 6 files changed, 124 insertions(+), 63 deletions(-) diff --git a/clangd/AST.cpp b/clangd/AST.cpp index 47559c10..61f65ab7 100644 --- a/clangd/AST.cpp +++ b/clangd/AST.cpp @@ -11,9 +11,12 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TypeLoc.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Index/USRGeneration.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ScopedPrinter.h" @@ -50,6 +53,22 @@ SourceLocation findNameLoc(const clang::Decl *D) { return SM.getSpellingLoc(D->getLocation()); } +static llvm::Optional> +getTemplateSpecializationArgLocs(const NamedDecl &ND) { + if (auto *Func = llvm::dyn_cast(&ND)) { + if (auto *Args = Func->getTemplateSpecializationArgsAsWritten()) + return Args->arguments(); + } else if (auto *Cls = + llvm::dyn_cast(&ND)) { + if (auto *Args = Cls->getTemplateArgsAsWritten()) + return Args->arguments(); + } else if (auto *Var = llvm::dyn_cast(&ND)) + return Var->getTemplateArgsInfo().arguments(); + // We return None for ClassTemplateSpecializationDecls because it does not + // contain TemplateArgumentLoc information. + return llvm::None; +} + std::string printQualifiedName(const NamedDecl &ND) { std::string QName; llvm::raw_string_ostream OS(QName); @@ -60,6 +79,19 @@ std::string printQualifiedName(const NamedDecl &ND) { // namespaces to query: the preamble doesn't have a dedicated list. Policy.SuppressUnwrittenScope = true; ND.printQualifiedName(OS, Policy); + if (auto Args = getTemplateSpecializationArgLocs(ND)) + printTemplateArgumentList(OS, *Args, Policy); + else if (auto *Cls = llvm::dyn_cast(&ND)) { + if (auto STL = Cls->getTypeAsWritten() + ->getTypeLoc() + .getAs()) { + llvm::SmallVector ArgLocs; + ArgLocs.reserve(STL.getNumArgs()); + for (unsigned I = 0; I < STL.getNumArgs(); ++I) + ArgLocs.push_back(STL.getArgLoc(I)); + printTemplateArgumentList(OS, ArgLocs, Policy); + } + } OS.flush(); assert(!StringRef(QName).startswith("::")); return QName; diff --git a/clangd/index/MemIndex.cpp b/clangd/index/MemIndex.cpp index ddd9a867..582091f0 100644 --- a/clangd/index/MemIndex.cpp +++ b/clangd/index/MemIndex.cpp @@ -38,15 +38,6 @@ bool MemIndex::fuzzyFind( for (const auto Pair : Index) { const Symbol *Sym = Pair.second; - // FIXME: Enable fuzzy find on template specializations once we start - // storing template arguments in the name. Currently we only store name for - // class template, which would cause duplication in the results. - if (Sym->SymInfo.Properties & - (static_cast( - index::SymbolProperty::TemplateSpecialization) | - static_cast( - index::SymbolProperty::TemplatePartialSpecialization))) - continue; // Exact match against all possible scopes. if (!Req.AnyScope && !llvm::is_contained(Req.Scopes, Sym->Scope)) continue; diff --git a/clangd/index/dex/Dex.cpp b/clangd/index/dex/Dex.cpp index dd004f5f..d767bb51 100644 --- a/clangd/index/dex/Dex.cpp +++ b/clangd/index/dex/Dex.cpp @@ -86,15 +86,6 @@ void Dex::buildIndex() { llvm::DenseMap> TempInvertedIndex; for (DocID SymbolRank = 0; SymbolRank < Symbols.size(); ++SymbolRank) { const auto *Sym = Symbols[SymbolRank]; - // FIXME: Enable fuzzy find on template specializations once we start - // storing template arguments in the name. Currently we only store name for - // class template, which would cause duplication in the results. - if (Sym->SymInfo.Properties & - (static_cast( - index::SymbolProperty::TemplateSpecialization) | - static_cast( - index::SymbolProperty::TemplatePartialSpecialization))) - continue; for (const auto &Token : generateSearchTokens(*Sym)) TempInvertedIndex[Token].push_back(SymbolRank); } diff --git a/unittests/clangd/DexTests.cpp b/unittests/clangd/DexTests.cpp index bd757d08..2cbfacb2 100644 --- a/unittests/clangd/DexTests.cpp +++ b/unittests/clangd/DexTests.cpp @@ -714,35 +714,30 @@ TEST(DexTest, TemplateSpecialization) { SymbolSlab::Builder B; Symbol S = symbol("TempSpec"); - S.ID = SymbolID("0"); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("1"); + S = symbol("TempSpec"); S.SymInfo.Properties = static_cast( index::SymbolProperty::TemplateSpecialization); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("2"); + S = symbol("TempSpec"); S.SymInfo.Properties = static_cast( index::SymbolProperty::TemplatePartialSpecialization); B.insert(S); auto I = dex::Dex::build(std::move(B).build(), RefSlab()); FuzzyFindRequest Req; - Req.Query = "TempSpec"; Req.AnyScope = true; - std::vector Symbols; - I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); }); - EXPECT_EQ(Symbols.size(), 1U); - EXPECT_FALSE(Symbols.front().SymInfo.Properties & - static_cast( - index::SymbolProperty::TemplateSpecialization)); - EXPECT_FALSE(Symbols.front().SymInfo.Properties & - static_cast( - index::SymbolProperty::TemplatePartialSpecialization)); + Req.Query = "TempSpec"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec", "TempSpec", + "TempSpec")); + + Req.Query = "TempSpec", "TempSpec")); } } // namespace diff --git a/unittests/clangd/IndexTests.cpp b/unittests/clangd/IndexTests.cpp index 3a159279..70dda711 100644 --- a/unittests/clangd/IndexTests.cpp +++ b/unittests/clangd/IndexTests.cpp @@ -187,35 +187,30 @@ TEST(MemIndexTest, TemplateSpecialization) { SymbolSlab::Builder B; Symbol S = symbol("TempSpec"); - S.ID = SymbolID("0"); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("1"); + S = symbol("TempSpec"); S.SymInfo.Properties = static_cast( index::SymbolProperty::TemplateSpecialization); B.insert(S); - S = symbol("TempSpec"); - S.ID = SymbolID("2"); + S = symbol("TempSpec"); S.SymInfo.Properties = static_cast( index::SymbolProperty::TemplatePartialSpecialization); B.insert(S); auto I = MemIndex::build(std::move(B).build(), RefSlab()); FuzzyFindRequest Req; - Req.Query = "TempSpec"; Req.AnyScope = true; - std::vector Symbols; - I->fuzzyFind(Req, [&Symbols](const Symbol &Sym) { Symbols.push_back(Sym); }); - EXPECT_EQ(Symbols.size(), 1U); - EXPECT_FALSE(Symbols.front().SymInfo.Properties & - static_cast( - index::SymbolProperty::TemplateSpecialization)); - EXPECT_FALSE(Symbols.front().SymInfo.Properties & - static_cast( - index::SymbolProperty::TemplatePartialSpecialization)); + Req.Query = "TempSpec"; + EXPECT_THAT(match(*I, Req), + UnorderedElementsAre("TempSpec", "TempSpec", + "TempSpec")); + + Req.Query = "TempSpec", "TempSpec")); } TEST(MergeIndexTest, Lookup) { diff --git a/unittests/clangd/SymbolCollectorTests.cpp b/unittests/clangd/SymbolCollectorTests.cpp index f7b125b9..90dfc100 100644 --- a/unittests/clangd/SymbolCollectorTests.cpp +++ b/unittests/clangd/SymbolCollectorTests.cpp @@ -394,23 +394,80 @@ TEST_F(SymbolCollectorTest, Template) { Annotations Header(R"( // Primary template and explicit specialization are indexed, instantiation // is not. - template struct [[Tmpl]] {T $xdecl[[x]] = 0;}; - template <> struct $specdecl[[Tmpl]] {}; - template struct $partspecdecl[[Tmpl]] {}; - extern template struct Tmpl; - template struct Tmpl; + template class $barclasstemp[[Bar]] {}; + template class Z, int Q> + struct [[Tmpl]] { T $xdecl[[x]] = 0; }; + + // template-template, non-type and type full spec + template <> struct $specdecl[[Tmpl]] {}; + + // template-template, non-type and type partial spec + template struct $partspecdecl[[Tmpl]] {}; + // instantiation + extern template struct Tmpl; + // instantiation + template struct Tmpl; + + template class $fooclasstemp[[Foo]] {}; + // parameter-packs full spec + template<> class $parampack[[Foo]], int, double> {}; + // parameter-packs partial spec + template class $parampackpartial[[Foo]] {}; + + template class $bazclasstemp[[Baz]] {}; + // non-type parameter-packs full spec + template<> class $parampacknontype[[Baz]]<3, 5, 8> {}; + // non-type parameter-packs partial spec + template class $parampacknontypepartial[[Baz]] {}; + + template