Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package clang-extract for openSUSE:Factory checked in at 2025-10-08 18:14:35 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/clang-extract (Old) and /work/SRC/openSUSE:Factory/.clang-extract.new.11973 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "clang-extract" Wed Oct 8 18:14:35 2025 rev:17 rq:1309814 version:0~20251008.e818417 Changes: -------- --- /work/SRC/openSUSE:Factory/clang-extract/clang-extract.changes 2025-07-10 22:14:17.329056306 +0200 +++ /work/SRC/openSUSE:Factory/.clang-extract.new.11973/clang-extract.changes 2025-10-08 18:18:33.636577783 +0200 @@ -1,0 +2,20 @@ +Wed Oct 08 14:10:03 UTC 2025 - [email protected] + +- Update to version 0~20251008.e818417: + * Fix test failing if gcc is 7.5.0 + +------------------------------------------------------------------- +Wed Oct 08 02:00:52 UTC 2025 - [email protected] + +- Update to version 0~20251006.0f2b19f: + * Properly handle win32 paths in `get_basename` + * Clean warnings and debug prints left in fe587574fc11ee87b5497400a941314bbe936c4c + * Remove any use of `basename` + * Make sure we get a matching number of #if and #endifs before copying function to output + * Fix corner case where struct attributes are declared from #include + * Add new expansion policies. + * Fix ArrayRef constructor ambiguity on 32-bit systems + * Add support to LLVM-21 + * Fix ce-inline crashing when no debuginfo is provided + +------------------------------------------------------------------- Old: ---- clang-extract-0~20250710.ac81bbb.tar.xz New: ---- clang-extract-0~20251008.e818417.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ clang-extract.spec ++++++ --- /var/tmp/diff_new_pack.whnrpG/_old 2025-10-08 18:18:35.544657856 +0200 +++ /var/tmp/diff_new_pack.whnrpG/_new 2025-10-08 18:18:35.544657856 +0200 @@ -1,7 +1,7 @@ # # spec file for package clang-extract # -# Copyright (c) 2025 SUSE LLC +# Copyright (c) 2025 SUSE LLC and contributors # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: clang-extract -Version: 0~20250710.ac81bbb +Version: 0~20251008.e818417 Release: 0 Summary: A tool to extract code content from source files License: Apache-2.0 WITH LLVM-exception AND NCSA @@ -36,9 +36,6 @@ BuildRequires: meson BuildRequires: ninja -# Remove i586 support -ExcludeArch: i586 - %description A tool to extract code content from source files using the clang and LLVM infrastructure. ++++++ _service ++++++ --- /var/tmp/diff_new_pack.whnrpG/_old 2025-10-08 18:18:35.576659199 +0200 +++ /var/tmp/diff_new_pack.whnrpG/_new 2025-10-08 18:18:35.580659367 +0200 @@ -2,7 +2,7 @@ <service name="tar_scm" mode="manual"> <param name="scm">git</param> <param name="url">https://github.com/SUSE/clang-extract</param> - <param name="revision">ac81bbb8f95e6409da2eeee8ef41cc9d7d970241</param> + <param name="revision">e8184176dfc568517e63b13840bef57f6663c2be</param> <param name="versionformat">0~%cd.%h</param> <param name="changesgenerate">enable</param> <param name="changesauthor">[email protected]</param> ++++++ clang-extract-0~20250710.ac81bbb.tar.xz -> clang-extract-0~20251008.e818417.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/.github/workflows/testsuite.yml new/clang-extract-0~20251008.e818417/.github/workflows/testsuite.yml --- old/clang-extract-0~20250710.ac81bbb/.github/workflows/testsuite.yml 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/.github/workflows/testsuite.yml 2025-10-08 16:07:31.000000000 +0200 @@ -15,7 +15,7 @@ opensuse: [tumbleweed] compiler: [clang] build-type: [debug, release] - version: [18, 19, 20] + version: [18, 19, 20, 21] container: image: opensuse/${{ matrix.opensuse }} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/README.md new/clang-extract-0~20251008.e818417/README.md --- old/clang-extract-0~20250710.ac81bbb/README.md 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/README.md 2025-10-08 16:07:31.000000000 +0200 @@ -93,6 +93,17 @@ $ clang out.c -O2 -o a ``` If you desire to keep the includes, see `-DCE_KEEP_INCLUDES` options and the _Supported options_ chapter. +The following expansion policies are supported: + - `nothing`: Do not expand any header. + - `everything`: Expand all headers. Has the same semantic effect of not passing `-DCE_KEEP_INCLUDES`, but forces clang-extract to pass it through its header expansion logics (slow and very likely buggy!). + - `kernel`: Special policy used by the kernel livepatching developers. + - `system`: Keep all system headers installed in `/usr/include`, etc. + - `compiler`: Keep all compiler-specific headers, such as `stdatomic.h`. Useful if you want to expand everything but still want to ensure compatibility with other compilers. + +You may want to use `clang-tidy` to cleanup the generated file afterwards to remove duplicated includes: +``` +$ clang-tidy -checks='-*,readability-duplicate-include,misc-include-cleaner' -fix <out.c> +``` ### Symbol Externalization @@ -192,7 +203,7 @@ - `-DCE_NO_EXTERNALIZATION` Disable symbol externalization. - `-DCE_DUMP_PASSES` Dump the results of each transformation pass into files. Files will be dumped at the same path of the input files. Additional files are also generated on `/tmp/` folder. - `-DCE_KEEP_INCLUDES` Keep all possible `#include<file>` directives. -- `-DCE_KEEP_INCLUDES=<policy>` Keep all possible `#include<file>` directives, but using the specified include expansion <policy>. Valid values are nothing, everything and kernel. +- `-DCE_KEEP_INCLUDES=<policy>` Keep all possible `#include<file>` directives, but using the specified include expansion <policy>. Valid values are `nothing`, `everything`, `kernel`, `system` and `compiler`. - `-DCE_EXPAND_INCLUDES=<args>` Force expansion of the headers provided in <args>. - `-DCE_RENAME_SYMBOLS` Allow renaming of extracted symbols. - `-DCE_DEBUGINFO_PATH=<arg>` Path to the compiled (ELF) object of the desired program to extract. This is used to decide if externalization is necessary or not for given symbol. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/ASTUnitHack.cpp new/clang-extract-0~20251008.e818417/libcextract/ASTUnitHack.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/ASTUnitHack.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/ASTUnitHack.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -16,35 +16,57 @@ #include <clang/Frontend/ASTUnit.h> #include <clang/Frontend/CompilerInvocation.h> #include <clang/Serialization/InMemoryModuleCache.h> +#include <clang/Basic/Version.h> + +#if CLANG_VERSION_MAJOR >= 21 +#include <clang/Serialization/ModuleCache.h> +#endif using namespace clang; +/** Common code for the ASTUnit::create functions. */ +#define ASTUNIT_COMMON(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile) \ + std::unique_ptr<ASTUnit> AST(new ASTUnit(false)); \ + ConfigureDiags(Diags, *AST, CaptureDiagnostics); \ + AST->Diagnostics = Diags; \ + AST->FileSystemOpts = CI->getFileSystemOpts(); \ + AST->Invocation = std::move(CI); \ + AST->FileMgr = new FileManager(AST->FileSystemOpts, _Hack_VFS); \ + AST->UserFilesAreVolatile = UserFilesAreVolatile; \ + AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr, \ + UserFilesAreVolatile) + /** Filesystem that will be used in our custom ASTUnit::create, so that way we * don't break clang's API. */ IntrusiveRefCntPtr<llvm::vfs::FileSystem> _Hack_VFS; + /** Hack to create an ASTUnit from LoadFromCompilerInvocationAction with a * virtual filesystem. That way we can use FrontendActions hooks when * creating the ASTUnit. */ +#if CLANG_VERSION_MAJOR >= 21 std::unique_ptr<ASTUnit> ASTUnit::create(std::shared_ptr<CompilerInvocation> CI, + std::shared_ptr<DiagnosticOptions> DiagOpts, IntrusiveRefCntPtr<DiagnosticsEngine> Diags, CaptureDiagsKind CaptureDiagnostics, bool UserFilesAreVolatile) { - std::unique_ptr<ASTUnit> AST(new ASTUnit(false)); - ConfigureDiags(Diags, *AST, CaptureDiagnostics); - - AST->Diagnostics = Diags; - AST->FileSystemOpts = CI->getFileSystemOpts(); - AST->Invocation = std::move(CI); - AST->FileMgr = new FileManager(AST->FileSystemOpts, _Hack_VFS); - AST->UserFilesAreVolatile = UserFilesAreVolatile; - AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr, - UserFilesAreVolatile); + ASTUNIT_COMMON(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile); + AST->DiagOpts = DiagOpts; + AST->ModCache = createCrossProcessModuleCache(); + return AST; +} +#else +std::unique_ptr<ASTUnit> +ASTUnit::create(std::shared_ptr<CompilerInvocation> CI, + IntrusiveRefCntPtr<DiagnosticsEngine> Diags, + CaptureDiagsKind CaptureDiagnostics, + bool UserFilesAreVolatile) { + ASTUNIT_COMMON(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile); AST->ModuleCache = new InMemoryModuleCache; - return AST; } +#endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/ArgvParser.cpp new/clang-extract-0~20251008.e818417/libcextract/ArgvParser.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/ArgvParser.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/ArgvParser.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -19,12 +19,6 @@ #include <clang/Basic/Version.h> -#ifndef _GNU_SOURCE -#define _GNU_SOURCE -#endif -/* Use the basename version that doesn't change the input string */ -#include <string.h> - #ifndef CLANG_VERSION_MAJOR # error "Unable to find clang version" #endif @@ -58,6 +52,8 @@ "-Wno-stringop-truncation", "-Werror=designated-init", "-Wimplicit-fallthrough=", + "-Wendif-labels", + "-Wmissing-selector-name", }; ArgvParser::ArgvParser(int argc, char **argv) @@ -99,7 +95,7 @@ * are not the same, it means that the module from PatchObject is builtin, so * assign vmlinux to PatchObject. */ if (Kernel && DebuginfoPath) { - std::string obj_path = basename(DebuginfoPath); + std::string obj_path = get_basename(DebuginfoPath); /* As the DebugInfo can point to a file with suffix (btrfs.ko for example), * check the substring */ if (obj_path.find(PatchObject) == std::string::npos) @@ -157,7 +153,7 @@ " -DCE_KEEP_INCLUDES=<policy>\n" " Keep all possible #include<file> directives, but using the\n" " specified include expansion <policy>. Valid values are\n" -" nothing, everything and kernel.\n" +" nothing, everything, kernel, system and compiler.\n" " -DCE_EXPAND_INCLUDES=<args>\n" " Force expansion of the headers provided in <args>.\n" " -DCE_RENAME_SYMBOLS Allow renaming of extracted symbols.\n" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/ClangCompat.hh new/clang-extract-0~20251008.e818417/libcextract/ClangCompat.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/ClangCompat.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/ClangCompat.hh 2025-10-08 16:07:31.000000000 +0200 @@ -38,6 +38,17 @@ # define ClangCompat_GetTokenPtr(token) (token).getPointer() #endif +/** Starting from LLVM-21, ASTUnit::create requires one more parameter. */ +#if CLANG_VERSION_MAJOR >= 21 +# define ClangCompat_ASTUP(CI, DO, D, CP, UFAV) CI, DO, D, CP, UFAV +# define ClangCompat_ASTULFCIAP(CI, PCH, DO, D, A, U, P, RFP, OLC, CD, PPANP, CCCR, UFAV, EAST) \ + CI, PCH, DO, D, A, U, P, RFP, OLC, CD, PPANP, CCCR, UFAV, EAST +#else +# define ClangCompat_ASTUP(CI, DO, D, CP, UFAV) CI, D, CP, UFAV +# define ClangCompat_ASTULFCIAP(CI, PCH, DO, D, A, U, P, RFP, OLC, CD, PPANP, CCCR, UFAV, EAST) \ + CI, PCH, D, A, U, P, RFP, OLC, CD, PPANP, CCCR, UFAV, EAST +#endif + static inline const clang::TypedefType *Get_Type_As_TypedefType(const clang::Type *type) { #if CLANG_VERSION_MAJOR >= 16 @@ -103,14 +114,37 @@ #endif } +#if CLANG_VERSION_MAJOR >= 21 + static inline IntrusiveRefCntPtr<DiagnosticsEngine> createDiagnostics( + llvm::vfs::FileSystem &VFS, + std::shared_ptr<DiagnosticOptions> Opts) + { + return CompilerInstance::createDiagnostics(VFS, *Opts); + } +#endif + static inline IntrusiveRefCntPtr<DiagnosticsEngine> createDiagnostics( llvm::vfs::FileSystem &VFS, DiagnosticOptions *Opts) { -#if CLANG_VERSION_MAJOR >= 20 +#if CLANG_VERSION_MAJOR >= 21 + return CompilerInstance::createDiagnostics(VFS, *Opts); +#elif CLANG_VERSION_MAJOR == 20 return CompilerInstance::createDiagnostics(VFS, Opts); #else return CompilerInstance::createDiagnostics(Opts); #endif } + +#if CLANG_VERSION_MAJOR >= 21 + static inline std::shared_ptr<DiagnosticOptions> createDiagnosticOptions(void) + { + return std::make_shared<DiagnosticOptions>(); + } +#else + static inline DiagnosticOptions *createDiagnosticOptions(void) + { + return new DiagnosticOptions(); + } +#endif } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/Error.cpp new/clang-extract-0~20251008.e818417/libcextract/Error.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/Error.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/Error.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -28,7 +28,7 @@ DiagsClass::DiagsClass(void) : LangOpts(), DOpts(DiagnosticOptionsWithColor()), - DiagsEngine(llvm::outs(), LangOpts, DOpts.Get_DiagnosticOptions()) + DiagsEngine(llvm::outs(), LangOpts, DOpts.getDiagsOptsToEngine()) {} /* Print error giving a piece of source code that caused the error. */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/Error.hh new/clang-extract-0~20251008.e818417/libcextract/Error.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/Error.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/Error.hh 2025-10-08 16:07:31.000000000 +0200 @@ -18,6 +18,9 @@ #include <clang/Frontend/TextDiagnostic.h> #include <clang/Basic/LangOptions.h> +// For CLANG_VERSION_MAJOR +#include <clang/Basic/Version.h> + using namespace clang; /* Creates a special DiagnosticOptions with forced ShowColors. */ @@ -31,6 +34,21 @@ return DOpts; } +/* Because clang changed the constructor of TextDiagnostics, we need this + special method here that returns the correct type just for it according + to clang's version. */ +#if CLANG_VERSION_MAJOR >= 21 + inline DiagnosticOptions &getDiagsOptsToEngine(void) + { + return *DOpts; + } +#else + inline DiagnosticOptions *getDiagsOptsToEngine(void) + { + return DOpts; + } +#endif + inline bool Is_Colored(void) { return DOpts->ShowColors; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/ExpansionPolicy.cpp new/clang-extract-0~20251008.e818417/libcextract/ExpansionPolicy.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/ExpansionPolicy.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/ExpansionPolicy.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -39,25 +39,40 @@ return true; } -IncludeExpansionPolicy *IncludeExpansionPolicy::Get_Expansion_Policy( - IncludeExpansionPolicy::Policy p) +bool SystemExpansionPolicy::Must_Expand(const StringRef &absolute_path, + const StringRef &relative_path) { - switch (p) { - case Policy::NOTHING: - return new NoIncludeExpansionPolicy(); - break; + const char *absolute_path_c = absolute_path.data(); - case Policy::EVERYTHING: - return new ExpandEverythingExpansionPolicy(); - break; + /* Look for system headers by looking to specific prefixes. */ + const char *include_paths[] = { "/usr/include/", "/usr/lib64/", + "/usr/lib/", "/usr/local/include/", }; + for (unsigned i = 0; i < ARRAY_LENGTH(include_paths); i++) { + if (prefix(include_paths[i], absolute_path_c)) { + return false; // Do not expand. + } + } - case Policy::KERNEL: - return new KernelExpansionPolicy(); - break; + /* Expand anything that doesn't match this. */ + return true; +} - default: - assert(false && "Invalid policy"); +bool CompilerExpansionPolicy::Must_Expand(const StringRef &absolute_path, + const StringRef &relative_path) +{ + const char *absolute_path_c = absolute_path.data(); + + /* Look for clang compiler headers by looking to specific prefixes. */ + const char *include_paths[] = { "/usr/lib64/clang/", "/usr/lib/clang/", + "/usr/local/lib64/clang/", "/usr/local/lib64/clang/", }; + for (unsigned i = 0; i < ARRAY_LENGTH(include_paths); i++) { + if (prefix(include_paths[i], absolute_path_c)) { + return false; // Do not expand. + } } + + /* Expand anything that doesn't match this. */ + return true; } std::unique_ptr<IncludeExpansionPolicy> IncludeExpansionPolicy::Get_Expansion_Policy_Unique( @@ -79,6 +94,16 @@ KernelExpansionPolicy()); break; + case Policy::SYSTEM: + return std::make_unique<SystemExpansionPolicy>( + SystemExpansionPolicy()); + break; + + case Policy::COMPILER: + return std::make_unique<CompilerExpansionPolicy>( + CompilerExpansionPolicy()); + break; + default: assert(false && "Invalid policy"); } @@ -96,7 +121,9 @@ } policies[] = { { "nothing", IncludeExpansionPolicy::NOTHING }, { "everything", IncludeExpansionPolicy::EVERYTHING }, - { "kernel", IncludeExpansionPolicy::KERNEL } + { "kernel", IncludeExpansionPolicy::KERNEL }, + { "system", IncludeExpansionPolicy::SYSTEM }, + { "compiler", IncludeExpansionPolicy::COMPILER }, }; for (unsigned long i = 0; i < ARRAY_LENGTH(policies); i++) { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/ExpansionPolicy.hh new/clang-extract-0~20251008.e818417/libcextract/ExpansionPolicy.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/ExpansionPolicy.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/ExpansionPolicy.hh 2025-10-08 16:07:31.000000000 +0200 @@ -32,6 +32,8 @@ NOTHING, EVERYTHING, KERNEL, + SYSTEM, + COMPILER, }; static IncludeExpansionPolicy *Get_Expansion_Policy(Policy policy); @@ -75,8 +77,23 @@ } }; +/** Expand any header according to kernel livepatching rules. */ class KernelExpansionPolicy : public IncludeExpansionPolicy { public: virtual bool Must_Expand(const StringRef &absolute_path, const StringRef &relative_path); +}; + +/** Expand any header that is not installed in the system. */ +class SystemExpansionPolicy : public IncludeExpansionPolicy +{ + public: + virtual bool Must_Expand(const StringRef &absolute_path, const StringRef &relative_path); +}; + +/** Expand any header that is not compiler-specific. */ +class CompilerExpansionPolicy : public IncludeExpansionPolicy +{ + public: + virtual bool Must_Expand(const StringRef &absolute_path, const StringRef &relative_path); }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/InlineAnalysis.hh new/clang-extract-0~20251008.e818417/libcextract/InlineAnalysis.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/InlineAnalysis.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/InlineAnalysis.hh 2025-10-08 16:07:31.000000000 +0200 @@ -54,7 +54,9 @@ InlineAnalysis(const char *elf_path, const char *ipaclone_path, const char *symvers_path, bool is_kernel) - : InlineAnalysis(std::vector<std::string>({elf_path}), + : InlineAnalysis(elf_path == nullptr ? + std::vector<std::string>() : + std::vector<std::string>({elf_path}), ipaclone_path, symvers_path, is_kernel) {} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/LLVMMisc.cpp new/clang-extract-0~20251008.e818417/libcextract/LLVMMisc.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/LLVMMisc.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/LLVMMisc.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -233,7 +233,7 @@ } } - return ArrayRef<Decl *>(nullptr, 0UL); + return ArrayRef<Decl *>(nullptr, size_t(0)); } std::string Build_CE_Location_Comment(SourceManager &sm, const SourceLocation &loc) @@ -315,3 +315,54 @@ return a_str == b_str; } + +#define TOKEN_VECTOR " ().,;+-*/^|&{}[]<>^&|!\r\n\t" + +/** Check if string has unmatched #if, #ifdef, #ifndef. */ +bool Has_Balanced_Ifdef(const StringRef &string) +{ + /* Create a temporary buffer for strtok and copy the string. */ + size_t len = string.size(); + char buf[len + 1]; + memcpy(buf, string.data(), len); + buf[len] = '\0'; + + /* Count the number of parenthesis problem. ifdef, ifndef, if increases, + endif decreases. */ + int balance = 0; + + /* Tokenize. */ + char *tok = strtok(buf, TOKEN_VECTOR); + while (tok != nullptr) { + /* There is the silly case in which #ifdef is written as `# ifdef`. */ + if (*tok == '#') { + /* Now check if it got into the same token or if we need to pull another + token. */ + if (tok[1] == '\0') { + tok = strtok(nullptr, TOKEN_VECTOR); + } else { + tok++; + } + + assert(tok != nullptr && "tok is null! why?"); + + /* Case 1: #ifdef, #ifndef, and #if has "if" as prefix. */ + if (prefix("if", tok)) { + balance++; + } + + /* Case 2: #endif. Decrease the balance counter. */ + else if (strcmp("endif", tok) == 0) { + balance--; + if (balance < 0) { + /* Impossible. This means there is an #endif for no matching #if. */ + return false; + } + } + } + + tok = strtok(nullptr, TOKEN_VECTOR); + } + + return balance == 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/LLVMMisc.hh new/clang-extract-0~20251008.e818417/libcextract/LLVMMisc.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/LLVMMisc.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/LLVMMisc.hh 2025-10-08 16:07:31.000000000 +0200 @@ -109,3 +109,6 @@ /** Check if two Decls are equivalent. */ bool Is_Decl_Equivalent_To(Decl *a, Decl *b); + +/** Check if string has unmatched #if, #ifdef, #ifndef. */ +bool Has_Balanced_Ifdef(const StringRef &string); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/NonLLVMMisc.cpp new/clang-extract-0~20251008.e818417/libcextract/NonLLVMMisc.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/NonLLVMMisc.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/NonLLVMMisc.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -140,3 +140,15 @@ return FILE_TYPE_UNKNOWN; } + +/** Get basename of a string. Works like the gnu version. */ +const char *get_basename(const char *path) +{ + const char *base = strrchr(path, '/'); +#ifdef _WIN32 + const char *backslash = strrchr(path, '\\'); + if (backslash > base) + base = backslash; +#endif + return base ? base+1 : path; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/NonLLVMMisc.hh new/clang-extract-0~20251008.e818417/libcextract/NonLLVMMisc.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/NonLLVMMisc.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/NonLLVMMisc.hh 2025-10-08 16:07:31.000000000 +0200 @@ -91,3 +91,6 @@ static enum FileType Get_File_Type(int fd); }; + +/** Get basename of a string. Works like the gnu version. */ +const char *get_basename(const char *filename); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/Passes.cpp new/clang-extract-0~20251008.e818417/libcextract/Passes.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/Passes.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/Passes.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -74,10 +74,8 @@ /* Built the ASTUnit from the passed command line and set its SourceManager to the PrettyPrint class. */ - DiagnosticOptions *diagopts = new DiagnosticOptions(); - if (check_color_available()) { - diagopts->ShowColors = true; - } + auto diagopts = ClangCompat::createDiagnosticOptions(); + diagopts->ShowColors = check_color_available(); Diags = ClangCompat::createDiagnostics(*_Hack_VFS, diagopts); @@ -93,11 +91,18 @@ /* Hacked function call, see ASTUnitHack.cpp. */ - auto AU = ASTUnit::create(CInvok, Diags, CaptureDiagsKind::None, false); + auto AU = ASTUnit::create(ClangCompat_ASTUP(CInvok, + diagopts, + Diags, + CaptureDiagsKind::None, + false)); std::unique_ptr<ASTUnit> *ErrAST = nullptr; - ASTUnit::LoadFromCompilerInvocationAction(CInvok, PCHContainerOps, - Diags, nullptr, AU.get(), + ASTUnit::LoadFromCompilerInvocationAction(ClangCompat_ASTULFCIAP( + CInvok, PCHContainerOps, + diagopts, + Diags, + nullptr, AU.get(), /*Persistent=*/true, /*ResourceFilesPath=*/StringRef(), /*OnlyLocalDecls=*/false, @@ -105,7 +110,7 @@ /*PrecompilePreambleAfterNParses=*/0, /*CacheCodeCompletionResults=*/false, /*UserFilesAreVolatile=*/false, - ErrAST); + ErrAST)); _Hack_VFS = nullptr; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/PrettyPrint.cpp new/clang-extract-0~20251008.e818417/libcextract/PrettyPrint.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/PrettyPrint.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/PrettyPrint.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -20,12 +20,13 @@ #include "LLVMMisc.hh" #include <clang/AST/Attr.h> +#include <llvm/Support/Regex.h> /** Public methods. */ #define Out (*Out) -void PrettyPrint::Print_Decl(Decl *decl) +void PrettyPrint::Print_Decl(Decl *decl, bool keep_includes) { /* When handling C code, we need to check if given declaration is a function with body. If yes, we can simply print the declaration, but otherwise @@ -38,22 +39,22 @@ if (f && f->hasBody() && f->isThisDeclarationADefinition()) { Print_Decl_Raw(f); Out << "\n\n"; - } else if (e) { - decl->print(Out, PPolicy); - Out << ";\n\n"; } else if (!e && t && t->getName() == "") { /* If the RecordType doesn't have a name, then don't print it. Except when it is an empty named enum declaration, which in this case we must print because it contains declared constants. */ } else { - /* Structs and prototypes */ + /* Structs, enums, and prototypes */ - /** Check if we can get a partial declaration of `decl` rather than a full - declaration. */ - bool full_def_removed = false; - if (t && t->isCompleteDefinitionRequired() == false) { - /* We don't need the full defintion. Hide the body for Print_Decl_Raw. */ - t->setCompleteDefinition(false); + /** Check if the output string has an include directive. In that case, if we + don't want to keep the includes, we must print the ast dump rather than + the source text to get rid of the #include directive. + FIXME: regexes are slow. */ + static llvm::Regex regex("# *include *(<|\")"); + + /* FIXME: Why isCompleteDefinitionRequired does not work for EnumDecls? */ + if (t && ((!e && t->isCompleteDefinitionRequired() == false) + || (!keep_includes && regex.match(Get_Source_Text(t->getSourceRange()))))) { /* FIXME: The Print_Decl_Raw class will attempt to write this declaration as the user wrote, that means WITH a body. To avoid this, we set @@ -63,7 +64,15 @@ correct way of doing this would be update the source location to the correct range. */ t->setLocStart(t->getEndLoc()); + } + /** Check if we can get a partial declaration of `decl` rather than a full + declaration. */ + bool full_def_removed = false; + /* FIXME: Why isCompleteDefinitionRequired does not work for EnumDecls? */ + if (t && !e && t->isCompleteDefinitionRequired() == false) { + /* We don't need the full defintion. Hide the body for Print_Decl_Raw. */ + t->setCompleteDefinition(false); full_def_removed = true; } @@ -182,7 +191,24 @@ } } } else { - Out << decl_source; + /* Check if the output string has a balanced number of ifdefs. This is + required because of the following construct from glibc: + + #ifdef !SHARED + #else + struct rtld_global_ro { + #endif + + In case we want to print rtld_global_ro, PrettyPrint will get the text + from struct rtld_global_ro and below, which would only include the + #endif, and not the #ifdef. In case its not balanced we fallback to + AST dumping. */ + if (Has_Balanced_Ifdef(decl_source)) { + Out << decl_source; + } else { + /* In case its not balanced, fallback to AST dump. */ + decl->print(Out, LangOpts); + } } } else { /* Else, we fallback to AST Dumping. */ @@ -613,7 +639,7 @@ PrettyPrint::Print_RawComment(sm, comment); } } - PrettyPrint::Print_Decl(decl); + PrettyPrint::Print_Decl(decl, KeepIncludes); } } @@ -656,13 +682,7 @@ decl = (*ASTIterator).AsDecl; Print_Decl(decl); ++ASTIterator; - - /* Skip to the end of the Declaration. */ - if (!dyn_cast<EnumDecl>(decl)) { - /* EnumDecls are handled somewhat differently: we dump the AST, not - what the user wrote. */ - ASTIterator.Skip_Until(decl->getEndLoc()); - } + ASTIterator.Skip_Until(decl->getEndLoc()); break; case TopLevelASTIterator::ReturnType::TYPE_PREPROCESSED_ENTITY: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/PrettyPrint.hh new/clang-extract-0~20251008.e818417/libcextract/PrettyPrint.hh --- old/clang-extract-0~20250710.ac81bbb/libcextract/PrettyPrint.hh 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/PrettyPrint.hh 2025-10-08 16:07:31.000000000 +0200 @@ -38,7 +38,7 @@ { public: /** Print a Decl node into ostream `Out`. */ - static void Print_Decl(Decl *decl); + static void Print_Decl(Decl *decl, bool keep_includes = false); /** Print Decl node as is, without any kind of processing. */ static void Print_Decl_Raw(Decl *decl); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/libcextract/SymversParser.cpp new/clang-extract-0~20251008.e818417/libcextract/SymversParser.cpp --- old/clang-extract-0~20250710.ac81bbb/libcextract/SymversParser.cpp 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/libcextract/SymversParser.cpp 2025-10-08 16:07:31.000000000 +0200 @@ -21,6 +21,8 @@ #include <sstream> #include <libgen.h> +#include "NonLLVMMisc.hh" + Symvers::Symvers(const std::string &path) : Parser(path) { @@ -64,7 +66,7 @@ std::getline(ss, sym_mod, '\t'); // Only get the name of the module, instead of the path to it - Symbol sym(sym_name, basename(sym_mod.data())); + Symbol sym(sym_name, get_basename(sym_mod.data())); Insert_Symbols_Into_Hash(sym); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/includes/policy-compiler-1.c new/clang-extract-0~20251008.e818417/testsuite/includes/policy-compiler-1.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/includes/policy-compiler-1.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/includes/policy-compiler-1.c 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,19 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=fn_c -DCE_NO_EXTERNALIZATION -DCE_KEEP_INCLUDES=compiler" }*/ + +#include <stdio.h> +#include <stdatomic.h> +#include <pthread.h> + +atomic_int cnt_atomic; + +void* fn_c(void *thr_data) { + (void)thr_data; + for (int i = 0; i < 40000; i++) { + atomic_fetch_add(&cnt_atomic, 1); + } + return NULL; +} + +/* { dg-final { scan-tree-dump-not "#include <stdio.h>" } } */ +/* { dg-final { scan-tree-dump "#include <stdatomic.h>" } } */ +/* { dg-final { scan-tree-dump "#include <stddef.h>" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/includes/policy-system-1.c new/clang-extract-0~20251008.e818417/testsuite/includes/policy-system-1.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/includes/policy-system-1.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/includes/policy-system-1.c 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,21 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=fn_c -DCE_NO_EXTERNALIZATION -DCE_KEEP_INCLUDES=system" }*/ + +#include <stdio.h> +#include <stdatomic.h> +#include <pthread.h> +#include "header-1.h" + +atomic_int cnt_atomic; + +void* fn_c(void *thr_data) { + (void)thr_data; + for (int i = 0; i < 40000; i++) { + atomic_fetch_add(&cnt_atomic, 1); + } + return NULL; +} + +/* { dg-final { scan-tree-dump "#include <stdio.h>" } } */ +/* { dg-final { scan-tree-dump "#include <stdatomic.h>" } } */ +/* { dg-final { scan-tree-dump "#include <pthread.h>" } } */ +/* { dg-final { scan-tree-dump-not "#include \"header-1.h\"" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/inline/inlined-into-1.c new/clang-extract-0~20251008.e818417/testsuite/inline/inlined-into-1.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/inline/inlined-into-1.c 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/testsuite/inline/inlined-into-1.c 2025-10-08 16:07:31.000000000 +0200 @@ -6,7 +6,7 @@ return 42; } -static __attribute__((noipa)) h(void) +static __attribute__((noipa)) __attribute__((noinline)) h(void) { return g(); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/lib/libtest.py new/clang-extract-0~20251008.e818417/testsuite/lib/libtest.py --- old/clang-extract-0~20250710.ac81bbb/testsuite/lib/libtest.py 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/testsuite/lib/libtest.py 2025-10-08 16:07:31.000000000 +0200 @@ -406,7 +406,7 @@ return r def check(self, tool, ce_output_path): - self.log.print("terminal output of inline:") + self.log.print("terminal output of " + os.path.basename(tool.args[0]) + ":") self.log.print(tool.stdout.decode()) should_xfail = self.extract_should_xfail() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/enum-11.c new/clang-extract-0~20251008.e818417/testsuite/small/enum-11.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/enum-11.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/small/enum-11.c 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,14 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +enum consts { + CST0 = 0, + CST1, +#include "enums.h" +}; + +enum consts f(void) +{ + return CST2; +} + +/* { dg-final { scan-tree-dump "CST2," } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/enum-6.c new/clang-extract-0~20251008.e818417/testsuite/small/enum-6.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/enum-6.c 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/testsuite/small/enum-6.c 2025-10-08 16:07:31.000000000 +0200 @@ -16,4 +16,4 @@ /* { dg-final { scan-tree-dump "ANOTHER_CONST = 1 << CONST0" } } */ /* { dg-final { scan-tree-dump "return ANOTHER_CONST;" } } */ -/* { dg-final { scan-tree-dump "enum *{\n *CONST0" } } */ +/* { dg-final { scan-tree-dump "enum\n? *{\n? *CONST0" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/enum-8.c new/clang-extract-0~20251008.e818417/testsuite/small/enum-8.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/enum-8.c 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/testsuite/small/enum-8.c 2025-10-08 16:07:31.000000000 +0200 @@ -32,6 +32,6 @@ } /* { dg-final { scan-tree-dump "TRACE_EVENT_FL_TRACEPOINT_BIT," } } */ -/* { dg-final { scan-tree-dump "TRACE_EVENT_FL_TRACEPOINT *= \(1 << TRACE_EVENT_FL_TRACEPOINT_BIT\)," } } */ +/* { dg-final { scan-tree-dump "TRACE_EVENT_FL_TRACEPOINT( |\t)*= \(1 << TRACE_EVENT_FL_TRACEPOINT_BIT\)," } } */ /* { dg-final { scan-tree-dump "#define MACRO TRACE_EVENT_FL_TRACEPOINT" } } */ /* { dg-final { scan-tree-dump "return 1 \+ MACRO;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/enums.h new/clang-extract-0~20251008.e818417/testsuite/small/enums.h --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/enums.h 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/small/enums.h 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,2 @@ +CST2, +CST3, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/fields.h new/clang-extract-0~20251008.e818417/testsuite/small/fields.h --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/fields.h 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/small/fields.h 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,2 @@ +int field2; +int field3; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/ifdef-1.c new/clang-extract-0~20251008.e818417/testsuite/small/ifdef-1.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/ifdef-1.c 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/testsuite/small/ifdef-1.c 2025-10-08 16:07:31.000000000 +0200 @@ -1,7 +1,4 @@ /* { dg-options "-DCE_EXTRACT_FUNCTIONS=function -DCE_NO_EXTERNALIZATION" }*/ -/* { dg-xfail } Tests fails because we currently can't track that the endif - comes from #ifdef AAA. */ - //#define AA diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/ifdef-2.c new/clang-extract-0~20251008.e818417/testsuite/small/ifdef-2.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/ifdef-2.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/small/ifdef-2.c 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,30 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +#define SHARED + +#define IS_IN(x) 0 + +#ifndef SHARED +# define GLRO(name) _##name +#else +# if IS_IN (rtld) +# define GLRO(name) _rtld_local_ro._##name +# else +# define GLRO(name) _rtld_global_ro._##name +# endif +struct rtld_global_ro +{ +#endif + int field1; +#ifdef SHARED + int field2; +}; +#endif + + +int f(struct rtld_global_ro *r) +{ + return r->field1; +} + +/* { dg-final { scan-tree-dump "struct rtld_global_ro ?\n?{" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/record-12.c new/clang-extract-0~20251008.e818417/testsuite/small/record-12.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/record-12.c 1970-01-01 01:00:00.000000000 +0100 +++ new/clang-extract-0~20251008.e818417/testsuite/small/record-12.c 2025-10-08 16:07:31.000000000 +0200 @@ -0,0 +1,15 @@ +/* { dg-options "-DCE_EXTRACT_FUNCTIONS=f -DCE_NO_EXTERNALIZATION" }*/ + +struct record { + int field1; +# include "fields.h" + int field4; +}; + +int f(struct record *r) +{ + return r->field2; +} + +/* { dg-final { scan-tree-dump "struct record {" } } */ +/* { dg-final { scan-tree-dump "int field2;" } } */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/clang-extract-0~20250710.ac81bbb/testsuite/small/typedef-6.c new/clang-extract-0~20251008.e818417/testsuite/small/typedef-6.c --- old/clang-extract-0~20250710.ac81bbb/testsuite/small/typedef-6.c 2025-07-10 16:18:24.000000000 +0200 +++ new/clang-extract-0~20251008.e818417/testsuite/small/typedef-6.c 2025-10-08 16:07:31.000000000 +0200 @@ -21,8 +21,8 @@ return a->y; } -/* { dg-final { scan-tree-dump "enum CONSTANT {\n *CONST1,\n *CONST2\n};" } } */ -/* { dg-final { scan-tree-dump "enum CONSTANT2 {\n *AAAA,\n *BBBB\n};" } } */ +/* { dg-final { scan-tree-dump "enum CONSTANT {\n *CONST1,\n *CONST2,?\n};" } } */ +/* { dg-final { scan-tree-dump "enum CONSTANT2 {\n *AAAA,\n *BBBB,?\n};" } } */ /* { dg-final { scan-tree-dump "typedef int \(\*GEN_SESSION_CB\)\(enum CONSTANT \*, enum CONSTANT2 \*\);" } } */ /* { dg-final { scan-tree-dump "struct A {\n *GEN_SESSION_CB a;\n *int y;\n};" } } */ /* { dg-final { scan-tree-dump "int f" } } */
