Changeset View
Changeset View
Standalone View
Standalone View
llvm/tools/llvm-rc/ResourceScriptStmt.h
Show First 20 Lines • Show All 313 Lines • ▼ Show 20 Lines | DialogResource(uint32_t PosX, uint32_t PosY, uint32_t DlgWidth, | ||||
: X(PosX), Y(PosY), Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID), | : X(PosX), Y(PosY), Width(DlgWidth), Height(DlgHeight), HelpID(DlgHelpID), | ||||
OptStatements(std::move(OptStmts)), IsExtended(IsDialogEx) {} | OptStatements(std::move(OptStmts)), IsExtended(IsDialogEx) {} | ||||
void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); } | void addControl(Control &&Ctl) { Controls.push_back(std::move(Ctl)); } | ||||
raw_ostream &log(raw_ostream &) const override; | raw_ostream &log(raw_ostream &) const override; | ||||
}; | }; | ||||
// -- VERSIONINFO resource and its helper classes -- | |||||
// | |||||
// This resource lists the version information on the executable/library. | |||||
// The declaration consists of the following items: | |||||
// * A number of fixed optional version statements (e.g. FILEVERSION, FILEOS) | |||||
// * BEGIN | |||||
// * A number of BLOCK and/or VALUE statements. BLOCK recursively defines | |||||
// another block of version information, whereas VALUE defines a | |||||
// key -> value correspondence. There might be more than one value | |||||
// corresponding to the single key. | |||||
// * END | |||||
// | |||||
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa381058(v=vs.85).aspx | |||||
// A single VERSIONINFO statement; | |||||
class VersionInfoStmt { | |||||
public: | |||||
virtual raw_ostream &log(raw_ostream &OS) const { return OS << "VI stmt\n"; } | |||||
virtual ~VersionInfoStmt() {} | |||||
}; | |||||
// BLOCK definition; also the main VERSIONINFO declaration is considered a | |||||
// BLOCK, although it has no name. | |||||
// The correct top-level blocks are "VarFileInfo" and "StringFileInfo". We don't | |||||
// care about them at the parsing phase. | |||||
class VersionInfoBlock : public VersionInfoStmt { | |||||
std::vector<std::unique_ptr<VersionInfoStmt>> Stmts; | |||||
StringRef Name; | |||||
public: | |||||
VersionInfoBlock(StringRef BlockName) : Name(BlockName) {} | |||||
void addStmt(std::unique_ptr<VersionInfoStmt> Stmt) { | |||||
Stmts.push_back(std::move(Stmt)); | |||||
} | |||||
raw_ostream &log(raw_ostream &) const override; | |||||
}; | |||||
class VersionInfoValue : public VersionInfoStmt { | |||||
StringRef Key; | |||||
std::vector<IntOrString> Values; | |||||
public: | |||||
VersionInfoValue(StringRef InfoKey, std::vector<IntOrString> &&Vals) | |||||
: Key(InfoKey), Values(std::move(Vals)) {} | |||||
raw_ostream &log(raw_ostream &) const override; | |||||
}; | |||||
class VersionInfoResource : public RCResource { | |||||
public: | |||||
// A class listing fixed VERSIONINFO statements (occuring before main BEGIN). | |||||
// If any of these is not specified, it is assumed by the original tool to | |||||
// be equal to 0. | |||||
class VersionInfoFixed { | |||||
public: | |||||
enum VersionInfoFixedType { | |||||
FtUnknown, | |||||
FtFileVersion, | |||||
FtProductVersion, | |||||
FtFileFlagsMask, | |||||
FtFileFlags, | |||||
FtFileOS, | |||||
FtFileType, | |||||
FtFileSubtype, | |||||
FtNumTypes | |||||
}; | |||||
private: | |||||
rnk: Generally, you don't need to template over the size of a SmallVector. You can simply take a… | |||||
static const StringMap<VersionInfoFixedType> FixedFieldsInfoMap; | |||||
Not Done ReplyInline ActionsDoes this need Name.upper()? I'm concerned about things like: VERSIONINFO FileVersion 1, 2, 3 FILEVERSION 4, 5, 6 BEGIN END Should that be an error? Maybe the best way to handle this is to have an enumeration, map from string to enum, maintain an array of all possible fields, and on set, check if the field is already set and report an error if so. rnk: Does this need Name.upper()? I'm concerned about things like:
```
VERSIONINFO
FileVersion 1… | |||||
Not Done ReplyInline ActionsThe original tool seems not to care about this one and just take the last occurrence of FILEVERSION. Of course, what you suggest is way better, and I think I'm going to do it your way. mnbvmar: The original tool seems not to care about this one and just take the last occurrence of… | |||||
static const StringRef FixedFieldsNames[FtNumTypes]; | |||||
public: | |||||
SmallVector<uint32_t, 4> FixedInfo[FtNumTypes]; | |||||
SmallVector<bool, FtNumTypes> IsTypePresent; | |||||
static VersionInfoFixedType getFixedType(StringRef Type); | |||||
static bool isTypeSupported(VersionInfoFixedType Type); | |||||
static bool isVersionType(VersionInfoFixedType Type); | |||||
VersionInfoFixed() : IsTypePresent(FtNumTypes, false) {} | |||||
void setValue(VersionInfoFixedType Type, ArrayRef<uint32_t> Value) { | |||||
FixedInfo[Type] = SmallVector<uint32_t, 4>(Value.begin(), Value.end()); | |||||
IsTypePresent[Type] = true; | |||||
} | |||||
raw_ostream &log(raw_ostream &) const; | |||||
}; | |||||
private: | |||||
VersionInfoBlock MainBlock; | |||||
VersionInfoFixed FixedData; | |||||
public: | |||||
VersionInfoResource(VersionInfoBlock &&TopLevelBlock, | |||||
VersionInfoFixed &&FixedInfo) | |||||
: MainBlock(std::move(TopLevelBlock)), FixedData(std::move(FixedInfo)) {} | |||||
raw_ostream &log(raw_ostream &) const override; | |||||
}; | |||||
// CHARACTERISTICS optional statement. | // CHARACTERISTICS optional statement. | ||||
// | // | ||||
// Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx | // Ref: msdn.microsoft.com/en-us/library/windows/desktop/aa380872(v=vs.85).aspx | ||||
class CharacteristicsStmt : public OptionalStmt { | class CharacteristicsStmt : public OptionalStmt { | ||||
uint32_t Value; | uint32_t Value; | ||||
public: | public: | ||||
CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {} | CharacteristicsStmt(uint32_t Characteristic) : Value(Characteristic) {} | ||||
▲ Show 20 Lines • Show All 56 Lines • Show Last 20 Lines |
Generally, you don't need to template over the size of a SmallVector. You can simply take a SmallVectorImpl<T> &, which is the base SmallVectors of any size.
However, for a const reference, it's usually better to accept an ArrayRef<T> Value. That is implicitly constructible from any SmallVector, and passes a pointer and size by value.