Fix eglibc remapping and revive the test for its completeness. (#4896)
[mono-project.git] / tools / checker / MonoChecker.cs
blobda70e70a5c7ed7c849497d068d1039d3cda623c1
1 using System;
2 using System.Collections.Generic;
3 using System.IO;
4 using System.Linq;
5 using System.Text.RegularExpressions;
6 using CppSharp.AST;
7 using CppSharp.AST.Extensions;
8 using CppSharp.Parser;
9 using Newtonsoft.Json;
11 namespace CppSharp
13 /**
14 * This tool reads the AST of a Mono source checkout.
16 static class MonoChecker
18 static string CompilationDatabasePath = @"";
20 public static void Main(string[] args)
22 ParseCommandLineArgs(args);
24 Console.WriteLine();
25 Console.WriteLine("Parsing Mono's source code...");
27 var options = new DriverOptions();
29 var log = new TextDiagnosticPrinter();
30 var driver = new Driver(options, log);
32 Setup(driver);
33 driver.Setup();
35 BuildParseOptions(driver);
36 if (!driver.ParseCode())
37 return;
39 Check(driver.ASTContext);
42 static void ParseCommandLineArgs(string[] args)
44 var needsArgs = string.IsNullOrWhiteSpace(CompilationDatabasePath);
46 if (!needsArgs)
47 return;
49 if (args.Length >= 1)
50 CompilationDatabasePath = Path.GetFullPath(args[0]);
51 else
52 CompilationDatabasePath = "compile_commands.json";
54 if (!File.Exists(CompilationDatabasePath)) {
55 Console.WriteLine("Could not find JSON compilation database '{0}'",
56 CompilationDatabasePath);
57 Environment.Exit(0);
61 static string GetXcodeToolchainPath()
63 var toolchains = Directory.EnumerateDirectories("/Applications", "Xcode*")
64 .ToList();
65 toolchains.Sort();
67 var toolchainPath = toolchains.LastOrDefault();
68 if (toolchainPath == null)
69 throw new Exception("Could not find a valid Xcode SDK");
71 return toolchainPath;
74 static string GetXcodeBuiltinIncludesFolder()
76 var toolchainPath = GetXcodeToolchainPath();
78 var toolchains = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
79 "Contents/Developer/Toolchains")).ToList();
80 toolchains.Sort();
82 toolchainPath = toolchains.LastOrDefault();
83 if (toolchainPath == null)
84 throw new Exception("Could not find a valid Xcode toolchain");
86 var includePaths = Directory.EnumerateDirectories(Path.Combine(toolchainPath,
87 "usr/lib/clang")).ToList();
88 var includePath = includePaths.LastOrDefault();
90 if (includePath == null)
91 throw new Exception("Could not find a valid Clang include folder");
93 return Path.Combine(includePath, "include");
96 static void SetupXcode(Driver driver)
98 var options = driver.Options;
100 var builtinsPath = GetXcodeBuiltinIncludesFolder();
101 options.addSystemIncludeDirs(builtinsPath);
103 var includePath = "/usr/include";
104 options.addSystemIncludeDirs(includePath);
106 options.NoBuiltinIncludes = true;
107 options.NoStandardIncludes = true;
110 static void Setup(Driver driver)
112 var options = driver.Options;
113 options.DryRun = true;
114 options.Verbose = false;
115 options.LibraryName = "Mono";
116 options.MicrosoftMode = false;
117 options.addArguments("-xc");
118 options.addArguments("-std=gnu99");
120 SetupXcode(driver);
123 struct CompileUnit
125 public string directory;
126 public string command;
127 public string file;
130 static List<CompileUnit> CleanCompileUnits(List<CompileUnit> database)
132 // The compilation database we get from Bear has duplicated entries
133 // for the same files, so clean it up before passing it down to
134 // further processing.
135 var units = new List<CompileUnit>();
137 foreach (var unit in database) {
138 // Ignore compile units compiled with PIC (Position-independent code)
139 if (unit.command.EndsWith("-fPIC -DPIC"))
140 continue;
142 // Ignore compile units that are compiled with gcc since in OSX
143 // it's a wrapper for the real compiler (clang) for which there'll
144 // be another entry.
145 if (unit.command.Contains("gcc"))
146 continue;
148 // Ignore the static runtime build.
149 if (unit.command.Contains("_static_la"))
150 continue;
152 // Ignore the Boehm runtime build.
153 if (unit.command.Contains("libmonoruntime_la"))
154 continue;
156 units.Add(unit);
159 return units;
162 static void BuildParseOptions(Driver driver)
164 var json = File.ReadAllText(CompilationDatabasePath);
165 var compileUnits = JsonConvert.DeserializeObject<List<CompileUnit>>(json);
167 compileUnits = CleanCompileUnits(compileUnits);
168 compileUnits = compileUnits.OrderBy(unit => unit.file).ToList();
170 foreach (var unit in compileUnits) {
171 var source = driver.Project.AddFile(unit.file);
172 source.Options = driver.BuildParseOptions(source);
174 var args = unit.command.Split(new char[] {' '}).Skip(1);
175 foreach (var arg in args) {
176 // Skip some arguments that Clang complains about...
177 var arguments = new List<string> {
178 "-no-cpp-precomp",
179 "-Qunused-arguments",
180 "-fno-strict-aliasing",
181 "-Qunused-arguments",
182 "-MD",
183 "-MF",
184 "-c"
187 if (arguments.Contains(arg))
188 continue;
190 source.Options.addArguments(arg);
195 static void Check(ASTContext context)
197 // TODO: Implement checking here