aboutsummaryrefslogtreecommitdiff
path: root/llvm/tools/llvm-rc
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-rc')
-rw-r--r--llvm/tools/llvm-rc/ResourceFileWriter.h2
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptStmt.h10
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptToken.cpp44
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptToken.h3
-rw-r--r--llvm/tools/llvm-rc/ResourceScriptTokenList.def2
-rw-r--r--llvm/tools/llvm-rc/ResourceVisitor.h2
-rw-r--r--llvm/tools/llvm-rc/llvm-rc.cpp3
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[] = {