aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/Decl.h68
-rw-r--r--include/clang/AST/DeclTemplate.h46
-rw-r--r--include/clang/AST/TemplateBase.h6
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;