clang: lib/Basic/TargetInfo.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

19#include "llvm/ADT/APFloat.h"

20#include "llvm/ADT/STLExtras.h"

21#include "llvm/Support/ErrorHandling.h"

22#include "llvm/TargetParser/TargetParser.h"

23#include

24using namespace clang;

25

27

28

30 0,

31 1,

32 3,

33 2,

34 0,

35 4,

36 5,

37 6,

38 7,

39 8,

40 9,

41 1,

42 5,

43 6,

44 3,

45 0,

46 10,

47 11,

48 12,

49 13,

50 20,

51};

52

53

55

56

78

79

86

87

88

89

90

95

99

100

101

102

103

104 if (T.isGNUEnvironment() || T.isWindowsMSVCEnvironment() || T.isAndroid() ||

105 T.isOHOSFamily())

106 NewAlign = Triple.isArch64Bit() ? 128 : Triple.isArch32Bit() ? 64 : 0;

107 else if (T.isOSDarwin() || T.isOSOpenBSD())

109 else

110 NewAlign = 0;

145 HalfFormat = &llvm::APFloat::IEEEhalf();

146 FloatFormat = &llvm::APFloat::IEEEsingle();

150 Ibm128Format = &llvm::APFloat::PPCDoubleDouble();

162

163

165

166

168

169

170 TheCXXABI.set(Triple.isKnownWindowsMSVCEnvironment()

171 ? TargetCXXABI::Microsoft

172 : TargetCXXABI::GenericItanium);

173

174

177

178

181

183

185}

186

187

189

193}

194

195bool

197 Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=branch";

198 return false;

199}

200

202

203

204 llvm::report_fatal_error("not implemented");

205}

206

210 Diags.Report(diag::err_opt_not_valid_on_target)

211 << (Twine("mcf-branch-label-scheme=") +

213 .str();

214 return false;

215}

216

217bool

219 Diags.Report(diag::err_opt_not_valid_on_target) << "cf-protection=return";

220 return false;

221}

222

223

224

226 switch (T) {

227 default: llvm_unreachable("not an integer!");

228 case SignedChar: return "signed char";

235 case UnsignedLong: return "long unsigned int";

238 }

239}

240

241

242

244 switch (T) {

245 default: llvm_unreachable("not an integer!");

253 return "";

254 [[fallthrough]];

257 return "";

258 [[fallthrough]];

262 }

263}

264

265

266

267

269 switch (T) {

270 default: llvm_unreachable("not an integer!");

281 }

282}

283

284

285

287 switch (T) {

288 default: llvm_unreachable("not an integer!");

299 };

300}

301

303 unsigned BitWidth, bool IsSigned) const {

315}

316

318 bool IsSigned) const {

330}

331

340

341 switch (BitWidth) {

342 case 96:

345 break;

346 case 128:

347

348

360 break;

361 }

362

364}

365

366

367

369 switch (T) {

370 default: llvm_unreachable("not an integer!");

381 };

382}

383

384

385

387 switch (T) {

388 default: llvm_unreachable("not an integer!");

394 return true;

400 return false;

401 };

402}

403

404

405

406

407

409 if (Opts.NoBitFieldTypeAlign)

411

412 switch (Opts.WCharSize) {

413 default: llvm_unreachable("invalid wchar_t width");

414 case 0: break;

418 }

419

420 if (Opts.AlignDouble) {

423 }

424

425

426

427 if (Opts.HLSL) {

430 if (!Opts.NativeHalfType) {

431 HalfFormat = &llvm::APFloat::IEEEsingle();

433 }

434 }

435

436 if (Opts.OpenCL) {

437

438

439

440

447

448

449

450

454 }

456

458 assert(MaxPointerWidth == 32 || MaxPointerWidth == 64);

459 bool Is32BitArch = MaxPointerWidth == 32;

463

466

467 HalfFormat = &llvm::APFloat::IEEEhalf();

468 FloatFormat = &llvm::APFloat::IEEEsingle();

470

471

472

473

474

475

476

477

478

479

483 OpenCLFeaturesMap, "__opencl_c_generic_address_space");

