summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp8
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp25
-rw-r--r--clang/lib/AST/MicrosoftMangle.cpp18
-rw-r--r--clang/lib/CodeGen/CGDecl.cpp10
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp6
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp6
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);
OpenPOWER on IntegriCloud