/// <summary> /// Same as <see cref="ParseTranslationUnit"/> but requires a full command line for /// <paramref name="commandLineArgs"/> including args[0]. This is useful if the standard /// library paths are relative to the binary. /// </summary> /// <param name="sourceFileName"> /// The name of the source file to load, or null if the source file is included in /// <paramref name="commandLineArgs"/>. /// </param> /// <param name="commandLineArgs"> /// The command-line arguments that would be passed to the clang executable if it were /// being invoked out-of-process. These command-line options will be parsed and will affect /// how the translation unit is parsed. Note that the following options are ignored: '-c', /// '-emit-ast', '-fsyntax-only' (which is the default), and '-o <output file>'. /// </param> /// <param name="unsavedFiles"> /// The files that have not yet been saved to disk but may be required for parsing, /// including the contents of those files. /// </param> /// <param name="options"> /// A bitmask of options that affects how the translation unit is managed but not its /// compilation. This should be a bitwise OR of the /// <see cref="TranslationUnitCreationOptions"/> flags. /// </param> /// <returns> /// The created <see cref="TranslationUnit"/>, describing the parsed code and containing /// any diagnostics produced by the compiler. /// </returns> /// <exception cref="ErrorCodeException"> /// The error code returned by libclang is not <see cref="ErrorCode.Success"/>. /// </exception> public TranslationUnit ParseTranslationUnitFullArgv( string sourceFileName, IEnumerable <string> commandLineArgs, IEnumerable <UnsavedFile> unsavedFiles = null, TranslationUnitCreationOptions options = TranslationUnitCreationOptions.None) { ThrowIfDisposed(); using (var cString = new CString(sourceFileName)) using (var args = new CStrings(commandLineArgs)) using (var files = new CXUnsavedFiles(unsavedFiles)) { var argsPtr = stackalloc sbyte *[args.Count]; args.Apply((arg, i) => argsPtr[i] = arg.Ptr); var filesPtr = stackalloc CXUnsavedFile[files.Count]; files.Apply((file, i) => filesPtr[i] = files[i]); CXTranslationUnitImpl *ptr; NativeMethods.clang_parseTranslationUnit2FullArgv( Ptr, cString.Ptr, argsPtr, args.Count, filesPtr, (uint)files.Count, (uint)options, &ptr).Check(); return(new TranslationUnit(ptr, this)); } }
/// <summary> /// Reparse the source files that produced this translation unit. /// </summary> /// <param name="unsavedFiles"> /// The files that have not yet been saved to disk but may be required for parsing, /// including the contents of those files. /// </param> /// <returns> /// <para> /// errodCode: /// <see cref="ErrorCode.Success"/> if the sources could be reparsed. Another error code /// will be returned if reparsing was impossible, such that the translation unit is /// invalid. In such cases, the only valid call for translationUnit is /// <see cref="Dispose"/>. /// </para> /// <para>translationUnit: The translation unit whose contents were re-parsed.</para> /// </returns> /// <remarks> /// <para> /// This routine can be used to re-parse the source files that originally created the /// given translation unit, for example because those source files have changed (either on /// disk or as passed via <paramref name="unsavedFiles"/>). The source code will be /// reparsed with the same command-line options as it was originally parsed. /// </para> /// <para> /// Reparsing a translation unit invalidates all cursors and source locations that refer /// into that translation unit. This makes reparsing a translation unit semantically /// equivalent to destroying the translation unit and then creating a new translation unit /// with the same command-line arguments. However, it may be more efficient to reparse a /// translation unit using this routine. /// </para> /// </remarks> public (ErrorCode errorCode, TranslationUnit translationUnit) TryReparse( IEnumerable <UnsavedFile> unsavedFiles) { ThrowIfDisposed(); var files = new CXUnsavedFiles(unsavedFiles); var filesPtr = stackalloc CXUnsavedFile[files.Count]; files.Apply((file, i) => filesPtr[i] = files[i]); var errorCode = (ErrorCode)NativeMethods.clang_reparseTranslationUnit( Ptr, (uint)files.Count, filesPtr, NativeMethods.clang_defaultReparseOptions(Ptr)); TranslationUnit translationUnit = null; if (errorCode != ErrorCode.Success) { Dispose(); } else { translationUnit = new TranslationUnit(Ptr, Index); disposed = true; } return(errorCode : errorCode, translationUnit : translationUnit); }