484 Opts.OpenCLPipes =

486 Opts.Blocks =

487 hasFeatureEnabled(OpenCLFeaturesMap, "__opencl_c_device_enqueue");

488 }

489 }

490

491 if (Opts.DoubleSize) {

492 if (Opts.DoubleSize == 32) {

497 } else if (Opts.DoubleSize == 64) {

502 }

503 }

504

505 if (Opts.LongDoubleSize) {

506 if (Opts.LongDoubleSize == DoubleWidth) {

510 } else if (Opts.LongDoubleSize == 128) {

513 } else if (Opts.LongDoubleSize == 80) {

515 if (getTriple().isWindowsMSVCEnvironment()) {

518 } else {

519 if (getTriple().getArch() == llvm::Triple::x86) {

522 } else {

525 }

526 }

527 }

528 }

529

530 if (Opts.NewAlignOverride)

532

533

534

536 CheckFixedPointBits();

537

539 Diags.Report(diag::err_opt_not_valid_on_target) << "-fprotect-parens";

540 Opts.ProtectParens = false;

541 }

542

543 if (Opts.MaxBitIntWidth)

544 MaxBitIntWidth = static_cast<unsigned>(Opts.MaxBitIntWidth);

545

546 if (Opts.FakeAddressSpaceMap)

548}

549

551 llvm::StringMap &Features, DiagnosticsEngine &Diags, StringRef CPU,

552 const std::vectorstd::string &FeatureVec) const {

553 for (const auto &F : FeatureVec) {

554 StringRef Name = F;

555 if (Name.empty())

556 continue;

557

558 if (Name[0] != '+' && Name[0] != '-')

559 Diags.Report(diag::warn_fe_backend_invalid_feature_flag) << Name;

560 else

562 }

563 return true;

564}

565

568 if (Features == "default")

569 return Ret;

571 Features.split(AttrFeatures, ",");

572

573

574

575 for (auto &Feature : AttrFeatures) {

576

577

578 Feature = Feature.trim();

579

580

581

582

583 if (Feature.starts_with("fpmath="))

584 continue;

585

586 if (Feature.starts_with("branch-protection=")) {

587 Ret.BranchProtection = Feature.split('=').second.trim();

588 continue;

589 }

590

591

592 if (Feature.starts_with("arch=")) {

593 if (!Ret.CPU.empty())

594 Ret.Duplicate = "arch=";

595 else

596 Ret.CPU = Feature.split("=").second.trim();

597 } else if (Feature.starts_with("tune=")) {

598 if (!Ret.Tune.empty())

599 Ret.Duplicate = "tune=";

600 else

601 Ret.Tune = Feature.split("=").second.trim();

602 } else if (Feature.starts_with("no-"))

603 Ret.Features.push_back("-" + Feature.split("-").second.str());

604 else

605 Ret.Features.push_back("+" + Feature.str());

606 }

607 return Ret;

608}

609

612 if (getCXXABI() != TargetCXXABI::Microsoft &&

613 (ClangABICompat4 || getTriple().isPS4()))

616}

617

620}

621

623 switch (TK) {

627

630

631 default:

633 }

634}

635

636

637

638

640 if (Name[0] == '%' || Name[0] == '#')

641 Name = Name.substr(1);

642

643 return Name;

644}

645

646

647

648

651 Name == "unwind");

652}

653

654

655

656

658 if (Name.empty())

659 return false;

660

661

663 if (Name.empty())

664 return false;

665

667

668

670 unsigned n;

671 if (!Name.getAsInteger(0, n))

672 return n < Names.size();

673 }

674

675

676 if (llvm::is_contained(Names, Name))

677 return true;

678

679

681 for (const char *AN : ARN.Names) {

682 if (!AN)

683 break;

684

685

686 if (AN == Name && ARN.RegNum < Names.size())

687 return true;

688 }

689

690

692 for (const char *A : GRA.Aliases) {

693 if (!A)

694 break;

695 if (A == Name)

696 return true;

697 }

698

699 return false;

700}

701

