<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>