Ver Fonte

Support include for IDxcRewriter (#384)

* Add RewriteNoFunctionBody to IDxcRewriter.

* Support include for rewriter.

* Add rewriter to dndxc.
Xiang Li há 8 anos atrás
pai
commit
be2910df32

+ 50 - 0
include/dxc/Support/dxcfilesystem.h

@@ -0,0 +1,50 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// dxcfilesystem.h                                                           //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Provides helper file system for dxcompiler.                               //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "dxc/dxcapi.h"
+#include "llvm/Support/MSFileSystem.h"
+
+namespace clang {
+class CompilerInstance;
+}
+
+namespace llvm {
+class raw_string_ostream;
+namespace sys {
+namespace fs {
+class MSFileSystem;
+}
+} // namespace sys
+} // namespace llvm
+
+
+
+namespace dxcutil {
+
+class DxcArgsFileSystem : public ::llvm::sys::fs::MSFileSystem {
+public:
+  virtual ~DxcArgsFileSystem(){};
+  virtual void SetupForCompilerInstance(clang::CompilerInstance &compiler) = 0;
+  virtual void GetStdOutpuHandleStream(IStream **ppResultStream) = 0;
+  virtual void WriteStdErrToStream(llvm::raw_string_ostream &s) = 0;
+  virtual void EnableDisplayIncludeProcess() = 0;
+  virtual HRESULT CreateStdStreams(_In_ IMalloc *pMalloc) = 0;
+  virtual HRESULT RegisterOutputStream(LPCWSTR pName, IStream *pStream) = 0;
+};
+
+HRESULT
+CreateDxcArgsFileSystem(_In_ IDxcBlob *pSource, _In_ LPCWSTR pSourceName,
+                        _In_opt_ IDxcIncludeHandler *pIncludeHandler,
+                        _Outptr_ DxcArgsFileSystem **ppResult) throw();
+
+} // namespace dxcutil

+ 16 - 0
include/dxc/dxctools.h

@@ -14,6 +14,12 @@
 
 
 #include <dxc/dxcapi.h>
 #include <dxc/dxcapi.h>
 
 
+enum RewirterOptionMask {
+  Default = 0,
+  SkipFunctionBody = 1,
+
+};
+
 struct __declspec(uuid("c012115b-8893-4eb9-9c5a-111456ea1c45"))
 struct __declspec(uuid("c012115b-8893-4eb9-9c5a-111456ea1c45"))
 IDxcRewriter : public IUnknown {
 IDxcRewriter : public IUnknown {
 
 
@@ -29,6 +35,16 @@ IDxcRewriter : public IUnknown {
                                                      _In_ UINT32 defineCount,
                                                      _In_ UINT32 defineCount,
                                                      _COM_Outptr_ IDxcOperationResult **ppResult) = 0;
                                                      _COM_Outptr_ IDxcOperationResult **ppResult) = 0;
 
 
+  virtual HRESULT STDMETHODCALLTYPE RewriteUnchangedWithInclude(_In_ IDxcBlobEncoding *pSource,
+                                                     // Optional file name for pSource. Used in errors and include handlers.
+                                                     _In_opt_ LPCWSTR pSourceName,
+                                                     _In_count_(defineCount) DxcDefine *pDefines,
+                                                     _In_ UINT32 defineCount,
+                                                     // user-provided interface to handle #include directives (optional)
+                                                     _In_opt_ IDxcIncludeHandler *pIncludeHandler,
+                                                     _In_ UINT32  rewriteOption,
+                                                     _COM_Outptr_ IDxcOperationResult **ppResult) = 0;
+
 };
 };
 
 
 __declspec(selectany)
 __declspec(selectany)

+ 1 - 2
tools/clang/test/HLSL/rewriter/correct_rewrites/includes_gold.hlsl

@@ -1,4 +1,4 @@
-
+// Rewrite unchanged result:
 int includedFunc(int a) {
 int includedFunc(int a) {
   return a + 50;
   return a + 50;
 }
 }
@@ -29,4 +29,3 @@ int func3(int f) {
 }
 }
 
 
 
 
-

+ 7 - 0
tools/clang/test/HLSL/rewriter/correct_rewrites/includes_gold_nobody.hlsl

@@ -0,0 +1,7 @@
+// Rewrite unchanged result:
+int includedFunc(int a);
+int includedFunc2(int c);
+int includedFunc3(int e);
+int func1(int b);
+int func2(int d);
+int func3(int f);

+ 8 - 4
tools/clang/tools/dotnetc/DotNetDxc.cs

@@ -265,15 +265,19 @@ namespace DotNetDxc
     interface IDxcRewriter
     interface IDxcRewriter
     {
     {
         IDxcRewriteResult RemoveUnusedGlobals(
         IDxcRewriteResult RemoveUnusedGlobals(
-            ref DXCEncodedText pSource,
+            IDxcBlobEncoding pSource,
             [MarshalAs(UnmanagedType.LPWStr)]string pEntryPoint,
             [MarshalAs(UnmanagedType.LPWStr)]string pEntryPoint,
             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] DXCDefine[] pDefines,
             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] DXCDefine[] pDefines,
             uint defineCount);
             uint defineCount);
         IDxcRewriteResult RewriteUnchanged(
         IDxcRewriteResult RewriteUnchanged(
-            ref DXCEncodedText pSource,
+            IDxcBlobEncoding pSource,
             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] DXCDefine[] pDefines,
             [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] DXCDefine[] pDefines,
             uint defineCount);
             uint defineCount);
 
 
+        IDxcRewriteResult RewriteUnchangedWithInclude(IDxcBlobEncoding pSource,
+             [MarshalAs(UnmanagedType.LPWStr)] string pName,
+            [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.Struct)] DXCDefine[] pDefines,
+            uint defineCount, IDxcIncludeHandler includeHandler, uint rewriteOption);
     }
     }
 
 
     [ComImport]
     [ComImport]
@@ -282,8 +286,8 @@ namespace DotNetDxc
     interface IDxcRewriteResult
     interface IDxcRewriteResult
     {
     {
         uint GetStatus();
         uint GetStatus();
-        void GetRewrite(ref DXCEncodedText rewrite);
-        void GetErrorBuffer(ref DXCEncodedText errorBuff);
+        IDxcBlobEncoding GetRewrite();
+        IDxcBlobEncoding GetErrorBuffer();
     }
     }
 
 
     [StructLayout(LayoutKind.Sequential)]
     [StructLayout(LayoutKind.Sequential)]

+ 151 - 122
tools/clang/tools/dotnetc/EditorForm.Designer.cs

@@ -78,6 +78,8 @@ namespace MainNs
             this.exportCompiledObjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.exportCompiledObjectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.toolsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.rewriterToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+            this.rewriteNobodyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
             this.splitContainer1 = new System.Windows.Forms.SplitContainer();
             this.splitContainer1 = new System.Windows.Forms.SplitContainer();
@@ -104,11 +106,13 @@ namespace MainNs
             this.label2 = new System.Windows.Forms.Label();
             this.label2 = new System.Windows.Forms.Label();
             this.label1 = new System.Windows.Forms.Label();
             this.label1 = new System.Windows.Forms.Label();
             this.AvailablePassesBox = new System.Windows.Forms.ListBox();
             this.AvailablePassesBox = new System.Windows.Forms.ListBox();
+            this.RewriterOutputTabPage = new System.Windows.Forms.TabPage();
             this.TheToolTip = new System.Windows.Forms.ToolTip(this.components);
             this.TheToolTip = new System.Windows.Forms.ToolTip(this.components);
             this.TopSplitContainer = new System.Windows.Forms.SplitContainer();
             this.TopSplitContainer = new System.Windows.Forms.SplitContainer();
             this.OutputTabControl = new System.Windows.Forms.TabControl();
             this.OutputTabControl = new System.Windows.Forms.TabControl();
             this.RenderLogTabPage = new System.Windows.Forms.TabPage();
             this.RenderLogTabPage = new System.Windows.Forms.TabPage();
             this.RenderLogBox = new System.Windows.Forms.TextBox();
             this.RenderLogBox = new System.Windows.Forms.TextBox();
+            this.RewriterOutputTextBox = new System.Windows.Forms.RichTextBox();
             this.TheStatusStrip.SuspendLayout();
             this.TheStatusStrip.SuspendLayout();
             this.TheMenuStrip.SuspendLayout();
             this.TheMenuStrip.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
@@ -120,6 +124,7 @@ namespace MainNs
             this.ASTTabPage.SuspendLayout();
             this.ASTTabPage.SuspendLayout();
             this.OptimizerTabPage.SuspendLayout();
             this.OptimizerTabPage.SuspendLayout();
             this.PassesContextMenu.SuspendLayout();
             this.PassesContextMenu.SuspendLayout();
+            this.RewriterOutputTabPage.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.TopSplitContainer)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.TopSplitContainer)).BeginInit();
             this.TopSplitContainer.Panel1.SuspendLayout();
             this.TopSplitContainer.Panel1.SuspendLayout();
             this.TopSplitContainer.Panel2.SuspendLayout();
             this.TopSplitContainer.Panel2.SuspendLayout();
@@ -133,10 +138,10 @@ namespace MainNs
             this.TheStatusStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
             this.TheStatusStrip.ImageScalingSize = new System.Drawing.Size(24, 24);
             this.TheStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.TheStatusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.TheStatusStripLabel});
             this.TheStatusStripLabel});
-            this.TheStatusStrip.Location = new System.Drawing.Point(0, 526);
+            this.TheStatusStrip.Location = new System.Drawing.Point(0, 821);
             this.TheStatusStrip.Name = "TheStatusStrip";
             this.TheStatusStrip.Name = "TheStatusStrip";
-            this.TheStatusStrip.Padding = new System.Windows.Forms.Padding(1, 0, 9, 0);
-            this.TheStatusStrip.Size = new System.Drawing.Size(784, 22);
+            this.TheStatusStrip.Padding = new System.Windows.Forms.Padding(2, 0, 14, 0);
+            this.TheStatusStrip.Size = new System.Drawing.Size(1176, 22);
             this.TheStatusStrip.TabIndex = 0;
             this.TheStatusStrip.TabIndex = 0;
             this.TheStatusStrip.Text = "statusStrip1";
             this.TheStatusStrip.Text = "statusStrip1";
             // 
             // 
@@ -157,8 +162,7 @@ namespace MainNs
             this.helpToolStripMenuItem});
             this.helpToolStripMenuItem});
             this.TheMenuStrip.Location = new System.Drawing.Point(0, 0);
             this.TheMenuStrip.Location = new System.Drawing.Point(0, 0);
             this.TheMenuStrip.Name = "TheMenuStrip";
             this.TheMenuStrip.Name = "TheMenuStrip";
-            this.TheMenuStrip.Padding = new System.Windows.Forms.Padding(4, 1, 0, 1);
-            this.TheMenuStrip.Size = new System.Drawing.Size(784, 24);
+            this.TheMenuStrip.Size = new System.Drawing.Size(1176, 33);
             this.TheMenuStrip.TabIndex = 1;
             this.TheMenuStrip.TabIndex = 1;
             this.TheMenuStrip.Text = "menuStrip1";
             this.TheMenuStrip.Text = "menuStrip1";
             // 
             // 
@@ -174,7 +178,7 @@ namespace MainNs
             this.toolStripMenuItem4,
             this.toolStripMenuItem4,
             this.exitToolStripMenuItem});
             this.exitToolStripMenuItem});
             this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
             this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
-            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 22);
+            this.fileToolStripMenuItem.Size = new System.Drawing.Size(50, 29);
             this.fileToolStripMenuItem.Text = "&File";
             this.fileToolStripMenuItem.Text = "&File";
             this.fileToolStripMenuItem.DropDownOpening += new System.EventHandler(this.fileToolStripMenuItem_DropDownOpening);
             this.fileToolStripMenuItem.DropDownOpening += new System.EventHandler(this.fileToolStripMenuItem_DropDownOpening);
             // 
             // 
@@ -182,7 +186,7 @@ namespace MainNs
             // 
             // 
             this.NewToolStripMenuItem.Name = "NewToolStripMenuItem";
             this.NewToolStripMenuItem.Name = "NewToolStripMenuItem";
             this.NewToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
             this.NewToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.N)));
-            this.NewToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
+            this.NewToolStripMenuItem.Size = new System.Drawing.Size(217, 30);
             this.NewToolStripMenuItem.Text = "&New";
             this.NewToolStripMenuItem.Text = "&New";
             this.NewToolStripMenuItem.Click += new System.EventHandler(this.NewToolStripMenuItem_Click);
             this.NewToolStripMenuItem.Click += new System.EventHandler(this.NewToolStripMenuItem_Click);
             // 
             // 
@@ -190,7 +194,7 @@ namespace MainNs
             // 
             // 
             this.openToolStripMenuItem.Name = "openToolStripMenuItem";
             this.openToolStripMenuItem.Name = "openToolStripMenuItem";
             this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
             this.openToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
-            this.openToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
+            this.openToolStripMenuItem.Size = new System.Drawing.Size(217, 30);
             this.openToolStripMenuItem.Text = "&Open...";
             this.openToolStripMenuItem.Text = "&Open...";
             this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
             this.openToolStripMenuItem.Click += new System.EventHandler(this.openToolStripMenuItem_Click);
             // 
             // 
@@ -198,37 +202,37 @@ namespace MainNs
             // 
             // 
             this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
             this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
             this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
             this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
-            this.saveToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
+            this.saveToolStripMenuItem.Size = new System.Drawing.Size(217, 30);
             this.saveToolStripMenuItem.Text = "&Save";
             this.saveToolStripMenuItem.Text = "&Save";
             this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
             this.saveToolStripMenuItem.Click += new System.EventHandler(this.saveToolStripMenuItem_Click);
             // 
             // 
             // saveAsToolStripMenuItem
             // saveAsToolStripMenuItem
             // 
             // 
             this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
             this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
-            this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
+            this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(217, 30);
             this.saveAsToolStripMenuItem.Text = "Save &As...";
             this.saveAsToolStripMenuItem.Text = "Save &As...";
             this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click);
             this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.saveAsToolStripMenuItem_Click);
             // 
             // 
             // toolStripSeparator1
             // toolStripSeparator1
             // 
             // 
             this.toolStripSeparator1.Name = "toolStripSeparator1";
             this.toolStripSeparator1.Name = "toolStripSeparator1";
-            this.toolStripSeparator1.Size = new System.Drawing.Size(152, 6);
+            this.toolStripSeparator1.Size = new System.Drawing.Size(214, 6);
             // 
             // 
             // recentFilesToolStripMenuItem
             // recentFilesToolStripMenuItem
             // 
             // 
             this.recentFilesToolStripMenuItem.Name = "recentFilesToolStripMenuItem";
             this.recentFilesToolStripMenuItem.Name = "recentFilesToolStripMenuItem";
-            this.recentFilesToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
+            this.recentFilesToolStripMenuItem.Size = new System.Drawing.Size(217, 30);
             this.recentFilesToolStripMenuItem.Text = "Recent &Files";
             this.recentFilesToolStripMenuItem.Text = "Recent &Files";
             // 
             // 
             // toolStripMenuItem4
             // toolStripMenuItem4
             // 
             // 
             this.toolStripMenuItem4.Name = "toolStripMenuItem4";
             this.toolStripMenuItem4.Name = "toolStripMenuItem4";
-            this.toolStripMenuItem4.Size = new System.Drawing.Size(152, 6);
+            this.toolStripMenuItem4.Size = new System.Drawing.Size(214, 6);
             // 
             // 
             // exitToolStripMenuItem
             // exitToolStripMenuItem
             // 
             // 
             this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
             this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
-            this.exitToolStripMenuItem.Size = new System.Drawing.Size(155, 22);
+            this.exitToolStripMenuItem.Size = new System.Drawing.Size(217, 30);
             this.exitToolStripMenuItem.Text = "E&xit";
             this.exitToolStripMenuItem.Text = "E&xit";
             this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
             this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
             // 
             // 
@@ -250,27 +254,27 @@ namespace MainNs
             this.FontGrowToolStripMenuItem,
             this.FontGrowToolStripMenuItem,
             this.FontShrinkToolStripMenuItem});
             this.FontShrinkToolStripMenuItem});
             this.editToolStripMenuItem.Name = "editToolStripMenuItem";
             this.editToolStripMenuItem.Name = "editToolStripMenuItem";
-            this.editToolStripMenuItem.Size = new System.Drawing.Size(39, 22);
+            this.editToolStripMenuItem.Size = new System.Drawing.Size(54, 29);
             this.editToolStripMenuItem.Text = "&Edit";
             this.editToolStripMenuItem.Text = "&Edit";
             // 
             // 
             // undoToolStripMenuItem
             // undoToolStripMenuItem
             // 
             // 
             this.undoToolStripMenuItem.Name = "undoToolStripMenuItem";
             this.undoToolStripMenuItem.Name = "undoToolStripMenuItem";
             this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z)));
             this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z)));
-            this.undoToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.undoToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.undoToolStripMenuItem.Text = "&Undo";
             this.undoToolStripMenuItem.Text = "&Undo";
             this.undoToolStripMenuItem.Click += new System.EventHandler(this.undoToolStripMenuItem_Click);
             this.undoToolStripMenuItem.Click += new System.EventHandler(this.undoToolStripMenuItem_Click);
             // 
             // 
             // toolStripMenuItem1
             // toolStripMenuItem1
             // 
             // 
             this.toolStripMenuItem1.Name = "toolStripMenuItem1";
             this.toolStripMenuItem1.Name = "toolStripMenuItem1";
-            this.toolStripMenuItem1.Size = new System.Drawing.Size(161, 6);
+            this.toolStripMenuItem1.Size = new System.Drawing.Size(227, 6);
             // 
             // 
             // cutToolStripMenuItem
             // cutToolStripMenuItem
             // 
             // 
             this.cutToolStripMenuItem.Name = "cutToolStripMenuItem";
             this.cutToolStripMenuItem.Name = "cutToolStripMenuItem";
             this.cutToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X)));
             this.cutToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.X)));
-            this.cutToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.cutToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.cutToolStripMenuItem.Text = "Cu&t";
             this.cutToolStripMenuItem.Text = "Cu&t";
             this.cutToolStripMenuItem.Click += new System.EventHandler(this.cutToolStripMenuItem_Click);
             this.cutToolStripMenuItem.Click += new System.EventHandler(this.cutToolStripMenuItem_Click);
             // 
             // 
@@ -278,7 +282,7 @@ namespace MainNs
             // 
             // 
             this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
             this.copyToolStripMenuItem.Name = "copyToolStripMenuItem";
             this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
             this.copyToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.C)));
-            this.copyToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.copyToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.copyToolStripMenuItem.Text = "&Copy";
             this.copyToolStripMenuItem.Text = "&Copy";
             this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
             this.copyToolStripMenuItem.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
             // 
             // 
@@ -286,48 +290,48 @@ namespace MainNs
             // 
             // 
             this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem";
             this.pasteToolStripMenuItem.Name = "pasteToolStripMenuItem";
             this.pasteToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
             this.pasteToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.V)));
-            this.pasteToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.pasteToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.pasteToolStripMenuItem.Text = "&Paste";
             this.pasteToolStripMenuItem.Text = "&Paste";
             this.pasteToolStripMenuItem.Click += new System.EventHandler(this.pasteToolStripMenuItem_Click);
             this.pasteToolStripMenuItem.Click += new System.EventHandler(this.pasteToolStripMenuItem_Click);
             // 
             // 
             // deleteToolStripMenuItem
             // deleteToolStripMenuItem
             // 
             // 
             this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
             this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";
-            this.deleteToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.deleteToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.deleteToolStripMenuItem.Text = "&Delete";
             this.deleteToolStripMenuItem.Text = "&Delete";
             this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click);
             this.deleteToolStripMenuItem.Click += new System.EventHandler(this.deleteToolStripMenuItem_Click);
             // 
             // 
             // toolStripMenuItem2
             // toolStripMenuItem2
             // 
             // 
             this.toolStripMenuItem2.Name = "toolStripMenuItem2";
             this.toolStripMenuItem2.Name = "toolStripMenuItem2";
