diff options
Diffstat (limited to 'llvm/tools/llvm-rc')
| -rw-r--r-- | llvm/tools/llvm-rc/ResourceFileWriter.h | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-rc/ResourceScriptStmt.h | 10 | ||||
| -rw-r--r-- | llvm/tools/llvm-rc/ResourceScriptToken.cpp | 44 | ||||
| -rw-r--r-- | llvm/tools/llvm-rc/ResourceScriptToken.h | 3 | ||||
| -rw-r--r-- | llvm/tools/llvm-rc/ResourceScriptTokenList.def | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-rc/ResourceVisitor.h | 2 | ||||
| -rw-r--r-- | llvm/tools/llvm-rc/llvm-rc.cpp | 3 |
7 files changed, 47 insertions, 19 deletions
diff --git a/llvm/tools/llvm-rc/ResourceFileWriter.h b/llvm/tools/llvm-rc/ResourceFileWriter.h index 82d3e3b..a13af45 100644 --- a/llvm/tools/llvm-rc/ResourceFileWriter.h +++ b/llvm/tools/llvm-rc/ResourceFileWriter.h @@ -19,6 +19,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Support/Endian.h" +#include <map> + namespace llvm { class MemoryBuffer; diff --git a/llvm/tools/llvm-rc/ResourceScriptStmt.h b/llvm/tools/llvm-rc/ResourceScriptStmt.h index a81e384f..84da9be 100644 --- a/llvm/tools/llvm-rc/ResourceScriptStmt.h +++ b/llvm/tools/llvm-rc/ResourceScriptStmt.h @@ -242,9 +242,9 @@ public: virtual raw_ostream &log(raw_ostream &OS) const { return OS << "Base statement\n"; }; - RCResource() {} + RCResource() = default; RCResource(uint16_t Flags) : MemoryFlags(Flags) {} - virtual ~RCResource() {} + virtual ~RCResource() = default; virtual Error visit(Visitor *) const { llvm_unreachable("This is unable to call methods from Visitor base"); @@ -290,7 +290,7 @@ class OptionalStmtList : public OptionalStmt { std::vector<std::unique_ptr<OptionalStmt>> Statements; public: - OptionalStmtList() {} + OptionalStmtList() = default; raw_ostream &log(raw_ostream &OS) const override; void addStmt(std::unique_ptr<OptionalStmt> Stmt) { @@ -510,7 +510,7 @@ public: virtual raw_ostream &log(raw_ostream &OS) const { return OS << "Base menu definition\n"; } - virtual ~MenuDefinition() {} + virtual ~MenuDefinition() = default; virtual uint16_t getResFlags() const { return 0; } virtual MenuDefKind getKind() const { return MkBase; } @@ -818,7 +818,7 @@ public: enum StmtKind { StBase = 0, StBlock = 1, StValue = 2 }; virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; } - virtual ~VersionInfoStmt() {} + virtual ~VersionInfoStmt() = default; virtual StmtKind getKind() const { return StBase; } static bool classof(const VersionInfoStmt *S) { diff --git a/llvm/tools/llvm-rc/ResourceScriptToken.cpp b/llvm/tools/llvm-rc/ResourceScriptToken.cpp index 0070037..046a1bf 100644 --- a/llvm/tools/llvm-rc/ResourceScriptToken.cpp +++ b/llvm/tools/llvm-rc/ResourceScriptToken.cpp @@ -26,11 +26,11 @@ using namespace llvm; using Kind = RCToken::Kind; // Checks if Representation is a correct description of an RC integer. -// It should be a 32-bit unsigned integer, either decimal, octal (0[0-7]+), -// or hexadecimal (0x[0-9a-f]+). It might be followed by a single 'L' -// character (that is the difference between our representation and -// StringRef's one). If Representation is correct, 'true' is returned and -// the return value is put back in Num. +// It should be a 32-bit unsigned integer, either decimal or hexadecimal +// (0x[0-9a-f]+). For Windres mode, it can also be octal (0[0-7]+). +// It might be followed by a single 'L' character (that is the difference +// between our representation and StringRef's one). If Representation is +// correct, 'true' is returned and the return value is put back in Num. static bool rcGetAsInteger(StringRef Representation, uint32_t &Num) { size_t Length = Representation.size(); if (Length == 0) @@ -95,7 +95,8 @@ namespace { class Tokenizer { public: - Tokenizer(StringRef Input) : Data(Input), DataLength(Input.size()), Pos(0) {} + Tokenizer(StringRef Input, bool IsWindres) + : Data(Input), DataLength(Input.size()), Pos(0), IsWindres(IsWindres) {} Expected<std::vector<RCToken>> run(); @@ -128,6 +129,7 @@ private: // character. bool canStartInt() const; bool canContinueInt() const; + void trimIntString(StringRef &Str) const; bool canStartString() const; @@ -153,6 +155,7 @@ private: StringRef Data; size_t DataLength, Pos; + bool IsWindres; }; void Tokenizer::skipCurrentLine() { @@ -187,7 +190,12 @@ Expected<std::vector<RCToken>> Tokenizer::run() { if (TokenKind == Kind::LineComment || TokenKind == Kind::StartComment) continue; - RCToken Token(TokenKind, Data.take_front(Pos).drop_front(TokenStart)); + StringRef Contents = Data.take_front(Pos).drop_front(TokenStart); + + if (TokenKind == Kind::Int) + trimIntString(Contents); + + RCToken Token(TokenKind, Contents); if (TokenKind == Kind::Identifier) { processIdentifier(Token); } else if (TokenKind == Kind::Int) { @@ -366,12 +374,30 @@ void Tokenizer::processIdentifier(RCToken &Token) const { Token = RCToken(Kind::BlockEnd, Name); } +void Tokenizer::trimIntString(StringRef &Str) const { + if (!IsWindres) { + // For compatibility with rc.exe, strip leading zeros that make the + // integer literal interpreted as octal. + // + // We do rely on Stringref::getAsInteger for autodetecting between + // decimal and hexadecimal literals, but we want to avoid interpreting + // literals as octal. + // + // This omits the leading zeros from the RCToken's value string entirely, + // which also has a visible effect when dumping the tokenizer output. + // Alternatively, we could store the IsWindres flag in RCToken and defer + // the trimming to RCToken::intValue. + while (Str.size() >= 2 && Str[0] == '0' && std::isdigit(Str[1])) + Str = Str.drop_front(1); + } +} + } // anonymous namespace namespace llvm { -Expected<std::vector<RCToken>> tokenizeRC(StringRef Input) { - return Tokenizer(Input).run(); +Expected<std::vector<RCToken>> tokenizeRC(StringRef Input, bool IsWindres) { + return Tokenizer(Input, IsWindres).run(); } } // namespace llvm diff --git a/llvm/tools/llvm-rc/ResourceScriptToken.h b/llvm/tools/llvm-rc/ResourceScriptToken.h index 3dcdfaf..4c839a0 100644 --- a/llvm/tools/llvm-rc/ResourceScriptToken.h +++ b/llvm/tools/llvm-rc/ResourceScriptToken.h @@ -28,7 +28,6 @@ #include "llvm/Support/Error.h" #include <cstdint> -#include <map> #include <vector> namespace llvm { @@ -76,7 +75,7 @@ private: // Tokens returned by this function hold only references to the parts // of the Input. Memory buffer containing Input cannot be freed, // modified or reallocated. -Expected<std::vector<RCToken>> tokenizeRC(StringRef Input); +Expected<std::vector<RCToken>> tokenizeRC(StringRef Input, bool IsWindres); } // namespace llvm diff --git a/llvm/tools/llvm-rc/ResourceScriptTokenList.def b/llvm/tools/llvm-rc/ResourceScriptTokenList.def index 6ee13b2..98af23c 100644 --- a/llvm/tools/llvm-rc/ResourceScriptTokenList.def +++ b/llvm/tools/llvm-rc/ResourceScriptTokenList.def @@ -14,7 +14,7 @@ // Long tokens. They might consist of more than one character. TOKEN(Invalid) // Invalid token. Should not occur in a valid script. -TOKEN(Int) // Integer (decimal, octal or hexadecimal). +TOKEN(Int) // Integer (decimal or hexadecimal, and possibly octal for windres). TOKEN(String) // String value. TOKEN(Identifier) // Script identifier (resource name or type). TOKEN(LineComment) // Beginning of single-line comment. diff --git a/llvm/tools/llvm-rc/ResourceVisitor.h b/llvm/tools/llvm-rc/ResourceVisitor.h index a121a0a..1815c6b 100644 --- a/llvm/tools/llvm-rc/ResourceVisitor.h +++ b/llvm/tools/llvm-rc/ResourceVisitor.h @@ -55,7 +55,7 @@ public: virtual Error visitVersionStmt(const VersionStmt *) = 0; virtual Error visitMenuStmt(const MenuStmt *) = 0; - virtual ~Visitor() {} + virtual ~Visitor() = default; }; } // namespace rc diff --git a/llvm/tools/llvm-rc/llvm-rc.cpp b/llvm/tools/llvm-rc/llvm-rc.cpp index f623342..38bf03f 100644 --- a/llvm/tools/llvm-rc/llvm-rc.cpp +++ b/llvm/tools/llvm-rc/llvm-rc.cpp @@ -619,7 +619,8 @@ void doRc(std::string Src, std::string Dest, RcOptions &Opts, StringRef Contents = FileContents->getBuffer(); std::string FilteredContents = filterCppOutput(Contents); - std::vector<RCToken> Tokens = ExitOnErr(tokenizeRC(FilteredContents)); + std::vector<RCToken> Tokens = + ExitOnErr(tokenizeRC(FilteredContents, Opts.IsWindres)); if (Opts.BeVerbose) { const Twine TokenNames[] = { |
