diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 3 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 6 | ||||
-rw-r--r-- | clang/lib/AST/NestedNameSpecifier.cpp | 71 |
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; } |