[libcxx-commits] [libcxx] a134477 - Revert "Add new 'preferred_name' attribute."

Richard Smith via libcxx-commits libcxx-commits at lists.llvm.org
Tue Dec 8 00:55:53 PST 2020


Author: Richard Smith
Date: 2020-12-08T00:42:48-08:00
New Revision: a1344779ab019a6bcd29842c1499343e15efbe87

URL: https://github.com/llvm/llvm-project/commit/a1344779ab019a6bcd29842c1499343e15efbe87
DIFF: https://github.com/llvm/llvm-project/commit/a1344779ab019a6bcd29842c1499343e15efbe87.diff

LOG: Revert "Add new 'preferred_name' attribute."

This change exposed a pre-existing issue with deserialization cycles
caused by a combination of attributes and template instantiations
violating the deserialization ordering restrictions; see PR48434 for
details.

A previous commit attempted to work around PR48434, but appears to have
only been a partial fix, and fixing this properly seems non-trivial.
Backing out for now to unblock things.

This reverts commit 98f76adf4e941738c0b9fe3b9965fa63603e9c89 and
commit a64c26a47a81b1b44e36d235ff3bc6a74a0bad9f.

Added: 
    

Modified: 
    clang/include/clang/AST/TypeProperties.td
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/AttrDocs.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/AST/TypePrinter.cpp
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/lib/Sema/SemaTemplate.cpp
    clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
    clang/test/SemaTemplate/attributes.cpp
    clang/utils/TableGen/ClangAttrEmitter.cpp
    libcxx/include/__config
    libcxx/include/iosfwd
    libcxx/include/regex
    libcxx/include/string
    libcxx/include/string_view

Removed: 
    clang/test/PCH/decl-attrs.cpp


################################################################################
diff  --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index b582395c44a6..a183ac0479c6 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -484,12 +484,8 @@ let Class = TagType in {
     let Read = [{ node->isDependentType() }];
   }
   def : Property<"declaration", DeclRef> {
-    // We don't know which declaration was originally referenced here, and we
-    // cannot reference a declaration that follows the use (because that can
-    // introduce deserialization cycles), so conservatively generate a
-    // reference to the first declaration.
-    // FIXME: If this is a reference to a class template specialization, that
-    // can still introduce a deserialization cycle.
+    // Serializing a reference to the canonical declaration is apparently
+    // necessary to make module-merging work.
     let Read = [{ node->getDecl()->getCanonicalDecl() }];
   }
 }

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 51f654fc7613..52041201d22f 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -126,9 +126,6 @@ def FunctionTmpl
                                  FunctionDecl::TK_FunctionTemplate}],
                     "function templates">;
 
-def ClassTmpl : SubsetSubject<CXXRecord, [{S->getDescribedClassTemplate()}],
-                              "class templates">;
-
 // FIXME: this hack is needed because DeclNodes.td defines the base Decl node
 // type to be a class, not a definition. This makes it impossible to create an
 // attribute subject which accepts a Decl. Normally, this is not a problem,
@@ -2394,16 +2391,6 @@ def Pascal : DeclOrTypeAttr {
   let Documentation = [Undocumented];
 }
 
-def PreferredName : InheritableAttr {
-  let Spellings = [Clang<"preferred_name", /*AllowInC*/0>];
-  let Subjects = SubjectList<[ClassTmpl]>;
-  let Args = [TypeArgument<"TypedefType">];
-  let Documentation = [PreferredNameDocs];
-  let InheritEvenIfAlreadyPresent = 1;
-  let MeaningfulToClassTemplateDefinition = 1;
-  let TemplateDependent = 1;
-}
-
 def PreserveMost : DeclOrTypeAttr {
   let Spellings = [Clang<"preserve_most">];
   let Documentation = [PreserveMostDocs];

diff  --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td
index 28f35cf2c0c7..e7e2805a9608 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -4471,30 +4471,6 @@ the old mangled name and the new code will use the new mangled name with tags.
   }];
 }
 
