1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #ifndef INCLUDED_COMPILERPLUGINS_CLANG_COMPAT_HXX
11 #define INCLUDED_COMPILERPLUGINS_CLANG_COMPAT_HXX
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclBase.h"
18 #include "clang/AST/DeclCXX.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "clang/Basic/DiagnosticIDs.h"
23 #include "clang/Basic/Linkage.h"
24 #include "clang/Basic/SourceManager.h"
25 #include "clang/Basic/Visibility.h"
26 #include "clang/Frontend/CompilerInstance.h"
27 #include "clang/Lex/PPCallbacks.h"
28 #include "clang/Lex/Preprocessor.h"
29 #include "llvm/ADT/StringRef.h"
30 #include "llvm/Support/FileSystem.h"
31 #include "llvm/Support/raw_ostream.h"
33 #if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3
34 #define LO_COMPILERPLUGINS_CLANG_COMPAT_HAVE_isAtEndOfImmediateMacroExpansion \
37 #define LO_COMPILERPLUGINS_CLANG_COMPAT_HAVE_isAtEndOfImmediateMacroExpansion \
41 // Compatibility wrapper to abstract over (trivial) changes in the Clang API:
44 inline bool isExternCContext(clang::DeclContext
const & ctxt
) {
45 #if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3
46 return ctxt
.isExternCContext();
48 for (clang::DeclContext
const * c
= &ctxt
;
49 c
->getDeclKind() != clang::Decl::TranslationUnit
; c
= c
->getParent())
51 if (c
->getDeclKind() == clang::Decl::LinkageSpec
) {
52 return llvm::cast
<clang::LinkageSpecDecl
>(c
)->getLanguage()
53 == clang::LinkageSpecDecl::lang_c
;
60 inline bool isInExternCContext(clang::FunctionDecl
const & decl
) {
61 #if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3
62 return decl
.isInExternCContext();
64 return isExternCContext(*decl
.getCanonicalDecl()->getDeclContext());
68 #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3
69 typedef clang::LinkageInfo LinkageInfo
;
71 typedef clang::NamedDecl::LinkageInfo LinkageInfo
;
74 inline clang::Linkage
getLinkage(LinkageInfo
const & info
) {
75 #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3
76 return info
.getLinkage();
78 return info
.linkage();
82 inline clang::Visibility
getVisibility(LinkageInfo
const & info
) {
83 #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3
84 return info
.getVisibility();
86 return info
.visibility();
90 inline bool isFirstDecl(clang::FunctionDecl
const & decl
) {
91 #if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3
92 return decl
.isFirstDecl();
94 return decl
.isFirstDeclaration();
98 inline clang::QualType
getReturnType(clang::FunctionDecl
const & decl
) {
99 #if (__clang_major__ == 3 && __clang_minor__ >= 5) || __clang_major__ > 3
100 return decl
.getReturnType();
102 return decl
.getResultType();
106 inline clang::QualType
getReturnType(clang::FunctionProtoType
const & type
) {
107 #if (__clang_major__ == 3 && __clang_minor__ >= 5) || __clang_major__ > 3
108 return type
.getReturnType();
110 return type
.getResultType();
114 inline unsigned getNumParams(clang::FunctionProtoType
const & type
) {
115 #if (__clang_major__ == 3 && __clang_minor__ >= 5) || __clang_major__ > 3
116 return type
.getNumParams();
118 return type
.getNumArgs();
122 inline clang::QualType
getParamType(
123 clang::FunctionProtoType
const & type
, unsigned i
)
125 #if (__clang_major__ == 3 && __clang_minor__ >= 5) || __clang_major__ > 3
126 return type
.getParamType(i
);
128 return type
.getArgType(i
);
132 inline unsigned getBuiltinCallee(clang::CallExpr
const & expr
) {
133 #if (__clang_major__ == 3 && __clang_minor__ >= 5) || __clang_major__ > 3
134 return expr
.getBuiltinCallee();
136 return expr
.isBuiltinCall();
140 inline bool isInMainFile(
141 clang::SourceManager
const & manager
, clang::SourceLocation Loc
)
143 #if (__clang_major__ == 3 && __clang_minor__ >= 4) || __clang_major__ > 3
144 return manager
.isInMainFile(Loc
);
146 return manager
.isFromMainFile(Loc
);
150 inline unsigned getCustomDiagID(
151 clang::DiagnosticsEngine
& engine
, clang::DiagnosticsEngine::Level L
,
152 llvm::StringRef FormatString
)
154 #if (__clang_major__ == 3 && __clang_minor__ >= 5) || __clang_major__ > 3
155 return engine
.getDiagnosticIDs()->getCustomDiagID(
156 static_cast<clang::DiagnosticIDs::Level
>(L
), FormatString
);
158 return engine
.getCustomDiagID(L
, FormatString
);
162 inline std::unique_ptr
<llvm::raw_fd_ostream
> create_raw_fd_ostream(
163 char const * Filename
, std::string
& ErrorInfo
)
165 #if (__clang_major__ == 3 && __clang_minor__ >= 6) || __clang_major__ > 3
167 std::unique_ptr
<llvm::raw_fd_ostream
> s(
168 new llvm::raw_fd_ostream(Filename
, ec
, llvm::sys::fs::F_None
));
169 ErrorInfo
= ec
? "error: " + ec
.message() : std::string();
171 #elif __clang_major__ == 3 && __clang_minor__ == 5
172 return std::unique_ptr
<llvm::raw_fd_ostream
>(
173 new llvm::raw_fd_ostream(Filename
, ErrorInfo
, llvm::sys::fs::F_None
));
175 return std::unique_ptr
<llvm::raw_fd_ostream
>(
176 new llvm::raw_fd_ostream(Filename
, ErrorInfo
));
180 #if (__clang_major__ == 3 && __clang_minor__ >= 7) || __clang_major__ > 3
181 typedef clang::DeclContext::lookup_result DeclContextLookupResult
;
182 typedef clang::DeclContext::lookup_iterator DeclContextLookupIterator
;
184 typedef clang::DeclContext::lookup_const_result DeclContextLookupResult
;
185 typedef clang::DeclContext::lookup_const_iterator DeclContextLookupIterator
;
188 inline DeclContextLookupIterator
begin(DeclContextLookupResult
const & result
) {
189 #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3
190 return result
.begin();
196 inline DeclContextLookupIterator
end(DeclContextLookupResult
const & result
) {
197 #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3
200 return result
.second
;
204 inline void addPPCallbacks(
205 clang::Preprocessor
& preprocessor
, clang::PPCallbacks
* C
)
207 #if (__clang_major__ == 3 && __clang_minor__ >= 6) || __clang_major__ > 3
208 preprocessor
.addPPCallbacks(std::unique_ptr
<clang::PPCallbacks
>(C
));
210 preprocessor
.addPPCallbacks(C
);
214 inline bool isMacroBodyExpansion(clang::CompilerInstance
& compiler
, clang::SourceLocation location
)
216 #if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3
217 return compiler
.getSourceManager().isMacroBodyExpansion(location
);
219 return location
.isMacroID()
220 && !compiler
.getSourceManager().isMacroArgExpansion(location
);
228 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */