<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 18, 2016 at 6:39 PM, Richard Smith via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">Author: rsmith<br>
Date: Wed May 18 20:39:10 2016<br>
New Revision: 270009<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=270009&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=270009&view=rev</a><br>
Log:<br>
Make Sema::getPrintingPolicy less ridiculously expensive. This used to perform<br>
an identifier table lookup, *and* copy the LangOptions (including various<br>
std::vector<std::string>s). Twice. We call this function once each time we start<br>
parsing a declaration specifier sequence, and once for each call to Sema::Diag.<br>
<br>
This reduces the compile time for a sample .c file from the linux kernel by 20%.<br>
<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTContext.h<br>
    cfe/trunk/include/clang/AST/PrettyPrinter.h<br>
    cfe/trunk/lib/AST/DeclarationName.cpp<br>
    cfe/trunk/lib/AST/StmtPrinter.cpp<br>
    cfe/trunk/lib/AST/TypePrinter.cpp<br>
    cfe/trunk/lib/Parse/ParseDecl.cpp<br>
    cfe/trunk/lib/Sema/Sema.cpp<br>
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
    cfe/trunk/test/Analysis/initializers-cfg-output.cpp<br>
    cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp<br>
    cfe/trunk/test/SemaCXX/member-pointer.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTContext.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed May 18 20:39:10 2016<br>
@@ -243,6 +243,9 @@ class ASTContext : public RefCountedBase<br>
   QualType ObjCClassRedefinitionType;<br>
   QualType ObjCSelRedefinitionType;<br>
<br>
+  /// The identifier 'bool'.<br>
+  mutable IdentifierInfo *BoolName = nullptr;<br>
+<br>
   /// The identifier 'NSObject'.<br>
   IdentifierInfo *NSObjectName = nullptr;<br>
<br>
@@ -1457,6 +1460,13 @@ public:<br>
     return NSCopyingName;<br>
   }<br>
<br>
+  /// Retrieve the identifier 'bool'.<br>
+  IdentifierInfo *getBoolName() const {<br>
+    if (!BoolName)<br>
+      BoolName = &Idents.get("bool");<br>
+    return BoolName;<br>
+  }<br>
+<br>
   IdentifierInfo *getMakeIntegerSeqName() const {<br>
     if (!MakeIntegerSeqName)<br>
       MakeIntegerSeqName = &Idents.get("__make_integer_seq");<br>
<br>
Modified: cfe/trunk/include/clang/AST/PrettyPrinter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/PrettyPrinter.h?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/PrettyPrinter.h (original)<br>
+++ cfe/trunk/include/clang/AST/PrettyPrinter.h Wed May 18 20:39:10 2016<br>
@@ -32,22 +32,35 @@ public:<br>
<br>
 /// \brief Describes how types, statements, expressions, and<br>
 /// declarations should be printed.<br>
+///<br>
+/// This type is intended to be small and suitable for passing by value.<br>
+/// It is very frequently copied.<br>
 struct PrintingPolicy {<br>
-  /// \brief Create a default printing policy for C.<br>
+  /// \brief Create a default printing policy for the specified language.<br>
   PrintingPolicy(const LangOptions &LO)<br>
-    : LangOpts(LO), Indentation(2), SuppressSpecifiers(false),<br>
-      SuppressTagKeyword(false),<br>
+    : Indentation(2), SuppressSpecifiers(false),<br>
+      SuppressTagKeyword(LO.CPlusPlus),<br>
       IncludeTagDefinition(false), SuppressScope(false),<br>
       SuppressUnwrittenScope(false), SuppressInitializers(false),<br>
       ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),<br>
       SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),<br>
       SuppressTemplateArgsInCXXConstructors(false),<br>
-      Bool(LO.Bool), TerseOutput(false), PolishForDeclaration(false),<br>
+      Bool(LO.Bool), Restrict(LO.C99),<br>
+      Alignof(LO.CPlusPlus11), UnderscoreAlignof(LO.C11),<br>
+      UseVoidForZeroParams(!LO.CPlusPlus),<br>
+      TerseOutput(false), PolishForDeclaration(false),<br>
       Half(LO.Half), MSWChar(LO.MicrosoftExt && !LO.WChar),<br>
       IncludeNewlines(true), MSVCFormatting(false) { }<br>
<br>
-  /// \brief What language we're printing.<br>
-  LangOptions LangOpts;<br>
+  /// \brief Adjust this printing policy for cases where it's known that<br>
+  /// we're printing C++ code (for instance, if AST dumping reaches a<br>
+  /// C++-only construct). This should not be used if a real LangOptions<br>
+  /// object is available.<br>
+  void adjustForCPlusPlus() {<br>
+    SuppressTagKeyword = true;<br>
+    Bool = true;<br>
+    UseVoidForZeroParams = false;<br>
+  }<br>
<br>
   /// \brief The number of spaces to use to indent each line.<br>
   unsigned Indentation : 8;<br>
