[flang-commits] [flang] 7d60232 - [flang][Frontend] Implement printing defined macros via -dM (#87627)
via flang-commits
flang-commits at lists.llvm.org
Wed Apr 10 08:41:24 PDT 2024
Author: Krzysztof Parzyszek
Date: 2024-04-10T10:41:20-05:00
New Revision: 7d60232b38b66138dae1b31027d73ee5b9df5c58
URL: https://github.com/llvm/llvm-project/commit/7d60232b38b66138dae1b31027d73ee5b9df5c58
DIFF: https://github.com/llvm/llvm-project/commit/7d60232b38b66138dae1b31027d73ee5b9df5c58.diff
LOG: [flang][Frontend] Implement printing defined macros via -dM (#87627)
This should work the same way as in clang.
Added:
flang/include/flang/Parser/preprocessor.h
flang/include/flang/Parser/token-sequence.h
flang/test/Preprocessing/show-macros1.F90
flang/test/Preprocessing/show-macros2.F90
flang/test/Preprocessing/show-macros3.F90
Modified:
clang/docs/tools/clang-formatted-files.txt
clang/include/clang/Driver/Options.td
clang/lib/Driver/ToolChains/Flang.cpp
flang/include/flang/Frontend/PreprocessorOptions.h
flang/include/flang/Parser/parsing.h
flang/lib/Frontend/CompilerInvocation.cpp
flang/lib/Frontend/FrontendActions.cpp
flang/lib/Parser/parsing.cpp
flang/lib/Parser/preprocessor.cpp
flang/lib/Parser/prescan.cpp
flang/lib/Parser/prescan.h
flang/lib/Parser/token-sequence.cpp
flang/test/Driver/driver-help-hidden.f90
flang/test/Driver/driver-help.f90
Removed:
flang/lib/Parser/preprocessor.h
flang/lib/Parser/token-sequence.h
################################################################################
diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt
index 70687c23b15e61..8fd4fed25a32a1 100644
--- a/clang/docs/tools/clang-formatted-files.txt
+++ b/clang/docs/tools/clang-formatted-files.txt
@@ -2147,8 +2147,10 @@ flang/include/flang/Parser/message.h
flang/include/flang/Parser/parse-state.h
flang/include/flang/Parser/parse-tree-visitor.h
flang/include/flang/Parser/parsing.h
+flang/include/flang/Parser/preprocessor.h
flang/include/flang/Parser/provenance.h
flang/include/flang/Parser/source.h
+flang/include/flang/Parser/token-sequence.h
flang/include/flang/Parser/tools.h
flang/include/flang/Parser/unparse.h
flang/include/flang/Parser/user-state.h
@@ -2319,7 +2321,6 @@ flang/lib/Parser/openmp-parsers.cpp
flang/lib/Parser/parse-tree.cpp
flang/lib/Parser/parsing.cpp
flang/lib/Parser/preprocessor.cpp
-flang/lib/Parser/preprocessor.h
flang/lib/Parser/prescan.cpp
flang/lib/Parser/prescan.h
flang/lib/Parser/program-parsers.cpp
@@ -2328,7 +2329,6 @@ flang/lib/Parser/source.cpp
flang/lib/Parser/stmt-parser.h
flang/lib/Parser/token-parsers.h
flang/lib/Parser/token-sequence.cpp
-flang/lib/Parser/token-sequence.h
flang/lib/Parser/tools.cpp
flang/lib/Parser/type-parser-implementation.h
flang/lib/Parser/type-parsers.h
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index f745e573eb2686..0a74e6c75f95bb 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1449,7 +1449,7 @@ def dD : Flag<["-"], "dD">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>
def dI : Flag<["-"], "dI">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
HelpText<"Print include directives in -E mode in addition to normal output">,
MarshallingInfoFlag<PreprocessorOutputOpts<"ShowIncludeDirectives">>;
-def dM : Flag<["-"], "dM">, Group<d_Group>, Visibility<[ClangOption, CC1Option]>,
+def dM : Flag<["-"], "dM">, Group<d_Group>, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
HelpText<"Print macro definitions in -E mode instead of normal output">;
def dead__strip : Flag<["-"], "dead_strip">;
def dependency_file : Separate<["-"], "dependency-file">,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 2c83f70eb7887e..9699443603d36a 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -679,7 +679,10 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Args.MakeArgString(TripleStr));
if (isa<PreprocessJobAction>(JA)) {
- CmdArgs.push_back("-E");
+ CmdArgs.push_back("-E");
+ if (Args.getLastArg(options::OPT_dM)) {
+ CmdArgs.push_back("-dM");
+ }
} else if (isa<CompileJobAction>(JA) || isa<BackendJobAction>(JA)) {
if (JA.getType() == types::TY_Nothing) {
CmdArgs.push_back("-fsyntax-only");
diff --git a/flang/include/flang/Frontend/PreprocessorOptions.h b/flang/include/flang/Frontend/PreprocessorOptions.h
index b2e9ac0e963b73..13a91ee9a184f8 100644
--- a/flang/include/flang/Frontend/PreprocessorOptions.h
+++ b/flang/include/flang/Frontend/PreprocessorOptions.h
@@ -56,6 +56,9 @@ struct PreprocessorOptions {
// -fno-reformat: Emit cooked character stream as -E output
bool noReformat{false};
+ // -dM: Show macro definitions with -dM -E
+ bool showMacros{false};
+
void addMacroDef(llvm::StringRef name) {
macros.emplace_back(std::string(name), false);
}
diff --git a/flang/include/flang/Parser/parsing.h b/flang/include/flang/Parser/parsing.h
index e80d8f724ac8f4..4d329c189cb80e 100644
--- a/flang/include/flang/Parser/parsing.h
+++ b/flang/include/flang/Parser/parsing.h
@@ -15,6 +15,7 @@
#include "parse-tree.h"
#include "provenance.h"
#include "flang/Common/Fortran-features.h"
+#include "flang/Parser/preprocessor.h"
#include "llvm/Support/raw_ostream.h"
#include <optional>
#include <string>
@@ -59,6 +60,7 @@ class Parsing {
const SourceFile *Prescan(const std::string &path, Options);
void EmitPreprocessedSource(
llvm::raw_ostream &, bool lineDirectives = true) const;
+ void EmitPreprocessorMacros(llvm::raw_ostream &) const;
void DumpCookedChars(llvm::raw_ostream &) const;
void DumpProvenance(llvm::raw_ostream &) const;
void DumpParsingLog(llvm::raw_ostream &) const;
@@ -83,6 +85,7 @@ class Parsing {
const char *finalRestingPlace_{nullptr};
std::optional<Program> parseTree_;
ParsingLog log_;
+ Preprocessor preprocessor_{allCooked_.allSources()};
};
} // namespace Fortran::parser
#endif // FORTRAN_PARSER_PARSING_H_
diff --git a/flang/lib/Parser/preprocessor.h b/flang/include/flang/Parser/preprocessor.h
similarity index 88%
rename from flang/lib/Parser/preprocessor.h
rename to flang/include/flang/Parser/preprocessor.h
index b61f1577727beb..630d5273d427c6 100644
--- a/flang/lib/Parser/preprocessor.h
+++ b/flang/include/flang/Parser/preprocessor.h
@@ -15,9 +15,10 @@
// performed, so that special compiler command options &/or source file name
// extensions for preprocessing will not be necessary.
-#include "token-sequence.h"
#include "flang/Parser/char-block.h"
#include "flang/Parser/provenance.h"
+#include "flang/Parser/token-sequence.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstddef>
#include <list>
#include <stack>
@@ -39,7 +40,7 @@ class Definition {
Definition(const std::string &predefined, AllSources &);
bool isFunctionLike() const { return isFunctionLike_; }
- std::size_t argumentCount() const { return argumentCount_; }
+ std::size_t argumentCount() const { return argNames_.size(); }
bool isVariadic() const { return isVariadic_; }
bool isDisabled() const { return isDisabled_; }
bool isPredefined() const { return isPredefined_; }
@@ -49,15 +50,21 @@ class Definition {
TokenSequence Apply(const std::vector<TokenSequence> &args, Prescanner &);
+ void Print(llvm::raw_ostream &out, const char *macroName = "") const;
+
private:
static TokenSequence Tokenize(const std::vector<std::string> &argNames,
const TokenSequence &token, std::size_t firstToken, std::size_t tokens);
+ // For a given token, return the index of the argument to which the token
+ // corresponds, or `argumentCount` if the token does not correspond to any
+ // argument.
+ std::size_t GetArgumentIndex(const CharBlock &token) const;
bool isFunctionLike_{false};
- std::size_t argumentCount_{0};
bool isVariadic_{false};
bool isDisabled_{false};
bool isPredefined_{false};
+ std::vector<std::string> argNames_;
TokenSequence replacement_;
};
@@ -89,6 +96,8 @@ class Preprocessor {
// Implements a preprocessor directive.
void Directive(const TokenSequence &, Prescanner &);
+ void PrintMacros(llvm::raw_ostream &out) const;
+
private:
enum class IsElseActive { No, Yes };
enum class CanDeadElseAppear { No, Yes };
diff --git a/flang/lib/Parser/token-sequence.h b/flang/include/flang/Parser/token-sequence.h
similarity index 97%
rename from flang/lib/Parser/token-sequence.h
rename to flang/include/flang/Parser/token-sequence.h
index 3df403d41e636f..849240d8ec62c5 100644
--- a/flang/lib/Parser/token-sequence.h
+++ b/flang/include/flang/Parser/token-sequence.h
@@ -42,8 +42,8 @@ class TokenSequence {
}
TokenSequence(TokenSequence &&that)
: start_{std::move(that.start_)}, nextStart_{that.nextStart_},
- char_{std::move(that.char_)}, provenances_{
- std::move(that.provenances_)} {}
+ char_{std::move(that.char_)},
+ provenances_{std::move(that.provenances_)} {}
TokenSequence(const std::string &s, Provenance p) { Put(s, p); }
TokenSequence &operator=(const TokenSequence &that) {
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index c830c7af2462c9..8ce6ab7baf4812 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -772,6 +772,7 @@ static void parsePreprocessorArgs(Fortran::frontend::PreprocessorOptions &opts,
opts.noReformat = args.hasArg(clang::driver::options::OPT_fno_reformat);
opts.noLineDirectives = args.hasArg(clang::driver::options::OPT_P);
+ opts.showMacros = args.hasArg(clang::driver::options::OPT_dM);
}
/// Parses all semantic related arguments and populates the variables
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 849b3c8e4dc027..8f251997ed401b 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -399,7 +399,9 @@ void PrintPreprocessedAction::executeAction() {
// Format or dump the prescanner's output
CompilerInstance &ci = this->getInstance();
- if (ci.getInvocation().getPreprocessorOpts().noReformat) {
+ if (ci.getInvocation().getPreprocessorOpts().showMacros) {
+ ci.getParsing().EmitPreprocessorMacros(outForPP);
+ } else if (ci.getInvocation().getPreprocessorOpts().noReformat) {
ci.getParsing().DumpCookedChars(outForPP);
} else {
ci.getParsing().EmitPreprocessedSource(
diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp
index a55d33bf6b91d6..43a898ff120c5d 100644
--- a/flang/lib/Parser/parsing.cpp
+++ b/flang/lib/Parser/parsing.cpp
@@ -7,10 +7,10 @@
//===----------------------------------------------------------------------===//
#include "flang/Parser/parsing.h"
-#include "preprocessor.h"
#include "prescan.h"
#include "type-parsers.h"
#include "flang/Parser/message.h"
+#include "flang/Parser/preprocessor.h"
#include "flang/Parser/provenance.h"
#include "flang/Parser/source.h"
#include "llvm/Support/raw_ostream.h"
@@ -60,20 +60,19 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
}
}
- Preprocessor preprocessor{allSources};
if (!options.predefinitions.empty()) {
- preprocessor.DefineStandardMacros();
+ preprocessor_.DefineStandardMacros();
for (const auto &predef : options.predefinitions) {
if (predef.second) {
- preprocessor.Define(predef.first, *predef.second);
+ preprocessor_.Define(predef.first, *predef.second);
} else {
- preprocessor.Undefine(predef.first);
+ preprocessor_.Undefine(predef.first);
}
}
}
currentCooked_ = &allCooked_.NewCookedSource();
Prescanner prescanner{
- messages_, *currentCooked_, preprocessor, options.features};
+ messages_, *currentCooked_, preprocessor_, options.features};
prescanner.set_fixedForm(options.isFixedForm)
.set_fixedFormColumnLimit(options.fixedFormColumns)
.AddCompilerDirectiveSentinel("dir$");
@@ -87,7 +86,7 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
if (options.features.IsEnabled(LanguageFeature::CUDA)) {
prescanner.AddCompilerDirectiveSentinel("$cuf");
prescanner.AddCompilerDirectiveSentinel("@cuf");
- preprocessor.Define("_CUDA", "1");
+ preprocessor_.Define("_CUDA", "1");
}
ProvenanceRange range{allSources.AddIncludedFile(
*sourceFile, ProvenanceRange{}, options.isModuleFile)};
@@ -107,6 +106,10 @@ const SourceFile *Parsing::Prescan(const std::string &path, Options options) {
return sourceFile;
}
+void Parsing::EmitPreprocessorMacros(llvm::raw_ostream &out) const {
+ preprocessor_.PrintMacros(out);
+}
+
void Parsing::EmitPreprocessedSource(
llvm::raw_ostream &out, bool lineDirectives) const {
const std::string *sourcePath{nullptr};
diff --git a/flang/lib/Parser/preprocessor.cpp b/flang/lib/Parser/preprocessor.cpp
index 515b8f62daf9ad..2fba28b0c0c7d8 100644
--- a/flang/lib/Parser/preprocessor.cpp
+++ b/flang/lib/Parser/preprocessor.cpp
@@ -6,7 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "preprocessor.h"
+#include "flang/Parser/preprocessor.h"
+
#include "prescan.h"
#include "flang/Common/idioms.h"
#include "flang/Parser/characters.h"
@@ -21,6 +22,7 @@
#include <optional>
#include <set>
#include <utility>
+#include <vector>
namespace Fortran::parser {
@@ -31,8 +33,7 @@ Definition::Definition(
Definition::Definition(const std::vector<std::string> &argNames,
const TokenSequence &repl, std::size_t firstToken, std::size_t tokens,
bool isVariadic)
- : isFunctionLike_{true},
- argumentCount_(argNames.size()), isVariadic_{isVariadic},
+ : isFunctionLike_{true}, isVariadic_{isVariadic}, argNames_{argNames},
replacement_{Tokenize(argNames, repl, firstToken, tokens)} {}
Definition::Definition(const std::string &predefined, AllSources &sources)
@@ -46,6 +47,37 @@ bool Definition::set_isDisabled(bool disable) {
return was;
}
+void Definition::Print(llvm::raw_ostream &out, const char *macroName) const {
+ if (!isFunctionLike_) {
+ // If it's not a function-like macro, then just print the replacement.
+ out << ' ' << replacement_.ToString();
+ return;
+ }
+
+ size_t argCount{argumentCount()};
+
+ out << '(';
+ for (size_t i{0}; i != argCount; ++i) {
+ if (i != 0) {
+ out << ", ";
+ }
+ out << argNames_[i];
+ }
+ if (isVariadic_) {
+ out << ", ...";
+ }
+ out << ") ";
+
+ for (size_t i{0}, e{replacement_.SizeInTokens()}; i != e; ++i) {
+ std::string tok{replacement_.TokenAt(i).ToString()};
+ if (size_t idx{GetArgumentIndex(tok)}; idx < argCount) {
+ out << argNames_[idx];
+ } else {
+ out << tok;
+ }
+ }
+}
+
static bool IsLegalIdentifierStart(const CharBlock &cpl) {
return cpl.size() > 0 && IsLegalIdentifierStart(cpl[0]);
}
@@ -73,6 +105,13 @@ TokenSequence Definition::Tokenize(const std::vector<std::string> &argNames,
return result;
}
+std::size_t Definition::GetArgumentIndex(const CharBlock &token) const {
+ if (token.size() >= 2 && token[0] == '~') {
+ return static_cast<size_t>(token[1] - 'A');
+ }
+ return argumentCount();
+}
+
static TokenSequence Stringify(
const TokenSequence &tokens, AllSources &allSources) {
TokenSequence result;
@@ -159,7 +198,7 @@ TokenSequence Definition::Apply(
continue;
}
if (bytes == 2 && token[0] == '~') { // argument substitution
- std::size_t index = token[1] - 'A';
+ std::size_t index{GetArgumentIndex(token)};
if (index >= args.size()) {
continue;
}
@@ -202,8 +241,8 @@ TokenSequence Definition::Apply(
Provenance commaProvenance{
prescanner.preprocessor().allSources().CompilerInsertionProvenance(
',')};
- for (std::size_t k{argumentCount_}; k < args.size(); ++k) {
- if (k > argumentCount_) {
+ for (std::size_t k{argumentCount()}; k < args.size(); ++k) {
+ if (k > argumentCount()) {
result.Put(","s, commaProvenance);
}
result.Put(args[k]);
@@ -212,7 +251,7 @@ TokenSequence Definition::Apply(
j + 2 < tokens && replacement_.TokenAt(j + 1).OnlyNonBlank() == '(' &&
parenthesesNesting == 0) {
parenthesesNesting = 1;
- skipping = args.size() == argumentCount_;
+ skipping = args.size() == argumentCount();
++j;
} else {
if (parenthesesNesting > 0) {
@@ -713,6 +752,21 @@ void Preprocessor::Directive(const TokenSequence &dir, Prescanner &prescanner) {
}
}
+void Preprocessor::PrintMacros(llvm::raw_ostream &out) const {
+ // std::set is ordered. Use that to print the macros in an
+ // alphabetical order.
+ std::set<std::string> macroNames;
+ for (const auto &[name, _] : definitions_) {
+ macroNames.insert(name.ToString());
+ }
+
+ for (const std::string &name : macroNames) {
+ out << "#define " << name;
+ definitions_.at(name).Print(out, name.c_str());
+ out << '\n';
+ }
+}
+
CharBlock Preprocessor::SaveTokenAsName(const CharBlock &t) {
names_.push_back(t.ToString());
return {names_.back().data(), names_.back().size()};
diff --git a/flang/lib/Parser/prescan.cpp b/flang/lib/Parser/prescan.cpp
index e9b23172ed2e28..96db3955299f33 100644
--- a/flang/lib/Parser/prescan.cpp
+++ b/flang/lib/Parser/prescan.cpp
@@ -7,12 +7,12 @@
//===----------------------------------------------------------------------===//
#include "prescan.h"
-#include "preprocessor.h"
-#include "token-sequence.h"
#include "flang/Common/idioms.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/message.h"
+#include "flang/Parser/preprocessor.h"
#include "flang/Parser/source.h"
+#include "flang/Parser/token-sequence.h"
#include "llvm/Support/raw_ostream.h"
#include <cstddef>
#include <cstring>
diff --git a/flang/lib/Parser/prescan.h b/flang/lib/Parser/prescan.h
index 7442b5d2263354..581980001bcc23 100644
--- a/flang/lib/Parser/prescan.h
+++ b/flang/lib/Parser/prescan.h
@@ -16,11 +16,11 @@
// fixed form character literals on truncated card images, file
// inclusion, and driving the Fortran source preprocessor.
-#include "token-sequence.h"
#include "flang/Common/Fortran-features.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/message.h"
#include "flang/Parser/provenance.h"
+#include "flang/Parser/token-sequence.h"
#include <bitset>
#include <optional>
#include <string>
diff --git a/flang/lib/Parser/token-sequence.cpp b/flang/lib/Parser/token-sequence.cpp
index 799d13a423660c..d0254ecd5aaefc 100644
--- a/flang/lib/Parser/token-sequence.cpp
+++ b/flang/lib/Parser/token-sequence.cpp
@@ -6,7 +6,8 @@
//
//===----------------------------------------------------------------------===//
-#include "token-sequence.h"
+#include "flang/Parser/token-sequence.h"
+
#include "prescan.h"
#include "flang/Parser/characters.h"
#include "flang/Parser/message.h"
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index 48f48f5384fdc5..35b188ad3a9ec4 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -21,6 +21,7 @@
! CHECK-NEXT: -ccc-print-phases Dump list of actions to perform
! CHECK-NEXT: -cpp Enable predefined and command line preprocessor macros
! CHECK-NEXT: -c Only run preprocess, compile, and assemble steps
+! CHECK-NEXT: -dM Print macro definitions in -E mode instead of normal output
! CHECK-NEXT: -dumpmachine Display the compiler's target processor
! CHECK-NEXT: -dumpversion Display the version of the compiler
! CHECK-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90
index 38f74395a678ab..d4dab55f40e8b5 100644
--- a/flang/test/Driver/driver-help.f90
+++ b/flang/test/Driver/driver-help.f90
@@ -17,6 +17,7 @@
! HELP-NEXT: -### Print (but do not run) the commands to run for this compilation
! HELP-NEXT: -cpp Enable predefined and command line preprocessor macros
! HELP-NEXT: -c Only run preprocess, compile, and assemble steps
+! HELP-NEXT: -dM Print macro definitions in -E mode instead of normal output
! HELP-NEXT: -dumpmachine Display the compiler's target processor
! HELP-NEXT: -dumpversion Display the version of the compiler
! HELP-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
@@ -155,6 +156,7 @@
! HELP-FC1-NEXT:OPTIONS:
! HELP-FC1-NEXT: -cpp Enable predefined and command line preprocessor macros
! HELP-FC1-NEXT: --dependent-lib=<value> Add dependent library
+! HELP-FC1-NEXT: -dM Print macro definitions in -E mode instead of normal output
! HELP-FC1-NEXT: -D <macro>=<value> Define <macro> to <value> (or 1 if <value> omitted)
! HELP-FC1-NEXT: -emit-fir Build the parse tree, then lower it to FIR
! HELP-FC1-NEXT: -emit-hlfir Build the parse tree, then lower it to HLFIR
diff --git a/flang/test/Preprocessing/show-macros1.F90 b/flang/test/Preprocessing/show-macros1.F90
new file mode 100644
index 00000000000000..8e3d59a7849f70
--- /dev/null
+++ b/flang/test/Preprocessing/show-macros1.F90
@@ -0,0 +1,14 @@
+! RUN: %flang -dM -E -o - %s | FileCheck %s
+
+! Check the default macros. Omit certain ones such as __LINE__
+! or __FILE__, or target-specific ones, like __x86_64__.
+
+! Macros are printed in the alphabetical order.
+
+! CHECK: #define __DATE__
+! CHECK: #define __TIME__
+! CHECK: #define __flang__
+! CHECK: #define __flang_major__
+! CHECK: #define __flang_minor__
+! CHECK: #define __flang_patchlevel__
+
diff --git a/flang/test/Preprocessing/show-macros2.F90 b/flang/test/Preprocessing/show-macros2.F90
new file mode 100644
index 00000000000000..baf52ba8161f11
--- /dev/null
+++ b/flang/test/Preprocessing/show-macros2.F90
@@ -0,0 +1,6 @@
+! RUN: %flang -DFOO -DBAR=FOO -dM -E -o - %s | FileCheck %s
+
+! Check command line definitions
+
+! CHECK: #define BAR FOO
+! CHECK: #define FOO 1
diff --git a/flang/test/Preprocessing/show-macros3.F90 b/flang/test/Preprocessing/show-macros3.F90
new file mode 100644
index 00000000000000..951a1ec5ba16f4
--- /dev/null
+++ b/flang/test/Preprocessing/show-macros3.F90
@@ -0,0 +1,9 @@
+! RUN: %flang -dM -E -o - %s | FileCheck %s
+
+! Variadic macro
+#define FOO1(X, Y, ...) bar(bar(X, Y), __VA_ARGS__)
+! CHECK: #define FOO1(X, Y, ...) bar(bar(X, Y), __VA_ARGS__)
+
+! Macro with an unused parameter
+#define FOO2(X, Y, Z) (X + Z)
+! CHECK: #define FOO2(X, Y, Z) (X + Z)
More information about the flang-commits
mailing list