diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 8 | ||||
-rw-r--r-- | clang/lib/AST/ItaniumMangle.cpp | 25 | ||||
-rw-r--r-- | clang/lib/AST/MicrosoftMangle.cpp | 18 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDecl.cpp | 10 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 6 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 4 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 6 |
7 files changed, 60 insertions, 17 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 4b42141452f..49948a5d418 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -8721,6 +8721,14 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) { !VD->evaluateValue()) return true; + // Likewise, variables with tuple-like bindings are required if their + // bindings have side-effects. + if (auto *DD = dyn_cast<DecompositionDecl>(VD)) + for (auto *BD : DD->bindings()) + if (auto *BindingVD = BD->getHoldingVar()) + if (DeclMustBeEmitted(BindingVD)) + return true; + return false; } diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp index 5b278314aee..67d217e7a66 100644 --- a/clang/lib/AST/ItaniumMangle.cpp +++ b/clang/lib/AST/ItaniumMangle.cpp @@ -1195,18 +1195,21 @@ void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, case DeclarationName::Identifier: { const IdentifierInfo *II = Name.getAsIdentifierInfo(); - // We mangle decomposition declarations as the name of their first binding. + // We mangle decomposition declarations as the names of their bindings. 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(); + // FIXME: Non-standard mangling for decomposition declarations: + // + // <unqualified-name> ::= DC <source-name>* E + // + // These can never be referenced across translation units, so we do + // not need a cross-vendor mangling for anything other than demanglers. + // Proposed on cxx-abi-dev on 2016-08-12 + Out << "DC"; + for (auto *BD : DD->bindings()) + mangleSourceName(BD->getDeclName().getAsIdentifierInfo()); + Out << 'E'; + writeAbiTags(ND, AdditionalAbiTags); + break; } if (II) { diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index 351997e02a9..479ac44aa09 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -394,7 +394,8 @@ bool MicrosoftMangleContextImpl::shouldMangleCXXName(const NamedDecl *D) { if (!getASTContext().getLangOpts().CPlusPlus) return false; - if (const VarDecl *VD = dyn_cast<VarDecl>(D)) { + const VarDecl *VD = dyn_cast<VarDecl>(D); + if (VD && !isa<DecompositionDecl>(D)) { // C variables are not mangled. if (VD->isExternC()) return false; @@ -780,6 +781,21 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, } } + if (const DecompositionDecl *DD = dyn_cast<DecompositionDecl>(ND)) { + // FIXME: Invented mangling for decomposition declarations: + // [X,Y,Z] + // where X,Y,Z are the names of the bindings. + llvm::SmallString<128> Name("["); + for (auto *BD : DD->bindings()) { + if (Name.size() > 1) + Name += ','; + Name += BD->getDeclName().getAsIdentifierInfo()->getName(); + } + Name += ']'; + mangleSourceName(Name); + break; + } + if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) { // We must have an anonymous union or struct declaration. const CXXRecordDecl *RD = VD->getType()->getAsCXXRecordDecl(); diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index e0cb07b98dd..037b1351c0f 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -87,6 +87,7 @@ void CodeGenFunction::EmitDecl(const Decl &D) { case Decl::UsingShadow: case Decl::ConstructorUsingShadow: case Decl::ObjCTypeParam: + case Decl::Binding: llvm_unreachable("Declaration should not be in declstmts!"); case Decl::Function: // void X(); case Decl::Record: // struct/union/class X; @@ -119,10 +120,13 @@ void CodeGenFunction::EmitDecl(const Decl &D) { const VarDecl &VD = cast<VarDecl>(D); assert(VD.isLocalVarDecl() && "Should not see file-scope variables inside a function!"); - return EmitVarDecl(VD); + EmitVarDecl(VD); + if (auto *DD = dyn_cast<DecompositionDecl>(&VD)) + for (auto *B : DD->bindings()) + if (auto *HD = B->getHoldingVar()) + EmitVarDecl(*HD); + return; } - case Decl::Binding: - return CGM.ErrorUnsupported(&D, "structured binding"); case Decl::OMPDeclareReduction: return CGM.EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(&D), this); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 039936a3a64..89df63d8bf3 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -2206,6 +2206,12 @@ LValue CodeGenFunction::EmitDeclRefLValue(const DeclRefExpr *E) { if (const auto *FD = dyn_cast<FunctionDecl>(ND)) return EmitFunctionDeclLValue(*this, E, FD); + // FIXME: While we're emitting a binding from an enclosing scope, all other + // DeclRefExprs we see should be implicitly treated as if they also refer to + // an enclosing scope. + if (const auto *BD = dyn_cast<BindingDecl>(ND)) + return EmitLValue(BD->getBinding()); + llvm_unreachable("Unhandled DeclRefExpr"); } diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 888af29d403..f20baab784b 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -3772,6 +3772,10 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { return; case Decl::VarTemplateSpecialization: EmitGlobal(cast<VarDecl>(D)); + if (auto *DD = dyn_cast<DecompositionDecl>(D)) + for (auto *B : DD->bindings()) + if (auto *HD = B->getHoldingVar()) + EmitGlobal(HD); break; // Indirect fields from global anonymous structs and unions can be diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 6193cd0eac2..0dc68769235 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1160,6 +1160,7 @@ static bool checkTupleLikeDecomposition(Sema &S, RefVD->setImplicit(); if (Src->isInlineSpecified()) RefVD->setInlineSpecified(); + RefVD->getLexicalDeclContext()->addHiddenDecl(RefVD); InitializedEntity Entity = InitializedEntity::InitializeBinding(RefVD); InitializationKind Kind = InitializationKind::CreateCopy(Loc, Loc); @@ -1167,11 +1168,12 @@ static bool checkTupleLikeDecomposition(Sema &S, E = Seq.Perform(S, Entity, Kind, Init); if (E.isInvalid()) return true; + E = S.ActOnFinishFullExpr(E.get(), Loc); + if (E.isInvalid()) + return true; RefVD->setInit(E.get()); RefVD->checkInitIsICE(); - RefVD->getLexicalDeclContext()->addHiddenDecl(RefVD); - E = S.BuildDeclarationNameExpr(CXXScopeSpec(), DeclarationNameInfo(B->getDeclName(), Loc), RefVD); |