|
11 | 11 | #include "flang/Common/restorer.h" |
12 | 12 | #include "flang/Evaluate/tools.h" |
13 | 13 | #include "flang/Parser/message.h" |
| 14 | +#include "flang/Parser/parse-tree-visitor.h" |
14 | 15 | #include "flang/Parser/parsing.h" |
15 | 16 | #include "flang/Parser/unparse.h" |
16 | 17 | #include "flang/Semantics/scope.h" |
@@ -72,6 +73,7 @@ static bool FileContentsMatch( |
72 | 73 | const std::string &, const std::string &, const std::string &); |
73 | 74 | static ModuleCheckSumType ComputeCheckSum(const std::string_view &); |
74 | 75 | static std::string CheckSumString(ModuleCheckSumType); |
| 76 | +static bool ProgramHasCUDAAttrs(const parser::Program &); |
75 | 77 |
|
76 | 78 | // Collect symbols needed for a subprogram interface |
77 | 79 | class SubprogramSymbolCollector { |
@@ -1703,6 +1705,13 @@ Scope *ModFileReader::Read(SourceName name, std::optional<bool> isIntrinsic, |
1703 | 1705 | return nullptr; |
1704 | 1706 | } |
1705 | 1707 | parser::Program &parseTree{context_.SaveParseTree(std::move(*parsedProgram))}; |
| 1708 | + if (context_.languageFeatures().IsEnabled(common::LanguageFeature::OpenACC) && |
| 1709 | + !context_.languageFeatures().IsEnabled(common::LanguageFeature::CUDA) && |
| 1710 | + ProgramHasCUDAAttrs(parseTree)) { |
| 1711 | + Say("use", name, ancestorName, |
| 1712 | + "CUDA is not enabled, but '%s' defines CUDA symbols"_err_en_US, |
| 1713 | + sourceFile->path()); |
| 1714 | + } |
1706 | 1715 | Scope *parentScope; // the scope this module/submodule goes into |
1707 | 1716 | if (!isIntrinsic.has_value()) { |
1708 | 1717 | for (const auto &dir : context_.intrinsicModuleDirectories()) { |
@@ -1823,6 +1832,26 @@ static std::optional<SourceName> GetSubmoduleParent( |
1823 | 1832 | } |
1824 | 1833 | } |
1825 | 1834 |
|
| 1835 | +struct CUDAAttrProgramVisitor { |
| 1836 | + template <typename A> bool Pre(const A &) { return true; } |
| 1837 | + template <typename A> void Post(const A &) {} |
| 1838 | + bool Pre(const common::CUDADataAttr &) { |
| 1839 | + foundCUDAAttrs = true; |
| 1840 | + return false; |
| 1841 | + } |
| 1842 | + bool Pre(const common::CUDASubprogramAttrs &) { |
| 1843 | + foundCUDAAttrs = true; |
| 1844 | + return false; |
| 1845 | + } |
| 1846 | + bool foundCUDAAttrs{false}; |
| 1847 | +}; |
| 1848 | + |
| 1849 | +static bool ProgramHasCUDAAttrs(const parser::Program &program) { |
| 1850 | + CUDAAttrProgramVisitor visitor; |
| 1851 | + parser::Walk(program, visitor); |
| 1852 | + return visitor.foundCUDAAttrs; |
| 1853 | +} |
| 1854 | + |
1826 | 1855 | void SubprogramSymbolCollector::Collect() { |
1827 | 1856 | const auto &details{symbol_.get<SubprogramDetails>()}; |
1828 | 1857 | isInterface_ = details.isInterface(); |
|
0 commit comments