File indexing completed on 2024-04-28 16:57:52
0001 /* 0002 This file is part of the clazy static checker. 0003 0004 Copyright (C) 2018 Sergio Martins <smartins@kde.org> 0005 0006 This library is free software; you can redistribute it and/or 0007 modify it under the terms of the GNU Library General Public 0008 License as published by the Free Software Foundation; either 0009 version 2 of the License, or (at your option) any later version. 0010 0011 This library is distributed in the hope that it will be useful, 0012 but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0014 Library General Public License for more details. 0015 0016 You should have received a copy of the GNU Library General Public License 0017 along with this library; see the file COPYING.LIB. If not, write to 0018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0019 Boston, MA 02110-1301, USA. 0020 */ 0021 0022 0023 #ifndef SOURCE_COMPAT_HELPERS 0024 #define SOURCE_COMPAT_HELPERS 0025 0026 #include <clang/AST/Attr.h> 0027 #include <clang/AST/Expr.h> 0028 #include <clang/AST/Decl.h> 0029 #include <clang/AST/DeclCXX.h> 0030 #include <clang/Basic/SourceLocation.h> 0031 #include <clang/Basic/SourceManager.h> 0032 #include <clang/Frontend/FrontendDiagnostic.h> 0033 #include <clang/Lex/Lexer.h> 0034 #include <clang/Tooling/Core/Diagnostic.h> 0035 0036 #if defined(CLAZY_USES_BOOST_REGEX) 0037 # define BOOST_NO_EXCEPTIONS 0038 # include <boost/throw_exception.hpp> 0039 inline void boost::throw_exception(std::exception const &){} 0040 # include <boost/regex.hpp> 0041 using namespace boost; 0042 #else 0043 # include <regex> 0044 using namespace std; 0045 #endif 0046 0047 namespace clazy { 0048 0049 template <typename T> 0050 inline clang::SourceLocation getLocStart(const T *t) 0051 { 0052 #if LLVM_VERSION_MAJOR >= 8 0053 return t->getBeginLoc(); 0054 #else 0055 return t->getLocStart(); 0056 #endif 0057 } 0058 0059 template <typename T> 0060 inline clang::SourceLocation getLocEnd(const T *t) 0061 { 0062 #if LLVM_VERSION_MAJOR >= 8 0063 return t->getEndLoc(); 0064 #else 0065 return t->getLocEnd(); 0066 #endif 0067 } 0068 0069 inline clang::CharSourceRange getImmediateExpansionRange(clang::SourceLocation macroLoc, const clang::SourceManager &sm) 0070 { 0071 #if LLVM_VERSION_MAJOR >= 7 0072 return sm.getImmediateExpansionRange(macroLoc); 0073 #else 0074 auto pair = sm.getImmediateExpansionRange(macroLoc); 0075 return clang::CharSourceRange(clang::SourceRange(pair.first, pair.second), false); 0076 #endif 0077 } 0078 0079 inline bool hasUnusedResultAttr(clang::FunctionDecl *func) 0080 { 0081 #if LLVM_VERSION_MAJOR >= 8 0082 auto RetType = func->getReturnType(); 0083 if (const auto *Ret = RetType->getAsRecordDecl()) { 0084 if (const auto *R = Ret->getAttr<clang::WarnUnusedResultAttr>()) 0085 return R != nullptr; 0086 } else if (const auto *ET = RetType->getAs<clang::EnumType>()) { 0087 if (const clang::EnumDecl *ED = ET->getDecl()) { 0088 if (const auto *R = ED->getAttr<clang::WarnUnusedResultAttr>()) 0089 return R != nullptr; 0090 } 0091 } 0092 return func->getAttr<clang::WarnUnusedResultAttr>() != nullptr; 0093 #else 0094 return func->hasUnusedResultAttr(); 0095 #endif 0096 0097 } 0098 0099 inline clang::tooling::Replacements& DiagnosticFix(clang::tooling::Diagnostic &diag, llvm::StringRef filePath) 0100 { 0101 #if LLVM_VERSION_MAJOR >= 9 0102 return diag.Message.Fix[filePath]; 0103 #else 0104 return diag.Fix[filePath]; 0105 #endif 0106 } 0107 0108 inline auto getBuffer(const clang::SourceManager &sm, clang::FileID id, bool *invalid) 0109 { 0110 #if LLVM_VERSION_MAJOR >= 12 0111 auto buffer = sm.getBufferOrNone(id); 0112 *invalid = !buffer.hasValue(); 0113 return buffer; 0114 #else 0115 return sm.getBuffer(id, invalid); 0116 #endif 0117 } 0118 0119 #if LLVM_VERSION_MAJOR >= 12 0120 0121 #define GET_LEXER(id, inputFile, sm, lo) \ 0122 clang::Lexer(id, inputFile.getValue(), sm, lo) 0123 0124 #else 0125 #define GET_LEXER(id, inputFile, sm, lo) \ 0126 clang::Lexer(id, inputFile, sm, lo) 0127 #endif 0128 0129 inline bool isFinal(const clang::CXXRecordDecl *record) 0130 { 0131 #if LLVM_VERSION_MAJOR >= 11 0132 return record->isEffectivelyFinal(); 0133 #else 0134 return record->hasAttr<clang::FinalAttr>(); 0135 #endif 0136 } 0137 0138 inline bool contains_lower(clang::StringRef haystack, clang::StringRef needle) 0139 { 0140 #if LLVM_VERSION_MAJOR >= 13 0141 return haystack.contains_insensitive(needle); 0142 #else 0143 return haystack.contains_lower(needle); 0144 #endif 0145 } 0146 0147 } 0148 0149 #endif