summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-08-11 22:25:46 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-08-11 22:25:46 +0000
commit5f0128122c3803afe7f26919f3f898f981451f44 (patch)
tree70ee26fc97baab18f26b5a194690a2977ee8dce9 /include
parente5174eea266bb5ec9e752f898a42ce3266400fd5 (diff)
downloadclang-5f0128122c3803afe7f26919f3f898f981451f44.tar.gz
P0217R3: Perform semantic checks and initialization for the bindings in a
decomposition declaration for arrays, aggregate-like structs, tuple-like types, and (as an extension) for complex and vector types. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@278435 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/clang/AST/CXXInheritance.h2
-rw-r--r--include/clang/AST/Decl.h6
-rw-r--r--include/clang/AST/DeclCXX.h8
-rw-r--r--include/clang/AST/UnresolvedSet.h2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td34
-rw-r--r--include/clang/Sema/Initialization.h26
-rw-r--r--include/clang/Sema/Sema.h14
7 files changed, 81 insertions, 11 deletions
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 50424a9661..3cf058f26b 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -172,7 +172,7 @@ public:
/// paths for a derived-to-base search.
explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
bool DetectVirtual = true)
- : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
+ : Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
NumDeclsFound(0) {}
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 90c854535e..254f575782 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -251,7 +251,7 @@ public:
// FIXME: Deprecated, move clients to getName().
std::string getNameAsString() const { return Name.getAsString(); }
- void printName(raw_ostream &os) const { os << Name; }
+ virtual void printName(raw_ostream &os) const;
/// getDeclName - Get the actual, stored name of the declaration,
/// which may be a special name.
@@ -1025,7 +1025,7 @@ public:
/// void foo() { int x; static int y; extern int z; }
///
bool isLocalVarDecl() const {
- if (getKind() != Decl::Var)
+ if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
if (const DeclContext *DC = getLexicalDeclContext())
return DC->getRedeclContext()->isFunctionOrMethod();
@@ -1040,7 +1040,7 @@ public:
/// isFunctionOrMethodVarDecl - Similar to isLocalVarDecl, but
/// excludes variables declared in blocks.
bool isFunctionOrMethodVarDecl() const {
- if (getKind() != Decl::Var)
+ if (getKind() != Decl::Var && getKind() != Decl::Decomposition)
return false;
const DeclContext *DC = getLexicalDeclContext()->getRedeclContext();
return DC->isFunctionOrMethod() && DC->getDeclKind() != Decl::Block;
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 6a2fcddfd7..48ada29bb6 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1147,6 +1147,12 @@ public:
/// \note This does NOT include a check for union-ness.
bool isEmpty() const { return data().Empty; }
+ /// \brief Determine whether this class has direct non-static data members.
+ bool hasDirectFields() const {
+ auto &D = data();
+ return D.HasPublicFields || D.HasProtectedFields || D.HasPrivateFields;
+ }
+
/// Whether this class is polymorphic (C++ [class.virtual]),
/// which means that the class contains or inherits a virtual function.
bool isPolymorphic() const { return data().Polymorphic; }
@@ -3451,6 +3457,8 @@ public:
return llvm::makeArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
}
+ void printName(raw_ostream &os) const override;
+
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decomposition; }
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h
index 7b4b4e5ccb..868c5a6e19 100644
--- a/include/clang/AST/UnresolvedSet.h
+++ b/include/clang/AST/UnresolvedSet.h
@@ -38,7 +38,7 @@ class UnresolvedSetIterator : public llvm::iterator_adaptor_base<
: iterator_adaptor_base(const_cast<DeclAccessPair *>(Iter)) {}
public:
- UnresolvedSetIterator() {}
+ UnresolvedSetIterator() = default;
NamedDecl *getDecl() const { return I->getDecl(); }
void setDecl(NamedDecl *ND) const { return I->setDecl(ND); }
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 81a47255bf..e7647f80f6 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -385,6 +385,40 @@ def err_decomp_decl_template : Error<
"decomposition declaration template not supported">;
def err_decomp_decl_not_alone : Error<
"decomposition declaration must be the only declaration in its group">;
+def err_decomp_decl_requires_init : Error<
+ "decomposition declaration %0 requires an initializer">;
+def err_decomp_decl_paren_init : Error<
+ "decomposition declaration %0 cannot have a parenthesized initializer">;
+def err_decomp_decl_wrong_number_bindings : Error<
+ "type %0 decomposes into %2 elements, but %select{only |}3%1 "
+ "names were provided">;
+def err_decomp_decl_unbindable_type : Error<
+ "cannot decompose %select{union|non-class, non-array}1 type %2">;
+def err_decomp_decl_multiple_bases_with_members : Error<
+ "cannot decompose class type %1: "
+ "%select{its base classes %2 and|both it and its base class}0 %3 "
+ "have non-static data members">;
+def err_decomp_decl_ambiguous_base : Error<
+ "cannot decompose members of ambiguous base class %1 of %0:%2">;
+def err_decomp_decl_non_public_base : Error<
+ "cannot decompose members of non-public base class %1 of %0">;
+def err_decomp_decl_non_public_member : Error<
+ "cannot decompose non-public member %0 of %1">;
+def err_decomp_decl_anon_union_member : Error<
+ "cannot decompose class type %1 because it has an anonymous "
+ "%select{struct|union} member">;
+def err_decomp_decl_std_tuple_element_not_specialized : Error<
+ "cannot decompose this type; 'std::tuple_element<%0>::type' "
+ "does not name a type">;
+def err_decomp_decl_std_tuple_size_not_constant : Error<
+ "cannot decompose this type; 'std::tuple_size<%0>::value' "
+ "is not a valid integral constant expression">;
+def note_in_binding_decl_init : Note<
+ "in implicit initialization of binding declaration %0">;
+
+def err_std_type_trait_not_class_template : Error<
+ "unsupported standard library implementation: "
+ "'std::%0' is not a class template">;
// C++ using declarations
def err_using_requires_qualname : Error<
diff --git a/include/clang/Sema/Initialization.h b/include/clang/Sema/Initialization.h
index cf636966d8..e160e3ecc6 100644
--- a/include/clang/Sema/Initialization.h
+++ b/include/clang/Sema/Initialization.h
@@ -84,7 +84,10 @@ public:
EK_RelatedResult,
/// \brief The entity being initialized is a function parameter; function
/// is member of group of audited CF APIs.
- EK_Parameter_CF_Audited
+ EK_Parameter_CF_Audited,
+ /// \brief The entity being initialized is a structured binding of a
+ /// decomposition declaration.
+ EK_Binding,
// Note: err_init_conversion_failed in DiagnosticSemaKinds.td uses this
// enum as an index for its first %select. When modifying this list,
@@ -126,9 +129,9 @@ private:
};
union {
- /// \brief When Kind == EK_Variable, or EK_Member, the VarDecl or
- /// FieldDecl, respectively.
- DeclaratorDecl *VariableOrMember;
+ /// \brief When Kind == EK_Variable, EK_Member or EK_Binding, the VarDecl,
+ /// FieldDecl or BindingDecl, respectively.
+ ValueDecl *VariableOrMember;
/// \brief When Kind == EK_RelatedResult, the ObjectiveC method where
/// result type was implicitly changed to accommodate ARC semantics.
@@ -180,6 +183,12 @@ private:
: Kind(EK_Member), Parent(Parent), Type(Member->getType()),
ManglingNumber(0), VariableOrMember(Member) { }
+ /// \brief Create the initialization entity for a binding.
+ InitializedEntity(BindingDecl *Binding, QualType Type,
+ const InitializedEntity &Parent)
+ : Kind(EK_Binding), Parent(&Parent), Type(Type),
+ ManglingNumber(0), VariableOrMember(Binding) {}
+
/// \brief Create the initialization entity for an array element.
InitializedEntity(ASTContext &Context, unsigned Index,
const InitializedEntity &Parent);
@@ -314,6 +323,13 @@ public:
return InitializedEntity(Context, Index, Parent);
}
+ /// \brief Create the initialization entity for a structured binding.
+ static InitializedEntity InitializeBinding(const InitializedEntity &Parent,
+ BindingDecl *Binding,
+ QualType Type) {
+ return InitializedEntity(Binding, Type, Parent);
+ }
+
/// \brief Create the initialization entity for a lambda capture.
static InitializedEntity InitializeLambdaCapture(IdentifierInfo *VarID,
QualType FieldType,
@@ -355,7 +371,7 @@ public:
/// \brief Retrieve the variable, parameter, or field being
/// initialized.
- DeclaratorDecl *getDecl() const;
+ ValueDecl *getDecl() const;
/// \brief Retrieve the ObjectiveC method being initialized.
ObjCMethodDecl *getMethodDecl() const { return MethodDecl; }
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e92a35f819..04f8b4b002 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1728,7 +1728,9 @@ public:
// Returns true if the variable declaration is a redeclaration
bool CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous);
void CheckVariableDeclarationType(VarDecl *NewVD);
- void CheckCompleteVariableDeclaration(VarDecl *var);
+ void CheckCompleteVariableDeclaration(VarDecl *VD, InitializedEntity &Entity);
+ void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD,
+ InitializedEntity &Entity);
void MaybeSuggestAddingStaticToDecl(const FunctionDecl *D);
NamedDecl* ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
@@ -3970,6 +3972,12 @@ public:
bool SuppressQualifierCheck = false,
ActOnMemberAccessExtraArgs *ExtraArgs = nullptr);
+ ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow,
+ SourceLocation OpLoc,
+ const CXXScopeSpec &SS, FieldDecl *Field,
+ DeclAccessPair FoundDecl,
+ const DeclarationNameInfo &MemberNameInfo);
+
ExprResult PerformMemberExprBaseConversion(Expr *Base, bool IsArrow);
bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,
@@ -5772,6 +5780,10 @@ public:
TemplateParameterList **OuterTemplateParamLists,
SkipBodyInfo *SkipBody = nullptr);
+ TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
+ QualType NTTPType,
+ SourceLocation Loc);
+
void translateTemplateArguments(const ASTTemplateArgsPtr &In,
TemplateArgumentListInfo &Out);