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 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); }