448 lines · cpp
1//===--- Types.cpp - Driver input & temporary type information ------------===//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 "clang/Driver/Types.h"10#include "clang/Driver/Driver.h"11#include "llvm/ADT/STLExtras.h"12#include "llvm/ADT/SmallVector.h"13#include "llvm/ADT/StringSwitch.h"14#include <cassert>15#include <cstring>16 17using namespace clang::driver;18using namespace clang::driver::types;19 20struct TypeInfo {21 const char *Name;22 const char *TempSuffix;23 ID PreprocessedType;24 class PhasesBitSet {25 unsigned Bits = 0;26 27 public:28 constexpr PhasesBitSet(std::initializer_list<phases::ID> Phases) {29 for (auto Id : Phases)30 Bits |= 1 << Id;31 }32 bool contains(phases::ID Id) const { return Bits & (1 << Id); }33 } Phases;34};35 36static constexpr TypeInfo TypeInfos[] = {37#define TYPE(NAME, ID, PP_TYPE, TEMP_SUFFIX, ...) \38 { NAME, TEMP_SUFFIX, TY_##PP_TYPE, { __VA_ARGS__ }, },39#include "clang/Driver/Types.def"40#undef TYPE41};42static const unsigned numTypes = std::size(TypeInfos);43 44static const TypeInfo &getInfo(unsigned id) {45 assert(id > 0 && id - 1 < numTypes && "Invalid Type ID.");46 return TypeInfos[id - 1];47}48 49const char *types::getTypeName(ID Id) {50 return getInfo(Id).Name;51}52 53types::ID types::getPreprocessedType(ID Id) {54 ID PPT = getInfo(Id).PreprocessedType;55 assert((getInfo(Id).Phases.contains(phases::Preprocess) !=56 (PPT == TY_INVALID)) &&57 "Unexpected Preprocess Type.");58 return PPT;59}60 61static bool isPreprocessedModuleType(ID Id) {62 return Id == TY_CXXModule || Id == TY_PP_CXXModule;63}64 65static bool isPreprocessedHeaderUnitType(ID Id) {66 return Id == TY_CXXSHeader || Id == TY_CXXUHeader || Id == TY_CXXHUHeader ||67 Id == TY_PP_CXXHeaderUnit;68}69 70types::ID types::getPrecompiledType(ID Id) {71 if (isPreprocessedModuleType(Id))72 return TY_ModuleFile;73 if (isPreprocessedHeaderUnitType(Id))74 return TY_HeaderUnit;75 if (onlyPrecompileType(Id))76 return TY_PCH;77 return TY_INVALID;78}79 80const char *types::getTypeTempSuffix(ID Id, bool CLStyle) {81 if (CLStyle) {82 switch (Id) {83 case TY_Object:84 case TY_LTO_BC:85 return "obj";86 case TY_Image:87 return "exe";88 case TY_PP_Asm:89 return "asm";90 default:91 break;92 }93 }94 return getInfo(Id).TempSuffix;95}96 97bool types::onlyPrecompileType(ID Id) {98 return getInfo(Id).Phases.contains(phases::Precompile) &&99 !isPreprocessedModuleType(Id);100}101 102bool types::canTypeBeUserSpecified(ID Id) {103 static const clang::driver::types::ID kStaticLangageTypes[] = {104 TY_CUDA_DEVICE, TY_HIP_DEVICE, TY_PP_CHeader,105 TY_PP_ObjCHeader, TY_PP_CXXHeader, TY_PP_ObjCXXHeader,106 TY_PP_CXXModule, TY_LTO_IR, TY_LTO_BC,107 TY_Plist, TY_RewrittenObjC, TY_RewrittenLegacyObjC,108 TY_Remap, TY_PCH, TY_Object,109 TY_Image, TY_dSYM, TY_Dependencies,110 TY_CUDA_FATBIN, TY_HIP_FATBIN};111 return !llvm::is_contained(kStaticLangageTypes, Id);112}113 114bool types::appendSuffixForType(ID Id) {115 return Id == TY_PCH || Id == TY_dSYM || Id == TY_CUDA_FATBIN ||116 Id == TY_HIP_FATBIN;117}118 119bool types::canLipoType(ID Id) {120 return (Id == TY_Nothing ||121 Id == TY_Image ||122 Id == TY_Object ||123 Id == TY_LTO_BC);124}125 126bool types::isAcceptedByClang(ID Id) {127 switch (Id) {128 default:129 return false;130 131 case TY_Asm:132 case TY_C: case TY_PP_C:133 case TY_CL: case TY_PP_CL: case TY_CLCXX: case TY_PP_CLCXX:134 case TY_CUDA: case TY_PP_CUDA:135 case TY_CUDA_DEVICE:136 case TY_HIP:137 case TY_PP_HIP:138 case TY_HIP_DEVICE:139 case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:140 case TY_CXX: case TY_PP_CXX:141 case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:142 case TY_CHeader: case TY_PP_CHeader:143 case TY_CLHeader:144 case TY_ObjCHeader: case TY_PP_ObjCHeader:145 case TY_CXXHeader: case TY_PP_CXXHeader:146 case TY_CXXSHeader:147 case TY_CXXUHeader:148 case TY_CXXHUHeader:149 case TY_PP_CXXHeaderUnit:150 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:151 case TY_CXXModule: case TY_PP_CXXModule:152 case TY_AST: case TY_ModuleFile: case TY_PCH:153 case TY_LLVM_IR: case TY_LLVM_BC:154 case TY_API_INFO:155 return true;156 }157}158 159bool types::isAcceptedByFlang(ID Id) {160 switch (Id) {161 default:162 return false;163 164 case TY_Fortran:165 case TY_PP_Fortran:166 return true;167 case TY_LLVM_IR:168 case TY_LLVM_BC:169 return true;170 case TY_PP_CUDA:171 case TY_CUDA:172 return true;173 }174}175 176bool types::isDerivedFromC(ID Id) {177 switch (Id) {178 default:179 return false;180 181 case TY_PP_C:182 case TY_C:183 case TY_CL:184 case TY_PP_CL:185 case TY_CLCXX:186 case TY_PP_CLCXX:187 case TY_PP_CUDA:188 case TY_CUDA:189 case TY_CUDA_DEVICE:190 case TY_PP_HIP:191 case TY_HIP:192 case TY_HIP_DEVICE:193 case TY_PP_ObjC:194 case TY_PP_ObjC_Alias:195 case TY_ObjC:196 case TY_PP_CXX:197 case TY_CXX:198 case TY_PP_ObjCXX:199 case TY_PP_ObjCXX_Alias:200 case TY_ObjCXX:201 case TY_PP_CHeader:202 case TY_CHeader:203 case TY_CLHeader:204 case TY_PP_ObjCHeader:205 case TY_ObjCHeader:206 case TY_PP_CXXHeader:207 case TY_CXXHeader:208 case TY_PP_ObjCXXHeader:209 case TY_ObjCXXHeader:210 case TY_CXXModule:211 case TY_PP_CXXModule:212 return true;213 }214}215 216bool types::isObjC(ID Id) {217 switch (Id) {218 default:219 return false;220 221 case TY_ObjC: case TY_PP_ObjC: case TY_PP_ObjC_Alias:222 case TY_ObjCXX: case TY_PP_ObjCXX:223 case TY_ObjCHeader: case TY_PP_ObjCHeader:224 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader: case TY_PP_ObjCXX_Alias:225 return true;226 }227}228 229bool types::isOpenCL(ID Id) {230 switch (Id) {231 default:232 return false;233 case TY_PP_CL:234 case TY_PP_CLCXX:235 case TY_CL:236 case TY_CLCXX:237 return true;238 }239}240 241bool types::isCXX(ID Id) {242 switch (Id) {243 default:244 return false;245 246 case TY_CXX: case TY_PP_CXX:247 case TY_ObjCXX: case TY_PP_ObjCXX: case TY_PP_ObjCXX_Alias:248 case TY_CXXHeader: case TY_PP_CXXHeader:249 case TY_CXXSHeader:250 case TY_CXXUHeader:251 case TY_CXXHUHeader:252 case TY_PP_CXXHeaderUnit:253 case TY_ObjCXXHeader: case TY_PP_ObjCXXHeader:254 case TY_CXXModule:255 case TY_PP_CXXModule:256 case TY_ModuleFile:257 case TY_PP_CLCXX:258 case TY_CUDA: case TY_PP_CUDA: case TY_CUDA_DEVICE:259 case TY_HIP:260 case TY_PP_HIP:261 case TY_HIP_DEVICE:262 return true;263 }264}265 266bool types::isLLVMIR(ID Id) {267 switch (Id) {268 default:269 return false;270 271 case TY_LLVM_IR:272 case TY_LLVM_BC:273 case TY_LTO_IR:274 case TY_LTO_BC:275 return true;276 }277}278 279bool types::isCuda(ID Id) {280 switch (Id) {281 default:282 return false;283 284 case TY_CUDA:285 case TY_PP_CUDA:286 case TY_CUDA_DEVICE:287 return true;288 }289}290 291bool types::isHIP(ID Id) {292 switch (Id) {293 default:294 return false;295 296 case TY_HIP:297 case TY_PP_HIP:298 case TY_HIP_DEVICE:299 return true;300 }301}302 303bool types::isHLSL(ID Id) { return Id == TY_HLSL; }304 305bool types::isSrcFile(ID Id) {306 return Id != TY_Object && getPreprocessedType(Id) != TY_INVALID;307}308 309types::ID types::lookupTypeForExtension(llvm::StringRef Ext) {310 return llvm::StringSwitch<types::ID>(Ext)311 .Case("c", TY_C)312 .Case("C", TY_CXX)313 .Case("F", TY_Fortran)314 .Case("f", TY_PP_Fortran)315 .Case("h", TY_CHeader)316 .Case("H", TY_CXXHeader)317 .Case("i", TY_PP_C)318 .Case("m", TY_ObjC)319 .Case("M", TY_ObjCXX)320 .Case("o", TY_Object)321 .Case("S", TY_Asm)322 .Case("s", TY_PP_Asm)323 .Case("bc", TY_LLVM_BC)324 .Case("cc", TY_CXX)325 .Case("CC", TY_CXX)326 .Case("cl", TY_CL)327 .Case("cli", TY_PP_CL)328 .Case("clcpp", TY_CLCXX)329 .Case("clii", TY_PP_CLCXX)330 .Case("cp", TY_CXX)331 .Case("cu", TY_CUDA)332 .Case("hh", TY_CXXHeader)333 .Case("ii", TY_PP_CXX)334 .Case("ll", TY_LLVM_IR)335 .Case("mi", TY_PP_ObjC)336 .Case("mm", TY_ObjCXX)337 .Case("adb", TY_Ada)338 .Case("ads", TY_Ada)339 .Case("asm", TY_PP_Asm)340 .Case("ast", TY_AST)341 .Case("ccm", TY_CXXModule)342 .Case("cpp", TY_CXX)343 .Case("CPP", TY_CXX)344 .Case("c++", TY_CXX)345 .Case("C++", TY_CXX)346 .Case("cui", TY_PP_CUDA)347 .Case("cxx", TY_CXX)348 .Case("CXX", TY_CXX)349 .Case("F03", TY_Fortran)350 .Case("f03", TY_PP_Fortran)351 .Case("F08", TY_Fortran)352 .Case("f08", TY_PP_Fortran)353 .Case("F90", TY_Fortran)354 .Case("f90", TY_PP_Fortran)355 .Case("F95", TY_Fortran)356 .Case("f95", TY_PP_Fortran)357 .Case("for", TY_PP_Fortran)358 .Case("FOR", TY_PP_Fortran)359 .Case("fpp", TY_Fortran)360 .Case("FPP", TY_Fortran)361 .Case("gch", TY_PCH)362 .Case("hip", TY_HIP)363 .Case("hipi", TY_PP_HIP)364 .Case("hpp", TY_CXXHeader)365 .Case("hxx", TY_CXXHeader)366 .Case("iim", TY_PP_CXXModule)367 .Case("iih", TY_PP_CXXHeaderUnit)368 .Case("lib", TY_Object)369 .Case("mii", TY_PP_ObjCXX)370 .Case("obj", TY_Object)371 .Case("ifs", TY_IFS)372 .Case("pch", TY_PCH)373 .Case("pcm", TY_ModuleFile)374 .Case("c++m", TY_CXXModule)375 .Case("cppm", TY_CXXModule)376 .Case("cxxm", TY_CXXModule)377 .Case("hlsl", TY_HLSL)378 .Default(TY_INVALID);379}380 381types::ID types::lookupTypeForTypeSpecifier(const char *Name) {382 for (unsigned i=0; i<numTypes; ++i) {383 types::ID Id = (types::ID) (i + 1);384 if (canTypeBeUserSpecified(Id) &&385 strcmp(Name, getInfo(Id).Name) == 0)386 return Id;387 }388 // Accept "cu" as an alias for "cuda" for NVCC compatibility389 if (strcmp(Name, "cu") == 0) {390 return types::TY_CUDA;391 }392 return TY_INVALID;393}394 395llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>396types::getCompilationPhases(ID Id, phases::ID LastPhase) {397 llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases> P;398 const auto &Info = getInfo(Id);399 for (int I = 0; I <= LastPhase; ++I)400 if (Info.Phases.contains(static_cast<phases::ID>(I)))401 P.push_back(static_cast<phases::ID>(I));402 assert(P.size() <= phases::MaxNumberOfPhases && "Too many phases in list");403 return P;404}405 406llvm::SmallVector<phases::ID, phases::MaxNumberOfPhases>407types::getCompilationPhases(const clang::driver::Driver &Driver,408 llvm::opt::DerivedArgList &DAL, ID Id) {409 return types::getCompilationPhases(Id, Driver.getFinalPhase(DAL));410}411 412ID types::lookupCXXTypeForCType(ID Id) {413 switch (Id) {414 default:415 return Id;416 417 case types::TY_C:418 return types::TY_CXX;419 case types::TY_PP_C:420 return types::TY_PP_CXX;421 case types::TY_CHeader:422 return types::TY_CXXHeader;423 case types::TY_PP_CHeader:424 return types::TY_PP_CXXHeader;425 }426}427 428ID types::lookupHeaderTypeForSourceType(ID Id) {429 switch (Id) {430 default:431 return Id;432 433 // FIXME: Handle preprocessed input types.434 case types::TY_C:435 return types::TY_CHeader;436 case types::TY_CXX:437 case types::TY_CXXModule:438 return types::TY_CXXHeader;439 case types::TY_ObjC:440 return types::TY_ObjCHeader;441 case types::TY_ObjCXX:442 return types::TY_ObjCXXHeader;443 case types::TY_CL:444 case types::TY_CLCXX:445 return types::TY_CLHeader;446 }447}448