forked from OSchip/llvm-project
Rework how YAMLReader is layered on top of YAMLParser. Turn hand written
recursive descent functions into one table driven parser. Add proper error recovery and reporting. Add lots of test cases with semantics errors and verify error messages. llvm-svn: 156136
This commit is contained in:
parent
6ccfcf346d
commit
3011259a85
|
@ -1,4 +1,4 @@
|
|||
//===- Core/InputFiles.cpp - Manages list of Files -----------------------===//
|
||||
//===- Core/InputFiles.cpp - Manages list of Files ------------------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
|
|
|
@ -18,35 +18,6 @@ namespace lld {
|
|||
namespace yaml {
|
||||
|
||||
|
||||
const char* const KeyValues::nameKeyword = "name";
|
||||
const char* const KeyValues::refNameKeyword = "ref-name";
|
||||
const char* const KeyValues::definitionKeyword = "definition";
|
||||
const char* const KeyValues::scopeKeyword = "scope";
|
||||
const char* const KeyValues::contentTypeKeyword = "type";
|
||||
const char* const KeyValues::deadStripKindKeyword = "dead-strip";
|
||||
const char* const KeyValues::sectionChoiceKeyword = "section-choice";
|
||||
const char* const KeyValues::interposableKeyword = "interposable";
|
||||
const char* const KeyValues::mergeKeyword = "merge";
|
||||
const char* const KeyValues::isThumbKeyword = "is-thumb";
|
||||
const char* const KeyValues::isAliasKeyword = "is-alias";
|
||||
const char* const KeyValues::sectionNameKeyword = "section-name";
|
||||
const char* const KeyValues::contentKeyword = "content";
|
||||
const char* const KeyValues::loadNameKeyword = "load-name";
|
||||
const char* const KeyValues::sizeKeyword = "size";
|
||||
const char* const KeyValues::valueKeyword = "value";
|
||||
const char* const KeyValues::fixupsKeyword = "fixups";
|
||||
const char* const KeyValues::permissionsKeyword = "permissions";
|
||||
const char* const KeyValues::canBeNullKeyword = "can-be-null";
|
||||
const char* const KeyValues::fixupsKindKeyword = "kind";
|
||||
const char* const KeyValues::fixupsOffsetKeyword = "offset";
|
||||
const char* const KeyValues::fixupsTargetKeyword = "target";
|
||||
const char* const KeyValues::fixupsAddendKeyword = "addend";
|
||||
const char* const KeyValues::fileAtomsKeyword = "atoms";
|
||||
const char* const KeyValues::fileKindKeyword = "kind";
|
||||
const char* const KeyValues::fileMembersKeyword = "members";
|
||||
|
||||
|
||||
|
||||
const DefinedAtom::Definition KeyValues::definitionDefault = Atom::definitionRegular;
|
||||
const DefinedAtom::Scope KeyValues::scopeDefault = DefinedAtom::scopeTranslationUnit;
|
||||
const DefinedAtom::ContentType KeyValues::contentTypeDefault = DefinedAtom::typeData;
|
||||
|
@ -58,36 +29,8 @@ const DefinedAtom::ContentPermissions KeyValues::permissionsDefault = DefinedAto
|
|||
const bool KeyValues::isThumbDefault = false;
|
||||
const bool KeyValues::isAliasDefault = false;
|
||||
const UndefinedAtom::CanBeNull KeyValues::canBeNullDefault = UndefinedAtom::canBeNullNever;
|
||||
const File::Kind KeyValues::fileKindDefault = File::kindObject;
|
||||
|
||||
|
||||
struct FileKindMapping {
|
||||
const char* string;
|
||||
File::Kind value;
|
||||
};
|
||||
|
||||
static const FileKindMapping fileKindMappings[] = {
|
||||
{ "object", File::kindObject },
|
||||
{ "archive", File::kindArchiveLibrary },
|
||||
{ "shared-library", File::kindSharedLibrary },
|
||||
{ nullptr, File::kindObject }
|
||||
};
|
||||
|
||||
File::Kind KeyValues::fileKind(StringRef str) {
|
||||
for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
|
||||
if (str == p->string)
|
||||
return p->value;
|
||||
}
|
||||
llvm::report_fatal_error("bad file kind value");
|
||||
}
|
||||
|
||||
const char* KeyValues::fileKind(File::Kind k) {
|
||||
for (const FileKindMapping* p = fileKindMappings; p->string != nullptr; ++p) {
|
||||
if ( p->value == k )
|
||||
return p->string;
|
||||
}
|
||||
llvm::report_fatal_error("bad file kind value");
|
||||
}
|
||||
|
||||
|
||||
struct DefinitionMapping {
|
||||
|
@ -103,13 +46,15 @@ static const DefinitionMapping defMappings[] = {
|
|||
{ nullptr, Atom::definitionRegular }
|
||||
};
|
||||
|
||||
Atom::Definition KeyValues::definition(StringRef s)
|
||||
bool KeyValues::definition(StringRef s, Atom::Definition &out)
|
||||
{
|
||||
for (const DefinitionMapping* p = defMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad definition value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::definition(Atom::Definition s) {
|
||||
|
@ -136,13 +81,15 @@ static const ScopeMapping scopeMappings[] = {
|
|||
{ nullptr, DefinedAtom::scopeGlobal }
|
||||
};
|
||||
|
||||
DefinedAtom::Scope KeyValues::scope(StringRef s)
|
||||
bool KeyValues::scope(StringRef s, DefinedAtom::Scope &out)
|
||||
{
|
||||
for (const ScopeMapping* p = scopeMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad scope value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::scope(DefinedAtom::Scope s) {
|
||||
|
@ -197,13 +144,15 @@ static const ContentTypeMapping typeMappings[] = {
|
|||
{ nullptr, DefinedAtom::typeUnknown }
|
||||
};
|
||||
|
||||
DefinedAtom::ContentType KeyValues::contentType(StringRef s)
|
||||
bool KeyValues::contentType(StringRef s, DefinedAtom::ContentType &out)
|
||||
{
|
||||
for (const ContentTypeMapping* p = typeMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad content type value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::contentType(DefinedAtom::ContentType s) {
|
||||
|
@ -225,26 +174,26 @@ struct DeadStripMapping {
|
|||
DefinedAtom::DeadStripKind value;
|
||||
};
|
||||
|
||||
static const DeadStripMapping deadStripMappings[] = {
|
||||
static const DeadStripMapping dsMappings[] = {
|
||||
{ "normal", DefinedAtom::deadStripNormal },
|
||||
{ "never", DefinedAtom::deadStripNever },
|
||||
{ "always", DefinedAtom::deadStripAlways },
|
||||
{ nullptr, DefinedAtom::deadStripNormal }
|
||||
};
|
||||
|
||||
DefinedAtom::DeadStripKind KeyValues::deadStripKind(StringRef s)
|
||||
bool KeyValues::deadStripKind(StringRef s, DefinedAtom::DeadStripKind &out)
|
||||
{
|
||||
for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p)
|
||||
{
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
for (const DeadStripMapping* p = dsMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad dead strip value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::deadStripKind(DefinedAtom::DeadStripKind dsk) {
|
||||
for (const DeadStripMapping* p = deadStripMappings; p->string != nullptr; ++p)
|
||||
{
|
||||
for (const DeadStripMapping* p = dsMappings; p->string != nullptr; ++p) {
|
||||
if ( p->value == dsk )
|
||||
return p->string;
|
||||
}
|
||||
|
@ -267,13 +216,15 @@ static const InterposableMapping interMappings[] = {
|
|||
{ nullptr, DefinedAtom::interposeNo }
|
||||
};
|
||||
|
||||
DefinedAtom::Interposable KeyValues::interposable(StringRef s)
|
||||
bool KeyValues::interposable(StringRef s, DefinedAtom::Interposable &out)
|
||||
{
|
||||
for (const InterposableMapping* p = interMappings; p->string != nullptr; ++p){
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad interposable value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::interposable(DefinedAtom::Interposable in) {
|
||||
|
@ -302,13 +253,15 @@ static const MergeMapping mergeMappings[] = {
|
|||
{ nullptr, DefinedAtom::mergeNo }
|
||||
};
|
||||
|
||||
DefinedAtom::Merge KeyValues::merge(StringRef s)
|
||||
bool KeyValues::merge(StringRef s, DefinedAtom::Merge& out)
|
||||
{
|
||||
for (const MergeMapping* p = mergeMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad merge value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::merge(DefinedAtom::Merge in) {
|
||||
|
@ -336,13 +289,15 @@ static const SectionChoiceMapping sectMappings[] = {
|
|||
{ nullptr, DefinedAtom::sectionBasedOnContent }
|
||||
};
|
||||
|
||||
DefinedAtom::SectionChoice KeyValues::sectionChoice(StringRef s)
|
||||
bool KeyValues::sectionChoice(StringRef s, DefinedAtom::SectionChoice &out)
|
||||
{
|
||||
for (const SectionChoiceMapping* p = sectMappings; p->string != nullptr; ++p){
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad dead strip value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::sectionChoice(DefinedAtom::SectionChoice s) {
|
||||
|
@ -365,21 +320,23 @@ struct PermissionsMapping {
|
|||
};
|
||||
|
||||
static const PermissionsMapping permMappings[] = {
|
||||
{ "content", DefinedAtom::perm___ },
|
||||
{ "custom", DefinedAtom::permR__ },
|
||||
{ "custom-required", DefinedAtom::permR_X },
|
||||
{ "custom-required", DefinedAtom::permRW_ },
|
||||
{ "custom-required", DefinedAtom::permRW_L },
|
||||
{ nullptr, DefinedAtom::perm___ }
|
||||
{ "---", DefinedAtom::perm___ },
|
||||
{ "r--", DefinedAtom::permR__ },
|
||||
{ "r-x", DefinedAtom::permR_X },
|
||||
{ "rw-", DefinedAtom::permRW_ },
|
||||
{ "rw-l", DefinedAtom::permRW_L },
|
||||
{ nullptr, DefinedAtom::perm___ }
|
||||
};
|
||||
|
||||
DefinedAtom::ContentPermissions KeyValues::permissions(StringRef s)
|
||||
bool KeyValues::permissions(StringRef s, DefinedAtom::ContentPermissions &out)
|
||||
{
|
||||
for (const PermissionsMapping* p = permMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad permissions value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
|
||||
|
@ -390,10 +347,42 @@ const char* KeyValues::permissions(DefinedAtom::ContentPermissions s) {
|
|||
llvm::report_fatal_error("bad permissions value");
|
||||
}
|
||||
|
||||
|
||||
bool KeyValues::isThumb(StringRef s, bool &out)
|
||||
{
|
||||
if ( s.equals("true") ) {
|
||||
out = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( s.equals("false") ) {
|
||||
out = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::isThumb(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
||||
|
||||
bool KeyValues::isAlias(StringRef s, bool &out)
|
||||
{
|
||||
if ( s.equals("true") ) {
|
||||
out = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( s.equals("false") ) {
|
||||
out = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::isAlias(bool b) {
|
||||
return b ? "true" : "false";
|
||||
}
|
||||
|
@ -414,13 +403,15 @@ static const CanBeNullMapping cbnMappings[] = {
|
|||
};
|
||||
|
||||
|
||||
UndefinedAtom::CanBeNull KeyValues::canBeNull(StringRef s)
|
||||
bool KeyValues::canBeNull(StringRef s, UndefinedAtom::CanBeNull &out)
|
||||
{
|
||||
for (const CanBeNullMapping* p = cbnMappings; p->string != nullptr; ++p) {
|
||||
if (s == p->string)
|
||||
return p->value;
|
||||
if (s == p->string) {
|
||||
out = p->value;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
llvm::report_fatal_error("bad can-be-null value");
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* KeyValues::canBeNull(UndefinedAtom::CanBeNull c) {
|
||||
|
|
|
@ -20,81 +20,62 @@ namespace yaml {
|
|||
|
||||
class KeyValues {
|
||||
public:
|
||||
static const char* const nameKeyword;
|
||||
static const char* const refNameKeyword;
|
||||
static const char* const sectionNameKeyword;
|
||||
static const char* const contentKeyword;
|
||||
static const char* const sizeKeyword;
|
||||
static const char* const loadNameKeyword;
|
||||
static const char* const valueKeyword;
|
||||
static const char* const fixupsKeyword;
|
||||
static const char* const fileAtomsKeyword;
|
||||
static const char* const fileMembersKeyword;
|
||||
|
||||
static const char* const fileKindKeyword;
|
||||
static const File::Kind fileKindDefault;
|
||||
static File::Kind fileKind(StringRef);
|
||||
static const char* fileKind(File::Kind);
|
||||
|
||||
static const char* const definitionKeyword;
|
||||
static const Atom::Definition definitionDefault;
|
||||
static Atom::Definition definition(StringRef);
|
||||
static bool definition(StringRef, Atom::Definition&);
|
||||
static const char* definition(Atom::Definition);
|
||||
|
||||
static const char* const scopeKeyword;
|
||||
static const DefinedAtom::Scope scopeDefault;
|
||||
static DefinedAtom::Scope scope(StringRef);
|
||||
static bool scope(StringRef, DefinedAtom::Scope&);
|
||||
static const char* scope(DefinedAtom::Scope);
|
||||
|
||||
static const char* const contentTypeKeyword;
|
||||
static const DefinedAtom::ContentType contentTypeDefault;
|
||||
static DefinedAtom::ContentType contentType(StringRef);
|
||||
static bool contentType(StringRef, DefinedAtom::ContentType&);
|
||||
static const char* contentType(DefinedAtom::ContentType);
|
||||
|
||||
static const char* const deadStripKindKeyword;
|
||||
static const DefinedAtom::DeadStripKind deadStripKindDefault;
|
||||
static DefinedAtom::DeadStripKind deadStripKind(StringRef);
|
||||
static bool deadStripKind(StringRef, DefinedAtom::DeadStripKind&);
|
||||
static const char* deadStripKind(DefinedAtom::DeadStripKind);
|
||||
|
||||
static const char* const sectionChoiceKeyword;
|
||||
static const DefinedAtom::SectionChoice sectionChoiceDefault;
|
||||
static DefinedAtom::SectionChoice sectionChoice(StringRef);
|
||||
static bool sectionChoice(StringRef, DefinedAtom::SectionChoice&);
|
||||
static const char* sectionChoice(DefinedAtom::SectionChoice);
|
||||
|
||||
static const char* const interposableKeyword;
|
||||
static const DefinedAtom::Interposable interposableDefault;
|
||||
static DefinedAtom::Interposable interposable(StringRef);
|
||||
static bool interposable(StringRef, DefinedAtom::Interposable&);
|
||||
static const char* interposable(DefinedAtom::Interposable);
|
||||
|
||||
static const char* const mergeKeyword;
|
||||
static const DefinedAtom::Merge mergeDefault;
|
||||
static DefinedAtom::Merge merge(StringRef);
|
||||
static bool merge(StringRef, DefinedAtom::Merge&);
|
||||
static const char* merge(DefinedAtom::Merge);
|
||||
|
||||
static const char* const permissionsKeyword;
|
||||
static const DefinedAtom::ContentPermissions permissionsDefault;
|
||||
static DefinedAtom::ContentPermissions permissions(StringRef);
|
||||
static bool permissions(StringRef, DefinedAtom::ContentPermissions&);
|
||||
static const char* permissions(DefinedAtom::ContentPermissions);
|
||||
|
||||
static const char* const isThumbKeyword;
|
||||
static const bool isThumbDefault;
|
||||
static bool isThumb(StringRef, bool&);
|
||||
static const char* isThumb(bool);
|
||||
|
||||
static const char* const isAliasKeyword;
|
||||
static const bool isAliasDefault;
|
||||
static bool isAlias(StringRef, bool&);
|
||||
static const char* isAlias(bool);
|
||||
|
||||
static const char* const canBeNullKeyword;
|
||||
static const UndefinedAtom::CanBeNull canBeNullDefault;
|
||||
static UndefinedAtom::CanBeNull canBeNull(StringRef);
|
||||
static bool canBeNull(StringRef, UndefinedAtom::CanBeNull&);
|
||||
static const char* canBeNull(UndefinedAtom::CanBeNull);
|
||||
|
||||
|
||||
static const char* const fixupsKindKeyword;
|
||||
static const char* const fixupsOffsetKeyword;
|
||||
static const char* const fixupsTargetKeyword;
|
||||
static const char* const fixupsAddendKeyword;
|
||||
|
||||
};
|
||||
|
||||
} // namespace yaml
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -164,9 +164,8 @@ public:
|
|||
bool hasDash = false;
|
||||
if ( !atom.name().empty() ) {
|
||||
out << " - "
|
||||
<< KeyValues::nameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::nameKeyword)
|
||||
<< "name:"
|
||||
<< spacePadding(strlen("name"))
|
||||
<< atom.name()
|
||||
<< "\n";
|
||||
hasDash = true;
|
||||
|
@ -174,9 +173,8 @@ public:
|
|||
|
||||
if ( _rnb.hasRefName(&atom) ) {
|
||||
out << (hasDash ? " " : " - ")
|
||||
<< KeyValues::refNameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::refNameKeyword)
|
||||
<< "ref-name:"
|
||||
<< spacePadding(strlen("ref-name"))
|
||||
<< _rnb.refName(&atom)
|
||||
<< "\n";
|
||||
hasDash = true;
|
||||
|
@ -184,9 +182,8 @@ public:
|
|||
|
||||
if ( atom.definition() != KeyValues::definitionDefault ) {
|
||||
out << (hasDash ? " " : " - ")
|
||||
<< KeyValues::definitionKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::definitionKeyword)
|
||||
<< "definition:"
|
||||
<< spacePadding(strlen("definition"))
|
||||
<< KeyValues::definition(atom.definition())
|
||||
<< "\n";
|
||||
hasDash = true;
|
||||
|
@ -194,9 +191,8 @@ public:
|
|||
|
||||
if ( atom.scope() != KeyValues::scopeDefault ) {
|
||||
out << (hasDash ? " " : " - ")
|
||||
<< KeyValues::scopeKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::scopeKeyword)
|
||||
<< "scope:"
|
||||
<< spacePadding(strlen("scope"))
|
||||
<< KeyValues::scope(atom.scope())
|
||||
<< "\n";
|
||||
hasDash = true;
|
||||
|
@ -204,70 +200,62 @@ public:
|
|||
|
||||
if ( atom.interposable() != KeyValues::interposableDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::interposableKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::interposableKeyword)
|
||||
<< "interposable:"
|
||||
<< spacePadding(strlen("interposable"))
|
||||
<< KeyValues::interposable(atom.interposable())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.merge() != KeyValues::mergeDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::mergeKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::mergeKeyword)
|
||||
<< "merge:"
|
||||
<< spacePadding(strlen("merge"))
|
||||
<< KeyValues::merge(atom.merge())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.contentType() != KeyValues::contentTypeDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::contentTypeKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::contentTypeKeyword)
|
||||
<< "type:"
|
||||
<< spacePadding(strlen("type"))
|
||||
<< KeyValues::contentType(atom.contentType())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.deadStrip() != KeyValues::deadStripKindDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::deadStripKindKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::deadStripKindKeyword)
|
||||
<< "dead-strip:"
|
||||
<< spacePadding(strlen("dead-strip"))
|
||||
<< KeyValues::deadStripKind(atom.deadStrip())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.sectionChoice() != KeyValues::sectionChoiceDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::sectionChoiceKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::sectionChoiceKeyword)
|
||||
<< "section-choice:"
|
||||
<< spacePadding(strlen("section-choice"))
|
||||
<< KeyValues::sectionChoice(atom.sectionChoice())
|
||||
<< "\n";
|
||||
assert( ! atom.customSectionName().empty() );
|
||||
out << " "
|
||||
<< KeyValues::sectionNameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::sectionNameKeyword)
|
||||
<< "section-name:"
|
||||
<< spacePadding(strlen("section-name"))
|
||||
<< atom.customSectionName()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.isThumb() != KeyValues::isThumbDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::isThumbKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::isThumbKeyword)
|
||||
<< "is-thumb:"
|
||||
<< spacePadding(strlen("is-thumb"))
|
||||
<< KeyValues::isThumb(atom.isThumb())
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.isAlias() != KeyValues::isAliasDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::isAliasKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::isAliasKeyword)
|
||||
<< "is-alias:"
|
||||
<< spacePadding(strlen("is-alias"))
|
||||
<< KeyValues::isAlias(atom.isAlias())
|
||||
<< "\n";
|
||||
}
|
||||
|
@ -275,9 +263,8 @@ public:
|
|||
if ( (atom.contentType() != DefinedAtom::typeZeroFill)
|
||||
&& (atom.size() != 0) ) {
|
||||
out << " "
|
||||
<< KeyValues::contentKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::contentKeyword)
|
||||
<< "content:"
|
||||
<< spacePadding(strlen("content"))
|
||||
<< "[ ";
|
||||
ArrayRef<uint8_t> arr = atom.rawContent();
|
||||
bool needComma = false;
|
||||
|
@ -301,15 +288,13 @@ public:
|
|||
wroteFirstFixup = true;
|
||||
}
|
||||
out << " - "
|
||||
<< KeyValues::fixupsOffsetKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::fixupsOffsetKeyword)
|
||||
<< "offset:"
|
||||
<< spacePadding(strlen("offset"))
|
||||
<< ref->offsetInAtom()
|
||||
<< "\n";
|
||||
out << " "
|
||||
<< KeyValues::fixupsKindKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::fixupsKindKeyword)
|
||||
<< "kind:"
|
||||
<< spacePadding(strlen("kind"))
|
||||
<< _platform.kindToString(ref->kind())
|
||||
<< "\n";
|
||||
const Atom* target = ref->target();
|
||||
|
@ -319,17 +304,15 @@ public:
|
|||
refName = _rnb.refName(target);
|
||||
assert(!refName.empty());
|
||||
out << " "
|
||||
<< KeyValues::fixupsTargetKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::fixupsTargetKeyword)
|
||||
<< "target:"
|
||||
<< spacePadding(strlen("target"))
|
||||
<< refName
|
||||
<< "\n";
|
||||
}
|
||||
if ( ref->addend() != 0 ) {
|
||||
out << " "
|
||||
<< KeyValues::fixupsAddendKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::fixupsAddendKeyword)
|
||||
<< "addend:"
|
||||
<< spacePadding(strlen("addend"))
|
||||
<< ref->addend()
|
||||
<< "\n";
|
||||
}
|
||||
|
@ -348,24 +331,21 @@ public:
|
|||
}
|
||||
|
||||
out << " - "
|
||||
<< KeyValues::nameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::nameKeyword)
|
||||
<< "name:"
|
||||
<< spacePadding(strlen("name"))
|
||||
<< atom.name()
|
||||
<< "\n";
|
||||
|
||||
out << " "
|
||||
<< KeyValues::definitionKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::definitionKeyword)
|
||||
<< "definition:"
|
||||
<< spacePadding(strlen("definition"))
|
||||
<< KeyValues::definition(atom.definition())
|
||||
<< "\n";
|
||||
|
||||
if ( atom.canBeNull() != KeyValues::canBeNullDefault ) {
|
||||
out << " "
|
||||
<< KeyValues::canBeNullKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::canBeNullKeyword)
|
||||
<< "can-be-null:"
|
||||
<< spacePadding(strlen("can-be-null"))
|
||||
<< KeyValues::canBeNull(atom.canBeNull())
|
||||
<< "\n";
|
||||
}
|
||||
|
@ -382,33 +362,29 @@ public:
|
|||
}
|
||||
|
||||
out << " - "
|
||||
<< KeyValues::nameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::nameKeyword)
|
||||
<< "name:"
|
||||
<< spacePadding(strlen("name"))
|
||||
<< atom.name()
|
||||
<< "\n";
|
||||
|
||||
out << " "
|
||||
<< KeyValues::definitionKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::definitionKeyword)
|
||||
<< "definition:"
|
||||
<< spacePadding(strlen("definition"))
|
||||
<< KeyValues::definition(atom.definition())
|
||||
<< "\n";
|
||||
|
||||
if ( !atom.loadName().empty() ) {
|
||||
out << " "
|
||||
<< KeyValues::loadNameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::loadNameKeyword)
|
||||
<< "load-name:"
|
||||
<< spacePadding(strlen("load-name"))
|
||||
<< atom.loadName()
|
||||
<< "\n";
|
||||
}
|
||||
|
||||
if ( atom.canBeNullAtRuntime() ) {
|
||||
out << " "
|
||||
<< KeyValues::canBeNullKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::canBeNullKeyword)
|
||||
<< "can-be-null:"
|
||||
<< spacePadding(strlen("can-be-null"))
|
||||
<< KeyValues::canBeNull(UndefinedAtom::canBeNullAtRuntime)
|
||||
<< "\n";
|
||||
}
|
||||
|
@ -425,23 +401,20 @@ public:
|
|||
}
|
||||
|
||||
out << " - "
|
||||
<< KeyValues::nameKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::nameKeyword)
|
||||
<< "name:"
|
||||
<< spacePadding(strlen("name"))
|
||||
<< atom.name()
|
||||
<< "\n";
|
||||
|
||||
out << " "
|
||||
<< KeyValues::definitionKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::definitionKeyword)
|
||||
<< "definition:"
|
||||
<< spacePadding(strlen("definition"))
|
||||
<< KeyValues::definition(atom.definition())
|
||||
<< "\n";
|
||||
|
||||
out << " "
|
||||
<< KeyValues::valueKeyword
|
||||
<< ":"
|
||||
<< spacePadding(KeyValues::valueKeyword)
|
||||
<< "value:"
|
||||
<< spacePadding(strlen("value"))
|
||||
<< "0x";
|
||||
out.write_hex(atom.value());
|
||||
out << "\n";
|
||||
|
@ -450,10 +423,10 @@ public:
|
|||
|
||||
private:
|
||||
// return a string of the correct number of spaces to align value
|
||||
const char* spacePadding(const char* key) {
|
||||
const char* spacePadding(int keyLen) {
|
||||
const char* spaces = " ";
|
||||
assert(strlen(spaces) > strlen(key));
|
||||
return &spaces[strlen(key)];
|
||||
assert(strlen(spaces) > keyLen);
|
||||
return &spaces[keyLen];
|
||||
}
|
||||
|
||||
char hexdigit(uint8_t nibble) {
|
||||
|
|
|
@ -14,7 +14,7 @@ atoms:
|
|||
|
||||
- name: bar
|
||||
scope: global
|
||||
content: zero-fill
|
||||
type: zero-fill
|
||||
merge: asTentative
|
||||
|
||||
---
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that unknown atom attribute produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
foobar: true
|
||||
dead-strip: never
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Unknown atom attribute
|
||||
# CHECK: foobar
|
|
@ -0,0 +1,18 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that an invalid hex byte produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
content: [ A5, 00, 4G, 1F ]
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Invalid content hex byte
|
||||
# CHECK: 4G
|
|
@ -0,0 +1,19 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that an out of range byte value produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
content: [ A5, 1234, 00, 4F ]
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Content hex byte out of range
|
||||
# CHECK: 1234
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that an unknown content type produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
type: superluminal
|
||||
dead-strip: never
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Invalid value for 'type:'
|
||||
# CHECK: superluminal
|
|
@ -0,0 +1,18 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that a defined attribute on an undefined atom produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: foo
|
||||
type: code
|
||||
definition: undefined
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Undefined atom 'foo' has attributes only allowed on defined atoms
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that unknown file attribute produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
aardvark: true
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Unknown file attribute
|
||||
# CHECK: aardvark
|
|
@ -0,0 +1,22 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that unknown fixup attribute produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
fixups:
|
||||
- offset: 3
|
||||
kind: 3
|
||||
weasel: bar
|
||||
addend: 100
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Unknown fixup attribute
|
||||
# CHECK: weasel
|
|
@ -0,0 +1,27 @@
|
|||
# RUN: not lld-core %s 2> %t.err
|
||||
# RUN: FileCheck < %t.err %s
|
||||
|
||||
#
|
||||
# Test that unbindable target name produces a readable error.
|
||||
#
|
||||
|
||||
---
|
||||
atoms:
|
||||
- name: entry
|
||||
scope: hidden
|
||||
fixups:
|
||||
- offset: 3
|
||||
kind: 3
|
||||
target: bar
|
||||
- offset: 5
|
||||
kind: 3
|
||||
target: baz
|
||||
|
||||
- name: bar
|
||||
definition: undefined
|
||||
|
||||
...
|
||||
|
||||
|
||||
# CHECK: error: Fixup has target 'baz' which does not exist
|
||||
# CHECK: baz
|
Loading…
Reference in New Issue