-def PreferredNameDocs : Documentation {
-  let Category = DocCatDecl;
-  let Content = [{
-The ``preferred_name`` attribute can be applied to a class template, and
-specifies a preferred way of naming a specialization of the template. The
-preferred name will be used whenever the corresponding template specialization
-would otherwise be printed in a diagnostic or similar context.
-
-The preferred name must be a typedef or type alias declaration that refers to a
-specialization of the class template (not including any type qualifiers). In
-general this requires the template to be declared at least twice. For example:
-
-.. code-block:: c++
-
-  template<typename T> struct basic_string;
-  using string = basic_string<char>;
-  using wstring = basic_string<wchar_t>;
-  template<typename T> struct [[clang::preferred_name(string),
-                                clang::preferred_name(wstring)]] basic_string {
-    // ...
-  };
-  }];
-}
-
 def PreserveMostDocs : Documentation {
   let Category = DocCatCallingConvs;
   let Content = [{

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 97773d35a694..4a5402455301 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -3941,9 +3941,6 @@ def note_protocol_decl : Note<
   "protocol is declared here">;
 def note_protocol_decl_undefined : Note<
   "protocol %0 has no definition">;
-def err_attribute_preferred_name_arg_invalid : Error<
-  "argument %0 to 'preferred_name' attribute is not a typedef for "
-  "a specialization of %1">;
 
 // objc_designated_initializer attribute diagnostics.
 def warn_objc_designated_init_missing_super_call : Warning<

diff  --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 77ca0f21cc8a..b4a9732b4def 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -10,8 +10,8 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/ASTContext.h"
-#include "clang/AST/Attr.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -19,7 +19,6 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/NestedNameSpecifier.h"
-#include "clang/AST/PrettyPrinter.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
@@ -1349,19 +1348,6 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
 }
 
 void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
-  // Print the preferred name if we have one for this type.
-  if (const auto *Spec =
-          dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl())) {
-    for (const auto *PNA : Spec->getSpecializedTemplate()
-                               ->getTemplatedDecl()
-                               ->getMostRecentDecl()
-                               ->specific_attrs<PreferredNameAttr>()) {
-      if (declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(), Spec))
-        return printTypeSpec(
-            PNA->getTypedefType()->castAs<TypedefType>()->getDecl(), OS);
-    }
-  }
-
   printTag(T->getDecl(), OS);
 }
 

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 15094854300d..aa30be20db5a 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -1380,43 +1380,6 @@ static void handlePackedAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
     S.Diag(AL.getLoc(), diag::warn_attribute_ignored) << AL;
 }
 
-static void handlePreferredName(Sema &S, Decl *D, const ParsedAttr &AL) {
-  auto *RD = cast<CXXRecordDecl>(D);
-  ClassTemplateDecl *CTD = RD->getDescribedClassTemplate();
-  assert(CTD && "attribute does not appertain to this declaration");
-
-  ParsedType PT = AL.getTypeArg();
-  TypeSourceInfo *TSI = nullptr;
-  QualType T = S.GetTypeFromParser(PT, &TSI);
-  if (!TSI)
-    TSI = S.Context.getTrivialTypeSourceInfo(T, AL.getLoc());
-
-  if (!T.hasQualifiers() && T->getAs<TypedefType>()) {
-    // Find the template name, if this type names a template specialization.
-    const TemplateDecl *Template = nullptr;
-    if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
-            T->getAsCXXRecordDecl())) {
-      Template = CTSD->getSpecializedTemplate();
-    } else if (const auto *TST = T->getAs<TemplateSpecializationType>()) {
-      while (TST && TST->isTypeAlias())
-        TST = TST->getAliasedType()->getAs<TemplateSpecializationType>();
-      if (TST)
-        Template = TST->getTemplateName().getAsTemplateDecl();
-    }
-
-    if (Template && declaresSameEntity(Template, CTD)) {
-      D->addAttr(::new (S.Context) PreferredNameAttr(S.Context, AL, TSI));
-      return;
-    }
-  }
-
-  S.Diag(AL.getLoc(), diag::err_attribute_preferred_name_arg_invalid)
-      << T << CTD;
-  if (const auto *TT = T->getAs<TypedefType>())
-    S.Diag(TT->getDecl()->getLocation(), diag::note_entity_declared_at)
-        << TT->getDecl();
-}
-
 static bool checkIBOutletCommon(Sema &S, Decl *D, const ParsedAttr &AL) {
   // The IBOutlet/IBOutletCollection attributes only apply to instance
   // variables or properties of Objective-C classes.  The outlet must also
@@ -7815,9 +7778,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case ParsedAttr::AT_Packed:
     handlePackedAttr(S, D, AL);
     break;
-  case ParsedAttr::AT_PreferredName:
-    handlePreferredName(S, D, AL);
-    break;
   case ParsedAttr::AT_Section:
     handleSectionAttr(S, D, AL);
     break;

diff  --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 4176aa1f458f..03715ef600bc 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3792,15 +3792,11 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
         Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
     }
 