-            this.toolStripMenuItem2.Size = new System.Drawing.Size(161, 6);
+            this.toolStripMenuItem2.Size = new System.Drawing.Size(227, 6);
             // 
             // 
             // selectAllToolStripMenuItem
             // selectAllToolStripMenuItem
             // 
             // 
             this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
             this.selectAllToolStripMenuItem.Name = "selectAllToolStripMenuItem";
             this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
             this.selectAllToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.A)));
-            this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.selectAllToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.selectAllToolStripMenuItem.Text = "Select &All";
             this.selectAllToolStripMenuItem.Text = "Select &All";
             this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
             this.selectAllToolStripMenuItem.Click += new System.EventHandler(this.selectAllToolStripMenuItem_Click);
             // 
             // 
             // toolStripMenuItem3
             // toolStripMenuItem3
             // 
             // 
             this.toolStripMenuItem3.Name = "toolStripMenuItem3";
             this.toolStripMenuItem3.Name = "toolStripMenuItem3";
-            this.toolStripMenuItem3.Size = new System.Drawing.Size(161, 6);
+            this.toolStripMenuItem3.Size = new System.Drawing.Size(227, 6);
             // 
             // 
             // findAndReplaceToolStripMenuItem
             // findAndReplaceToolStripMenuItem
             // 
             // 
             this.findAndReplaceToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.findAndReplaceToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.quickFindToolStripMenuItem});
             this.quickFindToolStripMenuItem});
             this.findAndReplaceToolStripMenuItem.Name = "findAndReplaceToolStripMenuItem";
             this.findAndReplaceToolStripMenuItem.Name = "findAndReplaceToolStripMenuItem";
-            this.findAndReplaceToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.findAndReplaceToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.findAndReplaceToolStripMenuItem.Text = "&Find and Replace";
             this.findAndReplaceToolStripMenuItem.Text = "&Find and Replace";
             // 
             // 
             // quickFindToolStripMenuItem
             // quickFindToolStripMenuItem
             // 
             // 
             this.quickFindToolStripMenuItem.Name = "quickFindToolStripMenuItem";
             this.quickFindToolStripMenuItem.Name = "quickFindToolStripMenuItem";
             this.quickFindToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
             this.quickFindToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F)));
-            this.quickFindToolStripMenuItem.Size = new System.Drawing.Size(171, 22);
+            this.quickFindToolStripMenuItem.Size = new System.Drawing.Size(240, 30);
             this.quickFindToolStripMenuItem.Text = "Quick &Find";
             this.quickFindToolStripMenuItem.Text = "Quick &Find";
             this.quickFindToolStripMenuItem.Click += new System.EventHandler(this.quickFindToolStripMenuItem_Click);
             this.quickFindToolStripMenuItem.Click += new System.EventHandler(this.quickFindToolStripMenuItem_Click);
             // 
             // 
@@ -335,14 +339,14 @@ namespace MainNs
             // 
             // 
             this.goToToolStripMenuItem.Name = "goToToolStripMenuItem";
             this.goToToolStripMenuItem.Name = "goToToolStripMenuItem";
             this.goToToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
             this.goToToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.G)));
-            this.goToToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.goToToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.goToToolStripMenuItem.Text = "&Go To...";
             this.goToToolStripMenuItem.Text = "&Go To...";
             this.goToToolStripMenuItem.Click += new System.EventHandler(this.goToToolStripMenuItem_Click);
             this.goToToolStripMenuItem.Click += new System.EventHandler(this.goToToolStripMenuItem_Click);
             // 
             // 
             // fileVariablesToolStripMenuItem
             // fileVariablesToolStripMenuItem
             // 
             // 
             this.fileVariablesToolStripMenuItem.Name = "fileVariablesToolStripMenuItem";
             this.fileVariablesToolStripMenuItem.Name = "fileVariablesToolStripMenuItem";
-            this.fileVariablesToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.fileVariablesToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.fileVariablesToolStripMenuItem.Text = "File &Variables...";
             this.fileVariablesToolStripMenuItem.Text = "File &Variables...";
             this.fileVariablesToolStripMenuItem.Click += new System.EventHandler(this.fileVariablesToolStripMenuItem_Click);
             this.fileVariablesToolStripMenuItem.Click += new System.EventHandler(this.fileVariablesToolStripMenuItem_Click);
             // 
             // 
@@ -352,7 +356,7 @@ namespace MainNs
             this.FontGrowToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) 
             this.FontGrowToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) 
             | System.Windows.Forms.Keys.OemPeriod)));
             | System.Windows.Forms.Keys.OemPeriod)));
             this.FontGrowToolStripMenuItem.ShowShortcutKeys = false;
             this.FontGrowToolStripMenuItem.ShowShortcutKeys = false;
-            this.FontGrowToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.FontGrowToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.FontGrowToolStripMenuItem.Text = "Font G&row";
             this.FontGrowToolStripMenuItem.Text = "Font G&row";
             this.FontGrowToolStripMenuItem.Click += new System.EventHandler(this.FontGrowToolStripMenuItem_Click);
             this.FontGrowToolStripMenuItem.Click += new System.EventHandler(this.FontGrowToolStripMenuItem_Click);
             // 
             // 
@@ -362,7 +366,7 @@ namespace MainNs
             this.FontShrinkToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) 
             this.FontShrinkToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift) 
             | System.Windows.Forms.Keys.Oemcomma)));
             | System.Windows.Forms.Keys.Oemcomma)));
             this.FontShrinkToolStripMenuItem.ShowShortcutKeys = false;
             this.FontShrinkToolStripMenuItem.ShowShortcutKeys = false;
-            this.FontShrinkToolStripMenuItem.Size = new System.Drawing.Size(164, 22);
+            this.FontShrinkToolStripMenuItem.Size = new System.Drawing.Size(230, 30);
             this.FontShrinkToolStripMenuItem.Text = "Font Shrin&k";
             this.FontShrinkToolStripMenuItem.Text = "Font Shrin&k";
             this.FontShrinkToolStripMenuItem.Click += new System.EventHandler(this.FontShrinkToolStripMenuItem_Click);
             this.FontShrinkToolStripMenuItem.Click += new System.EventHandler(this.FontShrinkToolStripMenuItem_Click);
             // 
             // 
@@ -376,48 +380,48 @@ namespace MainNs
             this.renderToolStripMenuItem,
             this.renderToolStripMenuItem,
             this.outputToolStripMenuItem});
             this.outputToolStripMenuItem});
             this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
             this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
-            this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 22);
+            this.viewToolStripMenuItem.Size = new System.Drawing.Size(61, 29);
             this.viewToolStripMenuItem.Text = "&View";
             this.viewToolStripMenuItem.Text = "&View";
             // 
             // 
             // autoUpdateToolStripMenuItem
             // autoUpdateToolStripMenuItem
             // 
             // 
             this.autoUpdateToolStripMenuItem.Name = "autoUpdateToolStripMenuItem";
             this.autoUpdateToolStripMenuItem.Name = "autoUpdateToolStripMenuItem";
-            this.autoUpdateToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.autoUpdateToolStripMenuItem.Size = new System.Drawing.Size(200, 30);
             this.autoUpdateToolStripMenuItem.Text = "&Auto-Update";
             this.autoUpdateToolStripMenuItem.Text = "&Auto-Update";
             this.autoUpdateToolStripMenuItem.Click += new System.EventHandler(this.autoUpdateToolStripMenuItem_Click);
             this.autoUpdateToolStripMenuItem.Click += new System.EventHandler(this.autoUpdateToolStripMenuItem_Click);
             // 
             // 
             // bitstreamToolStripMenuItem
             // bitstreamToolStripMenuItem
             // 
             // 
             this.bitstreamToolStripMenuItem.Name = "bitstreamToolStripMenuItem";
             this.bitstreamToolStripMenuItem.Name = "bitstreamToolStripMenuItem";
-            this.bitstreamToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.bitstreamToolStripMenuItem.Size = new System.Drawing.Size(200, 30);
             this.bitstreamToolStripMenuItem.Text = "&Bitstream";
             this.bitstreamToolStripMenuItem.Text = "&Bitstream";
             this.bitstreamToolStripMenuItem.Click += new System.EventHandler(this.bitstreamToolStripMenuItem_Click);
             this.bitstreamToolStripMenuItem.Click += new System.EventHandler(this.bitstreamToolStripMenuItem_Click);
             // 
             // 
             // ColorMenuItem
             // ColorMenuItem
             // 
             // 
             this.ColorMenuItem.Name = "ColorMenuItem";
             this.ColorMenuItem.Name = "ColorMenuItem";
-            this.ColorMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.ColorMenuItem.Size = new System.Drawing.Size(200, 30);
             this.ColorMenuItem.Text = "&Color";
             this.ColorMenuItem.Text = "&Color";
             this.ColorMenuItem.Click += new System.EventHandler(this.colorToolStripMenuItem_Click);
             this.ColorMenuItem.Click += new System.EventHandler(this.colorToolStripMenuItem_Click);
             // 
             // 
             // errorListToolStripMenuItem
             // errorListToolStripMenuItem
             // 
             // 
             this.errorListToolStripMenuItem.Name = "errorListToolStripMenuItem";
             this.errorListToolStripMenuItem.Name = "errorListToolStripMenuItem";
-            this.errorListToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.errorListToolStripMenuItem.Size = new System.Drawing.Size(200, 30);
             this.errorListToolStripMenuItem.Text = "Error L&ist";
             this.errorListToolStripMenuItem.Text = "Error L&ist";
             this.errorListToolStripMenuItem.Click += new System.EventHandler(this.errorListToolStripMenuItem_Click);
             this.errorListToolStripMenuItem.Click += new System.EventHandler(this.errorListToolStripMenuItem_Click);
             // 
             // 
             // renderToolStripMenuItem
             // renderToolStripMenuItem
             // 
             // 
             this.renderToolStripMenuItem.Name = "renderToolStripMenuItem";
             this.renderToolStripMenuItem.Name = "renderToolStripMenuItem";
-            this.renderToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.renderToolStripMenuItem.Size = new System.Drawing.Size(200, 30);
             this.renderToolStripMenuItem.Text = "&Render";
             this.renderToolStripMenuItem.Text = "&Render";
             this.renderToolStripMenuItem.Click += new System.EventHandler(this.renderToolStripMenuItem_Click);
             this.renderToolStripMenuItem.Click += new System.EventHandler(this.renderToolStripMenuItem_Click);
             // 
             // 
             // outputToolStripMenuItem
             // outputToolStripMenuItem
             // 
             // 
             this.outputToolStripMenuItem.Name = "outputToolStripMenuItem";
             this.outputToolStripMenuItem.Name = "outputToolStripMenuItem";
-            this.outputToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
+            this.outputToolStripMenuItem.Size = new System.Drawing.Size(200, 30);
             this.outputToolStripMenuItem.Text = "&Output";
             this.outputToolStripMenuItem.Text = "&Output";
             this.outputToolStripMenuItem.Click += new System.EventHandler(this.outputToolStripMenuItem_Click);
             this.outputToolStripMenuItem.Click += new System.EventHandler(this.outputToolStripMenuItem_Click);
             // 
             // 
@@ -427,51 +431,67 @@ namespace MainNs
             this.compileToolStripMenuItem,
             this.compileToolStripMenuItem,
             this.exportCompiledObjectToolStripMenuItem});
             this.exportCompiledObjectToolStripMenuItem});
             this.buildToolStripMenuItem.Name = "buildToolStripMenuItem";
             this.buildToolStripMenuItem.Name = "buildToolStripMenuItem";
-            this.buildToolStripMenuItem.Size = new System.Drawing.Size(46, 22);
+            this.buildToolStripMenuItem.Size = new System.Drawing.Size(63, 29);
             this.buildToolStripMenuItem.Text = "&Build";
             this.buildToolStripMenuItem.Text = "&Build";
             // 
             // 
             // compileToolStripMenuItem
             // compileToolStripMenuItem
             // 
             // 
             this.compileToolStripMenuItem.Name = "compileToolStripMenuItem";
             this.compileToolStripMenuItem.Name = "compileToolStripMenuItem";
             this.compileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F7)));
             this.compileToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.F7)));
-            this.compileToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
+            this.compileToolStripMenuItem.Size = new System.Drawing.Size(286, 30);
             this.compileToolStripMenuItem.Text = "Co&mpile";
             this.compileToolStripMenuItem.Text = "Co&mpile";
             this.compileToolStripMenuItem.Click += new System.EventHandler(this.compileToolStripMenuItem_Click);
             this.compileToolStripMenuItem.Click += new System.EventHandler(this.compileToolStripMenuItem_Click);
             // 
             // 
             // exportCompiledObjectToolStripMenuItem
             // exportCompiledObjectToolStripMenuItem
             // 
             // 
             this.exportCompiledObjectToolStripMenuItem.Name = "exportCompiledObjectToolStripMenuItem";
             this.exportCompiledObjectToolStripMenuItem.Name = "exportCompiledObjectToolStripMenuItem";
-            this.exportCompiledObjectToolStripMenuItem.Size = new System.Drawing.Size(200, 22);
+            this.exportCompiledObjectToolStripMenuItem.Size = new System.Drawing.Size(286, 30);
             this.exportCompiledObjectToolStripMenuItem.Text = "&Export Compiled Object";
             this.exportCompiledObjectToolStripMenuItem.Text = "&Export Compiled Object";
             this.exportCompiledObjectToolStripMenuItem.Click += new System.EventHandler(this.exportCompiledObjectToolStripMenuItem_Click);
             this.exportCompiledObjectToolStripMenuItem.Click += new System.EventHandler(this.exportCompiledObjectToolStripMenuItem_Click);
             // 
             // 
             // toolsToolStripMenuItem
             // toolsToolStripMenuItem
             // 
             // 
             this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.toolsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
-            this.optionsToolStripMenuItem});
+            this.optionsToolStripMenuItem,
+            this.rewriterToolStripMenuItem,
+            this.rewriteNobodyToolStripMenuItem});
             this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
             this.toolsToolStripMenuItem.Name = "toolsToolStripMenuItem";
-            this.toolsToolStripMenuItem.Size = new System.Drawing.Size(47, 22);
+            this.toolsToolStripMenuItem.Size = new System.Drawing.Size(65, 29);
             this.toolsToolStripMenuItem.Text = "&Tools";
             this.toolsToolStripMenuItem.Text = "&Tools";
             // 
             // 
             // optionsToolStripMenuItem
             // optionsToolStripMenuItem
             // 
             // 
             this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
             this.optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
-            this.optionsToolStripMenuItem.Size = new System.Drawing.Size(125, 22);
+            this.optionsToolStripMenuItem.Size = new System.Drawing.Size(219, 30);
             this.optionsToolStripMenuItem.Text = "&Options...";
             this.optionsToolStripMenuItem.Text = "&Options...";
             this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click);
             this.optionsToolStripMenuItem.Click += new System.EventHandler(this.optionsToolStripMenuItem_Click);
             // 
             // 
+            // rewriterToolStripMenuItem
+            // 
+            this.rewriterToolStripMenuItem.Name = "rewriterToolStripMenuItem";
+            this.rewriterToolStripMenuItem.Size = new System.Drawing.Size(219, 30);
+            this.rewriterToolStripMenuItem.Text = "Rewriter";
+            this.rewriterToolStripMenuItem.Click += new System.EventHandler(this.rewriterToolStripMenuItem_Click);
+            // 
+            // rewriteNobodyToolStripMenuItem
+            // 
+            this.rewriteNobodyToolStripMenuItem.Name = "rewriteNobodyToolStripMenuItem";
+            this.rewriteNobodyToolStripMenuItem.Size = new System.Drawing.Size(219, 30);
+            this.rewriteNobodyToolStripMenuItem.Text = "RewriteNobody";
+            this.rewriteNobodyToolStripMenuItem.Click += new System.EventHandler(this.rewriteNobodyToolStripMenuItem_Click);
+            // 
             // helpToolStripMenuItem
             // helpToolStripMenuItem
             // 
             // 
             this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
             this.aboutToolStripMenuItem});
             this.aboutToolStripMenuItem});
             this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
             this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
-            this.helpToolStripMenuItem.Size = new System.Drawing.Size(44, 22);
+            this.helpToolStripMenuItem.Size = new System.Drawing.Size(61, 29);
             this.helpToolStripMenuItem.Text = "&Help";
             this.helpToolStripMenuItem.Text = "&Help";
             // 
             // 
             // aboutToolStripMenuItem
             // aboutToolStripMenuItem
             // 
             // 
             this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
             this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";
-            this.aboutToolStripMenuItem.Size = new System.Drawing.Size(116, 22);
+            this.aboutToolStripMenuItem.Size = new System.Drawing.Size(158, 30);
             this.aboutToolStripMenuItem.Text = "&About...";
             this.aboutToolStripMenuItem.Text = "&About...";
             this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
             this.aboutToolStripMenuItem.Click += new System.EventHandler(this.aboutToolStripMenuItem_Click);
             // 
             // 
@@ -479,7 +499,6 @@ namespace MainNs
             // 
             // 
             this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
             this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
             this.splitContainer1.Location = new System.Drawing.Point(0, 0);
             this.splitContainer1.Location = new System.Drawing.Point(0, 0);
-            this.splitContainer1.Margin = new System.Windows.Forms.Padding(2);
             this.splitContainer1.Name = "splitContainer1";
             this.splitContainer1.Name = "splitContainer1";
             // 
             // 
             // splitContainer1.Panel1
             // splitContainer1.Panel1
@@ -489,9 +508,8 @@ namespace MainNs
             // splitContainer1.Panel2
             // splitContainer1.Panel2
             // 
             // 
             this.splitContainer1.Panel2.Controls.Add(this.AnalysisTabControl);
             this.splitContainer1.Panel2.Controls.Add(this.AnalysisTabControl);
-            this.splitContainer1.Size = new System.Drawing.Size(784, 502);
-            this.splitContainer1.SplitterDistance = 285;
-            this.splitContainer1.SplitterWidth = 3;
+            this.splitContainer1.Size = new System.Drawing.Size(1176, 788);
+            this.splitContainer1.SplitterDistance = 427;
             this.splitContainer1.TabIndex = 2;
             this.splitContainer1.TabIndex = 2;
             // 
             // 
             // CodeBox
             // CodeBox
@@ -499,9 +517,8 @@ namespace MainNs
             this.CodeBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.CodeBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.CodeBox.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
             this.CodeBox.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
             this.CodeBox.Location = new System.Drawing.Point(0, 0);
             this.CodeBox.Location = new System.Drawing.Point(0, 0);
-            this.CodeBox.Margin = new System.Windows.Forms.Padding(2);
             this.CodeBox.Name = "CodeBox";
             this.CodeBox.Name = "CodeBox";
-            this.CodeBox.Size = new System.Drawing.Size(285, 502);
+            this.CodeBox.Size = new System.Drawing.Size(427, 788);
             this.CodeBox.TabIndex = 0;
             this.CodeBox.TabIndex = 0;
             this.CodeBox.Text = "";
             this.CodeBox.Text = "";
             this.CodeBox.WordWrap = false;
             this.CodeBox.WordWrap = false;
@@ -513,23 +530,22 @@ namespace MainNs
             this.AnalysisTabControl.Controls.Add(this.DisassemblyTabPage);
             this.AnalysisTabControl.Controls.Add(this.DisassemblyTabPage);
             this.AnalysisTabControl.Controls.Add(this.ASTTabPage);
             this.AnalysisTabControl.Controls.Add(this.ASTTabPage);
             this.AnalysisTabControl.Controls.Add(this.OptimizerTabPage);
             this.AnalysisTabControl.Controls.Add(this.OptimizerTabPage);
+            this.AnalysisTabControl.Controls.Add(this.RewriterOutputTabPage);
             this.AnalysisTabControl.Dock = System.Windows.Forms.DockStyle.Fill;
             this.AnalysisTabControl.Dock = System.Windows.Forms.DockStyle.Fill;
             this.AnalysisTabControl.Location = new System.Drawing.Point(0, 0);
             this.AnalysisTabControl.Location = new System.Drawing.Point(0, 0);
