Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -3,6 +3,7 @@
add_subdirectory(modularize)
if(CLANG_ENABLE_STATIC_ANALYZER)
add_subdirectory(clang-tidy)
+add_subdirectory(clang-tidy-vs)
endif()
add_subdirectory(clang-query)
Index: clang-tidy-vs/CMakeLists.txt
===================================================================
--- /dev/null
+++ clang-tidy-vs/CMakeLists.txt
@@ -0,0 +1,28 @@
+option(BUILD_CLANG_TIDY_VS_PLUGIN "Build clang-tidy VS plugin" OFF)
+if (BUILD_CLANG_TIDY_VS_PLUGIN)
+ add_custom_target(clang_tidy_exe_for_vsix
+ ${CMAKE_COMMAND} -E copy_if_different
+ "${LLVM_TOOLS_BINARY_DIR}/clang-tidy.exe"
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/clang-tidy.exe"
+ DEPENDS clang-tidy)
+
+ add_custom_target(clang_tidy_license
+ ${CMAKE_COMMAND} -E copy_if_different
+ "${CLANG_SOURCE_DIR}/LICENSE.TXT"
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/license.txt")
+
+ if (NOT CLANG_TIDY_VS_VERSION)
+ set(CLANG_TIDY_VS_VERSION "${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
+ endif()
+
+ configure_file("source.extension.vsixmanifest.in"
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/source.extension.vsixmanifest")
+
+ add_custom_target(clang_tidy_vsix ALL
+ devenv "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy.sln" /Build Release
+ DEPENDS clang_tidy_exe_for_vsix "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/source.extension.vsixmanifest"
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${CMAKE_CURRENT_SOURCE_DIR}/ClangTidy/bin/Release/ClangTidy.vsix"
+ "${LLVM_TOOLS_BINARY_DIR}/ClangTidy.vsix"
+ DEPENDS clang_tidy_exe_for_vsix clang_tidy_license)
+endif()
Index: clang-tidy-vs/ClangTidy.sln
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy.sln
@@ -0,0 +1,22 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25123.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ClangTidy", "ClangTidy\ClangTidy.csproj", "{BE261DA1-36C6-449A-95C5-4653A549170A}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {BE261DA1-36C6-449A-95C5-4653A549170A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BE261DA1-36C6-449A-95C5-4653A549170A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BE261DA1-36C6-449A-95C5-4653A549170A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BE261DA1-36C6-449A-95C5-4653A549170A}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
Index: clang-tidy-vs/ClangTidy/CategoryVerb.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/CategoryVerb.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// Allows entire categories of properties to be enabled, disabled, or inherited
+ /// in one fell swoop. We add properties to each category with the value being
+ /// this enum, and when the value is selected, we use reflection to find all other
+ /// properties in the same category and perform the corresponding action.
+ ///
+ public enum CategoryVerb
+ {
+ None,
+ Disable,
+ Enable,
+ Inherit
+ }
+
+ public class CategoryVerbConverter : EnumConverter
+ {
+ public CategoryVerbConverter() : base(typeof(CategoryVerb))
+ {
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value is string)
+ {
+ switch ((string)value)
+ {
+ case "Disable Category":
+ return CategoryVerb.Disable;
+ case "Enable Category":
+ return CategoryVerb.Enable;
+ case "Inherit Category":
+ return CategoryVerb.Inherit;
+ case "":
+ return CategoryVerb.None;
+ }
+ }
+ return base.ConvertFrom(context, culture, value);
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (value.GetType() == typeof(CategoryVerb) && destinationType == typeof(string))
+ {
+ switch ((CategoryVerb)value)
+ {
+ case CategoryVerb.Disable:
+ return "Disable Category";
+ case CategoryVerb.Enable:
+ return "Enable Category";
+ case CategoryVerb.Inherit:
+ return "Inherit Category";
+ case CategoryVerb.None:
+ return String.Empty;
+ }
+ }
+
+ return base.ConvertTo(context, culture, value, destinationType);
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/CheckTree.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/CheckTree.cs
@@ -0,0 +1,274 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// CheckTree is used to group checks into categories and subcategories. For
+ /// example, given the following list of checks:
+ ///
+ /// llvm-include-order
+ /// llvm-namespace-comment
+ /// llvm-twine-local
+ /// llvm-header-guard
+ /// google-runtime-member-string-references
+ /// google-runtime-int
+ /// google-readability-namespace-comments
+ ///
+ /// the corresponding CheckTree would look like this:
+ ///
+ /// llvm
+ /// include-order
+ /// namespace-comment
+ /// twine-local
+ /// header-guard
+ /// google
+ /// runtime
+ /// member-string-references
+ /// int
+ /// readability
+ /// namespace-comments
+ /// redundant-smartptr-get
+ ///
+ /// This is useful when serializing a set of options out to a .clang-tidy file,
+ /// because we need to decide the most efficient way to serialize the sequence
+ /// of check commands, when to use wildcards, etc. For example, if everything
+ /// under google is inherited, we can simply leave that entry out entirely from
+ /// the .clang-tidy file. On the other hand, if anything is inherited, we *must
+ /// not* add or remove google-* by wildcard because that, by definition, means
+ /// the property is no longer inherited. When we can categorize the checks into
+ /// groups and subgroups like this, it is possible to efficiently serialize to
+ /// a minimal representative .clang-tidy file.
+ ///
+
+ public abstract class CheckTreeNode
+ {
+ private string Name_;
+ private CheckTreeNode Parent_;
+
+ protected CheckTreeNode(string Name, CheckTreeNode Parent)
+ {
+ Name_ = Name;
+ Parent_ = Parent;
+ }
+
+ public string Path
+ {
+ get
+ {
+ if (Parent_ == null)
+ return null;
+ string ParentPath = Parent_.Path;
+ if (ParentPath == null)
+ return Name_;
+ return ParentPath + "-" + Name_;
+ }
+ }
+
+ public string Name
+ {
+ get
+ {
+ return Name_;
+ }
+ }
+
+
+ public abstract int CountChecks { get; }
+ public abstract int CountExplicitlyDisabledChecks { get; }
+ public abstract int CountExplicitlyEnabledChecks { get; }
+ public abstract int CountInheritedChecks { get; }
+ }
+
+ public class CheckTree : CheckTreeNode
+ {
+ private Dictionary Children_ = new Dictionary();
+ public CheckTree()
+ : base(null, null)
+ {
+
+ }
+
+ private CheckTree(string Name, CheckTree Parent)
+ : base(Name, Parent)
+ {
+ }
+
+ private void AddLeaf(string Name, InheritableValuePropertyDescriptor Property)
+ {
+ Children_[Name] = new CheckLeaf(Name, this, Property);
+ }
+
+ private CheckTree AddOrCreateSubgroup(string Name)
+ {
+ CheckTreeNode Subgroup = null;
+ if (Children_.TryGetValue(Name, out Subgroup))
+ {
+ System.Diagnostics.Debug.Assert(Subgroup is CheckTree);
+ return (CheckTree)Subgroup;
+ }
+
+ CheckTree SG = new CheckTree(Name, this);
+ Children_[Name] = SG;
+ return SG;
+ }
+
+ public static CheckTree Build(ClangTidyProperties Config)
+ {
+ // Since some check names contain dashes in them, it doesn't make sense to
+ // simply split all check names by dash and construct a huge tree. For
+ // example, in the check called google-runtime-member-string-references,
+ // we don't need each of those to be a different subgroup. So instead we
+ // explicitly specify the common breaking points at which a user might want
+ // to use a -* and everything else falls as a leaf under one of these
+ // categories.
+ // FIXME: This should be configurable without recompilation
+ CheckTree Root = new CheckTree();
+ string[][] Groups = new string[][] {
+ new string[] {"boost"},
+ new string[] {"cert"},
+ new string[] {"clang", "diagnostic"},
+ new string[] {"cppcoreguidelines", "interfaces"},
+ new string[] {"cppcoreguidelines", "pro", "bounds"},
+ new string[] {"cppcoreguidelines", "pro", "type"},
+ new string[] {"google", "build"},
+ new string[] {"google", "readability"},
+ new string[] {"google", "runtime"},
+ new string[] {"llvm"},
+ new string[] {"misc"},
+ };
+
+ foreach (string[] Group in Groups)
+ {
+ CheckTree Subgroup = Root;
+ foreach (string Component in Group)
+ Subgroup = Subgroup.AddOrCreateSubgroup(Component);
+ }
+
+ var Props = Config.GetProperties()
+ .Cast()
+ .OfType>()
+ .Where(x => x.Attributes.OfType().Count() > 0)
+ .Select(x => new KeyValuePair, string>(
+ x, x.Attributes.OfType().First().CheckName));
+ var PropArray = Props.ToArray();
+ foreach (var CheckInfo in PropArray)
+ {
+ string LeafName = null;
+ CheckTree Tree = Root.LocateCheckLeafGroup(CheckInfo.Value, out LeafName);
+ Tree.AddLeaf(LeafName, CheckInfo.Key);
+ }
+ return Root;
+ }
+
+ private CheckTree LocateCheckLeafGroup(string Check, out string LeafName)
+ {
+ string[] Components = Check.Split('-');
+ string FirstComponent = Components.FirstOrDefault();
+ if (FirstComponent == null)
+ {
+ LeafName = Check;
+ return this;
+ }
+
+ CheckTreeNode Subgroup = null;
+ if (!Children_.TryGetValue(FirstComponent, out Subgroup))
+ {
+ LeafName = Check;
+ return this;
+ }
+ System.Diagnostics.Debug.Assert(Subgroup is CheckTree);
+ CheckTree Child = (CheckTree)Subgroup;
+ string ChildName = Check.Substring(FirstComponent.Length + 1);
+ return Child.LocateCheckLeafGroup(ChildName, out LeafName);
+ }
+
+ public override int CountChecks
+ {
+ get
+ {
+ return Children_.Aggregate(0, (X, V) => { return X + V.Value.CountChecks; });
+ }
+ }
+
+ public override int CountExplicitlyDisabledChecks
+ {
+ get
+ {
+ return Children_.Aggregate(0, (X, V) => { return X + V.Value.CountExplicitlyDisabledChecks; });
+ }
+ }
+
+ public override int CountExplicitlyEnabledChecks
+ {
+ get
+ {
+ return Children_.Aggregate(0, (X, V) => { return X + V.Value.CountExplicitlyEnabledChecks; });
+ }
+ }
+ public override int CountInheritedChecks
+ {
+ get
+ {
+ return Children_.Aggregate(0, (X, V) => { return X + V.Value.CountInheritedChecks; });
+ }
+ }
+
+ public IDictionary Children
+ {
+ get { return Children_; }
+ }
+ }
+
+ public class CheckLeaf : CheckTreeNode
+ {
+ private InheritableValuePropertyDescriptor Property_;
+
+ public CheckLeaf(string Name, CheckTree Parent, InheritableValuePropertyDescriptor Property)
+ : base(Name, Parent)
+ {
+ Property_ = Property;
+ }
+
+ public override int CountChecks
+ {
+ get
+ {
+ return 1;
+ }
+ }
+
+ public override int CountExplicitlyDisabledChecks
+ {
+ get
+ {
+ if (Property_.IsInheriting)
+ return 0;
+ return Property_.Value ? 0 : 1;
+ }
+ }
+
+ public override int CountExplicitlyEnabledChecks
+ {
+ get
+ {
+ if (Property_.IsInheriting)
+ return 0;
+ return Property_.Value ? 1 : 0;
+ }
+ }
+
+ public override int CountInheritedChecks
+ {
+ get
+ {
+ return (Property_.IsInheriting) ? 1 : 0;
+ }
+ }
+
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidy.csproj
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidy.csproj
@@ -0,0 +1,264 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 2.0
+ {BE261DA1-36C6-449A-95C5-4653A549170A}
+ {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ Library
+ Properties
+ LLVM.ClangTidy
+ ClangTidy
+ true
+ Key.snk
+ v4.5
+ 14.0
+
+
+
+
+ 4.0
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 0
+ false
+ AnyCPU
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ ..\packages\YamlDotNet.3.3.0\lib\net35\YamlDotNet.dll
+ True
+
+
+ ..\packages\YamlDotNet.Dynamic.3.2.3\lib\net40\YamlDotNet.Dynamic.dll
+ True
+
+
+
+
+ {80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}
+ 8
+ 0
+ 0
+ primary
+ False
+ False
+
+
+ {26AD1324-4B7C-44BC-84F8-B86AED45729F}
+ 10
+ 0
+ 0
+ primary
+ False
+ False
+
+
+ {1A31287A-4D7D-413E-8E32-3B374931BD89}
+ 8
+ 0
+ 0
+ primary
+ False
+ False
+
+
+ {2CE2370E-D744-4936-A090-3FFFE667B0E1}
+ 9
+ 0
+ 0
+ primary
+ False
+ False
+
+
+ {1CBA492E-7263-47BB-87FE-639000619B15}
+ 8
+ 0
+ 0
+ primary
+ False
+ False
+
+
+ {00020430-0000-0000-C000-000000000046}
+ 2
+ 0
+ 0
+ primary
+ False
+ False
+
+
+
+
+
+
+
+ Component
+
+
+ Component
+
+
+
+
+
+ Component
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+ UserControl
+
+
+ ClangTidyPropertyGrid.cs
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+ Designer
+
+
+ ClangTidyPropertyGrid.cs
+
+
+ true
+ VSPackage
+
+
+
+
+
+
+ Designer
+
+
+
+
+ Menus.ctmenu
+
+
+
+
+
+
+
+ true
+
+
+ true
+
+
+
+
+
+ False
+ Microsoft .NET Framework 4 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1 Client Profile
+ false
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+ False
+ Windows Installer 4.5
+ true
+
+
+
+ true
+
+
+ 10.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+
+ if not exist $(ProjectDir)Key.snk ("$(SDKToolsPath)\sn.exe" -k $(ProjectDir)Key.snk)
+
+
+
+
+
+
\ No newline at end of file
Index: clang-tidy-vs/ClangTidy/ClangTidy.vsct
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidy.vsct
@@ -0,0 +1,118 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: clang-tidy-vs/ClangTidy/ClangTidyCheckAttribute.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyCheckAttribute.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ public class ClangTidyCheckAttribute : Attribute
+ {
+ private string CheckName_;
+ public ClangTidyCheckAttribute(string CheckName)
+ {
+ this.CheckName_ = CheckName;
+ }
+
+ public string CheckName
+ {
+ get { return CheckName_; }
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidyConfigurationPage.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyConfigurationPage.cs
@@ -0,0 +1,33 @@
+using EnvDTE;
+using EnvDTE100;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Forms;
+
+namespace LLVM.ClangTidy
+{
+ [ClassInterface(ClassInterfaceType.AutoDual)]
+ [CLSCompliant(false), ComVisible(true)]
+ public class ClangTidyConfigurationPage : DialogPage
+ {
+ ClangTidyPropertyGrid Grid = null;
+ protected override IWin32Window Window
+ {
+ get
+ {
+ if (Grid == null)
+ Grid = new ClangTidyPropertyGrid();
+ return Grid;
+ }
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
@@ -0,0 +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)
+ {
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidyProperties.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyProperties.cs
@@ -0,0 +1,996 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+
+ public class ClangTidyProperties : InheritablePropertyComponent
+ {
+ private static ClangTidyProperties RootProperties_ = null;
+ private CheckTree CheckTree_;
+ private bool HasUnsavedChanges_ = false;
+
+ public struct CheckMapping
+ {
+ public string CheckName;
+ public string Property;
+ }
+
+ public ClangTidyProperties()
+ : base(null)
+ {
+ CheckTree_ = CheckTree.Build(this);
+ }
+
+ public ClangTidyProperties(InheritablePropertyComponent Parent)
+ : base(Parent)
+ {
+ CheckTree_ = CheckTree.Build(this);
+ }
+
+ static ClangTidyProperties()
+ {
+ RootProperties_ = new ClangTidyProperties(null);
+ PropertyDescriptor D;
+ }
+
+ public static ClangTidyProperties RootProperties
+ {
+ get { return RootProperties_; }
+ }
+
+ public CheckTree GetCheckTree() { return CheckTree_; }
+ public bool GetHasUnsavedChanges() { return HasUnsavedChanges_; }
+ public void SetHasUnsavedChanges(bool Value) { HasUnsavedChanges_ = Value; }
+
+ public IEnumerable FindChecksMatching(string Pattern)
+ {
+ foreach (var V in InheritedDescriptors_)
+ {
+ ClangTidyCheckAttribute CheckAttr = V.Value.Attributes.OfType().FirstOrDefault();
+ if (CheckAttr == null)
+ continue;
+
+ if (!Utility.MatchWildcardString(CheckAttr.CheckName, Pattern))
+ continue;
+
+ var Result = new CheckMapping { CheckName = CheckAttr.CheckName, Property = V.Value.Name };
+ yield return Result;
+ }
+ }
+
+ [Category("CERT Secure Coding Standards")]
+ [DisplayName("(Quick Actions)")]
+ [Description("")]
+ [TypeConverter(typeof(CategoryVerbConverter))]
+ [DefaultValue(CategoryVerb.None)]
+ public CategoryVerb CERTQuickActions { get; set; }
+
+ [Category("CERT Secure Coding Standards")]
+ [DisplayName("DCL50-CPP")]
+ [Description("Checks for violations of CERT DCL50-CPP - Do not define a C-style variadic function")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cert-dcl50-cpp")]
+ public bool CERTDCL50
+ {
+ get { return GetInheritableProperty("CERTDCL50").Value; }
+ set { GetInheritableProperty("CERTDCL50").Value = value; }
+ }
+
+ [Category("CERT Secure Coding Standards")]
+ [DisplayName("DCL54-CPP")]
+ [Description("Checks for violations of CERT DCL54-CPP - Overload allocation and deallocation functions as a pair in the same scope")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cert-dcl54-cpp")]
+ public bool CERTDCL54
+ {
+ get { return GetInheritableProperty("CERTDCL54").Value; }
+ set { GetInheritableProperty("CERTDCL54").Value = value; }
+ }
+
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("(Quick Actions)")]
+ [Description("")]
+ [TypeConverter(typeof(CategoryVerbConverter))]
+ [DefaultValue(CategoryVerb.None)]
+ public CategoryVerb CPPCoreQuickActions { get; set; }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("I.22 - Complex Global Initializers")]
+ [Description("Checks for violations of Core Guideline I.22 - Avoid complex initializers of global objects")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-interfaces-global-init")]
+ public bool CPPCoreI22
+ {
+ get { return GetInheritableProperty("CPPCoreI22").Value; }
+ set { GetInheritableProperty("CPPCoreI22").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Bounds.1 - No pointer arithmetic")]
+ [Description("Checks for violations of Core Guideline Bounds.3 - Don't use pointer arithmetic. Use span<> instead.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-bounds-pointer-arithmetic")]
+ public bool CPPCoreBounds1
+ {
+ get { return GetInheritableProperty("CPPCoreBounds1").Value; }
+ set { GetInheritableProperty("CPPCoreBounds1").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Bounds.2 - Constant array indices")]
+ [Description("Checks for violations of Core Bounds.2 - Only index into arrays using constant expressions.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-bounds-constant-array-index")]
+ public bool CPPCoreBounds2
+ {
+ get { return GetInheritableProperty("CPPCoreBounds2").Value; }
+ set { GetInheritableProperty("CPPCoreBounds2").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Bounds.3 - Array to Pointer Decay")]
+ [Description("Checks for violations of Core Guideline Bounds.3 - No array-to-pointer decay")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-bounds-array-to-pointer-decay")]
+ public bool CPPCoreBounds3
+ {
+ get { return GetInheritableProperty("CPPCoreBounds3").Value; }
+ set { GetInheritableProperty("CPPCoreBounds3").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("const_cast (Type.3)")]
+ [Description("Checks for violations of Core Guideline Type.3 - Don't use const_cast to cast away const")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-const-cast")]
+ public bool CPPCoreConstCast
+ {
+ get { return GetInheritableProperty("CPPCoreConstCast").Value; }
+ set { GetInheritableProperty("CPPCoreConstCast").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("C style casts (Type.4)")]
+ [Description("Checks for violations of Core Guideline Type.3 - Don't use C-style (T)expression casts that would perform a static downcast, const_cast, or reinterpret_cast")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-cstyle-cast")]
+ public bool CPPCoreCStyleCast
+ {
+ get { return GetInheritableProperty("CPPCoreCStyleCast").Value; }
+ set { GetInheritableProperty("CPPCoreCStyleCast").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("reinterpret_cast (Type.1)")]
+ [Description("Checks for violations of Core Guideline Type.1 - Don't use reinterpret_cast.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-reinterpret-cast")]
+ public bool CPPCoreReinterpretCast
+ {
+ get { return GetInheritableProperty("CPPCoreReinterpretCast").Value; }
+ set { GetInheritableProperty("CPPCoreReinterpretCast").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Prefer dynamic_cast (Type.2)")]
+ [Description("Checks for violations of Core Guideline Type.2 - Don't use static_cast downcasts. Use dynamic_cast instead.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-static-cast-downcast")]
+ public bool CPPCoreDynamicCast
+ {
+ get { return GetInheritableProperty("CPPCoreDynamicCast").Value; }
+ set { GetInheritableProperty("CPPCoreDynamicCast").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Member variable initialization (Type.6)")]
+ [Description("Checks for violations of Core Guideline Type.6 - Always initialize a member variable.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-member-init")]
+ public bool CPPCoreMemberVariableInit
+ {
+ get { return GetInheritableProperty("CPPCoreMemberVariableInit").Value; }
+ set { GetInheritableProperty("CPPCoreMemberVariableInit").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Avoid unions (Type.7)")]
+ [Description("Checks for violations of Core Guideline Type.7 - Avoid accessing members of raw unions. Use variant instead.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-union-access")]
+ public bool CPPCoreUnionMemberAccess
+ {
+ get { return GetInheritableProperty("CPPCoreUnionMemberAccess").Value; }
+ set { GetInheritableProperty("CPPCoreUnionMemberAccess").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Don't use varargs (Type.8)")]
+ [Description("Checks for violations of Core Guideline Type.8 - Avoid reading varargs or passing vararg arguments. Prefer variadic templates instead.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-pro-type-vararg")]
+ public bool CPPCoreVarArgs
+ {
+ get { return GetInheritableProperty("CPPCoreVarArgs").Value; }
+ set { GetInheritableProperty("CPPCoreVarArgs").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Don't slice (ES.63 & C.145)")]
+ [Description("Checks for violations of Core Guidelines ES.63 (Don't slice) and C.145 (Access polymorphic objects through pointers and references)")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-slicing")]
+ public bool CPPCoreDontSlice
+ {
+ get { return GetInheritableProperty("CPPCoreDontSlice").Value; }
+ set { GetInheritableProperty("CPPCoreDontSlice").Value = value; }
+ }
+
+ [Category("C++ Core Guidelines")]
+ [DisplayName("Detect unsafe special functions (C.21)")]
+ [Description("Checks for violations of Core Guidelines C.21 - If you define or =delete any default operation, define or =delete them all.")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("cppcoreguidelines-special-member-functions")]
+ public bool CPPCoreUnsafeSpecialFunctions
+ {
+ get { return GetInheritableProperty("CPPCoreUnsafeSpecialFunctions").Value; }
+ set { GetInheritableProperty("CPPCoreUnsafeSpecialFunctions").Value = value; }
+ }
+
+
+ [Category("Google Style Guide")]
+ [DisplayName("(Quick Actions)")]
+ [Description("")]
+ [TypeConverter(typeof(CategoryVerbConverter))]
+ [DefaultValue(CategoryVerb.None)]
+ public CategoryVerb GoogleQuickActions { get; set; }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Forbid explicitly parameterized make_pair")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-build-explicit-make-pair")]
+ public bool GoogleExplicitMakePair
+ {
+ get { return GetInheritableProperty("GoogleExplicitMakePair").Value; }
+ set { GetInheritableProperty("GoogleExplicitMakePair").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Anonymous namespace in headers")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-build-namespaces")]
+ public bool GoogleBuildNamespaces
+ {
+ get { return GetInheritableProperty("GoogleBuildNamespaces").Value; }
+ set { GetInheritableProperty("GoogleBuildNamespaces").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find using namespace directives")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-build-using-namespace")]
+ public bool GoogleBuildUsingNamespace
+ {
+ get { return GetInheritableProperty("GoogleBuildUsingNamespace").Value; }
+ set { GetInheritableProperty("GoogleBuildUsingNamespace").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Default arguments in virtual methods")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-default-arguments")]
+ public bool GoogleDefaultArgs
+ {
+ get { return GetInheritableProperty("GoogleDefaultArgs").Value; }
+ set { GetInheritableProperty("GoogleDefaultArgs").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("explicit constructors")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-explicit-constructor")]
+ public bool GoogleExplicitConstructor
+ {
+ get { return GetInheritableProperty("GoogleExplicitConstructor").Value; }
+ set { GetInheritableProperty("GoogleExplicitConstructor").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Global namespace pollution in headers")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-global-names-in-headers")]
+ public bool GoogleGlobalNamesInHeaders
+ {
+ get { return GetInheritableProperty("GoogleGlobalNamesInHeaders").Value; }
+ set { GetInheritableProperty("GoogleGlobalNamesInHeaders").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Braces around statements")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-readability-braces-around-statements")]
+ public bool GoogleReadabilityBracesAroundStatements
+ {
+ get { return GetInheritableProperty("GoogleReadabilityBracesAroundStatements").Value; }
+ set { GetInheritableProperty("GoogleReadabilityBracesAroundStatements").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("No C-style casts")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-readability-casting")]
+ public bool GoogleReadabilityCasting
+ {
+ get { return GetInheritableProperty("GoogleReadabilityCasting").Value; }
+ set { GetInheritableProperty("GoogleReadabilityCasting").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find large functions")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-readability-function-size")]
+ public bool GoogleReadabilityFunctionSize
+ {
+ get { return GetInheritableProperty("GoogleReadabilityFunctionSize").Value; }
+ set { GetInheritableProperty("GoogleReadabilityFunctionSize").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Namespace closing comments")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-readability-namespace-comments")]
+ public bool GoogleReadabilityNamespaceComments
+ {
+ get { return GetInheritableProperty("GoogleReadabilityNamespaceComments").Value; }
+ set { GetInheritableProperty("GoogleReadabilityNamespaceComments").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find unnecessary calls to .get()")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-readability-redundant-smartptr-get")]
+ public bool GoogleReadabilityRedundantSmartPtrGet
+ {
+ get { return GetInheritableProperty("GoogleReadabilityRedundantSmartPtrGet").Value; }
+ set { GetInheritableProperty("GoogleReadabilityRedundantSmartPtrGet").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-readability-todo")]
+ public bool GoogleReadabilityTodo
+ {
+ get { return GetInheritableProperty("GoogleReadabilityTodo").Value; }
+ set { GetInheritableProperty("GoogleReadabilityTodo").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find non-conformant TODO comments")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-runtime-int")]
+ public bool GoogleRuntimeInt
+ {
+ get { return GetInheritableProperty("GoogleRuntimeInt").Value; }
+ set { GetInheritableProperty("GoogleRuntimeInt").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find const string references")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-runtime-member-string-references")]
+ public bool GoogleRuntimeMemberStringReferences
+ {
+ get { return GetInheritableProperty("GoogleRuntimeMemberStringReferences").Value; }
+ set { GetInheritableProperty("GoogleRuntimeMemberStringReferences").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find zero-length memsets")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-runtime-memset")]
+ public bool GoogleRuntimeMemset
+ {
+ get { return GetInheritableProperty("GoogleRuntimeMemset").Value; }
+ set { GetInheritableProperty("GoogleRuntimeMemset").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Find overloads of operator&")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-runtime-operator")]
+ public bool GoogleRuntimeOperator
+ {
+ get { return GetInheritableProperty("GoogleRuntimeOperator").Value; }
+ set { GetInheritableProperty("GoogleRuntimeOperator").Value = value; }
+ }
+
+ [Category("Google Style Guide")]
+ [DisplayName("Check usage of non-const references")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("google-runtime-references")]
+ public bool GoogleRuntimeReferences
+ {
+ get { return GetInheritableProperty("GoogleRuntimeReferences").Value; }
+ set { GetInheritableProperty("GoogleRuntimeReferences").Value = value; }
+ }
+
+
+ [Category("LLVM Style Guide")]
+ [DisplayName("(Quick Actions)")]
+ [Description("")]
+ [TypeConverter(typeof(CategoryVerbConverter))]
+ [DefaultValue(CategoryVerb.None)]
+ public CategoryVerb LLVMQuickActions { get; set; }
+
+ [Category("LLVM Style Guide")]
+ [DisplayName("LLVM header guards")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("llvm-header-guard")]
+ public bool LLVMHeaderGuard
+ {
+ get { return GetInheritableProperty("LLVMHeaderGuard").Value; }
+ set { GetInheritableProperty("LLVMHeaderGuard").Value = value; }
+ }
+
+ [Category("LLVM Style Guide")]
+ [DisplayName("LLVM include order")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("llvm-include-order")]
+ public bool LLVMIncludeOrder
+ {
+ get { return GetInheritableProperty("LLVMIncludeOrder").Value; }
+ set { GetInheritableProperty("LLVMIncludeOrder").Value = value; }
+ }
+
+ [Category("LLVM Style Guide")]
+ [DisplayName("LLVM namespace comments")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("llvm-namespace-comment")]
+ public bool LLVMNamespaceComment
+ {
+ get { return GetInheritableProperty("LLVMNamespaceComment").Value; }
+ set { GetInheritableProperty("LLVMNamespaceComment").Value = value; }
+ }
+
+ [Category("LLVM Style Guide")]
+ [DisplayName("Find local twines")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("llvm-twine-local")]
+ public bool LLVMTwineLocal
+ {
+ get { return GetInheritableProperty("LLVMTwineLocal").Value; }
+ set { GetInheritableProperty("LLVMTwineLocal").Value = value; }
+ }
+
+
+ [Category("Clang Diagnostics")]
+ [DisplayName("(Quick Actions)")]
+ [Description("")]
+ [TypeConverter(typeof(CategoryVerbConverter))]
+ [DefaultValue(CategoryVerb.None)]
+ public CategoryVerb ClangDiagQuickActions { get; set; }
+
+ [Category("Clang Diagnostics")]
+ [DisplayName("Warnings")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("clang-diagnostic-warning")]
+ public bool ClangDiagWarning
+ {
+ get { return GetInheritableProperty("ClangDiagWarning").Value; }
+ set { GetInheritableProperty("ClangDiagWarning").Value = value; }
+ }
+
+ [Category("Clang Diagnostics")]
+ [DisplayName("Errors")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("clang-diagnostic-error")]
+ public bool ClangDiagError
+ {
+ get { return GetInheritableProperty("ClangDiagError").Value; }
+ set { GetInheritableProperty("ClangDiagError").Value = value; }
+ }
+
+ [Category("Clang Diagnostics")]
+ [DisplayName("Unknown")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("clang-diagnostic-unknown")]
+ public bool ClangDiagUnknown
+ {
+ get { return GetInheritableProperty("ClangDiagUnknown").Value; }
+ set { GetInheritableProperty("ClangDiagUnknown").Value = value; }
+ }
+
+
+ [Category("Miscellaneous")]
+ [DisplayName("(Quick Actions)")]
+ [Description("")]
+ [TypeConverter(typeof(CategoryVerbConverter))]
+ [DefaultValue(CategoryVerb.None)]
+ public CategoryVerb MiscQuickActions { get; set; }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Validate argument comments")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-argument-comment")]
+ public bool MiscArgumentComment
+ {
+ get { return GetInheritableProperty("MiscArgumentComment").Value; }
+ set { GetInheritableProperty("MiscArgumentComment").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Side effects in assert()")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-assert-side-effect")]
+ public bool MiscAssertSideEffect
+ {
+ get { return GetInheritableProperty("MiscAssertSideEffect").Value; }
+ set { GetInheritableProperty("MiscAssertSideEffect").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("bool / pointer implicit conversions")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-bool-pointer-implicit-conversion")]
+ public bool MiscBoolPointerImplicitConversion
+ {
+ get { return GetInheritableProperty("MiscBoolPointerImplicitConversion").Value; }
+ set { GetInheritableProperty("MiscBoolPointerImplicitConversion").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Dangling handles")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-dangling-handle")]
+ public bool MiscDanglingHandle
+ {
+ get { return GetInheritableProperty("MiscDanglingHandle").Value; }
+ set { GetInheritableProperty("MiscDanglingHandle").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Definitions in headers")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-definitions-in-headers")]
+ public bool MiscDefinitionsInHeaders
+ {
+ get { return GetInheritableProperty("MiscDefinitionsInHeaders").Value; }
+ set { GetInheritableProperty("MiscDefinitionsInHeaders").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Type mismatch in fold operations")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-fold-init-type")]
+ public bool MiscFoldInitType
+ {
+ get { return GetInheritableProperty("MiscFoldInitType").Value; }
+ set { GetInheritableProperty("MiscFoldInitType").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Forward declaration namespace")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-forward-declaration-namespace")]
+ public bool MiscForwardDeclarationNamespace
+ {
+ get { return GetInheritableProperty("MiscForwardDeclarationNamespace").Value; }
+ set { GetInheritableProperty("MiscForwardDeclarationNamespace").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Inaccurate erase")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-inaccurate-erase")]
+ public bool MiscInaccurateErase
+ {
+ get { return GetInheritableProperty("MiscInaccurateErase").Value; }
+ set { GetInheritableProperty("MiscInaccurateErase").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Incorrect rounding")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-incorrect-roundings")]
+ public bool MiscIncorrectRoundings
+ {
+ get { return GetInheritableProperty("MiscIncorrectRoundings").Value; }
+ set { GetInheritableProperty("MiscIncorrectRoundings").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Inefficient STL algorithms")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-inefficient-algorithm")]
+ public bool MiscInefficientAlgorithm
+ {
+ get { return GetInheritableProperty("MiscInefficientAlgorithm").Value; }
+ set { GetInheritableProperty("MiscInefficientAlgorithm").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Macro parentheses")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-macro-parentheses")]
+ public bool MiscMacroParens
+ {
+ get { return GetInheritableProperty("MiscMacroParens").Value; }
+ set { GetInheritableProperty("MiscMacroParens").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Macro repeated side effects")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-macro-repeated-side-effects")]
+ public bool MiscMacroRepeatedSideEffects
+ {
+ get { return GetInheritableProperty("MiscMacroRepeatedSideEffects").Value; }
+ set { GetInheritableProperty("MiscMacroRepeatedSideEffects").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Misplaced const")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-misplaced-const")]
+ public bool MiscMisplacedConst
+ {
+ get { return GetInheritableProperty("MiscMisplacedConst").Value; }
+ set { GetInheritableProperty("MiscMisplacedConst").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Misplaced widening casts")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-misplaced-widening-cast")]
+ public bool MiscMisplacedWideningCast
+ {
+ get { return GetInheritableProperty("MiscMisplacedWideningCast").Value; }
+ set { GetInheritableProperty("MiscMisplacedWideningCast").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Move constructor const arguments")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-move-const-arg")]
+ public bool MiscMoveConstArg
+ {
+ get { return GetInheritableProperty("MiscMoveConstArg").Value; }
+ set { GetInheritableProperty("MiscMoveConstArg").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Move constructor initialization")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-move-constructor-init")]
+ public bool MiscMoveConstructorInit
+ {
+ get { return GetInheritableProperty("MiscMoveConstructorInit").Value; }
+ set { GetInheritableProperty("MiscMoveConstructorInit").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Multi-statement macros")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-multiple-statement-macro")]
+ public bool MiscMultipleStatementMacro
+ {
+ get { return GetInheritableProperty("MiscMultipleStatementMacro").Value; }
+ set { GetInheritableProperty("MiscMultipleStatementMacro").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Verify new / delete overloads")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-new-delete-overloads")]
+ public bool MiscNewDeleteOverloads
+ {
+ get { return GetInheritableProperty("MiscNewDeleteOverloads").Value; }
+ set { GetInheritableProperty("MiscNewDeleteOverloads").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Ensure move constructors are noexcept")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-noexcept-move-constructor")]
+ public bool MiscNoexceptMoveConstructor
+ {
+ get { return GetInheritableProperty("MiscNoexceptMoveConstructor").Value; }
+ set { GetInheritableProperty("MiscNoexceptMoveConstructor").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Copying of non-copyable objects")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-non-copyable-objects")]
+ public bool MiscNoncopyableObjects
+ {
+ get { return GetInheritableProperty("MiscNoncopyableObjects").Value; }
+ set { GetInheritableProperty("MiscNoncopyableObjects").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Suspicious pointer / integer operations")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-pointer-and-integral-operation")]
+ public bool MiscPointerAndIntegralOperation
+ {
+ get { return GetInheritableProperty("MiscPointerAndIntegralOperation").Value; }
+ set { GetInheritableProperty("MiscPointerAndIntegralOperation").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Find redundant expressions")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-redundant-expression")]
+ public bool MiscRedundantExpression
+ {
+ get { return GetInheritableProperty("MiscRedundantExpression").Value; }
+ set { GetInheritableProperty("MiscRedundantExpression").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("sizeof() on stl containers")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-sizeof-container")]
+ public bool MiscSizeofContainer
+ {
+ get { return GetInheritableProperty("MiscSizeofContainer").Value; }
+ set { GetInheritableProperty("MiscSizeofContainer").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Suspicious sizeof() usage")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-sizeof-expression")]
+ public bool MiscSizeofExpression
+ {
+ get { return GetInheritableProperty("MiscSizeofExpression").Value; }
+ set { GetInheritableProperty("MiscSizeofExpression").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Replace assert with static_assert")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-static-assert")]
+ public bool MiscStaticAssert
+ {
+ get { return GetInheritableProperty("MiscStaticAssert").Value; }
+ set { GetInheritableProperty("MiscStaticAssert").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Suspicious string constructor")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-string-constructor")]
+ public bool MiscStringConstructor
+ {
+ get { return GetInheritableProperty("MiscStringConstructor").Value; }
+ set { GetInheritableProperty("MiscStringConstructor").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("String integer assignment")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-string-integer-assignment")]
+ public bool MiscStringIntegerAssignment
+ {
+ get { return GetInheritableProperty("MiscStringIntegerAssignment").Value; }
+ set { GetInheritableProperty("MiscStringIntegerAssignment").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("String literal with embedded null")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-string-literal-with-embedded-nul")]
+ public bool MiscStringLiteralWithEmbeddedNull
+ {
+ get { return GetInheritableProperty("MiscStringLiteralWithEmbeddedNull").Value; }
+ set { GetInheritableProperty("MiscStringLiteralWithEmbeddedNull").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Suspicious missing comma")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-suspicious-missing-comma")]
+ public bool MiscSuspiciousMissingComma
+ {
+ get { return GetInheritableProperty("MiscSuspiciousMissingComma").Value; }
+ set { GetInheritableProperty("MiscSuspiciousMissingComma").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Suspicious semicolon")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-suspicious-semicolon")]
+ public bool MiscSuspiciousSemicolon
+ {
+ get { return GetInheritableProperty("MiscSuspiciousSemicolon").Value; }
+ set { GetInheritableProperty("MiscSuspiciousSemicolon").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Suspicious string compare")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-suspicious-string-compare")]
+ public bool MiscSuspiciousStringCompare
+ {
+ get { return GetInheritableProperty("MiscSuspiciousStringCompare").Value; }
+ set { GetInheritableProperty("MiscSuspiciousStringCompare").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Swapped arguments")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-swapped-arguments")]
+ public bool MiscSwappedArguments
+ {
+ get { return GetInheritableProperty("MiscSwappedArguments").Value; }
+ set { GetInheritableProperty("MiscSwappedArguments").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Throw by value / catch by reference")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-throw-by-value-catch-by-reference")]
+ public bool MiscThrowCatch
+ {
+ get { return GetInheritableProperty("MiscThrowCatch").Value; }
+ set { GetInheritableProperty("MiscThrowCatch").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Unconventional operator=()")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-unconventional-assign-operator")]
+ public bool MiscUnconventionalAssignOperator
+ {
+ get { return GetInheritableProperty("MiscUnconventionalAssignOperator").Value; }
+ set { GetInheritableProperty("MiscUnconventionalAssignOperator").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Undelegated constructor")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-undelegated-constructor")]
+ public bool MiscUndelegatedConstructor
+ {
+ get { return GetInheritableProperty("MiscUndelegatedConstructor").Value; }
+ set { GetInheritableProperty("MiscUndelegatedConstructor").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("unique_ptr<> reset / release")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-uniqueptr-reset-release")]
+ public bool MiscUniqueptrResetRelease
+ {
+ get { return GetInheritableProperty("MiscUniqueptrResetRelease").Value; }
+ set { GetInheritableProperty("MiscUniqueptrResetRelease").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Unused Alias Decls")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-unused-alias-decls")]
+ public bool MiscUnusedAliasDecls
+ {
+ get { return GetInheritableProperty("MiscUnusedAliasDecls").Value; }
+ set { GetInheritableProperty("MiscUnusedAliasDecls").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Unused Params")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-unused-parameters")]
+ public bool MiscUnusedParams
+ {
+ get { return GetInheritableProperty("MiscUnusedParams").Value; }
+ set { GetInheritableProperty("MiscUnusedParams").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Unused Raii")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-unused-raii")]
+ public bool MiscUnusedRaii
+ {
+ get { return GetInheritableProperty("MiscUnusedRaii").Value; }
+ set { GetInheritableProperty("MiscUnusedRaii").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Unused Using Decls")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-unused-using-decls")]
+ public bool MiscUnusedUsingDecls
+ {
+ get { return GetInheritableProperty("MiscUnusedUsingDecls").Value; }
+ set { GetInheritableProperty("MiscUnusedUsingDecls").Value = value; }
+ }
+
+ [Category("Miscellaneous")]
+ [DisplayName("Virtual Near Miss")]
+ [Description("")]
+ [DefaultValue(true)]
+ [ClangTidyCheck("misc-virtual-near-miss")]
+ public bool MiscVirtualNearMiss
+ {
+ get { return GetInheritableProperty("MiscVirtualNearMiss").Value; }
+ set { GetInheritableProperty("MiscVirtualNearMiss").Value = value; }
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.Designer.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.Designer.cs
@@ -0,0 +1,120 @@
+namespace LLVM.ClangTidy
+{
+ partial class ClangTidyPropertyGrid
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.label1 = new System.Windows.Forms.Label();
+ this.textBox1 = new System.Windows.Forms.TextBox();
+ this.button1 = new System.Windows.Forms.Button();
+ this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
+ this.clangTidyProperties1 = new LLVM.ClangTidy.ClangTidyProperties();
+ this.clangTidyConfigurationPage1 = new LLVM.ClangTidy.ClangTidyConfigurationPage();
+ this.linkLabelPath = new System.Windows.Forms.LinkLabel();
+ this.SuspendLayout();
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(14, 17);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(88, 13);
+ this.label1.TabIndex = 0;
+ this.label1.Text = "Configuration File";
+ //
+ // textBox1
+ //
+ this.textBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.textBox1.Location = new System.Drawing.Point(108, 14);
+ this.textBox1.Name = "textBox1";
+ this.textBox1.Size = new System.Drawing.Size(222, 20);
+ this.textBox1.TabIndex = 1;
+ //
+ // button1
+ //
+ this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.button1.Location = new System.Drawing.Point(336, 14);
+ this.button1.Name = "button1";
+ this.button1.Size = new System.Drawing.Size(78, 20);
+ this.button1.TabIndex = 2;
+ this.button1.Text = "Browse";
+ this.button1.UseVisualStyleBackColor = true;
+ this.button1.Click += new System.EventHandler(this.button1_Click);
+ //
+ // propertyGrid1
+ //
+ this.propertyGrid1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
+ | System.Windows.Forms.AnchorStyles.Left)
+ | System.Windows.Forms.AnchorStyles.Right)));
+ this.propertyGrid1.Location = new System.Drawing.Point(20, 73);
+ this.propertyGrid1.Name = "propertyGrid1";
+ this.propertyGrid1.SelectedObject = this.clangTidyProperties1;
+ this.propertyGrid1.Size = new System.Drawing.Size(391, 384);
+ this.propertyGrid1.TabIndex = 6;
+ this.propertyGrid1.ViewBorderColor = System.Drawing.SystemColors.ControlDarkDark;
+ this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
+ //
+ // linkLabelPath
+ //
+ this.linkLabelPath.AutoSize = true;
+ this.linkLabelPath.Location = new System.Drawing.Point(29, 50);
+ this.linkLabelPath.Name = "linkLabelPath";
+ this.linkLabelPath.Size = new System.Drawing.Size(55, 13);
+ this.linkLabelPath.TabIndex = 7;
+ this.linkLabelPath.TabStop = true;
+ this.linkLabelPath.Text = "linkLabel1";
+ this.linkLabelPath.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabelPath_LinkClicked);
+ //
+ // ClangTidyPropertyGrid
+ //
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.linkLabelPath);
+ this.Controls.Add(this.propertyGrid1);
+ this.Controls.Add(this.button1);
+ this.Controls.Add(this.textBox1);
+ this.Controls.Add(this.label1);
+ this.Name = "ClangTidyPropertyGrid";
+ this.Size = new System.Drawing.Size(444, 469);
+ this.Load += new System.EventHandler(this.ClangTidyPropertyGrid_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TextBox textBox1;
+ private System.Windows.Forms.Button button1;
+ private System.Windows.Forms.PropertyGrid propertyGrid1;
+ private ClangTidyProperties clangTidyProperties1;
+ private ClangTidyConfigurationPage clangTidyConfigurationPage1;
+ private System.Windows.Forms.LinkLabel linkLabelPath;
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
@@ -0,0 +1,187 @@
+//===-- 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;
+
+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_;
+
+ ///
+ /// A tree representing all the checks that the extension knows about, used
+ /// when serializing a file to intelligently determine when to use wildcard
+ /// include / exclude rules.
+ ///
+ CheckTree Checks_;
+
+ public ClangTidyPropertyGrid()
+ {
+ InitializeComponent();
+
+ PropertyChain_ = new List>();
+ PropertyChain_.Add(new KeyValuePair(null, ClangTidyProperties.RootProperties));
+ reloadPropertyChain();
+ }
+
+ private void button1_Click(object sender, EventArgs e)
+ {
+ var UnsavedResults = PropertyChain_.Where(x => x.Key != null && x.Value.GetHasUnsavedChanges());
+ if (UnsavedResults.Count() > 0)
+ {
+ var Response = MessageBox.Show(
+ "You have unsaved changes! Do you want to save before loading a new file?",
+ "clang-tidy",
+ MessageBoxButtons.YesNoCancel);
+ if (Response == DialogResult.Cancel)
+ return;
+ if (Response == DialogResult.Yes)
+ {
+ foreach (var Result in UnsavedResults)
+ {
+ PropertyFileParser.SerializeClangTidyFile(Result.Value, Result.Key);
+ Result.Value.SetHasUnsavedChanges(false);
+ }
+ }
+ }
+
+ 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_ = PropertyFileParser.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 ClangTidyPropertyGrid_Load(object sender, EventArgs e)
+ {
+
+ }
+
+ private void linkLabelPath_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
+ {
+ ClangTidyProperties Props = (ClangTidyProperties)e.Link.LinkData;
+ propertyGrid1.SelectedObject = Props;
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.resx
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.resx
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 183, 17
+
+
\ No newline at end of file
Index: clang-tidy-vs/ClangTidy/ForwardingPropertyDescriptor.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/ForwardingPropertyDescriptor.cs
@@ -0,0 +1,191 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// A decorator of sorts. Accepts a PropertyDescriptor to its constructor
+ /// and forwards all calls to the underlying PropertyDescriptor. In this way
+ /// we can inherit from ForwardingPropertyDescriptor and override only the
+ /// few methods we need to customize the behavior of, while allowing the
+ /// underlying PropertyDescriptor to do the real work.
+ ///
+ public abstract class ForwardingPropertyDescriptor : PropertyDescriptor
+ {
+ private readonly PropertyDescriptor root;
+ protected PropertyDescriptor Root { get { return root; } }
+ protected ForwardingPropertyDescriptor(PropertyDescriptor root)
+ : base(root)
+ {
+ this.root = root;
+ }
+
+ public override void AddValueChanged(object component, EventHandler handler)
+ {
+ root.AddValueChanged(component, handler);
+ }
+
+ public override AttributeCollection Attributes
+ {
+ get
+ {
+ return root.Attributes;
+ }
+ }
+
+ public override bool CanResetValue(object component)
+ {
+ return root.CanResetValue(component);
+ }
+
+ public override string Category
+ {
+ get
+ {
+ return root.Category;
+ }
+ }
+
+ public override Type ComponentType
+ {
+ get
+ {
+ return root.ComponentType;
+ }
+ }
+
+ public override TypeConverter Converter
+ {
+ get
+ {
+ return root.Converter;
+ }
+ }
+
+ public override string Description
+ {
+ get
+ {
+ return root.Description;
+ }
+ }
+
+ public override bool DesignTimeOnly
+ {
+ get
+ {
+ return root.DesignTimeOnly;
+ }
+ }
+
+ public override string DisplayName
+ {
+ get
+ {
+ return root.DisplayName;
+ }
+ }
+
+ public override bool Equals(object obj)
+ {
+ return root.Equals(obj);
+ }
+
+ public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter)
+ {
+ return root.GetChildProperties(instance, filter);
+ }
+
+ public override object GetEditor(Type editorBaseType)
+ {
+ return root.GetEditor(editorBaseType);
+ }
+
+ public override int GetHashCode()
+ {
+ return root.GetHashCode();
+ }
+
+ public override object GetValue(object component)
+ {
+ return root.GetValue(component);
+ }
+
+ public override bool IsBrowsable
+ {
+ get
+ {
+ return root.IsBrowsable;
+ }
+ }
+
+ public override bool IsLocalizable
+ {
+ get
+ {
+ return root.IsLocalizable;
+ }
+ }
+
+ public override bool IsReadOnly
+ {
+ get
+ {
+ return root.IsReadOnly;
+ }
+ }
+
+ public override string Name
+ {
+ get
+ {
+ return root.Name;
+ }
+ }
+
+ public override Type PropertyType
+ {
+ get
+ {
+ return root.PropertyType;
+ }
+ }
+
+ public override void RemoveValueChanged(object component, EventHandler handler)
+ {
+ root.RemoveValueChanged(component, handler);
+ }
+
+ public override void ResetValue(object component)
+ {
+ root.ResetValue(component);
+ }
+
+ public override void SetValue(object component, object value)
+ {
+ root.SetValue(component, value);
+ }
+
+ public override bool ShouldSerializeValue(object component)
+ {
+ return root.ShouldSerializeValue(component);
+ }
+
+ public override bool SupportsChangeEvents
+ {
+ get
+ {
+ return root.SupportsChangeEvents;
+ }
+ }
+
+ public override string ToString()
+ {
+ return root.ToString();
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/GlobalSuppressions.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/GlobalSuppressions.cs
@@ -0,0 +1,11 @@
+// This file is used by Code Analysis to maintain SuppressMessage
+// attributes that are applied to this project. Project-level
+// suppressions either have no target or are given a specific target
+// and scoped to a namespace, type, member, etc.
+//
+// To add a suppression to this file, right-click the message in the
+// Error List, point to "Suppress Message(s)", and click "In Project
+// Suppression File". You do not need to add suppressions to this
+// file manually.
+
+[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1017:MarkAssembliesWithComVisible")]
Index: clang-tidy-vs/ClangTidy/Guids.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/Guids.cs
@@ -0,0 +1,12 @@
+using System;
+
+namespace LLVM.ClangTidy
+{
+ static class GuidList
+ {
+ public const string guidClangTidyPkgString = "AE4956BE-3DB8-430E-BBAB-7E2E9A014E9C";
+ public const string guidClangTidyCmdSetString = "9E0F0493-6493-46DE-AEE1-ACD8F60F265E";
+
+ public static readonly Guid guidClangTidyCmdSet = new Guid(guidClangTidyCmdSetString);
+ };
+}
\ No newline at end of file
Index: clang-tidy-vs/ClangTidy/InheritableProperty.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/InheritableProperty.cs
@@ -0,0 +1,127 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// The PropertyDescriptor itself. This is where the actual magic of inheritance happens.
+ /// This class determines what constitutes a "default" value and whether the user has
+ /// overridden the value of this property or if it is inherited.
+ ///
+ ///
+ public class InheritableValuePropertyDescriptor : ForwardingPropertyDescriptor
+ {
+ T Value_;
+ InheritableValuePropertyDescriptor Parent_;
+ bool IsInheriting_;
+
+ ///
+ /// Create a new PropertyDescriptor
+ ///
+ /// The parent from which inherited values will be taken. If null,
+ /// this PropertyDescriptor represents the global set of defaults which cannot be modified.
+ ///
+ /// A PropertyDescriptor representing the original unmodified property.
+ /// We will forward most calls to the underlying PropertyDescriptor, and only override the
+ /// behavior where it is necessary to implement property inheritance.
+ ///
+ public InheritableValuePropertyDescriptor(InheritableValuePropertyDescriptor Parent, PropertyDescriptor Root)
+ : base(Root)
+ {
+ foreach (DefaultValueAttribute Attr in Attributes.OfType())
+ {
+ Value_ = (T)Attr.Value;
+ }
+ Parent_ = Parent;
+ IsInheriting_ = true;
+ }
+
+ public bool IsInheriting { get { return IsInheriting_; } set { IsInheriting_ = value; } }
+ public InheritableValuePropertyDescriptor Parent { get { return Parent_; } }
+ public T Value
+ {
+ get
+ {
+ // Return either this property's value or the parents value, depending on
+ // whether or not this property is inheriting.
+ if (IsInheriting_ && Parent != null)
+ return Parent.Value;
+ return Value_;
+ }
+ set
+ {
+ // By explicitly setting the value, this property is no longer inheriting,
+ // even if the value the property is being set to is the same as that of
+ // the parent.
+ IsInheriting_ = false;
+ Value_ = value;
+ }
+ }
+
+ ///
+ /// Determines whether this property's value should be considered "default" (e.g.
+ /// displayed in bold in the property grid). Root properties are unmodifiable and
+ /// always default. Non-root properties are default iff they are inheriting.
+ /// That is to say, if a property is explicitly set to False, the property should
+ /// be serialized even if the parent is also False. It would only not be serialized
+ /// if the user had explicitly chosen to inherit it.
+ ///
+ ///
+ ///
+ public override bool ShouldSerializeValue(object component)
+ {
+ if (Parent_ == null)
+ return false;
+ return !IsInheriting;
+ }
+
+ ///
+ /// Set the value back to the default. For root properties, this essentially does
+ /// nothing as they are read-only anyway. For non-root properties, this only means
+ /// that the property is now inheriting.
+ ///
+ ///
+ public override void ResetValue(object component)
+ {
+ if (Parent_ == null)
+ Root.ResetValue(component);
+ IsInheriting_ = true;
+ }
+
+ public override void SetValue(object component, object value)
+ {
+ // This is a bit of a trick. If the user chose the inheritance option from the
+ // dropdown, we will try to set the value to that string. So look for that and
+ // then just reset the value.
+ if (value.Equals(MagicInheritance.Text))
+ ResetValue(component);
+ else
+ {
+ Value = (T)value;
+ Root.SetValue(component, value);
+ }
+ }
+
+ public override TypeConverter Converter
+ {
+ get
+ {
+ return new InheritablePropertyConverter(this, Root.Converter);
+ }
+ }
+
+ public override bool IsReadOnly
+ {
+ get
+ {
+ if (Parent_ == null)
+ return true;
+ return base.IsReadOnly;
+ }
+ }
+ }
+}
Index: clang-tidy-vs/ClangTidy/InheritablePropertyComponent.Designer.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/InheritablePropertyComponent.Designer.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ partial class InheritablePropertyComponent
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ }
+
+ #endregion
+ }
+}
Index: clang-tidy-vs/ClangTidy/InheritablePropertyComponent.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/InheritablePropertyComponent.cs
@@ -0,0 +1,188 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ ///
+ /// The goal of this class is to enable displaying of a PropertyGrid in much the
+ /// same way that Visual Studio's C++ project system does. A project or file can
+ /// have properties which might inherit from their parent, or be overridden.
+ /// It turns out this is somewhat non-trivial. The .NET PropertyGrid is good makes
+ /// displaying simple properties with a static notion of what constitutes a
+ /// "default" value very easy. You simply apply an Attribute to the class that says
+ /// what the default value is and you're done. But when you try to introduce the idea
+ /// that a property's default value depends on some other factor, things get much more
+ /// complicated due to the static nature of Attributes.
+ ///
+ /// The solution to this is to inherit from ICustomTypeDescriptor. This is the mechanism
+ /// by which you can inject or modify attributes or properties at runtime. The .NET
+ /// PropertyGrid is designed in such a way that instead of using simple .NET Reflection to
+ /// look for the properties and attributes on a class, it will invoke the methods of
+ /// ICustomTypeDescriptor (if your type inherits from it), and ask those methods. Our
+ /// implementation of ICustomTypeDescriptor works by waiting until the PropertyGrid requests
+ /// PropertyDescriptors for each of the properties, and then "decorating" them with our
+ /// own custom PropertyDescriptor implementation which understands the proeprty inheritance
+ /// model we wish to implement.
+ ///
+ public partial class InheritablePropertyComponent : Component, ICustomTypeDescriptor
+ {
+ private PropertyDescriptorCollection HackedProperties_ = null;
+ protected Dictionary InheritedDescriptors_ = new Dictionary();
+ private InheritablePropertyComponent Parent_;
+
+ public InheritablePropertyComponent(InheritablePropertyComponent Parent)
+ {
+ Parent_ = Parent;
+
+ InitializeHackedProperties();
+ }
+
+ public InheritablePropertyComponent(InheritablePropertyComponent Parent, IContainer container)
+ {
+ Parent_ = Parent;
+
+ container.Add(this);
+ InitializeComponent();
+
+ InitializeHackedProperties();
+ }
+
+ private void InitializeHackedProperties()
+ {
+ PropertyDescriptorCollection ParentProperties = null;
+ if (Parent_ != null)
+ ParentProperties = Parent_.GetProperties();
+
+ PropertyDescriptorCollection Props = TypeDescriptor.GetProperties(GetType());
+ HackedProperties_ = HackProperties(ParentProperties, Props);
+ }
+
+ public AttributeCollection GetAttributes()
+ {
+ return TypeDescriptor.GetAttributes(GetType());
+ }
+
+ public string GetClassName()
+ {
+ return TypeDescriptor.GetClassName(GetType());
+ }
+
+ public string GetComponentName()
+ {
+ return TypeDescriptor.GetComponentName(GetType());
+ }
+
+ public TypeConverter GetConverter()
+ {
+ return TypeDescriptor.GetConverter(GetType());
+ }
+
+ public EventDescriptor GetDefaultEvent()
+ {
+ return TypeDescriptor.GetDefaultEvent(GetType());
+ }
+
+ public PropertyDescriptor GetDefaultProperty()
+ {
+ return TypeDescriptor.GetDefaultProperty(GetType());
+ }
+
+ public object GetEditor(Type editorBaseType)
+ {
+ return TypeDescriptor.GetEditor(GetType(), editorBaseType);
+ }
+
+ public EventDescriptorCollection GetEvents()
+ {
+ return TypeDescriptor.GetEvents(GetType());
+ }
+
+ public EventDescriptorCollection GetEvents(Attribute[] attributes)
+ {
+ return TypeDescriptor.GetEvents(GetType(), attributes);
+ }
+
+ public PropertyDescriptorCollection GetProperties()
+ {
+ return HackedProperties_;
+ }
+
+ public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
+ {
+ List Props = new List();
+ PropertyDescriptorCollection UnhackedResult = TypeDescriptor.GetProperties(GetType(), attributes);
+
+ foreach (PropertyDescriptor Prop in UnhackedResult)
+ Props.Add(HackedProperties_[Prop.Name]);
+ return new PropertyDescriptorCollection(Props.ToArray(), true);
+ }
+
+ public object GetPropertyOwner(PropertyDescriptor pd)
+ {
+ return this;
+ }
+
+ protected InheritableValuePropertyDescriptor GetInheritableProperty(string Name)
+ {
+ return (InheritableValuePropertyDescriptor)(GetInheritableProperty(Name));
+ }
+
+ protected PropertyDescriptor GetInheritableProperty(string Name)
+ {
+ PropertyDescriptor Result = null;
+ if (!InheritedDescriptors_.TryGetValue(Name, out Result))
+ {
+ GetProperties();
+ if (!InheritedDescriptors_.TryGetValue(Name, out Result))
+ return null;
+ }
+ return Result;
+ }
+
+
+ public void SetPropertyValue(string Property, T Value)
+ {
+ GetInheritableProperty(Property).Value = Value;
+ }
+
+
+ private PropertyDescriptorCollection HackProperties(PropertyDescriptorCollection ParentProperties, PropertyDescriptorCollection Properties)
+ {
+ List Props = new List();
+ foreach (PropertyDescriptor Prop in Properties)
+ {
+ PropertyDescriptor Result = null;
+ if (!InheritedDescriptors_.TryGetValue(Prop.Name, out Result))
+ {
+ // The goal here is to invoke
+ // InheritableValuePropertyDescriptor(ParentDescriptor, Prop)
+ // to create the inherited descriptor.
+
+
+ // If we have a parent, find the corresponding PropertyDescriptor with the same
+ // name from the parent.
+ PropertyDescriptor ParentDescriptor = null;
+ if (ParentProperties != null)
+ ParentDescriptor = ParentProperties.Find(Prop.Name, false);
+
+ // Create a Type representing InheritableValuePropertyDescriptor
+ Type DescriptorType = typeof(InheritableValuePropertyDescriptor<>);
+ Type[] TypeArgs = { Prop.PropertyType };
+ Type ParameterizedDescriptorType = DescriptorType.MakeGenericType(TypeArgs);
+
+ // Call the constructor with ParentDescriptor, Prop as the args.
+ object[] ConstructorParams = { ParentDescriptor, Prop };
+ Result = (PropertyDescriptor)Activator.CreateInstance(ParameterizedDescriptorType, ConstructorParams);
+ InheritedDescriptors_.Add(Prop.Name, Result);
+ }
+ Props.Add(Result);
+ }
+ return new PropertyDescriptorCollection(Props.ToArray(), true);
+ }
+
+ }
+}
Index: clang-tidy-vs/ClangTidy/InheritablePropertyConverter.cs
===================================================================
--- /dev/null
+++ clang-tidy-vs/ClangTidy/InheritablePropertyConverter.cs
@@ -0,0 +1,146 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ class MagicInheritance {
+ public static readonly string Value = "{3A27184D-1774-489B-9BB7-7191B8E8E622}";
+ public static readonly string Text = "";
+ }
+
+ ///
+ /// This will be used by the PropertyGrid to convert values (usually booleans) to
+ /// strings and back in order to display them in the PropertyGrid. Inheritable
+ /// properties have an additional quirk though, in that the drop down list should
+ /// display an option to inherit the value from the parent. This means we have to
+ /// inject a value into the drop down that doesn't correspond to a unique value
+ /// of the property.
+ ///
+ /// The underlying type of the property being converted
+ class InheritablePropertyConverter : TypeConverter
+ {
+ private InheritableValuePropertyDescriptor Descriptor_;
+ private TypeConverter Root_;
+
+ public InheritablePropertyConverter(InheritableValuePropertyDescriptor Descriptor, TypeConverter Root)
+ {
+ Descriptor_ = Descriptor;
+ Root_ = Root;
+ }
+
+ ///
+ /// Returns true if there are specific values that can be chosen from a dropdown
+ /// for this property. Regardless of whether standard values are supported for
+ /// the underlying type, we always support standard values because we need to
+ /// display the inheritance option.
+ ///
+ /// true
+ public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
+ {
+ return true;
+ }
+
+ ///
+ /// Get the set of all standard values that can be chosen from a dropdown for this
+ /// property. If the underlying type supports standard values, we want to include
+ /// all those. Additionally, we want to display the option to inherit the value,
+ /// but only if the value is not already inheriting.
+ ///
+ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
+ {
+ List