FLANG
Fortran-features.h
1//===-- include/flang/Support/Fortran-features.h ----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef FORTRAN_SUPPORT_FORTRAN_FEATURES_H_
10#define FORTRAN_SUPPORT_FORTRAN_FEATURES_H_
11
12#include "Fortran.h"
13#include "flang/Common/enum-set.h"
14#include <string_view>
15#include <vector>
16
17namespace Fortran::common {
18
19// Non-conforming extensions & legacies
20ENUM_CLASS(LanguageFeature, BackslashEscapes, OldDebugLines,
21 FixedFormContinuationWithColumn1Ampersand, LogicalAbbreviations,
22 XOROperator, PunctuationInNames, OptionalFreeFormSpace, BOZExtensions,
23 EmptyStatement, AlternativeNE, ExecutionPartNamelist, DECStructures,
24 DoubleComplex, Byte, StarKind, ExponentMatchingKindParam, QuadPrecision,
25 SlashInitialization, TripletInArrayConstructor, MissingColons,
26 SignedComplexLiteral, OldStyleParameter, ComplexConstructor, PercentLOC,
27 SignedMultOperand, FileName, Carriagecontrol, Convert, Dispose,
28 IOListLeadingComma, AbbreviatedEditDescriptor, ProgramParentheses,
29 PercentRefAndVal, OmitFunctionDummies, CrayPointer, Hollerith, ArithmeticIF,
30 Assign, AssignedGOTO, Pause, OpenACC, OpenMP, CUDA, CruftAfterAmpersand,
31 ClassicCComments, AdditionalFormats, BigIntLiterals, RealDoControls,
32 EquivalenceNumericWithCharacter, EquivalenceNonDefaultNumeric,
33 EquivalenceSameNonSequence, AdditionalIntrinsics, AnonymousParents,
34 OldLabelDoEndStatements, LogicalIntegerAssignment, EmptySourceFile,
35 ProgramReturn, ImplicitNoneTypeNever, ImplicitNoneTypeAlways,
36 ImplicitNoneExternal, ForwardRefImplicitNone, OpenAccessAppend,
37 BOZAsDefaultInteger, DistinguishableSpecifics, DefaultSave,
38 PointerInSeqType, NonCharacterFormat, SaveMainProgram,
39 SaveBigMainProgramVariables, DistinctArrayConstructorLengths, PPCVector,
40 RelaxedIntentInChecking, ForwardRefImplicitNoneData,
41 NullActualForAllocatable, ActualIntegerConvertedToSmallerKind,
42 HollerithOrCharacterAsBOZ, BindingAsProcedure, StatementFunctionExtensions,
43 UseGenericIntrinsicWhenSpecificDoesntMatch, DataStmtExtensions,
44 RedundantContiguous, RedundantAttribute, InitBlankCommon,
45 EmptyBindCDerivedType, MiscSourceExtensions, AllocateToOtherLength,
46 LongNames, IntrinsicAsSpecific, BenignNameClash, BenignRedundancy,
47 NullMoldAllocatableComponentValue, NopassScalarBase, MiscUseExtensions,
48 ImpliedDoIndexScope, DistinctCommonSizes, OddIndexVariableRestrictions,
49 IndistinguishableSpecifics, SubroutineAndFunctionSpecifics,
50 EmptySequenceType, NonSequenceCrayPointee, BranchIntoConstruct,
51 BadBranchTarget, HollerithPolymorphic, ListDirectedSize,
52 NonBindCInteroperability, CudaManaged, CudaUnified,
53 PolymorphicActualAllocatableOrPointerToMonomorphicDummy, RelaxedPureDummy,
54 UndefinableAsynchronousOrVolatileActual, AutomaticInMainProgram, PrintCptr,
55 SavedLocalInSpecExpr, PrintNamelist, AssumedRankPassedToNonAssumedRank,
56 IgnoreIrrelevantAttributes, Unsigned, ContiguousOkForSeqAssociation,
57 ForwardRefExplicitTypeDummy, InaccessibleDeferredOverride,
58 CudaWarpMatchFunction, DoConcurrentOffload, TransferBOZ, Coarray,
59 PointerPassObject, MultipleIdenticalDATA,
60 DefaultStructConstructorNullPointer, AssumedRankIoItem,
61 MultipleProgramUnitsOnSameLine, AllocatedForAssociated,
62 OpenMPThreadprivateEquivalence, RelaxedCLocChecks, CudaPinned,
63 CUDAImplicitDataAttrSpelling, OpenAccDefaultNoneScalarsStrict,
64 OpenACCMultipleNamesInRoutine, EnumerationType, CUDAInit,
65 PreferIntrinsicModuleUseAssociation, MultipleCommonBlockInit,
66 OutOfBoundsSubscripts)
67
68// Portability and suspicious usage warnings
69ENUM_CLASS(UsageWarning, Portability, PointerToUndefinable,
70 NonTargetPassedToTarget, PointerToPossibleNoncontiguous,
71 ShortCharacterActual, ShortArrayActual, ImplicitInterfaceActual,
72 PolymorphicTransferArg, PointerComponentTransferArg, TransferSizePresence,
73 F202XAllocatableBreakingChange, OptionalMustBePresent, CommonBlockPadding,
74 LogicalVsCBool, BindCCharLength, ProcDummyArgShapes, ExternalNameConflict,
75 FoldingException, FoldingAvoidsRuntimeCrash, FoldingValueChecks,
76 FoldingFailure, FoldingLimit, Interoperability, CharacterInteroperability,
77 Bounds, Preprocessing, Scanning, OpenAccUsage, ProcPointerCompatibility,
78 VoidMold, KnownBadImplicitInterface, EmptyCase, CaseOverflow, CUDAUsage,
79 IgnoreTKRUsage, ExternalInterfaceMismatch, DefinedOperatorArgs, Final,
80 ZeroDoStep, UnusedForallIndex, OpenMPUsage, DataLength, IgnoredDirective,
81 HomonymousSpecific, HomonymousResult, IgnoredIntrinsicFunctionType,
82 PreviousScalarUse, RedeclaredInaccessibleComponent, ImplicitShared,
83 IndexVarRedefinition, IncompatibleImplicitInterfaces,
84 VectorSubscriptFinalization, UndefinedFunctionResult, UselessIomsg,
85 MismatchingDummyProcedure, SubscriptedEmptyArray, UnsignedLiteralTruncation,
86 CompatibleDeclarationsFromDistinctModules, ConstantIsContiguous,
87 NullActualForDefaultIntentAllocatable, UseAssociationIntoSameNameSubprogram,
88 HostAssociatedIntentOutInSpecExpr, NonVolatilePointerToVolatile,
89 RealConstantWidening, VolatileOrAsynchronousTemporary, UnusedVariable,
90 UsedUndefinedVariable, BadValueInDeadCode, AssumedTypeSizeDummy,
91 MisplacedIgnoreTKR, NamelistParameter, ImpureFinalInPure,
92 IgnoredNoReallocateLHS, ExperimentalOption, IoImpliedDoIndexConflict,
93 BOZLiteralTruncation, IntentInActualForDefaultIntent, BindCArrayDescriptor,
94 OpenMPDeprecated, OpenMPFuture)
95
98using LanguageFeatureOrWarning = std::variant<LanguageFeature, UsageWarning>;
99using LanguageControlFlag =
100 std::pair<LanguageFeatureOrWarning, /*shouldEnable=*/bool>;
101
102class LanguageFeatureControl {
103public:
104 LanguageFeatureControl();
105 LanguageFeatureControl(const LanguageFeatureControl &) = default;
106
107 void Enable(LanguageFeature f, bool yes = true) { disable_.set(f, !yes); }
108 void EnableWarning(LanguageFeature f, bool yes = true) {
109 warnLanguage_.set(f, yes);
110 }
111 void EnableWarning(UsageWarning w, bool yes = true) {
112 warnUsage_.set(w, yes);
113 }
114 void EnableWarning(LanguageFeatureOrWarning flag, bool yes = true) {
115 if (std::holds_alternative<LanguageFeature>(flag)) {
116 EnableWarning(std::get<LanguageFeature>(flag), yes);
117 } else {
118 EnableWarning(std::get<UsageWarning>(flag), yes);
119 }
120 }
121 void WarnOnAllNonstandard(bool yes = true);
122 bool IsWarnOnAllNonstandard() const { return warnAllLanguage_; }
123 void WarnOnAllUsage(bool yes = true);
124 bool IsWarnOnAllUsage() const { return warnAllUsage_; }
125 void DisableAllNonstandardWarnings() {
126 warnAllLanguage_ = false;
127 warnLanguage_.clear();
128 }
129 void DisableAllUsageWarnings() {
130 warnAllUsage_ = false;
131 warnUsage_.clear();
132 }
133 void DisableAllWarnings() {
134 disableAllWarnings_ = true;
135 DisableAllNonstandardWarnings();
136 DisableAllUsageWarnings();
137 }
138 bool AreWarningsDisabled() const { return disableAllWarnings_; }
139 bool IsEnabled(LanguageFeature f) const { return !disable_.test(f); }
140 bool ShouldWarn(LanguageFeature f) const { return warnLanguage_.test(f); }
141 bool ShouldWarn(UsageWarning w) const { return warnUsage_.test(w); }
142 // Cli options
143 // Find a warning by its Cli spelling, i.e. '[no-]warning-name'.
144 std::optional<LanguageControlFlag> FindWarning(std::string_view input);
145 // Take a string from the Cli and apply it to the LanguageFeatureControl.
146 // Return true if the option was recognized (and hence applied).
147 bool EnableWarning(std::string_view input);
148 // The add and replace functions are not currently used but are provided
149 // to allow a flexible many-to-one mapping from Cli spellings to enum values.
150 // Taking a string by value because the functions own this string after the
151 // call.
152 void AddAlternativeCliSpelling(LanguageFeature f, std::string input) {
153 cliOptions_.insert({input, {f}});
154 }
155 void AddAlternativeCliSpelling(UsageWarning w, std::string input) {
156 cliOptions_.insert({input, {w}});
157 }
158 void AddDeprecatedCliSpelling(LanguageFeature f,
159 const std::string &deprecated, const std::string &canonical) {
160 cliOptions_.insert({deprecated, {f}});
161 deprecatedCliOptions_.insert({deprecated, canonical});
162 }
163 void AddDeprecatedCliSpelling(UsageWarning w, const std::string &deprecated,
164 const std::string &canonical) {
165 cliOptions_.insert({deprecated, {w}});
166 deprecatedCliOptions_.insert({deprecated, canonical});
167 }
168 // Returns the canonical spelling if the input is a deprecated spelling.
169 std::optional<std::string_view> CheckDeprecatedSpelling(
170 std::string_view input) const;
171 void ReplaceCliCanonicalSpelling(LanguageFeature f, std::string input);
172 void ReplaceCliCanonicalSpelling(UsageWarning w, std::string input);
173 std::string_view getDefaultCliSpelling(LanguageFeature f) const {
174 return languageFeatureCliCanonicalSpelling_[EnumToInt(f)];
175 };
176 std::string_view getDefaultCliSpelling(UsageWarning w) const {
177 return usageWarningCliCanonicalSpelling_[EnumToInt(w)];
178 };
179 // Return all spellings of operators names, depending on features enabled
180 std::vector<const char *> GetNames(LogicalOperator) const;
181 std::vector<const char *> GetNames(RelationalOperator) const;
182
183private:
184 // Map from Cli syntax of language features and usage warnings to their enum
185 // values.
186 std::unordered_map<std::string, LanguageFeatureOrWarning> cliOptions_;
187 // Map from deprecated Cli spellings to their canonical replacements.
188 std::unordered_map<std::string, std::string> deprecatedCliOptions_;
189 // These two arrays map the enum values to their cannonical Cli spellings.
190 // Since each of the CanonicalSpelling is a string in the domain of the map
191 // above we just use a view of the string instead of another copy.
192 std::array<std::string, LanguageFeature_enumSize>
193 languageFeatureCliCanonicalSpelling_;
194 std::array<std::string, UsageWarning_enumSize>
195 usageWarningCliCanonicalSpelling_;
196 LanguageFeatures disable_;
197 LanguageFeatures warnLanguage_;
198 bool warnAllLanguage_{false};
199 UsageWarnings warnUsage_;
200 bool warnAllUsage_{false};
201 bool disableAllWarnings_{false};
202};
203} // namespace Fortran::common
204#endif // FORTRAN_SUPPORT_FORTRAN_FEATURES_H_
Definition enum-set.h:28
Definition bit-population-count.h:20