703 bool ReturnCanonical) const {

705

706

708

710

711

713 unsigned n;

714 if (!Name.getAsInteger(0, n)) {

715 assert(n < Names.size() && "Out of bounds register number!");

716 return Names[n];

717 }

718 }

719

720

722 for (const char *AN : ARN.Names) {

723 if (!AN)

724 break;

725

726

727 if (AN == Name && ARN.RegNum < Names.size())

728 return ReturnCanonical ? Names[ARN.RegNum] : Name;

729 }

730

731

733 for (const char *A : RA.Aliases) {

734 if (!A)

735 break;

736 if (A == Name)

737 return RA.Register;

738 }

739

740 return Name;

741}

742

745

746 if (*Name != '=' && *Name != '+')

747 return false;

748

749 if (*Name == '+')

751

752 Name++;

753 while (*Name) {

754 switch (*Name) {

755 default:

757

758

759

760 return false;

761 }

762 break;

763 case '&':

765 break;

766 case '%':

767

768 break;

769 case 'r':

771 break;

772 case 'm':

773 case 'o':

774 case 'V':

775 case '<':

776 case '>':

778 break;

779 case 'g':

780 case 'X':

783 break;

784 case ',':

785

786 if (Name[1] == '=' || Name[1] == '+')

787 Name++;

788 break;

789 case '#':

790 while (Name[1] && Name[1] != ',')

791 Name++;

792 break;

793 case '?':

794 case '!':

795 case '*':

796 case 'i':

797

798 case 'n':

799 case 'E':

800 case 'F':

801 break;

802 }

803

804 Name++;

805 }

806

807

808

810 return false;

811

812

813

815}

816

819 unsigned &Index) const {

820 assert(*Name == '[' && "Symbolic name did not start with '['");

821 Name++;

822 const char *Start = Name;

823 while (*Name && *Name != ']')

824 Name++;

825

826 if (!*Name) {

827

828 return false;

829 }

830

831 std::string SymbolicName(Start, Name - Start);

832

833 for (Index = 0; Index != OutputConstraints.size(); ++Index)

834 if (SymbolicName == OutputConstraints[Index].getName())

835 return true;

836

837 return false;

838}

839

844

845 if (!*Name)

846 return false;

847

848 while (*Name) {

849 switch (*Name) {

850 default:

851

852 if (*Name >= '0' && *Name <= '9') {

853 const char *DigitStart = Name;

854 while (Name[1] >= '0' && Name[1] <= '9')

855 Name++;

856 const char *DigitEnd = Name;

857 unsigned i;

858 if (StringRef(DigitStart, DigitEnd - DigitStart + 1)

859 .getAsInteger(10, i))

860 return false;

861

862

863 if (i >= OutputConstraints.size()) return false;

864

865

866 if (OutputConstraints[i].isReadWrite())

867 return false;

868

869

870

872 return false;

873

874

875

878

879

880

881 return false;

882 }

883 break;

884 case '[': {

885 unsigned Index = 0;

887 return false;

888

889

890

892 return false;

893

894

895 if (OutputConstraints[Index].isReadWrite())

896 return false;

897

898 Info.setTiedOperand(Index, OutputConstraints[Index]);

899 break;

900 }

901 case '%':

902

903 break;

904 case 'i':

905 break;

906 case 'n':

908 break;

909 case 'I':

910 case 'J':

911 case 'K':

912 case 'L':

913 case 'M':

914 case 'N':

915 case 'O':

916 case 'P':

918 return false;

919 break;

920 case 'r':

922 break;

923 case 'm':

924 case 'o':

925 case 'V':

926 case '<':

927 case '>':

929 break;

930 case 'g':

931 case 'X':

934 break;

935 case 'E':

936 case 'F':

937 case 'p':

938 break;

939 case ',':

940 break;

941 case '#':

942 while (Name[1] && Name[1] != ',')

943 Name++;

944 break;

945 case '?':

946 case '!':

947 case '*':

948 break;

949 }

950

951 Name++;

952 }

953

954 return true;

955}

956

958 return false;

959}

960

