Program.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. //===--- Program.cpp - Bytecode for the constexpr VM ------------*- C++ -*-===//
  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. #include "Program.h"
  9. #include "ByteCodeStmtGen.h"
  10. #include "Context.h"
  11. #include "Function.h"
  12. #include "Opcode.h"
  13. #include "PrimType.h"
  14. #include "clang/AST/Decl.h"
  15. #include "clang/AST/DeclCXX.h"
  16. using namespace clang;
  17. using namespace clang::interp;
  18. unsigned Program::getOrCreateNativePointer(const void *Ptr) {
  19. auto It = NativePointerIndices.find(Ptr);
  20. if (It != NativePointerIndices.end())
  21. return It->second;
  22. unsigned Idx = NativePointers.size();
  23. NativePointers.push_back(Ptr);
  24. NativePointerIndices[Ptr] = Idx;
  25. return Idx;
  26. }
  27. const void *Program::getNativePointer(unsigned Idx) {
  28. return NativePointers[Idx];
  29. }
  30. unsigned Program::createGlobalString(const StringLiteral *S) {
  31. const size_t CharWidth = S->getCharByteWidth();
  32. const size_t BitWidth = CharWidth * Ctx.getCharBit();
  33. PrimType CharType;
  34. switch (CharWidth) {
  35. case 1:
  36. CharType = PT_Sint8;
  37. break;
  38. case 2:
  39. CharType = PT_Uint16;
  40. break;
  41. case 4:
  42. CharType = PT_Uint32;
  43. break;
  44. default:
  45. llvm_unreachable("unsupported character width");
  46. }
  47. // Create a descriptor for the string.
  48. Descriptor *Desc = allocateDescriptor(S, CharType, S->getLength() + 1,
  49. /*isConst=*/true,
  50. /*isTemporary=*/false,
  51. /*isMutable=*/false);
  52. // Allocate storage for the string.
  53. // The byte length does not include the null terminator.
  54. unsigned I = Globals.size();
  55. unsigned Sz = Desc->getAllocSize();
  56. auto *G = new (Allocator, Sz) Global(Desc, /*isStatic=*/true,
  57. /*isExtern=*/false);
  58. Globals.push_back(G);
  59. // Construct the string in storage.
  60. const Pointer Ptr(G->block());
  61. for (unsigned I = 0, N = S->getLength(); I <= N; ++I) {
  62. Pointer Field = Ptr.atIndex(I).narrow();
  63. const uint32_t CodePoint = I == N ? 0 : S->getCodeUnit(I);
  64. switch (CharType) {
  65. case PT_Sint8: {
  66. using T = PrimConv<PT_Sint8>::T;
  67. Field.deref<T>() = T::from(CodePoint, BitWidth);
  68. break;
  69. }
  70. case PT_Uint16: {
  71. using T = PrimConv<PT_Uint16>::T;
  72. Field.deref<T>() = T::from(CodePoint, BitWidth);
  73. break;
  74. }
  75. case PT_Uint32: {
  76. using T = PrimConv<PT_Uint32>::T;
  77. Field.deref<T>() = T::from(CodePoint, BitWidth);
  78. break;
  79. }
  80. default:
  81. llvm_unreachable("unsupported character type");
  82. }
  83. }
  84. return I;
  85. }
  86. Pointer Program::getPtrGlobal(unsigned Idx) {
  87. assert(Idx < Globals.size());
  88. return Pointer(Globals[Idx]->block());
  89. }
  90. llvm::Optional<unsigned> Program::getGlobal(const ValueDecl *VD) {
  91. auto It = GlobalIndices.find(VD);
  92. if (It != GlobalIndices.end())
  93. return It->second;
  94. // Find any previous declarations which were already evaluated.
  95. llvm::Optional<unsigned> Index;
  96. for (const Decl *P = VD; P; P = P->getPreviousDecl()) {
  97. auto It = GlobalIndices.find(P);
  98. if (It != GlobalIndices.end()) {
  99. Index = It->second;
  100. break;
  101. }
  102. }
  103. // Map the decl to the existing index.
  104. if (Index) {
  105. GlobalIndices[VD] = *Index;
  106. return {};
  107. }
  108. return Index;
  109. }
  110. llvm::Optional<unsigned> Program::getOrCreateGlobal(const ValueDecl *VD) {
  111. if (auto Idx = getGlobal(VD))
  112. return Idx;
  113. if (auto Idx = createGlobal(VD)) {
  114. GlobalIndices[VD] = *Idx;
  115. return Idx;
  116. }
  117. return {};
  118. }
  119. llvm::Optional<unsigned> Program::getOrCreateDummy(const ParmVarDecl *PD) {
  120. auto &ASTCtx = Ctx.getASTContext();
  121. // Create a pointer to an incomplete array of the specified elements.
  122. QualType ElemTy = PD->getType()->castAs<PointerType>()->getPointeeType();
  123. QualType Ty = ASTCtx.getIncompleteArrayType(ElemTy, ArrayType::Normal, 0);
  124. // Dedup blocks since they are immutable and pointers cannot be compared.
  125. auto It = DummyParams.find(PD);
  126. if (It != DummyParams.end())
  127. return It->second;
  128. if (auto Idx = createGlobal(PD, Ty, /*isStatic=*/true, /*isExtern=*/true)) {
  129. DummyParams[PD] = *Idx;
  130. return Idx;
  131. }
  132. return {};
  133. }
  134. llvm::Optional<unsigned> Program::createGlobal(const ValueDecl *VD) {
  135. bool IsStatic, IsExtern;
  136. if (auto *Var = dyn_cast<VarDecl>(VD)) {
  137. IsStatic = !Var->hasLocalStorage();
  138. IsExtern = !Var->getAnyInitializer();
  139. } else {
  140. IsStatic = false;
  141. IsExtern = true;
  142. }
  143. if (auto Idx = createGlobal(VD, VD->getType(), IsStatic, IsExtern)) {
  144. for (const Decl *P = VD; P; P = P->getPreviousDecl())
  145. GlobalIndices[P] = *Idx;
  146. return *Idx;
  147. }
  148. return {};
  149. }
  150. llvm::Optional<unsigned> Program::createGlobal(const Expr *E) {
  151. return createGlobal(E, E->getType(), /*isStatic=*/true, /*isExtern=*/false);
  152. }
  153. llvm::Optional<unsigned> Program::createGlobal(const DeclTy &D, QualType Ty,
  154. bool IsStatic, bool IsExtern) {
  155. // Create a descriptor for the global.
  156. Descriptor *Desc;
  157. const bool IsConst = Ty.isConstQualified();
  158. const bool IsTemporary = D.dyn_cast<const Expr *>();
  159. if (auto T = Ctx.classify(Ty)) {
  160. Desc = createDescriptor(D, *T, IsConst, IsTemporary);
  161. } else {
  162. Desc = createDescriptor(D, Ty.getTypePtr(), IsConst, IsTemporary);
  163. }
  164. if (!Desc)
  165. return {};
  166. // Allocate a block for storage.
  167. unsigned I = Globals.size();
  168. auto *G = new (Allocator, Desc->getAllocSize())
  169. Global(getCurrentDecl(), Desc, IsStatic, IsExtern);
  170. G->block()->invokeCtor();
  171. Globals.push_back(G);
  172. return I;
  173. }
  174. Function *Program::getFunction(const FunctionDecl *F) {
  175. F = F->getDefinition();
  176. auto It = Funcs.find(F);
  177. return It == Funcs.end() ? nullptr : It->second.get();
  178. }
  179. llvm::Expected<Function *> Program::getOrCreateFunction(const FunctionDecl *F) {
  180. if (Function *Func = getFunction(F)) {
  181. return Func;
  182. }
  183. // Try to compile the function if it wasn't compiled yet.
  184. if (const FunctionDecl *FD = F->getDefinition())
  185. return ByteCodeStmtGen<ByteCodeEmitter>(Ctx, *this).compileFunc(FD);
  186. // A relocation which traps if not resolved.
  187. return nullptr;
  188. }
  189. Record *Program::getOrCreateRecord(const RecordDecl *RD) {
  190. // Use the actual definition as a key.
  191. RD = RD->getDefinition();
  192. if (!RD)
  193. return nullptr;
  194. // Deduplicate records.
  195. auto It = Records.find(RD);
  196. if (It != Records.end()) {
  197. return It->second;
  198. }
  199. // Number of bytes required by fields and base classes.
  200. unsigned Size = 0;
  201. // Number of bytes required by virtual base.
  202. unsigned VirtSize = 0;
  203. // Helper to get a base descriptor.
  204. auto GetBaseDesc = [this](const RecordDecl *BD, Record *BR) -> Descriptor * {
  205. if (!BR)
  206. return nullptr;
  207. return allocateDescriptor(BD, BR, /*isConst=*/false,
  208. /*isTemporary=*/false,
  209. /*isMutable=*/false);
  210. };
  211. // Reserve space for base classes.
  212. Record::BaseList Bases;
  213. Record::VirtualBaseList VirtBases;
  214. if (auto *CD = dyn_cast<CXXRecordDecl>(RD)) {
  215. for (const CXXBaseSpecifier &Spec : CD->bases()) {
  216. if (Spec.isVirtual())
  217. continue;
  218. const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
  219. Record *BR = getOrCreateRecord(BD);
  220. if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
  221. Size += align(sizeof(InlineDescriptor));
  222. Bases.push_back({BD, Size, Desc, BR});
  223. Size += align(BR->getSize());
  224. continue;
  225. }
  226. return nullptr;
  227. }
  228. for (const CXXBaseSpecifier &Spec : CD->vbases()) {
  229. const RecordDecl *BD = Spec.getType()->castAs<RecordType>()->getDecl();
  230. Record *BR = getOrCreateRecord(BD);
  231. if (Descriptor *Desc = GetBaseDesc(BD, BR)) {
  232. VirtSize += align(sizeof(InlineDescriptor));
  233. VirtBases.push_back({BD, VirtSize, Desc, BR});
  234. VirtSize += align(BR->getSize());
  235. continue;
  236. }
  237. return nullptr;
  238. }
  239. }
  240. // Reserve space for fields.
  241. Record::FieldList Fields;
  242. for (const FieldDecl *FD : RD->fields()) {
  243. // Reserve space for the field's descriptor and the offset.
  244. Size += align(sizeof(InlineDescriptor));
  245. // Classify the field and add its metadata.
  246. QualType FT = FD->getType();
  247. const bool IsConst = FT.isConstQualified();
  248. const bool IsMutable = FD->isMutable();
  249. Descriptor *Desc;
  250. if (llvm::Optional<PrimType> T = Ctx.classify(FT)) {
  251. Desc = createDescriptor(FD, *T, IsConst, /*isTemporary=*/false,
  252. IsMutable);
  253. } else {
  254. Desc = createDescriptor(FD, FT.getTypePtr(), IsConst,
  255. /*isTemporary=*/false, IsMutable);
  256. }
  257. if (!Desc)
  258. return nullptr;
  259. Fields.push_back({FD, Size, Desc});
  260. Size += align(Desc->getAllocSize());
  261. }
  262. Record *R = new (Allocator) Record(RD, std::move(Bases), std::move(Fields),
  263. std::move(VirtBases), VirtSize, Size);
  264. Records.insert({RD, R});
  265. return R;
  266. }
  267. Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
  268. bool IsConst, bool IsTemporary,
  269. bool IsMutable) {
  270. // Classes and structures.
  271. if (auto *RT = Ty->getAs<RecordType>()) {
  272. if (auto *Record = getOrCreateRecord(RT->getDecl()))
  273. return allocateDescriptor(D, Record, IsConst, IsTemporary, IsMutable);
  274. }
  275. // Arrays.
  276. if (auto ArrayType = Ty->getAsArrayTypeUnsafe()) {
  277. QualType ElemTy = ArrayType->getElementType();
  278. // Array of well-known bounds.
  279. if (auto CAT = dyn_cast<ConstantArrayType>(ArrayType)) {
  280. size_t NumElems = CAT->getSize().getZExtValue();
  281. if (llvm::Optional<PrimType> T = Ctx.classify(ElemTy)) {
  282. // Arrays of primitives.
  283. unsigned ElemSize = primSize(*T);
  284. if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems) {
  285. return {};
  286. }
  287. return allocateDescriptor(D, *T, NumElems, IsConst, IsTemporary,
  288. IsMutable);
  289. } else {
  290. // Arrays of composites. In this case, the array is a list of pointers,
  291. // followed by the actual elements.
  292. Descriptor *Desc =
  293. createDescriptor(D, ElemTy.getTypePtr(), IsConst, IsTemporary);
  294. if (!Desc)
  295. return nullptr;
  296. InterpSize ElemSize = Desc->getAllocSize() + sizeof(InlineDescriptor);
  297. if (std::numeric_limits<unsigned>::max() / ElemSize <= NumElems)
  298. return {};
  299. return allocateDescriptor(D, Desc, NumElems, IsConst, IsTemporary,
  300. IsMutable);
  301. }
  302. }
  303. // Array of unknown bounds - cannot be accessed and pointer arithmetic
  304. // is forbidden on pointers to such objects.
  305. if (isa<IncompleteArrayType>(ArrayType)) {
  306. if (llvm::Optional<PrimType> T = Ctx.classify(ElemTy)) {
  307. return allocateDescriptor(D, *T, IsTemporary,
  308. Descriptor::UnknownSize{});
  309. } else {
  310. Descriptor *Desc =
  311. createDescriptor(D, ElemTy.getTypePtr(), IsConst, IsTemporary);
  312. if (!Desc)
  313. return nullptr;
  314. return allocateDescriptor(D, Desc, IsTemporary,
  315. Descriptor::UnknownSize{});
  316. }
  317. }
  318. }
  319. // Atomic types.
  320. if (auto *AT = Ty->getAs<AtomicType>()) {
  321. const Type *InnerTy = AT->getValueType().getTypePtr();
  322. return createDescriptor(D, InnerTy, IsConst, IsTemporary, IsMutable);
  323. }
  324. // Complex types - represented as arrays of elements.
  325. if (auto *CT = Ty->getAs<ComplexType>()) {
  326. PrimType ElemTy = *Ctx.classify(CT->getElementType());
  327. return allocateDescriptor(D, ElemTy, 2, IsConst, IsTemporary, IsMutable);
  328. }
  329. return nullptr;
  330. }