diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-11 22:25:46 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-08-11 22:25:46 +0000 |
commit | 5f0128122c3803afe7f26919f3f898f981451f44 (patch) | |
tree | 70ee26fc97baab18f26b5a194690a2977ee8dce9 /include | |
parent | e5174eea266bb5ec9e752f898a42ce3266400fd5 (diff) | |
download | clang-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.h | 2 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 6 | ||||
-rw-r--r-- | include/clang/AST/DeclCXX.h | 8 | ||||
-rw-r--r-- | include/clang/AST/UnresolvedSet.h | 2 | ||||
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 34 | ||||
-rw-r--r-- | include/clang/Sema/Initialization.h | 26 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 14 |
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); |