Exemplo n.º 1
0
        /// <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 &lt;output file&gt;'.
        /// </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);
        }