Skip to content

Commit 76d52ce

Browse files
committed
fixup! implement TagDecl::printName
1 parent e6d55c0 commit 76d52ce

File tree

23 files changed

+149
-135
lines changed

23 files changed

+149
-135
lines changed

clang-tools-extra/clangd/unittests/FindSymbolsTests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -656,15 +656,15 @@ TEST(DocumentSymbols, Enums) {
656656
getSymbols(TU.build()),
657657
ElementsAre(
658658
AllOf(withName("(anonymous enum)"), withDetail("enum"),
659-
children(AllOf(withName("Red"), withDetail("(unnamed)")))),
659+
children(AllOf(withName("Red"), withDetail("(unnamed enum)")))),
660660
AllOf(withName("Color"), withDetail("enum"),
661661
children(AllOf(withName("Green"), withDetail("Color")))),
662662
AllOf(withName("Color2"), withDetail("enum"),
663663
children(AllOf(withName("Yellow"), withDetail("Color2")))),
664664
AllOf(withName("ns"),
665665
children(AllOf(withName("(anonymous enum)"), withDetail("enum"),
666666
children(AllOf(withName("Black"),
667-
withDetail("(unnamed)"))))))));
667+
withDetail("(unnamed enum)"))))))));
668668
}
669669

670670
TEST(DocumentSymbols, Macro) {

clang-tools-extra/clangd/unittests/FindTargetTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1827,7 +1827,7 @@ TEST_F(FindExplicitReferencesTest, AllRefsInFoo) {
18271827
int (*$2^fptr)(int $3^a, int) = nullptr;
18281828
}
18291829
)cpp",
1830-
"0: targets = {(unnamed)}\n"
1830+
"0: targets = {(unnamed class)}\n"
18311831
"1: targets = {x}, decl\n"
18321832
"2: targets = {fptr}, decl\n"
18331833
"3: targets = {a}, decl\n"},

clang-tools-extra/clangd/unittests/HoverTests.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2103,7 +2103,7 @@ TEST(Hover, All) {
21032103
HI.NamespaceScope = "";
21042104
// FIXME: This should be `(anon enum)::`
21052105
HI.LocalScope = "";
2106-
HI.Type = "enum (unnamed)";
2106+
HI.Type = "enum (unnamed enum)";
21072107
HI.Definition = "ONE";
21082108
HI.Value = "0";
21092109
}},

clang/include/clang/AST/Decl.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3771,6 +3771,9 @@ class TagDecl : public TypeDecl,
37713771
/// True if this decl is currently being defined.
37723772
void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; }
37733773

3774+
void printAnonymousTagDecl(llvm::raw_ostream &OS,
3775+
const PrintingPolicy &Policy) const;
3776+
37743777
public:
37753778
friend class ASTDeclReader;
37763779
friend class ASTDeclWriter;

clang/include/clang/AST/PrettyPrinter.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ struct PrintingPolicy {
6060
/// Create a default printing policy for the specified language.
6161
PrintingPolicy(const LangOptions &LO)
6262
: Indentation(2), SuppressSpecifiers(false),
63-
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
64-
SuppressScope(false), SuppressUnwrittenScope(false),
63+
SuppressTagKeyword(LO.CPlusPlus),
64+
SuppressTagKeywordInAnonymousTagNames(false),
65+
IncludeTagDefinition(false), SuppressScope(false),
66+
SuppressUnwrittenScope(false),
6567
SuppressInlineNamespace(SuppressInlineNamespaceMode::Redundant),
6668
SuppressInitializers(false), ConstantArraySizeAsWritten(false),
6769
AnonymousTagLocations(true), SuppressStrongLifetime(false),
@@ -121,6 +123,7 @@ struct PrintingPolicy {
121123
/// \endcode
122124
LLVM_PREFERRED_TYPE(bool)
123125
unsigned SuppressTagKeyword : 1;
126+
unsigned SuppressTagKeywordInAnonymousTagNames : 1;
124127

125128
/// When true, include the body of a tag definition.
126129
///

clang/include/clang/AST/TypeBase.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7374,10 +7374,6 @@ bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
73747374
ArrayRef<TemplateArgument> Args,
73757375
unsigned Depth);
73767376

7377-
void printAnonymousTagDecl(llvm::raw_ostream &OS, const TagDecl *D,
7378-
const PrintingPolicy &Policy,
7379-
bool PrintKindDecoration, bool PrintTagLocations);
7380-
73817377
/// Represents a qualified type name for which the type name is
73827378
/// dependent.
73837379
///

clang/lib/AST/Decl.cpp

Lines changed: 74 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
49605022
void 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
}

clang/lib/AST/TypePrinter.cpp

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1519,18 +1519,19 @@ void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
15191519
return;
15201520
}
15211521

1522-
bool PrintKindDecoration = Policy.AnonymousTagLocations;
1523-
1522+
bool PrintedKindDecoration = false;
15241523
if (T->isCanonicalUnqualified()) {
15251524
if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
1526-
PrintKindDecoration = false;
1525+
PrintedKindDecoration = true;
15271526
OS << D->getKindName();
15281527
OS << ' ';
15291528
}
15301529
} else {
15311530
OS << TypeWithKeyword::getKeywordName(T->getKeyword());
1532-
if (T->getKeyword() != ElaboratedTypeKeyword::None)
1531+
if (T->getKeyword() != ElaboratedTypeKeyword::None) {
1532+
PrintedKindDecoration = true;
15331533
OS << ' ';
1534+
}
15341535
}
15351536

15361537
if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
@@ -1544,13 +1545,17 @@ void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
15441545

