diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Decl.h | 68 | ||||
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 46 | ||||
-rw-r--r-- | include/clang/AST/TemplateBase.h | 6 |
3 files changed, 77 insertions, 43 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 117ec7eef3..e9643d2dc7 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -247,63 +247,45 @@ public: bool visibilityExplicit() const { return explicit_; } void setLinkage(Linkage L) { linkage_ = L; } + void mergeLinkage(Linkage L) { setLinkage(minLinkage(linkage(), L)); } - void mergeLinkage(LinkageInfo Other) { - mergeLinkage(Other.linkage()); + void mergeLinkage(LinkageInfo other) { + mergeLinkage(other.linkage()); } - // Merge the visibility V giving preference to explicit ones. - // This is used, for example, when merging the visibility of a class - // down to one of its members. If the member has no explicit visibility, - // the class visibility wins. - void mergeVisibility(Visibility V, bool E = false) { - // Never increase the visibility - if (visibility() < V) - return; - - // If we have an explicit visibility, keep it - if (visibilityExplicit()) - return; + /// Merge in the visibility 'newVis'. + void mergeVisibility(Visibility newVis, bool newExplicit) { + Visibility oldVis = visibility(); - setVisibility(V, E); - } - // Merge the visibility V, keeping the most restrictive one. - // This is used for cases like merging the visibility of a template - // argument to an instantiation. If we already have a hidden class, - // no argument should give it default visibility. - void mergeVisibilityWithMin(Visibility V, bool E = false) { - // Never increase the visibility - if (visibility() < V) + // Never increase visibility. + if (oldVis < newVis) return; - // FIXME: this - // If this visibility is explicit, keep it. - if (visibilityExplicit() && !E) + // If the new visibility is the same as the old and the new + // visibility isn't explicit, we have nothing to add. + if (oldVis == newVis && !newExplicit) return; - // should be replaced with this - // Don't lose the explicit bit for nothing - // if (visibility() == V && visibilityExplicit()) - // return; - - setVisibility(V, E); + // Otherwise, we're either decreasing visibility or making our + // existing visibility explicit. + setVisibility(newVis, newExplicit); } - void mergeVisibility(LinkageInfo Other) { - mergeVisibility(Other.visibility(), Other.visibilityExplicit()); - } - void mergeVisibilityWithMin(LinkageInfo Other) { - mergeVisibilityWithMin(Other.visibility(), Other.visibilityExplicit()); + void mergeVisibility(LinkageInfo other) { + mergeVisibility(other.visibility(), other.visibilityExplicit()); } - void merge(LinkageInfo Other) { - mergeLinkage(Other); - mergeVisibility(Other); + /// Merge both linkage and visibility. + void merge(LinkageInfo other) { + mergeLinkage(other); + mergeVisibility(other); } - void mergeWithMin(LinkageInfo Other) { - mergeLinkage(Other); - mergeVisibilityWithMin(Other); + + /// Merge linkage and conditionally merge visibility. + void mergeMaybeWithVisibility(LinkageInfo other, bool withVis) { + mergeLinkage(other); + if (withVis) mergeVisibility(other); } }; diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index 979827a525..f50d774bf1 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -84,6 +84,13 @@ public: unsigned size() const { return NumParams; } + llvm::ArrayRef<NamedDecl*> asArray() { + return llvm::ArrayRef<NamedDecl*>(begin(), size()); + } + llvm::ArrayRef<const NamedDecl*> asArray() const { + return llvm::ArrayRef<const NamedDecl*>(begin(), size()); + } + NamedDecl* getParam(unsigned Idx) { assert(Idx < size() && "Template parameter index out-of-range"); return begin()[Idx]; @@ -193,6 +200,11 @@ public: /// \brief Retrieve the template argument at a given index. const TemplateArgument &operator[](unsigned Idx) const { return get(Idx); } + /// \brief Produce this as an array ref. + llvm::ArrayRef<TemplateArgument> asArray() const { + return llvm::ArrayRef<TemplateArgument>(data(), size()); + } + /// \brief Retrieve the number of template arguments in this /// template argument list. unsigned size() const { return NumArguments; } @@ -324,6 +336,23 @@ public: return getTemplateSpecializationKind() == TSK_ExplicitSpecialization; } + /// \brief True if this declaration is an explicit specialization, + /// explicit instantiation declaration, or explicit instantiation + /// definition. + bool isExplicitInstantiationOrSpecialization() const { + switch (getTemplateSpecializationKind()) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + /// \brief Set the template specialization kind. void setTemplateSpecializationKind(TemplateSpecializationKind TSK) { assert(TSK != TSK_Undeclared && @@ -1433,6 +1462,23 @@ public: return getSpecializationKind() == TSK_ExplicitSpecialization; } + /// \brief True if this declaration is an explicit specialization, + /// explicit instantiation declaration, or explicit instantiation + /// definition. + bool isExplicitInstantiationOrSpecialization() const { + switch (getTemplateSpecializationKind()) { + case TSK_ExplicitSpecialization: + case TSK_ExplicitInstantiationDeclaration: + case TSK_ExplicitInstantiationDefinition: + return true; + + case TSK_Undeclared: + case TSK_ImplicitInstantiation: + return false; + } + llvm_unreachable("bad template specialization kind"); + } + void setSpecializationKind(TemplateSpecializationKind TSK) { SpecializationKind = TSK; } diff --git a/include/clang/AST/TemplateBase.h b/include/clang/AST/TemplateBase.h index 6899fdb7d9..da57293b08 100644 --- a/include/clang/AST/TemplateBase.h +++ b/include/clang/AST/TemplateBase.h @@ -317,6 +317,12 @@ public: return Args.NumArgs; } + /// \brief Return the array of arguments in this template argument pack. + llvm::ArrayRef<TemplateArgument> getPackAsArray() const { + assert(Kind == Pack); + return llvm::ArrayRef<TemplateArgument>(Args.Args, Args.NumArgs); + } + /// \brief Determines whether two template arguments are superficially the /// same. bool structurallyEquals(const TemplateArgument &Other) const; |