diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-01-20 14:31:54 +0100 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-01-20 14:32:35 +0100 |
commit | 3c2a6ad96b3549961f4c72c200da42ff82d8a188 (patch) | |
tree | ac3991577b628562dc9dbde4de01b88fe375ab49 /compilerplugins | |
parent | Resolves: #i124039# assure correct line break for multi-lined Input Fields (diff) | |
download | core-3c2a6ad96b3549961f4c72c200da42ff82d8a188.tar.gz core-3c2a6ad96b3549961f4c72c200da42ff82d8a188.zip |
Make implicitboolconversion.cxx compile with Clang 3.2
Change-Id: I011e74fd044d0b76cccc60adea362805917c584a
Diffstat (limited to 'compilerplugins')
-rw-r--r-- | compilerplugins/clang/implicitboolconversion.cxx | 33 |
1 files changed, 30 insertions, 3 deletions
diff --git a/compilerplugins/clang/implicitboolconversion.cxx b/compilerplugins/clang/implicitboolconversion.cxx index 98cb94c97102..31377d8e3c97 100644 --- a/compilerplugins/clang/implicitboolconversion.cxx +++ b/compilerplugins/clang/implicitboolconversion.cxx @@ -65,6 +65,33 @@ bool isBoolExpr(Expr const * expr) { return false; } +// It appears that, given a function declaration, there is no way to determine +// the language linkage of the function's type, only of the function's name +// (via FunctionDecl::isExternC); however, in a case like +// +// extern "C" { static void f(); } +// +// the function's name does not have C language linkage while the function's +// type does (as clarified in C++11 [decl.link]); cf. <http://clang-developers. +// 42468.n3.nabble.com/Language-linkage-of-function-type-tt4037248.html> +// "Language linkage of function type": +bool hasCLanguageLinkageType(FunctionDecl const * decl) { + assert(decl != nullptr); + if (decl->isExternC()) { + return true; + } +#if (__clang_major__ == 3 && __clang_minor__ >= 3) || __clang_major__ > 3 + if (decl->isInExternCContext()) { + return true; + } +#else + if (decl->getDeclContext()->isExternCContext()) { + return true; + } +#endif + return false; +} + class ImplicitBoolConversion: public RecursiveASTVisitor<ImplicitBoolConversion>, public loplugin::Plugin { @@ -126,14 +153,14 @@ bool ImplicitBoolConversion::TraverseCallExpr(CallExpr * expr) { FunctionProtoType const * t = nullptr; if (d != nullptr) { FunctionDecl const * fd = dyn_cast<FunctionDecl>(d); - if (fd != nullptr && (fd->isExternC() || fd->isInExternCContext())) { + if (fd != nullptr && fd->isExternC()) { ext = true; PointerType const * pt = dyn_cast<PointerType>(fd->getType()); t = (pt == nullptr ? fd->getType() : pt->getPointeeType()) ->getAs<FunctionProtoType>(); } else { VarDecl const * vd = dyn_cast<VarDecl>(d); - if (vd != nullptr && (vd->isExternC() || vd->isInExternCContext())) + if (vd != nullptr && vd->isExternC()) { ext = true; PointerType const * pt = dyn_cast<PointerType>(vd->getType()); @@ -432,7 +459,7 @@ bool ImplicitBoolConversion::TraverseReturnStmt(ReturnStmt * stmt) { } bool ImplicitBoolConversion::TraverseFunctionDecl(FunctionDecl * decl) { - bool ext = (decl->isExternC() || decl->isInExternCContext()) + bool ext = hasCLanguageLinkageType(decl) && decl->isThisDeclarationADefinition() && (decl->getResultType()->isSpecificBuiltinType(BuiltinType::Int) || decl->getResultType()->isSpecificBuiltinType(BuiltinType::UInt)); |