961void TargetInfo::CheckFixedPointBits() const {

962

963

972

979

980

981

988

989

990

991

992

993

994

995

1003

1004

1005

1006

1007

1008

1013

1014

1015

1019}

1020

1025}

Provides definitions for the various language-specific address spaces.

Defines the Diagnostic-related interfaces.

static const LangASMap DefaultAddrSpaceMap

static StringRef removeGCCRegisterPrefix(StringRef Name)

static const LangASMap FakeAddrSpaceMap

Defines the clang::LangOptions interface.

llvm::MachO::Target Target

static std::string getName(const CallEvent &Call)

Concrete class used by the front-end to report problems and issues.

DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)

Issue the message to the client.

@ Ver15

Attempt to be ABI-compatible with code generated by Clang 15.0.x.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

unsigned getOpenCLCompatibleVersion() const

Return the OpenCL version that kernel language is compatible with.

Exposes information about the current target.

virtual bool validatePointerAuthKey(const llvm::APSInt &value) const

Determine whether the given pointer-authentication key is valid.

unsigned getUnsignedLongFractScale() const

getUnsignedLongFractScale - Return the number of fractional bits in a 'unsigned long _Fract' type.

bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const

bool resolveSymbolicName(const char *&Name, ArrayRef< ConstraintInfo > OutputConstraints, unsigned &Index) const

void copyAuxTarget(const TargetInfo *Aux)

Copy type and layout related info.

TargetInfo(const llvm::Triple &T)

virtual bool checkCFProtectionReturnSupported(DiagnosticsEngine &Diags) const

Check if the target supports CFProtection return.

unsigned getShortWidth() const

getShortWidth/Align - Return the size of 'signed short' and 'unsigned short' for this target,...

unsigned getUnsignedAccumScale() const

getUnsignedAccumScale/IBits - Return the number of fractional/integral bits in a 'unsigned _Accum' ty...

unsigned getIntAlign() const

virtual ArrayRef< AddlRegName > getGCCAddlRegNames() const

unsigned getUnsignedAccumIBits() const

const llvm::Triple & getTriple() const

Returns the target triple of the primary target.

const LangASMap * AddrSpaceMap

const char * UserLabelPrefix

unsigned getUnsignedFractScale() const

getUnsignedFractScale - Return the number of fractional bits in a 'unsigned _Fract' type.

virtual bool checkCFBranchLabelSchemeSupported(const CFBranchLabelSchemeKind Scheme, DiagnosticsEngine &Diags) const

unsigned getLongAlign() const

virtual IntType getLeastIntTypeByWidth(unsigned BitWidth, bool IsSigned) const

Return the smallest integer type with at least the specified width.

unsigned getLongLongAlign() const

virtual bool hasFeatureEnabled(const llvm::StringMap< bool > &Features, StringRef Name) const

Check if target has a given feature enabled.

virtual CFBranchLabelSchemeKind getDefaultCFBranchLabelScheme() const

Get the target default CFBranchLabelScheme scheme.

unsigned HasAArch64SVETypes

void resetDataLayout(StringRef DL, const char *UserLabelPrefix="")

virtual ArrayRef< const char * > getGCCRegNames() const =0

unsigned getTypeWidth(IntType T) const

Return the width (in bits) of the specified integer type enum.

unsigned getLongFractScale() const

getLongFractScale - Return the number of fractional bits in a 'signed long _Fract' type.

static bool isTypeSigned(IntType T)

Returns true if the type is signed; false otherwise.

std::optional< unsigned > MaxBitIntWidth

virtual void setFeatureEnabled(llvm::StringMap< bool > &Features, StringRef Name, bool Enabled) const

Enable or disable a specific target feature; the feature name must be valid.

unsigned getAccumIBits() const

virtual CallingConvKind getCallingConvKind(bool ClangABICompat4) const

VersionTuple PlatformMinVersion

unsigned getIntWidth() const

getIntWidth/Align - Return the size of 'signed int' and 'unsigned int' for this target,...

unsigned getShortAccumIBits() const

unsigned getFloatWidth() const

getFloatWidth/Align/Format - Return the size/align/format of 'float'.

