1 //===--- Types.cpp - Driver input & temporary type information ------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "clang/Driver/Types.h"
10 #include "clang/Driver/Driver.h"
11 #include "clang/Driver/DriverDiagnostic.h"
12 #include "clang/Driver/Options.h"
13 #include "llvm/ADT/STLExtras.h"
14 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/Option/Arg.h"
20 using namespace clang::driver
;
21 using namespace clang::driver::types
;
25 const char *TempSuffix
;
31 constexpr PhasesBitSet(std::initializer_list
<phases::ID
> Phases
) {
32 for (auto Id
: Phases
)
35 bool contains(phases::ID Id
) const { return Bits
& (1 << Id
); }
39 static constexpr TypeInfo TypeInfos
[] = {
40 #define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, ...) \
41 { NAME, TEMP_SUFFIX, TY_##PP_TYPE, { __VA_ARGS__ }, },
42 #include "clang/Driver/Types.def"
45 static const unsigned numTypes
= std::size(TypeInfos
);
47 static const TypeInfo
&getInfo(unsigned id
) {
48 assert(id
> 0 && id
- 1 < numTypes
&& "Invalid Type ID.");
49 return TypeInfos
[id
- 1];
52 const char *types::getTypeName(ID Id
) {
53 return getInfo(Id
).Name
;
56 types::ID
types::getPreprocessedType(ID Id
) {
57 ID PPT
= getInfo(Id
).PreprocessedType
;
58 assert((getInfo(Id
).Phases
.contains(phases::Preprocess
) !=
59 (PPT
== TY_INVALID
)) &&
60 "Unexpected Preprocess Type.");
64 static bool isPreprocessedModuleType(ID Id
) {
65 return Id
== TY_CXXModule
|| Id
== TY_PP_CXXModule
;
68 static bool isPreprocessedHeaderUnitType(ID Id
) {
69 return Id
== TY_CXXSHeader
|| Id
== TY_CXXUHeader
|| Id
== TY_CXXHUHeader
||
70 Id
== TY_PP_CXXHeaderUnit
;
73 types::ID
types::getPrecompiledType(ID Id
) {
74 if (isPreprocessedModuleType(Id
))
76 if (isPreprocessedHeaderUnitType(Id
))
78 if (onlyPrecompileType(Id
))
83 const char *types::getTypeTempSuffix(ID Id
, bool CLMode
) {
97 return getInfo(Id
).TempSuffix
;
100 bool types::onlyPrecompileType(ID Id
) {
101 return getInfo(Id
).Phases
.contains(phases::Precompile
) &&
102 !isPreprocessedModuleType(Id
);
105 bool types::canTypeBeUserSpecified(ID Id
) {
106 static const clang::driver::types::ID kStaticLangageTypes
[] = {
107 TY_CUDA_DEVICE
, TY_HIP_DEVICE
, TY_PP_CHeader
,
108 TY_PP_ObjCHeader
, TY_PP_CXXHeader
, TY_PP_ObjCXXHeader
,
109 TY_PP_CXXModule
, TY_LTO_IR
, TY_LTO_BC
,
110 TY_Plist
, TY_RewrittenObjC
, TY_RewrittenLegacyObjC
,
111 TY_Remap
, TY_PCH
, TY_Object
,
112 TY_Image
, TY_dSYM
, TY_Dependencies
,
113 TY_CUDA_FATBIN
, TY_HIP_FATBIN
};
114 return !llvm::is_contained(kStaticLangageTypes
, Id
);
117 bool types::appendSuffixForType(ID Id
) {
118 return Id
== TY_PCH
|| Id
== TY_dSYM
|| Id
== TY_CUDA_FATBIN
||
122 bool types::canLipoType(ID Id
) {
123 return (Id
== TY_Nothing
||
129 bool types::isAcceptedByClang(ID Id
) {
135 case TY_C
: case TY_PP_C
:
136 case TY_CL
: case TY_CLCXX
:
137 case TY_CUDA
: case TY_PP_CUDA
:
142 case TY_ObjC
: case TY_PP_ObjC
: case TY_PP_ObjC_Alias
:
143 case TY_CXX
: case TY_PP_CXX
:
144 case TY_ObjCXX
: case TY_PP_ObjCXX
: case TY_PP_ObjCXX_Alias
:
145 case TY_CHeader
: case TY_PP_CHeader
:
147 case TY_ObjCHeader
: case TY_PP_ObjCHeader
:
148 case TY_CXXHeader
: case TY_PP_CXXHeader
:
152 case TY_PP_CXXHeaderUnit
:
153 case TY_ObjCXXHeader
: case TY_PP_ObjCXXHeader
:
154 case TY_CXXModule
: case TY_PP_CXXModule
:
155 case TY_AST
: case TY_ModuleFile
: case TY_PCH
:
156 case TY_LLVM_IR
: case TY_LLVM_BC
:
162 bool types::isAcceptedByFlang(ID Id
) {
176 bool types::isDerivedFromC(ID Id
) {
192 case TY_PP_ObjC_Alias
:
197 case TY_PP_ObjCXX_Alias
:
199 case TY_RenderScript
:
203 case TY_PP_ObjCHeader
:
205 case TY_PP_CXXHeader
:
207 case TY_PP_ObjCXXHeader
:
208 case TY_ObjCXXHeader
:
210 case TY_PP_CXXModule
:
215 bool types::isObjC(ID Id
) {
220 case TY_ObjC
: case TY_PP_ObjC
: case TY_PP_ObjC_Alias
:
221 case TY_ObjCXX
: case TY_PP_ObjCXX
:
222 case TY_ObjCHeader
: case TY_PP_ObjCHeader
:
223 case TY_ObjCXXHeader
: case TY_PP_ObjCXXHeader
: case TY_PP_ObjCXX_Alias
:
228 bool types::isOpenCL(ID Id
) { return Id
== TY_CL
|| Id
== TY_CLCXX
; }
230 bool types::isCXX(ID Id
) {
235 case TY_CXX
: case TY_PP_CXX
:
236 case TY_ObjCXX
: case TY_PP_ObjCXX
: case TY_PP_ObjCXX_Alias
:
237 case TY_CXXHeader
: case TY_PP_CXXHeader
:
241 case TY_PP_CXXHeaderUnit
:
242 case TY_ObjCXXHeader
: case TY_PP_ObjCXXHeader
:
243 case TY_CXXModule
: case TY_PP_CXXModule
:
244 case TY_CUDA
: case TY_PP_CUDA
: case TY_CUDA_DEVICE
:
252 bool types::isLLVMIR(ID Id
) {
265 bool types::isCuda(ID Id
) {
277 bool types::isHIP(ID Id
) {
289 bool types::isHLSL(ID Id
) { return Id
== TY_HLSL
; }
291 bool types::isSrcFile(ID Id
) {
292 return Id
!= TY_Object
&& getPreprocessedType(Id
) != TY_INVALID
;
295 types::ID
types::lookupTypeForExtension(llvm::StringRef Ext
) {
296 return llvm::StringSwitch
<types::ID
>(Ext
)
299 .Case("F", TY_Fortran
)
300 .Case("f", TY_PP_Fortran
)
301 .Case("h", TY_CHeader
)
302 .Case("H", TY_CXXHeader
)
305 .Case("M", TY_ObjCXX
)
306 .Case("o", TY_Object
)
308 .Case("s", TY_PP_Asm
)
309 .Case("bc", TY_LLVM_BC
)
313 .Case("clcpp", TY_CLCXX
)
316 .Case("hh", TY_CXXHeader
)
317 .Case("ii", TY_PP_CXX
)
318 .Case("ll", TY_LLVM_IR
)
319 .Case("mi", TY_PP_ObjC
)
320 .Case("mm", TY_ObjCXX
)
321 .Case("rs", TY_RenderScript
)
324 .Case("asm", TY_PP_Asm
)
326 .Case("ccm", TY_CXXModule
)
331 .Case("cui", TY_PP_CUDA
)
334 .Case("F90", TY_Fortran
)
335 .Case("f90", TY_PP_Fortran
)
336 .Case("F95", TY_Fortran
)
337 .Case("f95", TY_PP_Fortran
)
338 .Case("for", TY_PP_Fortran
)
339 .Case("FOR", TY_PP_Fortran
)
340 .Case("fpp", TY_Fortran
)
341 .Case("FPP", TY_Fortran
)
344 .Case("hipi", TY_PP_HIP
)
345 .Case("hpp", TY_CXXHeader
)
346 .Case("hxx", TY_CXXHeader
)
347 .Case("iim", TY_PP_CXXModule
)
348 .Case("iih", TY_PP_CXXHeaderUnit
)
349 .Case("lib", TY_Object
)
350 .Case("mii", TY_PP_ObjCXX
)
351 .Case("obj", TY_Object
)
354 .Case("pcm", TY_ModuleFile
)
355 .Case("c++m", TY_CXXModule
)
356 .Case("cppm", TY_CXXModule
)
357 .Case("cxxm", TY_CXXModule
)
358 .Case("hlsl", TY_HLSL
)
359 .Default(TY_INVALID
);
362 types::ID
types::lookupTypeForTypeSpecifier(const char *Name
) {
363 for (unsigned i
=0; i
<numTypes
; ++i
) {
364 types::ID Id
= (types::ID
) (i
+ 1);
365 if (canTypeBeUserSpecified(Id
) &&
366 strcmp(Name
, getInfo(Id
).Name
) == 0)
369 // Accept "cu" as an alias for "cuda" for NVCC compatibility
370 if (strcmp(Name
, "cu") == 0) {
371 return types::TY_CUDA
;
376 llvm::SmallVector
<phases::ID
, phases::MaxNumberOfPhases
>
377 types::getCompilationPhases(ID Id
, phases::ID LastPhase
) {
378 llvm::SmallVector
<phases::ID
, phases::MaxNumberOfPhases
> P
;
379 const auto &Info
= getInfo(Id
);
380 for (int I
= 0; I
<= LastPhase
; ++I
)
381 if (Info
.Phases
.contains(static_cast<phases::ID
>(I
)))
382 P
.push_back(static_cast<phases::ID
>(I
));
383 assert(P
.size() <= phases::MaxNumberOfPhases
&& "Too many phases in list");
387 llvm::SmallVector
<phases::ID
, phases::MaxNumberOfPhases
>
388 types::getCompilationPhases(const clang::driver::Driver
&Driver
,
389 llvm::opt::DerivedArgList
&DAL
, ID Id
) {
390 return types::getCompilationPhases(Id
, Driver
.getFinalPhase(DAL
));
393 ID
types::lookupCXXTypeForCType(ID Id
) {
399 return types::TY_CXX
;
401 return types::TY_PP_CXX
;
402 case types::TY_CHeader
:
403 return types::TY_CXXHeader
;
404 case types::TY_PP_CHeader
:
405 return types::TY_PP_CXXHeader
;
409 ID
types::lookupHeaderTypeForSourceType(ID Id
) {
414 // FIXME: Handle preprocessed input types.
416 return types::TY_CHeader
;
418 case types::TY_CXXModule
:
419 return types::TY_CXXHeader
;
421 return types::TY_ObjCHeader
;
422 case types::TY_ObjCXX
:
423 return types::TY_ObjCXXHeader
;
425 case types::TY_CLCXX
:
426 return types::TY_CLHeader
;