/// <summary> /// Find #import/#include directives in a specific file. /// </summary> /// <param name="translationUnit">Translation unit containing the file to query.</param> /// <param name="file">file to search for #import/#include directives.</param> /// <returns> /// true if the function was terminated by a callback /// (e.g., <see cref="Visit(Cursor, SourceRange)"/> returned false). /// </returns> /// <exception cref="ArgumentNullException"> /// <paramref name="translationUnit"/> or <paramref name="file"/> is null. /// </exception> public bool FindIncludesInFile(TranslationUnit translationUnit, SourceFile file) { Requires.NotNull(translationUnit, nameof(translationUnit)); Requires.NotNull(file, nameof(file)); translationUnit.ThrowIfDisposed(); visit visitor = (context, arg2, arg3) => { if (Visit( Cursor.Create(arg2, translationUnit), SourceRange.Create(arg3, translationUnit))) { return(CXVisitorResult.CXVisit_Continue); } else { return(CXVisitorResult.CXVisit_Break); } }; var result = NativeMethods.clang_findIncludesInFile( translationUnit.Ptr, file.Ptr, new CXCursorAndRangeVisitor { visit = Marshal.GetFunctionPointerForDelegate(visitor) }); GC.KeepAlive(visitor); switch (result) { case CXResult.CXResult_Success: return(false); case CXResult.CXResult_Invalid: throw new InvalidOperationException(result.ToString()); case CXResult.CXResult_VisitBreak: return(true); default: goto case CXResult.CXResult_Invalid; } }
/// <summary> /// Gets all ranges from all files that were skipped by the preprocessor. /// </summary> /// <remarks> /// The preprocessor will skip lines when they are surrounded by an if/ifdef/ifndef /// directive whose condition does not evaluate to true. /// </remarks> /// <returns>All ranges from all files that were skipped by the preprocessor.</returns> public SourceRange[] GetAllSkippedRanges() { ThrowIfDisposed(); var ptr = NativeMethods.clang_getAllSkippedRanges(Ptr); if (ptr == null) { return(Array.Empty <SourceRange>()); } else { try { var ranges = new SourceRange[ptr->count]; ranges.SetValues(i => SourceRange.Create(ptr->ranges[i], this)); return(ranges); } finally { NativeMethods.clang_disposeSourceRangeList(ptr); } } }
/// <summary> /// Visitor callback that will receive pairs of Cursor/SourceRange for each /// reference/directive found. /// </summary> /// <param name="cursor">The Cursor for a reference/directive.</param> /// <param name="range">The SourceRange for each reference/directive.</param> /// <returns>true to continue the cursor traversal.</returns> protected abstract bool Visit(Cursor cursor, SourceRange range);