-    if (Decl->getSpecializationKind() == TSK_Undeclared &&
-        ClassTemplate->getTemplatedDecl()->hasAttrs()) {
-      InstantiatingTemplate Inst(*this, TemplateLoc, Decl);
-      if (!Inst.isInvalid()) {
-        MultiLevelTemplateArgumentList TemplateArgLists;
-        TemplateArgLists.addOuterTemplateArguments(Converted);
-        InstantiateAttrsForDecl(TemplateArgLists,
-                                ClassTemplate->getTemplatedDecl(), Decl);
-      }
+    if (Decl->getSpecializationKind() == TSK_Undeclared) {
+      MultiLevelTemplateArgumentList TemplateArgLists;
+      TemplateArgLists.addOuterTemplateArguments(Converted);
+      InstantiateAttrsForDecl(TemplateArgLists, ClassTemplate->getTemplatedDecl(),
+                              Decl);
     }
 
     // Diagnose uses of this specialization.

diff  --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 7403d31c884a..6623e86765d1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -548,30 +548,12 @@ static void instantiateDependentAMDGPUWavesPerEUAttr(
   S.addAMDGPUWavesPerEUAttr(New, Attr, MinExpr, MaxExpr);
 }
 
-/// Determine whether the attribute A might be relevent to the declaration D.
-/// If not, we can skip instantiating it. The attribute may or may not have
-/// been instantiated yet.
-static bool isRelevantAttr(Sema &S, const Decl *D, const Attr *A) {
-  // Never instantiate preferred_name attributes; they're relevant only on the
-  // template.
-  if (const auto *PNA = dyn_cast<PreferredNameAttr>(A))
-    return false;
-
-  return true;
-}
-
 void Sema::InstantiateAttrsForDecl(
     const MultiLevelTemplateArgumentList &TemplateArgs, const Decl *Tmpl,
     Decl *New, LateInstantiatedAttrVec *LateAttrs,
     LocalInstantiationScope *OuterMostScope) {
   if (NamedDecl *ND = dyn_cast<NamedDecl>(New)) {
-    // FIXME: This function is called multiple times for the same template
-    // specialization. We should only instantiate attributes that were added
-    // since the previous instantiation.
     for (const auto *TmplAttr : Tmpl->attrs()) {
-      if (!isRelevantAttr(*this, New, TmplAttr))
-        continue;
-
       // FIXME: If any of the special case versions from InstantiateAttrs become
       // applicable to template declaration, we'll need to add them here.
       CXXThisScopeRAII ThisScope(
@@ -580,7 +562,7 @@ void Sema::InstantiateAttrsForDecl(
 
       Attr *NewAttr = sema::instantiateTemplateAttributeForDecl(
           TmplAttr, Context, *this, TemplateArgs);
-      if (NewAttr && isRelevantAttr(*this, New, NewAttr))
+      if (NewAttr)
         New->addAttr(NewAttr);
     }
   }
@@ -605,9 +587,6 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                             LateInstantiatedAttrVec *LateAttrs,
                             LocalInstantiationScope *OuterMostScope) {
   for (const auto *TmplAttr : Tmpl->attrs()) {
-    if (!isRelevantAttr(*this, New, TmplAttr))
-      continue;
-
     // FIXME: This should be generalized to more than just the AlignedAttr.
     const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr);
     if (Aligned && Aligned->isAlignmentDependent()) {
@@ -730,7 +709,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
 
       Attr *NewAttr = sema::instantiateTemplateAttribute(TmplAttr, Context,
                                                          *this, TemplateArgs);
-      if (NewAttr && isRelevantAttr(*this, New, TmplAttr))
+      if (NewAttr)
         New->addAttr(NewAttr);
     }
   }

diff  --git a/clang/test/PCH/decl-attrs.cpp b/clang/test/PCH/decl-attrs.cpp
deleted file mode 100644
index c89354d0c5de..000000000000
--- a/clang/test/PCH/decl-attrs.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-// RUN: %clang_cc1 -std=c++20 -emit-pch -o %t.a %s
-// RUN: %clang_cc1 -std=c++20 -include-pch %t.a %s -verify
-
-#ifndef HEADER
-#define HEADER
-
-namespace preferred_name {
-  template<typename T> struct X;
-  using Y = X<int>;
-  using Z = X<float>;
-  template<typename T> struct [[using clang: preferred_name(Y), preferred_name(Z)]] X {};
-  Y y;
-}
-
-#else
-
-namespace preferred_name {
-  Z z;
-
-  template<typename T> T forget(T t) { return t; }
-  void f() {
-    forget(y).foo(); // expected-error {{no member named 'foo' in 'preferred_name::Y'}}
-    forget(z).foo(); // expected-error {{no member named 'foo' in 'preferred_name::Z'}}
-  }
-}
-
-#endif

diff  --git a/clang/test/SemaTemplate/attributes.cpp b/clang/test/SemaTemplate/attributes.cpp
index 2411a2e831c9..7a04c4705bf2 100644
--- a/clang/test/SemaTemplate/attributes.cpp
+++ b/clang/test/SemaTemplate/attributes.cpp
@@ -63,63 +63,3 @@ namespace PR9049 {
 // CHECK:   AnnotateAttr {{.*}} "ANNOTATE_BAR"
 template<typename T> [[clang::annotate("ANNOTATE_FOO"), clang::annotate("ANNOTATE_BAR")]] void HasAnnotations();
 void UseAnnotations() { HasAnnotations<int>(); }
-
-namespace preferred_name {
-  int x [[clang::preferred_name("frank")]]; // expected-error {{expected a type}}
-  int y [[clang::preferred_name(int)]]; // expected-warning {{'preferred_name' attribute only applies to class templates}}
-  struct [[clang::preferred_name(int)]] A; // expected-warning {{'preferred_name' attribute only applies to class templates}}
-  template<typename T> struct [[clang::preferred_name(int)]] B; // expected-error {{argument 'int' to 'preferred_name' attribute is not a typedef for a specialization of 'B'}}
-  template<typename T> struct C;
-  using X = C<int>; // expected-note {{'X' declared here}}
-  typedef C<float> Y;
-  using Z = const C<double>; // expected-note {{'Z' declared here}}
-  template<typename T> struct [[clang::preferred_name(C<int>)]] C; // expected-error {{argument 'C<int>' to 'preferred_name' attribute is not a typedef for a specialization of 'C'}}
-  template<typename T> struct [[clang::preferred_name(X), clang::preferred_name(Y)]] C;
-  template<typename T> struct [[clang::preferred_name(const X)]] C; // expected-error {{argument 'const preferred_name::X'}}
-  template<typename T> struct [[clang::preferred_name(Z)]] C; // expected-error {{argument 'preferred_name::Z' (aka 'const C<double>')}}
-  template<typename T> struct C {};
-
-  // CHECK: ClassTemplateDecl {{.*}} <line:[[@LINE-10]]:{{.*}} C
-  // CHECK:   ClassTemplateSpecializationDecl {{.*}} struct C definition
-  // CHECK:     TemplateArgument type 'int'
-  // CHECK-NOT: PreferredNameAttr
-  // CHECK:     CXXRecordDecl
-  // CHECK:   ClassTemplateSpecializationDecl {{.*}} struct C definition
-  // CHECK:     TemplateArgument type 'float'
-  // CHECK-NOT: PreferredNameAttr
-  // CHECK:     CXXRecordDecl
-  // CHECK:   ClassTemplateSpecializationDecl {{.*}} struct C definition
-  // CHECK:     TemplateArgument type 'double'
-  // CHECK-NOT: PreferredNameAttr
-  // CHECK:     CXXRecordDecl
-
-  // Check this doesn't cause us to instantiate the same attribute multiple times.
-  C<float> *cf1;
-  C<float> *cf2;
-
-  void f(C<int> a, C<float> b, C<double> c) {
-    auto p = a;
-    auto q = b;
-    auto r = c;
-    p.f(); // expected-error {{no member named 'f' in 'preferred_name::X'}}
-    q.f(); // expected-error {{no member named 'f' in 'preferred_name::Y'}}
-    r.f(); // expected-error {{no member named 'f' in 'preferred_name::C<double>'}}
-  }
-
-  template<typename T> struct D;
-  using DInt = D<int>;
-  template<typename T> struct __attribute__((__preferred_name__(DInt))) D {};
-  template struct D<int>;
-  int use_dint = D<int>().get(); // expected-error {{no member named 'get' in 'preferred_name::DInt'}}
-
-  template<typename T> struct MemberTemplate {
-    template<typename U> struct Iter;
-    using iterator = Iter<T>;
-    using const_iterator = Iter<const T>;
-    template<typename U>
-    struct [[clang::preferred_name(iterator),
-             clang::preferred_name(const_iterator)]] Iter {};
-  };
-  auto it = MemberTemplate<int>::Iter<const int>();
-  int n = it; // expected-error {{no viable conversion from 'preferred_name::MemberTemplate<int>::Iter<const int>' to 'int'}}
-}

diff  --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp
index ec436df15e65..ec109e134e20 100644
--- a/clang/utils/TableGen/ClangAttrEmitter.cpp
+++ b/clang/utils/TableGen/ClangAttrEmitter.cpp
@@ -1149,9 +1149,8 @@ namespace {
          << "Unevaluated(S, Sema::ExpressionEvaluationContext::Unevaluated);\n";
       OS << "        ExprResult " << "Result = S.SubstExpr("
          << "A->get" << getUpperName() << "(), TemplateArgs);\n";
-      OS << "        if (Result.isInvalid())\n";
-      OS << "          return nullptr;\n";
-      OS << "        tempInst" << getUpperName() << " = Result.get();\n";
+      OS << "        tempInst" << getUpperName() << " = "
+         << "Result.getAs<Expr>();\n";
       OS << "      }\n";
     }
 
@@ -1203,9 +1202,7 @@ namespace {
          << "_end();\n";
       OS << "        for (; I != E; ++I, ++TI) {\n";
       OS << "          ExprResult Result = S.SubstExpr(*I, TemplateArgs);\n";
-      OS << "          if (Result.isInvalid())\n";
-      OS << "            return nullptr;\n";
-      OS << "          *TI = Result.get();\n";
+      OS << "          *TI = Result.getAs<Expr>();\n";
       OS << "        }\n";
       OS << "      }\n";
     }
@@ -1276,16 +1273,8 @@ namespace {
       OS << "      return false;\n";
     }
 
-    void writeTemplateInstantiation(raw_ostream &OS) const override {
-      OS << "      " << getType() << " tempInst" << getUpperName() << " =\n";
-      OS << "        S.SubstType(A->get" << getUpperName() << "Loc(), "
-         << "TemplateArgs, A->getLoc(), A->getAttrName());\n";
-      OS << "      if (!tempInst" << getUpperName() << ")\n";
-      OS << "        return nullptr;\n";
-    }
-
     void writeTemplateInstantiationArgs(raw_ostream &OS) const override {
-      OS << "tempInst" << getUpperName();
+      OS << "A->get" << getUpperName() << "Loc()";
     }
 
     void writePCHWrite(raw_ostream &OS) const override {
@@ -3330,13 +3319,12 @@ void EmitClangAttrTemplateInstantiateHelper(const std::vector<Record *> &Attrs,
     for (auto const &ai : Args)
       ai->writeTemplateInstantiation(OS);
 
-    OS << "      return new (C) " << R.getName() << "Attr(C, *A";
+    OS << "        return new (C) " << R.getName() << "Attr(C, *A";
     for (auto const &ai : Args) {
       OS << ", ";
       ai->writeTemplateInstantiationArgs(OS);
     }
-    OS << ");\n"
-       << "    }\n";
+    OS << ");\n    }\n";
   }
   OS << "  } // end switch\n"
      << "  llvm_unreachable(\"Unknown attribute!\");\n"

diff  --git a/libcxx/include/__config b/libcxx/include/__config
index 033cd8aea068..d2fdf6785c7e 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -1318,12 +1318,6 @@ _LIBCPP_FUNC_VIS extern "C" void __sanitizer_annotate_contiguous_container(
 #endif
 #endif // !defined(_LIBCPP_NODEBUG_TYPE)
 
-#if __has_attribute(__preferred_name__)
-#define _LIBCPP_PREFERRED_NAME(x) __attribute__((__preferred_name__(x)))
-#else
-#define _LIBCPP_PREFERRED_NAME(x)
-#endif
-
 #if defined(_LIBCPP_ABI_MICROSOFT) && \
     (defined(_LIBCPP_COMPILER_MSVC) || __has_declspec_attribute(empty_bases))
 #  define _LIBCPP_DECLSPEC_EMPTY_BASES __declspec(empty_bases)

diff  --git a/libcxx/include/iosfwd b/libcxx/include/iosfwd
index 0a0de99ff3a7..070fbe8bfad8 100644
--- a/libcxx/include/iosfwd
+++ b/libcxx/include/iosfwd
@@ -185,36 +185,6 @@ typedef basic_ifstream<wchar_t>      wifstream;
 typedef basic_ofstream<wchar_t>      wofstream;
 typedef basic_fstream<wchar_t>       wfstream;
 
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ios) _LIBCPP_PREFERRED_NAME(wios) basic_ios;
-
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_PREFERRED_NAME(wstreambuf) basic_streambuf;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(istream) _LIBCPP_PREFERRED_NAME(wistream) basic_istream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_PREFERRED_NAME(wostream) basic_ostream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_PREFERRED_NAME(wiostream) basic_iostream;
-
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(stringbuf) _LIBCPP_PREFERRED_NAME(wstringbuf) basic_stringbuf;
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(istringstream) _LIBCPP_PREFERRED_NAME(wistringstream) basic_istringstream;
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(ostringstream) _LIBCPP_PREFERRED_NAME(wostringstream) basic_ostringstream;
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(stringstream) _LIBCPP_PREFERRED_NAME(wstringstream) basic_stringstream;
-
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(filebuf) _LIBCPP_PREFERRED_NAME(wfilebuf) basic_filebuf;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ifstream) _LIBCPP_PREFERRED_NAME(wifstream) basic_ifstream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(ofstream) _LIBCPP_PREFERRED_NAME(wofstream) basic_ofstream;
-template <class _CharT, class _Traits>
-    class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_PREFERRED_NAME(wfstream) basic_fstream;
-
 template <class _State>             class _LIBCPP_TEMPLATE_VIS fpos;
 typedef fpos<mbstate_t>    streampos;
 typedef fpos<mbstate_t>    wstreampos;
@@ -240,8 +210,6 @@ template <class _CharT,             // for <stdexcept>
 typedef basic_string<char, char_traits<char>, allocator<char> > string;
 typedef basic_string<wchar_t, char_traits<wchar_t>, allocator<wchar_t> > wstring;
 
-template <class _CharT, class _Traits, class _Allocator>
-    class _LIBCPP_PREFERRED_NAME(string) _LIBCPP_PREFERRED_NAME(wstring) basic_string;
 
 // Include other forward declarations here
 template <class _Tp, class _Alloc = allocator<_Tp> >

diff  --git a/libcxx/include/regex b/libcxx/include/regex
index 8578039bf6a2..7c5b2fd61b93 100644
--- a/libcxx/include/regex
+++ b/libcxx/include/regex
@@ -2534,17 +2534,7 @@ __exit:
 template <class _CharT, class _Traits> class __lookahead;
 
 template <class _CharT, class _Traits = regex_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_regex;
-
-typedef basic_regex<char>    regex;
-typedef basic_regex<wchar_t> wregex;
-
-template <class _CharT, class _Traits>
-class
-    _LIBCPP_TEMPLATE_VIS
-    _LIBCPP_PREFERRED_NAME(regex)
-    _LIBCPP_PREFERRED_NAME(wregex)
-    basic_regex
+class _LIBCPP_TEMPLATE_VIS basic_regex
 {
 public:
     // types:
@@ -4889,21 +4879,13 @@ basic_regex<_CharT, _Traits>::__push_lookahead(const basic_regex& __exp,
     __end_ = static_cast<__owns_one_state<_CharT>*>(__end_->first());
 }
 
-// sub_match
+typedef basic_regex<char>    regex;
+typedef basic_regex<wchar_t> wregex;
 
-typedef sub_match<const char*>             csub_match;
-typedef sub_match<const wchar_t*>          wcsub_match;
-typedef sub_match<string::const_iterator>  ssub_match;
-typedef sub_match<wstring::const_iterator> wssub_match;
+// sub_match
 
 template <class _BidirectionalIterator>
-class
-    _LIBCPP_TEMPLATE_VIS
-    _LIBCPP_PREFERRED_NAME(csub_match)
-    _LIBCPP_PREFERRED_NAME(wcsub_match)
-    _LIBCPP_PREFERRED_NAME(ssub_match)
-    _LIBCPP_PREFERRED_NAME(wssub_match)
-    sub_match
+class _LIBCPP_TEMPLATE_VIS sub_match
     : public pair<_BidirectionalIterator, _BidirectionalIterator>
 {
 public:
@@ -4938,6 +4920,11 @@ public:
         {return str().compare(__s);}
 };
 
+typedef sub_match<const char*>             csub_match;
+typedef sub_match<const wchar_t*>          wcsub_match;
+typedef sub_match<string::const_iterator>  ssub_match;
+typedef sub_match<wstring::const_iterator> wssub_match;
+
 template <class _BiIter>
 inline _LIBCPP_INLINE_VISIBILITY
 bool
@@ -5320,19 +5307,8 @@ operator<<(basic_ostream<_CharT, _ST>& __os, const sub_match<_BiIter>& __m)
     return __os << __m.str();
 }
 
-typedef match_results<const char*>             cmatch;
-typedef match_results<const wchar_t*>          wcmatch;
-typedef match_results<string::const_iterator>  smatch;
-typedef match_results<wstring::const_iterator> wsmatch;
-
 template <class _BidirectionalIterator, class _Allocator>
-class
-    _LIBCPP_TEMPLATE_VIS
-    _LIBCPP_PREFERRED_NAME(cmatch)
-    _LIBCPP_PREFERRED_NAME(wcmatch)
-    _LIBCPP_PREFERRED_NAME(smatch)
-    _LIBCPP_PREFERRED_NAME(wsmatch)
-    match_results
+class _LIBCPP_TEMPLATE_VIS match_results
 {
 public:
     typedef _Allocator                                        allocator_type;
@@ -5652,6 +5628,11 @@ match_results<_BidirectionalIterator, _Allocator>::swap(match_results& __m)
     swap(__ready_, __m.__ready_);
 }
 
+typedef match_results<const char*>             cmatch;
+typedef match_results<const wchar_t*>          wcmatch;
+typedef match_results<string::const_iterator>  smatch;
+typedef match_results<wstring::const_iterator> wsmatch;
+
 template <class _BidirectionalIterator, class _Allocator>
 bool
 operator==(const match_results<_BidirectionalIterator, _Allocator>& __x,
@@ -6235,21 +6216,7 @@ regex_match(const basic_string<_CharT, _ST, _SA>& __s,
 template <class _BidirectionalIterator,
           class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
           class _Traits = regex_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS regex_iterator;
-
-typedef regex_iterator<const char*>             cregex_iterator;
-typedef regex_iterator<const wchar_t*>          wcregex_iterator;
-typedef regex_iterator<string::const_iterator>  sregex_iterator;
-typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
-
-template <class _BidirectionalIterator, class _CharT, class _Traits>
-class
-    _LIBCPP_TEMPLATE_VIS
-    _LIBCPP_PREFERRED_NAME(cregex_iterator)
-    _LIBCPP_PREFERRED_NAME(wcregex_iterator)
-    _LIBCPP_PREFERRED_NAME(sregex_iterator)
-    _LIBCPP_PREFERRED_NAME(wsregex_iterator)
-    regex_iterator
+class _LIBCPP_TEMPLATE_VIS regex_iterator
 {
 public:
     typedef basic_regex<_CharT, _Traits>          regex_type;
@@ -6358,26 +6325,17 @@ regex_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++()
     return *this;
 }
 
+typedef regex_iterator<const char*>             cregex_iterator;
+typedef regex_iterator<const wchar_t*>          wcregex_iterator;
+typedef regex_iterator<string::const_iterator>  sregex_iterator;
+typedef regex_iterator<wstring::const_iterator> wsregex_iterator;
+
 // regex_token_iterator
 
 template <class _BidirectionalIterator,
           class _CharT = typename iterator_traits<_BidirectionalIterator>::value_type,
           class _Traits = regex_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS regex_token_iterator;
-
-typedef regex_token_iterator<const char*>             cregex_token_iterator;
-typedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;
-typedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;
-typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
-
-template <class _BidirectionalIterator, class _CharT, class _Traits>
-class
-    _LIBCPP_TEMPLATE_VIS
-    _LIBCPP_PREFERRED_NAME(cregex_token_iterator)
-    _LIBCPP_PREFERRED_NAME(wcregex_token_iterator)
-    _LIBCPP_PREFERRED_NAME(sregex_token_iterator)
-    _LIBCPP_PREFERRED_NAME(wsregex_token_iterator)
-    regex_token_iterator
+class _LIBCPP_TEMPLATE_VIS regex_token_iterator
 {
 public:
     typedef basic_regex<_CharT, _Traits>      regex_type;
@@ -6655,6 +6613,11 @@ regex_token_iterator<_BidirectionalIterator, _CharT, _Traits>::operator++()
     return *this;
 }
 
+typedef regex_token_iterator<const char*>             cregex_token_iterator;
+typedef regex_token_iterator<const wchar_t*>          wcregex_token_iterator;
+typedef regex_token_iterator<string::const_iterator>  sregex_token_iterator;
+typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
+
 // regex_replace
 
 template <class _OutputIterator, class _BidirectionalIterator,

diff  --git a/libcxx/include/string b/libcxx/include/string
index b54fe2a93abd..1f3f444727fd 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -666,26 +666,8 @@ struct __padding<_CharT, 1>
 
 #endif  // _LIBCPP_ABI_ALTERNATE_STRING_LAYOUT
 
-#ifndef _LIBCPP_NO_HAS_CHAR8_T
-typedef basic_string<char8_t> u8string;
-#endif
-
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-typedef basic_string<char16_t> u16string;
-typedef basic_string<char32_t> u32string;
-#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
-
 template<class _CharT, class _Traits, class _Allocator>
-class
-    _LIBCPP_TEMPLATE_VIS
-#ifndef _LIBCPP_NO_HAS_CHAR8_T
-    _LIBCPP_PREFERRED_NAME(u8string)
-#endif
-#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
-    _LIBCPP_PREFERRED_NAME(u16string)
-    _LIBCPP_PREFERRED_NAME(u32string)
-#endif
-    basic_string
+class _LIBCPP_TEMPLATE_VIS basic_string
     : private __basic_string_common<true>
 {
 public:
@@ -4345,6 +4327,15 @@ swap(basic_string<_CharT, _Traits, _Allocator>& __lhs,
     __lhs.swap(__rhs);
 }
 
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+typedef basic_string<char8_t> u8string;
+#endif
+
+#ifndef _LIBCPP_HAS_NO_UNICODE_CHARS
+typedef basic_string<char16_t> u16string;
+typedef basic_string<char32_t> u32string;
+#endif  // _LIBCPP_HAS_NO_UNICODE_CHARS
+
 _LIBCPP_FUNC_VIS int                stoi  (const string& __str, size_t* __idx = nullptr, int __base = 10);
 _LIBCPP_FUNC_VIS long               stol  (const string& __str, size_t* __idx = nullptr, int __base = 10);
 _LIBCPP_FUNC_VIS unsigned long      stoul (const string& __str, size_t* __idx = nullptr, int __base = 10);

diff  --git a/libcxx/include/string_view b/libcxx/include/string_view
index 44ffb02c432d..7c3214fb2c2e 100644
--- a/libcxx/include/string_view
+++ b/libcxx/include/string_view
@@ -192,26 +192,7 @@ _LIBCPP_PUSH_MACROS
 _LIBCPP_BEGIN_NAMESPACE_STD
 
 template<class _CharT, class _Traits = char_traits<_CharT> >
-    class _LIBCPP_TEMPLATE_VIS basic_string_view;
-
-typedef basic_string_view<char>     string_view;
-#ifndef _LIBCPP_NO_HAS_CHAR8_T
-typedef basic_string_view<char8_t>  u8string_view;
-#endif
-typedef basic_string_view<char16_t> u16string_view;
-typedef basic_string_view<char32_t> u32string_view;
-typedef basic_string_view<wchar_t>  wstring_view;
-
-template<class _CharT, class _Traits>
-class
-    _LIBCPP_PREFERRED_NAME(string_view)
-#ifndef _LIBCPP_NO_HAS_CHAR8_T
-    _LIBCPP_PREFERRED_NAME(u8string_view)
-#endif
-    _LIBCPP_PREFERRED_NAME(u16string_view)
-    _LIBCPP_PREFERRED_NAME(u32string_view)
-    _LIBCPP_PREFERRED_NAME(wstring_view)
-    basic_string_view {
+class _LIBCPP_TEMPLATE_VIS basic_string_view {
 public:
     // types
     typedef _Traits                                    traits_type;
@@ -795,6 +776,14 @@ basic_ostream<_CharT, _Traits>&
 operator<<(basic_ostream<_CharT, _Traits>& __os,
            basic_string_view<_CharT, _Traits> __str);
 
+typedef basic_string_view<char>     string_view;
+#ifndef _LIBCPP_NO_HAS_CHAR8_T
+typedef basic_string_view<char8_t>  u8string_view;
+#endif
+typedef basic_string_view<char16_t> u16string_view;
+typedef basic_string_view<char32_t> u32string_view;
+typedef basic_string_view<wchar_t>  wstring_view;
+
 // [string.view.hash]
 template<class _CharT>
 struct _LIBCPP_TEMPLATE_VIS hash<basic_string_view<_CharT, char_traits<_CharT> > >


        


More information about the libcxx-commits mailing list