Skip to content

Commit 3fe5af6

Browse files
Merge from 'master' to 'sycl-web' (#1)
CONFLICT (content): Merge conflict in clang/lib/CodeGen/CodeGenTypes.cpp CONFLICT (content): Merge conflict in clang/lib/AST/Decl.cpp CONFLICT (content): Merge conflict in clang/include/clang/AST/PrettyPrinter.h
2 parents 83a1d2a + 5f12f4f commit 3fe5af6

File tree

7 files changed

+124
-34
lines changed

7 files changed

+124
-34
lines changed

clang/include/clang/AST/PrettyPrinter.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,10 @@ struct PrintingPolicy {
5252
: Indentation(2), SuppressSpecifiers(false),
5353
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
5454
SuppressScope(false), SuppressUnwrittenScope(false),
55-
SuppressInitializers(false), ConstantArraySizeAsWritten(false),
56-
AnonymousTagLocations(true), SuppressStrongLifetime(false),
57-
SuppressLifetimeQualifiers(false), SuppressTypedefs(false),
58-
SuppressTemplateArgsInCXXConstructors(false),
55+
SuppressInlineNamespace(true), SuppressInitializers(false),
56+
ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
57+
SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
58+
SuppressTypedefs(false), SuppressTemplateArgsInCXXConstructors(false),
5959
SuppressDefaultTemplateArgs(true), Bool(LO.Bool),
6060
Nullptr(LO.CPlusPlus11), Restrict(LO.C99), Alignof(LO.CPlusPlus11),
6161
UnderscoreAlignof(LO.C11), UseVoidForZeroParams(!LO.CPlusPlus),
@@ -127,10 +127,15 @@ struct PrintingPolicy {
127127
/// Suppresses printing of scope specifiers.
128128
unsigned SuppressScope : 1;
129129

130-
/// Suppress printing parts of scope specifiers that don't need
131-
/// to be written, e.g., for inline or anonymous namespaces.
130+
/// Suppress printing parts of scope specifiers that are never
131+
/// written, e.g., for anonymous namespaces.
132132
unsigned SuppressUnwrittenScope : 1;
133133

134+
/// Suppress printing parts of scope specifiers that correspond
135+
/// to inline namespaces, where the name is unambiguous with the specifier
136+
/// removed.
137+
unsigned SuppressInlineNamespace : 1;
138+
134139
/// Suppress printing of variable initializers.
135140
///
136141
/// This flag is used when printing the loop variable in a for-range

clang/lib/AST/Decl.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,24 +1602,38 @@ void NamedDecl::printNestedNameSpecifier(raw_ostream &OS,
16021602
ContextsTy Contexts;
16031603

16041604
// Collect named contexts.
1605-
while (Ctx) {
1606-
if (isa<NamedDecl>(Ctx))
1607-
Contexts.push_back(Ctx);
1608-
Ctx = Ctx->getParent();
1605+
DeclarationName NameInScope = getDeclName();
1606+
for (; Ctx; Ctx = Ctx->getParent()) {
1607+
// Suppress anonymous namespace if requested.
1608+
if (P.SuppressUnwrittenScope && isa<NamespaceDecl>(Ctx) &&
1609+
cast<NamespaceDecl>(Ctx)->isAnonymousNamespace())
1610+
continue;
1611+
1612+
// Suppress inline namespace if it doesn't make the result ambiguous.
1613+
if (P.SuppressInlineNamespace && Ctx->isInlineNamespace() && NameInScope &&
1614+
Ctx->lookup(NameInScope).size() ==
1615+
Ctx->getParent()->lookup(NameInScope).size())
1616+
continue;
1617+
1618+
// Skip non-named contexts such as linkage specifications and ExportDecls.
1619+
const NamedDecl *ND = dyn_cast<NamedDecl>(Ctx);
1620+
if (!ND)
1621+
continue;
1622+
1623+
Contexts.push_back(Ctx);
1624+
NameInScope = ND->getDeclName();
16091625
}
16101626

16111627
if (WithGlobalNsPrefix)
16121628
OS << "::";
16131629

1614-
for (const DeclContext *DC : llvm::reverse(Contexts)) {
1630+
for (unsigned I = Contexts.size(); I != 0; --I) {
1631+
const DeclContext *DC = Contexts[I - 1];
16151632
if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
16161633
OS << Spec->getName();
16171634
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
16181635
printTemplateArgumentList(OS, TemplateArgs.asArray(), P);
16191636
} else if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) {
1620-
if (P.SuppressUnwrittenScope &&
1621-
(ND->isAnonymousNamespace() || ND->isInline()))
1622-
continue;
16231637
if (ND->isAnonymousNamespace()) {
16241638
OS << (P.MSVCFormatting ? "`anonymous namespace\'"
16251639
: "(anonymous namespace)");

clang/lib/AST/TypePrinter.cpp

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ namespace {
118118

119119
void printBefore(QualType T, raw_ostream &OS);
120120
void printAfter(QualType T, raw_ostream &OS);
121-
void AppendScope(DeclContext *DC, raw_ostream &OS);
121+
void AppendScope(DeclContext *DC, raw_ostream &OS,
122+
DeclarationName NameInScope);
122123
void printTag(TagDecl *T, raw_ostream &OS);
123124
void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
124125
#define ABSTRACT_TYPE(CLASS, PARENT)
@@ -1028,7 +1029,7 @@ void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
10281029
// In C, this will always be empty except when the type
10291030
// being printed is anonymous within other Record.
10301031
if (!Policy.SuppressScope)
1031-
AppendScope(D->getDeclContext(), OS);
1032+
AppendScope(D->getDeclContext(), OS, D->getDeclName());
10321033

10331034
IdentifierInfo *II = D->getIdentifier();
10341035
OS << II->getName();
@@ -1218,20 +1219,34 @@ void TypePrinter::printDependentExtIntAfter(const DependentExtIntType *T,
12181219
raw_ostream &OS) {}
12191220

12201221
/// Appends the given scope to the end of a string.
1221-
void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
1222-
if (DC->isTranslationUnit()) return;
1223-
if (DC->isFunctionOrMethod()) return;
1224-
AppendScope(DC->getParent(), OS);
1222+
void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
1223+
DeclarationName NameInScope) {
1224+
if (DC->isTranslationUnit())
1225+
return;
1226+
1227+
// FIXME: Consider replacing this with NamedDecl::printNestedNameSpecifier,
1228+
// which can also print names for function and method scopes.
1229+
if (DC->isFunctionOrMethod())
1230+
return;
12251231

12261232
if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
1227-
if (Policy.SuppressUnwrittenScope &&
1228-
(NS->isAnonymousNamespace() || NS->isInline()))
1229-
return;
1233+
if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())
1234+
return AppendScope(DC->getParent(), OS, NameInScope);
1235+
1236+
// Only suppress an inline namespace if the name has the same lookup
1237+
// results in the enclosing namespace.
1238+
if (Policy.SuppressInlineNamespace && NS->isInline() && NameInScope &&
1239+
DC->getParent()->lookup(NameInScope).size() ==
1240+
DC->lookup(NameInScope).size())
1241+
return AppendScope(DC->getParent(), OS, NameInScope);
1242+
1243+
AppendScope(DC->getParent(), OS, NS->getDeclName());
12301244
if (NS->getIdentifier())
12311245
OS << NS->getName() << "::";
12321246
else
12331247
OS << "(anonymous namespace)::";
12341248
} else if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(DC)) {
1249+
AppendScope(DC->getParent(), OS, Spec->getDeclName());
12351250
IncludeStrongLifetimeRAII Strong(Policy);
12361251
OS << Spec->getIdentifier()->getName();
12371252
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
@@ -1240,12 +1255,15 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS) {
12401255
Spec->getSpecializedTemplate()->getTemplateParameters());
12411256
OS << "::";
12421257
} else if (const auto *Tag = dyn_cast<TagDecl>(DC)) {
1258+
AppendScope(DC->getParent(), OS, Tag->getDeclName());
12431259
if (TypedefNameDecl *Typedef = Tag->getTypedefNameForAnonDecl())
12441260
OS << Typedef->getIdentifier()->getName() << "::";
12451261
else if (Tag->getIdentifier())
12461262
OS << Tag->getIdentifier()->getName() << "::";
12471263
else
12481264
return;
1265+
} else {
1266+
AppendScope(DC->getParent(), OS, NameInScope);
12491267
}
12501268
}
12511269

@@ -1272,7 +1290,7 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
12721290
// In C, this will always be empty except when the type
12731291
// being printed is anonymous within other Record.
12741292
if (!Policy.SuppressScope)
1275-
AppendScope(D->getDeclContext(), OS);
1293+
AppendScope(D->getDeclContext(), OS, D->getDeclName());
12761294

12771295
if (const IdentifierInfo *II = D->getIdentifier())
12781296
OS << II->getName();

clang/lib/ASTMatchers/ASTMatchersInternal.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -630,13 +630,10 @@ bool HasNameMatcher::matchesNodeFullSlow(const NamedDecl &Node) const {
630630
llvm::SmallString<128> NodeName = StringRef("::");
631631
llvm::raw_svector_ostream OS(NodeName);
632632

633-
if (SkipUnwritten) {
634-
PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
635-
Policy.SuppressUnwrittenScope = true;
636-
Node.printQualifiedName(OS, Policy);
637-
} else {
638-
Node.printQualifiedName(OS);
639-
}
633+
PrintingPolicy Policy = Node.getASTContext().getPrintingPolicy();
634+
Policy.SuppressUnwrittenScope = SkipUnwritten;
635+
Policy.SuppressInlineNamespace = SkipUnwritten;
636+
Node.printQualifiedName(OS, Policy);
640637

641638
const StringRef FullName = OS.str();
642639

clang/lib/CodeGen/CodeGenTypes.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,26 @@ void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
6666
OS << ".";
6767
}
6868

69+
// FIXME: We probably want to make more tweaks to the printing policy. For
70+
// example, we should probably enable PrintCanonicalTypes and
71+
// FullyQualifiedNames.
72+
PrintingPolicy Policy = RD->getASTContext().getPrintingPolicy();
73+
Policy.SuppressInlineNamespace = false;
74+
6975
// Name the codegen type after the typedef name
7076
// if there is no tag type name available
7177
if (RD->getIdentifier()) {
7278
// FIXME: We should not have to check for a null decl context here.
7379
// Right now we do it because the implicit Obj-C decls don't have one.
7480
if (RD->getDeclContext())
75-
RD->printQualifiedName(OS);
81+
RD->printQualifiedName(OS, Policy);
7682
else
7783
RD->printName(OS);
7884
} else if (const TypedefNameDecl *TDD = RD->getTypedefNameForAnonDecl()) {
7985
// FIXME: We should not have to check for a null decl context here.
8086
// Right now we do it because the implicit Obj-C decls don't have one.
8187
if (TDD->getDeclContext())
82-
TDD->printQualifiedName(OS);
88+
TDD->printQualifiedName(OS, Policy);
8389
else
8490
TDD->printName(OS);
8591
} else

clang/test/CXX/dcl.dcl/basic.namespace/namespace.def/p8.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ void foo1() {
2121
f1();
2222
::f1();
2323
X::f1();
24-
Y::f1(); // expected-error {{no member named 'f1' in namespace 'X::Y'; did you mean simply 'f1'?}}
24+
Y::f1(); // expected-error {{no member named 'f1' in namespace 'Y'; did you mean simply 'f1'?}}
2525

2626
f2();
2727
::f2();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
// RUN: %clang_cc1 -verify %s -std=c++20
2+
3+
// We avoid printing the name of an inline namespace unless it's necessary to
4+
// uniquely identify the target.
5+
namespace N {
6+
inline namespace A {
7+
inline namespace B {
8+
inline namespace C {
9+
int f, g, h, i, j;
10+
struct f; struct g; struct h; struct i; struct j;
11+
}
12+
struct g;
13+
struct j;
14+
}
15+
struct h;
16+
}
17+
struct i;
18+
struct j;
19+
20+
template<int*> struct Q; // expected-note 5{{here}}
21+
Q<&A::B::C::f> q1; // expected-error {{implicit instantiation of undefined template 'N::Q<&N::f>'}}
22+
Q<&A::B::C::g> q2; // expected-error {{implicit instantiation of undefined template 'N::Q<&N::C::g>'}}
23+
Q<&A::B::C::h> q3; // expected-error {{implicit instantiation of undefined template 'N::Q<&N::B::h>'}}
24+
Q<&A::B::C::i> q4; // expected-error {{implicit instantiation of undefined template 'N::Q<&N::A::i>'}}
25+
Q<&A::B::C::j> q5; // expected-error {{implicit instantiation of undefined template 'N::Q<&N::C::j>'}}
26+
27+
template<typename> struct R; // expected-note 5{{here}}
28+
R<struct A::B::C::f> r1; // expected-error {{implicit instantiation of undefined template 'N::R<N::f>'}}
29+
R<struct A::B::C::g> r2; // expected-error {{implicit instantiation of undefined template 'N::R<N::C::g>'}}
30+
R<struct A::B::C::h> r3; // expected-error {{implicit instantiation of undefined template 'N::R<N::B::h>'}}
31+
R<struct A::B::C::i> r4; // expected-error {{implicit instantiation of undefined template 'N::R<N::A::i>'}}
32+
R<struct A::B::C::j> r5; // expected-error {{implicit instantiation of undefined template 'N::R<N::C::j>'}}
33+
34+
// Make the name N::C ambiguous.
35+
inline namespace A { int C; }
36+
37+
template<int*> struct S; // expected-note 5{{here}}
38+
S<&A::B::C::f> s1; // expected-error {{implicit instantiation of undefined template 'N::S<&N::f>'}}
39+
S<&A::B::C::g> s2; // expected-error {{implicit instantiation of undefined template 'N::S<&N::B::C::g>'}}
40+
S<&A::B::C::h> s3; // expected-error {{implicit instantiation of undefined template 'N::S<&N::B::h>'}}
41+
S<&A::B::C::i> s4; // expected-error {{implicit instantiation of undefined template 'N::S<&N::A::i>'}}
42+
S<&A::B::C::j> s5; // expected-error {{implicit instantiation of undefined template 'N::S<&N::B::C::j>'}}
43+
44+
template<typename> struct T; // expected-note 5{{here}}
45+
T<struct A::B::C::f> t1; // expected-error {{implicit instantiation of undefined template 'N::T<N::f>'}}
46+
T<struct A::B::C::g> t2; // expected-error {{implicit instantiation of undefined template 'N::T<N::B::C::g>'}}
47+
T<struct A::B::C::h> t3; // expected-error {{implicit instantiation of undefined template 'N::T<N::B::h>'}}
48+
T<struct A::B::C::i> t4; // expected-error {{implicit instantiation of undefined template 'N::T<N::A::i>'}}
49+
T<struct A::B::C::j> t5; // expected-error {{implicit instantiation of undefined template 'N::T<N::B::C::j>'}}
50+
}

0 commit comments

Comments
 (0)