summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTDumper.cpp7
-rw-r--r--clang/lib/AST/DeclBase.cpp2
-rw-r--r--clang/lib/AST/DeclCXX.cpp38
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp20
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(); }
OpenPOWER on IntegriCloud