r282443 - [Modules TS] Diagnose 'export' declaration within 'export' declaration.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 26 14:27:23 PDT 2016


Author: rsmith
Date: Mon Sep 26 16:27:23 2016
New Revision: 282443

URL: http://llvm.org/viewvc/llvm-project?rev=282443&view=rev
Log:
[Modules TS] Diagnose 'export' declaration within 'export' declaration.

Modified:
    cfe/trunk/include/clang/AST/DeclBase.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/AST/DeclBase.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/modules-ts.cppm

Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=282443&r1=282442&r2=282443&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Mon Sep 26 16:27:23 2016
@@ -568,6 +568,10 @@ public:
     return NextInContextAndBits.getInt() & ModulePrivateFlag;
   }
 
+  /// \brief Whether this declaration is exported (by virtue of being lexically
+  /// within an ExportDecl or by being a NamespaceDecl).
+  bool isExported() const;
+
   /// Return true if this declaration has an attribute which acts as
   /// definition of the entity, such as 'alias' or 'ifunc'.
   bool hasDefiningAttr() const;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=282443&r1=282442&r2=282443&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Sep 26 16:27:23 2016
@@ -8522,6 +8522,8 @@ def err_module_self_import : Error<
   "import of module '%0' appears within same top-level module '%1'">;
 def err_module_import_in_implementation : Error<
   "@import of module '%0' in implementation of '%1'; use #import">;
+def err_export_within_export : Error<
+  "export declaration appears within another export declaration">;
 
 def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
   "ambiguous use of internal linkage declaration %0 defined in multiple modules">,

Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=282443&r1=282442&r2=282443&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Mon Sep 26 16:27:23 2016
@@ -377,6 +377,22 @@ bool Decl::isReferenced() const {
   return false; 
 }
 
+bool Decl::isExported() const {
+  if (isModulePrivate())
+    return false;
+  // Namespaces are always exported.
+  if (isa<TranslationUnitDecl>(this) || isa<NamespaceDecl>(this))
+    return true;
+  // Otherwise, this is a strictly lexical check.
+  for (auto *DC = getLexicalDeclContext(); DC; DC = DC->getLexicalParent()) {
+    if (cast<Decl>(DC)->isModulePrivate())
+      return false;
+    if (isa<ExportDecl>(DC))
+      return true;
+  }
+  return false;
+}
+
 bool Decl::hasDefiningAttr() const {
   return hasAttr<AliasAttr>() || hasAttr<IFuncAttr>();
 }

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=282443&r1=282442&r2=282443&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Sep 26 16:27:23 2016
@@ -15465,14 +15465,17 @@ void Sema::createImplicitModuleImportFor
 /// (if present).
 Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc,
                                  SourceLocation LBraceLoc) {
-  // FIXME: C++ Modules TS:
+  ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
+
+  // C++ Modules TS draft:
   //   An export-declaration [...] shall not contain more than one
   //   export keyword.
   //
   // The intent here is that an export-declaration cannot appear within another
   // export-declaration.
+  if (D->isExported())
+    Diag(ExportLoc, diag::err_export_within_export);
 
-  ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc);
   CurContext->addDecl(D);
   PushDeclContext(S, D);
   return D;

Modified: cfe/trunk/test/SemaCXX/modules-ts.cppm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/modules-ts.cppm?rev=282443&r1=282442&r2=282443&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/modules-ts.cppm (original)
+++ cfe/trunk/test/SemaCXX/modules-ts.cppm Mon Sep 26 16:27:23 2016
@@ -66,3 +66,18 @@ struct S {
 
 // FIXME: Exports of declarations without external linkage are disallowed.
 // Exports of declarations with non-external-linkage types are disallowed.
+
+// Cannot export within another export. This isn't precisely covered by the
+// language rules right now, but (per personal correspondence between zygoloid
+// and gdr) is the intent.
+#if TEST == 1
+export {
+  extern "C++" {
+    namespace NestedExport {
+      export { // expected-error {{appears within another export}}
+        int q;
+      }
+    }
+  }
+}
+#endif




More information about the cfe-commits mailing list