@@ -143,10 +156,23 @@ struct PrintingPolicy {<br>
   /// constructors.<br>
   unsigned SuppressTemplateArgsInCXXConstructors : 1;<br>
<br>
-  /// \brief Whether we can use 'bool' rather than '_Bool', even if the language<br>
-  /// doesn't actually have 'bool' (because, e.g., it is defined as a macro).<br>
+  /// \brief Whether we can use 'bool' rather than '_Bool' (even if the language<br>
+  /// doesn't actually have 'bool', because, e.g., it is defined as a macro).<br>
   unsigned Bool : 1;<br>
<br>
+  /// \brief Whether we can use 'restrict' rather than '__restrict'.<br>
+  unsigned Restrict : 1;<br>
+<br>
+  /// \brief Whether we can use 'alignof' rather than '__alignof'.<br>
+  unsigned Alignof : 1;<br>
+<br>
+  /// \brief Whether we can use '_Alignof' rather than '__alignof'.<br>
+  unsigned UnderscoreAlignof : 1;<br>
+<br>
+  /// \brief Whether we should use '(void)' rather than '()' for a function<br>
+  /// prototype with zero parameters.<br>
+  unsigned UseVoidForZeroParams : 1;<br>
+<br>
   /// \brief Provide a 'terse' output.<br>
   ///<br>
   /// For example, in this mode we don't print function bodies, class members,<br>
<br>
Modified: cfe/trunk/lib/AST/DeclarationName.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclarationName.cpp Wed May 18 20:39:10 2016<br>
@@ -135,7 +135,10 @@ int DeclarationName::compare(Declaration<br>
<br>
 static void printCXXConstructorDestructorName(QualType ClassType,<br>
                                               raw_ostream &OS,<br>
-                                              const PrintingPolicy &Policy) {<br>
+                                              PrintingPolicy Policy) {<br>
+  // We know we're printing C++ here. Ensure we print types properly.<br>
+  Policy.adjustForCPlusPlus();<br>
+<br>
   if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {<br>
     OS << *ClassRec->getDecl();<br>
     return;<br>
@@ -146,14 +149,7 @@ static void printCXXConstructorDestructo<br>
       return;<br>
     }<br>
   }<br>
-  if (!Policy.LangOpts.CPlusPlus) {<br>
-    // Passed policy is the default one from operator <<, use a C++ policy.<br>
-    LangOptions LO;<br>
-    LO.CPlusPlus = true;<br>
-    ClassType.print(OS, PrintingPolicy(LO));<br>
-  } else {<br>
-    ClassType.print(OS, Policy);<br>
-  }<br>
+  ClassType.print(OS, Policy);<br>
 }<br>
<br>
 void DeclarationName::print(raw_ostream &OS, const PrintingPolicy &Policy) {<br>
@@ -206,15 +202,10 @@ void DeclarationName::print(raw_ostream<br>
       OS << *Rec->getDecl();<br>
       return;<br>
     }<br>
-    if (!Policy.LangOpts.CPlusPlus) {<br>
-      // Passed policy is the default one from operator <<, use a C++ policy.<br>
-      LangOptions LO;<br>
-      LO.CPlusPlus = true;<br>
-      LO.Bool = true;<br>
-      Type.print(OS, PrintingPolicy(LO));<br>
-    } else {<br>
-      Type.print(OS, Policy);<br>
-    }<br>
+    // We know we're printing C++ here, ensure we print 'bool' properly.<br>
+    PrintingPolicy CXXPolicy = Policy;<br>
+    CXXPolicy.adjustForCPlusPlus();<br>
+    Type.print(OS, CXXPolicy);<br>
     return;<br>
   }<br>
   case DeclarationName::CXXUsingDirective:<br>
<br>
Modified: cfe/trunk/lib/AST/StmtPrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Wed May 18 20:39:10 2016<br>
@@ -1397,9 +1397,9 @@ void StmtPrinter::VisitUnaryExprOrTypeTr<br>
     OS << "sizeof";<br>
     break;<br>
   case UETT_AlignOf:<br>
-    if (Policy.LangOpts.CPlusPlus)<br>
+    if (Policy.Alignof)<br>
       OS << "alignof";<br>
-    else if (Policy.LangOpts.C11)<br>
+    else if (Policy.UnderscoreAlignof)<br>
       OS << "_Alignof";<br>
     else<br>
       OS << "__alignof";<br>
@@ -1669,7 +1669,7 @@ void StmtPrinter::VisitNoInitExpr(NoInit<br>
 }<br>
<br>
 void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {<br>
-  if (Policy.LangOpts.CPlusPlus) {<br>
+  if (Node->getType()->getAsCXXRecordDecl()) {<br>
     OS << "/*implicit*/";<br>
     Node->getType().print(OS, Policy);<br>
     OS << "()";<br>
<br>
Modified: cfe/trunk/lib/AST/TypePrinter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/TypePrinter.cpp (original)<br>
+++ cfe/trunk/lib/AST/TypePrinter.cpp Wed May 18 20:39:10 2016<br>
@@ -112,7 +112,8 @@ namespace {<br>
   };<br>
 }<br>
<br>
-static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool C99) {<br>
+static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals,<br>
+                               bool HasRestrictKeyword) {<br>
   bool appendSpace = false;<br>
   if (TypeQuals & Qualifiers::Const) {<br>
     OS << "const";<br>
@@ -125,7 +126,7 @@ static void AppendTypeQualList(raw_ostre<br>
   }<br>
   if (TypeQuals & Qualifiers::Restrict) {<br>
     if (appendSpace) OS << ' ';<br>
-    if (C99) {<br>
+    if (HasRestrictKeyword) {<br>
       OS << "restrict";<br>
     } else {<br>
       OS << "__restrict";<br>
@@ -439,7 +440,8 @@ void TypePrinter::printConstantArrayAfte<br>
                                           raw_ostream &OS) {<br>
   OS << '[';<br>
   if (T->getIndexTypeQualifiers().hasQualifiers()) {<br>
-    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99);<br>
+    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(),<br>
+                       Policy.Restrict);<br>
     OS << ' ';<br>
   }<br>
<br>
@@ -472,7 +474,7 @@ void TypePrinter::printVariableArrayAfte<br>
                                           raw_ostream &OS) {<br>
   OS << '[';<br>
   if (T->getIndexTypeQualifiers().hasQualifiers()) {<br>
-    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.LangOpts.C99);<br>
+    AppendTypeQualList(OS, T->getIndexTypeCVRQualifiers(), Policy.Restrict);<br>
     OS << ' ';<br>
   }<br>
<br>
@@ -672,7 +674,7 @@ void TypePrinter::printFunctionProtoAfte<br>
     if (T->getNumParams())<br>
       OS << ", ";<br>
     OS << "...";<br>
-  } else if (T->getNumParams() == 0 && !Policy.LangOpts.CPlusPlus) {<br>
+  } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {<br>
     // Do not emit int() if we have a proto, emit 'int(void)'.<br>
     OS << "void";<br>
   }<br>
@@ -746,7 +748,7 @@ void TypePrinter::printFunctionProtoAfte<br>
<br>
   if (unsigned quals = T->getTypeQuals()) {<br>
     OS << ' ';<br>
-    AppendTypeQualList(OS, quals, Policy.LangOpts.C99);<br>
+    AppendTypeQualList(OS, quals, Policy.Restrict);<br>
   }<br>
<br>
   switch (T->getRefQualifier()) {<br>
@@ -947,13 +949,9 @@ void TypePrinter::printTag(TagDecl *D, r<br>
<br>
   bool HasKindDecoration = false;<br>
<br>
-  // bool SuppressTagKeyword<br>
-  //   = Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword;<br>
-<br>
   // We don't print tags unless this is an elaborated type.<br>
   // In C, we just assume every RecordType is an elaborated type.<br>
-  if (!(Policy.LangOpts.CPlusPlus || Policy.SuppressTagKeyword ||<br>
-        D->getTypedefNameForAnonDecl())) {<br>
+  if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {<br>
     HasKindDecoration = true;<br>
     OS << D->getKindName();<br>
     OS << ' ';<br>
@@ -1590,7 +1588,7 @@ void Qualifiers::print(raw_ostream &OS,<br>
<br>
   unsigned quals = getCVRQualifiers();<br>
   if (quals) {<br>
-    AppendTypeQualList(OS, quals, Policy.LangOpts.C99);<br>
+    AppendTypeQualList(OS, quals, Policy.Restrict);<br>
     addSpace = true;<br>
   }<br>
   if (hasUnaligned()) {<br>
<br>
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)<br>
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Wed May 18 20:39:10 2016<br>
@@ -2661,7 +2661,7 @@ void Parser::ParseDeclarationSpecifiers(<br>
   bool AttrsLastTime = false;<br>
   ParsedAttributesWithRange attrs(AttrFactory);<br>
   // We use Sema's policy to get bool macros right.<br>
-  const PrintingPolicy &Policy = Actions.getPrintingPolicy();<br>
+  PrintingPolicy Policy = Actions.getPrintingPolicy();<br>
   while (1) {<br>
     bool isInvalid = false;<br>
     bool isStorageClass = false;<br>
<br>
Modified: cfe/trunk/lib/Sema/Sema.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/Sema.cpp (original)<br>
+++ cfe/trunk/lib/Sema/Sema.cpp Wed May 18 20:39:10 2016<br>
@@ -52,13 +52,14 @@ ModuleLoader &Sema::getModuleLoader() co<br>
 PrintingPolicy Sema::getPrintingPolicy(const ASTContext &Context,<br>
                                        const Preprocessor &PP) {<br>
   PrintingPolicy Policy = Context.getPrintingPolicy();<br>
+  // Our printing policy is copied over the ASTContext printing policy whenever<br>
+  // a diagnostic is emitted, so recompute it.<br>
   Policy.Bool = Context.getLangOpts().Bool;<br>
   if (!Policy.Bool) {<br>
-    if (const MacroInfo *<br>
-          BoolMacro = PP.getMacroInfo(&Context.Idents.get("bool"))) {<br>
+    if (const MacroInfo *BoolMacro = PP.getMacroInfo(Context.getBoolName())) {<br>
       Policy.Bool = BoolMacro->isObjectLike() &&<br>
-        BoolMacro->getNumTokens() == 1 &&<br>
-        BoolMacro->getReplacementToken(0).is(tok::kw__Bool);<br>
+                    BoolMacro->getNumTokens() == 1 &&<br>
+                    BoolMacro->getReplacementToken(0).is(tok::kw__Bool);<br>
     }<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Wed May 18 20:39:10 2016<br>
@@ -1517,7 +1517,6 @@ static void AddOrdinaryNameResults(Sema:<br>
                                    ResultBuilder &Results) {<br>
   CodeCompletionAllocator &Allocator = Results.getAllocator();<br>
   CodeCompletionBuilder Builder(Allocator, Results.getCodeCompletionTUInfo());<br>
-  PrintingPolicy Policy = getCompletionPrintingPolicy(SemaRef);<br>
<br>
   typedef CodeCompletionResult Result;<br>
   switch (CCC) {<br>
<br>
Modified: cfe/trunk/test/Analysis/initializers-cfg-output.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initializers-cfg-output.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/initializers-cfg-output.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Analysis/initializers-cfg-output.cpp (original)<br>
+++ cfe/trunk/test/Analysis/initializers-cfg-output.cpp Wed May 18 20:39:10 2016<br>
@@ -61,7 +61,7 @@ class TestDelegating {<br>
 // CHECK:    6: B([B1.5]) (Base initializer)<br>
 // CHECK:    7:  (CXXConstructExpr, class A)<br>
 // CHECK:    8: A([B1.7]) (Base initializer)<br>
-// CHECK:    9: /*implicit*/int()<br>
+// CHECK:    9: /*implicit*/(int)0<br>
 // CHECK:   10: i([B1.9]) (Member initializer)<br>
 // CHECK:   11: this<br>
 // CHECK:   12: [B1.11]->i<br>
<br>
Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)<br>
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Wed May 18 20:39:10 2016<br>
@@ -1077,7 +1077,7 @@ int testConsistencyNestedNormalReturn(bo<br>
 // CHECK:    14: a([B1.13]) (Member initializer)<br>
 // CHECK:    15: ~B() (Temporary object destructor)<br>
 // CHECK:    16: ~A() (Temporary object destructor)<br>
-// CHECK:    17: /*implicit*/int()<br>
+// CHECK:    17: /*implicit*/(int)0<br>
 // CHECK:    18: b([B1.17]) (Member initializer)<br>
 // CHECK:     Preds (1): B2<br>
 // CHECK:     Succs (1): B0<br>
<br>
Modified: cfe/trunk/test/SemaCXX/member-pointer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-pointer.cpp?rev=270009&r1=270008&r2=270009&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/member-pointer.cpp?rev=270009&r1=270008&r2=270009&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/SemaCXX/member-pointer.cpp (original)<br>
+++ cfe/trunk/test/SemaCXX/member-pointer.cpp Wed May 18 20:39:10 2016<br>
@@ -323,3 +323,12 @@ namespace test8 {<br>
              .**(int A::**) 0; // expected-warning {{indirection of non-volatile null pointer will be deleted}} expected-note {{consider}}<br>
   }<br>
 }<br>
+<br>
+namespace PR27558 {<br>
+  template<typename Args> struct A { void f(); };<br>
+  template<typename Args> struct B : A<Args> {<br>
+    using A<Args>::f;<br>
+    B() { (void)&B<Args>::f; }<br>
+  };<br>
+  B<int> b;<br>
+}<br></blockquote><div><br></div><div>Was this PR27558 test case intentional?</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>