clang-tools 22.0.0git
FloatTypesCheck.cpp
Go to the documentation of this file.
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-exception
6//
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} // namespace
48
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::runtime
76
77} // namespace clang
void check(const ast_matchers::MatchFinder::MatchResult &Result) override
void registerMatchers(ast_matchers::MatchFinder *Finder) override
AST_POLYMORPHIC_MATCHER(isInAbseilFile, AST_POLYMORPHIC_SUPPORTED_TYPES(Decl, Stmt, TypeLoc, NestedNameSpecifierLoc))
Matches AST nodes that were found within Abseil files.
AST_MATCHER(BinaryOperator, isRelationalOperator)
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//