authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2021-06-01 20:00:46-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2021-06-02 09:12:45+03:00
loga9dd8d75431357a59238da3fd949aa1f11eead84
treed9074122fe12aa0a7ec2855216418743ea36b1f8
parentc6a0a4e7282d746ebf2b54df16161c5993ea5aa8

translate-c: Fix performance hazard in transPreprocessorEntities

Fixes O(N^2) behavior of `transPreprocessorEntities` due to repeated calls to `mem.len` Closes #8959

4 files changed, 20 insertions(+), 1 deletions(-)

src/clang.zig+7
...@@ -607,6 +607,13 @@ pub const IntegerLiteral = opaque {...@@ -607,6 +607,13 @@ pub const IntegerLiteral = opaque {
607 extern fn ZigClangIntegerLiteral_isZero(*const IntegerLiteral, *bool, *const ASTContext) bool;607 extern fn ZigClangIntegerLiteral_isZero(*const IntegerLiteral, *bool, *const ASTContext) bool;
608};608};
609609
610/// This is just used as a namespace for a static method on clang's Lexer class; we don't directly
611/// deal with Lexer objects
612pub const Lexer = struct {
613 pub const getLocForEndOfToken = ZigClangLexer_getLocForEndOfToken;
614 extern fn ZigClangLexer_getLocForEndOfToken(SourceLocation, *const SourceManager, *const ASTUnit) SourceLocation;
615};
616
610pub const MacroDefinitionRecord = opaque {617pub const MacroDefinitionRecord = opaque {
611 pub const getName_getNameStart = ZigClangMacroDefinitionRecord_getName_getNameStart;618 pub const getName_getNameStart = ZigClangMacroDefinitionRecord_getName_getNameStart;
612 extern fn ZigClangMacroDefinitionRecord_getName_getNameStart(*const MacroDefinitionRecord) [*:0]const u8;619 extern fn ZigClangMacroDefinitionRecord_getName_getNameStart(*const MacroDefinitionRecord) [*:0]const u8;
src/translate_c.zig+4-1
...@@ -4688,6 +4688,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {...@@ -4688,6 +4688,7 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
4688 const macro = @ptrCast(*clang.MacroDefinitionRecord, entity);4688 const macro = @ptrCast(*clang.MacroDefinitionRecord, entity);
4689 const raw_name = macro.getName_getNameStart();4689 const raw_name = macro.getName_getNameStart();
4690 const begin_loc = macro.getSourceRange_getBegin();4690 const begin_loc = macro.getSourceRange_getBegin();
4691 const end_loc = clang.Lexer.getLocForEndOfToken(macro.getSourceRange_getEnd(), c.source_manager, unit);
46914692
4692 const name = try c.str(raw_name);4693 const name = try c.str(raw_name);
4693 // TODO https://github.com/ziglang/zig/issues/37564694 // TODO https://github.com/ziglang/zig/issues/3756
...@@ -4698,7 +4699,9 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {...@@ -4698,7 +4699,9 @@ fn transPreprocessorEntities(c: *Context, unit: *clang.ASTUnit) Error!void {
4698 }4699 }
46994700
4700 const begin_c = c.source_manager.getCharacterData(begin_loc);4701 const begin_c = c.source_manager.getCharacterData(begin_loc);
4701 const slice = begin_c[0..mem.len(begin_c)];4702 const end_c = c.source_manager.getCharacterData(end_loc);
4703 const slice_len = @ptrToInt(end_c) - @ptrToInt(begin_c);
4704 const slice = begin_c[0..slice_len];
47024705
4703 var tokenizer = std.c.Tokenizer{4706 var tokenizer = std.c.Tokenizer{
4704 .buffer = slice,4707 .buffer = slice,
src/zig_clang.cpp+7
...@@ -3100,6 +3100,13 @@ struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEn...@@ -3100,6 +3100,13 @@ struct ZigClangSourceLocation ZigClangMacroDefinitionRecord_getSourceRange_getEn
3100 return bitcast(casted->getSourceRange().getEnd());3100 return bitcast(casted->getSourceRange().getEnd());
3101}3101}
31023102
3103struct ZigClangSourceLocation ZigClangLexer_getLocForEndOfToken(ZigClangSourceLocation loc, const ZigClangSourceManager *sm, const ZigClangASTUnit *unit) {
3104 const clang::SourceManager *casted_sm = reinterpret_cast<const clang::SourceManager *>(sm);
3105 const clang::ASTUnit *casted_unit = reinterpret_cast<const clang::ASTUnit *>(unit);
3106 clang::SourceLocation endloc = clang::Lexer::getLocForEndOfToken(bitcast(loc), 0, *casted_sm, casted_unit->getLangOpts());
3107 return bitcast(endloc);
3108}
3109
3103ZigClangRecordDecl_field_iterator ZigClangRecordDecl_field_begin(const struct ZigClangRecordDecl *self) {3110ZigClangRecordDecl_field_iterator ZigClangRecordDecl_field_begin(const struct ZigClangRecordDecl *self) {
3104 auto casted = reinterpret_cast<const clang::RecordDecl *>(self);3111 auto casted = reinterpret_cast<const clang::RecordDecl *>(self);
3105 return bitcast(casted->field_begin());3112 return bitcast(casted->field_begin());
src/zig_clang.h+2
...@@ -966,6 +966,8 @@ ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct Zig...@@ -966,6 +966,8 @@ ZIG_EXTERN_C const char* ZigClangSourceManager_getCharacterData(const struct Zig
966966
967ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T);967ZIG_EXTERN_C struct ZigClangQualType ZigClangASTContext_getPointerType(const struct ZigClangASTContext*, struct ZigClangQualType T);
968968
969ZIG_EXTERN_C struct ZigClangSourceLocation ZigClangLexer_getLocForEndOfToken(struct ZigClangSourceLocation,
970 const ZigClangSourceManager *, const ZigClangASTUnit *);
969971
970// Can return null.972// Can return null.
971ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,973ZIG_EXTERN_C struct ZigClangASTUnit *ZigClangLoadFromCommandLine(const char **args_begin, const char **args_end,