-            this.AnalysisTabControl.Margin = new System.Windows.Forms.Padding(2);
             this.AnalysisTabControl.Name = "AnalysisTabControl";
             this.AnalysisTabControl.Name = "AnalysisTabControl";
             this.AnalysisTabControl.SelectedIndex = 0;
             this.AnalysisTabControl.SelectedIndex = 0;
-            this.AnalysisTabControl.Size = new System.Drawing.Size(496, 502);
+            this.AnalysisTabControl.Size = new System.Drawing.Size(745, 788);
             this.AnalysisTabControl.TabIndex = 0;
             this.AnalysisTabControl.TabIndex = 0;
             this.AnalysisTabControl.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.AnalysisTabControl_Selecting);
             this.AnalysisTabControl.Selecting += new System.Windows.Forms.TabControlCancelEventHandler(this.AnalysisTabControl_Selecting);
             // 
             // 
             // DisassemblyTabPage
             // DisassemblyTabPage
             // 
             // 
             this.DisassemblyTabPage.Controls.Add(this.DisassemblyTextBox);
             this.DisassemblyTabPage.Controls.Add(this.DisassemblyTextBox);
-            this.DisassemblyTabPage.Location = new System.Drawing.Point(4, 22);
-            this.DisassemblyTabPage.Margin = new System.Windows.Forms.Padding(2);
+            this.DisassemblyTabPage.Location = new System.Drawing.Point(4, 29);
             this.DisassemblyTabPage.Name = "DisassemblyTabPage";
             this.DisassemblyTabPage.Name = "DisassemblyTabPage";
-            this.DisassemblyTabPage.Padding = new System.Windows.Forms.Padding(2);
-            this.DisassemblyTabPage.Size = new System.Drawing.Size(488, 476);
+            this.DisassemblyTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.DisassemblyTabPage.Size = new System.Drawing.Size(737, 755);
             this.DisassemblyTabPage.TabIndex = 0;
             this.DisassemblyTabPage.TabIndex = 0;
             this.DisassemblyTabPage.Text = "Disassembly";
             this.DisassemblyTabPage.Text = "Disassembly";
             this.DisassemblyTabPage.UseVisualStyleBackColor = true;
             this.DisassemblyTabPage.UseVisualStyleBackColor = true;
@@ -537,11 +553,10 @@ namespace MainNs
             // DisassemblyTextBox
             // DisassemblyTextBox
             // 
             // 
             this.DisassemblyTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.DisassemblyTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.DisassemblyTextBox.Location = new System.Drawing.Point(2, 2);
-            this.DisassemblyTextBox.Margin = new System.Windows.Forms.Padding(2);
+            this.DisassemblyTextBox.Location = new System.Drawing.Point(3, 3);
             this.DisassemblyTextBox.Name = "DisassemblyTextBox";
             this.DisassemblyTextBox.Name = "DisassemblyTextBox";
             this.DisassemblyTextBox.ReadOnly = true;
             this.DisassemblyTextBox.ReadOnly = true;
-            this.DisassemblyTextBox.Size = new System.Drawing.Size(484, 472);
+            this.DisassemblyTextBox.Size = new System.Drawing.Size(731, 749);
             this.DisassemblyTextBox.TabIndex = 0;
             this.DisassemblyTextBox.TabIndex = 0;
             this.DisassemblyTextBox.Text = "";
             this.DisassemblyTextBox.Text = "";
             this.DisassemblyTextBox.WordWrap = false;
             this.DisassemblyTextBox.WordWrap = false;
@@ -550,11 +565,10 @@ namespace MainNs
             // ASTTabPage
             // ASTTabPage
             // 
             // 
             this.ASTTabPage.Controls.Add(this.ASTDumpBox);
             this.ASTTabPage.Controls.Add(this.ASTDumpBox);
-            this.ASTTabPage.Location = new System.Drawing.Point(4, 22);
-            this.ASTTabPage.Margin = new System.Windows.Forms.Padding(2);
+            this.ASTTabPage.Location = new System.Drawing.Point(4, 29);
             this.ASTTabPage.Name = "ASTTabPage";
             this.ASTTabPage.Name = "ASTTabPage";
-            this.ASTTabPage.Padding = new System.Windows.Forms.Padding(2);
-            this.ASTTabPage.Size = new System.Drawing.Size(488, 476);
+            this.ASTTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.ASTTabPage.Size = new System.Drawing.Size(737, 755);
             this.ASTTabPage.TabIndex = 1;
             this.ASTTabPage.TabIndex = 1;
             this.ASTTabPage.Text = "AST";
             this.ASTTabPage.Text = "AST";
             this.ASTTabPage.UseVisualStyleBackColor = true;
             this.ASTTabPage.UseVisualStyleBackColor = true;
@@ -562,11 +576,10 @@ namespace MainNs
             // ASTDumpBox
             // ASTDumpBox
             // 
             // 
             this.ASTDumpBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.ASTDumpBox.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.ASTDumpBox.Location = new System.Drawing.Point(2, 2);
-            this.ASTDumpBox.Margin = new System.Windows.Forms.Padding(2);
+            this.ASTDumpBox.Location = new System.Drawing.Point(3, 3);
             this.ASTDumpBox.Name = "ASTDumpBox";
             this.ASTDumpBox.Name = "ASTDumpBox";
             this.ASTDumpBox.ReadOnly = true;
             this.ASTDumpBox.ReadOnly = true;
-            this.ASTDumpBox.Size = new System.Drawing.Size(484, 472);
+            this.ASTDumpBox.Size = new System.Drawing.Size(731, 749);
             this.ASTDumpBox.TabIndex = 0;
             this.ASTDumpBox.TabIndex = 0;
             this.ASTDumpBox.Text = "";
             this.ASTDumpBox.Text = "";
             // 
             // 
@@ -583,11 +596,10 @@ namespace MainNs
             this.OptimizerTabPage.Controls.Add(this.label2);
             this.OptimizerTabPage.Controls.Add(this.label2);
             this.OptimizerTabPage.Controls.Add(this.label1);
             this.OptimizerTabPage.Controls.Add(this.label1);
             this.OptimizerTabPage.Controls.Add(this.AvailablePassesBox);
             this.OptimizerTabPage.Controls.Add(this.AvailablePassesBox);
-            this.OptimizerTabPage.Location = new System.Drawing.Point(4, 22);
-            this.OptimizerTabPage.Margin = new System.Windows.Forms.Padding(2);
+            this.OptimizerTabPage.Location = new System.Drawing.Point(4, 29);
             this.OptimizerTabPage.Name = "OptimizerTabPage";
             this.OptimizerTabPage.Name = "OptimizerTabPage";
-            this.OptimizerTabPage.Padding = new System.Windows.Forms.Padding(2);
-            this.OptimizerTabPage.Size = new System.Drawing.Size(488, 476);
+            this.OptimizerTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.OptimizerTabPage.Size = new System.Drawing.Size(737, 755);
             this.OptimizerTabPage.TabIndex = 2;
             this.OptimizerTabPage.TabIndex = 2;
             this.OptimizerTabPage.Text = "Optimizer";
             this.OptimizerTabPage.Text = "Optimizer";
             this.OptimizerTabPage.UseVisualStyleBackColor = true;
             this.OptimizerTabPage.UseVisualStyleBackColor = true;
@@ -596,9 +608,10 @@ namespace MainNs
             // 
             // 
             this.PrintAllPassesBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
             this.PrintAllPassesBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
             this.PrintAllPassesBox.AutoSize = true;
             this.PrintAllPassesBox.AutoSize = true;
-            this.PrintAllPassesBox.Location = new System.Drawing.Point(7, 401);
+            this.PrintAllPassesBox.Location = new System.Drawing.Point(10, 624);
+            this.PrintAllPassesBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
             this.PrintAllPassesBox.Name = "PrintAllPassesBox";
             this.PrintAllPassesBox.Name = "PrintAllPassesBox";
-            this.PrintAllPassesBox.Size = new System.Drawing.Size(96, 17);
+            this.PrintAllPassesBox.Size = new System.Drawing.Size(141, 24);
             this.PrintAllPassesBox.TabIndex = 10;
             this.PrintAllPassesBox.TabIndex = 10;
             this.PrintAllPassesBox.Text = "Print all passes";
             this.PrintAllPassesBox.Text = "Print all passes";
             this.PrintAllPassesBox.UseVisualStyleBackColor = true;
             this.PrintAllPassesBox.UseVisualStyleBackColor = true;
@@ -606,10 +619,9 @@ namespace MainNs
             // ResetDefaultPassesButton
             // ResetDefaultPassesButton
             // 
             // 
             this.ResetDefaultPassesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
             this.ResetDefaultPassesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.ResetDefaultPassesButton.Location = new System.Drawing.Point(284, 404);
-            this.ResetDefaultPassesButton.Margin = new System.Windows.Forms.Padding(2);
+            this.ResetDefaultPassesButton.Location = new System.Drawing.Point(427, 627);
             this.ResetDefaultPassesButton.Name = "ResetDefaultPassesButton";
             this.ResetDefaultPassesButton.Name = "ResetDefaultPassesButton";
-            this.ResetDefaultPassesButton.Size = new System.Drawing.Size(146, 25);
+            this.ResetDefaultPassesButton.Size = new System.Drawing.Size(219, 38);
             this.ResetDefaultPassesButton.TabIndex = 9;
             this.ResetDefaultPassesButton.TabIndex = 9;
             this.ResetDefaultPassesButton.Text = "Reset Default Passes";
             this.ResetDefaultPassesButton.Text = "Reset Default Passes";
             this.ResetDefaultPassesButton.UseVisualStyleBackColor = true;
             this.ResetDefaultPassesButton.UseVisualStyleBackColor = true;
@@ -619,9 +631,10 @@ namespace MainNs
             // 
             // 
             this.AnalyzeCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
             this.AnalyzeCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
             this.AnalyzeCheckBox.AutoSize = true;
             this.AnalyzeCheckBox.AutoSize = true;
-            this.AnalyzeCheckBox.Location = new System.Drawing.Point(7, 380);
+            this.AnalyzeCheckBox.Location = new System.Drawing.Point(10, 592);
+            this.AnalyzeCheckBox.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
             this.AnalyzeCheckBox.Name = "AnalyzeCheckBox";
             this.AnalyzeCheckBox.Name = "AnalyzeCheckBox";
-            this.AnalyzeCheckBox.Size = new System.Drawing.Size(99, 17);
+            this.AnalyzeCheckBox.Size = new System.Drawing.Size(146, 24);
             this.AnalyzeCheckBox.TabIndex = 8;
             this.AnalyzeCheckBox.TabIndex = 8;
             this.AnalyzeCheckBox.Text = "Analyze passes";
             this.AnalyzeCheckBox.Text = "Analyze passes";
             this.AnalyzeCheckBox.UseVisualStyleBackColor = true;
             this.AnalyzeCheckBox.UseVisualStyleBackColor = true;
@@ -629,10 +642,9 @@ namespace MainNs
             // AddPrintModuleButton
             // AddPrintModuleButton
             // 
             // 
             this.AddPrintModuleButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
             this.AddPrintModuleButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.AddPrintModuleButton.Location = new System.Drawing.Point(7, 423);
-            this.AddPrintModuleButton.Margin = new System.Windows.Forms.Padding(2);
+            this.AddPrintModuleButton.Location = new System.Drawing.Point(10, 656);
             this.AddPrintModuleButton.Name = "AddPrintModuleButton";
             this.AddPrintModuleButton.Name = "AddPrintModuleButton";
-            this.AddPrintModuleButton.Size = new System.Drawing.Size(146, 25);
+            this.AddPrintModuleButton.Size = new System.Drawing.Size(219, 38);
             this.AddPrintModuleButton.TabIndex = 7;
             this.AddPrintModuleButton.TabIndex = 7;
             this.AddPrintModuleButton.Text = "Add Print Module";
             this.AddPrintModuleButton.Text = "Add Print Module";
             this.AddPrintModuleButton.UseVisualStyleBackColor = true;
             this.AddPrintModuleButton.UseVisualStyleBackColor = true;
@@ -641,10 +653,9 @@ namespace MainNs
             // RunPassesButton
             // RunPassesButton
             // 
             // 
             this.RunPassesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
             this.RunPassesButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.RunPassesButton.Location = new System.Drawing.Point(284, 431);
-            this.RunPassesButton.Margin = new System.Windows.Forms.Padding(2);
+            this.RunPassesButton.Location = new System.Drawing.Point(427, 668);
             this.RunPassesButton.Name = "RunPassesButton";
             this.RunPassesButton.Name = "RunPassesButton";
-            this.RunPassesButton.Size = new System.Drawing.Size(146, 25);
+            this.RunPassesButton.Size = new System.Drawing.Size(219, 38);
             this.RunPassesButton.TabIndex = 6;
             this.RunPassesButton.TabIndex = 6;
             this.RunPassesButton.Text = "Run Passes";
             this.RunPassesButton.Text = "Run Passes";
             this.RunPassesButton.UseVisualStyleBackColor = true;
             this.RunPassesButton.UseVisualStyleBackColor = true;
@@ -653,10 +664,9 @@ namespace MainNs
             // SelectPassDownButton
             // SelectPassDownButton
             // 
             // 
             this.SelectPassDownButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
             this.SelectPassDownButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.SelectPassDownButton.Location = new System.Drawing.Point(357, 373);
-            this.SelectPassDownButton.Margin = new System.Windows.Forms.Padding(2);
+            this.SelectPassDownButton.Location = new System.Drawing.Point(537, 579);
             this.SelectPassDownButton.Name = "SelectPassDownButton";
             this.SelectPassDownButton.Name = "SelectPassDownButton";
-            this.SelectPassDownButton.Size = new System.Drawing.Size(73, 25);
+            this.SelectPassDownButton.Size = new System.Drawing.Size(110, 38);
             this.SelectPassDownButton.TabIndex = 5;
             this.SelectPassDownButton.TabIndex = 5;
             this.SelectPassDownButton.Text = "Swap Down";
             this.SelectPassDownButton.Text = "Swap Down";
             this.SelectPassDownButton.UseVisualStyleBackColor = true;
             this.SelectPassDownButton.UseVisualStyleBackColor = true;
@@ -665,10 +675,9 @@ namespace MainNs
             // SelectPassUpButton
             // SelectPassUpButton
             // 
             // 
             this.SelectPassUpButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
             this.SelectPassUpButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
-            this.SelectPassUpButton.Location = new System.Drawing.Point(284, 373);
-            this.SelectPassUpButton.Margin = new System.Windows.Forms.Padding(2);
+            this.SelectPassUpButton.Location = new System.Drawing.Point(427, 579);
             this.SelectPassUpButton.Name = "SelectPassUpButton";
             this.SelectPassUpButton.Name = "SelectPassUpButton";
-            this.SelectPassUpButton.Size = new System.Drawing.Size(69, 25);
+            this.SelectPassUpButton.Size = new System.Drawing.Size(104, 38);
             this.SelectPassUpButton.TabIndex = 4;
             this.SelectPassUpButton.TabIndex = 4;
             this.SelectPassUpButton.Text = "Swap Up";
             this.SelectPassUpButton.Text = "Swap Up";
             this.SelectPassUpButton.UseVisualStyleBackColor = true;
             this.SelectPassUpButton.UseVisualStyleBackColor = true;
@@ -680,10 +689,10 @@ namespace MainNs
             | System.Windows.Forms.AnchorStyles.Right)));
             | System.Windows.Forms.AnchorStyles.Right)));
             this.SelectedPassesBox.ContextMenuStrip = this.PassesContextMenu;
             this.SelectedPassesBox.ContextMenuStrip = this.PassesContextMenu;
             this.SelectedPassesBox.FormattingEnabled = true;
             this.SelectedPassesBox.FormattingEnabled = true;
-            this.SelectedPassesBox.Location = new System.Drawing.Point(284, 30);
-            this.SelectedPassesBox.Margin = new System.Windows.Forms.Padding(2);
+            this.SelectedPassesBox.ItemHeight = 20;
+            this.SelectedPassesBox.Location = new System.Drawing.Point(427, 46);
             this.SelectedPassesBox.Name = "SelectedPassesBox";
             this.SelectedPassesBox.Name = "SelectedPassesBox";
-            this.SelectedPassesBox.Size = new System.Drawing.Size(207, 290);
+            this.SelectedPassesBox.Size = new System.Drawing.Size(308, 424);
             this.SelectedPassesBox.TabIndex = 3;
             this.SelectedPassesBox.TabIndex = 3;
             this.SelectedPassesBox.DoubleClick += new System.EventHandler(this.SelectedPassesBox_DoubleClick);
             this.SelectedPassesBox.DoubleClick += new System.EventHandler(this.SelectedPassesBox_DoubleClick);
             this.SelectedPassesBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.SelectedPassesBox_KeyUp);
             this.SelectedPassesBox.KeyUp += new System.Windows.Forms.KeyEventHandler(this.SelectedPassesBox_KeyUp);
@@ -697,31 +706,31 @@ namespace MainNs
             this.copyToolStripMenuItem1,
             this.copyToolStripMenuItem1,
             this.copyAllToolStripMenuItem});
             this.copyAllToolStripMenuItem});
             this.PassesContextMenu.Name = "PassesContextMenu";
             this.PassesContextMenu.Name = "PassesContextMenu";
-            this.PassesContextMenu.Size = new System.Drawing.Size(137, 76);
+            this.PassesContextMenu.Size = new System.Drawing.Size(177, 100);
             // 
             // 
             // PassPropertiesMenuItem
             // PassPropertiesMenuItem
             // 
             // 
             this.PassPropertiesMenuItem.Name = "PassPropertiesMenuItem";
             this.PassPropertiesMenuItem.Name = "PassPropertiesMenuItem";
-            this.PassPropertiesMenuItem.Size = new System.Drawing.Size(136, 22);
+            this.PassPropertiesMenuItem.Size = new System.Drawing.Size(176, 30);
             this.PassPropertiesMenuItem.Text = "&Properties...";
             this.PassPropertiesMenuItem.Text = "&Properties...";
             this.PassPropertiesMenuItem.Click += new System.EventHandler(this.PassPropertiesMenuItem_Click);
             this.PassPropertiesMenuItem.Click += new System.EventHandler(this.PassPropertiesMenuItem_Click);
             // 
             // 
             // toolStripMenuItem5
             // toolStripMenuItem5
             // 
             // 
             this.toolStripMenuItem5.Name = "toolStripMenuItem5";
             this.toolStripMenuItem5.Name = "toolStripMenuItem5";
-            this.toolStripMenuItem5.Size = new System.Drawing.Size(133, 6);
+            this.toolStripMenuItem5.Size = new System.Drawing.Size(173, 6);
             // 
             // 
             // copyToolStripMenuItem1
             // copyToolStripMenuItem1
             // 
             // 
             this.copyToolStripMenuItem1.Name = "copyToolStripMenuItem1";
             this.copyToolStripMenuItem1.Name = "copyToolStripMenuItem1";
-            this.copyToolStripMenuItem1.Size = new System.Drawing.Size(136, 22);
+            this.copyToolStripMenuItem1.Size = new System.Drawing.Size(176, 30);
             this.copyToolStripMenuItem1.Text = "&Copy";
             this.copyToolStripMenuItem1.Text = "&Copy";
             this.copyToolStripMenuItem1.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
             this.copyToolStripMenuItem1.Click += new System.EventHandler(this.copyToolStripMenuItem_Click);
             // 
             // 
             // copyAllToolStripMenuItem
             // copyAllToolStripMenuItem
             // 
             // 
             this.copyAllToolStripMenuItem.Name = "copyAllToolStripMenuItem";
             this.copyAllToolStripMenuItem.Name = "copyAllToolStripMenuItem";
-            this.copyAllToolStripMenuItem.Size = new System.Drawing.Size(136, 22);
+            this.copyAllToolStripMenuItem.Size = new System.Drawing.Size(176, 30);
             this.copyAllToolStripMenuItem.Text = "Copy &All";
             this.copyAllToolStripMenuItem.Text = "Copy &All";
             this.copyAllToolStripMenuItem.Click += new System.EventHandler(this.copyAllToolStripMenuItem_Click);
             this.copyAllToolStripMenuItem.Click += new System.EventHandler(this.copyAllToolStripMenuItem_Click);
             // 
             // 
@@ -729,20 +738,18 @@ namespace MainNs
             // 
             // 
             this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
             this.label2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
             this.label2.AutoSize = true;
             this.label2.AutoSize = true;
