From 30d433e5e49c6b5864e5ca7d8aa7cf30cf3191e2 Mon Sep 17 00:00:00 2001 From: Taylor Foxhall Date: Sun, 30 Mar 2025 15:50:50 -0400 Subject: [PATCH 1/9] Add support for LLVM 19 Implements #276 --- clang_delta/ExpressionDetector.cpp | 29 +++++++++++++++++++++++++++-- clang_delta/RemoveNamespace.cpp | 4 ++++ clang_delta/RenameCXXMethod.cpp | 4 ++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/clang_delta/ExpressionDetector.cpp b/clang_delta/ExpressionDetector.cpp index cf703924..22bdfcff 100644 --- a/clang_delta/ExpressionDetector.cpp +++ b/clang_delta/ExpressionDetector.cpp @@ -64,7 +64,8 @@ class IncludesPPCallbacks : public PPCallbacks { StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, OptionalFileEntryRef File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported, + const Module *SuggestedModule, + bool ModuleImported, SrcMgr::CharacteristicKind FileType) override; private: @@ -85,7 +86,8 @@ void IncludesPPCallbacks::InclusionDirective(SourceLocation HashLoc, OptionalFileEntryRef /*File*/, StringRef /*SearchPath*/, StringRef /*RelativePath*/, - const Module * /*Imported*/, + const Module * /*SuggestedModule*/, + bool /*ModuleImported*/, SrcMgr::CharacteristicKind /*FileType*/) { if (!SrcManager.isInMainFile(HashLoc)) @@ -118,7 +120,11 @@ bool LocalTmpVarCollector::VisitDeclRefExpr(DeclRefExpr *DRE) const VarDecl *VD = dyn_cast(DRE->getDecl()); if (!VD) return true; +#if LLVM_VERSION_MAJOR >= 19 + if (VD->getName().starts_with(Prefix)) +#else if (VD->getName().startswith(Prefix)) +#endif TmpVars.push_back(VD); return true; } @@ -363,7 +369,11 @@ void ExpressionDetector::addOneTempVar(const VarDecl *VD) { if (!VD) return; +#if LLVM_VERSION_MAJOR >= 19 + if (!VD->getName().starts_with(TmpVarNamePrefix)) +#else if (!VD->getName().startswith(TmpVarNamePrefix)) +#endif return; if (const Expr *E = VD->getInit()) ProcessedExprs[VD] = E->IgnoreParenImpCasts(); @@ -374,9 +384,15 @@ bool ExpressionDetector::refToTmpVar(const NamedDecl *ND) StringRef Name = ND->getName(); // We don't want to repeatly replace temporary variables // __creduce_expr_tmp_xxx, __creduce_printed_yy and __creduce_checked_zzz. +#if LLVM_VERSION_MAJOR >= 19 + return Name.starts_with(TmpVarNamePrefix) || + Name.starts_with(PrintedVarNamePrefix) || + Name.starts_with(CheckedVarNamePrefix); +#else return Name.startswith(TmpVarNamePrefix) || Name.startswith(PrintedVarNamePrefix) || Name.startswith(CheckedVarNamePrefix); +#endif } // Reference: IdenticalExprChecker.cpp from Clang @@ -524,8 +540,13 @@ bool ExpressionDetector::isValidExpr(Stmt *S, const Expr *E) if (const DeclRefExpr *SubE = dyn_cast(UO->getSubExpr()->IgnoreParenCasts())) { StringRef SubEName = SubE->getDecl()->getName(); +#if LLVM_VERSION_MAJOR >= 19 + if (SubEName.starts_with(PrintedVarNamePrefix) || + SubEName.starts_with(CheckedVarNamePrefix)) +#else if (SubEName.startswith(PrintedVarNamePrefix) || SubEName.startswith(CheckedVarNamePrefix)) +#endif return false; } } @@ -541,7 +562,11 @@ bool ExpressionDetector::isValidExpr(Stmt *S, const Expr *E) bool IsLit = SC == Stmt::IntegerLiteralClass || SC == Stmt::FloatingLiteralClass; if (IsLit && DRE && +#if LLVM_VERSION_MAJOR >= 19 + DRE->getDecl()->getName().starts_with(TmpVarNamePrefix) && +#else DRE->getDecl()->getName().startswith(TmpVarNamePrefix) && +#endif S->getStmtClass() == Stmt::IfStmtClass) { return false; } diff --git a/clang_delta/RemoveNamespace.cpp b/clang_delta/RemoveNamespace.cpp index 0f8fc427..82cd3b82 100644 --- a/clang_delta/RemoveNamespace.cpp +++ b/clang_delta/RemoveNamespace.cpp @@ -944,7 +944,11 @@ void RemoveNamespace::handleOneNamedDecl(const NamedDecl *ND, TransAssert(IdInfo && "Invalid IdentifierInfo!"); NewName += IdInfo->getName(); // Make sure we have valid suffix for user literals +#if LLVM_VERSION_MAJOR >= 19 + if (IsUserLiteral && IdInfo->getName().starts_with("_")) { +#else if (IsUserLiteral && IdInfo->getName().startswith("_")) { +#endif NewName = "_" + NewName; } NamedDeclToNewName[ND] = NewName; diff --git a/clang_delta/RenameCXXMethod.cpp b/clang_delta/RenameCXXMethod.cpp index e71cc738..680c03da 100644 --- a/clang_delta/RenameCXXMethod.cpp +++ b/clang_delta/RenameCXXMethod.cpp @@ -426,7 +426,11 @@ bool RenameCXXMethod::isValidName(const StringRef &Name) { size_t PrefixLen = MethodNamePrefix.length(); StringRef NamePrefix = Name.substr(0, PrefixLen); +#if LLVM_VERSION_MAJOR >= 19 + if (NamePrefix != MethodNamePrefix) +#else if (!NamePrefix.equals(MethodNamePrefix)) +#endif return false; llvm::APInt Num; return !Name.drop_front(PrefixLen).getAsInteger(10, Num); From fe93d889f08938fdc5e531172c37d57a741a6479 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Fri, 18 Jul 2025 16:38:03 -0700 Subject: [PATCH 2/9] Add clang-20 support Use new signature for createDiagnostics() API Signed-off-by: Khem Raj --- clang_delta/Transformation.cpp | 2 +- clang_delta/TransformationManager.cpp | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clang_delta/Transformation.cpp b/clang_delta/Transformation.cpp index b350eec5..707a0209 100644 --- a/clang_delta/Transformation.cpp +++ b/clang_delta/Transformation.cpp @@ -95,7 +95,7 @@ void Transformation::Initialize(ASTContext &context) void Transformation::outputTransformedSource(llvm::raw_ostream &OutStream) { FileID MainFileID = SrcManager->getMainFileID(); - const RewriteBuffer *RWBuf = TheRewriter.getRewriteBufferFor(MainFileID); + const llvm::RewriteBuffer *RWBuf = TheRewriter.getRewriteBufferFor(MainFileID); // RWBuf is non-empty upon any rewrites TransAssert(RWBuf && "Empty RewriteBuffer!"); diff --git a/clang_delta/TransformationManager.cpp b/clang_delta/TransformationManager.cpp index 79b17cee..e16e07ce 100644 --- a/clang_delta/TransformationManager.cpp +++ b/clang_delta/TransformationManager.cpp @@ -24,6 +24,7 @@ #include "clang/Lex/PreprocessorOptions.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Parse/ParseAST.h" +#include "llvm/Support/VirtualFileSystem.h" // For llvm::vfs::get GlobalVirtualFileSystem() #include "Transformation.h" @@ -90,8 +91,14 @@ bool TransformationManager::initializeCompilerInstance(std::string &ErrorMsg) ClangInstance = new CompilerInstance(); assert(ClangInstance); - + +#if LLVM_VERSION_MAJOR >= 20 + // Get the global virtual file system + auto VFS = llvm::vfs::getRealFileSystem(); + ClangInstance->createDiagnostics(*VFS); +#else ClangInstance->createDiagnostics(); +#endif TargetOptions &TargetOpts = ClangInstance->getTargetOpts(); PreprocessorOptions &PPOpts = ClangInstance->getPreprocessorOpts(); From 873c0a690a3fb8e05362a3d70f0f79105e883868 Mon Sep 17 00:00:00 2001 From: Bradley Walters Date: Fri, 2 Jan 2026 21:36:49 -0800 Subject: [PATCH 3/9] clang-21: fix DTST->getIdentifier() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - **Line 7086-7089**: Stores `NestedNameSpecifier *NNS` and `const IdentifierInfo *Name` as separate membe rs - **Line 7098-7099**: Provides `getQualifier()` and `getIdentifier()` methods - **Line 7258**: Now stores a single `DependentTemplateStorage Name` member (instead of separate NNS and I dentifierInfo) - **Line 7266-7268**: Provides `getDependentTemplateName()` method that returns `const DependentTemplateSt orage&` - **Removed**: `getQualifier()` and `getIdentifier()` methods are gone The `DependentTemplateStorage` class (defined in TemplateName.h:582-621) provides: - `getQualifier()` → returns `NestedNameSpecifier*` - `getName()` → returns `IdentifierOrOverloadedOperator` The `IdentifierOrOverloadedOperator` struct (TemplateName.h:545-572) provides: - `getIdentifier()` → returns `const IdentifierInfo*` The failing code at CommonRenameClassRewriteVisitor.h:313: ```cpp const IdentifierInfo *IdInfo = DTST->getIdentifier(); ``` Should be changed to: ```cpp const IdentifierInfo *IdInfo = DTST->getDependentTemplateName().getName().getIdentifier(); ``` This chains the new API calls: 1. `getDependentTemplateName()` returns the `DependentTemplateStorage` 2. `getName()` returns the `IdentifierOrOverloadedOperator` 3. `getIdentifier()` returns the `const IdentifierInfo*` --- clang_delta/CommonRenameClassRewriteVisitor.h | 4 ++++ clang_delta/RemoveNamespace.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/clang_delta/CommonRenameClassRewriteVisitor.h b/clang_delta/CommonRenameClassRewriteVisitor.h index 371bebbe..94b3f6fb 100644 --- a/clang_delta/CommonRenameClassRewriteVisitor.h +++ b/clang_delta/CommonRenameClassRewriteVisitor.h @@ -310,7 +310,11 @@ template bool CommonRenameClassRewriteVisitor:: dyn_cast(Ty); TransAssert(DTST && "Bad DependentTemplateSpecializationType!"); +#if LLVM_VERSION_MAJOR >= 21 + const IdentifierInfo *IdInfo = DTST->getDependentTemplateName().getName().getIdentifier(); +#else const IdentifierInfo *IdInfo = DTST->getIdentifier(); +#endif std::string IdName = IdInfo->getName().str(); std::string Name; if (getNewNameByName(IdName, Name)) { diff --git a/clang_delta/RemoveNamespace.cpp b/clang_delta/RemoveNamespace.cpp index 82cd3b82..5f2c4b4e 100644 --- a/clang_delta/RemoveNamespace.cpp +++ b/clang_delta/RemoveNamespace.cpp @@ -440,7 +440,11 @@ bool RemoveNamespaceRewriteVisitor::VisitDependentTemplateSpecializationTypeLoc( dyn_cast(Ty); TransAssert(DTST && "Bad DependentTemplateSpecializationType!"); +#if LLVM_VERSION_MAJOR >= 21 + const IdentifierInfo *IdInfo = DTST->getDependentTemplateName().getName().getIdentifier(); +#else const IdentifierInfo *IdInfo = DTST->getIdentifier(); +#endif std::string IdName = IdInfo->getName().str(); std::string Name; From e3eabd0ee27b480ab68a822f75c9a8a5f58490c0 Mon Sep 17 00:00:00 2001 From: Bradley Walters Date: Fri, 2 Jan 2026 21:40:22 -0800 Subject: [PATCH 4/9] clang-21: remove TypeSpecWithTemplate The enum has **6 values**: - Line 79-102: `Identifier`, `Namespace`, `NamespaceAlias`, `TypeSpec`, **`TypeSpecWithTemplate`**, `Globa l`, `Super` - Line 52-56: Storage enum includes `StoredTypeSpec = 2` and `StoredTypeSpecWithTemplate = 3` The enum has **5 values** (one removed): - Line 78-97: `Identifier`, `Namespace`, `NamespaceAlias`, `TypeSpec`, `Global`, `Super` - **`TypeSpecWithTemplate` was removed** - Line 52-55: Storage enum only has `StoredTypeSpec = 2` (no `StoredTypeSpecWithTemplate`) In LLVM 21, the distinction between `TypeSpec` and `TypeSpecWithTemplate` was eliminated. The `template` k eyword information is now stored differently (likely in the `TypeLoc` or associated location information r ather than in the specifier kind). Since both cases were doing the same thing (calling `TraverseTypeLoc`), and LLVM 21 merged them into a sin gle `TypeSpec` case, simply removing the `TypeSpecWithTemplate` case is the correct fix. The functionality remains the same because type specs with or without template keywords now both use the `TypeSpec` enum va lue. --- clang_delta/RemoveNamespace.cpp | 6 ++++-- clang_delta/Transformation.cpp | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/clang_delta/RemoveNamespace.cpp b/clang_delta/RemoveNamespace.cpp index 5f2c4b4e..dbef31eb 100644 --- a/clang_delta/RemoveNamespace.cpp +++ b/clang_delta/RemoveNamespace.cpp @@ -566,8 +566,10 @@ bool RemoveNamespaceRewriteVisitor::TraverseNestedNameSpecifierLoc( ND = NAD->getNamespace()->getCanonicalDecl(); break; } - case NestedNameSpecifier::TypeSpec: // Fall-through - case NestedNameSpecifier::TypeSpecWithTemplate: +#if LLVM_VERSION_MAJOR < 21 + case NestedNameSpecifier::TypeSpecWithTemplate: // Fall-through +#endif + case NestedNameSpecifier::TypeSpec: TraverseTypeLoc(Loc.getTypeLoc()); break; default: diff --git a/clang_delta/Transformation.cpp b/clang_delta/Transformation.cpp index 707a0209..7567d757 100644 --- a/clang_delta/Transformation.cpp +++ b/clang_delta/Transformation.cpp @@ -635,8 +635,10 @@ const DeclContext *Transformation::getDeclContextFromSpecifier( const NamespaceAliasDecl *NAD = NNS->getAsNamespaceAlias(); return NAD->getNamespace()->getCanonicalDecl(); } - case NestedNameSpecifier::TypeSpec: // Fall-through - case NestedNameSpecifier::TypeSpecWithTemplate: { +#if LLVM_VERSION_MAJOR < 21 + case NestedNameSpecifier::TypeSpecWithTemplate: // Fall-through +#endif + case NestedNameSpecifier::TypeSpec: { const Type *Ty = NNS->getAsType(); if (const RecordType *RT = Ty->getAs()) return RT->getDecl(); From 9556d0d915d3aca80b203cd38cf16a42c188166d Mon Sep 17 00:00:00 2001 From: Bradley Walters Date: Fri, 2 Jan 2026 21:41:44 -0800 Subject: [PATCH 5/9] clang-21: OpenCLKernelAttr --> DeviceKernelAttr The following kernel attributes existed: - `OpenCLKernelAttr` - for OpenCL kernels - `NVPTXKernelAttr` - for NVIDIA PTX kernels - `SYCLKernelAttr` - for SYCL kernels The attribute system was refactored: - **`OpenCLKernelAttr` was removed** - **`NVPTXKernelAttr` was removed** - Replaced with a unified `DeviceKernelAttr` attribute - `SYCLKernelEntryPointAttr` exists for SYCL-specific entry points LLVM 21 consolidated the various kernel attributes (`OpenCLKernelAttr`, `NVPTXKernelAttr`, etc.) into a si ngle unified `DeviceKernelAttr` that works across different device programming models (OpenCL, CUDA, etc.) . This change reflects the consolidation of kernel attributes in LLVM 21. The `DeviceKernelAttr` now covers what `OpenCLKernelAttr` (and other kernel attributes) used to represent. **Purpose**: The code is checking if a function is a kernel function that should not be removed even if it appears unused, since kernel functions are entry points called by the runtime. The new `DeviceKernelAttr` serves this same purpose across all device programming models. --- clang_delta/RemoveUnusedFunction.cpp | 4 ++++ clang_delta/RenameFun.cpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/clang_delta/RemoveUnusedFunction.cpp b/clang_delta/RemoveUnusedFunction.cpp index f0632be5..225942ed 100644 --- a/clang_delta/RemoveUnusedFunction.cpp +++ b/clang_delta/RemoveUnusedFunction.cpp @@ -254,7 +254,11 @@ bool RUFAnalysisVisitor::VisitFunctionDecl(FunctionDecl *FD) if (FD->isReferenced() || FD->isMain() || +#if LLVM_VERSION_MAJOR >= 21 + FD->hasAttr() || +#else FD->hasAttr() || +#endif ConsumerInstance->hasReferencedSpecialization(CanonicalFD) || ConsumerInstance->isInlinedSystemFunction(CanonicalFD) || ConsumerInstance->isInReferencedSet(CanonicalFD) || diff --git a/clang_delta/RenameFun.cpp b/clang_delta/RenameFun.cpp index 8dee2431..f7c2255e 100644 --- a/clang_delta/RenameFun.cpp +++ b/clang_delta/RenameFun.cpp @@ -261,7 +261,11 @@ void RenameFun::addFun(const FunctionDecl *FD) { std::string Name = FD->getNameAsString(); // Skip special functions +#if LLVM_VERSION_MAJOR >= 21 + if (isSpecialFun(Name) || FD->hasAttr()) +#else if (isSpecialFun(Name) || FD->hasAttr()) +#endif FunToNameMap[FD] = Name; if (FunToNameMap.find(FD) != FunToNameMap.end()) From 4dd7bcc21321738bcc78d0d9c1909b4687a4b13a Mon Sep 17 00:00:00 2001 From: Bradley Walters Date: Fri, 2 Jan 2026 21:46:36 -0800 Subject: [PATCH 6/9] clang-21: avoid deprecated FileManager::getDirectory The deprecated `getDirectory()` method that returned `ErrorOr` was removed in LLVM 21. The migration path is to use `getOptionalDirectoryRef()` which returns an `OptionalDirectoryEntryRef`. **Why this works**: - The original code checks the boolean value of the `ErrorOr` result (true if directory exists, false otherwise) - The new code checks the boolean value of the `OptionalDirectoryEntryRef` (true if directory exists, false otherwise) - Both support implicit conversion to bool in the same way, so the logic remains identical --- clang_delta/TransformationManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang_delta/TransformationManager.cpp b/clang_delta/TransformationManager.cpp index e16e07ce..3768c215 100644 --- a/clang_delta/TransformationManager.cpp +++ b/clang_delta/TransformationManager.cpp @@ -132,7 +132,7 @@ bool TransformationManager::initializeCompilerInstance(std::string &ErrorMsg) ClangInstance->createFileManager(); if(CLCPath != NULL && ClangInstance->hasFileManager() && - ClangInstance->getFileManager().getDirectory(CLCPath, false)) { + ClangInstance->getFileManager().getOptionalDirectoryRef(CLCPath, false)) { Args.push_back("-I"); Args.push_back(CLCPath); } From a392c5750006fc265772d24b08525f0905f55ed5 Mon Sep 17 00:00:00 2001 From: Bradley Walters Date: Fri, 2 Jan 2026 21:49:46 -0800 Subject: [PATCH 7/9] clang-21: call CompilerInvocation::getTargetOpts **LLVM 20 & 21 (CompilerInvocation.h:80)**: - `TargetOpts` is a **protected** member in `CompilerInvocationBase` - Direct access like `.TargetOpts` is not allowed from outside the class **Solution**: Use the public getter method `getTargetOpts()` instead of direct member access **LLVM 20 (TargetInfo.h:305-306)**: - Signature: `CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr &Opts)` - Accepts a `std::shared_ptr` (shared pointer) **LLVM 21 (TargetInfo.h:316-317)**: - Signature: `CreateTargetInfo(DiagnosticsEngine &Diags, TargetOptions &Opts)` - Accepts a `TargetOptions &` (reference) 1. The code was directly accessing the protected member `TargetOpts` instead of using the public getter 2. The `CreateTargetInfo` API changed from accepting a `shared_ptr` to accepting a reference **Why this works**: 1. `getTargetOpts()` is a public method (defined at line 250 in `CompilerInvocation`) that returns `TargetOptions &` 2. This matches the new LLVM 21 signature that expects `TargetOptions &` instead of `std::shared_ptr` 3. The getter dereferences the shared_ptr internally (`return *TargetOpts`), providing the reference that the new API needs --- clang_delta/TransformationManager.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang_delta/TransformationManager.cpp b/clang_delta/TransformationManager.cpp index 3768c215..2ed20cb0 100644 --- a/clang_delta/TransformationManager.cpp +++ b/clang_delta/TransformationManager.cpp @@ -153,8 +153,13 @@ bool TransformationManager::initializeCompilerInstance(std::string &ErrorMsg) } TargetInfo *Target = +#if LLVM_VERSION_MAJOR >= 21 + TargetInfo::CreateTargetInfo(ClangInstance->getDiagnostics(), + ClangInstance->getInvocation().getTargetOpts()); +#else TargetInfo::CreateTargetInfo(ClangInstance->getDiagnostics(), ClangInstance->getInvocation().TargetOpts); +#endif ClangInstance->setTarget(Target); if (const char *env = getenv("CREDUCE_INCLUDE_PATH")) { From 2c8a6064b2b54785445f6160287415bfebddada8 Mon Sep 17 00:00:00 2001 From: Bradley Walters Date: Fri, 2 Jan 2026 22:02:30 -0800 Subject: [PATCH 8/9] unifdef: constexpr is reserved in C23 --- unifdef/unifdef.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unifdef/unifdef.c b/unifdef/unifdef.c index 5c67cd44..692a1640 100644 --- a/unifdef/unifdef.c +++ b/unifdef/unifdef.c @@ -201,7 +201,7 @@ static int depth; /* current #if nesting */ static int delcount; /* count of deleted lines */ static unsigned blankcount; /* count of blank lines */ static unsigned blankmax; /* maximum recent blankcount */ -static bool constexpr; /* constant #if expression */ +static bool isconstexpr; /* constant #if expression */ static bool zerosyms; /* to format symdepth output */ static bool firstsym; /* ditto */ @@ -1078,7 +1078,7 @@ eval_unary(const struct ops *ops, long *valp, const char **cpp) *valp = (value[sym] != NULL); lt = *valp ? LT_TRUE : LT_FALSE; } - constexpr = false; + isconstexpr = false; } else if (!endsym(*cp)) { debug("eval%d symbol", prec(ops)); sym = findsym(&cp); @@ -1095,7 +1095,7 @@ eval_unary(const struct ops *ops, long *valp, const char **cpp) lt = *valp ? LT_TRUE : LT_FALSE; cp = skipargs(cp); } - constexpr = false; + isconstexpr = false; } else { debug("eval%d bad expr", prec(ops)); return (LT_ERROR); @@ -1162,10 +1162,10 @@ ifeval(const char **cpp) long val = 0; debug("eval %s", *cpp); - constexpr = killconsts ? false : true; + isconstexpr = killconsts ? false : true; ret = eval_table(eval_ops, &val, cpp); debug("eval = %d", val); - return (constexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); + return (isconstexpr ? LT_IF : ret == LT_ERROR ? LT_IF : ret); } /* From 795e09bca9b5185bfbf6176a1a918154c765faab Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Thu, 10 Sep 2026 17:07:01 +0200 Subject: [PATCH 9/9] clang-22 support --- clang_delta/CommonParameterRewriteVisitor.h | 4 + clang_delta/CommonRenameClassRewriteVisitor.h | 4 + clang_delta/EmptyStructToInt.cpp | 4 + clang_delta/InstantiateTemplateParam.cpp | 2 + clang_delta/RemoveBaseClass.cpp | 9 ++ clang_delta/RemoveNamespace.cpp | 94 ++++++++++++++++++- clang_delta/RemoveNamespace.h | 7 +- clang_delta/RemoveNestedFunction.cpp | 4 + clang_delta/RemoveUnusedFunction.cpp | 31 +++++- clang_delta/RemoveUnusedFunction.h | 6 +- clang_delta/ReplaceDependentName.cpp | 6 ++ clang_delta/ReplaceDependentName.h | 6 ++ clang_delta/ReplaceDependentTypedef.cpp | 2 + clang_delta/ReplaceSimpleTypedef.cpp | 4 + clang_delta/SimplifyDependentTypedef.cpp | 9 +- clang_delta/TemplateArgToInt.cpp | 2 + clang_delta/Transformation.cpp | 62 ++++++++++++ clang_delta/Transformation.h | 4 + clang_delta/TransformationManager.cpp | 6 +- 19 files changed, 258 insertions(+), 8 deletions(-) diff --git a/clang_delta/CommonParameterRewriteVisitor.h b/clang_delta/CommonParameterRewriteVisitor.h index ba59e931..79641adc 100644 --- a/clang_delta/CommonParameterRewriteVisitor.h +++ b/clang_delta/CommonParameterRewriteVisitor.h @@ -111,7 +111,11 @@ bool CommonParameterRewriteVisitor::VisitCallExpr( (DName.getNameKind() == clang::DeclarationName::CXXOperatorName)) && "Not an indentifier!"); +#if LLVM_VERSION_MAJOR >= 22 + if (clang::NestedNameSpecifier NNS = UE->getQualifier()) { +#else if (const clang::NestedNameSpecifier *NNS = UE->getQualifier()) { +#endif if (const clang::DeclContext *Ctx = ConsumerInstance->getDeclContextFromSpecifier(NNS)) { DeclContextSet VisitedCtxs; diff --git a/clang_delta/CommonRenameClassRewriteVisitor.h b/clang_delta/CommonRenameClassRewriteVisitor.h index 94b3f6fb..670a386c 100644 --- a/clang_delta/CommonRenameClassRewriteVisitor.h +++ b/clang_delta/CommonRenameClassRewriteVisitor.h @@ -54,8 +54,10 @@ class CommonRenameClassRewriteVisitor : public RecursiveASTVisitor { bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc); +#if LLVM_VERSION_MAJOR < 22 bool VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc DTSLoc); +#endif bool VisitClassTemplateSpecializationDecl( ClassTemplateSpecializationDecl *TSD); @@ -301,6 +303,7 @@ bool CommonRenameClassRewriteVisitor::VisitRecordTypeLoc(RecordTypeLoc RTLoc) return true; } +#if LLVM_VERSION_MAJOR < 22 template bool CommonRenameClassRewriteVisitor:: VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc DTSLoc) @@ -324,6 +327,7 @@ template bool CommonRenameClassRewriteVisitor:: return true; } +#endif template void CommonRenameClassRewriteVisitor::renameTemplateName( diff --git a/clang_delta/EmptyStructToInt.cpp b/clang_delta/EmptyStructToInt.cpp index d53a7a2f..132d3f58 100644 --- a/clang_delta/EmptyStructToInt.cpp +++ b/clang_delta/EmptyStructToInt.cpp @@ -64,7 +64,9 @@ class EmptyStructToIntRewriteVisitor : public bool VisitRecordTypeLoc(RecordTypeLoc RTLoc); +#if LLVM_VERSION_MAJOR < 22 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc Loc); +#endif bool VisitRecordDecl(RecordDecl *RD); @@ -137,6 +139,7 @@ bool EmptyStructToIntRewriteVisitor::VisitRecordTypeLoc(RecordTypeLoc RTLoc) return true; } +#if LLVM_VERSION_MAJOR < 22 bool EmptyStructToIntRewriteVisitor::VisitElaboratedTypeLoc( ElaboratedTypeLoc Loc) { @@ -195,6 +198,7 @@ bool EmptyStructToIntRewriteVisitor::VisitElaboratedTypeLoc( ConsumerInstance->TheRewriter.RemoveText(SourceRange(StartLoc, EndLoc)); return true; } +#endif bool EmptyStructToIntRewriteVisitor::VisitRecordDecl(RecordDecl *RD) { diff --git a/clang_delta/InstantiateTemplateParam.cpp b/clang_delta/InstantiateTemplateParam.cpp index 20798bc6..a2b954e7 100644 --- a/clang_delta/InstantiateTemplateParam.cpp +++ b/clang_delta/InstantiateTemplateParam.cpp @@ -301,10 +301,12 @@ bool InstantiateTemplateParam::getTypeString( Type::TypeClass TC = Ty->getTypeClass(); switch (TC) { +#if LLVM_VERSION_MAJOR < 22 case Type::Elaborated: { const ElaboratedType *ETy = dyn_cast(Ty); return getTypeString(ETy->getNamedType(), Str, ForwardStr); } +#endif case Type::Typedef: { const TypedefType *TdefTy = dyn_cast(Ty); diff --git a/clang_delta/RemoveBaseClass.cpp b/clang_delta/RemoveBaseClass.cpp index e45f557e..f08aa457 100644 --- a/clang_delta/RemoveBaseClass.cpp +++ b/clang_delta/RemoveBaseClass.cpp @@ -223,7 +223,11 @@ void RemoveBaseClass::copyBaseClassDecls(void) bool RemoveBaseClass::isTheBaseClass(const CXXBaseSpecifier &Specifier) { +#if LLVM_VERSION_MAJOR >= 22 + const Type *Ty = Context->getCanonicalTagType(TheBaseClass).getTypePtr(); +#else const Type *Ty = TheBaseClass->getTypeForDecl(); +#endif return Context->hasSameType(Specifier.getType(), Ty->getCanonicalTypeInternal()); } @@ -276,7 +280,12 @@ void RemoveBaseClass::rewriteOneCtor(const CXXConstructorDecl *Ctor) const Type *Ty = (*I)->getBaseClass(); TransAssert(Ty && "Invalid Base Class Type!"); if (Context->hasSameType(Ty->getCanonicalTypeInternal(), +#if LLVM_VERSION_MAJOR >= 22 + Context->getCanonicalTagType(TheBaseClass).getTypePtr() + ->getCanonicalTypeInternal())) { +#else TheBaseClass->getTypeForDecl()->getCanonicalTypeInternal())) { +#endif Init = (*I); break; } diff --git a/clang_delta/RemoveNamespace.cpp b/clang_delta/RemoveNamespace.cpp index dbef31eb..35ca5dc0 100644 --- a/clang_delta/RemoveNamespace.cpp +++ b/clang_delta/RemoveNamespace.cpp @@ -91,8 +91,10 @@ class RemoveNamespaceRewriteVisitor : public bool VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TSPLoc); +#if LLVM_VERSION_MAJOR < 22 bool VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc DTSLoc); +#endif bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TyLoc); @@ -226,9 +228,16 @@ bool RemoveNamespaceRewriteVisitor::VisitUsingDecl(UsingDecl *D) // check if this UsingDecl refers to the namespaced being removed NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); TransAssert(QualifierLoc && "Bad QualifierLoc!"); +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifierLoc PrefixLoc; + if (QualifierLoc.getNestedNameSpecifier().getKind() == + NestedNameSpecifier::Kind::Namespace) + PrefixLoc = QualifierLoc.getAsNamespaceAndPrefix().Prefix; + NestedNameSpecifier NNS = D->getQualifier(); +#else NestedNameSpecifierLoc PrefixLoc = QualifierLoc.getPrefix(); - const NestedNameSpecifier *NNS = D->getQualifier(); +#endif TransAssert(NNS && "Bad NameSpecifier!"); if (ConsumerInstance->isTheNamespaceSpecifier(NNS) && (!PrefixLoc || ConsumerInstance->isGlobalNamespace(PrefixLoc))) { @@ -432,6 +441,7 @@ bool RemoveNamespaceRewriteVisitor::VisitTemplateSpecializationTypeLoc( // template struct Derived: public Base { // typename Derived::template Base* p1; // }; +#if LLVM_VERSION_MAJOR < 22 bool RemoveNamespaceRewriteVisitor::VisitDependentTemplateSpecializationTypeLoc( DependentTemplateSpecializationTypeLoc DTSLoc) { @@ -472,6 +482,7 @@ bool RemoveNamespaceRewriteVisitor::VisitDependentTemplateSpecializationTypeLoc( return true; } +#endif bool RemoveNamespaceRewriteVisitor::VisitInjectedClassNameTypeLoc( InjectedClassNameTypeLoc TyLoc) @@ -492,7 +503,11 @@ bool RemoveNamespaceRewriteVisitor::VisitInjectedClassNameTypeLoc( bool RemoveNamespaceRewriteVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TyLoc) { +#if LLVM_VERSION_MAJOR >= 22 + const TypedefNameDecl *D = TyLoc.getDecl(); +#else const TypedefNameDecl *D = TyLoc.getTypedefNameDecl(); +#endif std::string Name; if (ConsumerInstance->getNewName(D, Name)) { @@ -546,16 +561,53 @@ bool RemoveNamespaceRewriteVisitor::TraverseNestedNameSpecifierLoc( return true; SmallVector QualifierLocs; +#if LLVM_VERSION_MAJOR >= 22 + for (NestedNameSpecifierLoc Cur = QualifierLoc; Cur; ) { + QualifierLocs.push_back(Cur); + if (Cur.getNestedNameSpecifier().getKind() == + NestedNameSpecifier::Kind::Namespace) + Cur = Cur.getAsNamespaceAndPrefix().Prefix; + else if (Cur.getNestedNameSpecifier().getKind() == + NestedNameSpecifier::Kind::Type) + Cur = Cur.getAsTypeLoc().getPrefix(); + else + break; + } +#else for (; QualifierLoc; QualifierLoc = QualifierLoc.getPrefix()) QualifierLocs.push_back(QualifierLoc); +#endif while (!QualifierLocs.empty()) { NestedNameSpecifierLoc Loc = QualifierLocs.pop_back_val(); +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS = Loc.getNestedNameSpecifier(); + NestedNameSpecifier::Kind Kind = NNS.getKind(); +#else NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier(); NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); +#endif const NamespaceDecl *ND = NULL; switch (Kind) { +#if LLVM_VERSION_MAJOR >= 22 + case NestedNameSpecifier::Kind::Namespace: { + const NamespaceBaseDecl *NBD = NNS.getAsNamespaceAndPrefix().Namespace; + if (const NamespaceAliasDecl *NAD = dyn_cast(NBD)) { + if (!NAD->getQualifier()) + ND = NAD->getNamespace()->getCanonicalDecl(); + } + else { + ND = NBD->getNamespace()->getCanonicalDecl(); + } + break; + } + case NestedNameSpecifier::Kind::Type: + TraverseTypeLoc(Loc.getAsTypeLoc()); + break; + default: + break; +#else case NestedNameSpecifier::Namespace: { ND = NNS->getAsNamespace()->getCanonicalDecl(); break; @@ -574,6 +626,7 @@ bool RemoveNamespaceRewriteVisitor::TraverseNestedNameSpecifierLoc( break; default: break; +#endif } if (!ND) @@ -782,7 +835,11 @@ void RemoveNamespace::handleOneUsingShadowDecl(const UsingShadowDecl *UD, return; NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS = QualifierLoc.getNestedNameSpecifier(); +#else NestedNameSpecifier *NNS = QualifierLoc.getNestedNameSpecifier(); +#endif // QualifierLoc could be ::foo, whose PrefixLoc is invalid, e.g., // void foo(); @@ -790,7 +847,11 @@ void RemoveNamespace::handleOneUsingShadowDecl(const UsingShadowDecl *UD, // using ::foo; // void bar () { foo(); } // } +#if LLVM_VERSION_MAJOR >= 22 + if (NNS.getKind() != NestedNameSpecifier::Kind::Global) { +#else if (NNS->getKind() != NestedNameSpecifier::Global) { +#endif // NestedNameSpecifierLoc PrefixLoc = QualifierLoc.getPrefix(); RewriteHelper->getQualifierAsString(QualifierLoc, NewName); } @@ -1112,11 +1173,39 @@ bool RemoveNamespace::getNewNameByName(const std::string &Name, bool RemoveNamespace::isGlobalNamespace(NestedNameSpecifierLoc Loc) { +#if LLVM_VERSION_MAJOR >= 22 + return (Loc.getNestedNameSpecifier().getKind() == + NestedNameSpecifier::Kind::Global); +#else NestedNameSpecifier *NNS = Loc.getNestedNameSpecifier(); return (NNS->getKind() == NestedNameSpecifier::Global); +#endif } -bool RemoveNamespace::isTheNamespaceSpecifier(const NestedNameSpecifier *NNS) +bool RemoveNamespace::isTheNamespaceSpecifier( +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS) +{ + switch (NNS.getKind()) { + case NestedNameSpecifier::Kind::Namespace: { + const NamespaceBaseDecl *NBD = NNS.getAsNamespaceAndPrefix().Namespace; + if (const NamespaceAliasDecl *NAD = dyn_cast(NBD)) { + // we remove the namealias only when it doesn't have nestedspecifier + if (NAD->getQualifier()) + return false; + return (NAD->getNamespace()->getCanonicalDecl() == TheNamespaceDecl); + } + return (NBD->getNamespace()->getCanonicalDecl() == TheNamespaceDecl); + } + + default: + return false; + } + TransAssert(0 && "Unreachable code!"); + return false; +} +#else + const NestedNameSpecifier *NNS) { NestedNameSpecifier::SpecifierKind Kind = NNS->getKind(); switch (Kind) { @@ -1142,6 +1231,7 @@ bool RemoveNamespace::isTheNamespaceSpecifier(const NestedNameSpecifier *NNS) TransAssert(0 && "Unreachable code!"); return false; } +#endif bool RemoveNamespace::isSuffix(std::string &Name, std::string &SpecifierName) { diff --git a/clang_delta/RemoveNamespace.h b/clang_delta/RemoveNamespace.h index 4f1f9841..12f2f76b 100644 --- a/clang_delta/RemoveNamespace.h +++ b/clang_delta/RemoveNamespace.h @@ -117,7 +117,12 @@ friend class RemoveNamespaceRewriteVisitor; bool isGlobalNamespace(clang::NestedNameSpecifierLoc Loc); - bool isTheNamespaceSpecifier(const clang::NestedNameSpecifier *NNS); + bool isTheNamespaceSpecifier( +#if LLVM_VERSION_MAJOR >= 22 + clang::NestedNameSpecifier NNS); +#else + const clang::NestedNameSpecifier *NNS); +#endif void removeLastNamespaceFromUsingDecl(const clang::UsingDirectiveDecl *D, const clang::NamespaceDecl *ND); diff --git a/clang_delta/RemoveNestedFunction.cpp b/clang_delta/RemoveNestedFunction.cpp index 8948d76b..05a2a740 100644 --- a/clang_delta/RemoveNestedFunction.cpp +++ b/clang_delta/RemoveNestedFunction.cpp @@ -280,7 +280,11 @@ void RemoveNestedFunction::getNewTmpVariableStr(ASTContext &ASTCtx, (DName.getNameKind() == DeclarationName::CXXOperatorName)) && "Not an indentifier!"); const FunctionDecl *FD = NULL; +#if LLVM_VERSION_MAJOR >= 22 + if (NestedNameSpecifier NNS = UE->getQualifier()) { +#else if (const NestedNameSpecifier *NNS = UE->getQualifier()) { +#endif if (const DeclContext *Ctx = getDeclContextFromSpecifier(NNS)) { DeclContextSet VisitedCtxs; FD = lookupFunctionDecl(DName, Ctx, VisitedCtxs); diff --git a/clang_delta/RemoveUnusedFunction.cpp b/clang_delta/RemoveUnusedFunction.cpp index 225942ed..2bcdb462 100644 --- a/clang_delta/RemoveUnusedFunction.cpp +++ b/clang_delta/RemoveUnusedFunction.cpp @@ -755,7 +755,27 @@ RemoveUnusedFunction::lookupFunctionDeclShallow(const DeclarationName &DName, } const FunctionDecl *RemoveUnusedFunction::getFunctionDeclFromSpecifier( - const DeclarationName &Name, const NestedNameSpecifier *NNS) + const DeclarationName &Name, +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS) +{ + const FunctionDecl *FD = NULL; + switch (NNS.getKind()) { + case NestedNameSpecifier::Kind::Namespace: + FD = lookupFunctionDeclShallow(Name, + NNS.getAsNamespaceAndPrefix().Namespace->getNamespace()); + break; + case NestedNameSpecifier::Kind::Global: + FD = lookupFunctionDeclShallow(Name, + Context->getTranslationUnitDecl()); + break; + default: + return NULL; + } + return FD; +} +#else + const NestedNameSpecifier *NNS) { const FunctionDecl *FD = NULL; switch (NNS->getKind()) { @@ -776,6 +796,7 @@ const FunctionDecl *RemoveUnusedFunction::getFunctionDeclFromSpecifier( } return FD; } +#endif void RemoveUnusedFunction::handleOneUsingDecl(const FunctionDecl *CurrentFD, const UsingDecl *UD) @@ -784,7 +805,11 @@ void RemoveUnusedFunction::handleOneUsingDecl(const FunctionDecl *CurrentFD, return; VisitedUsingDecls.insert(UD); +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS = UD->getQualifier(); +#else const NestedNameSpecifier *NNS = UD->getQualifier(); +#endif if (!NNS) return; DeclarationName Name = UD->getUnderlyingDecl()->getDeclName(); @@ -843,7 +868,11 @@ void RemoveUnusedFunction::handleOneUnresolvedLookupExpr( if ((K != DeclarationName::CXXOperatorName) && (K != DeclarationName::Identifier)) return; +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS = E->getQualifier(); +#else const NestedNameSpecifier *NNS = E->getQualifier(); +#endif // we fail only if UE is invoked with some qualifier or // instantiation, e.g.: // namespace NS { template void foo(T&) { } } diff --git a/clang_delta/RemoveUnusedFunction.h b/clang_delta/RemoveUnusedFunction.h index 97124c5c..c40fdfda 100644 --- a/clang_delta/RemoveUnusedFunction.h +++ b/clang_delta/RemoveUnusedFunction.h @@ -144,8 +144,12 @@ friend class ExtraReferenceVisitorWrapper; const clang::DeclContext *Ctx); const clang::FunctionDecl *getFunctionDeclFromSpecifier( - const clang::DeclarationName &Name, + const clang::DeclarationName &Name, +#if LLVM_VERSION_MAJOR >= 22 + clang::NestedNameSpecifier NNS); +#else const clang::NestedNameSpecifier *NNS); +#endif void addOneReferencedFunction(const clang::FunctionDecl *FD); diff --git a/clang_delta/ReplaceDependentName.cpp b/clang_delta/ReplaceDependentName.cpp index 2c70b5ba..15238d8f 100644 --- a/clang_delta/ReplaceDependentName.cpp +++ b/clang_delta/ReplaceDependentName.cpp @@ -41,7 +41,9 @@ class ReplaceDependentNameCollectionVisitor : public bool VisitDependentNameTypeLoc(DependentNameTypeLoc TLoc); +#if LLVM_VERSION_MAJOR < 22 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc TLoc); +#endif private: ReplaceDependentName *ConsumerInstance; @@ -55,12 +57,14 @@ bool ReplaceDependentNameCollectionVisitor::VisitDependentNameTypeLoc( return true; } +#if LLVM_VERSION_MAJOR < 22 bool ReplaceDependentNameCollectionVisitor::VisitElaboratedTypeLoc( ElaboratedTypeLoc TLoc) { ConsumerInstance->handleOneElaboratedTypeLoc(TLoc); return true; } +#endif void ReplaceDependentName::Initialize(ASTContext &context) { @@ -94,6 +98,7 @@ void ReplaceDependentName::HandleTranslationUnit(ASTContext &Ctx) TransError = TransInternalError; } +#if LLVM_VERSION_MAJOR < 22 SourceLocation ReplaceDependentName::getElaboratedTypeLocBegin( const ElaboratedTypeLoc &TLoc) { @@ -150,6 +155,7 @@ void ReplaceDependentName::handleOneElaboratedTypeLoc( TheNameLocEnd = TLoc.getEndLoc(); } } +#endif void ReplaceDependentName::handleOneDependentNameTypeLoc( const DependentNameTypeLoc &TLoc) diff --git a/clang_delta/ReplaceDependentName.h b/clang_delta/ReplaceDependentName.h index 5a472374..45d64a84 100644 --- a/clang_delta/ReplaceDependentName.h +++ b/clang_delta/ReplaceDependentName.h @@ -19,7 +19,9 @@ namespace clang { class DeclGroupRef; class ASTContext; class DependentNameTypeLoc; +#if LLVM_VERSION_MAJOR < 22 class ElaboratedTypeLoc; +#endif } class ReplaceDependentNameCollectionVisitor; @@ -45,12 +47,16 @@ friend class ReplaceDependentNameCollectionVisitor; void handleOneDependentNameTypeLoc(const clang::DependentNameTypeLoc &TLoc); +#if LLVM_VERSION_MAJOR < 22 void handleOneElaboratedTypeLoc(const clang::ElaboratedTypeLoc &TLoc); +#endif void rewriteDependentName(); +#if LLVM_VERSION_MAJOR < 22 clang::SourceLocation getElaboratedTypeLocBegin( const clang::ElaboratedTypeLoc &TLoc); +#endif ReplaceDependentNameCollectionVisitor *CollectionVisitor; diff --git a/clang_delta/ReplaceDependentTypedef.cpp b/clang_delta/ReplaceDependentTypedef.cpp index 148998ea..ee00f1ed 100644 --- a/clang_delta/ReplaceDependentTypedef.cpp +++ b/clang_delta/ReplaceDependentTypedef.cpp @@ -111,6 +111,7 @@ bool ReplaceDependentTypedef::isValidType(const QualType &QT) case Type::DependentName: // fall-through return true; +#if LLVM_VERSION_MAJOR < 22 case Type::Elaborated: { const ElaboratedType *ETy = dyn_cast(Ty); ElaboratedTypeKeyword Keyword = ETy->getKeyword(); @@ -121,6 +122,7 @@ bool ReplaceDependentTypedef::isValidType(const QualType &QT) return ((Keyword == ETK_Typename) || (Keyword == ETK_None)); #endif } +#endif default: return false; diff --git a/clang_delta/ReplaceSimpleTypedef.cpp b/clang_delta/ReplaceSimpleTypedef.cpp index 6e7effe4..ad9d6506 100644 --- a/clang_delta/ReplaceSimpleTypedef.cpp +++ b/clang_delta/ReplaceSimpleTypedef.cpp @@ -58,7 +58,9 @@ class ReplaceSimpleTypedefRewriteVisitor : public bool VisitTypedefTypeLoc(TypedefTypeLoc Loc); +#if LLVM_VERSION_MAJOR < 22 bool VisitElaboratedTypeLoc(ElaboratedTypeLoc Loc); +#endif private: ReplaceSimpleTypedef *ConsumerInstance; @@ -103,6 +105,7 @@ bool ReplaceSimpleTypedefRewriteVisitor::VisitTypedefTypeLoc(TypedefTypeLoc Loc) // }; // S::Int g; // where S::Int is referred as an ElaboratedType +#if LLVM_VERSION_MAJOR < 22 bool ReplaceSimpleTypedefRewriteVisitor::VisitElaboratedTypeLoc( ElaboratedTypeLoc Loc) { @@ -125,6 +128,7 @@ bool ReplaceSimpleTypedefRewriteVisitor::VisitElaboratedTypeLoc( } return true; } +#endif void ReplaceSimpleTypedef::Initialize(ASTContext &context) { diff --git a/clang_delta/SimplifyDependentTypedef.cpp b/clang_delta/SimplifyDependentTypedef.cpp index ed3cc7ac..5cd3329e 100644 --- a/clang_delta/SimplifyDependentTypedef.cpp +++ b/clang_delta/SimplifyDependentTypedef.cpp @@ -199,9 +199,14 @@ void SimplifyDependentTypedef::handleOneTypedefDecl(const TypedefDecl *D) const Type *Ty = QT.getTypePtr(); Type::TypeClass TC = Ty->getTypeClass(); if ((TC != Type::DependentName) && +#if LLVM_VERSION_MAJOR < 22 (TC != Type::DependentTemplateSpecialization) && - (TC != Type::TemplateSpecialization) && - (TC != Type::Elaborated)) +#endif + (TC != Type::TemplateSpecialization) +#if LLVM_VERSION_MAJOR < 22 + && (TC != Type::Elaborated) +#endif + ) return; TemplateTypeParmTypeVisitor->setTypeSet(&TypeSet); diff --git a/clang_delta/TemplateArgToInt.cpp b/clang_delta/TemplateArgToInt.cpp index e8b44a2a..75d5d152 100644 --- a/clang_delta/TemplateArgToInt.cpp +++ b/clang_delta/TemplateArgToInt.cpp @@ -325,11 +325,13 @@ TemplateArgToInt::getSubstTemplateTypeParmType(const Type *Ty) { Type::TypeClass TC = Ty->getTypeClass(); switch (TC) { +#if LLVM_VERSION_MAJOR < 22 case Type::Elaborated: { const ElaboratedType *ETy = dyn_cast(Ty); const Type *NamedT = ETy->getNamedType().getTypePtr(); return getSubstTemplateTypeParmType(NamedT); } +#endif case Type::Typedef: { const TypedefType *TdefTy = dyn_cast(Ty); diff --git a/clang_delta/Transformation.cpp b/clang_delta/Transformation.cpp index 7567d757..9332c5c0 100644 --- a/clang_delta/Transformation.cpp +++ b/clang_delta/Transformation.cpp @@ -565,7 +565,11 @@ const FunctionDecl *Transformation::lookupFunctionDeclFromCtx( if (const UnresolvedUsingValueDecl *UUD = dyn_cast(*I)) { +#if LLVM_VERSION_MAJOR >= 22 + const NestedNameSpecifier NNS = UUD->getQualifier(); +#else const NestedNameSpecifier *NNS = UUD->getQualifier(); +#endif const DeclContext *Ctx = getDeclContextFromSpecifier(NNS); if (!Ctx) continue; @@ -621,6 +625,41 @@ const FunctionDecl *Transformation::lookupFunctionDecl( return lookupFunctionDecl(DName, ParentCtx, VisitedCtxs); } +const DeclContext *Transformation::getDeclContextFromSpecifier( +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier NNS) +{ + switch (NNS.getKind()) { + case NestedNameSpecifier::Kind::Namespace: { + return NNS.getAsNamespaceAndPrefix().Namespace->getNamespace() + ->getCanonicalDecl(); + } + case NestedNameSpecifier::Kind::Type: { + const Type *Ty = NNS.getAsType(); + if (const RecordType *RT = Ty->getAs()) + return RT->getDecl(); + if (const TypedefType *TT = Ty->getAs()) { + const TypedefNameDecl *TypeDecl = TT->getDecl(); + const Type *UnderlyingTy = TypeDecl->getUnderlyingType().getTypePtr(); + if (const RecordType *RT = UnderlyingTy->getAs()) + return RT->getDecl(); + if (const TemplateSpecializationType *TST = + UnderlyingTy->getAs()) { + return getBaseDeclFromTemplateSpecializationType(TST); + } + } + if (const TemplateSpecializationType *TST = + Ty->getAs()) { + return getBaseDeclFromTemplateSpecializationType(TST); + } + break; + } + default: + break; + } + return NULL; +} +#else const DeclContext *Transformation::getDeclContextFromSpecifier( const NestedNameSpecifier *NNS) { @@ -660,6 +699,7 @@ const DeclContext *Transformation::getDeclContextFromSpecifier( } return NULL; } +#endif bool Transformation::isSpecialRecordDecl(const RecordDecl *RD) { @@ -705,6 +745,7 @@ const CXXRecordDecl *Transformation::getBaseDeclFromType(const Type *Ty) return getBaseDeclFromTemplateSpecializationType(TSTy); } +#if LLVM_VERSION_MAJOR < 22 case Type::DependentTemplateSpecialization: { return NULL; } @@ -714,6 +755,7 @@ const CXXRecordDecl *Transformation::getBaseDeclFromType(const Type *Ty) const Type *NamedT = ETy->getNamedType().getTypePtr(); return getBaseDeclFromType(NamedT); } +#endif case Type::Paren: { const ParenType *PT = dyn_cast(Ty); @@ -889,12 +931,21 @@ bool Transformation::replaceDependentNameString(const Type *Ty, const IdentifierInfo *IdInfo = DNT->getIdentifier(); if (!IdInfo) return false; +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier Specifier = DNT->getQualifier(); + if (!Specifier) + return false; + if (Specifier.getKind() != NestedNameSpecifier::Kind::Type) + return false; + const Type *DependentTy = Specifier.getAsType(); +#else const NestedNameSpecifier *Specifier = DNT->getQualifier(); if (!Specifier) return false; const Type *DependentTy = Specifier->getAsType(); if (!DependentTy) return false; +#endif const TemplateTypeParmType *ParmTy = DependentTy->getAs(); @@ -984,12 +1035,21 @@ bool Transformation::getDependentNameTypeString( const IdentifierInfo *IdInfo = DNT->getIdentifier(); if (!IdInfo) return false; +#if LLVM_VERSION_MAJOR >= 22 + NestedNameSpecifier Specifier = DNT->getQualifier(); + if (!Specifier) + return false; + if (Specifier.getKind() != NestedNameSpecifier::Kind::Type) + return false; + const Type *Ty = Specifier.getAsType(); +#else const NestedNameSpecifier *Specifier = DNT->getQualifier(); if (!Specifier) return false; const Type *Ty = Specifier->getAsType(); if (!Ty) return false; +#endif const CXXRecordDecl *Base = getBaseDeclFromType(Ty); if (!Base) return false; @@ -1020,10 +1080,12 @@ bool Transformation::getTypeString(const QualType &QT, return getTypeString(TP->getReplacementType(), Str, Typename); } +#if LLVM_VERSION_MAJOR < 22 case Type::Elaborated: { const ElaboratedType *ETy = dyn_cast(Ty); return getTypeString(ETy->getNamedType(), Str, Typename); } +#endif case Type::Typedef: { const TypedefType *TdefTy = dyn_cast(Ty); diff --git a/clang_delta/Transformation.h b/clang_delta/Transformation.h index 5b2da62f..61af3926 100644 --- a/clang_delta/Transformation.h +++ b/clang_delta/Transformation.h @@ -250,7 +250,11 @@ friend class clang_delta_common_visitor::CommonRenameClassRewriteVisitor; clang::DeclarationName &DName, const clang::DeclContext *Ctx); const clang::DeclContext *getDeclContextFromSpecifier( +#if LLVM_VERSION_MAJOR >= 22 + clang::NestedNameSpecifier NNS); +#else const clang::NestedNameSpecifier *NNS); +#endif bool isSpecialRecordDecl(const clang::RecordDecl *RD); diff --git a/clang_delta/TransformationManager.cpp b/clang_delta/TransformationManager.cpp index 2ed20cb0..c07bd7d0 100644 --- a/clang_delta/TransformationManager.cpp +++ b/clang_delta/TransformationManager.cpp @@ -92,7 +92,7 @@ bool TransformationManager::initializeCompilerInstance(std::string &ErrorMsg) ClangInstance = new CompilerInstance(); assert(ClangInstance); -#if LLVM_VERSION_MAJOR >= 20 +#if LLVM_VERSION_MAJOR >= 20 && LLVM_VERSION_MAJOR < 22 // Get the global virtual file system auto VFS = llvm::vfs::getRealFileSystem(); ClangInstance->createDiagnostics(*VFS); @@ -178,7 +178,11 @@ bool TransformationManager::initializeCompilerInstance(std::string &ErrorMsg) } ClangInstance->createFileManager(); +#if LLVM_VERSION_MAJOR >= 22 + ClangInstance->createSourceManager(); +#else ClangInstance->createSourceManager(ClangInstance->getFileManager()); +#endif ClangInstance->createPreprocessor(TU_Complete); DiagnosticConsumer &DgClient = ClangInstance->getDiagnosticClient();