public void BasicWrapper(string name) { // Create a unique directory var dir = Path.GetRandomFileName(); _ = Directory.CreateDirectory(dir); try { // Create a file with the right name var file = new FileInfo(Path.Combine(dir, name + ".c")); File.WriteAllText(file.FullName, "int main() { return 0; }"); var index = CXIndex.Create(); var translationUnit = CXTranslationUnit.Parse(index, file.FullName, Array.Empty <string>(), Array.Empty <CXUnsavedFile>(), CXTranslationUnit_Flags.CXTranslationUnit_None); var clangFile = translationUnit.GetFile(file.FullName); var clangFileName = clangFile.Name; var clangFileNameString = clangFileName.CString; Assert.Equal(file.FullName, clangFileNameString); } finally { Directory.Delete(dir, true); } }
public void Parse() { s_Root = new Node(); CXIndex index = clang.createIndex(0, 0); string[] arr = { "-std=c++17", "-ast-dump" }; // -ast-dump // OnlyLocalDecls CXUnsavedFile unsavedFile; CXTranslationUnit translationUnit; // TODO: grab errors and warnings //var translationUnitError = clang.parseTranslationUnit2(index, "C:\\Users\\Alex\\source\\repos\\clang_test\\clang_test\\test.cpp", arr, 2, out unsavedFile, 0, 0, out translationUnit); var translationUnitError = clang.parseTranslationUnit2(index, m_url, arr, 2, out unsavedFile, 0, 0, out translationUnit); if (translationUnitError != CXErrorCode.CXError_Success) { Console.WriteLine("Error: " + translationUnitError); var numDiagnostics = clang.getNumDiagnostics(translationUnit); for (uint i = 0; i < numDiagnostics; ++i) { var diagnostic = clang.getDiagnostic(translationUnit, i); Console.WriteLine(clang.getDiagnosticSpelling(diagnostic).ToString()); clang.disposeDiagnostic(diagnostic); } } else { traverse(translationUnit); clang.disposeTranslationUnit(translationUnit); } clang.disposeIndex(index); }
protected static TranslationUnit CreateTranslationUnit(string inputContents) { Assert.True(File.Exists(DefaultInputFileName)); using var unsavedFile = CXUnsavedFile.Create(DefaultInputFileName, inputContents); var unsavedFiles = new CXUnsavedFile[] { unsavedFile }; var index = CXIndex.Create(); var translationUnit = CXTranslationUnit.Parse(index, DefaultInputFileName, DefaultClangCommandLineArgs, unsavedFiles, DefaultTranslationUnitFlags); if (translationUnit.NumDiagnostics != 0) { var errorDiagnostics = new StringBuilder(); _ = errorDiagnostics.AppendLine($"The provided {nameof(CXTranslationUnit)} has the following diagnostics which prevent its use:"); var invalidTranslationUnitHandle = false; for (uint i = 0; i < translationUnit.NumDiagnostics; ++i) { using var diagnostic = translationUnit.GetDiagnostic(i); if (diagnostic.Severity is CXDiagnosticSeverity.CXDiagnostic_Error or CXDiagnosticSeverity.CXDiagnostic_Fatal) { invalidTranslationUnitHandle = true; _ = errorDiagnostics.Append(' ', 4); _ = errorDiagnostics.AppendLine(diagnostic.Format(CXDiagnosticDisplayOptions.CXDiagnostic_DisplayOption).ToString()); } } Assert.False(invalidTranslationUnitHandle, errorDiagnostics.ToString()); } return(TranslationUnit.GetOrCreate(translationUnit)); }
private static bool TryParseTranslationUnit( string filePath, ImmutableArray <string> commandLineArgs, out CXTranslationUnit translationUnit) { // ReSharper disable BitwiseOperatorOnEnumWithoutFlags var flags = CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes | CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes | CXTranslationUnit_Flags.CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles | CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; var index = CXIndex.Create(); var errorCode = CXTranslationUnit.TryParse( index, filePath, commandLineArgs.AsSpan(), Array.Empty <CXUnsavedFile>(), flags, out translationUnit); if (errorCode == CXErrorCode.CXError_Success) { return(translationUnit != null); } translationUnit = null !; return(false); }
public ClangWrapper(string filePath, CXIndex index, CXTranslationUnit translationUnit, CXCursor cursor) { FilePath = filePath; Index = index; TranslationUnit = translationUnit; Cursor = cursor; }
internal static extern ErrorCode clang_parseTranslationUnit2FullArgv(CXIndex index, string source_filename, [MarshalAs(UnmanagedType.LPArray)] string[] command_line_args, int num_command_line_args, [MarshalAs(UnmanagedType.LPArray)] CXUnsavedFile[] unsaved_files, uint num_unsaved_files, TranslationUnitFlags options, out CXTranslationUnit out_tu);
public static extern CXErrorCode parseTranslationUnit2(CXIndex @CIdx, [MarshalAs(UnmanagedType.LPStr)] string @source_filename, string[] @command_line_args, int @num_command_line_args, [MarshalAs(UnmanagedType.LPArray)] CXUnsavedFile[] @unsaved_files, uint @num_unsaved_files, uint @options, out CXTranslationUnit @out_TU);
public ParseClang(DeepEnds.Core.Parser parser, TextWriter logger) { this.parser = parser; this.logger = logger; this.createIndex = clang.createIndex(0, 0); this.leaves = new Dictionary <string, DeepEnds.Core.Dependency>(); this.links = new Dictionary <DeepEnds.Core.Dependency, HashSet <string> >(); }
/// <summary> /// Constructor /// </summary> /// <param name="proj"> /// A <see cref="CProject"/> reference: project which the manager manages /// </param> public CLangManager(CProject proj) { project = proj; index = clang.createIndex(0, 0); SerManager = new SerializationManager(project, this, index); translationUnits = new Dictionary <string, CXTranslationUnit> (); Loaded = new Dictionary <string, bool> (); project.DefaultConfigurationChanged += HandleDefaultConfigurationChange; project.FileAddedToProject += HandleAddition; project.FileChangedInProject += HandleChange; project.FileRemovedFromProject += HandleRemoval; project.FileRenamedInProject += HandleRename; }
/// <inheritDoc /> public BIR.BIR Produce(Configuration config) { using (var index = CXIndex.Create()) { using (var tu = BuildClangAST(config, index)) { if (tu != null) { return(TransformClangASTtoBIR(config, index, tu)); } } } return(null); }
/// <summary> /// Transform the Clang AST to BIR /// </summary> private BIR.BIR TransformClangASTtoBIR(Configuration config, CXIndex index, TranslationUnit tu) { BIR.BIR bir = null; using (var section = CreateSection("Transforming Clang AST to BIR")) { using (var parser = new ClangParser(Context, index, tu)) { bir = parser.ProduceBIR(config); } if (bir != null) { section.Done(); } } return(bir); }
public AST ParseWithClangArgs(CppConfig config) { if (config.Sources.Count == 0) { Console.WriteLine("No input sources or includes"); return(null); } // the index object CXIndex Index = clang.createIndex(0, 0); // prepare some vars for parse uint option = clang.defaultEditingTranslationUnitOptions() | (uint)CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; CXUnsavedFile unsavedFile = new CXUnsavedFile(); CXTranslationUnit TU; var error = clang.parseTranslationUnit2(Index, config.Sources[0], config.Extras, config.Extras.Length, out unsavedFile, 0, option, out TU); if (error != CXErrorCode.CXError_Success) { Console.WriteLine("Failed to parse Translation Unit!"); return(null); } bool fatal = false; var numDiagnostics = clang.getNumDiagnostics(TU); for (uint loop = 0; loop < numDiagnostics; ++loop) { fatal |= DealingWithDiagnostic(clang.getDiagnostic(TU, loop)); } if (fatal) { return(null); } ASTVisitor visitor = new ASTVisitor(); AST ast = visitor.Visit(TU); clang.disposeIndex(Index); return(ast); }
public void AugmentSignatureHelpSession(ISignatureHelpSession session, IList <ISignature> signatures) { ThreadHelper.ThrowIfNotOnUIThread(); var snapshot = _textBuffer.CurrentSnapshot; var triggerPoint = session.GetTriggerPoint(_textBuffer); var snapshotPoint = triggerPoint.GetPoint(snapshot); var position = triggerPoint.GetPosition(snapshot); var applicableToSpan = _textBuffer.CurrentSnapshot.CreateTrackingSpan(new Span(position, 0), SpanTrackingMode.EdgeInclusive, TrackingFidelityMode.Forward); // Parse the entire document into an AST var index = CXIndex.Create(false, false); if ((_dte.ActiveDocument, snapshot).TryParseDocument(index, out var translationUnit, out _)) { var visitor = new EmplacingVisitor(_dte.ActiveDocument.FullName, snapshotPoint.GetContainingLine().LineNumber); visitor.CtorFound += (templateParameters, parameters) => { // TODO: eliminate this stupid back-and-forth string handling var signatureBuilder = new StringBuilder("emplace"); signatureBuilder.Append('('); foreach (var parameter in parameters) { signatureBuilder.Append(parameter.Type).Append(' ').Append(parameter.Name).Append(", "); } if (parameters.Count > 0) { signatureBuilder.Length -= 2; } signatureBuilder.Append(')'); signatures.Add(CreateSignature(_textBuffer, signatureBuilder.ToString(), applicableToSpan)); }; visitor.Visit(translationUnit); } }
public SerializationManager(CProject proj, CLangManager man, CXIndex ind) { Manager = man; project = proj; Index = ind; }
/// <summary> /// Build the Clang AST /// </summary> private TranslationUnit BuildClangAST(Configuration config, CXIndex index) { CXTranslationUnit tu = null; using (var section = CreateSection("Building Clang AST")) { // Assemble the arguments var clangArgs = new List <string>() { "-Wno-pragma-once-outside-header" }; switch (config.Clang.Language) { case LanguageEnum.C99: clangArgs.Add("-xc"); clangArgs.Add("-std=c99"); break; case LanguageEnum.Cpp11: clangArgs.Add("-xc++"); clangArgs.Add("-std=c++11"); break; case LanguageEnum.Cpp14: clangArgs.Add("-xc++"); clangArgs.Add("-std=c++14"); break; case LanguageEnum.Cpp17: clangArgs.Add("-xc++"); clangArgs.Add("-std=c++17"); break; default: throw new Exception($"unknown language {config.Clang.Language}"); } clangArgs.AddRange(GetWinSDKDIncludeArgs(config)); clangArgs.AddRange(GetCxxSTLIncludeArgs(config)); clangArgs.AddRange(config.Clang.Includes.Select(i => MakeIncludeArg(i))); clangArgs.AddRange(config.Clang.Defines.Select((m, v) => $"-D{m}=\"{v}\"")); clangArgs.AddRange(config.Clang.Arguments.Split(" ")); var tuFlags = CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; // Create the TU source file var sourceFiles = new HashSet <string>(); config.Hook.Descriptions.Values.ToList().ForEach(hook => hook.Input.ForEach(source => sourceFiles.Add(source))); var tuFilename = Path.GetFileNameWithoutExtension(string.IsNullOrEmpty(config.Plugin.Name) ? Path.GetTempFileName() : config.Plugin.Name) + ".cpp"; Logger.Debug($"Clang TU filename: {tuFilename}"); var tuSource = "#include <" + string.Join(">\n#include <", sourceFiles) + ">"; Logger.Debug($"Clang TU source:\n {tuSource.Replace("\n", "\n ")}"); using (var tuSourceFile = CXUnsavedFile.Create(tuFilename, tuSource)) { // Invoke clang to get the TU Logger.Debug($"Clang args: {string.Join(" ", clangArgs)}"); var tuError = CXTranslationUnit.TryParse(index, tuSourceFile.FilenameString, clangArgs.ToArray(), new CXUnsavedFile[] { tuSourceFile }, tuFlags, out tu); if (tuError != CXErrorCode.CXError_Success) { throw new Exception($"clang error: failed to generate tanslation unit: {tuError}"); } } section.Done(); } if (tu == null) { return(null); } return(TranslationUnit.GetOrCreate(tu)); }
internal static extern CXIndexAction clang_IndexAction_create(CXIndex index);
internal static extern void clang_disposeIndex(CXIndex index);
internal static extern CXTranslationUnit clang_createTranslationUnit(CXIndex index, string ast_filename);
/// <summary> /// Private method parsing file or content. /// </summary> /// <param name="cppFiles">A list of path to C/C++ header files on the disk to parse</param> /// <param name="options">Options used for parsing this file (e.g include folders...)</param> /// <returns>The result of the compilation</returns> private static unsafe CppCompilation ParseInternal(List <CppFileOrString> cppFiles, CppParserOptions options = null) { if (cppFiles == null) { throw new ArgumentNullException(nameof(cppFiles)); } options = options ?? new CppParserOptions(); var arguments = new List <string>(); // Make sure that paths are absolute var normalizedIncludePaths = new List <string>(); normalizedIncludePaths.AddRange(options.IncludeFolders.Select(x => Path.Combine(Environment.CurrentDirectory, x))); var normalizedSystemIncludePaths = new List <string>(); normalizedSystemIncludePaths.AddRange(options.SystemIncludeFolders.Select(x => Path.Combine(Environment.CurrentDirectory, x))); arguments.AddRange(options.AdditionalArguments); arguments.AddRange(normalizedIncludePaths.Select(x => $"-I{x}")); arguments.AddRange(normalizedSystemIncludePaths.Select(x => $"-isystem{x}")); arguments.AddRange(options.Defines.Select(x => $"-D{x}")); arguments.Add("-dM"); arguments.Add("-E"); if (options.ParseAsCpp && !arguments.Contains("-xc++")) { arguments.Add("-xc++"); } if (!arguments.Any(x => x.StartsWith("--target="))) { arguments.Add($"--target={GetTripleFromOptions(options)}"); } if (options.ParseComments) { arguments.Add("-fparse-all-comments"); } var translationFlags = CXTranslationUnit_Flags.CXTranslationUnit_None; translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; // Don't traverse function bodies translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes; // Include attributed types in CXType translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes; // Implicit attributes should be visited if (options.ParseMacros) { translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_DetailedPreprocessingRecord; } translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_DetailedPreprocessingRecord; var argumentsArray = arguments.ToArray(); using (var createIndex = CXIndex.Create()) { var builder = new CppModelBuilder { AutoSquashTypedef = options.AutoSquashTypedef, ParseSystemIncludes = options.ParseSystemIncludes, ParseAttributeEnabled = options.ParseAttributes, }; var compilation = builder.RootCompilation; string rootFileName = CppAstRootFileName; string rootFileContent = null; // Creates a fake 'header.hpp' that includes all the files we passed, so they are parsed all at once // Build the root input source file var tempBuilder = new StringBuilder(); if (options.PreHeaderText != null) { tempBuilder.AppendLine(options.PreHeaderText); } foreach (var file in cppFiles) { if (file.Content != null) { tempBuilder.AppendLine(file.Content); } else { var filePath = Path.Combine(Environment.CurrentDirectory, file.Filename); tempBuilder.AppendLine($"#include \"{filePath}\""); } } if (options.PostHeaderText != null) { tempBuilder.AppendLine(options.PostHeaderText); } // TODO: Add debug rootFileContent = tempBuilder.ToString(); var rootFileContentUTF8 = Encoding.UTF8.GetBytes(rootFileContent); compilation.InputText = rootFileContent; fixed(void *rootFileContentUTF8Ptr = rootFileContentUTF8) { CXTranslationUnit translationUnit; var rootFileNameUTF8 = Marshal.StringToHGlobalAnsi(rootFileName); translationUnit = CXTranslationUnit.Parse(createIndex, rootFileName, argumentsArray, new CXUnsavedFile[] { new CXUnsavedFile() { Contents = (sbyte *)rootFileContentUTF8Ptr, Filename = (sbyte *)rootFileNameUTF8, Length = new UIntPtr((uint)rootFileContentUTF8.Length) } }, translationFlags); // Skips the processing of the file if 1 error is raised // We don't want that, so remove that part //bool skipProcessing = false; //if (translationUnit.NumDiagnostics != 0) //{ // for (uint i = 0; i < translationUnit.NumDiagnostics; ++i) // { // using (var diagnostic = translationUnit.GetDiagnostic(i)) // { // var message = GetMessageAndLocation(rootFileContent, diagnostic, out var location); // switch (diagnostic.Severity) // { // case CXDiagnosticSeverity.CXDiagnostic_Ignored: // case CXDiagnosticSeverity.CXDiagnostic_Note: // compilation.Diagnostics.Info(message, location); // break; // case CXDiagnosticSeverity.CXDiagnostic_Warning: // compilation.Diagnostics.Warning(message, location); // break; // case CXDiagnosticSeverity.CXDiagnostic_Error: // case CXDiagnosticSeverity.CXDiagnostic_Fatal: // compilation.Diagnostics.Error(message, location); // skipProcessing = true; // break; // } // } // } //} //if (skipProcessing) //{ // compilation.Diagnostics.Warning($"Compilation aborted due to one or more errors listed above.", new CppSourceLocation(rootFileName, 0, 1, 1)); //} //else //{ using (translationUnit) { translationUnit.Cursor.VisitChildren(builder.VisitTranslationUnit, clientData: default); } //} } return(compilation); } }
internal static extern GlobalOptionFlags clang_CXIndex_getGlobalOptions(CXIndex index);
internal static extern void clang_IndexAction_dispose(CXIndex index);
internal static extern void clang_CXIndex_setGlobalOptions(CXIndex index, GlobalOptionFlags options);
internal static extern CXTranslationUnit clang_createTranslationUnitFromSourceFile(CXIndex index, string sourceFilename, int numClangCommandLineArgs, string[] clangCommandLineArgs, uint numUnsavedFiles, UnsavedFile[] unsavedFiles);
public ClangParser(string root) { Root = root; index = clang.createIndex(0, 0); }
internal static extern CXTranslationUnit clang_createTranslationUnitFromSourceFile(CXIndex index, string source_filename, int num_clang_command_line_args, [MarshalAs(UnmanagedType.LPArray)] string[] clang_command_line_ags, uint num_unsaved_files, [MarshalAs(UnmanagedType.LPArray)] CXUnsavedFile[] unsaved_files);
/// <summary> /// Private method parsing file or content. /// </summary> /// <param name="cppFiles">A list of path to C/C++ header files on the disk to parse</param> /// <param name="options">Options used for parsing this file (e.g include folders...)</param> /// <returns>The result of the compilation</returns> private static CppCompilation ParseInternal(List <CppFileOrString> cppFiles, CppParserOptions options = null) { if (cppFiles == null) { throw new ArgumentNullException(nameof(cppFiles)); } options = options ?? new CppParserOptions(); var arguments = new List <string>(); // Make sure that paths are absolute var normalizedIncludePaths = new List <string>(); normalizedIncludePaths.AddRange(options.IncludeFolders.Select(x => Path.Combine(Environment.CurrentDirectory, x))); var normalizedSystemIncludePaths = new List <string>(); normalizedSystemIncludePaths.AddRange(options.SystemIncludeFolders.Select(x => Path.Combine(Environment.CurrentDirectory, x))); arguments.AddRange(options.AdditionalArguments); arguments.AddRange(normalizedIncludePaths.Select(x => $"-I{x}")); arguments.AddRange(normalizedSystemIncludePaths.Select(x => $"-isystem{x}")); arguments.AddRange(options.Defines.Select(x => $"-D{x}")); if (options.ParseAsCpp && !arguments.Contains("-xc++")) { arguments.Add("-xc++"); } if (!arguments.Any(x => x.StartsWith("--target="))) { arguments.Add($"--target={GetTripleFromOptions(options)}"); } if (options.ParseComments) { arguments.Add("-fparse-all-comments"); } var translationFlags = CXTranslationUnit_Flags.CXTranslationUnit_None; translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; // Don't traverse function bodies translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes; // Include attributed types in CXType translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes; // Implicit attributes should be visited if (options.ParseMacros) { translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_DetailedPreprocessingRecord; } var argumentsArray = arguments.ToArray(); using (var createIndex = CXIndex.Create()) { var builder = new CppModelBuilder { AutoSquashTypedef = options.AutoSquashTypedef }; var compilation = builder.RootCompilation; string rootFileName = CppAstRootFileName; string rootFileContent = null; // Build the root input source file var tempBuilder = new StringBuilder(); if (options.PreHeaderText != null) { tempBuilder.AppendLine(options.PreHeaderText); } foreach (var file in cppFiles) { if (file.Content != null) { tempBuilder.AppendLine(file.Content); } else { var filePath = Path.Combine(Environment.CurrentDirectory, file.Filename); tempBuilder.AppendLine($"#include \"{filePath}\""); } } if (options.PostHeaderText != null) { tempBuilder.AppendLine(options.PostHeaderText); } // TODO: Add debug rootFileContent = tempBuilder.ToString(); compilation.InputText = rootFileContent; { CXTranslationUnit translationUnit; CXErrorCode translationUnitError; translationUnitError = CXTranslationUnit.Parse(createIndex, rootFileName, argumentsArray, new CXUnsavedFile[] { new CXUnsavedFile() { Contents = rootFileContent, Filename = rootFileName, Length = (uint)Encoding.UTF8.GetByteCount(rootFileContent) } }, translationFlags, out translationUnit); bool skipProcessing = false; if (translationUnitError != CXErrorCode.CXError_Success) { compilation.Diagnostics.Error($"Parsing failed due to '{translationUnitError}'", new CppSourceLocation(rootFileName, 0, 1, 1)); skipProcessing = true; } else if (translationUnit.NumDiagnostics != 0) { for (uint i = 0; i < translationUnit.NumDiagnostics; ++i) { using (var diagnostic = translationUnit.GetDiagnostic(i)) { CppSourceLocation location; var message = GetMessageAndLocation(rootFileContent, diagnostic, out location); switch (diagnostic.Severity) { case CXDiagnosticSeverity.CXDiagnostic_Ignored: case CXDiagnosticSeverity.CXDiagnostic_Note: compilation.Diagnostics.Info(message, location); break; case CXDiagnosticSeverity.CXDiagnostic_Warning: compilation.Diagnostics.Warning(message, location); break; case CXDiagnosticSeverity.CXDiagnostic_Error: case CXDiagnosticSeverity.CXDiagnostic_Fatal: compilation.Diagnostics.Error(message, location); skipProcessing = true; break; } } } } if (skipProcessing) { compilation.Diagnostics.Warning($"Compilation aborted due to one or more errors listed above.", new CppSourceLocation(rootFileName, 0, 1, 1)); } else { using (translationUnit) { translationUnit.Cursor.VisitChildren(builder.VisitTranslationUnit, clientData: default); } } } return(compilation); } }
public ClangCodeParser() { _index = CXIndex.Create(); }
public static int Run(InvocationContext context) { var additionalArgs = context.ParseResult.ValueForOption <string[]>("additional"); var config = new ConfigurationOptions(context.ParseResult.ValueForOption <string[]>("config")) { ExcludedFunctions = context.ParseResult.ValueForOption <string[]>("excludeFunction"), LibraryPath = context.ParseResult.ValueForOption <string>("libraryPath"), MethodClassName = context.ParseResult.ValueForOption <string>("methodClassName"), Namespace = context.ParseResult.ValueForOption <string>("namespace"), OutputLocation = context.ParseResult.ValueForOption <string>("output"), MethodPrefixToStrip = context.ParseResult.ValueForOption <string>("prefixStrip"), }; var defines = context.ParseResult.ValueForOption <string[]>("define"); var files = context.ParseResult.ValueForOption <string[]>("file"); var includeDirs = context.ParseResult.ValueForOption <string[]>("include"); var errorList = new List <string>(); if (!files.Any()) { errorList.Add("Error: No input C/C++ files provided. Use --file or -f"); } if (string.IsNullOrWhiteSpace(config.Namespace)) { errorList.Add("Error: No namespace provided. Use --namespace or -n"); } if (string.IsNullOrWhiteSpace(config.OutputLocation)) { errorList.Add("Error: No output file location provided. Use --output or -o"); } if (string.IsNullOrWhiteSpace(config.LibraryPath)) { errorList.Add("Error: No library path location provided. Use --libraryPath or -l"); } if (errorList.Any()) { foreach (var error in errorList) { context.Console.Error.WriteLine(error); } context.Console.Error.WriteLine(); new HelpBuilder(context.Console).Write(s_rootCommand); return(-1); } var arr = new string[] { "-xc++", // The input files are C++ "-Wno-pragma-once-outside-header" // We are processing files which may be header files }; arr = arr.Concat(includeDirs.Select(x => "-I" + x)).ToArray(); arr = arr.Concat(defines.Select(x => "-D" + x)).ToArray(); arr = arr.Concat(additionalArgs).ToArray(); var translationFlags = CXTranslationUnit_Flags.CXTranslationUnit_None; translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_SkipFunctionBodies; // Don't traverse function bodies translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_IncludeAttributedTypes; // Include attributed types in CXType translationFlags |= CXTranslationUnit_Flags.CXTranslationUnit_VisitImplicitAttributes; // Implicit attributes should be visited using (var createIndex = CXIndex.Create()) using (var cursorWriter = new CursorWriter(config)) { foreach (var file in files) { var translationUnitError = CXTranslationUnit.Parse(createIndex, file, arr, Array.Empty <CXUnsavedFile>(), translationFlags, out CXTranslationUnit translationUnitHandle); bool skipProcessing = false; if (translationUnitError != CXErrorCode.CXError_Success) { Console.WriteLine($"Error: Parsing failed for '{file}' due to '{translationUnitError}'."); skipProcessing = true; } else if (translationUnitHandle.NumDiagnostics != 0) { Console.WriteLine($"Diagnostics for '{file}':"); for (uint i = 0; i < translationUnitHandle.NumDiagnostics; ++i) { using (var diagnostic = translationUnitHandle.GetDiagnostic(i)) { Console.Write(" "); Console.WriteLine(diagnostic.Format(CXDiagnosticDisplayOptions.CXDiagnostic_DisplayOption).ToString()); skipProcessing |= (diagnostic.Severity == CXDiagnosticSeverity.CXDiagnostic_Error); skipProcessing |= (diagnostic.Severity == CXDiagnosticSeverity.CXDiagnostic_Fatal); } } } if (skipProcessing) { Console.WriteLine($"Skipping '{file}' due to one or more errors listed above."); Console.WriteLine(); continue; } using (translationUnitHandle) { var translationUnit = new TranslationUnit(translationUnitHandle.Cursor); translationUnit.Visit(clientData: default);
public CodeCParser() { _index = CXIndex.Create(); }
internal static extern ErrorCode clang_createTranslationUnit2(CXIndex index, string ast_filename, out CXTranslationUnit out_tu);
internal static extern void clang_CXIndex_setInvocationEmissionPathOption(CXIndex index, string path);
public ClangParser(CompilerContext ctx, CXIndex index, TranslationUnit tu) : base(ctx) { Index = index; TU = tu; }