-            this.label2.Location = new System.Drawing.Point(281, 8);
-            this.label2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+            this.label2.Location = new System.Drawing.Point(423, 12);
             this.label2.Name = "label2";
             this.label2.Name = "label2";
-            this.label2.Size = new System.Drawing.Size(47, 13);
+            this.label2.Size = new System.Drawing.Size(68, 20);
             this.label2.TabIndex = 2;
             this.label2.TabIndex = 2;
             this.label2.Text = "&Pipeline:";
             this.label2.Text = "&Pipeline:";
             // 
             // 
             // label1
             // label1
             // 
             // 
             this.label1.AutoSize = true;
             this.label1.AutoSize = true;
-            this.label1.Location = new System.Drawing.Point(4, 8);
-            this.label1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
+            this.label1.Location = new System.Drawing.Point(6, 12);
             this.label1.Name = "label1";
             this.label1.Name = "label1";
-            this.label1.Size = new System.Drawing.Size(189, 13);
+            this.label1.Size = new System.Drawing.Size(278, 20);
             this.label1.TabIndex = 1;
             this.label1.TabIndex = 1;
             this.label1.Text = "&Available Passes (double-click to add):";
             this.label1.Text = "&Available Passes (double-click to add):";
             // 
             // 
@@ -752,20 +759,30 @@ namespace MainNs
             | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
             | System.Windows.Forms.AnchorStyles.Right)));
             this.AvailablePassesBox.FormattingEnabled = true;
             this.AvailablePassesBox.FormattingEnabled = true;
-            this.AvailablePassesBox.Location = new System.Drawing.Point(7, 30);
-            this.AvailablePassesBox.Margin = new System.Windows.Forms.Padding(2);
+            this.AvailablePassesBox.ItemHeight = 20;
+            this.AvailablePassesBox.Location = new System.Drawing.Point(10, 46);
             this.AvailablePassesBox.Name = "AvailablePassesBox";
             this.AvailablePassesBox.Name = "AvailablePassesBox";
             this.AvailablePassesBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
             this.AvailablePassesBox.SelectionMode = System.Windows.Forms.SelectionMode.MultiExtended;
-            this.AvailablePassesBox.Size = new System.Drawing.Size(273, 290);
+            this.AvailablePassesBox.Size = new System.Drawing.Size(409, 424);
             this.AvailablePassesBox.TabIndex = 0;
             this.AvailablePassesBox.TabIndex = 0;
             this.AvailablePassesBox.DoubleClick += new System.EventHandler(this.AvailablePassesBox_DoubleClick);
             this.AvailablePassesBox.DoubleClick += new System.EventHandler(this.AvailablePassesBox_DoubleClick);
             // 
             // 
+            // RewriterOutputTabPage
+            // 
+            this.RewriterOutputTabPage.Controls.Add(this.RewriterOutputTextBox);
+            this.RewriterOutputTabPage.Location = new System.Drawing.Point(4, 29);
+            this.RewriterOutputTabPage.Name = "RewriterOutputTabPage";
+            this.RewriterOutputTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.RewriterOutputTabPage.Size = new System.Drawing.Size(737, 755);
+            this.RewriterOutputTabPage.TabIndex = 3;
+            this.RewriterOutputTabPage.Text = "RewriterOutput";
+            this.RewriterOutputTabPage.UseVisualStyleBackColor = true;
+            // 
             // TopSplitContainer
             // TopSplitContainer
             // 
             // 
             this.TopSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
             this.TopSplitContainer.Dock = System.Windows.Forms.DockStyle.Fill;
             this.TopSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
             this.TopSplitContainer.FixedPanel = System.Windows.Forms.FixedPanel.Panel2;
-            this.TopSplitContainer.Location = new System.Drawing.Point(0, 24);
-            this.TopSplitContainer.Margin = new System.Windows.Forms.Padding(2);
+            this.TopSplitContainer.Location = new System.Drawing.Point(0, 33);
             this.TopSplitContainer.Name = "TopSplitContainer";
             this.TopSplitContainer.Name = "TopSplitContainer";
             this.TopSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
             this.TopSplitContainer.Orientation = System.Windows.Forms.Orientation.Horizontal;
             // 
             // 
@@ -777,9 +794,9 @@ namespace MainNs
             // 
             // 
             this.TopSplitContainer.Panel2.Controls.Add(this.OutputTabControl);
             this.TopSplitContainer.Panel2.Controls.Add(this.OutputTabControl);
             this.TopSplitContainer.Panel2Collapsed = true;
             this.TopSplitContainer.Panel2Collapsed = true;
-            this.TopSplitContainer.Size = new System.Drawing.Size(784, 502);
+            this.TopSplitContainer.Size = new System.Drawing.Size(1176, 788);
             this.TopSplitContainer.SplitterDistance = 477;
             this.TopSplitContainer.SplitterDistance = 477;
-            this.TopSplitContainer.SplitterWidth = 2;
+            this.TopSplitContainer.SplitterWidth = 3;
             this.TopSplitContainer.TabIndex = 3;
             this.TopSplitContainer.TabIndex = 3;
             // 
             // 
             // OutputTabControl
             // OutputTabControl
@@ -787,7 +804,6 @@ namespace MainNs
             this.OutputTabControl.Controls.Add(this.RenderLogTabPage);
             this.OutputTabControl.Controls.Add(this.RenderLogTabPage);
             this.OutputTabControl.Dock = System.Windows.Forms.DockStyle.Fill;
             this.OutputTabControl.Dock = System.Windows.Forms.DockStyle.Fill;
             this.OutputTabControl.Location = new System.Drawing.Point(0, 0);
             this.OutputTabControl.Location = new System.Drawing.Point(0, 0);
-            this.OutputTabControl.Margin = new System.Windows.Forms.Padding(2);
             this.OutputTabControl.Name = "OutputTabControl";
             this.OutputTabControl.Name = "OutputTabControl";
             this.OutputTabControl.SelectedIndex = 0;
             this.OutputTabControl.SelectedIndex = 0;
             this.OutputTabControl.Size = new System.Drawing.Size(150, 46);
             this.OutputTabControl.Size = new System.Drawing.Size(150, 46);
@@ -796,11 +812,10 @@ namespace MainNs
             // RenderLogTabPage
             // RenderLogTabPage
             // 
             // 
             this.RenderLogTabPage.Controls.Add(this.RenderLogBox);
             this.RenderLogTabPage.Controls.Add(this.RenderLogBox);
-            this.RenderLogTabPage.Location = new System.Drawing.Point(4, 20);
-            this.RenderLogTabPage.Margin = new System.Windows.Forms.Padding(2);
+            this.RenderLogTabPage.Location = new System.Drawing.Point(6, 31);
             this.RenderLogTabPage.Name = "RenderLogTabPage";
             this.RenderLogTabPage.Name = "RenderLogTabPage";
-            this.RenderLogTabPage.Padding = new System.Windows.Forms.Padding(2);
-            this.RenderLogTabPage.Size = new System.Drawing.Size(776, 86);
+            this.RenderLogTabPage.Padding = new System.Windows.Forms.Padding(3);
+            this.RenderLogTabPage.Size = new System.Drawing.Size(1164, 132);
             this.RenderLogTabPage.TabIndex = 0;
             this.RenderLogTabPage.TabIndex = 0;
             this.RenderLogTabPage.Text = "Render Log";
             this.RenderLogTabPage.Text = "Render Log";
             this.RenderLogTabPage.UseVisualStyleBackColor = true;
             this.RenderLogTabPage.UseVisualStyleBackColor = true;
@@ -808,25 +823,34 @@ namespace MainNs
             // RenderLogBox
             // RenderLogBox
             // 
             // 
             this.RenderLogBox.Dock = System.Windows.Forms.DockStyle.Fill;
             this.RenderLogBox.Dock = System.Windows.Forms.DockStyle.Fill;
-            this.RenderLogBox.Location = new System.Drawing.Point(2, 2);
-            this.RenderLogBox.Margin = new System.Windows.Forms.Padding(2);
+            this.RenderLogBox.Location = new System.Drawing.Point(3, 3);
             this.RenderLogBox.Multiline = true;
             this.RenderLogBox.Multiline = true;
             this.RenderLogBox.Name = "RenderLogBox";
             this.RenderLogBox.Name = "RenderLogBox";
             this.RenderLogBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
             this.RenderLogBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
-            this.RenderLogBox.Size = new System.Drawing.Size(772, 82);
+            this.RenderLogBox.Size = new System.Drawing.Size(1158, 126);
             this.RenderLogBox.TabIndex = 0;
             this.RenderLogBox.TabIndex = 0;
             this.RenderLogBox.WordWrap = false;
             this.RenderLogBox.WordWrap = false;
             // 
             // 
+            // RewriterOutputTextBox
+            // 
+            this.RewriterOutputTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
+            this.RewriterOutputTextBox.Location = new System.Drawing.Point(3, 3);
+            this.RewriterOutputTextBox.Name = "RewriterOutputTextBox";
+            this.RewriterOutputTextBox.ReadOnly = true;
+            this.RewriterOutputTextBox.Size = new System.Drawing.Size(731, 749);
+            this.RewriterOutputTextBox.TabIndex = 1;
+            this.RewriterOutputTextBox.Text = "";
+            this.RewriterOutputTextBox.WordWrap = false;
+            // 
             // EditorForm
             // EditorForm
             // 
             // 
-            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+            this.AutoScaleDimensions = new System.Drawing.SizeF(9F, 20F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(784, 548);
+            this.ClientSize = new System.Drawing.Size(1176, 843);
             this.Controls.Add(this.TopSplitContainer);
             this.Controls.Add(this.TopSplitContainer);
             this.Controls.Add(this.TheStatusStrip);
             this.Controls.Add(this.TheStatusStrip);
             this.Controls.Add(this.TheMenuStrip);
             this.Controls.Add(this.TheMenuStrip);
             this.MainMenuStrip = this.TheMenuStrip;
             this.MainMenuStrip = this.TheMenuStrip;
-            this.Margin = new System.Windows.Forms.Padding(2);
             this.Name = "EditorForm";
             this.Name = "EditorForm";
             this.Text = "DirectX Compiler Editor";
             this.Text = "DirectX Compiler Editor";
             this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.EditorForm_FormClosing);
             this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.EditorForm_FormClosing);
@@ -847,6 +871,7 @@ namespace MainNs
             this.OptimizerTabPage.ResumeLayout(false);
             this.OptimizerTabPage.ResumeLayout(false);
             this.OptimizerTabPage.PerformLayout();
             this.OptimizerTabPage.PerformLayout();
             this.PassesContextMenu.ResumeLayout(false);
             this.PassesContextMenu.ResumeLayout(false);
+            this.RewriterOutputTabPage.ResumeLayout(false);
             this.TopSplitContainer.Panel1.ResumeLayout(false);
             this.TopSplitContainer.Panel1.ResumeLayout(false);
             this.TopSplitContainer.Panel2.ResumeLayout(false);
             this.TopSplitContainer.Panel2.ResumeLayout(false);
             ((System.ComponentModel.ISupportInitialize)(this.TopSplitContainer)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.TopSplitContainer)).EndInit();
@@ -932,5 +957,9 @@ namespace MainNs
         private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
         private System.Windows.Forms.ToolStripMenuItem toolsToolStripMenuItem;
         private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
         private System.Windows.Forms.ToolStripMenuItem optionsToolStripMenuItem;
         private System.Windows.Forms.ToolStripMenuItem ColorMenuItem;
         private System.Windows.Forms.ToolStripMenuItem ColorMenuItem;
+        private System.Windows.Forms.TabPage RewriterOutputTabPage;
+        private System.Windows.Forms.ToolStripMenuItem rewriterToolStripMenuItem;
+        private System.Windows.Forms.ToolStripMenuItem rewriteNobodyToolStripMenuItem;
+        private System.Windows.Forms.RichTextBox RewriterOutputTextBox;
     }
     }
 }
 }

+ 21 - 0
tools/clang/tools/dotnetc/EditorForm.cs

@@ -2872,6 +2872,27 @@ namespace MainNs
             this.ColorMenuItem.Checked = !this.ColorMenuItem.Checked;
             this.ColorMenuItem.Checked = !this.ColorMenuItem.Checked;
             CodeBox_SelectionChanged(sender, e);
             CodeBox_SelectionChanged(sender, e);
         }
         }
+
+        private void rewriterToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            IDxcRewriter rewriter = HlslDxcLib.CreateDxcRewriter();
+            IDxcBlobEncoding code = CreateBlobForCodeText();
+            IDxcRewriteResult rewriterResult = rewriter.RewriteUnchanged(code, null, 0);
+            IDxcBlobEncoding rewriteBlob = rewriterResult.GetRewrite();
+            string rewriteText = GetStringFromBlob(rewriteBlob);
+            RewriterOutputTextBox.Text = rewriteText;
+        }
+
+        private void rewriteNobodyToolStripMenuItem_Click(object sender, EventArgs e)
+        {
+            IDxcRewriter rewriter = HlslDxcLib.CreateDxcRewriter();
+            IDxcBlobEncoding code = CreateBlobForCodeText();
+            IDxcRewriteResult rewriterResult = rewriter.RewriteUnchangedWithInclude(code, "input.hlsl",null, 0, null, 1);
+            IDxcBlobEncoding rewriteBlob = rewriterResult.GetRewrite();
+            string rewriteText = GetStringFromBlob(rewriteBlob);
+            RewriterOutputTextBox.Text = rewriteText;
+            AnalysisTabControl.SelectTab(RewriterOutputTabPage);
+        }
     }
     }
 
 
     public static class RichTextBoxExt
     public static class RichTextBoxExt

+ 1 - 0
tools/clang/tools/dxcompiler/CMakeLists.txt

