@@ -1790,15 +1790,17 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
17901790 }
17911791 else
17921792 OS << *ND;
1793- } else if (const auto *RD = dyn_cast<RecordDecl>(DC)) {
1794- if (TypedefNameDecl *TD = RD->getTypedefNameForAnonDecl ())
1795- OS << *TD;
1796- else if (!RD->getIdentifier ())
1797- printAnonymousTagDecl (OS, llvm::cast<TagDecl>(RD), P,
1798- /* PrintKindDecoration=*/ true ,
1799- /* AllowSourceLocations=*/ false );
1800- else
1801- OS << *RD;
1793+ } else if (const auto *RD = llvm::dyn_cast<RecordDecl>(DC)) {
1794+ PrintingPolicy Copy (P);
1795+ // As part of a scope we want to print anonymous names as:
1796+ // ..::(anonymous struct)::..
1797+ //
1798+ // I.e., suppress tag locations, suppress leading keyword, *don't*
1799+ // suppress tag in name
1800+ Copy.SuppressTagKeyword = true ;
1801+ Copy.SuppressTagKeywordInAnonymousTagNames = false ;
1802+ Copy.AnonymousTagLocations = false ;
1803+ RD->printName (OS, Copy);
18021804 } else if (const auto *FD = dyn_cast<FunctionDecl>(DC)) {
18031805 const FunctionProtoType *FT = nullptr ;
18041806 if (FD->hasWrittenPrototype ())
@@ -4957,19 +4959,76 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
49574959 }
49584960}
49594961
4962+ void TagDecl::printAnonymousTagDecl (llvm::raw_ostream &OS,
4963+ const PrintingPolicy &Policy) const {
4964+ if (TypedefNameDecl *Typedef = getTypedefNameForAnonDecl ()) {
4965+ assert (Typedef->getIdentifier () && " Typedef without identifier?" );
4966+ OS << Typedef->getIdentifier ()->getName ();
4967+ return ;
4968+ }
4969+
4970+ bool SuppressTagKeywordInName = Policy.SuppressTagKeywordInAnonymousTagNames ;
4971+
4972+ // Emit leading keyword. Since we printed a leading keyword make sure we
4973+ // don't print the tag as part of the name too.
4974+ if (!Policy.SuppressTagKeyword ) {
4975+ OS << getKindName () << ' ' ;
4976+ SuppressTagKeywordInName = true ;
4977+ }
4978+
4979+ // Make an unambiguous representation for anonymous types, e.g.
4980+ // (anonymous enum at /usr/include/string.h:120:9)
4981+ OS << (Policy.MSVCFormatting ? ' `' : ' (' );
4982+
4983+ if (isa<CXXRecordDecl>(this ) && cast<CXXRecordDecl>(this )->isLambda ()) {
4984+ OS << " lambda" ;
4985+ SuppressTagKeywordInName = true ;
4986+ } else if ((isa<RecordDecl>(this ) &&
4987+ cast<RecordDecl>(this )->isAnonymousStructOrUnion ())) {
4988+ OS << " anonymous" ;
4989+ } else {
4990+ OS << " unnamed" ;
4991+ }
4992+
4993+ if (!SuppressTagKeywordInName)
4994+ OS << ' ' << getKindName ();
4995+
4996+ if (Policy.AnonymousTagLocations ) {
4997+ PresumedLoc PLoc =
4998+ getASTContext ().getSourceManager ().getPresumedLoc (getLocation ());
4999+ if (PLoc.isValid ()) {
5000+ OS << " at " ;
5001+ StringRef File = PLoc.getFilename ();
5002+ llvm::SmallString<1024 > WrittenFile (File);
5003+ if (auto *Callbacks = Policy.Callbacks )
5004+ WrittenFile = Callbacks->remapPath (File);
5005+ // Fix inconsistent path separator created by
5006+ // clang::DirectoryLookup::LookupFile when the file path is relative
5007+ // path.
5008+ llvm::sys::path::Style Style =
5009+ llvm::sys::path::is_absolute (WrittenFile)
5010+ ? llvm::sys::path::Style::native
5011+ : (Policy.MSVCFormatting
5012+ ? llvm::sys::path::Style::windows_backslash
5013+ : llvm::sys::path::Style::posix);
5014+ llvm::sys::path::native (WrittenFile, Style);
5015+ OS << WrittenFile << ' :' << PLoc.getLine () << ' :' << PLoc.getColumn ();
5016+ }
5017+ }
5018+
5019+ OS << (Policy.MSVCFormatting ? ' \' ' : ' )' );
5020+ }
5021+
49605022void TagDecl::printName (raw_ostream &OS, const PrintingPolicy &Policy) const {
49615023 DeclarationName Name = getDeclName ();
49625024 // If the name is supposed to have an identifier but does not have one, then
49635025 // the tag is anonymous and we should print it differently.
49645026 if (Name.isIdentifier () && !Name.getAsIdentifierInfo ()) {
4965- // If the caller wanted to print a qualified name, they've already printed
4966- // the scope. And if the caller doesn't want that, the scope information
4967- // is already printed as part of the type.
4968- PrintingPolicy Copy (Policy);
4969- Copy.SuppressScope = true ;
4970- QualType (getASTContext ().getCanonicalTagType (this )).print (OS, Copy);
5027+ printAnonymousTagDecl (OS, Policy);
5028+
49715029 return ;
49725030 }
5031+
49735032 // Otherwise, do the normal printing.
49745033 Name.print (OS, Policy);
49755034}
0 commit comments