virtual ArrayRef< GCCRegAlias > getGCCRegAliases() const =0

StringRef getNormalizedGCCRegisterName(StringRef Name, bool ReturnCanonical=false) const

Returns the "normalized" GCC register name.

unsigned getLongAccumIBits() const

FloatModeKind getRealTypeByWidth(unsigned BitWidth, FloatModeKind ExplicitType) const

Return floating point type with specified width.

virtual IntType getIntTypeByWidth(unsigned BitWidth, bool IsSigned) const

Return integer type with specified width.

unsigned getHalfWidth() const

getHalfWidth/Align/Format - Return the size/align/format of 'half'.

unsigned char SSERegParmMax

unsigned HasUnalignedAccess

unsigned char MaxAtomicPromoteWidth

virtual LangAS getOpenCLTypeAddrSpace(OpenCLTypeKind TK) const

Get address space for OpenCL type.

static const char * getTypeName(IntType T)

Return the user string for the specified integer type enum.

unsigned getCharAlign() const

unsigned RealTypeUsesObjCFPRetMask

unsigned MaxOpenCLWorkGroupSize

unsigned getLongLongWidth() const

getLongLongWidth/Align - Return the size of 'signed long long' and 'unsigned long long' for this targ...

virtual bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const =0

llvm::StringMap< bool > & getSupportedOpenCLOpts()

Get supported OpenCL extensions and optional core features.

bool UseAddrSpaceMapMangling

Specify if mangling based on address space map should be used or not for language specific address sp...

unsigned ComplexLongDoubleUsesFP2Ret

virtual bool hasIbm128Type() const

Determine whether the __ibm128 type is supported on this target.

virtual void adjust(DiagnosticsEngine &Diags, LangOptions &Opts)

Set forced language options.

unsigned getUnsignedShortAccumIBits() const

std::string DataLayoutString

unsigned getUnsignedLongAccumScale() const

getUnsignedLongAccumScale/IBits - Return the number of fractional/integral bits in a 'unsigned long _...

virtual bool hasFloat128Type() const

Determine whether the __float128 type is supported on this target.

unsigned getUnsignedLongAccumIBits() const

unsigned getUnsignedShortFractScale() const

getUnsignedShortFractScale - Return the number of fractional bits in a 'unsigned short _Fract' type.

unsigned HasAlignMac68kSupport

const llvm::fltSemantics & getLongDoubleFormat() const

bool validateOutputConstraint(ConstraintInfo &Info) const

TargetCXXABI getCXXABI() const

Get the C++ ABI currently in use.

const char * getTypeConstantSuffix(IntType T) const

Return the constant suffix for the specified integer type enum.

unsigned getDoubleWidth() const

getDoubleWidth/Align/Format - Return the size/align/format of 'double'.

virtual bool checkArithmeticFenceSupported() const

Controls if __arithmetic_fence is supported in the targeted backend.

bool isValidClobber(StringRef Name) const

Returns whether the passed in string is a valid clobber in an inline asm statement.

virtual bool areDefaultedSMFStillPOD(const LangOptions &) const

Controls whether explicitly defaulted (= default) special member functions disqualify something from ...

unsigned getCharWidth() const

virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const

unsigned getLongWidth() const

getLongWidth/Align - Return the size of 'signed long' and 'unsigned long' for this target,...

unsigned getFractScale() const

getFractScale - Return the number of fractional bits in a 'signed _Fract' type.

virtual bool initFeatureMap(llvm::StringMap< bool > &Features, DiagnosticsEngine &Diags, StringRef CPU, const std::vector< std::string > &FeatureVec) const

Initialize the map with the default set of target features for the CPU this should include all legal ...

virtual bool checkCFProtectionBranchSupported(DiagnosticsEngine &Diags) const

Check if the target supports CFProtection branch.

unsigned char MaxAtomicInlineWidth

unsigned AllowAMDGPUUnsafeFPAtomics

unsigned getShortFractScale() const

getShortFractScale - Return the number of fractional bits in a 'signed short _Fract' type.