15451546
if (const IdentifierInfo *II = D->getIdentifier())
15461547
OS << II->getName();
1547-
else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {
1548-
assert(Typedef->getIdentifier() && "Typedef without identifier?");
1549-
OS << Typedef->getIdentifier()->getName();
1550-
} else
1551-
printAnonymousTagDecl(OS, D, Policy,
1552-
/*PrintKindDecoration=*/PrintKindDecoration,
1553-
/*PrintTagLocations=*/Policy.AnonymousTagLocations);
1548+
else {
1549+
clang::PrintingPolicy Copy(Policy);
1550+
1551+
// Suppress the redundant tag keyword if we just printed one.
1552+
if (PrintedKindDecoration) {
1553+
Copy.SuppressTagKeywordInAnonymousTagNames = true;
1554+
Copy.SuppressTagKeyword = true;
1555+
}
1556+
1557+
D->printName(OS, Copy);
1558+
}
15541559

15551560
// If this is a class template specialization, print the template
15561561
// arguments.
@@ -2429,58 +2434,6 @@ static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg,
24292434
return false;
24302435
}
24312436

2432-
void clang::printAnonymousTagDecl(llvm::raw_ostream &OS, const TagDecl *D,
2433-
const PrintingPolicy &Policy,
2434-
bool PrintKindDecoration,
2435-
bool PrintTagLocations) {
2436-
assert(D);
2437-
2438-
// Make an unambiguous representation for anonymous types, e.g.
2439-
// (anonymous enum at /usr/include/string.h:120:9)
2440-
OS << (Policy.MSVCFormatting ? '`' : '(');
2441-
2442-
if (isa<CXXRecordDecl>(D) && cast<CXXRecordDecl>(D)->isLambda()) {
2443-
PrintKindDecoration = false;
2444-
OS << "lambda";
2445-
} else if ((isa<RecordDecl>(D) &&
2446-
cast<RecordDecl>(D)->isAnonymousStructOrUnion())) {
2447-
OS << "anonymous";
2448-
} else {
2449-
OS << "unnamed";
2450-
}
2451-
2452-
// Suppress the redundant tag keyword if we just printed one.
2453-
// We don't have to worry about ElaboratedTypes here because you can't
2454-
// refer to an anonymous type with one.
2455-
if (PrintKindDecoration)
2456-
OS << " " << D->getKindName();
2457-
2458-
if (PrintTagLocations) {
2459-
PresumedLoc PLoc =
2460-
D->getASTContext().getSourceManager().getPresumedLoc(D->getLocation());
2461-
if (PLoc.isValid()) {
2462-
OS << " at ";
2463-
StringRef File = PLoc.getFilename();
2464-
llvm::SmallString<1024> WrittenFile(File);
2465-
if (auto *Callbacks = Policy.Callbacks)
2466-
WrittenFile = Callbacks->remapPath(File);
2467-
// Fix inconsistent path separator created by
2468-
// clang::DirectoryLookup::LookupFile when the file path is relative
2469-
// path.
2470-
llvm::sys::path::Style Style =
2471-
llvm::sys::path::is_absolute(WrittenFile)
2472-
? llvm::sys::path::Style::native
2473-
: (Policy.MSVCFormatting
2474-
? llvm::sys::path::Style::windows_backslash
2475-
: llvm::sys::path::Style::posix);
2476-
llvm::sys::path::native(WrittenFile, Style);
2477-
OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();
2478-
}
2479-
}
2480-
2481-
OS << (Policy.MSVCFormatting ? '\'' : ')');
2482-
}
2483-
24842437
bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
24852438
const NamedDecl *Param,
24862439
ArrayRef<TemplateArgument> Args,

clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,9 @@ static StringRef getNodeName(const RecordDecl &Node,
518518

519519
llvm::raw_svector_ostream OS(Scratch);
520520

521-
printAnonymousTagDecl(
522-
OS, llvm::cast<TagDecl>(&Node), Node.getASTContext().getPrintingPolicy(),
523-
/*PrintKindDecoration=*/true, /*PrintTagLocations=*/false);
521+
PrintingPolicy Copy(Node.getASTContext().getPrintingPolicy());
522+
Copy.AnonymousTagLocations = false;
523+
Node.printName(OS, Copy);
524524

525525
return OS.str();
526526
}

clang/test/AST/HLSL/cbuffer.hlsl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,15 @@ cbuffer CB {
191191
// CHECK: FieldDecl {{.*}} f 'RWBuffer<float>':'hlsl::RWBuffer<float>'
192192
RWBuffer<float> f;
193193
} s9;
194-
// CHECK: VarDecl {{.*}} s9 'hlsl_constant struct (unnamed struct at {{.*}}cbuffer.hlsl:[[# @LINE - 8]]:3
194+
// CHECK: VarDecl {{.*}} s9 'hlsl_constant struct (unnamed at {{.*}}cbuffer.hlsl:[[# @LINE - 8]]:3
195195
// CHECK: CXXRecordDecl {{.*}} struct definition
196196
struct {
197197
// CHECK: FieldDecl {{.*}} g 'float'
198198
float g;
199199
// CHECK: FieldDecl {{.*}} f 'RWBuffer<float>':'hlsl::RWBuffer<float>'
200200
RWBuffer<float> f;
201201
} s10;
202-
// CHECK: VarDecl {{.*}} s10 'hlsl_constant struct (unnamed struct at {{.*}}cbuffer.hlsl:[[# @LINE - 6]]:3
202+
// CHECK: VarDecl {{.*}} s10 'hlsl_constant struct (unnamed at {{.*}}cbuffer.hlsl:[[# @LINE - 6]]:3
203203
// CHECK: CXXRecordDecl {{.*}} implicit referenced struct __cblayout_anon definition
204204
// CHECK: PackedAttr
205205
// CHECK-NEXT: FieldDecl {{.*}} e 'float'

0 commit comments

Comments
 (0)