LLDB mainline
LanguageOpts.cpp
Go to the documentation of this file.
1//===-- LanguageOpts.cpp --------------------------------------------------===//
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 "LanguageOpts.h"
10
11#include "clang/Basic/Diagnostic.h"
12#include "clang/Basic/DiagnosticIDs.h"
13#include "clang/Basic/DiagnosticOptions.h"
14#include "clang/Basic/TargetInfo.h"
15#include "clang/Basic/TargetOptions.h"
16
17#include "llvm/ADT/APFloat.h"
18#include "llvm/Support/ErrorExtras.h"
19#include "llvm/Support/MathExtras.h"
20
21#include <memory>
22#include <utility>
23
24using namespace lldb_private;
25using namespace lldb_private::clike;
26
27/// Build a TargetInfo for \p triple, or null if Clang doesn't know the target.
28static std::unique_ptr<clang::TargetInfo>
29CreateTargetInfo(clang::TargetOptions target_opts) {
30 clang::DiagnosticOptions diag_opts;
31 clang::DiagnosticsEngine diags(
32 llvm::makeIntrusiveRefCnt<clang::DiagnosticIDs>(), diag_opts,
33 new clang::IgnoringDiagConsumer());
34
35 return std::unique_ptr<clang::TargetInfo>(
36 clang::TargetInfo::CreateTargetInfo(diags, target_opts));
37}
38
39LanguageOpts::LanguageOpts(llvm::Triple triple,
40 std::unique_ptr<clang::TargetInfo> target,
41 BuiltinSizes sizes, FloatSemantics semantics)
42 : m_triple(std::move(triple)), m_target(std::move(target)),
43 m_builtin_sizes(sizes), m_semantics(semantics) {}
44
45llvm::Expected<LanguageOpts> LanguageOpts::Create(llvm::Triple triple) {
46 clang::TargetOptions target_opts;
47 target_opts.Triple = triple.str();
48 std::unique_ptr<clang::TargetInfo> target = CreateTargetInfo(target_opts);
49 if (!target)
50 return llvm::createStringErrorV("Unknown Clang target: '{0}'",
51 triple.str());
52
53 auto bytes = [](unsigned bits) -> uint32_t { return bits / 8; };
54 BuiltinSizes sizes;
55 sizes.bool_size = bytes(target->getBoolWidth());
56 sizes.short_size = bytes(target->getShortWidth());
57 sizes.int_size = bytes(target->getIntWidth());
58 sizes.long_size = bytes(target->getLongWidth());
59 sizes.long_long_size = bytes(target->getLongLongWidth());
60 sizes.wchar_size = bytes(target->getWCharWidth());
61 sizes.char16_size = bytes(target->getChar16Width());
62 sizes.char32_size = bytes(target->getChar32Width());
63 sizes.float_size = bytes(target->getFloatWidth());
64 sizes.double_size = bytes(target->getDoubleWidth());
65 sizes.long_double_size = bytes(target->getLongDoubleWidth());
66 sizes.pointer_size = bytes(target->getPointerWidth(clang::LangAS::Default));
67
68 FloatSemantics semantics;
69 semantics.half = &target->getHalfFormat();
70 semantics.single = &target->getFloatFormat();
71 semantics.double_ = &target->getDoubleFormat();
72 semantics.long_double = &target->getLongDoubleFormat();
73 semantics.float128 = &target->getFloat128Format();
74
75 return LanguageOpts(std::move(triple), std::move(target), sizes, semantics);
76}
77
78const llvm::fltSemantics &
80 const lldb::Format format) const {
81 const size_t bit_size = byte_size * 8;
82 if (byte_size == m_builtin_sizes.float_size)
83 return *m_semantics.single;
84 if (byte_size == m_builtin_sizes.double_size)
85 return *m_semantics.double_;
86 if (format == lldb::eFormatFloat128 && bit_size == 128)
87 return *m_semantics.float128;
88 if (byte_size == m_builtin_sizes.long_double_size ||
89 bit_size == llvm::APFloat::semanticsSizeInBits(*m_semantics.long_double))
90 return *m_semantics.long_double;
91 if (bit_size == 16)
92 return *m_semantics.half;
93 if (bit_size == 128)
94 return *m_semantics.float128;
95 return llvm::APFloat::Bogus();
96}
97
98std::optional<uint64_t> LanguageOpts::GetBitIntByteSize(unsigned bits) const {
99 if (bits == 0)
100 return std::nullopt;
101
102 if (bits > m_target->getMaxBitIntWidth())
103 return std::nullopt;
104
105 // clang lays out a `_BitInt` by rounding its width up to its ABI alignment.
106 unsigned align_bits = m_target->getBitIntAlign(bits);
107 uint64_t size_bits = llvm::alignTo(bits, align_bits);
108 return size_bits / 8;
109}
static std::unique_ptr< clang::TargetInfo > CreateTargetInfo(clang::TargetOptions target_opts)
Build a TargetInfo for triple, or null if Clang doesn't know the target.
std::optional< uint64_t > GetBitIntByteSize(unsigned bits) const
The storage size (in bytes) of a _BitInt(bits) on this target.
static llvm::Expected< LanguageOpts > Create(llvm::Triple triple)
The language options for triple, or an error if Clang cannot describe the triple.
LanguageOpts(llvm::Triple triple, std::unique_ptr< clang::TargetInfo > target, BuiltinSizes sizes, FloatSemantics semantics)
std::unique_ptr< clang::TargetInfo > m_target
const llvm::fltSemantics & GetFloatTypeSemantics(const size_t byte_size, const lldb::Format format) const
The floating point semantics for a float of the given storage size.
A class that represents a running process on the host machine.
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition ARMUtils.h:265
Format
Display format definitions.
@ eFormatFloat128
Disambiguate between 128-bit long double (which uses eFormatFloat) and __float128 (which uses eFormat...
Sizes (in bytes) of the target-dependent builtin types.