summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp3
-rw-r--r--clang/lib/AST/ASTImporter.cpp7
-rw-r--r--clang/lib/AST/ExprCXX.cpp3
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp6
-rw-r--r--clang/lib/AST/NestedNameSpecifier.cpp71
5 files changed, 76 insertions, 14 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index cafde32eb6f..7e5182e3397 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -4195,7 +4195,8 @@ ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
}
case NestedNameSpecifier::Global:
- // The global specifier is canonical and unique.
+ case NestedNameSpecifier::Super:
+ // The global specifier and __super specifer are canonical and unique.
return NNS;
}
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 05f39abaa37..ca7ab63c96f 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -4760,6 +4760,13 @@ NestedNameSpecifier *ASTImporter::Import(NestedNameSpecifier *FromNNS) {
case NestedNameSpecifier::Global:
return NestedNameSpecifier::GlobalSpecifier(ToContext);
+ case NestedNameSpecifier::Super:
+ if (CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(Import(FromNNS->getAsRecordDecl()))) {
+ return NestedNameSpecifier::SuperSpecifier(ToContext, RD);
+ }
+ return nullptr;
+
case NestedNameSpecifier::TypeSpec:
case NestedNameSpecifier::TypeSpecWithTemplate: {
QualType T = Import(QualType(FromNNS->getAsType(), 0u));
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 08230bebed1..93361666183 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1404,7 +1404,8 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() const {
// It can't be dependent: after all, we were actually able to do the
// lookup.
CXXRecordDecl *Record = nullptr;
- if (getQualifier()) {
+ auto *NNS = getQualifier();
+ if (NNS && NNS->getKind() != NestedNameSpecifier::Super) {
const Type *T = getQualifier()->getAsType();
assert(T && "qualifier in member expression does not name type");
Record = T->getAsCXXRecordDecl();
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 4717174b4a4..d2d02fac03e 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -814,6 +814,9 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
// We never want an 'E' here.
return;
+ case NestedNameSpecifier::Super:
+ llvm_unreachable("Can't mangle __super specifier");
+
case NestedNameSpecifier::Namespace:
if (qualifier->getPrefix())
mangleUnresolvedPrefix(qualifier->getPrefix(), firstQualifierLookup,
@@ -1462,6 +1465,9 @@ void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
// nothing
return;
+ case NestedNameSpecifier::Super:
+ llvm_unreachable("Can't mangle __super specifier");
+
case NestedNameSpecifier::Namespace:
mangleName(qualifier->getAsNamespace());
return;
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index 1f041aa4954..50a00502ca9 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -66,7 +66,7 @@ NestedNameSpecifier::Create(const ASTContext &Context,
"Broken nested name specifier");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredNamespaceOrAlias);
+ Mockup.Prefix.setInt(StoredDecl);
Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
return FindOrInsert(Context, Mockup);
}
@@ -82,7 +82,7 @@ NestedNameSpecifier::Create(const ASTContext &Context,
"Broken nested name specifier");
NestedNameSpecifier Mockup;
Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredNamespaceOrAlias);
+ Mockup.Prefix.setInt(StoredDecl);
Mockup.Specifier = Alias;
return FindOrInsert(Context, Mockup);
}
@@ -118,6 +118,16 @@ NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
return Context.GlobalNestedNameSpecifier;
}
+NestedNameSpecifier *
+NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
+ CXXRecordDecl *RD) {
+ NestedNameSpecifier Mockup;
+ Mockup.Prefix.setPointer(nullptr);
+ Mockup.Prefix.setInt(StoredDecl);
+ Mockup.Specifier = RD;
+ return FindOrInsert(Context, Mockup);
+}
+
NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
if (!Specifier)
return Global;
@@ -126,9 +136,12 @@ NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
case StoredIdentifier:
return Identifier;
- case StoredNamespaceOrAlias:
- return isa<NamespaceDecl>(static_cast<NamedDecl *>(Specifier))? Namespace
- : NamespaceAlias;
+ case StoredDecl: {
+ NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
+ if (isa<CXXRecordDecl>(ND))
+ return Super;
+ return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
+ }
case StoredTypeSpec:
return TypeSpec;
@@ -140,24 +153,29 @@ NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
llvm_unreachable("Invalid NNS Kind!");
}
-/// \brief Retrieve the namespace stored in this nested name
-/// specifier.
+/// \brief Retrieve the namespace stored in this nested name specifier.
NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
- if (Prefix.getInt() == StoredNamespaceOrAlias)
+ if (Prefix.getInt() == StoredDecl)
return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
return nullptr;
}
-/// \brief Retrieve the namespace alias stored in this nested name
-/// specifier.
+/// \brief Retrieve the namespace alias stored in this nested name specifier.
NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
- if (Prefix.getInt() == StoredNamespaceOrAlias)
+ if (Prefix.getInt() == StoredDecl)
return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
return nullptr;
}
+/// \brief Retrieve the record declaration stored in this nested name specifier.
+CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
+ if (Prefix.getInt() == StoredDecl)
+ return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
+
+ return nullptr;
+}
/// \brief Whether this nested name specifier refers to a dependent
/// type or not.
@@ -172,6 +190,15 @@ bool NestedNameSpecifier::isDependent() const {
case Global:
return false;
+ case Super: {
+ CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
+ for (const auto &Base : RD->bases())
+ if (Base.getType()->isDependentType())
+ return true;
+
+ return false;
+ }
+
case TypeSpec:
case TypeSpecWithTemplate:
return getAsType()->isDependentType();
@@ -191,8 +218,9 @@ bool NestedNameSpecifier::isInstantiationDependent() const {
case Namespace:
case NamespaceAlias:
case Global:
+ case Super:
return false;
-
+
case TypeSpec:
case TypeSpecWithTemplate:
return getAsType()->isInstantiationDependentType();
@@ -209,6 +237,7 @@ bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
case Namespace:
case NamespaceAlias:
case Global:
+ case Super:
return false;
case TypeSpec:
@@ -246,6 +275,10 @@ NestedNameSpecifier::print(raw_ostream &OS,
case Global:
break;
+ case Super:
+ OS << "__super";
+ break;
+
case TypeSpecWithTemplate:
OS << "template ";
// Fall through to print the type.
@@ -304,6 +337,7 @@ NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Super:
// The location of the identifier or namespace name.
Length += sizeof(unsigned);
break;
@@ -369,6 +403,7 @@ SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
case NestedNameSpecifier::Identifier:
case NestedNameSpecifier::Namespace:
case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Super:
return SourceRange(LoadSourceLocation(Data, Offset),
LoadSourceLocation(Data, Offset + sizeof(unsigned)));
@@ -552,6 +587,17 @@ void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}
+void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
+ CXXRecordDecl *RD,
+ SourceLocation SuperLoc,
+ SourceLocation ColonColonLoc) {
+ Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
+
+ // Push source-location info into the buffer.
+ SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
+ SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
+}
+
void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
NestedNameSpecifier *Qualifier,
SourceRange R) {
@@ -583,6 +629,7 @@ void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
}
case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Super:
break;
}
OpenPOWER on IntegriCloud