|
17 | 17 | #include "clang/AST/DeclCXX.h"
|
18 | 18 | #include "clang/AST/DeclObjC.h"
|
19 | 19 | #include "clang/AST/ExprCXX.h"
|
| 20 | +#include "llvm/IR/GlobalValue.h" |
20 | 21 | #include "gtest/gtest.h"
|
21 | 22 |
|
22 | 23 | using namespace clang;
|
@@ -1116,3 +1117,118 @@ TEST_F(TestTypeSystemClang, AddMethodToCXXRecordType_ParmVarDecls) {
|
1116 | 1117 | EXPECT_EQ(method_it->getParamDecl(0)->getDeclContext(), *method_it);
|
1117 | 1118 | EXPECT_EQ(method_it->getParamDecl(1)->getDeclContext(), *method_it);
|
1118 | 1119 | }
|
| 1120 | + |
| 1121 | +TEST_F(TestTypeSystemClang, AsmLabel_CtorDtor) { |
| 1122 | + // Tests TypeSystemClang::DeclGetMangledName for constructors/destructors |
| 1123 | + // with and without AsmLabels. |
| 1124 | + |
| 1125 | + llvm::StringRef class_name = "S"; |
| 1126 | + CompilerType t = clang_utils::createRecord(*m_ast, class_name); |
| 1127 | + m_ast->StartTagDeclarationDefinition(t); |
| 1128 | + |
| 1129 | + CompilerType return_type = m_ast->GetBasicType(lldb::eBasicTypeVoid); |
| 1130 | + const bool is_virtual = false; |
| 1131 | + const bool is_static = false; |
| 1132 | + const bool is_inline = false; |
| 1133 | + const bool is_explicit = true; |
| 1134 | + const bool is_attr_used = false; |
| 1135 | + const bool is_artificial = false; |
| 1136 | + |
| 1137 | + CompilerType function_type = |
| 1138 | + m_ast->CreateFunctionType(return_type, {}, |
| 1139 | + /*variadic=*/false, /*quals*/ 0U); |
| 1140 | + auto *ctor_nolabel = m_ast->AddMethodToCXXRecordType( |
| 1141 | + t.GetOpaqueQualType(), "S", /*asm_label=*/{}, function_type, |
| 1142 | + lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, |
| 1143 | + is_explicit, is_attr_used, is_artificial); |
| 1144 | + |
| 1145 | + auto *dtor_nolabel = m_ast->AddMethodToCXXRecordType( |
| 1146 | + t.GetOpaqueQualType(), "~S", /*asm_label=*/{}, function_type, |
| 1147 | + lldb::AccessType::eAccessPublic, is_virtual, is_static, is_inline, |
| 1148 | + is_explicit, is_attr_used, is_artificial); |
| 1149 | + |
| 1150 | + auto *ctor = m_ast->AddMethodToCXXRecordType( |
| 1151 | + t.GetOpaqueQualType(), "S", /*asm_label=*/"$__lldb_func:0x0:0x0:S", |
| 1152 | + function_type, lldb::AccessType::eAccessPublic, is_virtual, is_static, |
| 1153 | + is_inline, is_explicit, is_attr_used, is_artificial); |
| 1154 | + |
| 1155 | + auto *dtor = m_ast->AddMethodToCXXRecordType( |
| 1156 | + t.GetOpaqueQualType(), "~S", /*asm_label=*/"$__lldb_func:0x0:0x0:~S", |
| 1157 | + function_type, lldb::AccessType::eAccessPublic, is_virtual, is_static, |
| 1158 | + is_inline, is_explicit, is_attr_used, is_artificial); |
| 1159 | + |
| 1160 | + m_ast->CompleteTagDeclarationDefinition(t); |
| 1161 | + |
| 1162 | + ASSERT_TRUE(ctor_nolabel); |
| 1163 | + ASSERT_TRUE(dtor_nolabel); |
| 1164 | + ASSERT_TRUE(ctor); |
| 1165 | + ASSERT_TRUE(dtor); |
| 1166 | + |
| 1167 | + ASSERT_STREQ(m_ast->DeclGetMangledName(ctor_nolabel).GetCString(), |
| 1168 | + "_ZN1SC1Ev"); |
| 1169 | + ASSERT_STREQ(m_ast->DeclGetMangledName(dtor_nolabel).GetCString(), |
| 1170 | + "_ZN1SD1Ev"); |
| 1171 | + ASSERT_STREQ(m_ast->DeclGetMangledName(ctor).GetCString(), |
| 1172 | + "\01$__lldb_func:0x0:0x0:S"); |
| 1173 | + ASSERT_STREQ(m_ast->DeclGetMangledName(dtor).GetCString(), |
| 1174 | + "\01$__lldb_func:0x0:0x0:~S"); |
| 1175 | +} |
| 1176 | + |
| 1177 | +struct AsmLabelTestCase { |
| 1178 | + llvm::StringRef mangled; |
| 1179 | + llvm::StringRef expected; |
| 1180 | +}; |
| 1181 | + |
| 1182 | +class TestTypeSystemClangAsmLabel |
| 1183 | + : public testing::TestWithParam<AsmLabelTestCase> { |
| 1184 | +public: |
| 1185 | + SubsystemRAII<FileSystem, HostInfo> subsystems; |
| 1186 | + |
| 1187 | + void SetUp() override { |
| 1188 | + m_holder = |
| 1189 | + std::make_unique<clang_utils::TypeSystemClangHolder>("test ASTContext"); |
| 1190 | + m_ast = m_holder->GetAST(); |
| 1191 | + } |
| 1192 | + |
| 1193 | + void TearDown() override { |
| 1194 | + m_ast = nullptr; |
| 1195 | + m_holder.reset(); |
| 1196 | + } |
| 1197 | + |
| 1198 | +protected: |
| 1199 | + TypeSystemClang *m_ast = nullptr; |
| 1200 | + std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder; |
| 1201 | +}; |
| 1202 | + |
| 1203 | +static AsmLabelTestCase g_asm_label_test_cases[] = { |
| 1204 | + {/*mangled=*/"$__lldb_func:0x0:0x0:_Z3foov", |
| 1205 | + /*expected=*/"_Z3foov"}, |
| 1206 | + {/*mangled=*/"$__lldb_func:0x0:0x0:foo", |
| 1207 | + /*expected=*/"$__lldb_func:0x0:0x0:foo"}, |
| 1208 | + {/*mangled=*/"foo", |
| 1209 | + /*expected=*/"foo"}, |
| 1210 | + {/*mangled=*/"_Z3foov", |
| 1211 | + /*expected=*/"_Z3foov"}, |
| 1212 | + {/*mangled=*/"$__lldb_func:", |
| 1213 | + /*expected=*/"$__lldb_func:"}, |
| 1214 | +}; |
| 1215 | + |
| 1216 | +TEST_P(TestTypeSystemClangAsmLabel, DeclGetMangledName) { |
| 1217 | + const auto &[mangled, expected] = GetParam(); |
| 1218 | + |
| 1219 | + CompilerType int_type = m_ast->GetBasicType(lldb::eBasicTypeInt); |
| 1220 | + clang::TranslationUnitDecl *TU = m_ast->GetTranslationUnitDecl(); |
| 1221 | + |
| 1222 | + // Prepare the declarations/types we need for the template. |
| 1223 | + CompilerType clang_type = m_ast->CreateFunctionType(int_type, {}, false, 0U); |
| 1224 | + FunctionDecl *func = m_ast->CreateFunctionDeclaration( |
| 1225 | + TU, OptionalClangModuleID(), "foo", clang_type, StorageClass::SC_None, |
| 1226 | + false, /*asm_label=*/mangled); |
| 1227 | + |
| 1228 | + ASSERT_EQ(llvm::GlobalValue::dropLLVMManglingEscape( |
| 1229 | + m_ast->DeclGetMangledName(func).GetStringRef()), |
| 1230 | + expected); |
| 1231 | +} |
| 1232 | + |
| 1233 | +INSTANTIATE_TEST_SUITE_P(AsmLabelTests, TestTypeSystemClangAsmLabel, |
| 1234 | + testing::ValuesIn(g_asm_label_test_cases)); |
0 commit comments