-
Notifications
You must be signed in to change notification settings - Fork 15.1k
clang_EvalResult_getAsCXString impl #134551
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,14 +25,19 @@ enum CXStringFlag { | |
| /// CXString contains a 'const char *' that it doesn't own. | ||
| CXS_Unmanaged, | ||
|
|
||
| /// CXString contains a 'const char *' that it allocated with malloc(). | ||
| CXS_Malloc, | ||
| /// CXString contains a 'CStringImpl' that it allocated with malloc(). | ||
| CXS_MallocWithSize, | ||
|
|
||
| /// CXString contains a CXStringBuf that needs to be returned to the | ||
| /// CXStringPool. | ||
| CXS_StringBuf | ||
| }; | ||
|
|
||
| struct CStringImpl { | ||
| size_t length; | ||
| char buffer[sizeof(length)]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain this a bit more? I would have expected this to be: with a flexible array member. This always allocates 4-8 bytes for the string length and runs into out-of-bounds array behavior because the final member is a fixed length array rather than a FAM. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I forgot about oob here. I was trying to avoid compiler extensions (flexible array member), as I understand it's not standard C++. I can change it to flexible array member without problem. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This not being in C++ is a good point. Given that this is purely internal, maybe we want to just have the size field and then tail-allocate the buffer? We could probably even use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'll look at that class when I get the time, but just allocating the data without making a struct seems straight forward enough. I also need to see why tests fail while I'm at it. |
||
| }; | ||
|
|
||
| namespace clang { | ||
| namespace cxstring { | ||
|
|
||
|
|
@@ -71,10 +76,7 @@ CXString createDup(const char *String) { | |
| if (String[0] == '\0') | ||
| return createEmpty(); | ||
|
|
||
| CXString Str; | ||
| Str.data = strdup(String); | ||
| Str.private_flags = CXS_Malloc; | ||
| return Str; | ||
| return createDup(StringRef(String)); | ||
| } | ||
|
|
||
| CXString createRef(StringRef String) { | ||
|
|
@@ -91,12 +93,18 @@ CXString createRef(StringRef String) { | |
| } | ||
|
|
||
| CXString createDup(StringRef String) { | ||
| auto toAllocate = | ||
| sizeof(size_t) + std::max(sizeof(size_t), String.size() + 1); | ||
| assert(toAllocate >= sizeof(CStringImpl)); | ||
| auto ptr = static_cast<CStringImpl *>(llvm::safe_malloc(toAllocate)); | ||
|
|
||
| ptr->length = String.size(); | ||
| memcpy(ptr->buffer, String.data(), String.size()); | ||
| ptr->buffer[String.size()] = 0; | ||
|
|
||
| CXString Result; | ||
| char *Spelling = static_cast<char *>(llvm::safe_malloc(String.size() + 1)); | ||
| memmove(Spelling, String.data(), String.size()); | ||
| Spelling[String.size()] = 0; | ||
| Result.data = Spelling; | ||
| Result.private_flags = (unsigned) CXS_Malloc; | ||
| Result.data = ptr; | ||
| Result.private_flags = (unsigned)CXS_MallocWithSize; | ||
| return Result; | ||
| } | ||
|
|
||
|
|
@@ -164,19 +172,38 @@ const char *clang_getCString(CXString string) { | |
| return static_cast<const char *>(string.data); | ||
| } | ||
|
|
||
| CStringInfo clang_getCStringInfo(CXString string) { | ||
| switch ((CXStringFlag)string.private_flags) { | ||
| case CXS_Unmanaged: { | ||
| auto ptr = static_cast<const char *>(string.data); | ||
| return {ptr, strlen(ptr)}; | ||
| } | ||
| case CXS_MallocWithSize: { | ||
| auto ptr = static_cast<const CStringImpl *>(string.data); | ||
| return {ptr->buffer, ptr->length}; | ||
| } | ||
| case CXS_StringBuf: { | ||
| auto ptr = static_cast<const cxstring::CXStringBuf *>(string.data); | ||
| return {ptr->Data.data(), ptr->Data.size()}; | ||
| } | ||
| } | ||
| llvm_unreachable("Invalid CXString::private_flags"); | ||
| } | ||
|
|
||
| void clang_disposeString(CXString string) { | ||
| switch ((CXStringFlag) string.private_flags) { | ||
| case CXS_Unmanaged: | ||
| break; | ||
| case CXS_Malloc: | ||
| return; | ||
| case CXS_MallocWithSize: | ||
| if (string.data) | ||
| free(const_cast<void *>(string.data)); | ||
| break; | ||
| return; | ||
| case CXS_StringBuf: | ||
| static_cast<cxstring::CXStringBuf *>( | ||
| const_cast<void *>(string.data))->dispose(); | ||
| break; | ||
| return; | ||
| } | ||
| llvm_unreachable("Invalid CXString::private_flags"); | ||
| } | ||
|
|
||
| void clang_disposeStringSet(CXStringSet *set) { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we leave space for future expansion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we can now feel a bit more free to add a different
private_flagsvalue, I think we're fine to not leave space for future expansion. WDYT?