summaryrefslogtreecommitdiffstats
path: root/clang-tidy-vs
diff options
context:
space:
mode:
authorZachary Turner <zturner@google.com>2016-09-07 18:28:55 +0000
committerZachary Turner <zturner@google.com>2016-09-07 18:28:55 +0000
commit62b2dcfa5923f12e0afd268c0df3864590e912e5 (patch)
treea56824e752b56d45dd6356c784a12002b085edae /clang-tidy-vs
parented5caf38fbaa3d7e7ac53dd46b768fa7905556d8 (diff)
Add a clang-tidy visual studio extension.
For now this only adds the UI necessary to configure clang-tidy settings graphically, and it enables reading in and saving out of .clang-tidy files. It does not actually run clang-tidy on any source files yet. Differential Revision: https://reviews.llvm.org/D23848 git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@280840 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'clang-tidy-vs')
-rw-r--r--clang-tidy-vs/.gitignore7
-rw-r--r--clang-tidy-vs/CMakeLists.txt28
-rw-r--r--clang-tidy-vs/ClangTidy.sln22
-rw-r--r--clang-tidy-vs/ClangTidy/CategoryVerb.cs70
-rw-r--r--clang-tidy-vs/ClangTidy/CheckDatabase.cs67
-rw-r--r--clang-tidy-vs/ClangTidy/CheckTree.cs272
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidy.csproj267
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidy.vsct118
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyCheckAttribute.cs22
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyConfigParser.cs214
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyConfigurationPage.cs61
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyPackage.cs56
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyProperties.cs84
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.Designer.cs119
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs215
-rw-r--r--clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.resx123
-rw-r--r--clang-tidy-vs/ClangTidy/DynamicPropertyComponent.Designer.cs42
-rw-r--r--clang-tidy-vs/ClangTidy/DynamicPropertyComponent.cs138
-rw-r--r--clang-tidy-vs/ClangTidy/DynamicPropertyConverter.cs139
-rw-r--r--clang-tidy-vs/ClangTidy/DynamicPropertyDescriptor.cs137
-rw-r--r--clang-tidy-vs/ClangTidy/ForwardingPropertyDescriptor.cs191
-rw-r--r--clang-tidy-vs/ClangTidy/GlobalSuppressions.cs11
-rw-r--r--clang-tidy-vs/ClangTidy/Guids.cs12
-rw-r--r--clang-tidy-vs/ClangTidy/PkgCmdID.cs7
-rw-r--r--clang-tidy-vs/ClangTidy/Properties/AssemblyInfo.cs33
-rw-r--r--clang-tidy-vs/ClangTidy/Resources.Designer.cs81
-rw-r--r--clang-tidy-vs/ClangTidy/Resources.resx124
-rw-r--r--clang-tidy-vs/ClangTidy/Resources/ClangTidyChecks.yaml325
-rw-r--r--clang-tidy-vs/ClangTidy/Resources/Images_32bit.bmpbin0 -> 5176 bytes
-rw-r--r--clang-tidy-vs/ClangTidy/Resources/Package.icobin0 -> 1078 bytes
-rw-r--r--clang-tidy-vs/ClangTidy/Utility.cs35
-rw-r--r--clang-tidy-vs/ClangTidy/VSPackage.resx130
-rw-r--r--clang-tidy-vs/ClangTidy/license.txt63
-rw-r--r--clang-tidy-vs/ClangTidy/packages.config6
-rw-r--r--clang-tidy-vs/ClangTidy/source.extension.vsixmanifest36
-rw-r--r--clang-tidy-vs/README.txt17
-rw-r--r--clang-tidy-vs/source.extension.vsixmanifest.in36
37 files changed, 3308 insertions, 0 deletions
diff --git a/clang-tidy-vs/.gitignore b/clang-tidy-vs/.gitignore
new file mode 100644
index 00000000..2b0f3e77
--- /dev/null
+++ b/clang-tidy-vs/.gitignore
@@ -0,0 +1,7 @@
+obj/
+bin/
+.vs/
+Key.snk
+clang-tidy.exe
+packages/
+*.csproj.user
diff --git a/clang-tidy-vs/CMakeLists.txt b/clang-tidy-vs/CMakeLists.txt
new file mode 100644
index 00000000..96381bd6
--- /dev/null
+++ b/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()
diff --git a/clang-tidy-vs/ClangTidy.sln b/clang-tidy-vs/ClangTidy.sln
new file mode 100644
index 00000000..345eb830
--- /dev/null
+++ b/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
diff --git a/clang-tidy-vs/ClangTidy/CategoryVerb.cs b/clang-tidy-vs/ClangTidy/CategoryVerb.cs
new file mode 100644
index 00000000..ef07a896
--- /dev/null
+++ b/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
+{
+ /// <summary>
+ /// 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.
+ /// </summary>
+ 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 is 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);
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/CheckDatabase.cs b/clang-tidy-vs/ClangTidy/CheckDatabase.cs
new file mode 100644
index 00000000..3cf8efca
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/CheckDatabase.cs
@@ -0,0 +1,67 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+
+namespace LLVM.ClangTidy
+{
+ public class CheckInfo
+ {
+ [YamlAlias("Name")]
+ public string Name { get; set; }
+
+ [YamlAlias("Label")]
+ public string Label { get; set; }
+
+ [YamlAlias("Description")]
+ public string Desc { get; set; }
+
+ [YamlAlias("Category")]
+ public string Category { get; set; }
+ }
+
+ /// <summary>
+ /// Reads the list of checks from Yaml and builds a description of each one.
+ /// This list of checks is then used by the PropertyGrid to determine what
+ /// items to display.
+ /// </summary>
+ public static class CheckDatabase
+ {
+ static CheckInfo[] Checks_ = null;
+
+ class CheckRoot
+ {
+ [YamlAlias("Checks")]
+ public CheckInfo[] Checks { get; set; }
+ }
+
+ static CheckDatabase()
+ {
+ using (StringReader Reader = new StringReader(Resources.ClangTidyChecks))
+ {
+ Deserializer D = new Deserializer(namingConvention: new PascalCaseNamingConvention());
+ var Root = D.Deserialize<CheckRoot>(Reader);
+ Checks_ = Root.Checks;
+
+ HashSet<string> Names = new HashSet<string>();
+ foreach (var Check in Checks_)
+ {
+ if (Names.Contains(Check.Name))
+ throw new ArgumentException(String.Format("Check {0} exists more than once!", Check.Name));
+ Names.Add(Check.Name);
+ }
+ }
+ }
+
+ public static IEnumerable<CheckInfo> Checks
+ {
+ get
+ {
+ return Checks_;
+ }
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/CheckTree.cs b/clang-tidy-vs/ClangTidy/CheckTree.cs
new file mode 100644
index 00000000..ab746fe3
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/CheckTree.cs
@@ -0,0 +1,272 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Text;
+
+namespace LLVM.ClangTidy
+{
+ /// <summary>
+ /// 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.
+ /// </summary>
+
+ 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<string, CheckTreeNode> Children_ = new Dictionary<string, CheckTreeNode>();
+ public CheckTree()
+ : base(null, null)
+ {
+
+ }
+
+ private CheckTree(string Name, CheckTree Parent)
+ : base(Name, Parent)
+ {
+ }
+
+ private void AddLeaf(string Name, DynamicPropertyDescriptor<bool> 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<PropertyDescriptor>()
+ .OfType<DynamicPropertyDescriptor<bool>>()
+ .Where(x => x.Attributes.OfType<ClangTidyCheckAttribute>().Count() > 0)
+ .Select(x => new KeyValuePair<DynamicPropertyDescriptor<bool>, string>(
+ x, x.Attributes.OfType<ClangTidyCheckAttribute>().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<string, CheckTreeNode> Children
+ {
+ get { return Children_; }
+ }
+ }
+
+ public class CheckLeaf : CheckTreeNode
+ {
+ private DynamicPropertyDescriptor<bool> Property_;
+
+ public CheckLeaf(string Name, CheckTree Parent, DynamicPropertyDescriptor<bool> Property)
+ : base(Name, Parent)
+ {
+ Property_ = Property;
+ }
+
+ public override int CountChecks
+ {
+ get
+ {
+ return 1;
+ }
+ }
+
+ public override int CountExplicitlyDisabledChecks
+ {
+ get
+ {
+ if (Property_.IsInheriting)
+ return 0;
+ return (bool)Property_.GetValue(null) ? 0 : 1;
+ }
+ }
+
+ public override int CountExplicitlyEnabledChecks
+ {
+ get
+ {
+ if (Property_.IsInheriting)
+ return 0;
+ return (bool)Property_.GetValue(null) ? 1 : 0;
+ }
+ }
+
+ public override int CountInheritedChecks
+ {
+ get
+ {
+ return (Property_.IsInheriting) ? 1 : 0;
+ }
+ }
+
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidy.csproj b/clang-tidy-vs/ClangTidy/ClangTidy.csproj
new file mode 100644
index 00000000..32fc2d7f
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidy.csproj
@@ -0,0 +1,267 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{BE261DA1-36C6-449A-95C5-4653A549170A}</ProjectGuid>
+ <ProjectTypeGuids>{82b43b9b-a64c-4715-b499-d71e9ca2bd60};{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>LLVM.ClangTidy</RootNamespace>
+ <AssemblyName>ClangTidy</AssemblyName>
+ <SignAssembly>true</SignAssembly>
+ <AssemblyOriginatorKeyFile>Key.snk</AssemblyOriginatorKeyFile>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+ <FileUpgradeFlags>
+ </FileUpgradeFlags>
+ <UpgradeBackupLocation>
+ </UpgradeBackupLocation>
+ <OldToolsVersion>4.0</OldToolsVersion>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
+ <TargetFrameworkProfile />
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>0</WarningLevel>
+ <Prefer32Bit>false</Prefer32Bit>
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <RunCodeAnalysis>true</RunCodeAnalysis>
+ <Prefer32Bit>false</Prefer32Bit>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="Microsoft.VisualStudio.CoreUtility, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Editor, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.OLE.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Settings.14.0, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=x86" />
+ <Reference Include="Microsoft.VisualStudio.Shell.14.0, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Immutable.10.0, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Immutable.14.0, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="Microsoft.VisualStudio.Shell.Interop" />
+ <Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
+ <Reference Include="Microsoft.VisualStudio.TextManager.Interop" />
+ <Reference Include="Microsoft.VisualStudio.Utilities, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Design" />
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Windows.Forms" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="YamlDotNet, Version=3.3.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\YamlDotNet.3.3.0\lib\net35\YamlDotNet.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ <Reference Include="YamlDotNet.Dynamic, Version=3.2.0.0, Culture=neutral, processorArchitecture=MSIL">
+ <HintPath>..\packages\YamlDotNet.Dynamic.3.2.3\lib\net40\YamlDotNet.Dynamic.dll</HintPath>
+ <Private>True</Private>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <COMReference Include="EnvDTE">
+ <Guid>{80CC9F66-E7D8-4DDD-85B6-D9E6CD0E93E2}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE100">
+ <Guid>{26AD1324-4B7C-44BC-84F8-B86AED45729F}</Guid>
+ <VersionMajor>10</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE80">
+ <Guid>{1A31287A-4D7D-413E-8E32-3B374931BD89}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="EnvDTE90">
+ <Guid>{2CE2370E-D744-4936-A090-3FFFE667B0E1}</Guid>
+ <VersionMajor>9</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="Microsoft.VisualStudio.CommandBars">
+ <Guid>{1CBA492E-7263-47BB-87FE-639000619B15}</Guid>
+ <VersionMajor>8</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ <COMReference Include="stdole">
+ <Guid>{00020430-0000-0000-C000-000000000046}</Guid>
+ <VersionMajor>2</VersionMajor>
+ <VersionMinor>0</VersionMinor>
+ <Lcid>0</Lcid>
+ <WrapperTool>primary</WrapperTool>
+ <Isolated>False</Isolated>
+ <EmbedInteropTypes>False</EmbedInteropTypes>
+ </COMReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="CategoryVerb.cs" />
+ <Compile Include="CheckDatabase.cs" />
+ <Compile Include="CheckTree.cs" />
+ <Compile Include="ClangTidyCheckAttribute.cs" />
+ <Compile Include="ClangTidyConfigurationPage.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="ClangTidyProperties.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="DynamicPropertyConverter.cs" />
+ <Compile Include="DynamicPropertyDescriptor.cs" />
+ <Compile Include="ForwardingPropertyDescriptor.cs" />
+ <Compile Include="Guids.cs" />
+ <Compile Include="DynamicPropertyComponent.cs">
+ <SubType>Component</SubType>
+ </Compile>
+ <Compile Include="DynamicPropertyComponent.Designer.cs" />
+ <Compile Include="ClangTidyConfigParser.cs" />
+ <Compile Include="Resources.Designer.cs">
+ <AutoGen>True</AutoGen>
+ <DesignTime>True</DesignTime>
+ <DependentUpon>Resources.resx</DependentUpon>
+ </Compile>
+ <Compile Include="GlobalSuppressions.cs" />
+ <Compile Include="ClangTidyPackage.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="PkgCmdID.cs" />
+ <Compile Include="ClangTidyPropertyGrid.cs">
+ <SubType>UserControl</SubType>
+ </Compile>
+ <Compile Include="ClangTidyPropertyGrid.Designer.cs">
+ <DependentUpon>ClangTidyPropertyGrid.cs</DependentUpon>
+ </Compile>
+ <Compile Include="Utility.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Resources.resx">
+ <Generator>ResXFileCodeGenerator</Generator>
+ <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+ <SubType>Designer</SubType>
+ </EmbeddedResource>
+ <EmbeddedResource Include="ClangTidyPropertyGrid.resx">
+ <DependentUpon>ClangTidyPropertyGrid.cs</DependentUpon>
+ </EmbeddedResource>
+ <EmbeddedResource Include="VSPackage.resx">
+ <MergeWithCTO>true</MergeWithCTO>
+ <ManifestResourceName>VSPackage</ManifestResourceName>
+ </EmbeddedResource>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Key.snk" />
+ <None Include="packages.config" />
+ <None Include="Resources\ClangTidyChecks.yaml" />
+ <None Include="source.extension.vsixmanifest">
+ <SubType>Designer</SubType>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <VSCTCompile Include="ClangTidy.vsct">
+ <ResourceName>Menus.ctmenu</ResourceName>
+ <SubType>Designer</SubType>
+ </VSCTCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\Images_32bit.bmp" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="clang-tidy.exe">
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ <Content Include="license.txt">
+ <IncludeInVSIX>true</IncludeInVSIX>
+ </Content>
+ <Content Include="Resources\Package.ico" />
+ </ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include=".NETFramework,Version=v4.0">
+ <Visible>False</Visible>
+ <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 4.5</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
+ <PropertyGroup>
+ <UseCodebase>true</UseCodebase>
+ </PropertyGroup>
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(VSToolsPath)\VSSDK\Microsoft.VsSDK.targets" Condition="'$(VSToolsPath)' != ''" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\VSSDK\Microsoft.VsSDK.targets" Condition="false" />
+ <PropertyGroup>
+ <PreBuildEvent>if not exist $(ProjectDir)Key.snk ("$(SDKToolsPath)\sn.exe" -k $(ProjectDir)Key.snk)</PreBuildEvent>
+ </PropertyGroup>
+ <Target Name="BeforeBuild">
+ <Exec ContinueOnError="false" Command="&quot;..\packages\Brutal.Dev.StrongNameSigner.1.8.0\tools\StrongNameSigner.Console.exe&quot; -in &quot;..\packages&quot;" />
+ </Target>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/clang-tidy-vs/ClangTidy/ClangTidy.vsct b/clang-tidy-vs/ClangTidy/ClangTidy.vsct
new file mode 100644
index 00000000..8bdaeec7
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidy.vsct
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="utf-8"?>
+<CommandTable xmlns="http://schemas.microsoft.com/VisualStudio/2005-10-18/CommandTable" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <!-- This is the file that defines the actual layout and type of the commands.
+ It is divided in different sections (e.g. command definition, command
+ placement, ...), with each defining a specific set of properties.
+ See the comment before each section for more details about how to
+ use it. -->
+
+ <!-- The VSCT compiler (the tool that translates this file into the binary
+ format that VisualStudio will consume) has the ability to run a preprocessor
+ on the vsct file; this preprocessor is (usually) the C++ preprocessor, so
+ it is possible to define includes and macros with the same syntax used
+ in C++ files. Using this ability of the compiler here, we include some files
+ defining some of the constants that we will use inside the file. -->
+
+ <!--This is the file that defines the IDs for all the commands exposed by VisualStudio. -->
+ <Extern href="stdidcmd.h"/>
+
+ <!--This header contains the command ids for the menus provided by the shell. -->
+ <Extern href="vsshlids.h"/>
+
+
+
+
+ <!--The Commands section is where we the commands, menus and menu groups are defined.
+ This section uses a Guid to identify the package that provides the command defined inside it. -->
+ <Commands package="guidClangTidyPkg">
+ <!-- Inside this section we have different sub-sections: one for the menus, another
+ for the menu groups, one for the buttons (the actual commands), one for the combos
+ and the last one for the bitmaps used. Each element is identified by a command id that
+ is a unique pair of guid and numeric identifier; the guid part of the identifier is usually
+ called "command set" and is used to group different command inside a logically related
+ group; your package should define its own command set in order to avoid collisions
+ with command ids defined by other packages. -->
+
+
+ <!-- In this section you can define new menu groups. A menu group is a container for
+ other menus or buttons (commands); from a visual point of view you can see the
+ group as the part of a menu contained between two lines. The parent of a group
+ must be a menu. -->
+ <Groups>
+
+ <Group guid="guidClangTidyCmdSet" id="MyMenuGroup" priority="0x0600">
+ <Parent guid="guidSHLMainMenu" id="IDM_VS_MENU_TOOLS"/>
+ </Group>
+
+
+
+ </Groups>
+
+ <!--Buttons section. -->
+ <!--This section defines the elements the user can interact with, like a menu command or a button
+ or combo box in a toolbar. -->
+ <Buttons>
+ <!--To define a menu group you have to specify its ID, the parent menu and its display priority.
+ The command is visible and enabled by default. If you need to change the visibility, status, etc, you can use
+ the CommandFlag node.
+ You can add more than one CommandFlag node e.g.:
+ <CommandFlag>DefaultInvisible</CommandFlag>
+ <CommandFlag>DynamicVisibility</CommandFlag>
+ If you do not want an image next to your command, remove the Icon node /> -->
+
+ <Button guid="guidClangTidyCmdSet" id="cmdidClangTidy" priority="0x0100" type="Button">
+ <Parent guid="guidClangTidyCmdSet" id="MyMenuGroup" />
+ <Icon guid="guidImages" id="bmpPic1" />
+ <Strings>
+ <ButtonText>ClangTidy</ButtonText>
+ </Strings>
+ </Button>
+
+
+
+ </Buttons>
+
+ <!--The bitmaps section is used to define the bitmaps that are used for the commands.-->
+ <Bitmaps>
+ <!-- The bitmap id is defined in a way that is a little bit different from the others:
+ the declaration starts with a guid for the bitmap strip, then there is the resource id of the
+ bitmap strip containing the bitmaps and then there are the numeric ids of the elements used
+ inside a button definition. An important aspect of this declaration is that the element id
+ must be the actual index (1-based) of the bitmap inside the bitmap strip. -->
+ <Bitmap guid="guidImages" href="Resources\Images_32bit.bmp" usedList="bmpPic1, bmpPic2, bmpPicSearch, bmpPicX, bmpPicArrows"/>
+
+ </Bitmaps>
+
+ </Commands>
+
+
+ <KeyBindings>
+ <KeyBinding guid="guidClangTidyCmdSet" id="cmdidClangTidy" editor="guidTextEditor" key1="R" mod1="Control" key2="T" mod2="Control"/>
+ </KeyBindings>
+
+
+
+ <Symbols>
+ <!-- This is the package guid. -->
+ <GuidSymbol name="guidClangTidyPkg" value="{AE4956BE-3DB8-430E-BBAB-7E2E9A014E9C}" />
+
+ <!-- This is the guid used to group the menu commands together -->
+ <GuidSymbol name="guidClangTidyCmdSet" value="{9E0F0493-6493-46DE-AEE1-ACD8F60F265E}">
+ <IDSymbol name="MyMenuGroup" value="0x1020" />
+ <IDSymbol name="cmdidClangTidy" value="0x0100" />
+ </GuidSymbol>
+
+ <GuidSymbol name="guidTextEditor" value="{E10FAD35-7FB8-4991-A269-EF88F12166C9}" />
+
+
+ <GuidSymbol name="guidImages" value="{942F126F-942D-428A-84B4-4AC7C523D0B2}" >
+ <IDSymbol name="bmpPic1" value="1" />
+ <IDSymbol name="bmpPic2" value="2" />
+ <IDSymbol name="bmpPicSearch" value="3" />
+ <IDSymbol name="bmpPicX" value="4" />
+ <IDSymbol name="bmpPicArrows" value="5" />
+ </GuidSymbol>
+ </Symbols>
+
+</CommandTable>
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyCheckAttribute.cs b/clang-tidy-vs/ClangTidy/ClangTidyCheckAttribute.cs
new file mode 100644
index 00000000..59234d74
--- /dev/null
+++ b/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_; }
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyConfigParser.cs b/clang-tidy-vs/ClangTidy/ClangTidyConfigParser.cs
new file mode 100644
index 00000000..db5b055c
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidyConfigParser.cs
@@ -0,0 +1,214 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+
+namespace LLVM.ClangTidy
+{
+ static class ClangTidyConfigParser
+ {
+ public class CheckOption
+ {
+ [YamlAlias("key")]
+ public string Key { get; set; }
+
+ [YamlAlias("value")]
+ public string Value { get; set; }
+ }
+ public class ClangTidyYaml
+ {
+ [YamlAlias("Checks")]
+ public string Checks { get; set; }
+
+ [YamlAlias("CheckOptions")]
+ public List<CheckOption> CheckOptions { get; set; }
+ }
+
+ public static List<KeyValuePair<string, ClangTidyProperties>> ParseConfigurationChain(string ClangTidyFile)
+ {
+ List<KeyValuePair<string, ClangTidyProperties>> Result = new List<KeyValuePair<string, ClangTidyProperties>>();
+ Result.Add(new KeyValuePair<string, ClangTidyProperties>(null, ClangTidyProperties.RootProperties));
+
+ foreach (string P in Utility.SplitPath(ClangTidyFile).Reverse())
+ {
+ if (!Utility.HasClangTidyFile(P))
+ continue;
+
+ string ConfigFile = Path.Combine(P, ".clang-tidy");
+
+ using (StreamReader Reader = new StreamReader(ConfigFile))
+ {
+ Deserializer D = new Deserializer(namingConvention: new PascalCaseNamingConvention());
+ ClangTidyYaml Y = D.Deserialize<ClangTidyYaml>(Reader);
+ ClangTidyProperties Parent = Result[Result.Count - 1].Value;
+ ClangTidyProperties NewProps = new ClangTidyProperties(Parent);
+ SetPropertiesFromYaml(Y, NewProps);
+ Result.Add(new KeyValuePair<string, ClangTidyProperties>(P, NewProps));
+ }
+ }
+ return Result;
+ }
+
+ enum TreeLevelOp
+ {
+ Enable,
+ Disable,
+ Inherit
+ }
+
+ public static void SerializeClangTidyFile(ClangTidyProperties Props, string ClangTidyFilePath)
+ {
+ List<string> CommandList = new List<string>();
+ SerializeCheckTree(CommandList, Props.GetCheckTree(), TreeLevelOp.Inherit);
+
+ CommandList.Sort((x, y) =>
+ {
+ bool LeftSub = x.StartsWith("-");
+ bool RightSub = y.StartsWith("-");
+ if (LeftSub && !RightSub)
+ return -1;
+ if (RightSub && !LeftSub)
+ return 1;
+ return StringComparer.CurrentCulture.Compare(x, y);
+ });
+
+ string ConfigFile = Path.Combine(ClangTidyFilePath, ".clang-tidy");
+ using (StreamWriter Writer = new StreamWriter(ConfigFile))
+ {
+ Serializer S = new Serializer(namingConvention: new PascalCaseNamingConvention());
+ ClangTidyYaml Yaml = new ClangTidyYaml();
+ Yaml.Checks = String.Join(",", CommandList.ToArray());
+ S.Serialize(Writer, Yaml);
+ }
+ }
+
+ /// <summary>
+ /// Convert the given check tree into serialized list of commands that can be written to
+ /// the Yaml. The goal here is to determine the minimal sequence of check commands that
+ /// will produce the exact configuration displayed in the UI. This is complicated by the
+ /// fact that an inherited True is not the same as an explicitly specified True. If the
+ /// user has chosen to inherit a setting in a .clang-tidy file, then changing it in the
+ /// parent should show the reflected changes in the current file as well. So we cannot
+ /// simply -* everything and then add in the checks we need, because -* immediately marks
+ /// every single check as explicitly false, thus disabling inheritance.
+ /// </summary>
+ /// <param name="CommandList">State passed through this recursive algorithm representing
+ /// the sequence of commands we have determined so far.
+ /// </param>
+ /// <param name="Tree">The check tree to serialize. This is the parameter that will be
+ /// recursed on as successive subtrees get serialized to `CommandList`.
+ /// </param>
+ /// <param name="CurrentOp">The current state of the subtree. For example, if the
+ /// algorithm decides to -* an entire subtree and then add back one single check,
+ /// after adding a -subtree-* command to CommandList, it would pass in a value of
+ /// CurrentOp=TreeLevelOp.Disable when it recurses down. This allows deeper iterations
+ /// of the algorithm to know what kind of command (if any) needs to be added to CommandList
+ /// in order to put a particular check into a particular state.
+ /// </param>
+ private static void SerializeCheckTree(List<string> CommandList, CheckTree Tree, TreeLevelOp CurrentOp)
+ {
+ int NumChecks = Tree.CountChecks;
+ int NumDisabled = Tree.CountExplicitlyDisabledChecks;
+ int NumEnabled = Tree.CountExplicitlyEnabledChecks;
+ int NumInherited = Tree.CountInheritedChecks;
+
+ if (NumChecks == 0)
+ return;
+
+ if (NumInherited > 0)
+ System.Diagnostics.Debug.Assert(CurrentOp == TreeLevelOp.Inherit);
+
+ // If this entire tree is inherited, just exit, nothing about this needs to
+ // go in the clang-tidy file.
+ if (NumInherited == NumChecks)
+ return;
+
+ TreeLevelOp NewOp = CurrentOp;
+ // If there are no inherited properties in this subtree, decide whether to
+ // explicitly enable or disable this subtree. Decide by looking at whether
+ // there is a larger proportion of disabled or enabled descendants. If
+ // there are more disabled items in this subtree for example, disabling the
+ // subtree will lead to a smaller configuration file.
+ if (NumInherited == 0)
+ {
+ if (NumDisabled >= NumEnabled)
+ NewOp = TreeLevelOp.Disable;
+ else
+ NewOp = TreeLevelOp.Enable;
+ }
+
+ if (NewOp == TreeLevelOp.Disable)
+ {
+ // Only add an explicit disable command if the tree was not already disabled
+ // to begin with.
+ if (CurrentOp != TreeLevelOp.Disable)
+ {
+ string WildcardPath = "*";
+ if (Tree.Path != null)
+ WildcardPath = Tree.Path + "-" + WildcardPath;
+ CommandList.Add("-" + WildcardPath);
+ }
+ // If the entire subtree was disabled, there's no point descending.
+ if (NumDisabled == NumChecks)
+ return;
+ }
+ else if (NewOp == TreeLevelOp.Enable)
+ {
+ // Only add an explicit enable command if the tree was not already enabled
+ // to begin with. Note that if we're at the root, all checks are already
+ // enabled by default, so there's no need to explicitly include *
+ if (CurrentOp != TreeLevelOp.Enable && Tree.Path != null)
+ {
+ string WildcardPath = Tree.Path + "-*";
+ CommandList.Add(WildcardPath);
+ }
+ // If the entire subtree was enabled, there's no point descending.
+ if (NumEnabled == NumChecks)
+ return;
+ }
+
+ foreach (var Child in Tree.Children)
+ {
+ if (Child.Value is CheckLeaf)
+ {
+ CheckLeaf Leaf = (CheckLeaf)Child.Value;
+ if (Leaf.CountExplicitlyEnabledChecks == 1 && NewOp != TreeLevelOp.Enable)
+ CommandList.Add(Leaf.Path);
+ else if (Leaf.CountExplicitlyDisabledChecks == 1 && NewOp != TreeLevelOp.Disable)
+ CommandList.Add("-" + Leaf.Path);
+ continue;
+ }
+
+ System.Diagnostics.Debug.Assert(Child.Value is CheckTree);
+ CheckTree ChildTree = (CheckTree)Child.Value;
+ SerializeCheckTree(CommandList, ChildTree, NewOp);
+ }
+ }
+
+ private static void SetPropertiesFromYaml(ClangTidyYaml Yaml, ClangTidyProperties Props)
+ {
+ string[] CheckCommands = Yaml.Checks.Split(',');
+ foreach (string Command in CheckCommands)
+ {
+ if (Command == null || Command.Length == 0)
+ continue;
+ bool Add = true;
+ string Pattern = Command;
+ if (Pattern[0] == '-')
+ {
+ Pattern = Pattern.Substring(1);
+ Add = false;
+ }
+
+ foreach (var Match in CheckDatabase.Checks.Where(x => Utility.MatchWildcardString(x.Name, Pattern)))
+ {
+ Props.SetDynamicValue(Match.Name, Add);
+ }
+ }
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyConfigurationPage.cs b/clang-tidy-vs/ClangTidy/ClangTidyConfigurationPage.cs
new file mode 100644
index 00000000..0f7a8e90
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidyConfigurationPage.cs
@@ -0,0 +1,61 @@
+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;
+ }
+ }
+
+ protected override void SaveSetting(PropertyDescriptor property)
+ {
+ base.SaveSetting(property);
+ }
+
+ public override void SaveSettingsToStorage()
+ {
+ if (Grid != null)
+ Grid.SaveSettingsToStorage();
+
+ base.SaveSettingsToStorage();
+ }
+
+ public override void ResetSettings()
+ {
+ base.ResetSettings();
+ }
+
+ protected override void LoadSettingFromStorage(PropertyDescriptor prop)
+ {
+ base.LoadSettingFromStorage(prop);
+ }
+
+ public override void LoadSettingsFromStorage()
+ {
+ if (Grid != null)
+ Grid.InitializeSettings();
+ base.LoadSettingsFromStorage();
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs b/clang-tidy-vs/ClangTidy/ClangTidyPackage.cs
new file mode 100644
index 00000000..9a0c9b67
--- /dev/null
+++ b/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)
+ {
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyProperties.cs b/clang-tidy-vs/ClangTidy/ClangTidyProperties.cs
new file mode 100644
index 00000000..ac831217
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidyProperties.cs
@@ -0,0 +1,84 @@
+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 : DynamicPropertyComponent
+ {
+ 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)
+ {
+ AddClangCheckProperties();
+ CheckTree_ = CheckTree.Build(this);
+ }
+
+ public ClangTidyProperties(DynamicPropertyComponent Parent)
+ : base(Parent)
+ {
+ AddClangCheckProperties();
+ CheckTree_ = CheckTree.Build(this);
+ }
+
+ static ClangTidyProperties()
+ {
+ RootProperties_ = new ClangTidyProperties(null);
+ PropertyDescriptor D;
+ }
+
+ public static ClangTidyProperties RootProperties
+ {
+ get { return RootProperties_; }
+ }
+
+ private void AddClangCheckProperties()
+ {
+ // Add each check in the check database
+ HashSet<string> Categories = new HashSet<string>();
+ foreach (var Check in CheckDatabase.Checks)
+ {
+ string Name = Check.Name.Replace('-', '_');
+ List<Attribute> Attrs = new List<Attribute>();
+ Attrs.Add(new CategoryAttribute(Check.Category));
+ Attrs.Add(new DisplayNameAttribute(Check.Label));
+ Attrs.Add(new DefaultValueAttribute(true));
+ Attrs.Add(new DescriptionAttribute(Check.Desc));
+ Attrs.Add(new ClangTidyCheckAttribute(Check.Name));
+ Categories.Add(Check.Category);
+ AddDynamicProperty<bool>(Check.Name, Attrs.ToArray());
+ }
+
+ // Add a category verb for each unique category.
+ foreach (string Cat in Categories)
+ {
+ List<Attribute> Attrs = new List<Attribute>();
+ Attrs.Add(new CategoryAttribute(Cat));
+ Attrs.Add(new DisplayNameAttribute("(Category Verbs)"));
+ Attrs.Add(new TypeConverterAttribute(typeof(CategoryVerbConverter)));
+ Attrs.Add(new DefaultValueAttribute(CategoryVerb.None));
+ AddDynamicProperty<CategoryVerb>(Cat + "Verb", Attrs.ToArray());
+ }
+ }
+
+ public CheckTree GetCheckTree() { return CheckTree_; }
+ public bool GetHasUnsavedChanges() { return HasUnsavedChanges_; }
+ public void SetHasUnsavedChanges(bool Value) { HasUnsavedChanges_ = Value; }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.Designer.cs b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.Designer.cs
new file mode 100644
index 00000000..ce9324af
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.Designer.cs
@@ -0,0 +1,119 @@
+namespace LLVM.ClangTidy
+{
+ partial class ClangTidyPropertyGrid
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ 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.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;
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
new file mode 100644
index 00000000..c6d93708
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.cs
@@ -0,0 +1,215 @@
+//===-- 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
+{
+ /// <summary>
+ /// 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).
+ /// </summary>
+ public partial class ClangTidyPropertyGrid : UserControl
+ {
+ /// <summary>
+ /// The sequence of .clang-tidy configuration files, starting from the root
+ /// of the filesystem, down to the selected file.
+ /// </summary>
+ List<KeyValuePair<string, ClangTidyProperties>> PropertyChain_ = null;
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ CheckTree Checks_;
+
+ 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<KeyValuePair<string, ClangTidyProperties>>();
+ PropertyChain_.Add(new KeyValuePair<string, ClangTidyProperties>(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";
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ 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<CategoryAttribute>().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/ClangTidyPropertyGrid.resx b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.resx
new file mode 100644
index 00000000..22dfde01
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/ClangTidyPropertyGrid.resx
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <metadata name="clangTidyConfigurationPage1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+ <value>183, 17</value>
+ </metadata>
+</root> \ No newline at end of file
diff --git a/clang-tidy-vs/ClangTidy/DynamicPropertyComponent.Designer.cs b/clang-tidy-vs/ClangTidy/DynamicPropertyComponent.Designer.cs
new file mode 100644
index 00000000..099f1c0a
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/DynamicPropertyComponent.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 DynamicPropertyComponent
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ }
+
+ #endregion
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/DynamicPropertyComponent.cs b/clang-tidy-vs/ClangTidy/DynamicPropertyComponent.cs
new file mode 100644
index 00000000..e8843db4
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/DynamicPropertyComponent.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ /// <summary>
+ /// 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.
+ /// </summary>
+ public partial class DynamicPropertyComponent : Component, ICustomTypeDescriptor
+ {
+ PropertyDescriptorCollection DynamicProperties_ = new PropertyDescriptorCollection(null);
+ private DynamicPropertyComponent Parent_;
+
+ public DynamicPropertyComponent(DynamicPropertyComponent Parent)
+ {
+ Parent_ = Parent;
+ }
+
+ public DynamicPropertyComponent(DynamicPropertyComponent Parent, IContainer container)
+ {
+ Parent_ = Parent;
+
+ container.Add(this);
+ InitializeComponent();
+ }
+
+ 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 DynamicProperties_;
+ }
+
+ public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
+ {
+ var Props = DynamicProperties_.OfType<PropertyDescriptor>();
+ var Filtered = Props.Where(x => x.Attributes.Contains(attributes)).ToArray();
+ return new PropertyDescriptorCollection(Filtered);
+ }
+
+ public object GetPropertyOwner(PropertyDescriptor pd)
+ {
+ return this;
+ }
+
+ public void SetDynamicValue<T>(string Name, T Value)
+ {
+ Name = Name.Replace('-', '_');
+ DynamicPropertyDescriptor<T> Descriptor = (DynamicPropertyDescriptor<T>)DynamicProperties_.Find(Name, false);
+ Descriptor.SetValue(this, Value);
+ }
+
+ public T GetDynamicValue<T>(string Name)
+ {
+ Name = Name.Replace('-', '_');
+ DynamicPropertyDescriptor<T> Descriptor = (DynamicPropertyDescriptor<T>)DynamicProperties_.Find(Name, false);
+ return (T)Descriptor.GetValue(this);
+ }
+
+ protected void AddDynamicProperty<T>(string Name, Attribute[] Attributes)
+ {
+ Name = Name.Replace('-', '_');
+
+ // If we have a parent, find the corresponding PropertyDescriptor with the same
+ // name from the parent.
+ DynamicPropertyDescriptor<T> ParentDescriptor = null;
+ if (Parent_ != null)
+ ParentDescriptor = (DynamicPropertyDescriptor<T>)Parent_.GetProperties().Find(Name, false);
+
+ DynamicProperties_.Add(new DynamicPropertyDescriptor<T>(Name, ParentDescriptor, Name, Attributes));
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/DynamicPropertyConverter.cs b/clang-tidy-vs/ClangTidy/DynamicPropertyConverter.cs
new file mode 100644
index 00000000..9442667d
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/DynamicPropertyConverter.cs
@@ -0,0 +1,139 @@
+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 = "<Inherit from project or parent>";
+ }
+
+
+ class DynamicPropertyConverter<T> : TypeConverter
+ {
+ private DynamicPropertyDescriptor<T> Descriptor_;
+ private TypeConverter Root_;
+
+ public DynamicPropertyConverter(DynamicPropertyDescriptor<T> Descriptor, TypeConverter Root)
+ {
+ Descriptor_ = Descriptor;
+ Root_ = Root;
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <returns>true</returns>
+ public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
+ {
+ return true;
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
+ {
+ List<object> Values = new List<object>();
+ if (Root_.GetStandardValuesSupported(context))
+ {
+ StandardValuesCollection RootValues = Root_.GetStandardValues(context);
+ Values.AddRange(RootValues.Cast<object>());
+ }
+ if (!Descriptor_.IsInheriting)
+ Values.Add(MagicInheritance.Value);
+ StandardValuesCollection Result = new StandardValuesCollection(Values);
+ return Result;
+ }
+
+ /// <summary>
+ /// Determines whether this property can accept values other than those specified
+ /// in the dropdown (for example by manually typing into the field).
+ /// </summary>
+ public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
+ {
+ // Although we add items to the dropdown list, we do not change whether or not
+ // the set of values are exclusive. If the user could type into the field before
+ // they still can. And if they couldn't before, they still can't.
+ return Root_.GetStandardValuesExclusive(context);
+ }
+
+ public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
+ {
+ return Root_.CanConvertFrom(context, sourceType);
+ }
+
+ public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
+ {
+ return Root_.CanConvertTo(context, destinationType);
+ }
+
+ public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
+ {
+ if (value.Equals(MagicInheritance.Value))
+ return MagicInheritance.Text;
+ return Root_.ConvertFrom(context, culture, value);
+ }
+
+ public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
+ {
+ if (value.GetType() == destinationType)
+ return value;
+
+ return Root_.ConvertTo(context, culture, value, destinationType);
+ }
+
+ public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
+ {
+ return Root_.CreateInstance(context, propertyValues);
+ }
+
+ public override bool Equals(object obj)
+ {
+ return Root_.Equals(obj);
+ }
+
+ public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
+ {
+ return Root_.GetCreateInstanceSupported(context);
+ }
+
+ public override int GetHashCode()
+ {
+ return Root_.GetHashCode();
+ }
+
+ public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
+ {
+ return Root_.GetProperties(context, value, attributes);
+ }
+
+ public override bool GetPropertiesSupported(ITypeDescriptorContext context)
+ {
+ return Root_.GetPropertiesSupported(context);
+ }
+
+ public override bool IsValid(ITypeDescriptorContext context, object value)
+ {
+ return Root_.IsValid(context, value);
+ }
+
+ public override string ToString()
+ {
+ return Root_.ToString();
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/DynamicPropertyDescriptor.cs b/clang-tidy-vs/ClangTidy/DynamicPropertyDescriptor.cs
new file mode 100644
index 00000000..f0d76914
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/DynamicPropertyDescriptor.cs
@@ -0,0 +1,137 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ public class DynamicPropertyDescriptor<T> : PropertyDescriptor
+ {
+ T Value_;
+ DynamicPropertyDescriptor<T> Parent_;
+ bool IsInheriting_;
+ object Component_;
+
+ public DynamicPropertyDescriptor(object Component, DynamicPropertyDescriptor<T> Parent, string Name, Attribute[] Attrs)
+ : base(Name, Attrs)
+ {
+ foreach (DefaultValueAttribute Attr in Attrs.OfType<DefaultValueAttribute>())
+ {
+ Value_ = (T)Attr.Value;
+ }
+ Parent_ = Parent;
+ IsInheriting_ = true;
+ Component_ = Component;
+ }
+
+ public bool IsInheriting { get { return IsInheriting_; } set { IsInheriting_ = value; } }
+ public DynamicPropertyDescriptor<T> Parent { get { return Parent_; } }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="component"></param>
+ /// <returns></returns>
+ public override bool ShouldSerializeValue(object component)
+ {
+ return (Parent_ != null) && !IsInheriting;
+ }
+
+ /// <summary>
+ /// 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.
+ /// </summary>
+ /// <param name="component"></param>
+ public override void ResetValue(object 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
+ {
+ // 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_ = (T)value;
+ }
+ }
+
+ public override TypeConverter Converter
+ {
+ get
+ {
+ // We need to return a DynamicPropertyConverter<> that can deal with our requirement
+ // to inject the inherit property option into the dropdown. But we still need to use
+ // the "real" converter to do the actual work for the underlying type. Therefore,
+ // we need to look for a TypeConverter<> attribute on the property, and if it is present
+ // forward an instance of that converter to the DynamicPropertyConverter<>. Otherwise,
+ // forward an instance of the default converter for type T to the DynamicPropertyConverter<>.
+ TypeConverter UnderlyingConverter = null;
+ var ConverterAttr = this.Attributes.OfType<TypeConverterAttribute>().LastOrDefault();
+ if (ConverterAttr != null)
+ {
+ Type ConverterType = Type.GetType(ConverterAttr.ConverterTypeName);
+ UnderlyingConverter = (TypeConverter)Activator.CreateInstance(ConverterType);
+ }
+ else
+ UnderlyingConverter = TypeDescriptor.GetConverter(typeof(T));
+
+ return new DynamicPropertyConverter<T>(this, UnderlyingConverter);
+ }
+ }
+
+ public override bool IsReadOnly
+ {
+ get
+ {
+ return (Parent_ == null);
+ }
+ }
+
+ public override Type ComponentType
+ {
+ get
+ {
+ return Component_.GetType();
+ }
+ }
+
+ public override object GetValue(object component)
+ {
+ // 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.GetValue(component);
+ return Value_;
+ }
+
+ public override bool CanResetValue(object component)
+ {
+ return !IsReadOnly;
+ }
+
+ public override Type PropertyType
+ {
+ get
+ {
+ return typeof(T);
+ }
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/ForwardingPropertyDescriptor.cs b/clang-tidy-vs/ClangTidy/ForwardingPropertyDescriptor.cs
new file mode 100644
index 00000000..22b08fbb
--- /dev/null
+++ b/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
+{
+ /// <summary>
+ /// 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.
+ /// </summary>
+ 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();
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/GlobalSuppressions.cs b/clang-tidy-vs/ClangTidy/GlobalSuppressions.cs
new file mode 100644
index 00000000..175a74e2
--- /dev/null
+++ b/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")]
diff --git a/clang-tidy-vs/ClangTidy/Guids.cs b/clang-tidy-vs/ClangTidy/Guids.cs
new file mode 100644
index 00000000..0c99a6f9
--- /dev/null
+++ b/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);
+ };
+}
diff --git a/clang-tidy-vs/ClangTidy/PkgCmdID.cs b/clang-tidy-vs/ClangTidy/PkgCmdID.cs
new file mode 100644
index 00000000..3faf403a
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/PkgCmdID.cs
@@ -0,0 +1,7 @@
+namespace LLVM.ClangTidy
+{
+ static class PkgCmdIDList
+ {
+ public const uint cmdidClangTidy = 0x100;
+ };
+} \ No newline at end of file
diff --git a/clang-tidy-vs/ClangTidy/Properties/AssemblyInfo.cs b/clang-tidy-vs/ClangTidy/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..71053050
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ClangFormat")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("LLVM")]
+[assembly: AssemblyProduct("ClangFormat")]
+[assembly: AssemblyCopyright("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+[assembly: ComVisible(false)]
+[assembly: CLSCompliant(false)]
+[assembly: NeutralResourcesLanguage("en-US")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+// FIXME: Add a way to have this generated automatically by CMake
+[assembly: AssemblyVersion("1.1.0.0")]
+[assembly: AssemblyFileVersion("1.1.0.0")]
diff --git a/clang-tidy-vs/ClangTidy/Resources.Designer.cs b/clang-tidy-vs/ClangTidy/Resources.Designer.cs
new file mode 100644
index 00000000..b601fb37
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Resources.Designer.cs
@@ -0,0 +1,81 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace LLVM.ClangTidy {
+ using System;
+
+
+ /// <summary>
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ /// </summary>
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ /// <summary>
+ /// Returns the cached ResourceManager instance used by this class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("LLVM.ClangTidy.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ /// <summary>
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ /// </summary>
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ /// <summary>
+ /// Looks up a localized string similar to ---
+ ///Checks:
+ ///Checks:
+ /// - Name: cert-dcl54-cpp
+ /// Label: Overloaded allocation function pairs
+ /// Description: Checks for violations of CERT DCL54-CPP - Overload allocation and deallocation functions as a pair in the same scope
+ /// Category: CERT Secure Coding Standards
+ /// - Name: cppcoreguidelines-interfaces-global-init
+ /// Label: I.22 - Complex Global Initializers
+ /// Description: Checks for violations of Core Guideline I.22 - Avoid complex initializers of global object [rest of string was truncated]&quot;;.
+ /// </summary>
+ internal static string ClangTidyChecks {
+ get {
+ return ResourceManager.GetString("ClangTidyChecks", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/Resources.resx b/clang-tidy-vs/ClangTidy/Resources.resx
new file mode 100644
index 00000000..7f634752
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Resources.resx
@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="ClangTidyChecks" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>Resources\ClangTidyChecks.yaml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/clang-tidy-vs/ClangTidy/Resources/ClangTidyChecks.yaml b/clang-tidy-vs/ClangTidy/Resources/ClangTidyChecks.yaml
new file mode 100644
index 00000000..fc16d234
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Resources/ClangTidyChecks.yaml
@@ -0,0 +1,325 @@
+---
+Checks:
+ # This file should be updated when new checks are added, and eventually we should
+ # generate this file automatically from the .rst files in clang-tidy.
+ - Category: CERT Secure Coding Standards
+ Label: Overloaded allocation function pairs
+ Description: Checks for violations of CERT DCL54-CPP - Overload allocation and deallocation functions as a pair in the same scope
+ Name: cert-dcl54-cpp
+ - Category: C++ Core Guidelines
+ Label: I.22 - Complex Global Initializers
+ Description: Checks for violations of Core Guideline I.22 - Avoid complex initializers of global objects
+ Name: cppcoreguidelines-interfaces-global-init
+ - Category: CERT Secure Coding Standards
+ Label: DCL50-CPP
+ Description: Checks for violations of CERT DCL50-CPP - Do not define a C-style variadic function
+ Name: cert-dcl50-cpp
+ - Category: C++ Core Guidelines
+ Label: Bounds.1 - No pointer arithmetic
+ Description: Checks for violations of Core Guideline Bounds.3 - Don't use pointer arithmetic. Use span<> instead.
+ Name: cppcoreguidelines-pro-bounds-pointer-arithmetic
+ - Category: C++ Core Guidelines
+ Label: Bounds.2 - Constant array indices
+ Description: Checks for violations of Core Bounds.2 - Only index into arrays using constant expressions.
+ Name: cppcoreguidelines-pro-bounds-constant-array-index
+ - Category: C++ Core Guidelines
+ Label: Bounds.3 - Array to Pointer Decay
+ Description: Checks for violations of Core Guideline Bounds.3 - No array-to-pointer decay
+ Name: cppcoreguidelines-pro-bounds-array-to-pointer-decay
+ - Category: C++ Core Guidelines
+ Label: const_cast (Type.3)
+ Description: Checks for violations of Core Guideline Type.3 - Don't use const_cast to cast away const
+ Name: cppcoreguidelines-pro-type-const-cast
+ - Category: C++ Core Guidelines
+ Label: 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
+ Name: cppcoreguidelines-pro-type-cstyle-cast
+ - Category: C++ Core Guidelines
+ Label: reinterpret_cast (Type.1)
+ Description: Checks for violations of Core Guideline Type.1 - Don't use reinterpret_cast.
+ Name: cppcoreguidelines-pro-type-reinterpret-cast
+ - Category: C++ Core Guidelines
+ Label: Prefer dynamic_cast (Type.2)
+ Description: Checks for violations of Core Guideline Type.2 - Don't use static_cast downcasts. Use dynamic_cast instead.
+ Name: cppcoreguidelines-pro-type-static-cast-downcast
+ - Category: C++ Core Guidelines
+ Label: Member variable initialization (Type.6)
+ Description: Checks for violations of Core Guideline Type.6 - Always initialize a member variable.
+ Name: cppcoreguidelines-pro-type-member-init
+ - Category: C++ Core Guidelines
+ Label: Avoid unions (Type.7)
+ Description: Checks for violations of Core Guideline Type.7 - Avoid accessing members of raw unions. Use variant instead.
+ Name: cppcoreguidelines-pro-type-union-access
+ - Category: C++ Core Guidelines
+ Label: 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.
+ Name: cppcoreguidelines-pro-type-vararg
+ - Category: C++ Core Guidelines
+ Label: 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)
+ Name: cppcoreguidelines-slicing
+ - Category: C++ Core Guidelines
+ Label: 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.
+ Name: cppcoreguidelines-special-member-functions
+ - Category: Google Style Guide
+ Label: Forbid explicitly parameterized make_pair
+ Description:
+ Name: google-build-explicit-make-pair
+ - Category: Google Style Guide
+ Label: Anonymous namespace in headers
+ Description:
+ Name: google-build-namespaces
+ - Category: Google Style Guide
+ Label: Find using namespace directives
+ Description:
+ Name: google-build-using-namespace
+ - Category: Google Style Guide
+ Label: Default arguments in virtual methods
+ Description:
+ Name: google-default-arguments
+ - Category: Google Style Guide
+ Label: explicit constructors
+ Description:
+ Name: google-explicit-constructor
+ - Category: Google Style Guide
+ Label: Global namespace pollution in headers
+ Description:
+ Name: google-global-names-in-headers
+ - Category: Google Style Guide
+ Label: Braces around statements
+ Description:
+ Name: google-readability-braces-around-statements
+ - Category: Google Style Guide
+ Label: No C-style casts
+ Description:
+ Name: google-readability-casting
+ - Category: Google Style Guide
+ Label: Find large functions
+ Description:
+ Name: google-readability-function-size
+ - Category: Google Style Guide
+ Label: Namespace closing comments
+ Description:
+ Name: google-readability-namespace-comments
+ - Category: Google Style Guide
+ Label: Find unnecessary calls to .get()
+ Description:
+ Name: google-readability-redundant-smartptr-get
+ - Category: Google Style Guide
+ Label: Find noncomformant TODO comments
+ Description:
+ Name: google-readability-todo
+ - Category: Google Style Guide
+ Label: Find implementation-specific integral types
+ Description:
+ Name: google-runtime-int
+ - Category: Google Style Guide
+ Label: Find const string references
+ Description:
+ Name: google-runtime-member-string-references
+ - Category: Google Style Guide
+ Label: Find zero-length memsets
+ Description:
+ Name: google-runtime-memset
+ - Category: Google Style Guide
+ Label: Find overloads of operator&
+ Description:
+ Name: google-runtime-operator
+ - Category: Google Style Guide
+ Label: Check usage of non-const references
+ Description:
+ Name: google-runtime-references
+ - Category: LLVM Style Guide
+ Label: LLVM header guards
+ Description:
+ Name: llvm-header-guard
+ - Category: LLVM Style Guide
+ Label: LLVM include order
+ Description:
+ Name: llvm-include-order
+ - Category: LLVM Style Guide
+ Label: LLVM namespace comments
+ Description:
+ Name: llvm-namespace-comment
+ - Category: LLVM Style Guide
+ Label: Find local twines
+ Description:
+ Name: llvm-twine-local
+ - Category: Clang Diagnostics
+ Label: Warnings
+ Description:
+ Name: clang-diagnostic-warning
+ - Category: Clang Diagnostics
+ Label: Errors
+ Description:
+ Name: clang-diagnostic-error
+ - Category: Clang Diagnostics
+ Label: Unknown
+ Description:
+ Name: clang-diagnostic-unknown
+ - Category: Miscellaneous
+ Label: Validate argument comments
+ Description:
+ Name: misc-argument-comment
+ - Category: Miscellaneous
+ Label: Side effects in assert()
+ Description:
+ Name: misc-assert-side-effect
+ - Category: Miscellaneous
+ Label: bool / pointer implicit conversions
+ Description:
+ Name: misc-bool-pointer-implicit-conversion
+ - Category: Miscellaneous
+ Label: Dangling handles
+ Description:
+ Name: misc-dangling-handle
+ - Category: Miscellaneous
+ Label: Definitions in headers
+ Description:
+ Name: misc-definitions-in-headers
+ - Category: Miscellaneous
+ Label: Type mismatch in fold operations
+ Description:
+ Name: misc-fold-init-type
+ - Category: Miscellaneous
+ Label: Forward declaration namespace
+ Description:
+ Name: misc-forward-declaration-namespace
+ - Category: Miscellaneous
+ Label: Inaccurate erase
+ Description:
+ Name: misc-inaccurate-erase
+ - Category: Miscellaneous
+ Label: Incorrect rounding
+ Description:
+ Name: misc-incorrect-roundings
+ - Category: Miscellaneous
+ Label: Inefficient STL algorithms
+ Description:
+ Name: misc-inefficient-algorithm
+ - Category: Miscellaneous
+ Label: Macro parentheses
+ Description:
+ Name: misc-macro-parentheses
+ - Category: Miscellaneous
+ Label: Macro repeated side effects
+ Description:
+ Name: misc-macro-repeated-side-effects
+ - Category: Miscellaneous
+ Label: Misplaced const
+ Description:
+ Name: misc-misplaced-const
+ - Category: Miscellaneous
+ Label: Misplaced widening casts
+ Description:
+ Name: misc-misplaced-widening-cast
+ - Category: Miscellaneous
+ Label: Move constructor const arguments
+ Description:
+ Name: misc-move-const-arg
+ - Category: Miscellaneous
+ Label: Move constructor initialization
+ Description:
+ Name: misc-move-constructor-init
+ - Category: Miscellaneous
+ Label: Multi-statement macros
+ Description:
+ Name: misc-multiple-statement-macro
+ - Category: Miscellaneous
+ Label: Verify new / delete overloads
+ Description:
+ Name: misc-new-delete-overloads
+ - Category: Miscellaneous
+ Label: Ensure move constructors are noexcept
+ Description:
+ Name: misc-noexcept-move-constructor
+ - Category: Miscellaneous
+ Label: Copying of non-copyable objects
+ Description:
+ Name: misc-non-copyable-objects
+ - Category: Miscellaneous
+ Label: Suspicious pointer / integer operations
+ Description:
+ Name: misc-pointer-and-integral-operation
+ - Category: Miscellaneous
+ Label: Find redundant expressions
+ Description:
+ Name: misc-redundant-expression
+ - Category: Miscellaneous
+ Label: sizeof() on stl containers
+ Description:
+ Name: misc-sizeof-container
+ - Category: Miscellaneous
+ Label: Suspicious sizeof() usage
+ Description:
+ Name: misc-sizeof-expression
+ - Category: Miscellaneous
+ Label: Replace assert with static_assert
+ Description:
+ Name: misc-static-assert
+ - Category: Miscellaneous
+ Label: Suspicious string constructor
+ Description:
+ Name: misc-string-constructor
+ - Category: Miscellaneous
+ Label: String integer assignment
+ Description:
+ Name: misc-string-integer-assignment
+ - Category: Miscellaneous
+ Label: String literal with embedded null
+ Description:
+ Name: misc-string-literal-with-embedded-nul
+ - Category: Miscellaneous
+ Label: Suspicious missing comma
+ Description:
+ Name: misc-suspicious-missing-comma
+ - Category: Miscellaneous
+ Label: Suspicious semicolon
+ Description:
+ Name: misc-suspicious-semicolon
+ - Category: Miscellaneous
+ Label: Suspicious string compare
+ Description:
+ Name: misc-suspicious-string-compare
+ - Category: Miscellaneous
+ Label: Swapped arguments
+ Description:
+ Name: misc-swapped-arguments
+ - Category: Miscellaneous
+ Label: Throw by value / catch by reference
+ Description:
+ Name: misc-throw-by-value-catch-by-reference
+ - Category: Miscellaneous
+ Label: Unconventional operator=()
+ Description:
+ Name: misc-unconventional-assign-operator
+ - Category: Miscellaneous
+ Label: Undelegated constructor
+ Description:
+ Name: misc-undelegated-constructor
+ - Category: Miscellaneous
+ Label: unique_ptr<> reset / release
+ Description:
+ Name: misc-uniqueptr-reset-release
+ - Category: Miscellaneous
+ Label: Unused Alias Decls
+ Description:
+ Name: misc-unused-alias-decls
+ - Category: Miscellaneous
+ Label: Unused Params
+ Description:
+ Name: misc-unused-parameters
+ - Category: Miscellaneous
+ Label: Unused Raii
+ Description:
+ Name: misc-unused-raii
+ - Category: Miscellaneous
+ Label: Unused Using Decls
+ Description:
+ Name: misc-unused-using-decls
+ - Category: Miscellaneous
+ Label: Virtual Near Miss
+ Description:
+ Name: misc-virtual-near-miss
+...
diff --git a/clang-tidy-vs/ClangTidy/Resources/Images_32bit.bmp b/clang-tidy-vs/ClangTidy/Resources/Images_32bit.bmp
new file mode 100644
index 00000000..2fa7ab00
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Resources/Images_32bit.bmp
Binary files differ
diff --git a/clang-tidy-vs/ClangTidy/Resources/Package.ico b/clang-tidy-vs/ClangTidy/Resources/Package.ico
new file mode 100644
index 00000000..ea3b23fe
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Resources/Package.ico
Binary files differ
diff --git a/clang-tidy-vs/ClangTidy/Utility.cs b/clang-tidy-vs/ClangTidy/Utility.cs
new file mode 100644
index 00000000..5a220e6b
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/Utility.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace LLVM.ClangTidy
+{
+ static class Utility
+ {
+ public static IEnumerable<string> SplitPath(string FileOrDir)
+ {
+ string P = Path.GetDirectoryName(FileOrDir);
+ do
+ {
+ yield return P;
+ P = Path.GetDirectoryName(P);
+ } while (P != null);
+ }
+
+ public static bool HasClangTidyFile(string Folder)
+ {
+ string ClangTidy = Path.Combine(Folder, ".clang-tidy");
+ return File.Exists(ClangTidy);
+ }
+
+ public static bool MatchWildcardString(string Value, string Pattern)
+ {
+ string RE = Regex.Escape(Pattern).Replace(@"\*", ".*");
+ return Regex.IsMatch(Value, RE);
+ }
+ }
+}
diff --git a/clang-tidy-vs/ClangTidy/VSPackage.resx b/clang-tidy-vs/ClangTidy/VSPackage.resx
new file mode 100644
index 00000000..932b0620
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/VSPackage.resx
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+ <!--
+ Microsoft ResX Schema
+
+ Version 2.0
+
+ The primary goals of this format is to allow a simple XML format
+ that is mostly human readable. The generation and parsing of the
+ various data types are done through the TypeConverter classes
+ associated with the data types.
+
+ Example:
+
+ ... ado.net/XML headers & schema ...
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
+ <resheader name="version">2.0</resheader>
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
+ </data>
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+ <comment>This is a comment</comment>
+ </data>
+
+ There are any number of "resheader" rows that contain simple
+ name/value pairs.
+
+ Each data row contains a name, and value. The row also contains a
+ type or mimetype. Type corresponds to a .NET class that support
+ text/value conversion through the TypeConverter architecture.
+ Classes that don't support this are serialized and stored with the
+ mimetype set.
+
+ The mimetype is used for serialized objects, and tells the
+ ResXResourceReader how to depersist the object. This is currently not
+ extensible. For a given mimetype the value must be set accordingly:
+
+ Note - application/x-microsoft.net.object.binary.base64 is the format
+ that the ResXResourceWriter will generate, however the reader can
+ read any of the formats listed below.
+
+ mimetype: application/x-microsoft.net.object.binary.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.soap.base64
+ value : The object must be serialized with
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+ : and then encoded with base64 encoding.
+
+ mimetype: application/x-microsoft.net.object.bytearray.base64
+ value : The object must be serialized into a byte array
+ : using a System.ComponentModel.TypeConverter
+ : and then encoded with base64 encoding.
+ -->
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+ <xsd:element name="root" msdata:IsDataSet="true">
+ <xsd:complexType>
+ <xsd:choice maxOccurs="unbounded">
+ <xsd:element name="metadata">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
+ </xsd:sequence>
+ <xsd:attribute name="name" use="required" type="xsd:string" />
+ <xsd:attribute name="type" type="xsd:string" />
+ <xsd:attribute name="mimetype" type="xsd:string" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="assembly">
+ <xsd:complexType>
+ <xsd:attribute name="alias" type="xsd:string" />
+ <xsd:attribute name="name" type="xsd:string" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="data">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+ <xsd:attribute ref="xml:space" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="resheader">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+ </xsd:sequence>
+ <xsd:attribute name="name" type="xsd:string" use="required" />
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:schema>
+ <resheader name="resmimetype">
+ <value>text/microsoft-resx</value>
+ </resheader>
+ <resheader name="version">
+ <value>2.0</value>
+ </resheader>
+ <resheader name="reader">
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <resheader name="writer">
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+ </resheader>
+ <data name="110" xml:space="preserve">
+ <value>ClangTidy</value>
+ </data>
+ <data name="112" xml:space="preserve">
+ <value>Analyzes code by calling the clang-tidy executable.</value>
+ </data>
+ <assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <data name="400" type="System.Resources.ResXFileRef, System.Windows.Forms">
+ <value>Resources\Package.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
+ </data>
+</root> \ No newline at end of file
diff --git a/clang-tidy-vs/ClangTidy/license.txt b/clang-tidy-vs/ClangTidy/license.txt
new file mode 100644
index 00000000..b452ca2e
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/license.txt
@@ -0,0 +1,63 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2007-2016 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+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
+------- ---------
+<none yet>
+
diff --git a/clang-tidy-vs/ClangTidy/packages.config b/clang-tidy-vs/ClangTidy/packages.config
new file mode 100644
index 00000000..75d7fafc
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/packages.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Brutal.Dev.StrongNameSigner" version="1.8.0" targetFramework="net45" />
+ <package id="YamlDotNet" version="3.3.0" targetFramework="net45" />
+ <package id="YamlDotNet.Dynamic" version="3.2.3" targetFramework="net45" />
+</packages> \ No newline at end of file
diff --git a/clang-tidy-vs/ClangTidy/source.extension.vsixmanifest b/clang-tidy-vs/ClangTidy/source.extension.vsixmanifest
new file mode 100644
index 00000000..cd0e8633
--- /dev/null
+++ b/clang-tidy-vs/ClangTidy/source.extension.vsixmanifest
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Vsix Version="1.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
+ <Identifier Id="405594C3-042A-4155-B9A6-E25DAB8B1924">
+ <Name>ClangFormat</Name>
+ <Author>LLVM</Author>
+ <Version>4.0.0</Version>
+ <Description xml:space="preserve">A static analysis tool for C/C++ code.</Description>
+ <Locale>1033</Locale>
+ <MoreInfoUrl>http://clang.llvm.org/extra/clang-tidy/</MoreInfoUrl>
+ <License>license.txt</License>
+ <InstalledByMsi>false</InstalledByMsi>
+ <SupportedProducts>
+ <VisualStudio Version="10.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ <VisualStudio Version="11.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ <VisualStudio Version="12.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ <VisualStudio Version="14.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ </SupportedProducts>
+ <SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />
+ </Identifier>
+ <References>
+ <Reference Id="Microsoft.VisualStudio.MPF" MinVersion="10.0">
+ <Name>Visual Studio MPF</Name>
+ </Reference>
+ </References>
+ <Content>
+ <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
+ </Content>
+</Vsix>
diff --git a/clang-tidy-vs/README.txt b/clang-tidy-vs/README.txt
new file mode 100644
index 00000000..d8785c9f
--- /dev/null
+++ b/clang-tidy-vs/README.txt
@@ -0,0 +1,17 @@
+This directory contains a VSPackage project to generate a Visual Studio extension
+for clang-tidy.
+
+Build prerequisites are:
+- Visual Studio 2013 Professional
+- Visual Studio 2013 SDK
+- Visual Studio 2010 Professional (?)
+- Visual Studio 2010 SDK (?)
+
+The extension is built using CMake by setting BUILD_CLANG_TIDY_VS_PLUGIN=ON
+when configuring a Clang build, and building the clang_tidy_vsix target.
+
+The CMake build will copy clang-tidy.exe and LICENSE.TXT into the ClangTidy/
+directory so they can be bundled with the plug-in, as well as creating
+ClangTidy/source.extension.vsixmanifest. Once the plug-in has been built with
+CMake once, it can be built manually from the ClangTidy.sln solution in Visual
+Studio.
diff --git a/clang-tidy-vs/source.extension.vsixmanifest.in b/clang-tidy-vs/source.extension.vsixmanifest.in
new file mode 100644
index 00000000..6b470977
--- /dev/null
+++ b/clang-tidy-vs/source.extension.vsixmanifest.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Vsix Version="1.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2010">
+ <Identifier Id="405594C3-042A-4155-B9A6-E25DAB8B1924">
+ <Name>ClangFormat</Name>
+ <Author>LLVM</Author>
+ <Version>@CLANG_TIDY_VS_VERSION@</Version>
+ <Description xml:space="preserve">A static analysis tool for C/C++ code.</Description>
+ <Locale>1033</Locale>
+ <MoreInfoUrl>http://clang.llvm.org/extra/clang-tidy/</MoreInfoUrl>
+ <License>license.txt</License>
+ <InstalledByMsi>false</InstalledByMsi>
+ <SupportedProducts>
+ <VisualStudio Version="10.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ <VisualStudio Version="11.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ <VisualStudio Version="12.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ <VisualStudio Version="14.0">
+ <Edition>Pro</Edition>
+ </VisualStudio>
+ </SupportedProducts>
+ <SupportedFrameworkRuntimeEdition MinVersion="4.0" MaxVersion="4.0" />
+ </Identifier>
+ <References>
+ <Reference Id="Microsoft.VisualStudio.MPF" MinVersion="10.0">
+ <Name>Visual Studio MPF</Name>
+ </Reference>
+ </References>
+ <Content>
+ <VsPackage>|%CurrentProject%;PkgdefProjectOutputGroup|</VsPackage>
+ </Content>
+</Vsix>