/// <summary> /// Execute Core Logic /// </summary> /// <param name="index">Clang Index</param> /// <param name="tu">Clang Translation Unit</param> protected override void ExecuteCore(ClangIndex index, ClangTranslationUnit tu) { var cursor = tu.Cursor; this.SendMessage($"Inclusion Tree Dump:"); tu.GetInclusions(this.Visitor, IntPtr.Zero); }
/// <summary> /// Execute Translation Unit Handler Core /// </summary> /// <param name="index">Clang Index</param> /// <param name="tu">Clang Translation Unit</param> private void ExecuteCore(ClangIndex index, ClangTranslationUnit tu) { if (this.Setting.DumpAST) { this.SendMessage($"AST Dump:"); } this.VisitChild(tu.Cursor, 0); }
/// <summary> /// Execute Core Logic /// </summary> /// <param name="index">Clang Index</param> /// <param name="tu">Clang Translation Unit</param> protected override void ExecuteCore(ClangIndex index, ClangTranslationUnit tu) { var cursor = tu.Cursor; this.SendMessage($"AST Dump:"); cursor.VisitChildren(this.Visitor, 0); this.DumpIncludes("System", this.SystemIncludes); this.DumpIncludes("User", this.UserIncludes); }
private ClangTranslationUnit GetAndParseTranslationUnit(List <ClangUnsavedFile> unsavedFiles) { if (_translationUnit == null) { _translationUnit = GenerateTranslationUnit(unsavedFiles); } // Always do a reparse, as a workaround for some issues in libclang 3.7.1 _translationUnit.Reparse(unsavedFiles.ToArray(), ReparseTranslationUnitFlags.None); return(_translationUnit); }
private ClangTranslationUnit GenerateTranslationUnit(ISourceFile file, List <ClangUnsavedFile> unsavedFiles) { ClangTranslationUnit result = null; if (System.IO.File.Exists(file.Location)) { var args = new List <string>(); var superProject = file.Project.Solution.StartupProject as IStandardProject; var project = file.Project as IStandardProject; var toolchainIncludes = superProject.ToolChain?.GetToolchainIncludes(file); if (toolchainIncludes != null) { AddArguments(args, toolchainIncludes.Select(s => $"-isystem{s}")); } // toolchain includes // This code is same as in toolchain, get compiler arguments... does this need a refactor, or toolchain get passed in? Clang take GCC compatible arguments. // perhaps this language service has its own clang tool chain, to generate compiler arguments from project configuration? // Referenced includes var referencedIncludes = project.GetReferencedIncludes(); AddArguments(args, referencedIncludes.Select(s => $"-I{s}")); // global includes var globalIncludes = superProject.GetGlobalIncludes(); AddArguments(args, globalIncludes.Select(s => $"-I{s}")); // includes AddArguments(args, project.Includes.Select(s => $"-I{Path.Combine(project.CurrentDirectory, s.Value)}")); var referencedDefines = project.GetReferencedDefines(); AddArguments(args, referencedDefines.Select(s => $"-D{s}")); // global includes var globalDefines = superProject.GetGlobalDefines(); AddArguments(args, globalDefines.Select(s => $"-D{s}")); AddArguments(args, project.Defines.Select(s => $"-D{s}")); switch (file.Extension) { case ".c": { AddArguments(args, superProject.CCompilerArguments); } break; case ".cpp": { AddArguments(args, superProject.CppCompilerArguments); } break; } // TODO do we mark files as class header? CAn clang auto detect this? //if (file.Language == Language.Cpp) { args.Add("-xc++"); args.Add("-std=c++14"); args.Add("-D__STDC__"); // This is needed to ensure inbuilt functions are appropriately prototyped. } args.Add("-Wunused-variable"); var translationUnitFlags = TranslationUnitFlags.IncludeBriefCommentsInCodeCompletion | TranslationUnitFlags.PrecompiledPreamble | TranslationUnitFlags.CacheCompletionResults | TranslationUnitFlags.Incomplete; result = index.ParseTranslationUnit(file.Location, args.ToArray(), unsavedFiles.ToArray(), translationUnitFlags); } if (result == null) { throw new Exception("Error generating translation unit."); } return(result); }
private void GenerateDiagnostics(IEnumerable <ClangDiagnostic> clangDiagnostics, ClangTranslationUnit translationUnit, IProject project, TextSegmentCollection <Diagnostic> result) { foreach (var diagnostic in clangDiagnostics) { if (diagnostic.Location.IsFromMainFile) { var diag = new Diagnostic { Project = project, StartOffset = diagnostic.Location.FileLocation.Offset, Line = diagnostic.Location.FileLocation.Line, Spelling = diagnostic.Spelling, File = diagnostic.Location.FileLocation.File.FileName, Level = (DiagnosticLevel)diagnostic.Severity }; var cursor = translationUnit.GetCursor(diagnostic.Location); var tokens = translationUnit.Tokenize(cursor.CursorExtent); foreach (var token in tokens.Tokens) { if (token.Location == diagnostic.Location) { diag.EndOffset = diag.StartOffset + token.Spelling.Length; } } result.Add(diag); tokens.Dispose(); } } }
/// <summary> /// Execute Translation Unit Handler Core /// </summary> /// <param name="index">Clang Index</param> /// <param name="tu">Clang Translation Unit</param> protected abstract void ExecuteCore(ClangIndex index, ClangTranslationUnit tu);
private ClangTranslationUnit GenerateTranslationUnit(ISourceFile file, List <ClangUnsavedFile> unsavedFiles) { ClangTranslationUnit result = null; if (System.IO.File.Exists(file.Location)) { var args = new List <string>(); var superProject = file.Project.Solution.StartupProject as IStandardProject; var project = file.Project as IStandardProject; var toolchainIncludes = superProject.ToolChain?.Includes; if (toolchainIncludes != null) { foreach (var include in toolchainIncludes) { AddArgument(args, string.Format("-isystem{0}", include)); } } // toolchain includes // This code is same as in toolchain, get compiler arguments... does this need a refactor, or toolchain get passed in? Clang take GCC compatible arguments. // perhaps this language service has its own clang tool chain, to generate compiler arguments from project configuration? // Referenced includes var referencedIncludes = project.GetReferencedIncludes(); foreach (var include in referencedIncludes) { AddArgument(args, string.Format("-I{0}", include)); } // global includes var globalIncludes = superProject.GetGlobalIncludes(); foreach (var include in globalIncludes) { AddArgument(args, string.Format("-I{0}", include)); } // public includes foreach (var include in project.PublicIncludes) { AddArgument(args, string.Format("-I{0}", include)); } // includes foreach (var include in project.Includes) { AddArgument(args, string.Format("-I{0}", Path.Combine(project.CurrentDirectory, include.Value))); } var referencedDefines = project.GetReferencedDefines(); foreach (var define in referencedDefines) { AddArgument(args, string.Format("-D{0}", define)); } // global includes var globalDefines = superProject.GetGlobalDefines(); foreach (var define in globalDefines) { AddArgument(args, string.Format("-D{0}", define)); } foreach (var define in project.Defines) { AddArgument(args, string.Format("-D{0}", define)); } //foreach (var arg in superProject.ToolChainArguments) //{ // args.Add(string.Format("{0}", arg)); //} //foreach (var arg in superProject.CompilerArguments) //{ // args.Add(string.Format("{0}", arg)); //} switch (file.Extension) { case ".c": { foreach (var arg in superProject.CCompilerArguments) { args.Add(string.Format("{0}", arg)); } } break; case ".cpp": { foreach (var arg in superProject.CppCompilerArguments) { args.Add(string.Format("{0}", arg)); } } break; } // TODO do we mark files as class header? CAn clang auto detect this? //if (file.Language == Language.Cpp) { args.Add("-xc++"); args.Add("-std=c++14"); } args.Add("-Wunused-variable"); result = index.ParseTranslationUnit(file.Location, args.ToArray(), unsavedFiles.ToArray(), TranslationUnitFlags.IncludeBriefCommentsInCodeCompletion | TranslationUnitFlags.PrecompiledPreamble | TranslationUnitFlags.CacheCompletionResults | TranslationUnitFlags.Incomplete); } if (result == null) { throw new Exception("Error generating translation unit."); } return(result); }
private void GenerateDiagnostics(IEnumerable <ClangDiagnostic> clangDiagnostics, ClangTranslationUnit translationUnit, IProject project, TextSegmentCollection <Diagnostic> result, TextMarkerService service) { foreach (var diagnostic in clangDiagnostics) { if (diagnostic.Location.IsFromMainFile) { var diag = new Diagnostic { Project = project, StartOffset = diagnostic.Location.FileLocation.Offset, Line = diagnostic.Location.FileLocation.Line, Spelling = diagnostic.Spelling, File = diagnostic.Location.FileLocation.File.FileName, Level = (DiagnosticLevel)diagnostic.Severity }; var cursor = translationUnit.GetCursor(diagnostic.Location); var tokens = translationUnit.Tokenize(cursor.CursorExtent); foreach (var token in tokens.Tokens) { if (token.Location == diagnostic.Location) { diag.EndOffset = diag.StartOffset + token.Spelling.Length; } } result.Add(diag); tokens.Dispose(); Color markerColor; switch (diag.Level) { case DiagnosticLevel.Error: case DiagnosticLevel.Fatal: markerColor = Color.FromRgb(253, 45, 45); break; case DiagnosticLevel.Warning: markerColor = Color.FromRgb(255, 207, 40); break; default: markerColor = Color.FromRgb(0, 42, 74); break; } service.Create(diag.StartOffset, diag.Length, diag.Spelling, markerColor); } } }
private void GenerateDiagnostics(IEnumerable <ClangDiagnostic> clangDiagnostics, ClangTranslationUnit translationUnit, ISourceFile file, List <Diagnostic> result) { foreach (var diagnostic in clangDiagnostics) { if (diagnostic.Location.IsFromMainFile) { var diag = new Diagnostic( diagnostic.Location.FileLocation.Offset, 0, file.Project, diagnostic.Location.FileLocation.File.FileName, diagnostic.Location.FileLocation.Line, diagnostic.Spelling, (DiagnosticLevel)diagnostic.Severity, DiagnosticCategory.Compiler); var cursor = translationUnit.GetCursor(diagnostic.Location); var tokens = translationUnit.Tokenize(cursor.CursorExtent); foreach (var token in tokens.Tokens) { if (token.Location == diagnostic.Location) { diag.EndOffset = diag.StartOffset + token.Spelling.Length; } } result.Add(diag); tokens.Dispose(); } } }