diff options
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTDumper.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/DeclBase.cpp | 2 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 38 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 20 |
4 files changed, 65 insertions, 2 deletions
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp index 872ba356a9b..1a4207f5120 100644 --- a/clang/lib/AST/ASTDumper.cpp +++ b/clang/lib/AST/ASTDumper.cpp @@ -428,6 +428,7 @@ namespace { void VisitFunctionDecl(const FunctionDecl *D); void VisitFieldDecl(const FieldDecl *D); void VisitVarDecl(const VarDecl *D); + void VisitDecompositionDecl(const DecompositionDecl *D); void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); void VisitImportDecl(const ImportDecl *D); void VisitPragmaCommentDecl(const PragmaCommentDecl *D); @@ -1217,6 +1218,12 @@ void ASTDumper::VisitVarDecl(const VarDecl *D) { } } +void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) { + VisitVarDecl(D); + for (auto *B : D->bindings()) + dumpDecl(B); +} + void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { dumpStmt(D->getAsmString()); } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index e07bf480ec6..8918e18d430 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -598,6 +598,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case CXXConversion: case EnumConstant: case Var: + case Binding: case ImplicitParam: case ParmVar: case ObjCMethod: @@ -678,6 +679,7 @@ unsigned Decl::getIdentifierNamespaceForKind(Kind DeclKind) { case Captured: case TranslationUnit: case ExternCContext: + case Decomposition: case UsingDirective: case BuiltinTemplate: diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index d069bfdc3dc..7e6c7253483 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -2306,6 +2306,44 @@ StaticAssertDecl *StaticAssertDecl::CreateDeserialized(ASTContext &C, nullptr, SourceLocation(), false); } +void BindingDecl::anchor() {} + +BindingDecl *BindingDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation IdLoc, IdentifierInfo *Id) { + return new (C, DC) BindingDecl(DC, IdLoc, Id); +} + +BindingDecl *BindingDecl::CreateDeserialized(ASTContext &C, unsigned ID) { + return new (C, ID) BindingDecl(nullptr, SourceLocation(), nullptr); +} + +void DecompositionDecl::anchor() {} + +DecompositionDecl *DecompositionDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, + SourceLocation LSquareLoc, + QualType T, TypeSourceInfo *TInfo, + StorageClass SC, + ArrayRef<BindingDecl *> Bindings) { + size_t Extra = additionalSizeToAlloc<BindingDecl *>(Bindings.size()); + return new (C, DC, Extra) + DecompositionDecl(C, DC, StartLoc, LSquareLoc, T, TInfo, SC, Bindings); +} + +DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C, + unsigned ID, + unsigned NumBindings) { + size_t Extra = additionalSizeToAlloc<BindingDecl *>(NumBindings); + auto *Result = new (C, ID, Extra) DecompositionDecl( + C, nullptr, SourceLocation(), SourceLocation(), QualType(), nullptr, StorageClass(), None); + // Set up and clean out the bindings array. + Result->NumBindings = NumBindings; + auto *Trail = Result->getTrailingObjects<BindingDecl *>(); + for (unsigned I = 0; I != NumBindings; ++I) + new (Trail + I) BindingDecl*(nullptr); + return Result; +} + MSPropertyDecl *MSPropertyDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 51de561d5f1..5b278314aee 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -593,7 +593,7 @@ bool ItaniumMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { return false; const VarDecl *VD = dyn_cast<VarDecl>(D); - if (VD) { + if (VD && !isa<DecompositionDecl>(D)) { // C variables are not mangled. if (VD->isExternC()) return false; @@ -1193,7 +1193,23 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, // ::= <source-name> switch (Name.getNameKind()) { case DeclarationName::Identifier: { - if (const IdentifierInfo *II = Name.getAsIdentifierInfo()) { + const IdentifierInfo *II = Name.getAsIdentifierInfo(); + + // We mangle decomposition declarations as the name of their first binding. + if (auto *DD = dyn_cast<DecompositionDecl>(ND)) { + auto B = DD->bindings(); + if (B.begin() == B.end()) { + // FIXME: This is ill-formed but we accept it as an extension. + DiagnosticsEngine &Diags = Context.getDiags(); + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, + "cannot mangle global empty decomposition decl"); + Diags.Report(DD->getLocation(), DiagID); + break; + } + II = (*B.begin())->getIdentifier(); + } + + if (II) { // We must avoid conflicts between internally- and externally- // linked variable and function declaration names in the same TU: // void test() { extern void foo(); } |