78 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "FloatTypesCheck.h"10#include "clang/ASTMatchers/ASTMatchFinder.h"11#include "clang/Lex/Lexer.h"12 13namespace clang {14 15using namespace ast_matchers;16 17namespace {18 19AST_POLYMORPHIC_MATCHER(isValidAndNotInMacro,20 AST_POLYMORPHIC_SUPPORTED_TYPES(TypeLoc,21 FloatingLiteral)) {22 const SourceLocation Loc = Node.getBeginLoc();23 return Loc.isValid() && !Loc.isMacroID();24}25 26AST_MATCHER(TypeLoc, isLongDoubleType) {27 TypeLoc TL = Node;28 if (const auto QualLoc = Node.getAs<QualifiedTypeLoc>())29 TL = QualLoc.getUnqualifiedLoc();30 31 const auto BuiltinLoc = TL.getAs<BuiltinTypeLoc>();32 if (!BuiltinLoc)33 return false;34 35 if (const auto *BT = BuiltinLoc.getTypePtr())36 return BT->getKind() == BuiltinType::LongDouble;37 return false;38}39 40AST_MATCHER(FloatingLiteral, isLongDoubleLiteral) {41 if (const auto *BT =42 dyn_cast_if_present<BuiltinType>(Node.getType().getTypePtr()))43 return BT->getKind() == BuiltinType::LongDouble;44 return false;45}46 47} // namespace48 49namespace tidy::google::runtime {50 51void RuntimeFloatCheck::registerMatchers(MatchFinder *Finder) {52 Finder->addMatcher(typeLoc(loc(realFloatingPointType()),53 isValidAndNotInMacro(), isLongDoubleType())54 .bind("longDoubleTypeLoc"),55 this);56 Finder->addMatcher(floatLiteral(isValidAndNotInMacro(), isLongDoubleLiteral())57 .bind("longDoubleFloatLiteral"),58 this);59}60 61void RuntimeFloatCheck::check(const MatchFinder::MatchResult &Result) {62 if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("longDoubleTypeLoc")) {63 diag(TL->getBeginLoc(), "%0 type is not portable and should not be used")64 << TL->getType();65 }66 67 if (const auto *FL =68 Result.Nodes.getNodeAs<FloatingLiteral>("longDoubleFloatLiteral")) {69 diag(FL->getBeginLoc(), "%0 type from literal suffix 'L' is not portable "70 "and should not be used")71 << FL->getType();72 }73}74 75} // namespace tidy::google::runtime76 77} // namespace clang78