aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Program.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Program.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Program.cpp79
1 files changed, 36 insertions, 43 deletions
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index e0b2852..4d34e0b 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -36,30 +36,19 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) {
const size_t BitWidth = CharWidth * Ctx.getCharBit();
unsigned StringLength = S->getLength();
- PrimType CharType;
- switch (CharWidth) {
- case 1:
- CharType = PT_Sint8;
- break;
- case 2:
- CharType = PT_Uint16;
- break;
- case 4:
- CharType = PT_Uint32;
- break;
- default:
- llvm_unreachable("unsupported character width");
- }
+ OptPrimType CharType =
+ Ctx.classify(S->getType()->castAsArrayTypeUnsafe()->getElementType());
+ assert(CharType);
if (!Base)
Base = S;
// Create a descriptor for the string.
- Descriptor *Desc =
- allocateDescriptor(Base, CharType, Descriptor::GlobalMD, StringLength + 1,
- /*isConst=*/true,
- /*isTemporary=*/false,
- /*isMutable=*/false);
+ Descriptor *Desc = allocateDescriptor(Base, *CharType, Descriptor::GlobalMD,
+ StringLength + 1,
+ /*isConst=*/true,
+ /*isTemporary=*/false,
+ /*isMutable=*/false);
// Allocate storage for the string.
// The byte length does not include the null terminator.
@@ -79,26 +68,9 @@ unsigned Program::createGlobalString(const StringLiteral *S, const Expr *Base) {
} else {
// Construct the string in storage.
for (unsigned I = 0; I <= StringLength; ++I) {
- const uint32_t CodePoint = I == StringLength ? 0 : S->getCodeUnit(I);
- switch (CharType) {
- case PT_Sint8: {
- using T = PrimConv<PT_Sint8>::T;
- Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
- break;
- }
- case PT_Uint16: {
- using T = PrimConv<PT_Uint16>::T;
- Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
- break;
- }
- case PT_Uint32: {
- using T = PrimConv<PT_Uint32>::T;
- Ptr.elem<T>(I) = T::from(CodePoint, BitWidth);
- break;
- }
- default:
- llvm_unreachable("unsupported character type");
- }
+ uint32_t CodePoint = I == StringLength ? 0 : S->getCodeUnit(I);
+ INT_TYPE_SWITCH_NO_BOOL(*CharType,
+ Ptr.elem<T>(I) = T::from(CodePoint, BitWidth););
}
}
Ptr.initializeAllElements();
@@ -218,21 +190,42 @@ UnsignedOrNone Program::createGlobal(const ValueDecl *VD, const Expr *Init) {
return std::nullopt;
Global *NewGlobal = Globals[*Idx];
+ // Note that this loop has one iteration where Redecl == VD.
for (const Decl *Redecl : VD->redecls()) {
- unsigned &PIdx = GlobalIndices[Redecl];
+
+ // If this redecl was registered as a dummy variable, it is now a proper
+ // global variable and points to the block we just created.
+ if (auto DummyIt = DummyVariables.find(Redecl);
+ DummyIt != DummyVariables.end()) {
+ assert(!Globals[DummyIt->second]->block()->hasPointers());
+ Globals[DummyIt->second] = NewGlobal;
+ DummyVariables.erase(DummyIt);
+ }
+ // If the redeclaration hasn't been registered yet at all, we just set its
+ // global index to Idx. If it has been registered yet, it might have
+ // pointers pointing to it and we need to transfer those pointers to the new
+ // block.
+ auto [Iter, Inserted] = GlobalIndices.try_emplace(Redecl);
+ if (Inserted) {
+ GlobalIndices[Redecl] = *Idx;
+ continue;
+ }
+
if (Redecl != VD) {
- if (Block *RedeclBlock = Globals[PIdx]->block();
+ if (Block *RedeclBlock = Globals[Iter->second]->block();
RedeclBlock->isExtern()) {
- Globals[PIdx] = NewGlobal;
+
// All pointers pointing to the previous extern decl now point to the
// new decl.
// A previous iteration might've already fixed up the pointers for this
// global.
if (RedeclBlock != NewGlobal->block())
RedeclBlock->movePointersTo(NewGlobal->block());
+
+ Globals[Iter->second] = NewGlobal;
}
}
- PIdx = *Idx;
+ Iter->second = *Idx;
}
return *Idx;