1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00
llvm-mirror/unittests/Option/OptionMarshallingTest.cpp
Jan Svoboda 4f287c334a [clang][cli] Specify KeyPath prefixes via TableGen classes
It turns out we need to handle `LangOptions` separately from the rest of the options. `LangOptions` used to be conditionally parsed only when `!(DashX.getFormat() == InputKind::Precompiled || DashX.getLanguage() == Language::LLVM_IR)` and we need to restore this order (for more info, see D94682).

We could do this similarly to how `DiagnosticOptions` are handled: via a counterpart to the `IsDiag` mix-in (e.g. `IsLang`). These mix-ins would prefix the option key path with the appropriate `CompilerInvocation::XxxOpts` member. However, this solution would be problematic, as we'd now have two kinds of options (`Lang` and `Diag`) with seemingly incomplete key paths in the same file. To understand what `CompilerInvocation` member an option affects, one would need to read the whole option definition and notice the `IsDiag` or `IsLang` class.

Instead, this patch introduces more robust way to handle different kinds of options separately: via the `KeyPathAndMacroPrefix` class. We have one specialization of that class per `CompilerInvocation` member (e.g. `LangOpts`, `DiagnosticOpts`, etc.). Now, instead of specifying a key path with `"LangOpts->UndefPrefixes"`, we use `LangOpts<"UndefPrefixes">`. This keeps the readability intact (you don't have to look for the `IsLang` mix-in, the key path is complete on its own) and allows us to specify a custom macro prefix within `LangOpts`.

Reviewed By: Bigcheese

Differential Revision: https://reviews.llvm.org/D94676
2021-01-15 08:42:59 +01:00

56 lines
2.3 KiB
C++

//===- unittest/Support/OptionMarshallingTest.cpp - OptParserEmitter tests ===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "gtest/gtest.h"
struct OptionWithMarshallingInfo {
const char *Name;
const char *KeyPath;
const char *ImpliedCheck;
const char *ImpliedValue;
};
static const OptionWithMarshallingInfo MarshallingTable[] = {
#define OPTION_WITH_MARSHALLING( \
PREFIX_TYPE, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, PARAM, \
HELPTEXT, METAVAR, VALUES, SPELLING, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, \
DEFAULT_VALUE, IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, \
MERGER, EXTRACTOR, TABLE_INDEX) \
{NAME, #KEYPATH, #IMPLIED_CHECK, #IMPLIED_VALUE},
#include "Opts.inc"
#undef OPTION_WITH_MARSHALLING
};
TEST(OptionMarshalling, EmittedOrderSameAsDefinitionOrder) {
ASSERT_STREQ(MarshallingTable[0].Name, "marshalled-flag-d");
ASSERT_STREQ(MarshallingTable[1].Name, "marshalled-flag-c");
ASSERT_STREQ(MarshallingTable[2].Name, "marshalled-flag-b");
ASSERT_STREQ(MarshallingTable[3].Name, "marshalled-flag-a");
}
TEST(OptionMarshalling, EmittedSpecifiedKeyPath) {
ASSERT_STREQ(MarshallingTable[0].KeyPath, "X->MarshalledFlagD");
ASSERT_STREQ(MarshallingTable[1].KeyPath, "X->MarshalledFlagC");
ASSERT_STREQ(MarshallingTable[2].KeyPath, "X->MarshalledFlagB");
ASSERT_STREQ(MarshallingTable[3].KeyPath, "X->MarshalledFlagA");
}
TEST(OptionMarshalling, ImpliedCheckContainsDisjunctionOfKeypaths) {
ASSERT_STREQ(MarshallingTable[0].ImpliedCheck, "false");
ASSERT_STREQ(MarshallingTable[1].ImpliedCheck, "false || X->MarshalledFlagD");
ASSERT_STREQ(MarshallingTable[1].ImpliedValue, "true");
ASSERT_STREQ(MarshallingTable[2].ImpliedCheck, "false || X->MarshalledFlagD");
ASSERT_STREQ(MarshallingTable[2].ImpliedValue, "true");
ASSERT_STREQ(MarshallingTable[3].ImpliedCheck,
"false || X->MarshalledFlagC || X->MarshalledFlagB");
ASSERT_STREQ(MarshallingTable[3].ImpliedValue, "true");
}