@@ -47,6 +47,7 @@ set(SOURCES
   DXCompiler.cpp
   DXCompiler.cpp
   DXCompiler.rc
   DXCompiler.rc
   DXCompiler.def
   DXCompiler.def
+  dxcfilesystem.cpp
   dxillib.cpp
   dxillib.cpp
   dxcontainerbuilder.cpp
   dxcontainerbuilder.cpp
   dxcutil.cpp
   dxcutil.cpp

+ 725 - 0
tools/clang/tools/dxcompiler/dxcfilesystem.cpp

@@ -0,0 +1,725 @@
+///////////////////////////////////////////////////////////////////////////////
+//                                                                           //
+// dxcfilesystem.cpp                                                         //
+// Copyright (C) Microsoft Corporation. All rights reserved.                 //
+// This file is distributed under the University of Illinois Open Source     //
+// License. See LICENSE.TXT for details.                                     //
+//                                                                           //
+// Provides helper file system for dxcompiler.                               //
+//                                                                           //
+///////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "dxc/Support/WinIncludes.h"
+#include "dxc/HLSL/DxilContainer.h"
+#include "dxc/Support/FileIOHelper.h"
+#include "dxc/Support/Global.h"
+#include "dxc/dxcapi.h"
+#include "llvm/Support/raw_ostream.h"
+#include "dxcutil.h"
+
+#include "dxc/Support/dxcfilesystem.h"
+#include "dxc/Support/Unicode.h"
+#include "clang/Frontend/CompilerInstance.h"
+
+using namespace llvm;
+using namespace hlsl;
+
+// DxcArgsFileSystem
+namespace {
+
+#if defined(_MSC_VER)
+#include <io.h>
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+#endif
+
+#ifdef DBG
+
+// This should be improved with global enabled mask rather than a compile-time mask.
+#define DXTRACE_MASK_ENABLED  0
+#define DXTRACE_MASK_APIFS    1
+#define DXTRACE_ENABLED(subsystem) (DXTRACE_MASK_ENABLED & subsystem)
+
+// DXTRACE_FMT formats a debugger trace message if DXTRACE_MASK allows it.
+#define DXTRACE_FMT(subsystem, fmt, ...) do { \
+  if (DXTRACE_ENABLED(subsystem)) OutputDebugFormatA(fmt, __VA_ARGS__); \
+} while (0)
+/// DXTRACE_FMT_APIFS is used by the API-based virtual filesystem.
+#define DXTRACE_FMT_APIFS(fmt, ...) DXTRACE_FMT(DXTRACE_MASK_APIFS, fmt, __VA_ARGS__)
+
+#else
+
+#define DXTRACE_FMT_APIFS(...)
+
+#endif // DBG
+
+
+enum class HandleKind {
+  Special = 0,
+  File = 1,
+  FileDir = 2,
+  SearchDir = 3
+};
+enum class SpecialValue {
+  Unknown = 0,
+  StdOut = 1,
+  StdErr = 2,
+  Source = 3,
+  Output = 4
+};
+struct HandleBits {
+  unsigned Offset : 8;
+  unsigned Length : 8;
+  unsigned Kind : 4;
+};
+struct DxcArgsHandle {
+  DxcArgsHandle(HANDLE h) : Handle(h) {}
+  DxcArgsHandle(unsigned fileIndex)
+    : Bits{ fileIndex, 0, (unsigned)HandleKind::File } {}
+  DxcArgsHandle(HandleKind HK, unsigned fileIndex, unsigned dirLength)
+    : Bits{ fileIndex, dirLength, (unsigned)HK} {}
+  DxcArgsHandle(SpecialValue V)
+      : Bits{(unsigned)V, 0, (unsigned)HandleKind::Special} {}
+  union {
+    HANDLE Handle;
+    HandleBits Bits;
+  };
+  bool operator==(const DxcArgsHandle &Other) { return Handle == Other.Handle; }
+  HandleKind GetKind() const { return (HandleKind)Bits.Kind; }
+  bool IsFileKind() const { return GetKind() == HandleKind::File; }
+  bool IsSpecialUnknown() const { return Handle == 0; }
+  bool IsDirHandle() const {
+    return GetKind() == HandleKind::FileDir || GetKind() == HandleKind::SearchDir;
+  }
+  bool IsStdHandle() const {
+    return GetKind() == HandleKind::Special &&
+           (GetSpecialValue() == SpecialValue::StdErr ||
+            GetSpecialValue() == SpecialValue::StdOut);
+  }
+  unsigned GetFileIndex() const {
+    DXASSERT_NOMSG(IsFileKind());
+    return Bits.Offset;
+  }
+  SpecialValue GetSpecialValue() const {
+    DXASSERT_NOMSG(GetKind() == HandleKind::Special);
+    return (SpecialValue)Bits.Offset;
+  }
+  unsigned Length() const { return Bits.Length; }
+};
+
+static_assert(sizeof(DxcArgsHandle) == sizeof(HANDLE), "else can't transparently typecast");
+
+const DxcArgsHandle UnknownHandle(SpecialValue::Unknown);
+const DxcArgsHandle StdOutHandle(SpecialValue::StdOut);
+const DxcArgsHandle StdErrHandle(SpecialValue::StdErr);
+const DxcArgsHandle OutputHandle(SpecialValue::Output);
+
+/// Max number of included files (1:1 to their directories) or search directories.
+/// If programs include more than a handful, DxcArgsFileSystem will need to do better than linear scans.
+/// If this is fired, ERROR_OUT_OF_STRUCTURES will be returned by an attempt to open a file.
+static const size_t MaxIncludedFiles = 200;
+
+bool IsAbsoluteOrCurDirRelativeW(LPCWSTR Path) {
+  if (!Path || !Path[0]) return FALSE;
+  // Current dir-relative path.
+  if (Path[0] == L'.') {
+    return Path[1] == L'\0' || Path[1] == L'/' || Path[1] == L'\\';
+  }
+  // Disk designator, then absolute path.
+  if (Path[1] == L':' && Path[2] == L'\\') {
+    return TRUE;
+  }
+  // UNC name
+  if (Path[0] == L'\\') {
+    return Path[1] == L'\\';
+  }
+
+  //
+  // NOTE: there are a number of cases we don't handle, as they don't play well with the simple
+  // file system abstraction we use:
+  // - current directory on disk designator (eg, D:file.ext), requires per-disk current dir
+  // - parent paths relative to current directory (eg, ..\\file.ext)
+  //
+  // The current-directory support is available to help in-memory handlers. On-disk handlers
+  // will typically have absolute paths to begin with.
+  //
+  return FALSE;
+}
+
+void MakeAbsoluteOrCurDirRelativeW(LPCWSTR &Path, std::wstring &PathStorage) {
+  if (IsAbsoluteOrCurDirRelativeW(Path)) {
+    return;
+  }
+  else {
+    PathStorage = L"./";
+    PathStorage += Path;
+    Path = PathStorage.c_str();
+  }
+}
+
+}
+
+namespace dxcutil {
+/// File system based on API arguments. Support being added incrementally.
+///
+/// DxcArgsFileSystem emulates a file system to clang/llvm based on API
+/// arguments. It can block certain functionality (like picking up the current
+/// directory), while adding other (like supporting an app's in-memory
+/// files through an IDxcIncludeHandler).
+///
+/// stdin/stdout/stderr are registered especially (given that they have a
+/// special role in llvm::ins/outs/errs and are defaults to various operations,
+/// it's not unexpected). The direct user of DxcArgsFileSystem can also register
+/// streams to capture output for specific files.
+///
+/// Support for IDxcIncludeHandler is somewhat tricky because the API is very
+/// minimal, to allow simple implementations, but that puts this class in the
+/// position of brokering between llvm/clang existing files (which probe for
+/// files and directories in various patterns), and this simpler handler.
+/// The current approach is to minimize changes in llvm/clang and work around
+/// the absence of directory support in IDxcIncludeHandler by assuming all
+/// included paths already exist (the handler may reject those paths later on),
+/// and always querying for a file before its parent directory (so we can
+/// disambiguate between one or the other).
+class DxcArgsFileSystemImpl : public DxcArgsFileSystem {
+private:
+  CComPtr<IDxcBlob> m_pSource;
+  LPCWSTR m_pSourceName;
+  std::wstring m_pAbsSourceName; // absolute (or '.'-relative) source name
+  CComPtr<IStream> m_pSourceStream;
+  CComPtr<IStream> m_pOutputStream;
+  CComPtr<AbstractMemoryStream> m_pStdOutStream;
+  CComPtr<AbstractMemoryStream> m_pStdErrStream;
+  LPCWSTR m_pOutputStreamName;
+  std::wstring m_pAbsOutputStreamName;
+  CComPtr<IDxcIncludeHandler> m_includeLoader;
+  std::vector<std::wstring> m_searchEntries;
+  bool m_bDisplayIncludeProcess;
+
+  // Some constraints of the current design: opening the same file twice
+  // will return the same handle/structure, and thus the same file pointer.
+  struct IncludedFile {
+    CComPtr<IDxcBlob> Blob;
+    CComPtr<IStream> BlobStream;
+    std::wstring Name;
+    IncludedFile(std::wstring &&name, IDxcBlob *pBlob, IStream *pStream)
+      : Name(name), Blob(pBlob), BlobStream(pStream) { }
+  };
+  llvm::SmallVector<IncludedFile, 4> m_includedFiles;
+
+  static bool IsDirOf(LPCWSTR lpDir, size_t dirLen, const std::wstring &fileName) {
+    if (fileName.size() <= dirLen) return false;
+    if (0 != wcsncmp(lpDir, fileName.data(), dirLen)) return false;
+
+    // Prefix matches, c:\\ to c:\\foo.hlsl or ./bar to ./bar/file.hlsl
+    // Ensure there are no additional characters, don't match ./ba if ./bar.hlsl exists
+    if (lpDir[dirLen - 1] == '\\' || lpDir[dirLen - 1] == '/') {
+      // The file name was already terminated in a separator.
+      return true;
+    }
+
+    return fileName.data()[dirLen] == '\\' || fileName.data()[dirLen] == '/';
+  }
+
+  static bool IsDirPrefixOrSame(LPCWSTR lpDir, size_t dirLen, const std::wstring &path) {
+    if (0 == wcscmp(lpDir, path.c_str())) return true;
+    return IsDirOf(lpDir, dirLen, path);
+  }
+
+  HANDLE TryFindDirHandle(LPCWSTR lpDir) const {
+    size_t dirLen = wcslen(lpDir);
+    for (size_t i = 0; i < m_includedFiles.size(); ++i) {
+      const std::wstring &fileName = m_includedFiles[i].Name;
+      if (IsDirOf(lpDir, dirLen, fileName)) {
+        return DxcArgsHandle(HandleKind::FileDir, i, dirLen).Handle;
+      }
+    }
+    for (size_t i = 0; i < m_searchEntries.size(); ++i) {
+      if (IsDirPrefixOrSame(lpDir, dirLen, m_searchEntries[i])) {
+        return DxcArgsHandle(HandleKind::SearchDir, i, dirLen).Handle;
+      }
+    }
+    return INVALID_HANDLE_VALUE;
+  }
+  DWORD TryFindOrOpen(LPCWSTR lpFileName, size_t &index) {
+    for (size_t i = 0; i < m_includedFiles.size(); ++i) {
+      if (0 == wcscmp(lpFileName, m_includedFiles[i].Name.data())) {
+        index = i;
+        return ERROR_SUCCESS;
+      }
+    }
+
+    if (m_includeLoader.p != nullptr) {
+      if (m_includedFiles.size() == MaxIncludedFiles) {
+        return ERROR_OUT_OF_STRUCTURES;
+      }
+
+      CComPtr<::IDxcBlob> fileBlob;
+      HRESULT hr = m_includeLoader->LoadSource(lpFileName, &fileBlob);
+      if (FAILED(hr)) {
+        return ERROR_UNHANDLED_EXCEPTION;
+      }
+      if (fileBlob.p != nullptr) {
+        CComPtr<IDxcBlobEncoding> fileBlobEncoded;
+        if (FAILED(hlsl::DxcGetBlobAsUtf8(fileBlob, &fileBlobEncoded))) {
+          return ERROR_UNHANDLED_EXCEPTION;
+        }
+        CComPtr<IStream> fileStream;
+        if (FAILED(hlsl::CreateReadOnlyBlobStream(fileBlobEncoded, &fileStream))) {
+          return ERROR_UNHANDLED_EXCEPTION;
+        }
+        m_includedFiles.emplace_back(std::wstring(lpFileName), fileBlobEncoded, fileStream);
+        index = m_includedFiles.size() - 1;
+
+        if (m_bDisplayIncludeProcess) {
+          std::string openFileStr;
+          raw_string_ostream s(openFileStr);
+          std::string fileName = Unicode::UTF16ToUTF8StringOrThrow(lpFileName);
+          s << "Opening file [" << fileName << "], stack top [" << (index-1)
+            << "]\n";
+          s.flush();
+          ULONG cbWritten;
+          IFT(m_pStdErrStream->Write(openFileStr.c_str(), openFileStr.size(),
+                                 &cbWritten));
+        }
+        return ERROR_SUCCESS;
+      }
+    }
+    return ERROR_NOT_FOUND;
+  }
+  static HANDLE IncludedFileIndexToHandle(size_t index) {
+    return DxcArgsHandle(index).Handle;
+  }
+  bool IsKnownHandle(HANDLE h) const {
+    return !DxcArgsHandle(h).IsSpecialUnknown();
+  }
+  IncludedFile &HandleToIncludedFile(HANDLE handle) {
+    DxcArgsHandle argsHandle(handle);
+    DXASSERT_NOMSG(argsHandle.GetFileIndex() < m_includedFiles.size());
+    return m_includedFiles[argsHandle.GetFileIndex()];
+  }
+
+public:
+  DxcArgsFileSystemImpl(_In_ IDxcBlob *pSource, LPCWSTR pSourceName, _In_opt_ IDxcIncludeHandler* pHandler)
+      : m_pSource(pSource), m_pSourceName(pSourceName), m_includeLoader(pHandler), m_bDisplayIncludeProcess(false),
+        m_pOutputStreamName(nullptr) {
+    MakeAbsoluteOrCurDirRelativeW(m_pSourceName, m_pAbsSourceName);
+    IFT(CreateReadOnlyBlobStream(m_pSource, &m_pSourceStream));
+    m_includedFiles.push_back(IncludedFile(std::wstring(m_pSourceName), m_pSource, m_pSourceStream));
+  }
+  void EnableDisplayIncludeProcess() override {
+    m_bDisplayIncludeProcess = true;
+  }
+  void WriteStdErrToStream(raw_string_ostream &s) override {
+    s.write((char*)m_pStdErrStream->GetPtr(), m_pStdErrStream->GetPtrSize());
+    s.flush();
+  }
+  HRESULT CreateStdStreams(_In_ IMalloc* pMalloc) override {
+    DXASSERT(m_pStdOutStream == nullptr, "else already created");
+    CreateMemoryStream(pMalloc, &m_pStdOutStream);
+    CreateMemoryStream(pMalloc, &m_pStdErrStream);
+    if (m_pStdOutStream == nullptr || m_pStdErrStream == nullptr) {
+      return E_OUTOFMEMORY;
+    }
+    return S_OK;
+  }
+
+  void GetStreamForFD(int fd, IStream** ppResult) {
+    return GetStreamForHandle(HandleFromFD(fd), ppResult);
+  }
+  void GetStreamForHandle(HANDLE handle, IStream** ppResult) {
+    CComPtr<IStream> stream;
+    DxcArgsHandle argsHandle(handle);
+    if (argsHandle == OutputHandle) {
+      stream = m_pOutputStream;
+    }
+    else if (argsHandle == StdOutHandle) {
+      stream = m_pStdOutStream;
+    }
+    else if (argsHandle == StdErrHandle) {
+      stream = m_pStdErrStream;
+    }
+    else if (argsHandle.GetKind() == HandleKind::File) {
+      stream = HandleToIncludedFile(handle).BlobStream;
+    }
+    *ppResult = stream.Detach();
+  }
+
+  void GetStdOutpuHandleStream(IStream **ppResultStream) override {
+    return GetStreamForHandle(StdOutHandle.Handle, ppResultStream);
+  }
+
+  void SetupForCompilerInstance(clang::CompilerInstance &compiler) override {
+    DXASSERT(m_searchEntries.size() == 0, "else compiler instance being set twice");
+    // Turn these into UTF-16 to avoid converting later, and ensure they
+    // are fully-qualified or relative to the current directory.
+    const std::vector<clang::HeaderSearchOptions::Entry> &entries =
+      compiler.getHeaderSearchOpts().UserEntries;
+    if (entries.size() > MaxIncludedFiles) {
+      throw hlsl::Exception(HRESULT_FROM_WIN32(ERROR_OUT_OF_STRUCTURES));
+    }
+    for (unsigned i = 0, e = entries.size(); i != e; ++i) {
+      const clang::HeaderSearchOptions::Entry &E = entries[i];
+      if (IsAbsoluteOrCurDirRelative(E.Path.c_str())) {
+        m_searchEntries.emplace_back(Unicode::UTF8ToUTF16StringOrThrow(E.Path.c_str()));
+      }
+      else {
+        std::wstring ws(L"./");
+        ws += Unicode::UTF8ToUTF16StringOrThrow(E.Path.c_str());
+        m_searchEntries.emplace_back(std::move(ws));
+      }
+    }
+  }
+
+  HRESULT RegisterOutputStream(LPCWSTR pName, IStream *pStream) override {
+    DXASSERT(m_pOutputStream.p == nullptr, "else multiple outputs registered");
+    m_pOutputStream = pStream;
+    m_pOutputStreamName = pName;
+    MakeAbsoluteOrCurDirRelativeW(m_pOutputStreamName, m_pAbsOutputStreamName);
+    return S_OK;
+  }
+
+  __override ~DxcArgsFileSystemImpl() { };
+  __override BOOL FindNextFileW(
+    _In_   HANDLE hFindFile,
+    _Out_  LPWIN32_FIND_DATAW lpFindFileData) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+
+  __override HANDLE FindFirstFileW(
+    _In_   LPCWSTR lpFileName,
+    _Out_  LPWIN32_FIND_DATAW lpFindFileData) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+
+  __override void FindClose(HANDLE findHandle) throw() {
+    __debugbreak();
+  }
+
+  __override HANDLE CreateFileW(
+    _In_      LPCWSTR lpFileName,
+    _In_      DWORD dwDesiredAccess,
+    _In_      DWORD dwShareMode,
+    _In_      DWORD dwCreationDisposition,
+    _In_      DWORD dwFlagsAndAttributes) throw() {
+    DXTRACE_FMT_APIFS("DxcArgsFileSystem::CreateFileW %S\n", lpFileName);
+    std::wstring FileNameStore;
+    MakeAbsoluteOrCurDirRelativeW(lpFileName, FileNameStore);
+
+    // Check for a match to the output file.
+    if (m_pOutputStreamName != nullptr &&
+        0 == wcscmp(lpFileName, m_pOutputStreamName)) {
+      return OutputHandle.Handle;
+    }
+
+    HANDLE dirHandle = TryFindDirHandle(lpFileName);
+    if (dirHandle != INVALID_HANDLE_VALUE) {
+      return dirHandle;
+    }
+
+    size_t includedIndex;
+    DWORD findError = TryFindOrOpen(lpFileName, includedIndex);
+    if (findError == ERROR_SUCCESS) {
+      return IncludedFileIndexToHandle(includedIndex);
+    }
+
+    SetLastError(findError);
+    return INVALID_HANDLE_VALUE;
+  }
+
+  __override BOOL SetFileTime(_In_ HANDLE hFile,
+    _In_opt_  const FILETIME *lpCreationTime,
+    _In_opt_  const FILETIME *lpLastAccessTime,
+    _In_opt_  const FILETIME *lpLastWriteTime) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+
+  __override BOOL GetFileInformationByHandle(_In_ HANDLE hFile, _Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation) throw() {
+    DxcArgsHandle argsHandle(hFile);
+    ZeroMemory(lpFileInformation, sizeof(*lpFileInformation));
+    lpFileInformation->nFileIndexLow = (DWORD)(uintptr_t)hFile;
+    if (argsHandle.IsFileKind()) {
+      IncludedFile &file = HandleToIncludedFile(hFile);
+      lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+      lpFileInformation->nFileSizeLow = file.Blob->GetBufferSize();
+      return TRUE;
+    }
+    if (argsHandle == OutputHandle) {
+      lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
+      STATSTG stat;
+      HRESULT hr = m_pOutputStream->Stat(&stat, STATFLAG_NONAME);
+      if (FAILED(hr)) {
+        SetLastError(ERROR_IO_DEVICE);
+        return FALSE;
+      }
+      lpFileInformation->nFileSizeLow = stat.cbSize.LowPart;
+      return TRUE;
+    }
+    else if (argsHandle.IsDirHandle()) {
+      lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+      lpFileInformation->nFileIndexHigh = 1;
+      return TRUE;
+    }
+
+    SetLastError(ERROR_INVALID_HANDLE);
+    return FALSE;
+  }
+
+  __override DWORD GetFileType(_In_ HANDLE hFile) throw() {
+    DxcArgsHandle argsHandle(hFile);
+    if (argsHandle.IsStdHandle()) {
+      return FILE_TYPE_CHAR;
+    }
+    // Every other known handle is of type disk.
+    if (!argsHandle.IsSpecialUnknown()) {
+      return FILE_TYPE_DISK;
+    }
+
+    SetLastError(ERROR_NOT_FOUND);
+    return FILE_TYPE_UNKNOWN;
+  }
+
+  __override BOOL CreateHardLinkW(_In_ LPCWSTR lpFileName, _In_ LPCWSTR lpExistingFileName) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override BOOL MoveFileExW(_In_ LPCWSTR lpExistingFileName, _In_opt_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override DWORD GetFileAttributesW(_In_ LPCWSTR lpFileName) throw() {
+    DXTRACE_FMT_APIFS("DxcArgsFileSystem::GetFileAttributesW %S\n", lpFileName);
+    std::wstring FileNameStore;
+    MakeAbsoluteOrCurDirRelativeW(lpFileName, FileNameStore);
+    size_t sourceNameLen = wcslen(m_pSourceName);
+    size_t fileNameLen = wcslen(lpFileName);
+
+    // Check for a match to the source.
+    if (fileNameLen == sourceNameLen) {
+      if (0 == wcsncmp(m_pSourceName, lpFileName, fileNameLen)) {
+        return FILE_ATTRIBUTE_NORMAL;
+      }
+    }
+
+    // Check for a perfect match to the output.
+    if (m_pOutputStreamName != nullptr &&
+        0 == wcscmp(m_pOutputStreamName, lpFileName)) {
+      return FILE_ATTRIBUTE_NORMAL;
+    }
+
+    if (TryFindDirHandle(lpFileName) != INVALID_HANDLE_VALUE) {
+      return FILE_ATTRIBUTE_DIRECTORY;
+    }
+
+    size_t includedIndex;
+    DWORD findError = TryFindOrOpen(lpFileName, includedIndex);
+    if (findError == ERROR_SUCCESS) {
+      return FILE_ATTRIBUTE_NORMAL;
+    }
+
+    SetLastError(findError);
+    return INVALID_FILE_ATTRIBUTES;
+  }
+
+  __override BOOL CloseHandle(_In_ HANDLE hObject) throw() {
+    // Not actually closing handle. Would allow improper usage, but simplifies
+    // query/open/usage patterns.
+    if (IsKnownHandle(hObject)) {
+      return TRUE;
+    }
+
+    SetLastError(ERROR_INVALID_HANDLE);
+    return FALSE;
+  }
+  __override BOOL DeleteFileW(_In_ LPCWSTR lpFileName) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override BOOL RemoveDirectoryW(_In_ LPCWSTR lpFileName) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override BOOL CreateDirectoryW(_In_ LPCWSTR lpPathName) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  _Success_(return != 0 && return < nBufferLength)
+    __override DWORD GetCurrentDirectoryW(_In_ DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  _Success_(return != 0 && return < nSize)
+    __override DWORD GetMainModuleFileNameW(__out_ecount_part(nSize, return +1) LPWSTR lpFilename, DWORD nSize) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override DWORD GetTempPathW(DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override BOOLEAN CreateSymbolicLinkW(_In_ LPCWSTR lpSymlinkFileName, _In_ LPCWSTR lpTargetFileName, DWORD dwFlags) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override bool SupportsCreateSymbolicLink() throw() {
+    return false;
+  }
+  __override BOOL ReadFile(_In_ HANDLE hFile, _Out_bytecap_(nNumberOfBytesToRead) LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+  __override HANDLE CreateFileMappingW(
+    _In_      HANDLE hFile,
+    _In_      DWORD flProtect,
+    _In_      DWORD dwMaximumSizeHigh,
+    _In_      DWORD dwMaximumSizeLow) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return INVALID_HANDLE_VALUE;
+  }
+  __override LPVOID MapViewOfFile(
+    _In_  HANDLE hFileMappingObject,
+    _In_  DWORD dwDesiredAccess,
+    _In_  DWORD dwFileOffsetHigh,
+    _In_  DWORD dwFileOffsetLow,
+    _In_  SIZE_T dwNumberOfBytesToMap) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return nullptr;
+  }
+  __override BOOL UnmapViewOfFile(_In_ LPCVOID lpBaseAddress) throw() {
+    SetLastError(ERROR_NOT_CAPABLE);
+    return FALSE;
+  }
+
+  // Console APIs.
+  __override bool FileDescriptorIsDisplayed(int fd) throw() {
+    return false;
+  }
+  __override unsigned GetColumnCount(DWORD nStdHandle) throw() {
+    return 80;
+  }
+  __override unsigned GetConsoleOutputTextAttributes() throw() {
+    return 0;
+  }
+  __override void SetConsoleOutputTextAttributes(unsigned) throw() {
+    __debugbreak();
+  }
+  __override void ResetConsoleOutputTextAttributes() throw() {
+    __debugbreak();
+  }
+
+  // CRT APIs - handles and file numbers can be mapped directly.
+  HANDLE HandleFromFD(int fd) const {
+    if (fd == STDOUT_FILENO) return StdOutHandle.Handle;
+    if (fd == STDERR_FILENO) return StdErrHandle.Handle;
+    return (HANDLE)(uintptr_t)(fd);
+  }
+  __override int open_osfhandle(intptr_t osfhandle, int flags) throw() {
+    DxcArgsHandle H((HANDLE)osfhandle);
+    if (H == StdOutHandle.Handle) return STDOUT_FILENO;
+    if (H == StdErrHandle.Handle) return STDERR_FILENO;
+    return (int)(intptr_t)H.Handle;
+  }
+  __override intptr_t get_osfhandle(int fd) throw() {
+    return (intptr_t)HandleFromFD(fd);
+  }
+  __override int close(int fd) throw() {
+    return 0;
+  }
+  __override long lseek(int fd, long offset, int origin) throw() {
+    CComPtr<IStream> stream;
+    GetStreamForFD(fd, &stream);
+    if (stream == nullptr) {
+      errno = EBADF;
+      return -1;
+    }
+
+    LARGE_INTEGER li;
+    li.LowPart = offset;
+    li.HighPart = 0;
+    ULARGE_INTEGER newOffset;
+    HRESULT hr = stream->Seek(li, origin, &newOffset);
+    if (FAILED(hr)) {
+      errno = EINVAL;
+      return -1;
+    }
+
+    return newOffset.LowPart;
+  }
+  __override int setmode(int fd, int mode) throw() {
+    return 0;
+  }
+  __override errno_t resize_file(_In_ LPCWSTR path, uint64_t size) throw() {
+    return 0;
+  }
+  __override int Read(int fd, _Out_bytecap_(count) void* buffer, unsigned int count) throw() {
+    CComPtr<IStream> stream;
+    GetStreamForFD(fd, &stream);
+    if (stream == nullptr) {
+      errno = EBADF;
+      return -1;
+    }
+
+    ULONG cbRead;
+    HRESULT hr = stream->Read(buffer, count, &cbRead);
+    if (FAILED(hr)) {
+      errno = EIO;
+      return -1;
+    }
+
+    return (int)cbRead;
+  }
+  __override int Write(int fd, _In_bytecount_(count) const void* buffer, unsigned int count) throw() {
+    CComPtr<IStream> stream;
+    GetStreamForFD(fd, &stream);
+    if (stream == nullptr) {
+      errno = EBADF;
+      return -1;
+    }
+
+#ifdef _DEBUG
+    if (fd == STDERR_FILENO) {
+        char* copyWithNull = new char[count+1];
+        strncpy(copyWithNull, (char*)buffer, count);
+        copyWithNull[count] = '\0';
+        OutputDebugStringA(copyWithNull);
+        delete[] copyWithNull;
+    }
+#endif
+
+    ULONG written;
+    HRESULT hr = stream->Write(buffer, count, &written);
+    if (FAILED(hr)) {
+      errno = EIO;
+      return -1;
+    }
+
+    return (int)written;
+  }
+};
+}
+
+namespace dxcutil {
+
+HRESULT
+CreateDxcArgsFileSystem(
+    _In_ IDxcBlob *pSource, _In_ LPCWSTR pSourceName,
+    _In_opt_ IDxcIncludeHandler *pIncludeHandler,
+    _Outptr_ DxcArgsFileSystem **ppResult) throw() {
+  *ppResult = new (std::nothrow)
+      DxcArgsFileSystemImpl(pSource, pSourceName, pIncludeHandler);
+  if (*ppResult == nullptr) {
+    return E_OUTOFMEMORY;
+  }
+  return S_OK;
+}
+
+} // namespace dxcutil

+ 11 - 719
tools/clang/tools/dxcompiler/dxcompilerobj.cpp

@@ -9,9 +9,8 @@
 //                                                                           //
 //                                                                           //
 ///////////////////////////////////////////////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////////
 
 
-#include "clang/AST/ASTConsumer.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/AST/RecursiveASTVisitor.h"
+//#include "clang/AST/ASTConsumer.h"
+//#include "clang/AST/ASTContext.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/SourceManager.h"
@@ -20,12 +19,8 @@
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/Preprocessor.h"
 #include "clang/Lex/HLSLMacroExpander.h"
 #include "clang/Lex/HLSLMacroExpander.h"
-#include "clang/Parse/ParseAST.h"
-#include "clang/Rewrite/Core/Rewriter.h"
-#include "clang/Sema/SemaConsumer.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
-#include "llvm/Support/Host.h"
 #include "clang/Sema/SemaHLSL.h"
 #include "clang/Sema/SemaHLSL.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "llvm/Bitcode/ReaderWriter.h"
 #include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/FrontendActions.h"
@@ -35,6 +30,7 @@
 #include "dxc/HLSL/HLSLExtensionsCodegenHelper.h"
 #include "dxc/HLSL/HLSLExtensionsCodegenHelper.h"
 #include "dxc/HLSL/DxilRootSignature.h"
 #include "dxc/HLSL/DxilRootSignature.h"
 #include "dxcutil.h"
 #include "dxcutil.h"
+#include "dxc/Support/dxcfilesystem.h"
 
 
 // SPIRV change starts
 // SPIRV change starts
 #ifdef ENABLE_SPIRV_CODEGEN
 #ifdef ENABLE_SPIRV_CODEGEN
@@ -42,32 +38,15 @@
 #endif
 #endif
 // SPIRV change ends
 // SPIRV change ends
 
 
-#if defined(_MSC_VER)
-#include <io.h>
-#ifndef STDOUT_FILENO
-# define STDOUT_FILENO 1
-#endif
-#ifndef STDERR_FILENO
-# define STDERR_FILENO 2
-#endif
-#endif
 
 
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/Support/WinIncludes.h"
 #include "dxc/HLSL/DxilContainer.h"
 #include "dxc/HLSL/DxilContainer.h"
-#include "dxc/HLSL/DxilShaderModel.h"
-#include "dxc/HLSL/DxilModule.h"
-#include "dxc/HLSL/DxilResource.h"
-#include "dxc/HLSL/HLMatrixLowerHelper.h"
-#include "dxc/HLSL/DxilConstants.h"
-#include "dxc/HLSL/DxilOperations.h"
 
 
 #include "dxc/dxcapi.internal.h"
 #include "dxc/dxcapi.internal.h"
 
 
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/dxcapi.use.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/Global.h"
 #include "dxc/Support/Unicode.h"
 #include "dxc/Support/Unicode.h"
-#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/MSFileSystem.h"
 #include "dxc/Support/microcom.h"
 #include "dxc/Support/microcom.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/FileIOHelper.h"
 #include "dxc/Support/dxcapi.impl.h"
 #include "dxc/Support/dxcapi.impl.h"
@@ -79,26 +58,6 @@
 
 
 #define CP_UTF16 1200
 #define CP_UTF16 1200
 
 
-#ifdef DBG
-
-// This should be improved with global enabled mask rather than a compile-time mask.
-#define DXTRACE_MASK_ENABLED  0
-#define DXTRACE_MASK_APIFS    1
-#define DXTRACE_ENABLED(subsystem) (DXTRACE_MASK_ENABLED & subsystem)
-
-// DXTRACE_FMT formats a debugger trace message if DXTRACE_MASK allows it.
-#define DXTRACE_FMT(subsystem, fmt, ...) do { \
-  if (DXTRACE_ENABLED(subsystem)) OutputDebugFormatA(fmt, __VA_ARGS__); \
-} while (0)
-/// DXTRACE_FMT_APIFS is used by the API-based virtual filesystem.
-#define DXTRACE_FMT_APIFS(fmt, ...) DXTRACE_FMT(DXTRACE_MASK_APIFS, fmt, __VA_ARGS__)
-
-#else
-
-#define DXTRACE_FMT_APIFS(...)
-
-#endif // DBG
-
 using namespace llvm;
 using namespace llvm;
 using namespace clang;
 using namespace clang;
 using namespace hlsl;
 using namespace hlsl;
@@ -117,686 +76,19 @@ HRESULT RunInternalValidator(_In_ IDxcValidator *pValidator,
                              _In_ IDxcBlob *pShader, UINT32 Flags,
                              _In_ IDxcBlob *pShader, UINT32 Flags,
                              _In_ IDxcOperationResult **ppResult);
                              _In_ IDxcOperationResult **ppResult);
 
 