virtual uint64_t getMaxPointerWidth() const

Return the maximum width of pointers on this target.

unsigned ARMCDECoprocMask

static const char * getTypeFormatModifier(IntType T)

Return the printf format modifier for the specified integer type enum.

unsigned getUnsignedShortAccumScale() const

getUnsignedShortAccumScale/IBits - Return the number of fractional/integral bits in a 'unsigned short...

unsigned HasBuiltinMSVaList

unsigned getTypeAlign(IntType T) const

Return the alignment (in bits) of the specified integer type enum.

unsigned getShortAlign() const

virtual bool isValidGCCRegisterName(StringRef Name) const

Returns whether the passed in string is a valid register name according to GCC.

Defines the clang::TargetInfo interface.

The JSON file list parser is used to communicate input to InstallAPI.

unsigned[(unsigned) LangAS::FirstTargetAddressSpace] LangASMap

The type of a lookup table which maps from language-specific address spaces to target-specific ones.

OpenCLTypeKind

OpenCL type kinds.

LLVM_READONLY bool isDigit(unsigned char c)

Return true if this character is an ASCII digit: [0-9].

LangAS

Defines the address space values used by the address space qualifier of QualType.

static const char * getCFBranchLabelSchemeFlagVal(const CFBranchLabelSchemeKind Scheme)

const FunctionProtoType * T

Contains information gathered from parsing the contents of TargetAttr.

const std::string & getConstraintStr() const

std::string ConstraintStr

unsigned getTiedOperand() const

bool allowsMemory() const

void setTiedOperand(unsigned N, ConstraintInfo &Output)

Indicate that this is an input operand that is tied to the specified output operand.

bool hasTiedOperand() const

Return true if this input operand is a matching constraint that ties it to an output operand.

bool allowsRegister() const

void setRequiresImmediate(int Min, int Max)

Fields controlling how types are laid out in memory; these may need to be copied for targets like AMD...

const llvm::fltSemantics * DoubleFormat

unsigned UseZeroLengthBitfieldAlignment

Whether zero length bitfields (e.g., int : 0;) force alignment of the next bitfield.

unsigned short SuitableAlign

unsigned char PointerWidth

unsigned UseExplicitBitFieldAlignment

Whether explicit bit field alignment attributes are honored.

IntType

===-— Target Data Type Query Methods ----------------------------—===//

const llvm::fltSemantics * LongDoubleFormat

unsigned char LargeArrayAlign

unsigned char ShortAccumWidth

unsigned ZeroLengthBitfieldBoundary

If non-zero, specifies a fixed alignment value for bitfields that follow zero length bitfield,...

const llvm::fltSemantics * Float128Format

unsigned char DoubleWidth

unsigned UseLeadingZeroLengthBitfield

Whether zero length bitfield alignment is respected if they are the leading members.

unsigned char LongLongAlign

unsigned char LongAccumAlign

unsigned UseBitFieldTypeAlignment

Control whether the alignment of bit-field types is respected when laying out structures.

unsigned char LargeArrayMinWidth

unsigned char PointerAlign

unsigned char LongDoubleAlign

unsigned char LongDoubleWidth

unsigned char Int128Align

unsigned char ShortAccumScale

unsigned MaxAlignedAttribute

If non-zero, specifies a maximum alignment to truncate alignment specified in the aligned attribute o...

unsigned char DoubleAlign

bool PaddingOnUnsignedFixedPoint

const llvm::fltSemantics * Ibm128Format

unsigned char LongFractWidth

unsigned char Ibm128Align

unsigned char ShortFractAlign

unsigned char ShortAccumAlign

unsigned char LongFractAlign

const llvm::fltSemantics * FloatFormat

const llvm::fltSemantics * HalfFormat

unsigned char LongLongWidth

unsigned char LongAccumScale

unsigned char MinGlobalAlign

unsigned UseSignedCharForObjCBool

Whether Objective-C's built-in boolean type should be signed char.

unsigned char Float128Align

unsigned char LongAccumWidth

unsigned char DefaultAlignForAttributeAligned

unsigned char ShortFractWidth