|
@@ -14,9 +14,10 @@
|
|
|
#ifndef LLVM_CLANG_AST_ATTR_H
|
|
|
#define LLVM_CLANG_AST_ATTR_H
|
|
|
|
|
|
-#include "clang/Basic/LLVM.h"
|
|
|
-#include "clang/Basic/AttrKinds.h"
|
|
|
+#include "clang/AST/AttrIterator.h"
|
|
|
#include "clang/AST/Type.h"
|
|
|
+#include "clang/Basic/AttrKinds.h"
|
|
|
+#include "clang/Basic/LLVM.h"
|
|
|
#include "clang/Basic/SourceLocation.h"
|
|
|
#include "clang/Basic/VersionTuple.h"
|
|
|
#include "llvm/ADT/SmallVector.h"
|
|
@@ -26,7 +27,6 @@
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
#include <cassert>
|
|
|
#include <cstring>
|
|
|
-#include <algorithm>
|
|
|
|
|
|
namespace clang {
|
|
|
class ASTContext;
|
|
@@ -36,23 +36,6 @@ namespace clang {
|
|
|
class QualType;
|
|
|
class FunctionDecl;
|
|
|
class TypeSourceInfo;
|
|
|
-}
|
|
|
-
|
|
|
-// Defined in ASTContext.h
|
|
|
-void *operator new(size_t Bytes, const clang::ASTContext &C,
|
|
|
- size_t Alignment = 16);
|
|
|
-// FIXME: Being forced to not have a default argument here due to redeclaration
|
|
|
-// rules on default arguments sucks
|
|
|
-void *operator new[](size_t Bytes, const clang::ASTContext &C,
|
|
|
- size_t Alignment);
|
|
|
-
|
|
|
-// It is good practice to pair new/delete operators. Also, MSVC gives many
|
|
|
-// warnings if a matching delete overload is not declared, even though the
|
|
|
-// throw() spec guarantees it will not be implicitly called.
|
|
|
-void operator delete(void *Ptr, const clang::ASTContext &C, size_t);
|
|
|
-void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
|
|
|
-
|
|
|
-namespace clang {
|
|
|
|
|
|
/// Attr - This represents one attribute.
|
|
|
class Attr {
|
|
@@ -139,114 +122,6 @@ public:
|
|
|
|
|
|
#include "clang/AST/Attrs.inc"
|
|
|
|
|
|
-/// AttrVec - A vector of Attr, which is how they are stored on the AST.
|
|
|
-typedef SmallVector<Attr*, 2> AttrVec;
|
|
|
-typedef SmallVector<const Attr*, 2> ConstAttrVec;
|
|
|
-
|
|
|
-/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
|
|
|
-/// providing attributes that are of a specifc type.
|
|
|
-template <typename SpecificAttr, typename Container = AttrVec>
|
|
|
-class specific_attr_iterator {
|
|
|
- typedef typename Container::const_iterator Iterator;
|
|
|
-
|
|
|
- /// Current - The current, underlying iterator.
|
|
|
- /// In order to ensure we don't dereference an invalid iterator unless
|
|
|
- /// specifically requested, we don't necessarily advance this all the
|
|
|
- /// way. Instead, we advance it when an operation is requested; if the
|
|
|
- /// operation is acting on what should be a past-the-end iterator,
|
|
|
- /// then we offer no guarantees, but this way we do not dererence a
|
|
|
- /// past-the-end iterator when we move to a past-the-end position.
|
|
|
- mutable Iterator Current;
|
|
|
-
|
|
|
- void AdvanceToNext() const {
|
|
|
- while (!isa<SpecificAttr>(*Current))
|
|
|
- ++Current;
|
|
|
- }
|
|
|
-
|
|
|
- void AdvanceToNext(Iterator I) const {
|
|
|
- while (Current != I && !isa<SpecificAttr>(*Current))
|
|
|
- ++Current;
|
|
|
- }
|
|
|
-
|
|
|
-public:
|
|
|
- typedef SpecificAttr* value_type;
|
|
|
- typedef SpecificAttr* reference;
|
|
|
- typedef SpecificAttr* pointer;
|
|
|
- typedef std::forward_iterator_tag iterator_category;
|
|
|
- typedef std::ptrdiff_t difference_type;
|
|
|
-
|
|
|
- specific_attr_iterator() : Current() { }
|
|
|
- explicit specific_attr_iterator(Iterator i) : Current(i) { }
|
|
|
-
|
|
|
- reference operator*() const {
|
|
|
- AdvanceToNext();
|
|
|
- return cast<SpecificAttr>(*Current);
|
|
|
- }
|
|
|
- pointer operator->() const {
|
|
|
- AdvanceToNext();
|
|
|
- return cast<SpecificAttr>(*Current);
|
|
|
- }
|
|
|
-
|
|
|
- specific_attr_iterator& operator++() {
|
|
|
- ++Current;
|
|
|
- return *this;
|
|
|
- }
|
|
|
- specific_attr_iterator operator++(int) {
|
|
|
- specific_attr_iterator Tmp(*this);
|
|
|
- ++(*this);
|
|
|
- return Tmp;
|
|
|
- }
|
|
|
-
|
|
|
- friend bool operator==(specific_attr_iterator Left,
|
|
|
- specific_attr_iterator Right) {
|
|
|
- if (Left.Current < Right.Current)
|
|
|
- Left.AdvanceToNext(Right.Current);
|
|
|
- else
|
|
|
- Right.AdvanceToNext(Left.Current);
|
|
|
- return Left.Current == Right.Current;
|
|
|
- }
|
|
|
- friend bool operator!=(specific_attr_iterator Left,
|
|
|
- specific_attr_iterator Right) {
|
|
|
- return !(Left == Right);
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-template <typename SpecificAttr, typename Container>
|
|
|
-inline specific_attr_iterator<SpecificAttr, Container>
|
|
|
- specific_attr_begin(const Container& container) {
|
|
|
- return specific_attr_iterator<SpecificAttr, Container>(container.begin());
|
|
|
-}
|
|
|
-template <typename SpecificAttr, typename Container>
|
|
|
-inline specific_attr_iterator<SpecificAttr, Container>
|
|
|
- specific_attr_end(const Container& container) {
|
|
|
- return specific_attr_iterator<SpecificAttr, Container>(container.end());
|
|
|
-}
|
|
|
-
|
|
|
-template <typename SpecificAttr, typename Container>
|
|
|
-inline bool hasSpecificAttr(const Container& container) {
|
|
|
- return specific_attr_begin<SpecificAttr>(container) !=
|
|
|
- specific_attr_end<SpecificAttr>(container);
|
|
|
-}
|
|
|
-template <typename SpecificAttr, typename Container>
|
|
|
-inline SpecificAttr *getSpecificAttr(const Container& container) {
|
|
|
- specific_attr_iterator<SpecificAttr, Container> i =
|
|
|
- specific_attr_begin<SpecificAttr>(container);
|
|
|
- if (i != specific_attr_end<SpecificAttr>(container))
|
|
|
- return *i;
|
|
|
- else
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/// getMaxAlignment - Returns the highest alignment value found among
|
|
|
-/// AlignedAttrs in an AttrVec, or 0 if there are none.
|
|
|
-inline unsigned getMaxAttrAlignment(const AttrVec& V, ASTContext &Ctx) {
|
|
|
- unsigned Align = 0;
|
|
|
- specific_attr_iterator<AlignedAttr> i(V.begin()), e(V.end());
|
|
|
- for(; i != e; ++i)
|
|
|
- Align = std::max(Align, i->getAlignment(Ctx));
|
|
|
- return Align;
|
|
|
-}
|
|
|
-
|
|
|
} // end namespace clang
|
|
|
|
|
|
#endif
|