-enum class HandleKind {
-  Special = 0,
-  File = 1,
-  FileDir = 2,
-  SearchDir = 3
-};
-enum class SpecialValue {
-  Unknown = 0,
-  StdOut = 1,
-  StdErr = 2,
-  Source = 3,
-  Output = 4
-};
-struct HandleBits {
-  unsigned Offset : 8;
-  unsigned Length : 8;
-  unsigned Kind : 4;
-};
-struct DxcArgsHandle {
-  DxcArgsHandle(HANDLE h) : Handle(h) {}
-  DxcArgsHandle(unsigned fileIndex)
-    : Bits{ fileIndex, 0, (unsigned)HandleKind::File } {}
-  DxcArgsHandle(HandleKind HK, unsigned fileIndex, unsigned dirLength)
-    : Bits{ fileIndex, dirLength, (unsigned)HK} {}
-  DxcArgsHandle(SpecialValue V)
-      : Bits{(unsigned)V, 0, (unsigned)HandleKind::Special} {}
-  union {
-    HANDLE Handle;
-    HandleBits Bits;
-  };
-  bool operator==(const DxcArgsHandle &Other) { return Handle == Other.Handle; }
-  HandleKind GetKind() const { return (HandleKind)Bits.Kind; }
-  bool IsFileKind() const { return GetKind() == HandleKind::File; }
-  bool IsSpecialUnknown() const { return Handle == 0; }
-  bool IsDirHandle() const {
-    return GetKind() == HandleKind::FileDir || GetKind() == HandleKind::SearchDir;
-  }
-  bool IsStdHandle() const {
-    return GetKind() == HandleKind::Special &&
-           (GetSpecialValue() == SpecialValue::StdErr ||
-            GetSpecialValue() == SpecialValue::StdOut);
-  }
-  unsigned GetFileIndex() const {
-    DXASSERT_NOMSG(IsFileKind());
-    return Bits.Offset;
-  }
-  SpecialValue GetSpecialValue() const {
-    DXASSERT_NOMSG(GetKind() == HandleKind::Special);
-    return (SpecialValue)Bits.Offset;
-  }
-  unsigned Length() const { return Bits.Length; }
-};
-
-static_assert(sizeof(DxcArgsHandle) == sizeof(HANDLE), "else can't transparently typecast");
-
-static const DxcArgsHandle UnknownHandle(SpecialValue::Unknown);
-static const DxcArgsHandle StdOutHandle(SpecialValue::StdOut);
-static const DxcArgsHandle StdErrHandle(SpecialValue::StdErr);
-static const DxcArgsHandle OutputHandle(SpecialValue::Output);
-
-/// Max number of included files (1:1 to their directories) or search directories.
-/// If programs include more than a handful, DxcArgsFileSystem will need to do better than linear scans.
-/// If this is fired, ERROR_OUT_OF_STRUCTURES will be returned by an attempt to open a file.
-static const size_t MaxIncludedFiles = 200;
-
-static bool IsAbsoluteOrCurDirRelativeW(LPCWSTR Path) {
-  if (!Path || !Path[0]) return FALSE;
-  // Current dir-relative path.
-  if (Path[0] == L'.') {
-    return Path[1] == L'\0' || Path[1] == L'/' || Path[1] == L'\\';
-  }
-  // Disk designator, then absolute path.
-  if (Path[1] == L':' && Path[2] == L'\\') {
-    return TRUE;
-  }
-  // UNC name
-  if (Path[0] == L'\\') {
-    return Path[1] == L'\\';
-  }
-
-  //
-  // NOTE: there are a number of cases we don't handle, as they don't play well with the simple
-  // file system abstraction we use:
-  // - current directory on disk designator (eg, D:file.ext), requires per-disk current dir
-  // - parent paths relative to current directory (eg, ..\\file.ext)
-  //
-  // The current-directory support is available to help in-memory handlers. On-disk handlers
-  // will typically have absolute paths to begin with.
-  //
-  return FALSE;
-}
-
-static void MakeAbsoluteOrCurDirRelativeW(LPCWSTR &Path, std::wstring &PathStorage) {
-  if (IsAbsoluteOrCurDirRelativeW(Path)) {
-    return;
-  }
-  else {
-    PathStorage = L"./";
-    PathStorage += Path;
-    Path = PathStorage.c_str();
-  }
-}
-
-static bool IsAbsoluteOrCurDirRelative(const Twine &T) {
-  if (llvm::sys::path::is_absolute(T)) {
-    return true;
-  }
-  if (T.isSingleStringRef()) {
-    StringRef r = T.getSingleStringRef();
-    if (r.size() < 2) return false;
-    const char *pData = r.data();
-    return pData[0] == '.' && (pData[1] == '\\' || pData[1] == '/');
-  }
-  DXASSERT(false, "twine kind not supported");
-  return false;
-}
-
-/// File system based on API arguments. Support being added incrementally.
-///
-/// DxcArgsFileSystem emulates a file system to clang/llvm based on API
-/// arguments. It can block certain functionality (like picking up the current
-/// directory), while adding other (like supporting an app's in-memory
-/// files through an IDxcIncludeHandler).
-///
-/// stdin/stdout/stderr are registered especially (given that they have a
-/// special role in llvm::ins/outs/errs and are defaults to various operations,
-/// it's not unexpected). The direct user of DxcArgsFileSystem can also register
-/// streams to capture output for specific files.
-///
-/// Support for IDxcIncludeHandler is somewhat tricky because the API is very
-/// minimal, to allow simple implementations, but that puts this class in the
-/// position of brokering between llvm/clang existing files (which probe for
-/// files and directories in various patterns), and this simpler handler.
-/// The current approach is to minimize changes in llvm/clang and work around
-/// the absence of directory support in IDxcIncludeHandler by assuming all
-/// included paths already exist (the handler may reject those paths later on),
-/// and always querying for a file before its parent directory (so we can
-/// disambiguate between one or the other).
-class DxcArgsFileSystem : public ::llvm::sys::fs::MSFileSystem {
-private:
-  CComPtr<IDxcBlob> m_pSource;
-  LPCWSTR m_pSourceName;
-  std::wstring m_pAbsSourceName; // absolute (or '.'-relative) source name
-  CComPtr<IStream> m_pSourceStream;
-  CComPtr<IStream> m_pOutputStream;
-  CComPtr<AbstractMemoryStream> m_pStdOutStream;
-  CComPtr<AbstractMemoryStream> m_pStdErrStream;
-  LPCWSTR m_pOutputStreamName;
-  std::wstring m_pAbsOutputStreamName;
-  CComPtr<IDxcIncludeHandler> m_includeLoader;
-  std::vector<std::wstring> m_searchEntries;
-  bool m_bDisplayIncludeProcess;
-
-  // Some constraints of the current design: opening the same file twice
-  // will return the same handle/structure, and thus the same file pointer.
-  struct IncludedFile {
-    CComPtr<IDxcBlob> Blob;
-    CComPtr<IStream> BlobStream;
-    std::wstring Name;
-    IncludedFile(std::wstring &&name, IDxcBlob *pBlob, IStream *pStream)
-      : Name(name), Blob(pBlob), BlobStream(pStream) { }
-  };
-  llvm::SmallVector<IncludedFile, 4> m_includedFiles;
-
-  static bool IsDirOf(LPCWSTR lpDir, size_t dirLen, const std::wstring &fileName) {
-    if (fileName.size() <= dirLen) return false;
-    if (0 != wcsncmp(lpDir, fileName.data(), dirLen)) return false;
-
-    // Prefix matches, c:\\ to c:\\foo.hlsl or ./bar to ./bar/file.hlsl
-    // Ensure there are no additional characters, don't match ./ba if ./bar.hlsl exists
-    if (lpDir[dirLen - 1] == '\\' || lpDir[dirLen - 1] == '/') {
-      // The file name was already terminated in a separator.
-      return true;
-    }
-
-    return fileName.data()[dirLen] == '\\' || fileName.data()[dirLen] == '/';
-  }
-
-  static bool IsDirPrefixOrSame(LPCWSTR lpDir, size_t dirLen, const std::wstring &path) {
-    if (0 == wcscmp(lpDir, path.c_str())) return true;
-    return IsDirOf(lpDir, dirLen, path);
-  }
-
-  HANDLE TryFindDirHandle(LPCWSTR lpDir) const {
-    size_t dirLen = wcslen(lpDir);
-    for (size_t i = 0; i < m_includedFiles.size(); ++i) {
-      const std::wstring &fileName = m_includedFiles[i].Name;
-      if (IsDirOf(lpDir, dirLen, fileName)) {
-        return DxcArgsHandle(HandleKind::FileDir, i, dirLen).Handle;
-      }
-    }
-    for (size_t i = 0; i < m_searchEntries.size(); ++i) {
-      if (IsDirPrefixOrSame(lpDir, dirLen, m_searchEntries[i])) {
-        return DxcArgsHandle(HandleKind::SearchDir, i, dirLen).Handle;
-      }
-    }
-    return INVALID_HANDLE_VALUE;
-  }
-  DWORD TryFindOrOpen(LPCWSTR lpFileName, size_t &index) {
-    for (size_t i = 0; i < m_includedFiles.size(); ++i) {
-      if (0 == wcscmp(lpFileName, m_includedFiles[i].Name.data())) {
-        index = i;
-        return ERROR_SUCCESS;
-      }
-    }
-
-    if (m_includeLoader.p != nullptr) {
-      if (m_includedFiles.size() == MaxIncludedFiles) {
-        return ERROR_OUT_OF_STRUCTURES;
-      }
-
-      CComPtr<IDxcBlob> fileBlob;
-      HRESULT hr = m_includeLoader->LoadSource(lpFileName, &fileBlob);
-      if (FAILED(hr)) {
-        return ERROR_UNHANDLED_EXCEPTION;
-      }
-      if (fileBlob.p != nullptr) {
-        CComPtr<IDxcBlobEncoding> fileBlobEncoded;
-        if (FAILED(hlsl::DxcGetBlobAsUtf8(fileBlob, &fileBlobEncoded))) {
-          return ERROR_UNHANDLED_EXCEPTION;
-        }
-        CComPtr<IStream> fileStream;
-        if (FAILED(hlsl::CreateReadOnlyBlobStream(fileBlobEncoded, &fileStream))) {
-          return ERROR_UNHANDLED_EXCEPTION;
-        }
-        m_includedFiles.emplace_back(std::wstring(lpFileName), fileBlobEncoded, fileStream);
-        index = m_includedFiles.size() - 1;
-
-        if (m_bDisplayIncludeProcess) {
-          std::string openFileStr;
-          raw_string_ostream s(openFileStr);
-          std::string fileName = Unicode::UTF16ToUTF8StringOrThrow(lpFileName);
-          s << "Opening file [" << fileName << "], stack top [" << (index-1)
-            << "]\n";
-          s.flush();
-          ULONG cbWritten;
-          IFT(m_pStdErrStream->Write(openFileStr.c_str(), openFileStr.size(),
-                                 &cbWritten));
-        }
-        return ERROR_SUCCESS;
-      }
-    }
-    return ERROR_NOT_FOUND;
-  }
-  static HANDLE IncludedFileIndexToHandle(size_t index) {
-    return DxcArgsHandle(index).Handle;
-  }
-  bool IsKnownHandle(HANDLE h) const {
-    return !DxcArgsHandle(h).IsSpecialUnknown();
-  }
-  IncludedFile &HandleToIncludedFile(HANDLE handle) {
-    DxcArgsHandle argsHandle(handle);
-    DXASSERT_NOMSG(argsHandle.GetFileIndex() < m_includedFiles.size());
-    return m_includedFiles[argsHandle.GetFileIndex()];
-  }
-
-public:
-  DxcArgsFileSystem(_In_ IDxcBlob *pSource, LPCWSTR pSourceName, _In_opt_ IDxcIncludeHandler* pHandler)
-      : m_pSource(pSource), m_pSourceName(pSourceName), m_includeLoader(pHandler), m_bDisplayIncludeProcess(false),
-        m_pOutputStreamName(nullptr) {
-    MakeAbsoluteOrCurDirRelativeW(m_pSourceName, m_pAbsSourceName);
-    IFT(CreateReadOnlyBlobStream(m_pSource, &m_pSourceStream));
-    m_includedFiles.push_back(IncludedFile(std::wstring(m_pSourceName), m_pSource, m_pSourceStream));
-  }
-  void EnableDisplayIncludeProcess() {
-    m_bDisplayIncludeProcess = true;
-  }
-  void WriteStdErrToStream(raw_string_ostream &s) {
-    s.write((char*)m_pStdErrStream->GetPtr(), m_pStdErrStream->GetPtrSize());
-    s.flush();
-  }
-  HRESULT CreateStdStreams(_In_ IMalloc* pMalloc) {
-    DXASSERT(m_pStdOutStream == nullptr, "else already created");
-    CreateMemoryStream(pMalloc, &m_pStdOutStream);
-    CreateMemoryStream(pMalloc, &m_pStdErrStream);
-    if (m_pStdOutStream == nullptr || m_pStdErrStream == nullptr) {
-      return E_OUTOFMEMORY;
-    }
-    return S_OK;
-  }
-
-  void GetStreamForFD(int fd, IStream** ppResult) {
-    return GetStreamForHandle(HandleFromFD(fd), ppResult);
-  }
-  void GetStreamForHandle(HANDLE handle, IStream** ppResult) {
-    CComPtr<IStream> stream;
-    DxcArgsHandle argsHandle(handle);
-    if (argsHandle == OutputHandle) {
-      stream = m_pOutputStream;
-    }
-    else if (argsHandle == StdOutHandle) {
-      stream = m_pStdOutStream;
-    }
-    else if (argsHandle == StdErrHandle) {
-      stream = m_pStdErrStream;
-    }
-    else if (argsHandle.GetKind() == HandleKind::File) {
-      stream = HandleToIncludedFile(handle).BlobStream;
-    }
-    *ppResult = stream.Detach();
-  }
-
-  void SetupForCompilerInstance(CompilerInstance &compiler) {
-    DXASSERT(m_searchEntries.size() == 0, "else compiler instance being set twice");
-    // Turn these into UTF-16 to avoid converting later, and ensure they
-    // are fully-qualified or relative to the current directory.
-    const std::vector<HeaderSearchOptions::Entry> &entries =
-      compiler.getHeaderSearchOpts().UserEntries;
-    if (entries.size() > MaxIncludedFiles) {
-      throw hlsl::Exception(HRESULT_FROM_WIN32(ERROR_OUT_OF_STRUCTURES));
-    }
-    for (unsigned i = 0, e = entries.size(); i != e; ++i) {
-      const HeaderSearchOptions::Entry &E = entries[i];
-      if (IsAbsoluteOrCurDirRelative(E.Path)) {
-        m_searchEntries.emplace_back(Unicode::UTF8ToUTF16StringOrThrow(E.Path.c_str()));
-      }
-      else {
-        std::wstring ws(L"./");
-        ws += Unicode::UTF8ToUTF16StringOrThrow(E.Path.c_str());
-        m_searchEntries.emplace_back(std::move(ws));
-      }
-    }
-  }
-
-  HRESULT RegisterOutputStream(LPCWSTR pName, IStream *pStream) {
-    DXASSERT(m_pOutputStream.p == nullptr, "else multiple outputs registered");
-    m_pOutputStream = pStream;
-    m_pOutputStreamName = pName;
-    MakeAbsoluteOrCurDirRelativeW(m_pOutputStreamName, m_pAbsOutputStreamName);
-    return S_OK;
-  }
-
-  __override ~DxcArgsFileSystem() { };
-  __override BOOL FindNextFileW(
-    _In_   HANDLE hFindFile,
-    _Out_  LPWIN32_FIND_DATAW lpFindFileData) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-
-  __override HANDLE FindFirstFileW(
-    _In_   LPCWSTR lpFileName,
-    _Out_  LPWIN32_FIND_DATAW lpFindFileData) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-
-  __override void FindClose(HANDLE findHandle) throw() {
-    __debugbreak();
-  }
-
-  __override HANDLE CreateFileW(
-    _In_      LPCWSTR lpFileName,
-    _In_      DWORD dwDesiredAccess,
-    _In_      DWORD dwShareMode,
-    _In_      DWORD dwCreationDisposition,
-    _In_      DWORD dwFlagsAndAttributes) throw() {
-    DXTRACE_FMT_APIFS("DxcArgsFileSystem::CreateFileW %S\n", lpFileName);
-    size_t sourceNameLen = wcslen(m_pSourceName);
-    std::wstring FileNameStore;
-    MakeAbsoluteOrCurDirRelativeW(lpFileName, FileNameStore);
-    size_t fileNameLen = wcslen(lpFileName);
-
-    // Check for a match to the output file.
-    if (m_pOutputStreamName != nullptr &&
-        0 == wcscmp(lpFileName, m_pOutputStreamName)) {
-      return OutputHandle.Handle;
-    }
-
-    HANDLE dirHandle = TryFindDirHandle(lpFileName);
-    if (dirHandle != INVALID_HANDLE_VALUE) {
-      return dirHandle;
-    }
-
-    size_t includedIndex;
-    DWORD findError = TryFindOrOpen(lpFileName, includedIndex);
-    if (findError == ERROR_SUCCESS) {
-      return IncludedFileIndexToHandle(includedIndex);
-    }
-
-    SetLastError(findError);
-    return INVALID_HANDLE_VALUE;
-  }
-
-  __override BOOL SetFileTime(_In_ HANDLE hFile,
-    _In_opt_  const FILETIME *lpCreationTime,
-    _In_opt_  const FILETIME *lpLastAccessTime,
-    _In_opt_  const FILETIME *lpLastWriteTime) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-
-  __override BOOL GetFileInformationByHandle(_In_ HANDLE hFile, _Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation) throw() {
-    DxcArgsHandle argsHandle(hFile);
-    ZeroMemory(lpFileInformation, sizeof(*lpFileInformation));
-    lpFileInformation->nFileIndexLow = (DWORD)(uintptr_t)hFile;
-    if (argsHandle.IsFileKind()) {
-      IncludedFile &file = HandleToIncludedFile(hFile);
-      lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-      lpFileInformation->nFileSizeLow = file.Blob->GetBufferSize();
-      return TRUE;
-    }
-    if (argsHandle == OutputHandle) {
-      lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
-      STATSTG stat;
-      HRESULT hr = m_pOutputStream->Stat(&stat, STATFLAG_NONAME);
-      if (FAILED(hr)) {
-        SetLastError(ERROR_IO_DEVICE);
-        return FALSE;
-      }
-      lpFileInformation->nFileSizeLow = stat.cbSize.LowPart;
-      return TRUE;
-    }
-    else if (argsHandle.IsDirHandle()) {
-      lpFileInformation->dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
-      lpFileInformation->nFileIndexHigh = 1;
-      return TRUE;
-    }
-
-    SetLastError(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
-
-  __override DWORD GetFileType(_In_ HANDLE hFile) throw() {
-    DxcArgsHandle argsHandle(hFile);
-    if (argsHandle.IsStdHandle()) {
-      return FILE_TYPE_CHAR;
-    }
-    // Every other known handle is of type disk.
-    if (!argsHandle.IsSpecialUnknown()) {
-      return FILE_TYPE_DISK;
-    }
-
-    SetLastError(ERROR_NOT_FOUND);
-    return FILE_TYPE_UNKNOWN;
-  }
-
-  __override BOOL CreateHardLinkW(_In_ LPCWSTR lpFileName, _In_ LPCWSTR lpExistingFileName) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override BOOL MoveFileExW(_In_ LPCWSTR lpExistingFileName, _In_opt_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override DWORD GetFileAttributesW(_In_ LPCWSTR lpFileName) throw() {
-    DXTRACE_FMT_APIFS("DxcArgsFileSystem::GetFileAttributesW %S\n", lpFileName);
-    std::wstring FileNameStore;
-    MakeAbsoluteOrCurDirRelativeW(lpFileName, FileNameStore);
-    size_t sourceNameLen = wcslen(m_pSourceName);
-    size_t fileNameLen = wcslen(lpFileName);
-
-    // Check for a match to the source.
-    if (fileNameLen == sourceNameLen) {
-      if (0 == wcsncmp(m_pSourceName, lpFileName, fileNameLen)) {
-        return FILE_ATTRIBUTE_NORMAL;
-      }
-    }
-
-    // Check for a perfect match to the output.
-    if (m_pOutputStreamName != nullptr &&
-        0 == wcscmp(m_pOutputStreamName, lpFileName)) {
-      return FILE_ATTRIBUTE_NORMAL;
-    }
-
-    if (TryFindDirHandle(lpFileName) != INVALID_HANDLE_VALUE) {
-      return FILE_ATTRIBUTE_DIRECTORY;
-    }
-
-    size_t includedIndex;
-    DWORD findError = TryFindOrOpen(lpFileName, includedIndex);
-    if (findError == ERROR_SUCCESS) {
-      return FILE_ATTRIBUTE_NORMAL;
-    }
-
-    SetLastError(findError);
-    return INVALID_FILE_ATTRIBUTES;
-  }
-
-  __override BOOL CloseHandle(_In_ HANDLE hObject) throw() {
-    // Not actually closing handle. Would allow improper usage, but simplifies
-    // query/open/usage patterns.
-    if (IsKnownHandle(hObject)) {
-      return TRUE;
-    }
-
-    SetLastError(ERROR_INVALID_HANDLE);
-    return FALSE;
-  }
-  __override BOOL DeleteFileW(_In_ LPCWSTR lpFileName) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override BOOL RemoveDirectoryW(_In_ LPCWSTR lpFileName) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override BOOL CreateDirectoryW(_In_ LPCWSTR lpPathName) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  _Success_(return != 0 && return < nBufferLength)
-    __override DWORD GetCurrentDirectoryW(_In_ DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  _Success_(return != 0 && return < nSize)
-    __override DWORD GetMainModuleFileNameW(__out_ecount_part(nSize, return +1) LPWSTR lpFilename, DWORD nSize) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override DWORD GetTempPathW(DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override BOOLEAN CreateSymbolicLinkW(_In_ LPCWSTR lpSymlinkFileName, _In_ LPCWSTR lpTargetFileName, DWORD dwFlags) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override bool SupportsCreateSymbolicLink() throw() {
-    return false;
-  }
-  __override BOOL ReadFile(_In_ HANDLE hFile, _Out_bytecap_(nNumberOfBytesToRead) LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-  __override HANDLE CreateFileMappingW(
-    _In_      HANDLE hFile,
-    _In_      DWORD flProtect,
-    _In_      DWORD dwMaximumSizeHigh,
-    _In_      DWORD dwMaximumSizeLow) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return INVALID_HANDLE_VALUE;
-  }
-  __override LPVOID MapViewOfFile(
-    _In_  HANDLE hFileMappingObject,
-    _In_  DWORD dwDesiredAccess,
-    _In_  DWORD dwFileOffsetHigh,
-    _In_  DWORD dwFileOffsetLow,
-    _In_  SIZE_T dwNumberOfBytesToMap) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return nullptr;
-  }
-  __override BOOL UnmapViewOfFile(_In_ LPCVOID lpBaseAddress) throw() {
-    SetLastError(ERROR_NOT_CAPABLE);
-    return FALSE;
-  }
-
-  // Console APIs.
-  __override bool FileDescriptorIsDisplayed(int fd) throw() {
-    return false;
-  }
-  __override unsigned GetColumnCount(DWORD nStdHandle) throw() {
-    return 80;
-  }
-  __override unsigned GetConsoleOutputTextAttributes() throw() {
-    return 0;
-  }
-  __override void SetConsoleOutputTextAttributes(unsigned) throw() {
-    __debugbreak();
-  }
-  __override void ResetConsoleOutputTextAttributes() throw() {
-    __debugbreak();
-  }
-
-  // CRT APIs - handles and file numbers can be mapped directly.
-  HANDLE HandleFromFD(int fd) const {
-    if (fd == STDOUT_FILENO) return StdOutHandle.Handle;
-    if (fd == STDERR_FILENO) return StdErrHandle.Handle;
-    return (HANDLE)(uintptr_t)(fd);
-  }
-  __override int open_osfhandle(intptr_t osfhandle, int flags) throw() {
-    DxcArgsHandle H((HANDLE)osfhandle);
-    if (H == StdOutHandle.Handle) return STDOUT_FILENO;
-    if (H == StdErrHandle.Handle) return STDERR_FILENO;
-    return (int)(intptr_t)H.Handle;
-  }
-  __override intptr_t get_osfhandle(int fd) throw() {
-    return (intptr_t)HandleFromFD(fd);
-  }
-  __override int close(int fd) throw() {
-    return 0;
-  }
-  __override long lseek(int fd, long offset, int origin) throw() {
-    CComPtr<IStream> stream;
-    GetStreamForFD(fd, &stream);
-    if (stream == nullptr) {
-      errno = EBADF;
-      return -1;
-    }
-
-    LARGE_INTEGER li;
-    li.LowPart = offset;
-    li.HighPart = 0;
-    ULARGE_INTEGER newOffset;
-    HRESULT hr = stream->Seek(li, origin, &newOffset);
-    if (FAILED(hr)) {
-      errno = EINVAL;
-      return -1;
-    }
-
-    return newOffset.LowPart;
-  }
-  __override int setmode(int fd, int mode) throw() {
-    return 0;
-  }
-  __override errno_t resize_file(_In_ LPCWSTR path, uint64_t size) throw() {
-    return 0;
-  }
-  __override int Read(int fd, _Out_bytecap_(count) void* buffer, unsigned int count) throw() {
-    CComPtr<IStream> stream;
-    GetStreamForFD(fd, &stream);
-    if (stream == nullptr) {
-      errno = EBADF;
-      return -1;
-    }
-
-    ULONG cbRead;
-    HRESULT hr = stream->Read(buffer, count, &cbRead);
-    if (FAILED(hr)) {
-      errno = EIO;
-      return -1;
-    }
-
-    return (int)cbRead;
-  }
-  __override int Write(int fd, _In_bytecount_(count) const void* buffer, unsigned int count) throw() {
-    CComPtr<IStream> stream;
-    GetStreamForFD(fd, &stream);
-    if (stream == nullptr) {
-      errno = EBADF;
-      return -1;
-    }
-
-#ifdef _DEBUG
-    if (fd == STDERR_FILENO) {
-        char* copyWithNull = new char[count+1];
-        strncpy(copyWithNull, (char*)buffer, count);
-        copyWithNull[count] = '\0';
-        OutputDebugStringA(copyWithNull);
-        delete[] copyWithNull;
-    }
-#endif
-
-    ULONG written;
-    HRESULT hr = stream->Write(buffer, count, &written);
-    if (FAILED(hr)) {
-      errno = EIO;
-      return -1;
-    }
-
-    return (int)written;
-  }
-};
-
-static HRESULT
-CreateDxcArgsFileSystem(_In_ IDxcBlob *pSource, _In_ LPCWSTR pSourceName,
-                        _In_opt_ IDxcIncludeHandler *pIncludeHandler,
-                        _Outptr_ DxcArgsFileSystem **ppResult) throw() {
-  *ppResult = new (std::nothrow) DxcArgsFileSystem(pSource, pSourceName, pIncludeHandler);
-  if (*ppResult == nullptr) {
-    return E_OUTOFMEMORY;
-  }
-  return S_OK;
-}
-
 static void CreateOperationResultFromOutputs(
 static void CreateOperationResultFromOutputs(
-    IDxcBlob *pResultBlob, DxcArgsFileSystem *msfPtr,
+    IDxcBlob *pResultBlob, dxcutil::DxcArgsFileSystem *msfPtr,
     const std::string &warnings, clang::DiagnosticsEngine &diags,
     const std::string &warnings, clang::DiagnosticsEngine &diags,
     _COM_Outptr_ IDxcOperationResult **ppResult) {
     _COM_Outptr_ IDxcOperationResult **ppResult) {
   CComPtr<IStream> pErrorStream;
   CComPtr<IStream> pErrorStream;
   CComPtr<IDxcBlobEncoding> pErrorBlob;
   CComPtr<IDxcBlobEncoding> pErrorBlob;
-  msfPtr->GetStreamForHandle(StdOutHandle.Handle, &pErrorStream);
-
+  msfPtr->GetStdOutpuHandleStream(&pErrorStream);
   dxcutil::CreateOperationResultFromOutputs(pResultBlob, pErrorStream, warnings,
   dxcutil::CreateOperationResultFromOutputs(pResultBlob, pErrorStream, warnings,
                                             diags.hasErrorOccurred(), ppResult);
                                             diags.hasErrorOccurred(), ppResult);
 }
 }
 
 
 static void CreateOperationResultFromOutputs(
 static void CreateOperationResultFromOutputs(
-    AbstractMemoryStream *pOutputStream, DxcArgsFileSystem *msfPtr,
+    AbstractMemoryStream *pOutputStream, dxcutil::DxcArgsFileSystem *msfPtr,
     const std::string &warnings, clang::DiagnosticsEngine &diags,
     const std::string &warnings, clang::DiagnosticsEngine &diags,
     _COM_Outptr_ IDxcOperationResult **ppResult) {
     _COM_Outptr_ IDxcOperationResult **ppResult) {
   CComPtr<IDxcBlob> pResultBlob;
   CComPtr<IDxcBlob> pResultBlob;
@@ -1024,8 +316,8 @@ public:
     try {
     try {
       CComPtr<IMalloc> pMalloc;
       CComPtr<IMalloc> pMalloc;
       CComPtr<IDxcBlob> pOutputBlob;
       CComPtr<IDxcBlob> pOutputBlob;
-      DxcArgsFileSystem *msfPtr;
-      IFT(CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler, &msfPtr));
+      dxcutil::DxcArgsFileSystem *msfPtr;
+      IFT(dxcutil::CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler, &msfPtr));
       std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
       std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
 
 
       ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
       ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
@@ -1301,8 +593,8 @@ public:
     try {
     try {
       CComPtr<IMalloc> pMalloc;
       CComPtr<IMalloc> pMalloc;
       CComPtr<AbstractMemoryStream> pOutputStream;
       CComPtr<AbstractMemoryStream> pOutputStream;
-      DxcArgsFileSystem *msfPtr;
-      IFT(CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler, &msfPtr));
+      dxcutil::DxcArgsFileSystem *msfPtr;
+      IFT(dxcutil::CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler, &msfPtr));
       std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
       std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
 
 
       ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
       ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
@@ -1472,7 +764,7 @@ public:
     for (const llvm::opt::Arg *A : Opts.Args.filtered(options::OPT_I)) {
     for (const llvm::opt::Arg *A : Opts.Args.filtered(options::OPT_I)) {
       const bool IsFrameworkFalse = false;
       const bool IsFrameworkFalse = false;
       const bool IgnoreSysRoot = true;
       const bool IgnoreSysRoot = true;
-      if (IsAbsoluteOrCurDirRelative(A->getValue())) {
+      if (dxcutil::IsAbsoluteOrCurDirRelative(A->getValue())) {
         HSOpts.AddPath(A->getValue(), frontend::Angled, IsFrameworkFalse, IgnoreSysRoot);
         HSOpts.AddPath(A->getValue(), frontend::Angled, IsFrameworkFalse, IgnoreSysRoot);
       }
       }
       else {
       else {

+ 16 - 0
tools/clang/tools/dxcompiler/dxcutil.cpp

@@ -24,6 +24,8 @@
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "llvm/Transforms/Utils/Cloning.h"
 #include "dxc/Support/dxcapi.impl.h"
 #include "dxc/Support/dxcapi.impl.h"
 
 
+#include "llvm/Support/Path.h"
+
 using namespace llvm;
 using namespace llvm;
 using namespace hlsl;
 using namespace hlsl;
 
 
@@ -196,4 +198,18 @@ void CreateOperationResultFromOutputs(
                                                       status, ppResult));
                                                       status, ppResult));
 }
 }
 
 
+bool IsAbsoluteOrCurDirRelative(const Twine &T) {
+  if (llvm::sys::path::is_absolute(T)) {
+    return true;
+  }
+  if (T.isSingleStringRef()) {
+    StringRef r = T.getSingleStringRef();
+    if (r.size() < 2) return false;
+    const char *pData = r.data();
+    return pData[0] == '.' && (pData[1] == '\\' || pData[1] == '/');
+  }
+  DXASSERT(false, "twine kind not supported");
+  return false;
+}
+
 } // namespace dxcutil
 } // namespace dxcutil

+ 6 - 1
tools/clang/tools/dxcompiler/dxcutil.h

@@ -23,13 +23,15 @@ class DiagnosticsEngine;
 namespace llvm {
 namespace llvm {
 class Module;
 class Module;
 class raw_string_ostream;
 class raw_string_ostream;
-}
+class Twine;
+} // namespace llvm
 
 
 namespace hlsl {
 namespace hlsl {
 enum class SerializeDxilFlags : uint32_t;
 enum class SerializeDxilFlags : uint32_t;
 class AbstractMemoryStream;
 class AbstractMemoryStream;
 }
 }
 
 
+
 namespace dxcutil {
 namespace dxcutil {
 HRESULT ValidateAndAssembleToContainer(
 HRESULT ValidateAndAssembleToContainer(
     std::unique_ptr<llvm::Module> pM, CComPtr<IDxcBlob> &pOutputContainerBlob,
     std::unique_ptr<llvm::Module> pM, CComPtr<IDxcBlob> &pOutputContainerBlob,
@@ -48,4 +50,7 @@ void CreateOperationResultFromOutputs(
     IDxcBlob *pResultBlob, CComPtr<IStream> &pErrorStream,
     IDxcBlob *pResultBlob, CComPtr<IStream> &pErrorStream,
     const std::string &warnings, bool hasErrorOccurred,
     const std::string &warnings, bool hasErrorOccurred,
     _COM_Outptr_ IDxcOperationResult **ppResult);
     _COM_Outptr_ IDxcOperationResult **ppResult);
+
+bool IsAbsoluteOrCurDirRelative(const llvm::Twine &T);
+
 } // namespace dxcutil
 } // namespace dxcutil

+ 61 - 6
tools/clang/tools/libclang/dxcrewriteunused.cpp

@@ -40,6 +40,7 @@
 #include "dxc/dxctools.h"
 #include "dxc/dxctools.h"
 #include "dxc/Support/dxcapi.impl.h"
 #include "dxc/Support/dxcapi.impl.h"
 #include "dxc/Support/DxcLangExtensionsHelper.h"
 #include "dxc/Support/DxcLangExtensionsHelper.h"
+#include "dxc/Support/dxcfilesystem.h"
 
 
 #define CP_UTF16 1200
 #define CP_UTF16 1200
 
 
@@ -117,6 +118,8 @@ void SetupCompilerForRewrite(CompilerInstance &compiler,
   compiler.createFileManager();
   compiler.createFileManager();
   compiler.createSourceManager(compiler.getFileManager());
   compiler.createSourceManager(compiler.getFileManager());
   compiler.setTarget(TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), targetOptions));
   compiler.setTarget(TargetInfo::CreateTargetInfo(compiler.getDiagnostics(), targetOptions));
+  // Not use builtin includes.
+  compiler.getHeaderSearchOpts().UseBuiltinIncludes = false;
 
 
   PreprocessorOptions &PPOpts = compiler.getPreprocessorOpts();
   PreprocessorOptions &PPOpts = compiler.getPreprocessorOpts();
   if (rewrite != nullptr) {
   if (rewrite != nullptr) {
@@ -349,10 +352,11 @@ HRESULT DoRewriteUnused(_In_ DxcLangExtensionsHelper *pHelper,
 }
 }
 
 
 static
 static
-HRESULT DoUnparse(_In_ DxcLangExtensionsHelper *pHelper,
+HRESULT DoSimpleReWrite(_In_ DxcLangExtensionsHelper *pHelper,
                _In_ LPCSTR pFileName,
                _In_ LPCSTR pFileName,
                _In_ ASTUnit::RemappedFile *pRemap,
                _In_ ASTUnit::RemappedFile *pRemap,
                _In_ LPCSTR pDefines,
                _In_ LPCSTR pDefines,
+               _In_ bool bSkipFunctionBody,
                _Outptr_result_z_ LPSTR *pWarnings,
                _Outptr_result_z_ LPSTR *pWarnings,
                _Outptr_result_z_ LPSTR *pResult) {
                _Outptr_result_z_ LPSTR *pResult) {
   if (pWarnings != nullptr) *pWarnings = nullptr;
   if (pWarnings != nullptr) *pWarnings = nullptr;
@@ -370,7 +374,7 @@ HRESULT DoUnparse(_In_ DxcLangExtensionsHelper *pHelper,
 
 
   // Parse the source file.
   // Parse the source file.
   compiler.getDiagnosticClient().BeginSourceFile(compiler.getLangOpts(), &compiler.getPreprocessor());
   compiler.getDiagnosticClient().BeginSourceFile(compiler.getLangOpts(), &compiler.getPreprocessor());
-  ParseAST(compiler.getSema(), false, false);
+  ParseAST(compiler.getSema(), false, bSkipFunctionBody);
 
 
   ASTContext& C = compiler.getASTContext();
   ASTContext& C = compiler.getASTContext();
   TranslationUnitDecl *tu = C.getTranslationUnitDecl();
   TranslationUnitDecl *tu = C.getTranslationUnitDecl();
@@ -422,7 +426,7 @@ public:
     LPCSTR fakeName = "input.hlsl";
     LPCSTR fakeName = "input.hlsl";
 
 
     try {
     try {
-      ::llvm::sys::fs::MSFileSystem *msfPtr;
+      ::llvm::sys::fs::MSFileSystem* msfPtr;
       IFT(CreateMSFileSystemForDisk(&msfPtr));
       IFT(CreateMSFileSystemForDisk(&msfPtr));
       std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
       std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
 
 
@@ -478,9 +482,60 @@ public:
 
 
       LPSTR errors = nullptr;
       LPSTR errors = nullptr;
       LPSTR rewrite = nullptr;
       LPSTR rewrite = nullptr;
-      HRESULT status = DoUnparse(
-          &m_langExtensionsHelper, fakeName, pRemap.get(),
-          defineCount > 0 ? definesStr.c_str() : nullptr, &errors, &rewrite);
+      HRESULT status =
+          DoSimpleReWrite(&m_langExtensionsHelper, fakeName, pRemap.get(),
+                          defineCount > 0 ? definesStr.c_str() : nullptr,
+                          /*bSkipFunctionBody*/ false, &errors, &rewrite);
+
+      return DxcOperationResult::CreateFromUtf8Strings(errors, rewrite, status,
+                                                       ppResult);
+    }
+    CATCH_CPP_RETURN_HRESULT();
+
+  }
+
+  __override HRESULT STDMETHODCALLTYPE RewriteUnchangedWithInclude(
+      _In_ IDxcBlobEncoding *pSource,
+      // Optional file name for pSource. Used in errors and include handlers.
+      _In_opt_ LPCWSTR pSourceName, _In_count_(defineCount) DxcDefine *pDefines,
+      _In_ UINT32 defineCount,
+      // user-provided interface to handle #include directives (optional)
+      _In_opt_ IDxcIncludeHandler *pIncludeHandler,
+      _In_ UINT32 rewriteOption,
+      _COM_Outptr_ IDxcOperationResult **ppResult) {
+    if (pSource == nullptr || ppResult == nullptr || (defineCount > 0 && pDefines == nullptr))
+      return E_POINTER;
+
+    *ppResult = nullptr;
+
+    CComPtr<IDxcBlobEncoding> utf8Source;
+    IFR(hlsl::DxcGetBlobAsUtf8(pSource, &utf8Source));
+
+    CW2A utf8SourceName(pSourceName, CP_UTF8);
+    LPCSTR fName = utf8SourceName.m_psz;
+
+    try {
+      dxcutil::DxcArgsFileSystem *msfPtr;
+      IFT(dxcutil::CreateDxcArgsFileSystem(utf8Source, pSourceName, pIncludeHandler, &msfPtr));
+      std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
+
+      ::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
+      IFTLLVM(pts.error_code());
+
+      StringRef Data((LPCSTR)utf8Source->GetBufferPointer(), utf8Source->GetBufferSize());
+      std::unique_ptr<llvm::MemoryBuffer> pBuffer(llvm::MemoryBuffer::getMemBufferCopy(Data, fName));
+      std::unique_ptr<ASTUnit::RemappedFile> pRemap(new ASTUnit::RemappedFile(fName, pBuffer.release()));
+
+      std::string definesStr = DefinesToString(pDefines, defineCount);
+
+      LPSTR errors = nullptr;
+      LPSTR rewrite = nullptr;
+      bool bSkipFunctionBody =
+          rewriteOption & RewirterOptionMask::SkipFunctionBody;
+      HRESULT status =
+          DoSimpleReWrite(&m_langExtensionsHelper, fName, pRemap.get(),
+                          defineCount > 0 ? definesStr.c_str() : nullptr,
+                          bSkipFunctionBody, &errors, &rewrite);
 
 
       return DxcOperationResult::CreateFromUtf8Strings(errors, rewrite, status,
       return DxcOperationResult::CreateFromUtf8Strings(errors, rewrite, status,
                                                        ppResult);
                                                        ppResult);

+ 104 - 30
tools/clang/unittests/HLSL/RewriterTest.cpp

@@ -63,7 +63,7 @@ public:
   TEST_METHOD(RunVectorAssignments);
   TEST_METHOD(RunVectorAssignments);
   TEST_METHOD(RunVectorSyntaxMix);
   TEST_METHOD(RunVectorSyntaxMix);
   TEST_METHOD(RunVectorSyntax);
   TEST_METHOD(RunVectorSyntax);
-  //TEST_METHOD(RunIncludes);  // TODO: Includes have not been implemented yet; uncomment when they have
+  TEST_METHOD(RunIncludes);
   TEST_METHOD(RunStructMethods);
   TEST_METHOD(RunStructMethods);
   TEST_METHOD(RunPredefines);
   TEST_METHOD(RunPredefines);
   TEST_METHOD(RunUTF16OneByte);
   TEST_METHOD(RunUTF16OneByte);
@@ -73,8 +73,11 @@ public:
   TEST_METHOD(RunNonUnicode);
   TEST_METHOD(RunNonUnicode);
   TEST_METHOD(RunEffect);
   TEST_METHOD(RunEffect);
   TEST_METHOD(RunSemanticDefines);
   TEST_METHOD(RunSemanticDefines);
+  TEST_METHOD(RunNoFunctionBody);
+  TEST_METHOD(RunNoFunctionBodyInclude);
 
 
   dxc::DxcDllSupport m_dllSupport;
   dxc::DxcDllSupport m_dllSupport;
+  CComPtr<IDxcIncludeHandler> m_pIncludeHandler;
 
 
   struct VerifyResult {
   struct VerifyResult {
     std::string warnings; // warnings from first compilation
     std::string warnings; // warnings from first compilation
@@ -127,6 +130,10 @@ public:
   HRESULT CreateRewriter(IDxcRewriter** pRewriter) {
   HRESULT CreateRewriter(IDxcRewriter** pRewriter) {
     if (!m_dllSupport.IsEnabled()) {
     if (!m_dllSupport.IsEnabled()) {
       VERIFY_SUCCEEDED(m_dllSupport.Initialize());
       VERIFY_SUCCEEDED(m_dllSupport.Initialize());
+
+      CComPtr<IDxcLibrary> library;
+      VERIFY_SUCCEEDED(m_dllSupport.CreateInstance(CLSID_DxcLibrary, &library));
+      VERIFY_SUCCEEDED(library->CreateIncludeHandler(&m_pIncludeHandler));
     }
     }
     return m_dllSupport.CreateInstance(CLSID_DxcRewriter, pRewriter);
     return m_dllSupport.CreateInstance(CLSID_DxcRewriter, pRewriter);
   }
   }
@@ -162,29 +169,7 @@ public:
     }
     }
   };
   };
 
 
-  // Note: Previous versions of this file included a RewriteCompareRewrite method here that rewrote twice and compared  
-  // to check for stable output.  It has now been replaced by a new test that checks against a gold baseline.
-
-  void RewriteCompareGold(LPCWSTR path, LPCWSTR goldPath,
-                          _COM_Outptr_ IDxcOperationResult **ppResult,
-                          _In_ IDxcRewriter *rewriter) {
-    // Get the source text from a file
-    FileWithBlob source(m_dllSupport, path);
-
-    const int myDefinesCount = 3;
-    DxcDefine myDefines[myDefinesCount] = { 
-      { L"myDefine", L"2" }, 
-      { L"myDefine3", L"1994" }, 
-      { L"myDefine4", nullptr }
-    };
-
-    // Run rewrite unchanged on the source code
-    VERIFY_SUCCEEDED(rewriter->RewriteUnchanged(source.BlobEncoding, myDefines, myDefinesCount, ppResult));
-
-    CComPtr<IDxcBlob> pRewriteResult;
-    IFT((*ppResult)->GetResult(&pRewriteResult));
-    std::string firstPass = BlobToUtf8(pRewriteResult);
-
+  bool CompareGold(std::string &firstPass, LPCWSTR goldPath) {
     HANDLE goldHandle = CreateFileW(goldPath, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
     HANDLE goldHandle = CreateFileW(goldPath, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
     VERIFY_ARE_NOT_EQUAL(goldHandle, INVALID_HANDLE_VALUE);
     VERIFY_ARE_NOT_EQUAL(goldHandle, INVALID_HANDLE_VALUE);
     CHandle checkedGoldHandle(goldHandle);
     CHandle checkedGoldHandle(goldHandle);
@@ -211,8 +196,31 @@ public:
       //  }
       //  }
       //  atChar++;
       //  atChar++;
       //}
       //}
-      
-    if (firstPass.compare(gold) == 0) {
+    return firstPass.compare(gold) == 0;
+  }
+
+  // Note: Previous versions of this file included a RewriteCompareRewrite method here that rewrote twice and compared  
+  // to check for stable output.  It has now been replaced by a new test that checks against a gold baseline.
+
+  void RewriteCompareGold(LPCWSTR path, LPCWSTR goldPath,
+                          _COM_Outptr_ IDxcOperationResult **ppResult,
+                          _In_ IDxcRewriter *rewriter) {
+    // Get the source text from a file
+    FileWithBlob source(m_dllSupport, path);
+
+    const int myDefinesCount = 3;
+    DxcDefine myDefines[myDefinesCount] = {
+        {L"myDefine", L"2"}, {L"myDefine3", L"1994"}, {L"myDefine4", nullptr}};
+
+    // Run rewrite unchanged on the source code
+    VERIFY_SUCCEEDED(rewriter->RewriteUnchanged(source.BlobEncoding, myDefines,
+                                                myDefinesCount, ppResult));
+
+    CComPtr<IDxcBlob> pRewriteResult;
+    IFT((*ppResult)->GetResult(&pRewriteResult));
+    std::string firstPass = BlobToUtf8(pRewriteResult);
+
+    if (CompareGold(firstPass, goldPath)) {
       return;
       return;
     }
     }
 
 
@@ -241,6 +249,34 @@ public:
           L"diff " << goldPath << L" " << PrintName << L"\n";
           L"diff " << goldPath << L" " << PrintName << L"\n";
     ::WEX::Logging::Log::Error(ss.str().c_str());
     ::WEX::Logging::Log::Error(ss.str().c_str());
   }
   }
+
+  bool RewriteCompareGoldInclude(LPCWSTR path, LPCWSTR goldPath,
+                                 unsigned rewriteOption) {
+    CComPtr<IDxcRewriter> pRewriter;
+    VERIFY_SUCCEEDED(CreateRewriter(&pRewriter));
+    CComPtr<IDxcOperationResult> pRewriteResult;
+
+    std::wstring fileName = GetPathToHlslDataFile(path);
+
+    // Get the source text from a file
+    FileWithBlob source(m_dllSupport, fileName.c_str());
+
+    const int myDefinesCount = 3;
+    DxcDefine myDefines[myDefinesCount] = {
+        {L"myDefine", L"2"}, {L"myDefine3", L"1994"}, {L"myDefine4", nullptr}};
+
+    // Run rewrite no function body on the source code
+    VERIFY_SUCCEEDED(pRewriter->RewriteUnchangedWithInclude(
+        source.BlobEncoding, fileName.c_str(), myDefines, myDefinesCount,
+        m_pIncludeHandler, rewriteOption, &pRewriteResult));
+
+    CComPtr<IDxcBlob> result;
+    VERIFY_SUCCEEDED(pRewriteResult->GetResult(&result));
+
+    std::string rewriteText = BlobToUtf8(result);
+
+    return CompareGold(rewriteText, GetPathToHlslDataFile(goldPath).c_str());
+  }
 };
 };
 
 
 TEST_F(RewriterTest, RunAttributes) {
 TEST_F(RewriterTest, RunAttributes) {
@@ -303,10 +339,19 @@ TEST_F(RewriterTest, RunVectorSyntax) {
     CheckVerifiesHLSL(L"rewriter\\vector-syntax_noerr.hlsl", L"rewriter\\correct_rewrites\\vector-syntax_gold.hlsl");
     CheckVerifiesHLSL(L"rewriter\\vector-syntax_noerr.hlsl", L"rewriter\\correct_rewrites\\vector-syntax_gold.hlsl");
 }
 }
 
 
-// TODO: Includes have not been implemented yet; uncomment when they have
-//TEST_F(RewriterTest, RunIncludes) {
-//  CheckVerifiesHLSL(L"rewriter\\includes.hlsl", L"rewriter\\correct_rewrites\\includes_gold.hlsl");
-//}
+TEST_F(RewriterTest, RunIncludes) {
+  VERIFY_IS_TRUE(RewriteCompareGoldInclude(
+      L"rewriter\\includes.hlsl",
+      L"rewriter\\correct_rewrites\\includes_gold.hlsl",
+      RewirterOptionMask::Default));
+}
+
+TEST_F(RewriterTest, RunNoFunctionBodyInclude) {
+  VERIFY_IS_TRUE(RewriteCompareGoldInclude(
+      L"rewriter\\includes.hlsl",
+      L"rewriter\\correct_rewrites\\includes_gold_nobody.hlsl",
+      RewirterOptionMask::SkipFunctionBody));
+}
 
 
 TEST_F(RewriterTest, RunStructMethods) {
 TEST_F(RewriterTest, RunStructMethods) {
   CheckVerifiesHLSL(L"rewriter\\struct-methods.hlsl", L"rewriter\\correct_rewrites\\struct-methods_gold.hlsl");
   CheckVerifiesHLSL(L"rewriter\\struct-methods.hlsl", L"rewriter\\correct_rewrites\\struct-methods_gold.hlsl");
@@ -418,3 +463,32 @@ TEST_F(RewriterTest, RunSemanticDefines) {
   CheckVerifies(pRewriter, hlsl_test::GetPathToHlslDataFile(L"rewriter\\semantic-defines.hlsl").c_str(),
   CheckVerifies(pRewriter, hlsl_test::GetPathToHlslDataFile(L"rewriter\\semantic-defines.hlsl").c_str(),
                            hlsl_test::GetPathToHlslDataFile(L"rewriter\\correct_rewrites\\semantic-defines_gold.hlsl").c_str());
                            hlsl_test::GetPathToHlslDataFile(L"rewriter\\correct_rewrites\\semantic-defines_gold.hlsl").c_str());
 }
 }
+
+TEST_F(RewriterTest, RunNoFunctionBody) {
+  CComPtr<IDxcRewriter> pRewriter;
+  VERIFY_SUCCEEDED(CreateRewriter(&pRewriter));
+  CComPtr<IDxcOperationResult> pRewriteResult;
+
+  // Get the source text from a file
+  FileWithBlob source(
+      m_dllSupport,
+      GetPathToHlslDataFile(L"rewriter\\vector-assignments_noerr.hlsl")
+          .c_str());
+
+  const int myDefinesCount = 3;
+  DxcDefine myDefines[myDefinesCount] = {
+      {L"myDefine", L"2"}, {L"myDefine3", L"1994"}, {L"myDefine4", nullptr}};
+
+  // Run rewrite no function body on the source code
+  VERIFY_SUCCEEDED(pRewriter->RewriteUnchangedWithInclude(
+      source.BlobEncoding, L"vector-assignments_noerr.hlsl", myDefines,
+      myDefinesCount, /*pIncludeHandler*/ nullptr, RewirterOptionMask::SkipFunctionBody,
+      &pRewriteResult));
+
+  CComPtr<IDxcBlob> result;
+  VERIFY_SUCCEEDED(pRewriteResult->GetResult(&result));
+  // Function decl only.
+  VERIFY_IS_TRUE(strcmp(BlobToUtf8(result).c_str(),
+                        "// Rewrite unchanged result:\nfloat pick_one(float2 "
+                        "f2);\nvoid main();\n") == 0);
+}