Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ ELF/ScriptParser.cpp @@ -76,7 +76,7 @@ // so that you can write "file-name.cpp" as one bare token, for example. size_t Pos = S.find_first_not_of( "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" - "0123456789_.$/\\~=+[]*?-:!<>"); + "0123456789_.$/\\~=+[]*?-:!<>^"); // A character that cannot start a word (which is usually a // punctuation) forms a single character token. Index: ELF/Strings.cpp =================================================================== --- ELF/Strings.cpp +++ ELF/Strings.cpp @@ -24,25 +24,32 @@ using namespace lld::elf; bool elf::hasWildcard(StringRef S) { - return S.find_first_of("?*") != StringRef::npos; + return S.find_first_of("?*[") != StringRef::npos; } // Converts a glob pattern to a regular expression. static std::string toRegex(StringRef S) { - if (S.find_first_of("[]") != StringRef::npos) - warning("unsupported wildcard: " + S); - std::string T; + bool InBracketExpr = false; while (!S.empty()) { char C = S.front(); + if (InBracketExpr) { + InBracketExpr = C != ']'; + T += C; + S = S.drop_front(); + continue; + } + if (C == '*') T += ".*"; else if (C == '?') T += '.'; - else if (StringRef(".+^${}()|/\\[]").find_first_of(C) != StringRef::npos) + else if (StringRef(".+^${}()|/\\").find_first_of(C) != StringRef::npos) T += std::string("\\") + C; else T += C; + + InBracketExpr = C == '['; S = S.substr(1); } return T; Index: test/ELF/version-script-complex-wildcards.s =================================================================== --- test/ELF/version-script-complex-wildcards.s +++ test/ELF/version-script-complex-wildcards.s @@ -0,0 +1,102 @@ +# REQUIRES: shell + +# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[c]*; \ +# RUN: }; \ +# RUN: }; " > %t.script +# RUN: ld.lld --version-script %t.script -shared %t.o -o %t.so +# RUN: llvm-readobj -V %t.so | FileCheck %s --check-prefix=ABC +# ABC: Name: _Z3abbi@ +# ABC: Name: _Z3abci@@LIBSAMPLE_2.0 + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[b]*; \ +# RUN: }; \ +# RUN: }; " > %t1.script +# RUN: ld.lld --version-script %t1.script -shared %t.o -o %t1.so +# RUN: llvm-readobj -V %t1.so | FileCheck %s --check-prefix=ABB +# ABB: Name: _Z3abbi@@LIBSAMPLE_2.0 +# ABB: Name: _Z3abci@ + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[a-b]*; \ +# RUN: }; \ +# RUN: }; " > %t2.script +# RUN: ld.lld --version-script %t2.script -shared %t.o -o %t2.so +# RUN: llvm-readobj -V %t2.so | FileCheck %s --check-prefix=ABB + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[a-c]*; \ +# RUN: }; \ +# RUN: }; " > %t3.script +# RUN: ld.lld --version-script %t3.script -shared %t.o -o %t3.so +# RUN: llvm-readobj -V %t3.so | FileCheck %s --check-prefix=ABBABC +# ABBABC: Name: _Z3abbi@@LIBSAMPLE_2.0 +# ABBABC: Name: _Z3abci@@LIBSAMPLE_2.0 + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[a-bc-d]*; \ +# RUN: }; \ +# RUN: }; " > %t4.script +# RUN: ld.lld --version-script %t4.script -shared %t.o -o %t4.so +# RUN: llvm-readobj -V %t4.so | FileCheck %s --check-prefix=ABBABC + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[a-bd-e]*; \ +# RUN: }; \ +# RUN: }; " > %t5.script +# RUN: ld.lld --version-script %t5.script -shared %t.o -o %t5.so +# RUN: llvm-readobj -V %t5.so | FileCheck %s --check-prefix=ABB + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[^a-c]*; \ +# RUN: }; \ +# RUN: }; " > %t6.script +# RUN: ld.lld --version-script %t6.script -shared %t.o -o %t6.so +# RUN: llvm-readobj -V %t6.so | FileCheck %s --check-prefix=NO +# NO: Name: _Z3abbi@ +# NO: Name: _Z3abci@ + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: ab[^c-z]*; \ +# RUN: }; \ +# RUN: }; " > %t7.script +# RUN: ld.lld --version-script %t7.script -shared %t.o -o %t7.so +# RUN: llvm-readobj -V %t7.so | FileCheck %s --check-prefix=ABB + +# RUN: echo "LIBSAMPLE_2.0 { \ +# RUN: global: \ +# RUN: extern "C++" { \ +# RUN: a[x-za-b][a-c]*; \ +# RUN: }; \ +# RUN: }; " > %t8.script +# RUN: ld.lld --version-script %t8.script -shared %t.o -o %t8.so +# RUN: llvm-readobj -V %t8.so | FileCheck %s --check-prefix=ABBABC + +.text +.globl _Z3abci +.type _Z3abci,@function +_Z3abci: +retq + +.globl _Z3abbi +.type _Z3abbi,@function +_Z3abbi: +retq