[cfe-commits] r111455 - in /cfe/trunk: include/clang/ include/clang/AST/ include/clang/Basic/ include/clang/Sema/ include/clang/Serialization/ lib/AST/ lib/Checker/ lib/CodeGen/ lib/Sema/ lib/Serialization/ tools/libclang/
Sean Hunt
rideau3 at gmail.com
Wed Aug 18 16:23:40 PDT 2010
Author: coppro
Date: Wed Aug 18 18:23:40 2010
New Revision: 111455
URL: http://llvm.org/viewvc/llvm-project?rev=111455&view=rev
Log:
Generate Attr subclasses with TableGen.
Now all classes derived from Attr are generated from TableGen.
Additionally, Attr* is no longer its own linked list; SmallVectors or
Attr* are used. The accompanying LLVM commit contains the updates to
TableGen necessary for this.
Some other notes about newly-generated attribute classes:
- The constructor arguments are a SourceLocation and a Context&,
followed by the attributes arguments in the order that they were
defined in Attr.td
- Every argument in Attr.td has an appropriate accessor named getFoo,
and there are sometimes a few extra ones (such as to get the length
of a variadic argument).
Additionally, specific_attr_iterator has been introduced, which will
iterate over an AttrVec, but only over attributes of a certain type. It
can be accessed through either Decl::specific_attr_begin/end or
the global functions of the same name.
Added:
cfe/trunk/include/clang/Serialization/CMakeLists.txt
cfe/trunk/include/clang/Serialization/Makefile
Modified:
cfe/trunk/include/clang/AST/ASTContext.h
cfe/trunk/include/clang/AST/Attr.h
cfe/trunk/include/clang/AST/CMakeLists.txt
cfe/trunk/include/clang/AST/DeclBase.h
cfe/trunk/include/clang/AST/DeclObjC.h
cfe/trunk/include/clang/AST/Makefile
cfe/trunk/include/clang/Basic/Attr.td
cfe/trunk/include/clang/CMakeLists.txt
cfe/trunk/include/clang/Makefile
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Serialization/PCHReader.h
cfe/trunk/include/clang/Serialization/PCHWriter.h
cfe/trunk/lib/AST/ASTContext.cpp
cfe/trunk/lib/AST/AttrImpl.cpp
cfe/trunk/lib/AST/CMakeLists.txt
cfe/trunk/lib/AST/DeclBase.cpp
cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
cfe/trunk/lib/Checker/MallocChecker.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclAttr.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/lib/Sema/SemaDeclObjC.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaTemplate.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
cfe/trunk/lib/Sema/TargetAttributesSema.cpp
cfe/trunk/lib/Serialization/CMakeLists.txt
cfe/trunk/lib/Serialization/PCHReaderDecl.cpp
cfe/trunk/lib/Serialization/PCHWriter.cpp
cfe/trunk/tools/libclang/CIndex.cpp
Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Aug 18 18:23:40 2010
@@ -18,7 +18,6 @@
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/PartialDiagnostic.h"
-#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
@@ -199,7 +198,7 @@
///
/// Since so few decls have attrs, we keep them in a hash map instead of
/// wasting space in the Decl class.
- llvm::DenseMap<const Decl*, Attr*> DeclAttrs;
+ llvm::DenseMap<const Decl*, AttrVec> DeclAttrs;
/// \brief Keeps track of the static data member templates from which
/// static data members of class template specializations were instantiated.
@@ -322,7 +321,7 @@
}
/// \brief Retrieve the attributes for the given declaration.
- Attr*& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
+ AttrVec& getDeclAttrs(const Decl *D) { return DeclAttrs[D]; }
/// \brief Erase the attributes corresponding to the given declaration.
void eraseDeclAttrs(const Decl *D) { DeclAttrs.erase(D); }
Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Wed Aug 18 18:23:40 2010
@@ -15,9 +15,11 @@
#define LLVM_CLANG_AST_ATTR_H
#include "llvm/Support/Casting.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "clang/Basic/AttrKinds.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
#include <cassert>
#include <cstring>
#include <algorithm>
@@ -29,25 +31,33 @@
class ObjCInterfaceDecl;
class Expr;
class QualType;
+ class FunctionDecl;
+ class TypeSourceInfo;
}
// Defined in ASTContext.h
void *operator new(size_t Bytes, clang::ASTContext &C,
size_t Alignment = 16) throw ();
+// FIXME: Being forced to not have a default argument here due to redeclaration
+// rules on default arguments sucks
+void *operator new[](size_t Bytes, clang::ASTContext &C,
+ size_t Alignment) throw ();
// 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, clang::ASTContext &C, size_t)
throw ();
+void operator delete[](void *Ptr, clang::ASTContext &C, size_t)
+ throw ();
namespace clang {
/// Attr - This represents one attribute.
class Attr {
private:
- Attr *Next;
- attr::Kind AttrKind;
+ SourceLocation Loc;
+ unsigned AttrKind : 16;
bool Inherited : 1;
protected:
@@ -61,38 +71,36 @@
assert(0 && "Attrs cannot be released with regular 'delete'.");
}
+public:
+ // Forward so that the regular new and delete do not hide global ones.
+ void* operator new(size_t Bytes, ASTContext &C,
+ size_t Alignment = 16) throw() {
+ return ::operator new(Bytes, C, Alignment);
+ }
+ void operator delete(void *Ptr, ASTContext &C,
+ size_t Alignment = 16) throw() {
+ return ::operator delete(Ptr, C, Alignment);
+ }
+
protected:
- Attr(attr::Kind AK) : Next(0), AttrKind(AK), Inherited(false) {}
-
+ Attr(attr::Kind AK, SourceLocation L)
+ : Loc(L), AttrKind(AK) {}
+
public:
/// \brief Whether this attribute should be merged to new
/// declarations.
virtual bool isMerged() const { return true; }
- attr::Kind getKind() const { return AttrKind; }
-
- Attr *getNext() { return Next; }
- const Attr *getNext() const { return Next; }
- void setNext(Attr *next) { Next = next; }
-
- template<typename T> const T *getNext() const {
- for (const Attr *attr = getNext(); attr; attr = attr->getNext())
- if (const T *V = dyn_cast<T>(attr))
- return V;
- return 0;
+ attr::Kind getKind() const {
+ return static_cast<attr::Kind>(AttrKind);
}
- bool isInherited() const { return Inherited; }
- void setInherited(bool value) { Inherited = value; }
-
- void addAttr(Attr *attr) {
- assert((attr != 0) && "addAttr(): attr is null");
+ SourceLocation getLocation() const { return Loc; }
+ void setLocation(SourceLocation L) { Loc = L; }
- // FIXME: This doesn't preserve the order in any way.
- attr->Next = Next;
- Next = attr;
- }
+ bool isInherited() const { return Inherited; }
+ void setInherited(bool I) { Inherited = I; }
// Clone this attribute.
virtual Attr* clone(ASTContext &C) const = 0;
@@ -102,591 +110,112 @@
};
#include "clang/AST/Attrs.inc"
-
-class AttrWithString : public Attr {
-private:
- const char *Str;
- unsigned StrLen;
-protected:
- AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s);
- llvm::StringRef getString() const { return llvm::StringRef(Str, StrLen); }
- void ReplaceString(ASTContext &C, llvm::StringRef newS);
-};
-
-#define DEF_SIMPLE_ATTR(ATTR) \
-class ATTR##Attr : public Attr { \
-public: \
- ATTR##Attr() : Attr(attr::ATTR) {} \
- virtual Attr *clone(ASTContext &C) const; \
- static bool classof(const Attr *A) { return A->getKind() == attr::ATTR; } \
- static bool classof(const ATTR##Attr *A) { return true; } \
-}
-
-DEF_SIMPLE_ATTR(Packed);
-/// \brief Attribute for specifying a maximum field alignment; this is only
-/// valid on record decls.
-class MaxFieldAlignmentAttr : public Attr {
- unsigned Alignment;
+/// AttrVec - A vector of Attr, which is how they are stored on the AST.
+typedef llvm::SmallVector<Attr*, 2> AttrVec;
+typedef llvm::SmallVector<const Attr*, 2> ConstAttrVec;
-public:
- MaxFieldAlignmentAttr(unsigned alignment)
- : Attr(attr::MaxFieldAlignment), Alignment(alignment) {}
-
- /// getAlignment - The specified alignment in bits.
- unsigned getAlignment() const { return Alignment; }
-
- virtual Attr* clone(ASTContext &C) const;
+/// DestroyAttrs - Destroy the contents of an AttrVec.
+inline void DestroyAttrs (AttrVec& V, ASTContext &C) {
+}
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::MaxFieldAlignment;
+/// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
+/// providing attributes that are of a specifc type.
+template <typename SpecificAttr>
+class specific_attr_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 AttrVec::const_iterator Current;
+
+ void AdvanceToNext() const {
+ while (!llvm::isa<SpecificAttr>(*Current))
+ ++Current;
+ }
+
+ void AdvanceToNext(AttrVec::const_iterator I) const {
+ while (Current != I && !llvm::isa<SpecificAttr>(*Current))
+ ++Current;
}
- static bool classof(const MaxFieldAlignmentAttr *A) { return true; }
-};
-DEF_SIMPLE_ATTR(AlignMac68k);
-
-/// \brief Atribute for specifying the alignment of a variable or type.
-///
-/// This node will either contain the precise Alignment (in bits, not bytes!)
-/// or will contain the expression for the alignment attribute in the case of
-/// a dependent expression within a class or function template. At template
-/// instantiation time these are transformed into concrete attributes.
-class AlignedAttr : public Attr {
- unsigned Alignment;
- Expr *AlignmentExpr;
public:
- AlignedAttr(unsigned alignment)
- : Attr(attr::Aligned), Alignment(alignment), AlignmentExpr(0) {}
- AlignedAttr(Expr *E)
- : Attr(attr::Aligned), Alignment(0), AlignmentExpr(E) {}
-
- /// getAlignmentExpr - Get a dependent alignment expression if one is present.
- Expr *getAlignmentExpr() const {
- return AlignmentExpr;
- }
-
- /// isDependent - Is the alignment a dependent expression
- bool isDependent() const {
- return getAlignmentExpr();
- }
-
- /// getAlignment - The specified alignment in bits. Requires !isDependent().
- unsigned getAlignment() const {
- assert(!isDependent() && "Cannot get a value dependent alignment");
- return Alignment;
- }
-
- /// getMaxAlignment - Get the maximum alignment of attributes on this list.
- unsigned getMaxAlignment() const {
- const AlignedAttr *Next = getNext<AlignedAttr>();
- if (Next)
- return std::max(Next->getMaxAlignment(), getAlignment());
+ 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(AttrVec::const_iterator i) : Current(i) { }
+
+ reference operator*() const {
+ AdvanceToNext();
+ return llvm::cast<SpecificAttr>(*Current);
+ }
+ pointer operator->() const {
+ AdvanceToNext();
+ return llvm::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
- return getAlignment();
- }
-
- virtual Attr* clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::Aligned;
- }
- static bool classof(const AlignedAttr *A) { return true; }
-};
-
-class AnnotateAttr : public AttrWithString {
-public:
- AnnotateAttr(ASTContext &C, llvm::StringRef ann)
- : AttrWithString(attr::Annotate, C, ann) {}
-
- llvm::StringRef getAnnotation() const { return getString(); }
-
- virtual Attr* clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::Annotate;
- }
- static bool classof(const AnnotateAttr *A) { return true; }
-};
-
-class AsmLabelAttr : public AttrWithString {
-public:
- AsmLabelAttr(ASTContext &C, llvm::StringRef L)
- : AttrWithString(attr::AsmLabel, C, L) {}
-
- llvm::StringRef getLabel() const { return getString(); }
-
- virtual Attr* clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::AsmLabel;
- }
- static bool classof(const AsmLabelAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AlwaysInline);
-
-class AliasAttr : public AttrWithString {
-public:
- AliasAttr(ASTContext &C, llvm::StringRef aliasee)
- : AttrWithString(attr::Alias, C, aliasee) {}
-
- llvm::StringRef getAliasee() const { return getString(); }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Alias; }
- static bool classof(const AliasAttr *A) { return true; }
-};
-
-class ConstructorAttr : public Attr {
- int priority;
-public:
- ConstructorAttr(int p) : Attr(attr::Constructor), priority(p) {}
-
- int getPriority() const { return priority; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Constructor; }
- static bool classof(const ConstructorAttr *A) { return true; }
-};
-
-class DestructorAttr : public Attr {
- int priority;
-public:
- DestructorAttr(int p) : Attr(attr::Destructor), priority(p) {}
-
- int getPriority() const { return priority; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Destructor; }
- static bool classof(const DestructorAttr *A) { return true; }
-};
-
-class IBOutletAttr : public Attr {
-public:
- IBOutletAttr() : Attr(attr::IBOutlet) {}
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::IBOutlet;
- }
- static bool classof(const IBOutletAttr *A) { return true; }
-};
-
-class IBOutletCollectionAttr : public Attr {
- QualType QT;
-public:
- IBOutletCollectionAttr(QualType qt = QualType())
- : Attr(attr::IBOutletCollection), QT(qt) {}
-
- QualType getType() const { return QT; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::IBOutletCollection;
+ Right.AdvanceToNext(Left.Current);
+ return Left.Current == Right.Current;
}
- static bool classof(const IBOutletCollectionAttr *A) { return true; }
-};
-
-class IBActionAttr : public Attr {
-public:
- IBActionAttr() : Attr(attr::IBAction) {}
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::IBAction;
- }
- static bool classof(const IBActionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(AnalyzerNoReturn);
-DEF_SIMPLE_ATTR(Deprecated);
-DEF_SIMPLE_ATTR(GNUInline);
-DEF_SIMPLE_ATTR(Malloc);
-DEF_SIMPLE_ATTR(NoReturn);
-DEF_SIMPLE_ATTR(NoInstrumentFunction);
-
-class SectionAttr : public AttrWithString {
-public:
- SectionAttr(ASTContext &C, llvm::StringRef N)
- : AttrWithString(attr::Section, C, N) {}
-
- llvm::StringRef getName() const { return getString(); }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::Section;
- }
- static bool classof(const SectionAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(Unavailable);
-DEF_SIMPLE_ATTR(Unused);
-DEF_SIMPLE_ATTR(Used);
-DEF_SIMPLE_ATTR(Weak);
-DEF_SIMPLE_ATTR(WeakImport);
-DEF_SIMPLE_ATTR(WeakRef);
-DEF_SIMPLE_ATTR(NoThrow);
-DEF_SIMPLE_ATTR(Const);
-DEF_SIMPLE_ATTR(Pure);
-
-class NonNullAttr : public Attr {
- unsigned* ArgNums;
- unsigned Size;
-public:
- NonNullAttr(ASTContext &C, unsigned* arg_nums = 0, unsigned size = 0);
-
- typedef const unsigned *iterator;
- iterator begin() const { return ArgNums; }
- iterator end() const { return ArgNums + Size; }
- unsigned size() const { return Size; }
-
- bool isNonNull(unsigned arg) const {
- return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true;
+ friend bool operator!=(specific_attr_iterator Left,
+ specific_attr_iterator Right) {
+ return !(Left == Right);
}
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A) { return A->getKind() == attr::NonNull; }
- static bool classof(const NonNullAttr *A) { return true; }
};
-/// OwnershipAttr
-/// Ownership attributes are used to annotate pointers that own a resource
-/// in order for the analyzer to check correct allocation and deallocation.
-/// There are three attributes, ownership_returns, ownership_holds and
-/// ownership_takes, represented by subclasses of OwnershipAttr
-class OwnershipAttr: public AttrWithString {
- protected:
- unsigned* ArgNums;
- unsigned Size;
-public:
- attr::Kind AKind;
-public:
- OwnershipAttr(attr::Kind AK, ASTContext &C, unsigned* arg_nums, unsigned size,
- llvm::StringRef module);
-
-
- virtual void Destroy(ASTContext &C);
-
- /// Ownership attributes have a 'module', which is the name of a kind of
- /// resource that can be checked.
- /// The Malloc checker uses the module 'malloc'.
- llvm::StringRef getModule() const {
- return getString();
- }
- void setModule(ASTContext &C, llvm::StringRef module) {
- ReplaceString(C, module);
- }
- bool isModule(const char *m) const {
- return getModule().equals(m);
- }
-
- typedef const unsigned *iterator;
- iterator begin() const {
- return ArgNums;
- }
- iterator end() const {
- return ArgNums + Size;
- }
- unsigned size() const {
- return Size;
- }
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A) {
- switch (A->getKind()) {
- case attr::OwnershipTakes:
- case attr::OwnershipHolds:
- case attr::OwnershipReturns:
- return true;
- default:
- return false;
- }
- }
- static bool classof(const OwnershipAttr *A) {
- return true;
- }
-};
-
-class OwnershipTakesAttr: public OwnershipAttr {
-public:
- OwnershipTakesAttr(ASTContext &C, unsigned* arg_nums, unsigned size,
- llvm::StringRef module);
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A) {
- return A->getKind() == attr::OwnershipTakes;
- }
- static bool classof(const OwnershipTakesAttr *A) {
- return true;
- }
-};
-
-class OwnershipHoldsAttr: public OwnershipAttr {
-public:
- OwnershipHoldsAttr(ASTContext &C, unsigned* arg_nums, unsigned size,
- llvm::StringRef module);
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A) {
- return A->getKind() == attr::OwnershipHolds;
- }
- static bool classof(const OwnershipHoldsAttr *A) {
- return true;
- }
-};
-
-class OwnershipReturnsAttr: public OwnershipAttr {
-public:
- OwnershipReturnsAttr(ASTContext &C, unsigned* arg_nums, unsigned size,
- llvm::StringRef module);
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A) {
- return A->getKind() == attr::OwnershipReturns;
- }
- static bool classof(const OwnershipReturnsAttr *A) {
- return true;
- }
-};
-
-class FormatAttr : public AttrWithString {
- int formatIdx, firstArg;
-public:
- FormatAttr(ASTContext &C, llvm::StringRef type, int idx, int first)
- : AttrWithString(attr::Format, C, type), formatIdx(idx), firstArg(first) {}
-
- llvm::StringRef getType() const { return getString(); }
- void setType(ASTContext &C, llvm::StringRef type);
- int getFormatIdx() const { return formatIdx; }
- int getFirstArg() const { return firstArg; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Format; }
- static bool classof(const FormatAttr *A) { return true; }
-};
-
-class FormatArgAttr : public Attr {
- int formatIdx;
-public:
- FormatArgAttr(int idx) : Attr(attr::FormatArg), formatIdx(idx) {}
- int getFormatIdx() const { return formatIdx; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::FormatArg; }
- static bool classof(const FormatArgAttr *A) { return true; }
-};
-
-class SentinelAttr : public Attr {
- int sentinel, NullPos;
-public:
- SentinelAttr(int sentinel_val, int nullPos) : Attr(attr::Sentinel),
- sentinel(sentinel_val), NullPos(nullPos) {}
- int getSentinel() const { return sentinel; }
- int getNullPos() const { return NullPos; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Sentinel; }
- static bool classof(const SentinelAttr *A) { return true; }
-};
-
-class VisibilityAttr : public Attr {
-public:
- /// @brief An enumeration for the kinds of visibility of symbols.
- enum VisibilityTypes {
- DefaultVisibility = 0,
- HiddenVisibility,
- ProtectedVisibility
- };
-private:
- VisibilityTypes VisibilityType;
- bool FromPragma;
-public:
- VisibilityAttr(VisibilityTypes v, bool fp) : Attr(attr::Visibility),
- VisibilityType(v), FromPragma(fp) {}
-
- VisibilityTypes getVisibility() const { return VisibilityType; }
-
- bool isFromPragma() const { return FromPragma; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Visibility; }
- static bool classof(const VisibilityAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(FastCall);
-DEF_SIMPLE_ATTR(StdCall);
-DEF_SIMPLE_ATTR(ThisCall);
-DEF_SIMPLE_ATTR(CDecl);
-DEF_SIMPLE_ATTR(TransparentUnion);
-DEF_SIMPLE_ATTR(ObjCNSObject);
-DEF_SIMPLE_ATTR(ObjCException);
-
-class OverloadableAttr : public Attr {
-public:
- OverloadableAttr() : Attr(attr::Overloadable) { }
-
- virtual bool isMerged() const { return false; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A)
- { return A->getKind() == attr::Overloadable; }
- static bool classof(const OverloadableAttr *) { return true; }
-};
-
-class BlocksAttr : public Attr {
-public:
- enum BlocksAttrTypes {
- ByRef = 0
- };
-private:
- BlocksAttrTypes BlocksAttrType;
-public:
- BlocksAttr(BlocksAttrTypes t) : Attr(attr::Blocks), BlocksAttrType(t) {}
-
- BlocksAttrTypes getType() const { return BlocksAttrType; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Blocks; }
- static bool classof(const BlocksAttr *A) { return true; }
-};
-
-class FunctionDecl;
-
-class CleanupAttr : public Attr {
- FunctionDecl *FD;
-
-public:
- CleanupAttr(FunctionDecl *fd) : Attr(attr::Cleanup), FD(fd) {}
-
- const FunctionDecl *getFunctionDecl() const { return FD; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Cleanup; }
- static bool classof(const CleanupAttr *A) { return true; }
-};
-
-DEF_SIMPLE_ATTR(NoDebug);
-DEF_SIMPLE_ATTR(WarnUnusedResult);
-DEF_SIMPLE_ATTR(NoInline);
-
-class RegparmAttr : public Attr {
- unsigned NumParams;
-
-public:
- RegparmAttr(unsigned np) : Attr(attr::Regparm), NumParams(np) {}
-
- unsigned getNumParams() const { return NumParams; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) { return A->getKind() == attr::Regparm; }
- static bool classof(const RegparmAttr *A) { return true; }
-};
-
-class ReqdWorkGroupSizeAttr : public Attr {
- unsigned X, Y, Z;
-public:
- ReqdWorkGroupSizeAttr(unsigned X, unsigned Y, unsigned Z)
- : Attr(attr::ReqdWorkGroupSize), X(X), Y(Y), Z(Z) {}
-
- unsigned getXDim() const { return X; }
- unsigned getYDim() const { return Y; }
- unsigned getZDim() const { return Z; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A) {
- return A->getKind() == attr::ReqdWorkGroupSize;
- }
- static bool classof(const ReqdWorkGroupSizeAttr *A) { return true; }
-};
-
-class InitPriorityAttr : public Attr {
- unsigned Priority;
-public:
- InitPriorityAttr(unsigned priority)
- : Attr(attr::InitPriority), Priority(priority) {}
-
- unsigned getPriority() const { return Priority; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- static bool classof(const Attr *A)
- { return A->getKind() == attr::InitPriority; }
- static bool classof(const InitPriorityAttr *A) { return true; }
-};
-
-// Checker-specific attributes.
-DEF_SIMPLE_ATTR(CFReturnsNotRetained);
-DEF_SIMPLE_ATTR(CFReturnsRetained);
-DEF_SIMPLE_ATTR(NSReturnsNotRetained);
-DEF_SIMPLE_ATTR(NSReturnsRetained);
-
-// Target-specific attributes
-DEF_SIMPLE_ATTR(DLLImport);
-DEF_SIMPLE_ATTR(DLLExport);
-
-class MSP430InterruptAttr : public Attr {
- unsigned Number;
-
-public:
- MSP430InterruptAttr(unsigned n) : Attr(attr::MSP430Interrupt), Number(n) {}
-
- unsigned getNumber() const { return Number; }
-
- virtual Attr *clone(ASTContext &C) const;
-
- // Implement isa/cast/dyncast/etc.
- static bool classof(const Attr *A)
- { return A->getKind() == attr::MSP430Interrupt; }
- static bool classof(const MSP430InterruptAttr *A) { return true; }
-};
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_begin(const AttrVec& vec) {
+ return specific_attr_iterator<T>(vec.begin());
+}
+template <typename T>
+inline specific_attr_iterator<T> specific_attr_end(const AttrVec& vec) {
+ return specific_attr_iterator<T>(vec.end());
+}
-DEF_SIMPLE_ATTR(X86ForceAlignArgPointer);
+template <typename T>
+inline bool hasSpecificAttr(const AttrVec& vec) {
+ return specific_attr_begin<T>(vec) != specific_attr_end<T>(vec);
+}
+template <typename T>
+inline T *getSpecificAttr(const AttrVec& vec) {
+ specific_attr_iterator<T> i = specific_attr_begin<T>(vec);
+ if (i != specific_attr_end<T>(vec))
+ return *i;
+ else
+ return 0;
+}
-#undef DEF_SIMPLE_ATTR
+/// 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
Modified: cfe/trunk/include/clang/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/AST/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -5,6 +5,12 @@
add_custom_target(ClangAttrClasses
DEPENDS Attrs.inc)
+tablegen(AttrImpl.inc
+ -gen-clang-attr-impl
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrImpl
+ DEPENDS AttrImpl.inc)
+
set(LLVM_TARGET_DEFINITIONS ../Basic/StmtNodes.td)
tablegen(StmtNodes.inc
-gen-clang-stmt-nodes)
Modified: cfe/trunk/include/clang/AST/DeclBase.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclBase.h (original)
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Aug 18 18:23:40 2010
@@ -308,24 +308,52 @@
}
bool hasAttrs() const { return HasAttrs; }
- void initAttrs(Attr *attrs);
- void addAttr(Attr *attr);
- const Attr *getAttrs() const {
- if (!HasAttrs) return 0; // common case, no attributes.
- return getAttrsImpl(); // Uncommon case, out of line hash lookup.
+ void setAttrs(const AttrVec& Attrs);
+ AttrVec& getAttrs() {
+ return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs());
}
+ const AttrVec &getAttrs() const;
void swapAttrs(Decl *D);
- void invalidateAttrs();
+ void dropAttrs();
- template<typename T> const T *getAttr() const {
- for (const Attr *attr = getAttrs(); attr; attr = attr->getNext())
- if (const T *V = dyn_cast<T>(attr))
- return V;
- return 0;
+ void addAttr(Attr *A) {
+ if (hasAttrs())
+ getAttrs().push_back(A);
+ else
+ setAttrs(AttrVec(1, A));
}
+ typedef AttrVec::const_iterator attr_iterator;
+
+ // FIXME: Do not rely on iterators having comparable singular values.
+ // Note that this should error out if they do not.
+ attr_iterator attr_begin() const {
+ return hasAttrs() ? getAttrs().begin() : 0;
+ }
+ attr_iterator attr_end() const {
+ return hasAttrs() ? getAttrs().end() : 0;
+ }
+
+ template <typename T>
+ specific_attr_iterator<T> specific_attr_begin() const {
+ return specific_attr_iterator<T>(attr_begin());
+ }
+ template <typename T>
+ specific_attr_iterator<T> specific_attr_end() const {
+ return specific_attr_iterator<T>(attr_end());
+ }
+
+ template<typename T> T *getAttr() const {
+ return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : 0;
+ }
template<typename T> bool hasAttr() const {
- return getAttr<T>() != 0;
+ return hasAttrs() && hasSpecificAttr<T>(getAttrs());
+ }
+
+ /// getMaxAlignment - return the maximum alignment specified by attributes
+ /// on this decl, 0 if there are none.
+ unsigned getMaxAlignment() const {
+ return hasAttrs() ? getMaxAttrAlignment(getAttrs(), getASTContext()) : 0;
}
/// setInvalidDecl - Indicates the Decl had a semantic error. This
@@ -346,16 +374,16 @@
/// (in addition to the "used" bit set by \c setUsed()) when determining
/// whether the function is used.
bool isUsed(bool CheckUsedAttr = true) const;
-
+
void setUsed(bool U = true) { Used = U; }
/// \brief Retrieve the level of precompiled header from which this
/// declaration was generated.
///
/// The PCH level of a declaration describes where the declaration originated
- /// from. A PCH level of 0 indicates that the declaration was not from a
+ /// from. A PCH level of 0 indicates that the declaration was not from a
/// precompiled header. A PCH level of 1 indicates that the declaration was
- /// from a top-level precompiled header; 2 indicates that the declaration
+ /// from a top-level precompiled header; 2 indicates that the declaration
/// comes from a precompiled header on which the top-level precompiled header
/// depends, and so on.
unsigned getPCHLevel() const { return PCHLevel; }
Modified: cfe/trunk/include/clang/AST/DeclObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclObjC.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclObjC.h (original)
+++ cfe/trunk/include/clang/AST/DeclObjC.h Wed Aug 18 18:23:40 2010
@@ -21,7 +21,6 @@
class Expr;
class Stmt;
class FunctionDecl;
-class AttributeList;
class RecordDecl;
class ObjCIvarDecl;
class ObjCMethodDecl;
Modified: cfe/trunk/include/clang/AST/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Makefile?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Makefile (original)
+++ cfe/trunk/include/clang/AST/Makefile Wed Aug 18 18:23:40 2010
@@ -1,6 +1,6 @@
CLANG_LEVEL := ../../..
TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = Attrs.inc StmtNodes.inc DeclNodes.inc
+BUILT_SOURCES = Attrs.inc AttrImpl.inc StmtNodes.inc DeclNodes.inc
TABLEGEN_INC_FILES_COMMON = 1
@@ -12,6 +12,12 @@
$(Verb) $(TableGen) -gen-clang-attr-classes -o $(call SYSPATH, $@) \
-I $(PROJ_SRC_DIR)/../../ $<
+$(ObjDir)/AttrImpl.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute implementations with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-impl -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
$(ObjDir)/StmtNodes.inc.tmp : $(TD_SRC_DIR)/StmtNodes.td $(TBLGEN) \
$(ObjDir)/.dir
$(Echo) "Building Clang statement node tables with tblgen"
Modified: cfe/trunk/include/clang/Basic/Attr.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Attr.td?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/Attr.td (original)
+++ cfe/trunk/include/clang/Basic/Attr.td Wed Aug 18 18:23:40 2010
@@ -33,8 +33,8 @@
// a possible subject.
def NormalVar : SubsetSubject<Var, "non-register, non-parameter variable",
[{S->getStorageClass() != VarDecl::Register &&
- S->getKind() != Decl::ImplicitParam
- S->getKind() != Decl::ParmVar
+ S->getKind() != Decl::ImplicitParam &&
+ S->getKind() != Decl::ParmVar &&
S->getKind() != Decl::NonTypeTemplateParm}]>;
def CXXVirtualMethod : SubsetSubject<CXXRecord, "virtual member function",
[{S->isVirtual()}]>;
@@ -51,18 +51,27 @@
class StringArgument<string name> : Argument<name>;
class ExprArgument<string name> : Argument<name>;
class FunctionArgument<string name> : Argument<name>;
-class ObjCInterfaceArgument<string name> : Argument<name>;
-class UnsignedIntArgument<string name> : Argument<name>;
-class UnsignedIntOrTypeArgument<string name> : Argument<name>;
+class TypeArgument<string name> : Argument<name>;
+class UnsignedArgument<string name> : Argument<name>;
+class VariadicUnsignedArgument<string name> : Argument<name>;
+
+// This one's a doozy, so it gets its own special type
+// It can be an unsigned integer, or a type. Either can
+// be dependent.
+class AlignedArgument<string name> : Argument<name>;
// An integer argument with a default value
class DefaultIntArgument<string name, int default> : IntArgument<name> {
int Default = default;
}
-// Zero or more arguments of a type
-class VariadicArgument<Argument arg> : Argument<arg.Name> {
- Argument VariadicArg = arg;
+// This argument is more complex, it includes the enumerator type name,
+// a list of strings to accept, and a list of enumerators to map them to.
+class EnumArgument<string name, string type, list<string> values,
+ list<string> enums> : Argument<name> {
+ string Type = type;
+ list<string> Values = values;
+ list<string> Enums = enums;
}
class Attr {
@@ -76,9 +85,8 @@
// The attribute will not be permitted in C++0x attribute-specifiers if
// this is empty; the empty string can be used as a namespace.
list<string> Namespaces = [];
- // A temporary development bit to tell TableGen not to emit certain
- // information about the attribute.
- bit DoNotEmit = 1;
+ // Any additional text that should be included verbatim in the class.
+ code AdditionalMembers = [{}];
}
//
@@ -87,13 +95,13 @@
def Alias : Attr {
let Spellings = ["alias"];
- let Args = [StringArgument<"AliasName">];
+ let Args = [StringArgument<"Aliasee">];
}
def Aligned : Attr {
let Spellings = ["align", "aligned"];
let Subjects = [NonBitField, NormalVar, Tag];
- let Args = [UnsignedIntOrTypeArgument<"Alignment">];
+ let Args = [AlignedArgument<"Alignment">];
let Namespaces = ["", "std"];
}
@@ -123,19 +131,17 @@
let Spellings = ["base_check"];
let Subjects = [CXXRecord];
let Namespaces = ["", "std"];
- let DoNotEmit = 0;
}
def Blocks : Attr {
let Spellings = ["blocks"];
- let Args = [IdentifierArgument<"Type">];
+ let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>];
}
def CarriesDependency : Attr {
let Spellings = ["carries_dependency"];
let Subjects = [ParmVar, Function];
let Namespaces = ["", "std"];
- let DoNotEmit = 0;
}
def CDecl : Attr {
@@ -189,7 +195,6 @@
let Spellings = ["final"];
let Subjects = [CXXRecord, CXXVirtualMethod];
let Namespaces = ["", "std"];
- let DoNotEmit = 0;
}
def Format : Attr {
@@ -211,7 +216,6 @@
let Spellings = ["hiding"];
let Subjects = [Field, CXXMethod];
let Namespaces = ["", "std"];
- let DoNotEmit = 0;
}
def IBAction : Attr {
@@ -224,7 +228,7 @@
def IBOutletCollection : Attr {
let Spellings = ["iboutletcollection"];
- let Args = [ObjCInterfaceArgument<"Class">];
+ let Args = [TypeArgument<"Interface">];
}
def Malloc : Attr {
@@ -233,12 +237,12 @@
def MaxFieldAlignment : Attr {
let Spellings = [];
- let Args = [UnsignedIntArgument<"Alignment">];
+ let Args = [UnsignedArgument<"Alignment">];
}
def MSP430Interrupt : Attr {
let Spellings = [];
- let Args = [UnsignedIntArgument<"Number">];
+ let Args = [UnsignedArgument<"Number">];
}
def NoDebug : Attr {
@@ -251,7 +255,15 @@
def NonNull : Attr {
let Spellings = ["nonnull"];
- let Args = [VariadicArgument<UnsignedIntArgument<"Args">>];
+ let Args = [VariadicUnsignedArgument<"Args">];
+ let AdditionalMembers =
+[{bool isNonNull(unsigned idx) const {
+ for (args_iterator i = args_begin(), e = args_end();
+ i != e; ++i)
+ if (*i == idx)
+ return true;
+ return false;
+ } }];
}
def NoReturn : Attr {
@@ -290,26 +302,18 @@
let Spellings = ["override"];
let Subjects = [CXXVirtualMethod];
let Namespaces = ["", "std"];
- let DoNotEmit = 0;
}
def Overloadable : Attr {
let Spellings = ["overloadable"];
}
-def OwnershipReturns : Attr {
- let Spellings = ["ownership_returns"];
- let Args = [StringArgument<"Module">, IntArgument<"SizeIdx">];
-}
-
-def OwnershipTakes : Attr {
- let Spellings = ["ownership_takes"];
- let Args = [StringArgument<"Module">, IntArgument<"PtrIdx">];
-}
-
-def OwnershipHolds : Attr {
- let Spellings = ["ownership_holds"];
- let Args = [StringArgument<"Module">, IntArgument<"PtrIdx">];
+def Ownership : Attr {
+ let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"];
+ let Args = [EnumArgument<"OwnKind", "OwnershipKind",
+ ["ownership_holds", "ownership_returns", "ownership_takes"],
+ ["Holds", "Returns", "Takes"]>,
+ StringArgument<"Module">, VariadicUnsignedArgument<"Args">];
}
def Packed : Attr {
@@ -322,18 +326,18 @@
def Regparm : Attr {
let Spellings = ["regparm"];
- let Args = [UnsignedIntArgument<"NumParams">];
+ let Args = [UnsignedArgument<"NumParams">];
}
def ReqdWorkGroupSize : Attr {
let Spellings = ["reqd_work_group_size"];
- let Args = [UnsignedIntArgument<"XDim">, UnsignedIntArgument<"YDim">,
- UnsignedIntArgument<"ZDim">];
+ let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">,
+ UnsignedArgument<"ZDim">];
}
def InitPriority : Attr {
let Spellings = ["init_priority"];
- let Args = [UnsignedIntArgument<"Priority">];
+ let Args = [UnsignedArgument<"Priority">];
}
def Section : Attr {
@@ -343,8 +347,8 @@
def Sentinel : Attr {
let Spellings = ["sentinel"];
- let Args = [DefaultIntArgument<"NulPos", 0>,
- DefaultIntArgument<"Sentinel", 0>];
+ let Args = [DefaultIntArgument<"Sentinel", 0>,
+ DefaultIntArgument<"NullPos", 0>];
}
def StdCall : Attr {
@@ -373,13 +377,14 @@
def Visibility : Attr {
let Spellings = ["visibility"];
- let Args = [StringArgument<"Visibility">];
+ let Args = [EnumArgument<"Visibility", "VisibilityType",
+ ["default", "hidden", "internal", "protected"],
+ ["Default", "Hidden", "Hidden", "Protected"]>];
}
def VecReturn : Attr {
let Spellings = ["vecreturn"];
let Subjects = [CXXRecord];
- let DoNotEmit = 0;
}
def WarnUnusedResult : Attr {
Modified: cfe/trunk/include/clang/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -1,3 +1,4 @@
add_subdirectory(AST)
add_subdirectory(Basic)
add_subdirectory(Driver)
+add_subdirectory(Serialization)
Modified: cfe/trunk/include/clang/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Makefile?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Makefile (original)
+++ cfe/trunk/include/clang/Makefile Wed Aug 18 18:23:40 2010
@@ -1,5 +1,5 @@
CLANG_LEVEL := ../..
-DIRS := AST Basic Driver
+DIRS := AST Basic Driver Serialization
include $(CLANG_LEVEL)/Makefile
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Wed Aug 18 18:23:40 2010
@@ -4265,7 +4265,8 @@
/// PushPragmaVisibility - Push the top element of the visibility stack; used
/// for '#pragma GCC visibility' and visibility attributes on namespaces.
- void PushPragmaVisibility(VisibilityAttr::VisibilityTypes type);
+ void PushPragmaVisibility(VisibilityAttr::VisibilityType type,
+ SourceLocation loc);
/// PopPragmaVisibility - Pop the top element of the visibility stack; used
/// for '#pragma GCC visibility' and visibility attributes on namespaces.
@@ -4276,6 +4277,7 @@
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
+ void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *T);
/// CastCategory - Get the correct forwarded implicit cast result category
/// from the inner expression.
Added: cfe/trunk/include/clang/Serialization/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/CMakeLists.txt?rev=111455&view=auto
==============================================================================
--- cfe/trunk/include/clang/Serialization/CMakeLists.txt (added)
+++ cfe/trunk/include/clang/Serialization/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -0,0 +1,12 @@
+set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td)
+tablegen(AttrPCHRead.inc
+ -gen-clang-attr-pch-read
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrPCHRead
+ DEPENDS AttrPCHRead.inc)
+
+tablegen(AttrPCHWrite.inc
+ -gen-clang-attr-pch-write
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrPCHWrite
+ DEPENDS AttrPCHWrite.inc)
Added: cfe/trunk/include/clang/Serialization/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Makefile?rev=111455&view=auto
==============================================================================
--- cfe/trunk/include/clang/Serialization/Makefile (added)
+++ cfe/trunk/include/clang/Serialization/Makefile Wed Aug 18 18:23:40 2010
@@ -0,0 +1,19 @@
+CLANG_LEVEL := ../../..
+TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
+BUILT_SOURCES = AttrPCHRead.inc AttrPCHWrite.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(CLANG_LEVEL)/Makefile
+
+$(ObjDir)/AttrPCHRead.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang PCH reader with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-pch-read -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
+
+$(ObjDir)/AttrPCHWrite.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang PCH writer with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-pch-write -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
Modified: cfe/trunk/include/clang/Serialization/PCHReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/PCHReader.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/PCHReader.h (original)
+++ cfe/trunk/include/clang/Serialization/PCHReader.h Wed Aug 18 18:23:40 2010
@@ -908,7 +908,7 @@
CXXTemporary *ReadCXXTemporary(const RecordData &Record, unsigned &Idx);
/// \brief Reads attributes from the current stream position.
- Attr *ReadAttributes(llvm::BitstreamCursor &DeclsCursor);
+ void ReadAttributes(llvm::BitstreamCursor &DeclsCursor, AttrVec &Attrs);
/// \brief Reads a statement.
Stmt *ReadStmt(llvm::BitstreamCursor &Cursor);
Modified: cfe/trunk/include/clang/Serialization/PCHWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/PCHWriter.h?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/PCHWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/PCHWriter.h Wed Aug 18 18:23:40 2010
@@ -281,7 +281,7 @@
void WriteSelectors(Sema &SemaRef);
void WriteReferencedSelectorsPool(Sema &SemaRef);
void WriteIdentifierTable(Preprocessor &PP);
- void WriteAttributeRecord(const Attr *Attr);
+ void WriteAttributeRecord(const AttrVec &Attrs);
void WriteDeclUpdateBlock();
unsigned ParmVarDeclAbbrev;
Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Aug 18 18:23:40 2010
@@ -497,8 +497,7 @@
CharUnits ASTContext::getDeclAlign(const Decl *D, bool RefAsPointee) {
unsigned Align = Target.getCharWidth();
- if (const AlignedAttr* AA = D->getAttr<AlignedAttr>())
- Align = std::max(Align, AA->getMaxAlignment());
+ Align = std::max(Align, D->getMaxAlignment());
if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
QualType T = VD->getType();
@@ -760,12 +759,9 @@
case Type::Typedef: {
const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl();
- if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) {
- Align = std::max(Aligned->getMaxAlignment(),
- getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
- Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
- } else
- return getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
+ Align = std::max(Typedef->getMaxAlignment(),
+ getTypeAlign(Typedef->getUnderlyingType().getTypePtr()));
+ Width = getTypeSize(Typedef->getUnderlyingType().getTypePtr());
break;
}
Modified: cfe/trunk/lib/AST/AttrImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/AttrImpl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/AttrImpl.cpp (original)
+++ cfe/trunk/lib/AST/AttrImpl.cpp Wed Aug 18 18:23:40 2010
@@ -13,231 +13,10 @@
#include "clang/AST/Attr.h"
#include "clang/AST/ASTContext.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/Expr.h"
using namespace clang;
Attr::~Attr() { }
-AttrWithString::AttrWithString(attr::Kind AK, ASTContext &C, llvm::StringRef s)
- : Attr(AK) {
- assert(!s.empty());
- StrLen = s.size();
- Str = new (C) char[StrLen];
- memcpy(const_cast<char*>(Str), s.data(), StrLen);
-}
-
-void AttrWithString::ReplaceString(ASTContext &C, llvm::StringRef newS) {
- if (newS.size() > StrLen) {
- C.Deallocate(const_cast<char*>(Str));
- Str = new (C) char[newS.size()];
- }
- StrLen = newS.size();
- memcpy(const_cast<char*>(Str), newS.data(), StrLen);
-}
-
-void FormatAttr::setType(ASTContext &C, llvm::StringRef type) {
- ReplaceString(C, type);
-}
-
-NonNullAttr::NonNullAttr(ASTContext &C, unsigned* arg_nums, unsigned size)
- : Attr(attr::NonNull), ArgNums(0), Size(0) {
- if (size == 0)
- return;
- assert(arg_nums);
- ArgNums = new (C) unsigned[size];
- Size = size;
- memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
-}
-
-OwnershipAttr::OwnershipAttr(attr::Kind AK, ASTContext &C, unsigned* arg_nums,
- unsigned size, llvm::StringRef module)
- : AttrWithString(AK, C, module), ArgNums(0), Size(0) {
- if (size == 0)
- return;
- assert(arg_nums);
- ArgNums = new (C) unsigned[size];
- Size = size;
- memcpy(ArgNums, arg_nums, sizeof(*ArgNums) * size);
-}
-
-
-void OwnershipAttr::Destroy(ASTContext &C) {
- if (ArgNums)
- C.Deallocate(ArgNums);
-}
-
-OwnershipTakesAttr::OwnershipTakesAttr(ASTContext &C, unsigned* arg_nums,
- unsigned size, llvm::StringRef module)
- : OwnershipAttr(attr::OwnershipTakes, C, arg_nums, size, module) {
-}
-
-OwnershipHoldsAttr::OwnershipHoldsAttr(ASTContext &C, unsigned* arg_nums,
- unsigned size, llvm::StringRef module)
- : OwnershipAttr(attr::OwnershipHolds, C, arg_nums, size, module) {
-}
-
-OwnershipReturnsAttr::OwnershipReturnsAttr(ASTContext &C, unsigned* arg_nums,
- unsigned size,
- llvm::StringRef module)
- : OwnershipAttr(attr::OwnershipReturns, C, arg_nums, size, module) {
-}
-
-#define DEF_SIMPLE_ATTR_CLONE(ATTR) \
- Attr *ATTR##Attr::clone(ASTContext &C) const { \
- return ::new (C) ATTR##Attr; \
- }
-
-// FIXME: Can we use variadic macro to define DEF_SIMPLE_ATTR_CLONE for
-// "non-simple" classes?
-
-DEF_SIMPLE_ATTR_CLONE(AlignMac68k)
-DEF_SIMPLE_ATTR_CLONE(AlwaysInline)
-DEF_SIMPLE_ATTR_CLONE(AnalyzerNoReturn)
-DEF_SIMPLE_ATTR_CLONE(BaseCheck)
-DEF_SIMPLE_ATTR_CLONE(CDecl)
-DEF_SIMPLE_ATTR_CLONE(CFReturnsNotRetained)
-DEF_SIMPLE_ATTR_CLONE(CFReturnsRetained)
-DEF_SIMPLE_ATTR_CLONE(Const)
-DEF_SIMPLE_ATTR_CLONE(DLLExport)
-DEF_SIMPLE_ATTR_CLONE(DLLImport)
-DEF_SIMPLE_ATTR_CLONE(Deprecated)
-DEF_SIMPLE_ATTR_CLONE(FastCall)
-DEF_SIMPLE_ATTR_CLONE(Final)
-DEF_SIMPLE_ATTR_CLONE(Hiding)
-DEF_SIMPLE_ATTR_CLONE(Malloc)
-DEF_SIMPLE_ATTR_CLONE(NSReturnsNotRetained)
-DEF_SIMPLE_ATTR_CLONE(NSReturnsRetained)
-DEF_SIMPLE_ATTR_CLONE(NoDebug)
-DEF_SIMPLE_ATTR_CLONE(NoInline)
-DEF_SIMPLE_ATTR_CLONE(NoInstrumentFunction)
-DEF_SIMPLE_ATTR_CLONE(NoReturn)
-DEF_SIMPLE_ATTR_CLONE(NoThrow)
-DEF_SIMPLE_ATTR_CLONE(ObjCException)
-DEF_SIMPLE_ATTR_CLONE(ObjCNSObject)
-DEF_SIMPLE_ATTR_CLONE(Override)
-DEF_SIMPLE_ATTR_CLONE(Packed)
-DEF_SIMPLE_ATTR_CLONE(Pure)
-DEF_SIMPLE_ATTR_CLONE(StdCall)
-DEF_SIMPLE_ATTR_CLONE(ThisCall)
-DEF_SIMPLE_ATTR_CLONE(TransparentUnion)
-DEF_SIMPLE_ATTR_CLONE(Unavailable)
-DEF_SIMPLE_ATTR_CLONE(Unused)
-DEF_SIMPLE_ATTR_CLONE(Used)
-DEF_SIMPLE_ATTR_CLONE(VecReturn)
-DEF_SIMPLE_ATTR_CLONE(WarnUnusedResult)
-DEF_SIMPLE_ATTR_CLONE(Weak)
-DEF_SIMPLE_ATTR_CLONE(WeakImport)
-
-DEF_SIMPLE_ATTR_CLONE(WeakRef)
-DEF_SIMPLE_ATTR_CLONE(X86ForceAlignArgPointer)
-
-Attr* MaxFieldAlignmentAttr::clone(ASTContext &C) const {
- return ::new (C) MaxFieldAlignmentAttr(Alignment);
-}
-
-Attr* AlignedAttr::clone(ASTContext &C) const {
- return ::new (C) AlignedAttr(Alignment);
-}
-
-Attr* AnnotateAttr::clone(ASTContext &C) const {
- return ::new (C) AnnotateAttr(C, getAnnotation());
-}
-
-Attr *AsmLabelAttr::clone(ASTContext &C) const {
- return ::new (C) AsmLabelAttr(C, getLabel());
-}
-
-Attr *AliasAttr::clone(ASTContext &C) const {
- return ::new (C) AliasAttr(C, getAliasee());
-}
-
-Attr *ConstructorAttr::clone(ASTContext &C) const {
- return ::new (C) ConstructorAttr(priority);
-}
-
-Attr *DestructorAttr::clone(ASTContext &C) const {
- return ::new (C) DestructorAttr(priority);
-}
-
-Attr *IBOutletAttr::clone(ASTContext &C) const {
- return ::new (C) IBOutletAttr;
-}
-
-Attr *IBOutletCollectionAttr::clone(ASTContext &C) const {
- return ::new (C) IBOutletCollectionAttr(QT);
-}
-
-Attr *IBActionAttr::clone(ASTContext &C) const {
- return ::new (C) IBActionAttr;
-}
-
-Attr *GNUInlineAttr::clone(ASTContext &C) const {
- return ::new (C) GNUInlineAttr;
-}
-
-Attr *SectionAttr::clone(ASTContext &C) const {
- return ::new (C) SectionAttr(C, getName());
-}
-
-Attr *NonNullAttr::clone(ASTContext &C) const {
- return ::new (C) NonNullAttr(C, ArgNums, Size);
-}
-
-Attr *OwnershipAttr::clone(ASTContext &C) const {
- return ::new (C) OwnershipAttr(AKind, C, ArgNums, Size, getModule());
-}
-
-Attr *OwnershipReturnsAttr::clone(ASTContext &C) const {
- return ::new (C) OwnershipReturnsAttr(C, ArgNums, Size, getModule());
-}
-
-Attr *OwnershipTakesAttr::clone(ASTContext &C) const {
- return ::new (C) OwnershipTakesAttr(C, ArgNums, Size, getModule());
-}
-
-Attr *OwnershipHoldsAttr::clone(ASTContext &C) const {
- return ::new (C) OwnershipHoldsAttr(C, ArgNums, Size, getModule());
-}
-
-Attr *FormatAttr::clone(ASTContext &C) const {
- return ::new (C) FormatAttr(C, getType(), formatIdx, firstArg);
-}
-
-Attr *FormatArgAttr::clone(ASTContext &C) const {
- return ::new (C) FormatArgAttr(formatIdx);
-}
-
-Attr *SentinelAttr::clone(ASTContext &C) const {
- return ::new (C) SentinelAttr(sentinel, NullPos);
-}
-
-Attr *VisibilityAttr::clone(ASTContext &C) const {
- return ::new (C) VisibilityAttr(VisibilityType, FromPragma);
-}
-
-Attr *OverloadableAttr::clone(ASTContext &C) const {
- return ::new (C) OverloadableAttr;
-}
-
-Attr *BlocksAttr::clone(ASTContext &C) const {
- return ::new (C) BlocksAttr(BlocksAttrType);
-}
-
-Attr *CleanupAttr::clone(ASTContext &C) const {
- return ::new (C) CleanupAttr(FD);
-}
-
-Attr *RegparmAttr::clone(ASTContext &C) const {
- return ::new (C) RegparmAttr(NumParams);
-}
-
-Attr *ReqdWorkGroupSizeAttr::clone(ASTContext &C) const {
- return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z);
-}
-
-Attr *InitPriorityAttr::clone(ASTContext &C) const {
- return ::new (C) InitPriorityAttr(Priority);
-}
-
-Attr *MSP430InterruptAttr::clone(ASTContext &C) const {
- return ::new (C) MSP430InterruptAttr(Number);
-}
+#include "clang/AST/AttrImpl.inc"
Modified: cfe/trunk/lib/AST/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/CMakeLists.txt (original)
+++ cfe/trunk/lib/AST/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -43,4 +43,4 @@
)
add_dependencies(clangAST ClangARMNeon ClangAttrClasses ClangAttrList
- ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)
+ ClangAttrImpl ClangDiagnosticAST ClangDeclNodes ClangStmtNodes)
Modified: cfe/trunk/lib/AST/DeclBase.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclBase.cpp (original)
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Aug 18 18:23:40 2010
@@ -312,35 +312,25 @@
return 0;
}
-void Decl::initAttrs(Attr *attrs) {
+void Decl::setAttrs(const AttrVec &attrs) {
assert(!HasAttrs && "Decl already contains attrs.");
- Attr *&AttrBlank = getASTContext().getDeclAttrs(this);
- assert(AttrBlank == 0 && "HasAttrs was wrong?");
+ AttrVec &AttrBlank = getASTContext().getDeclAttrs(this);
+ assert(AttrBlank.empty() && "HasAttrs was wrong?");
AttrBlank = attrs;
HasAttrs = true;
}
-void Decl::addAttr(Attr *NewAttr) {
- Attr *&ExistingAttr = getASTContext().getDeclAttrs(this);
-
- assert(NewAttr->getNext() == 0 && "Chain of attributes will be truncated!");
- NewAttr->setNext(ExistingAttr);
- ExistingAttr = NewAttr;
-
- HasAttrs = true;
-}
-
-void Decl::invalidateAttrs() {
+void Decl::dropAttrs() {
if (!HasAttrs) return;
HasAttrs = false;
getASTContext().eraseDeclAttrs(this);
}
-const Attr *Decl::getAttrsImpl() const {
- assert(HasAttrs && "getAttrs() should verify this!");
+const AttrVec &Decl::getAttrs() const {
+ assert(HasAttrs && "No attrs to get!");
return getASTContext().getDeclAttrs(this);
}
Modified: cfe/trunk/lib/AST/RecordLayoutBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/RecordLayoutBuilder.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/AST/RecordLayoutBuilder.cpp (original)
+++ cfe/trunk/lib/AST/RecordLayoutBuilder.cpp Wed Aug 18 18:23:40 2010
@@ -1123,8 +1123,8 @@
if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>())
MaxFieldAlignment = MFAA->getAlignment();
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- UpdateAlignment(AA->getMaxAlignment());
+ if (unsigned MaxAlign = D->getMaxAlignment())
+ UpdateAlignment(MaxAlign);
}
}
@@ -1287,8 +1287,7 @@
if (FieldPacked || !Context.Target.useBitFieldTypeAlignment())
FieldAlign = 1;
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+ FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
// The maximum field alignment overrides the aligned attribute.
if (MaxFieldAlignment)
@@ -1357,8 +1356,7 @@
if (FieldPacked)
FieldAlign = 8;
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
- FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
+ FieldAlign = std::max(FieldAlign, D->getMaxAlignment());
// The maximum field alignment overrides the aligned attribute.
if (MaxFieldAlignment)
Modified: cfe/trunk/lib/Checker/MallocChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/MallocChecker.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/MallocChecker.cpp (original)
+++ cfe/trunk/lib/Checker/MallocChecker.cpp Wed Aug 18 18:23:40 2010
@@ -176,19 +176,23 @@
// There can be multiple of these attributes.
bool rv = false;
if (FD->hasAttrs()) {
- for (const Attr *attr = FD->getAttrs(); attr; attr = attr->getNext()) {
- switch (attr->getKind()) {
- case attr::OwnershipReturns:
- MallocMemReturnsAttr(C, CE, cast<OwnershipAttr>(attr));
+ for (specific_attr_iterator<OwnershipAttr>
+ i = FD->specific_attr_begin<OwnershipAttr>(),
+ e = FD->specific_attr_end<OwnershipAttr>();
+ i != e; ++i) {
+ switch ((*i)->getOwnKind()) {
+ case OwnershipAttr::Returns: {
+ MallocMemReturnsAttr(C, CE, *i);
rv = true;
break;
- case attr::OwnershipTakes:
- case attr::OwnershipHolds:
- FreeMemAttr(C, CE, cast<OwnershipAttr>(attr));
+ }
+ case OwnershipAttr::Takes:
+ case OwnershipAttr::Holds: {
+ FreeMemAttr(C, CE, *i);
rv = true;
break;
+ }
default:
- // Ignore non-ownership attributes.
break;
}
}
@@ -204,10 +208,10 @@
void MallocChecker::MallocMemReturnsAttr(CheckerContext &C, const CallExpr *CE,
const OwnershipAttr* Att) {
- if (!Att->isModule("malloc"))
+ if (Att->getModule() != "malloc")
return;
- const unsigned *I = Att->begin(), *E = Att->end();
+ OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
if (I != E) {
const GRState *state =
MallocMemAux(C, CE, CE->getArg(*I), UndefinedVal(), C.getState());
@@ -258,14 +262,15 @@
void MallocChecker::FreeMemAttr(CheckerContext &C, const CallExpr *CE,
const OwnershipAttr* Att) {
- if (!Att->isModule("malloc"))
+ if (Att->getModule() != "malloc")
return;
- for (const unsigned *I = Att->begin(), *E = Att->end(); I != E; ++I) {
- const GRState *state =
- FreeMemAux(C, CE, C.getState(), *I, isa<OwnershipHoldsAttr>(Att));
- if (state)
- C.addTransition(state);
+ for (OwnershipAttr::args_iterator I = Att->args_begin(), E = Att->args_end();
+ I != E; ++I) {
+ const GRState *state = FreeMemAux(C, CE, C.getState(), *I,
+ Att->getOwnKind() == OwnershipAttr::Holds);
+ if (state)
+ C.addTransition(state);
}
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Aug 18 18:23:40 2010
@@ -150,11 +150,11 @@
if (const VisibilityAttr *attr = D->getAttr<VisibilityAttr>()) {
switch (attr->getVisibility()) {
default: assert(0 && "Unknown visibility!");
- case VisibilityAttr::DefaultVisibility:
+ case VisibilityAttr::Default:
return LangOptions::Default;
- case VisibilityAttr::HiddenVisibility:
+ case VisibilityAttr::Hidden:
return LangOptions::Hidden;
- case VisibilityAttr::ProtectedVisibility:
+ case VisibilityAttr::Protected:
return LangOptions::Protected;
}
}
@@ -461,12 +461,10 @@
else if (Features.getStackProtectorMode() == LangOptions::SSPReq)
F->addFnAttr(llvm::Attribute::StackProtectReq);
- if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) {
- unsigned width = Context.Target.getCharWidth();
- F->setAlignment(AA->getAlignment() / width);
- while ((AA = AA->getNext<AlignedAttr>()))
- F->setAlignment(std::max(F->getAlignment(), AA->getAlignment() / width));
- }
+ unsigned alignment = D->getMaxAlignment() / Context.getCharWidth();
+ if (alignment)
+ F->setAlignment(alignment);
+
// C++ ABI requires 2-byte alignment for member functions.
if (F->getAlignment() < 2 && isa<CXXMethodDecl>(D))
F->setAlignment(2);
Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Wed Aug 18 18:23:40 2010
@@ -14,6 +14,7 @@
#include "clang/Sema/Sema.h"
#include "clang/Sema/Lookup.h"
+#include "clang/AST/Attr.h"
#include "clang/AST/Expr.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
@@ -120,9 +121,11 @@
// Otherwise, check to see if we need a max field alignment attribute.
if (unsigned Alignment = Stack->getAlignment()) {
if (Alignment == PackStackEntry::kMac68kAlignmentSentinel)
- RD->addAttr(::new (Context) AlignMac68kAttr());
+ RD->addAttr(::new (Context) AlignMac68kAttr(SourceLocation(), Context));
else
- RD->addAttr(::new (Context) MaxFieldAlignmentAttr(Alignment * 8));
+ RD->addAttr(::new (Context) MaxFieldAlignmentAttr(SourceLocation(),
+ Context,
+ Alignment * 8));
}
}
@@ -285,11 +288,12 @@
continue;
}
- VD->addAttr(::new (Context) UnusedAttr());
+ VD->addAttr(::new (Context) UnusedAttr(Tok.getLocation(), Context));
}
}
-typedef std::vector<VisibilityAttr::VisibilityTypes> VisStack;
+typedef std::vector<std::pair<VisibilityAttr::VisibilityType,
+ SourceLocation> > VisStack;
void Sema::AddPushedVisibilityAttribute(Decl *D) {
if (!VisContext)
@@ -299,9 +303,10 @@
return;
VisStack *Stack = static_cast<VisStack*>(VisContext);
- VisibilityAttr::VisibilityTypes type = Stack->back();
+ VisibilityAttr::VisibilityType type = Stack->back().first;
+ SourceLocation loc = Stack->back().second;
- D->addAttr(::new (Context) VisibilityAttr(type, true));
+ D->addAttr(::new (Context) VisibilityAttr(loc, Context, type));
}
/// FreeVisContext - Deallocate and null out VisContext.
@@ -314,33 +319,34 @@
SourceLocation PragmaLoc) {
if (IsPush) {
// Compute visibility to use.
- VisibilityAttr::VisibilityTypes type;
+ VisibilityAttr::VisibilityType type;
if (VisType->isStr("default"))
- type = VisibilityAttr::DefaultVisibility;
+ type = VisibilityAttr::Default;
else if (VisType->isStr("hidden"))
- type = VisibilityAttr::HiddenVisibility;
+ type = VisibilityAttr::Hidden;
else if (VisType->isStr("internal"))
- type = VisibilityAttr::HiddenVisibility; // FIXME
+ type = VisibilityAttr::Hidden; // FIXME
else if (VisType->isStr("protected"))
- type = VisibilityAttr::ProtectedVisibility;
+ type = VisibilityAttr::Protected;
else {
Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
VisType->getName();
return;
}
- PushPragmaVisibility(type);
+ PushPragmaVisibility(type, PragmaLoc);
} else {
PopPragmaVisibility();
}
}
-void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityTypes type) {
+void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityType type,
+ SourceLocation loc) {
// Put visibility on stack.
if (!VisContext)
VisContext = new VisStack;
VisStack *Stack = static_cast<VisStack*>(VisContext);
- Stack->push_back(type);
+ Stack->push_back(std::make_pair(type, loc));
}
void Sema::PopPragmaVisibility() {
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Aug 18 18:23:40 2010
@@ -347,9 +347,12 @@
}
}
- for (const NonNullAttr *NonNull = FDecl->getAttr<NonNullAttr>(); NonNull;
- NonNull = NonNull->getNext<NonNullAttr>())
- CheckNonNullArguments(NonNull, TheCall);
+ specific_attr_iterator<NonNullAttr>
+ i = FDecl->specific_attr_begin<NonNullAttr>(),
+ e = FDecl->specific_attr_end<NonNullAttr>();
+
+ for (; i != e; ++i)
+ CheckNonNullArguments(*i, TheCall);
return false;
}
@@ -1041,7 +1044,8 @@
void
Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
const CallExpr *TheCall) {
- for (NonNullAttr::iterator i = NonNull->begin(), e = NonNull->end();
+ for (NonNullAttr::args_iterator i = NonNull->args_begin(),
+ e = NonNull->args_end();
i != e; ++i) {
const Expr *ArgExpr = TheCall->getArg(*i);
if (ArgExpr->isNullPointerConstant(Context,
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Aug 18 18:23:40 2010
@@ -997,19 +997,32 @@
/// DeclhasAttr - returns true if decl Declaration already has the target
/// attribute.
static bool
-DeclHasAttr(const Decl *decl, const Attr *target) {
- for (const Attr *attr = decl->getAttrs(); attr; attr = attr->getNext())
- if (attr->getKind() == target->getKind())
+DeclHasAttr(const Decl *D, const Attr *A) {
+ const OwnershipAttr *OA = dyn_cast<OwnershipAttr>(A);
+ for (Decl::attr_iterator i = D->attr_begin(), e = D->attr_end(); i != e; ++i)
+ if ((*i)->getKind() == A->getKind()) {
+ // FIXME: Don't hardcode this check
+ if (OA && isa<OwnershipAttr>(*i))
+ return OA->getOwnKind() == cast<OwnershipAttr>(*i)->getOwnKind();
return true;
+ }
return false;
}
-/// MergeAttributes - append attributes from the Old decl to the New one.
-static void MergeAttributes(Decl *New, Decl *Old, ASTContext &C) {
- for (const Attr *attr = Old->getAttrs(); attr; attr = attr->getNext()) {
- if (!DeclHasAttr(New, attr) && attr->isMerged()) {
- Attr *NewAttr = attr->clone(C);
+/// MergeDeclAttributes - append attributes from the Old decl to the New one.
+static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) {
+ if (!Old->hasAttrs())
+ return;
+ // Ensure that any moving of objects within the allocated map is done before
+ // we process them.
+ if (!New->hasAttrs())
+ New->setAttrs(AttrVec());
+ for (Decl::attr_iterator i = Old->attr_begin(), e = Old->attr_end(); i != e;
+ ++i) {
+ // FIXME: Make this more general than just checking for Overloadable.
+ if (!DeclHasAttr(New, *i) && (*i)->getKind() != attr::Overloadable) {
+ Attr *NewAttr = (*i)->clone(C);
NewAttr->setInherited(true);
New->addAttr(NewAttr);
}
@@ -1402,7 +1415,7 @@
/// \returns false
bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old) {
// Merge the attributes
- MergeAttributes(New, Old, Context);
+ MergeDeclAttributes(New, Old, Context);
// Merge the storage class.
if (Old->getStorageClass() != FunctionDecl::Extern &&
@@ -1447,7 +1460,7 @@
return New->setInvalidDecl();
}
- MergeAttributes(New, Old, Context);
+ MergeDeclAttributes(New, Old, Context);
// Merge the types
QualType MergedT;
@@ -1611,9 +1624,7 @@
}
if (RecordDecl *Record = dyn_cast_or_null<RecordDecl>(Tag)) {
- // If there are attributes in the DeclSpec, apply them to the record.
- if (const AttributeList *AL = DS.getAttributes())
- ProcessDeclAttributeList(S, Record, AL);
+ ProcessDeclAttributeList(S, Record, DS.getAttributes());
if (!Record->getDeclName() && Record->isDefinition() &&
DS.getStorageClassSpec() != DeclSpec::SCS_typedef) {
@@ -2770,7 +2781,8 @@
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewVD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+ NewVD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0),
+ Context, SE->getString()));
}
// Diagnose shadowed variables before filtering for scope.
@@ -2810,6 +2822,8 @@
NewVD->setInvalidDecl();
// attributes declared post-definition are currently ignored
+ // FIXME: This should be handled in attribute merging, not
+ // here.
if (Previous.isSingleResult()) {
VarDecl *Def = dyn_cast<VarDecl>(Previous.getFoundDecl());
if (Def && (Def = Def->getDefinition()) &&
@@ -3447,7 +3461,8 @@
if (Expr *E = (Expr*) D.getAsmLabel()) {
// The parser guarantees this is a string.
StringLiteral *SE = cast<StringLiteral>(E);
- NewFD->addAttr(::new (Context) AsmLabelAttr(Context, SE->getString()));
+ NewFD->addAttr(::new (Context) AsmLabelAttr(SE->getStrTokenLoc(0), Context,
+ SE->getString()));
}
// Copy the parameter declarations from the declarator D to the function
@@ -3673,6 +3688,7 @@
ProcessDeclAttributes(S, NewFD, D);
// attributes declared post-definition are currently ignored
+ // FIXME: This should happen during attribute merging
if (Redeclaration && Previous.isSingleResult()) {
const FunctionDecl *Def;
FunctionDecl *PrevFD = dyn_cast<FunctionDecl>(Previous.getFoundDecl());
@@ -3684,7 +3700,7 @@
AddKnownFunctionAttributes(NewFD);
- if (OverloadableAttrRequired && !NewFD->getAttr<OverloadableAttr>()) {
+ if (OverloadableAttrRequired && !NewFD->hasAttr<OverloadableAttr>()) {
// If a function name is overloadable in C, then every function
// with that name must be marked "overloadable".
Diag(NewFD->getLocation(), diag::err_attribute_overloadable_missing)
@@ -3692,7 +3708,7 @@
if (!Previous.empty())
Diag(Previous.getRepresentativeDecl()->getLocation(),
diag::note_attribute_overloadable_prev_overload);
- NewFD->addAttr(::new (Context) OverloadableAttr());
+ NewFD->addAttr(::new (Context) OverloadableAttr(SourceLocation(), Context));
}
if (NewFD->hasAttr<OverloadableAttr>() &&
@@ -4792,10 +4808,10 @@
// Checking attributes of current function definition
// dllimport attribute.
- if (FD->getAttr<DLLImportAttr>() &&
- (!FD->getAttr<DLLExportAttr>())) {
- // dllimport attribute cannot be applied to definition.
- if (!(FD->getAttr<DLLImportAttr>())->isInherited()) {
+ DLLImportAttr *DA = FD->getAttr<DLLImportAttr>();
+ if (DA && (!FD->getAttr<DLLExportAttr>())) {
+ // dllimport attribute cannot be directly applied to definition.
+ if (!DA->isInherited()) {
Diag(FD->getLocation(),
diag::err_attribute_can_be_applied_only_to_symbol_declaration)
<< "dllimport";
@@ -5041,7 +5057,7 @@
CurContext = Context.getTranslationUnitDecl();
FunctionDecl *FD =
- dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
+ dyn_cast<FunctionDecl>(ActOnDeclarator(TUScope, D).getAs<Decl>());
FD->setImplicit();
CurContext = PrevDC;
@@ -5069,13 +5085,15 @@
bool HasVAListArg;
if (Context.BuiltinInfo.isPrintfLike(BuiltinID, FormatIdx, HasVAListArg)) {
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", FormatIdx+1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", FormatIdx+1,
HasVAListArg ? 0 : FormatIdx+2));
}
if (Context.BuiltinInfo.isScanfLike(BuiltinID, FormatIdx,
HasVAListArg)) {
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "scanf", FormatIdx+1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "scanf", FormatIdx+1,
HasVAListArg ? 0 : FormatIdx+2));
}
@@ -5085,15 +5103,15 @@
if (!getLangOptions().MathErrno &&
Context.BuiltinInfo.isConstWithoutErrno(BuiltinID)) {
if (!FD->getAttr<ConstAttr>())
- FD->addAttr(::new (Context) ConstAttr());
+ FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
if (Context.BuiltinInfo.isNoReturn(BuiltinID))
FD->setType(Context.getNoReturnType(FD->getType()));
if (Context.BuiltinInfo.isNoThrow(BuiltinID))
- FD->addAttr(::new (Context) NoThrowAttr());
+ FD->addAttr(::new (Context) NoThrowAttr(FD->getLocation(), Context));
if (Context.BuiltinInfo.isConst(BuiltinID))
- FD->addAttr(::new (Context) ConstAttr());
+ FD->addAttr(::new (Context) ConstAttr(FD->getLocation(), Context));
}
IdentifierInfo *Name = FD->getIdentifier();
@@ -5115,13 +5133,15 @@
// FIXME: We known better than our headers.
const_cast<FormatAttr *>(Format)->setType(Context, "printf");
} else
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", 1,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", 1,
Name->isStr("NSLogv") ? 0 : 2));
} else if (Name->isStr("asprintf") || Name->isStr("vasprintf")) {
// FIXME: asprintf and vasprintf aren't C99 functions. Should they be
// target-specific builtins, perhaps?
if (!FD->getAttr<FormatAttr>())
- FD->addAttr(::new (Context) FormatAttr(Context, "printf", 2,
+ FD->addAttr(::new (Context) FormatAttr(FD->getLocation(), Context,
+ "printf", 2,
Name->isStr("vasprintf") ? 0 : 3));
}
}
@@ -7009,7 +7029,7 @@
Decl *PrevDecl = LookupSingleName(TUScope, Name, NameLoc, LookupOrdinaryName);
if (PrevDecl) {
- PrevDecl->addAttr(::new (Context) WeakAttr());
+ PrevDecl->addAttr(::new (Context) WeakAttr(PragmaLoc, Context));
} else {
(void)WeakUndeclaredIdentifiers.insert(
std::pair<IdentifierInfo*,WeakInfo>
Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Wed Aug 18 18:23:40 2010
@@ -211,7 +211,7 @@
}
if (TagDecl *TD = dyn_cast<TagDecl>(d))
- TD->addAttr(::new (S.Context) PackedAttr);
+ TD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
else if (FieldDecl *FD = dyn_cast<FieldDecl>(d)) {
// If the alignment is less than or equal to 8 bits, the packed attribute
// has no effect.
@@ -220,7 +220,7 @@
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
<< Attr.getName() << FD->getType();
else
- FD->addAttr(::new (S.Context) PackedAttr);
+ FD->addAttr(::new (S.Context) PackedAttr(Attr.getLoc(), S.Context));
} else
S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
}
@@ -235,7 +235,7 @@
// The IBAction attributes only apply to instance methods.
if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(d))
if (MD->isInstanceMethod()) {
- d->addAttr(::new (S.Context) IBActionAttr());
+ d->addAttr(::new (S.Context) IBActionAttr(Attr.getLoc(), S.Context));
return;
}
@@ -252,7 +252,7 @@
// The IBOutlet attributes only apply to instance variables of
// Objective-C classes.
if (isa<ObjCIvarDecl>(d) || isa<ObjCPropertyDecl>(d)) {
- d->addAttr(::new (S.Context) IBOutletAttr());
+ d->addAttr(::new (S.Context) IBOutletAttr(Attr.getLoc(), S.Context));
return;
}
@@ -307,7 +307,8 @@
S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
return;
}
- d->addAttr(::new (S.Context) IBOutletCollectionAttr(QT));
+ d->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getLoc(), S.Context,
+ QT));
}
static void HandleNonNullAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -378,7 +379,8 @@
unsigned* start = &NonNullArgs[0];
unsigned size = NonNullArgs.size();
llvm::array_pod_sort(start, start + size);
- d->addAttr(::new (S.Context) NonNullAttr(S.Context, start, size));
+ d->addAttr(::new (S.Context) NonNullAttr(Attr.getLoc(), S.Context, start,
+ size));
}
static void HandleOwnershipAttr(Decl *d, const AttributeList &AL, Sema &S) {
@@ -397,24 +399,24 @@
return;
}
// Figure out our Kind, and check arguments while we're at it.
- attr::Kind K;
+ OwnershipAttr::OwnershipKind K;
switch (AL.getKind()) {
case AttributeList::AT_ownership_takes:
- K = attr::OwnershipTakes;
+ K = OwnershipAttr::Takes;
if (AL.getNumArgs() < 1) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
return;
}
break;
case AttributeList::AT_ownership_holds:
- K = attr::OwnershipHolds;
+ K = OwnershipAttr::Holds;
if (AL.getNumArgs() < 1) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
return;
}
break;
case AttributeList::AT_ownership_returns:
- K = attr::OwnershipReturns;
+ K = OwnershipAttr::Returns;
if (AL.getNumArgs() > 1) {
S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments)
<< AL.getNumArgs() + 1;
@@ -463,21 +465,21 @@
}
--x;
switch (K) {
- case attr::OwnershipTakes:
- case attr::OwnershipHolds: {
+ case OwnershipAttr::Takes:
+ case OwnershipAttr::Holds: {
// Is the function argument a pointer type?
QualType T = getFunctionOrMethodArgType(d, x);
if (!T->isAnyPointerType() && !T->isBlockPointerType()) {
// FIXME: Should also highlight argument in decl.
S.Diag(AL.getLoc(), diag::err_ownership_type)
- << ((K==attr::OwnershipTakes)?"ownership_takes":"ownership_holds")
+ << ((K==OwnershipAttr::Takes)?"ownership_takes":"ownership_holds")
<< "pointer"
<< IdxExpr->getSourceRange();
continue;
}
break;
}
- case attr::OwnershipReturns: {
+ case OwnershipAttr::Returns: {
if (AL.getNumArgs() > 1) {
// Is the function argument an integer type?
Expr *IdxExpr = static_cast<Expr *>(AL.getArg(0));
@@ -497,18 +499,16 @@
} // switch
// Check we don't have a conflict with another ownership attribute.
- if (K != attr::OwnershipReturns && d->hasAttrs()) {
- for (const Attr *attr = d->getAttrs(); attr; attr = attr->getNext()) {
- if (const OwnershipAttr* Att = dyn_cast<OwnershipAttr>(attr)) {
- // Two ownership attributes of the same kind can't conflict,
- // except returns attributes.
- if (Att->getKind() != K) {
- for (const unsigned *I = Att->begin(), *E = Att->end(); I!=E; ++I) {
- if (x == *I) {
- S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
- << AL.getName()->getName() << "ownership_*";
- }
- }
+ for (specific_attr_iterator<OwnershipAttr>
+ i = d->specific_attr_begin<OwnershipAttr>(),
+ e = d->specific_attr_end<OwnershipAttr>();
+ i != e; ++i) {
+ if ((*i)->getOwnKind() != K) {
+ for (const unsigned *I = (*i)->args_begin(), *E = (*i)->args_end();
+ I!=E; ++I) {
+ if (x == *I) {
+ S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
+ << AL.getName()->getName() << "ownership_*";
}
}
}
@@ -519,33 +519,14 @@
unsigned* start = OwnershipArgs.data();
unsigned size = OwnershipArgs.size();
llvm::array_pod_sort(start, start + size);
- switch (K) {
- case attr::OwnershipTakes: {
- if (OwnershipArgs.empty()) {
- S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
- return;
- }
- d->addAttr(::new (S.Context) OwnershipTakesAttr(S.Context, start, size,
- Module));
- break;
- }
- case attr::OwnershipHolds: {
- if (OwnershipArgs.empty()) {
- S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
- return;
- }
- d->addAttr(::new (S.Context) OwnershipHoldsAttr(S.Context, start, size,
- Module));
- break;
- }
- case attr::OwnershipReturns: {
- d->addAttr(::new (S.Context) OwnershipReturnsAttr(S.Context, start, size,
- Module));
- break;
- }
- default:
- llvm_unreachable("Unknown ownership attribute");
+
+ if (K != OwnershipAttr::Returns && OwnershipArgs.empty()) {
+ S.Diag(AL.getLoc(), diag::err_attribute_wrong_number_arguments) << 2;
+ return;
}
+
+ d->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
+ start, size));
}
static bool isStaticVarOrStaticFunciton(Decl *D) {
@@ -622,10 +603,10 @@
}
// GCC will accept anything as the argument of weakref. Should we
// check for an existing decl?
- d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
}
- d->addAttr(::new (S.Context) WeakRefAttr());
+ d->addAttr(::new (S.Context) WeakRefAttr(Attr.getLoc(), S.Context));
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -647,7 +628,7 @@
// FIXME: check if target symbol exists in current file
- d->addAttr(::new (S.Context) AliasAttr(S.Context, Str->getString()));
+ d->addAttr(::new (S.Context) AliasAttr(Attr.getLoc(), S.Context, Str->getString()));
}
static void HandleAlwaysInlineAttr(Decl *d, const AttributeList &Attr,
@@ -664,7 +645,7 @@
return;
}
- d->addAttr(::new (S.Context) AlwaysInlineAttr());
+ d->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleMallocAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -677,7 +658,7 @@
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(d)) {
QualType RetTy = FD->getResultType();
if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
- d->addAttr(::new (S.Context) MallocAttr());
+ d->addAttr(::new (S.Context) MallocAttr(Attr.getLoc(), S.Context));
return;
}
}
@@ -711,13 +692,13 @@
static void HandleNoReturnAttr(Decl *d, const AttributeList &Attr, Sema &S) {
/* Diagnostics (if any) was emitted by Sema::ProcessFnAttr(). */
assert(Attr.isInvalid() == false);
- d->addAttr(::new (S.Context) NoReturnAttr());
+ d->addAttr(::new (S.Context) NoReturnAttr(Attr.getLoc(), S.Context));
}
static void HandleAnalyzerNoReturnAttr(Decl *d, const AttributeList &Attr,
Sema &S) {
if (HandleCommonNoReturnAttr(d, Attr, S))
- d->addAttr(::new (S.Context) AnalyzerNoReturnAttr());
+ d->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getLoc(), S.Context));
}
// PS3 PPU-specific.
@@ -756,7 +737,7 @@
return;
}
- d->addAttr(::new (S.Context) VecReturnAttr());
+ d->addAttr(::new (S.Context) VecReturnAttr(Attr.getLoc(), S.Context));
}
static void HandleDependencyAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -782,7 +763,7 @@
return;
}
- d->addAttr(::new (S.Context) UnusedAttr());
+ d->addAttr(::new (S.Context) UnusedAttr(Attr.getLoc(), S.Context));
}
static void HandleUsedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -803,7 +784,7 @@
return;
}
- d->addAttr(::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
static void HandleConstructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -833,7 +814,7 @@
return;
}
- d->addAttr(::new (S.Context) ConstructorAttr(priority));
+ d->addAttr(::new (S.Context) ConstructorAttr(Attr.getLoc(), S.Context, priority));
}
static void HandleDestructorAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -863,7 +844,7 @@
return;
}
- d->addAttr(::new (S.Context) DestructorAttr(priority));
+ d->addAttr(::new (S.Context) DestructorAttr(Attr.getLoc(), S.Context, priority));
}
static void HandleDeprecatedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -873,7 +854,7 @@
return;
}
- d->addAttr(::new (S.Context) DeprecatedAttr());
+ d->addAttr(::new (S.Context) DeprecatedAttr(Attr.getLoc(), S.Context));
}
static void HandleUnavailableAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -883,7 +864,7 @@
return;
}
- d->addAttr(::new (S.Context) UnavailableAttr());
+ d->addAttr(::new (S.Context) UnavailableAttr(Attr.getLoc(), S.Context));
}
static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -904,22 +885,22 @@
}
llvm::StringRef TypeStr = Str->getString();
- VisibilityAttr::VisibilityTypes type;
+ VisibilityAttr::VisibilityType type;
if (TypeStr == "default")
- type = VisibilityAttr::DefaultVisibility;
+ type = VisibilityAttr::Default;
else if (TypeStr == "hidden")
- type = VisibilityAttr::HiddenVisibility;
+ type = VisibilityAttr::Hidden;
else if (TypeStr == "internal")
- type = VisibilityAttr::HiddenVisibility; // FIXME
+ type = VisibilityAttr::Hidden; // FIXME
else if (TypeStr == "protected")
- type = VisibilityAttr::ProtectedVisibility;
+ type = VisibilityAttr::Protected;
else {
S.Diag(Attr.getLoc(), diag::warn_attribute_unknown_visibility) << TypeStr;
return;
}
- d->addAttr(::new (S.Context) VisibilityAttr(type, false));
+ d->addAttr(::new (S.Context) VisibilityAttr(Attr.getLoc(), S.Context, type));
}
static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
@@ -935,7 +916,7 @@
return;
}
- D->addAttr(::new (S.Context) ObjCExceptionAttr());
+ D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getLoc(), S.Context));
}
static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -951,7 +932,7 @@
return;
}
}
- D->addAttr(::new (S.Context) ObjCNSObjectAttr());
+ D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getLoc(), S.Context));
}
static void
@@ -966,7 +947,7 @@
return;
}
- D->addAttr(::new (S.Context) OverloadableAttr());
+ D->addAttr(::new (S.Context) OverloadableAttr(Attr.getLoc(), S.Context));
}
static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -981,7 +962,7 @@
return;
}
- BlocksAttr::BlocksAttrTypes type;
+ BlocksAttr::BlockType type;
if (Attr.getParameterName()->isStr("byref"))
type = BlocksAttr::ByRef;
else {
@@ -990,7 +971,7 @@
return;
}
- d->addAttr(::new (S.Context) BlocksAttr(type));
+ d->addAttr(::new (S.Context) BlocksAttr(Attr.getLoc(), S.Context, type));
}
static void HandleSentinelAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1083,7 +1064,7 @@
<< Attr.getName() << 6 /*function, method or block */;
return;
}
- d->addAttr(::new (S.Context) SentinelAttr(sentinel, nullPos));
+ d->addAttr(::new (S.Context) SentinelAttr(Attr.getLoc(), S.Context, sentinel, nullPos));
}
static void HandleWarnUnusedResult(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1111,7 +1092,7 @@
return;
}
- D->addAttr(::new (S.Context) WarnUnusedResultAttr());
+ D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getLoc(), S.Context));
}
static void HandleWeakAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1135,7 +1116,7 @@
return;
}
- D->addAttr(::new (S.Context) WeakAttr());
+ D->addAttr(::new (S.Context) WeakAttr(Attr.getLoc(), S.Context));
}
static void HandleWeakImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1171,7 +1152,7 @@
return;
}
- D->addAttr(::new (S.Context) WeakImportAttr());
+ D->addAttr(::new (S.Context) WeakImportAttr(Attr.getLoc(), S.Context));
}
static void HandleReqdWorkGroupSize(Decl *D, const AttributeList &Attr,
@@ -1194,7 +1175,8 @@
}
WGSize[i] = (unsigned) ArgNum.getZExtValue();
}
- D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(WGSize[0], WGSize[1],
+ D->addAttr(::new (S.Context) ReqdWorkGroupSizeAttr(Attr.getLoc(), S.Context,
+ WGSize[0], WGSize[1],
WGSize[2]));
}
@@ -1228,7 +1210,7 @@
return;
}
- D->addAttr(::new (S.Context) SectionAttr(S.Context, SE->getString()));
+ D->addAttr(::new (S.Context) SectionAttr(Attr.getLoc(), S.Context, SE->getString()));
}
@@ -1239,7 +1221,7 @@
return;
}
- d->addAttr(::new (S.Context) NoThrowAttr());
+ d->addAttr(::new (S.Context) NoThrowAttr(Attr.getLoc(), S.Context));
}
static void HandleConstAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1249,7 +1231,7 @@
return;
}
- d->addAttr(::new (S.Context) ConstAttr());
+ d->addAttr(::new (S.Context) ConstAttr(Attr.getLoc(), S.Context));
}
static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1259,7 +1241,7 @@
return;
}
- d->addAttr(::new (S.Context) PureAttr());
+ d->addAttr(::new (S.Context) PureAttr(Attr.getLoc(), S.Context));
}
static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1317,7 +1299,7 @@
return;
}
- d->addAttr(::new (S.Context) CleanupAttr(FD));
+ d->addAttr(::new (S.Context) CleanupAttr(Attr.getLoc(), S.Context, FD));
}
/// Handle __attribute__((format_arg((idx)))) attribute based on
@@ -1380,7 +1362,7 @@
return;
}
- d->addAttr(::new (S.Context) FormatArgAttr(Idx.getZExtValue()));
+ d->addAttr(::new (S.Context) FormatArgAttr(Attr.getLoc(), S.Context, Idx.getZExtValue()));
}
enum FormatAttrKind {
@@ -1462,7 +1444,7 @@
Attr.setInvalid();
return;
}
- d->addAttr(::new (S.Context) InitPriorityAttr(prioritynum));
+ d->addAttr(::new (S.Context) InitPriorityAttr(Attr.getLoc(), S.Context, prioritynum));
}
/// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -1606,7 +1588,8 @@
return;
}
- d->addAttr(::new (S.Context) FormatAttr(S.Context, Format, Idx.getZExtValue(),
+ d->addAttr(::new (S.Context) FormatAttr(Attr.getLoc(), S.Context, Format,
+ Idx.getZExtValue(),
FirstArg.getZExtValue()));
}
@@ -1675,7 +1658,7 @@
}
}
- RD->addAttr(::new (S.Context) TransparentUnionAttr());
+ RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getLoc(), S.Context));
}
static void HandleAnnotateAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1693,7 +1676,7 @@
S.Diag(ArgExpr->getLocStart(), diag::err_attribute_not_string) <<"annotate";
return;
}
- d->addAttr(::new (S.Context) AnnotateAttr(S.Context, SE->getString()));
+ d->addAttr(::new (S.Context) AnnotateAttr(Attr.getLoc(), S.Context, SE->getString()));
}
static void HandleAlignedAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -1708,9 +1691,7 @@
// weaker alignment, rather than being silently ignored.
if (Attr.getNumArgs() == 0) {
- // FIXME: This should be the target specific maximum alignment.
- // (For now we just use 128 bits which is the maximum on X86).
- D->addAttr(::new (S.Context) AlignedAttr(128));
+ D->addAttr(::new (S.Context) AlignedAttr(Attr.getLoc(), S.Context, true, 0));
return;
}
@@ -1720,10 +1701,11 @@
void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E) {
if (E->isTypeDependent() || E->isValueDependent()) {
// Save dependent expressions in the AST to be instantiated.
- D->addAttr(::new (Context) AlignedAttr(E));
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
return;
}
+ // FIXME: Cache the number on the Attr object?
llvm::APSInt Alignment(32);
if (!E->isIntegerConstantExpr(Alignment, Context)) {
Diag(AttrLoc, diag::err_attribute_argument_not_int)
@@ -1736,7 +1718,14 @@
return;
}
- D->addAttr(::new (Context) AlignedAttr(Alignment.getZExtValue() * 8));
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, true, E));
+}
+
+void Sema::AddAlignedAttr(SourceLocation AttrLoc, Decl *D, TypeSourceInfo *TS) {
+ // FIXME: Cache the number on the Attr object if non-dependent?
+ // FIXME: Perform checking of type validity
+ D->addAttr(::new (Context) AlignedAttr(AttrLoc, Context, false, TS));
+ return;
}
/// HandleModeAttr - This attribute modifies the width of a decl with primitive
@@ -1923,7 +1912,7 @@
return;
}
- d->addAttr(::new (S.Context) NoDebugAttr());
+ d->addAttr(::new (S.Context) NoDebugAttr(Attr.getLoc(), S.Context));
}
static void HandleNoInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1939,7 +1928,7 @@
return;
}
- d->addAttr(::new (S.Context) NoInlineAttr());
+ d->addAttr(::new (S.Context) NoInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleNoInstrumentFunctionAttr(Decl *d, const AttributeList &Attr,
@@ -1956,7 +1945,7 @@
return;
}
- d->addAttr(::new (S.Context) NoInstrumentFunctionAttr());
+ d->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getLoc(), S.Context));
}
static void HandleGNUInlineAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1978,7 +1967,7 @@
return;
}
- d->addAttr(::new (S.Context) GNUInlineAttr());
+ d->addAttr(::new (S.Context) GNUInlineAttr(Attr.getLoc(), S.Context));
}
static void HandleCallConvAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -1988,15 +1977,15 @@
switch (Attr.getKind()) {
case AttributeList::AT_fastcall:
- d->addAttr(::new (S.Context) FastCallAttr());
+ d->addAttr(::new (S.Context) FastCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_stdcall:
- d->addAttr(::new (S.Context) StdCallAttr());
+ d->addAttr(::new (S.Context) StdCallAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_thiscall:
- d->addAttr(::new (S.Context) ThisCallAttr());
+ d->addAttr(::new (S.Context) ThisCallAttr(Attr.getLoc(), S.Context));
case AttributeList::AT_cdecl:
- d->addAttr(::new (S.Context) CDeclAttr());
+ d->addAttr(::new (S.Context) CDeclAttr(Attr.getLoc(), S.Context));
return;
default:
llvm_unreachable("unexpected attribute kind");
@@ -2038,7 +2027,8 @@
return;
}
- d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
+ d->addAttr(::new (S.Context) RegparmAttr(Attr.getLoc(), S.Context,
+ NumParams.getZExtValue()));
}
static void HandleFinalAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2064,7 +2054,7 @@
return;
}
- d->addAttr(::new (S.Context) FinalAttr());
+ d->addAttr(::new (S.Context) FinalAttr(Attr.getLoc(), S.Context));
}
//===----------------------------------------------------------------------===//
@@ -2090,7 +2080,7 @@
return;
}
- d->addAttr(::new (S.Context) BaseCheckAttr());
+ d->addAttr(::new (S.Context) BaseCheckAttr(Attr.getLoc(), S.Context));
}
static void HandleHidingAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2115,7 +2105,7 @@
return;
}
- d->addAttr(::new (S.Context) HidingAttr());
+ d->addAttr(::new (S.Context) HidingAttr(Attr.getLoc(), S.Context));
}
static void HandleOverrideAttr(Decl *d, const AttributeList &Attr, Sema &S) {
@@ -2140,7 +2130,7 @@
return;
}
- d->addAttr(::new (S.Context) OverrideAttr());
+ d->addAttr(::new (S.Context) OverrideAttr(Attr.getLoc(), S.Context));
}
//===----------------------------------------------------------------------===//
@@ -2176,16 +2166,16 @@
assert(0 && "invalid ownership attribute");
return;
case AttributeList::AT_cf_returns_not_retained:
- d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_ns_returns_not_retained:
- d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_cf_returns_retained:
- d->addAttr(::new (S.Context) CFReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getLoc(), S.Context));
return;
case AttributeList::AT_ns_returns_retained:
- d->addAttr(::new (S.Context) NSReturnsRetainedAttr());
+ d->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getLoc(), S.Context));
return;
};
}
@@ -2369,8 +2359,9 @@
if (W.getAlias()) { // clone decl, impersonate __attribute(weak,alias(...))
IdentifierInfo *NDId = ND->getIdentifier();
NamedDecl *NewD = DeclClonePragmaWeak(ND, W.getAlias());
- NewD->addAttr(::new (Context) AliasAttr(Context, NDId->getName()));
- NewD->addAttr(::new (Context) WeakAttr());
+ NewD->addAttr(::new (Context) AliasAttr(W.getLocation(), Context,
+ NDId->getName()));
+ NewD->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
WeakTopLevelDecl.push_back(NewD);
// FIXME: "hideous" code from Sema::LazilyCreateBuiltin
// to insert Decl at TU scope, sorry.
@@ -2379,7 +2370,7 @@
PushOnScopeChains(NewD, S);
CurContext = SavedContext;
} else { // just add weak to existing
- ND->addAttr(::new (Context) WeakAttr());
+ ND->addAttr(::new (Context) WeakAttr(W.getLocation(), Context));
}
}
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Aug 18 18:23:40 2010
@@ -3292,7 +3292,7 @@
ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
- PushPragmaVisibility(attr->getVisibility());
+ PushPragmaVisibility(attr->getVisibility(), attr->getLocation());
if (II) {
// C++ [namespace.def]p2:
Modified: cfe/trunk/lib/Sema/SemaDeclObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclObjC.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclObjC.cpp Wed Aug 18 18:23:40 2010
@@ -1454,13 +1454,14 @@
}
static inline
-bool containsInvalidMethodImplAttribute(const AttributeList *A) {
+bool containsInvalidMethodImplAttribute(const AttrVec &A) {
// The 'ibaction' attribute is allowed on method definitions because of
// how the IBAction macro is used on both method declarations and definitions.
// If the method definitions contains any other attributes, return true.
- while (A && A->getKind() == AttributeList::AT_IBAction)
- A = A->getNext();
- return A != NULL;
+ for (AttrVec::const_iterator i = A.begin(), e = A.end(); i != e; ++i)
+ if ((*i)->getKind() != attr::IBAction)
+ return true;
+ return false;
}
Sema::DeclPtrTy Sema::ActOnMethodDeclaration(
@@ -1590,7 +1591,8 @@
}
InterfaceMD = ImpDecl->getClassInterface()->getMethod(Sel,
MethodType == tok::minus);
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
} else if (ObjCCategoryImplDecl *CatImpDecl =
dyn_cast<ObjCCategoryImplDecl>(ClassDecl)) {
@@ -1601,7 +1603,8 @@
PrevMethod = CatImpDecl->getClassMethod(Sel);
CatImpDecl->addClassMethod(ObjCMethod);
}
- if (containsInvalidMethodImplAttribute(AttrList))
+ if (ObjCMethod->hasAttrs() &&
+ containsInvalidMethodImplAttribute(ObjCMethod->getAttrs()))
Diag(EndLoc, diag::warn_attribute_method_def);
}
if (PrevMethod) {
@@ -1613,8 +1616,10 @@
// If the interface declared this method, and it was deprecated there,
// mark it deprecated here.
- if (InterfaceMD && InterfaceMD->hasAttr<DeprecatedAttr>())
- ObjCMethod->addAttr(::new (Context) DeprecatedAttr());
+ if (InterfaceMD)
+ if (Attr *DA = InterfaceMD->getAttr<DeprecatedAttr>())
+ ObjCMethod->addAttr(::new (Context) DeprecatedAttr(DA->getLocation(),
+ Context));
return DeclPtrTy::make(ObjCMethod);
}
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Wed Aug 18 18:23:40 2010
@@ -1259,7 +1259,7 @@
// FIXME: Do we need to check for default arguments here?
if (Func->getNumParams() == 1 && InitialParamType == Argument) {
if(AddMallocAttr && !Func->hasAttr<MallocAttr>())
- Func->addAttr(::new (Context) MallocAttr());
+ Func->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
return;
}
}
@@ -1287,7 +1287,7 @@
Alloc->setImplicit();
if (AddMallocAttr)
- Alloc->addAttr(::new (Context) MallocAttr());
+ Alloc->addAttr(::new (Context) MallocAttr(SourceLocation(), Context));
ParmVarDecl *Param = ParmVarDecl::Create(Context, Alloc, SourceLocation(),
0, Argument, /*TInfo=*/0,
Modified: cfe/trunk/lib/Sema/SemaTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplate.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp Wed Aug 18 18:23:40 2010
@@ -4031,7 +4031,7 @@
/// \brief Strips various properties off an implicit instantiation
/// that has just been explicitly specialized.
static void StripImplicitInstantiation(NamedDecl *D) {
- D->invalidateAttrs();
+ D->dropAttrs();
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
FD->setInlineSpecified(false);
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Aug 18 18:23:40 2010
@@ -140,21 +140,30 @@
// FIXME: Is this still too simple?
void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
Decl *Tmpl, Decl *New) {
- for (const Attr *TmplAttr = Tmpl->getAttrs(); TmplAttr;
- TmplAttr = TmplAttr->getNext()) {
+ for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end();
+ i != e; ++i) {
+ const Attr *TmplAttr = *i;
// FIXME: This should be generalized to more than just the AlignedAttr.
if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) {
- if (Aligned->isDependent()) {
+ if (Aligned->isAlignmentDependent()) {
// The alignment expression is not potentially evaluated.
EnterExpressionEvaluationContext Unevaluated(*this,
Action::Unevaluated);
- OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
- TemplateArgs);
- if (!Result.isInvalid())
- // FIXME: Is this the correct source location?
- AddAlignedAttr(Aligned->getAlignmentExpr()->getExprLoc(),
- New, Result.takeAs<Expr>());
+ if (Aligned->isAlignmentExpr()) {
+ OwningExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
+ TemplateArgs);
+ if (!Result.isInvalid())
+ AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>());
+ }
+ else {
+ TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
+ TemplateArgs,
+ Aligned->getLocation(),
+ DeclarationName());
+ if (Result)
+ AddAlignedAttr(Aligned->getLocation(), New, Result);
+ }
continue;
}
}
Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Wed Aug 18 18:23:40 2010
@@ -51,8 +51,8 @@
return;
}
- d->addAttr(::new (S.Context) MSP430InterruptAttr(Num));
- d->addAttr(::new (S.Context) UsedAttr());
+ d->addAttr(::new (S.Context) MSP430InterruptAttr(Attr.getLoc(), S.Context, Num));
+ d->addAttr(::new (S.Context) UsedAttr(Attr.getLoc(), S.Context));
}
namespace {
@@ -97,7 +97,7 @@
return;
}
- D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr());
+ D->addAttr(::new (S.Context) X86ForceAlignArgPointerAttr(Attr.getLoc(), S.Context));
}
static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -109,7 +109,7 @@
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
return;
}
@@ -146,7 +146,7 @@
return;
}
- D->addAttr(::new (S.Context) DLLImportAttr());
+ D->addAttr(::new (S.Context) DLLImportAttr(Attr.getLoc(), S.Context));
}
static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -158,7 +158,7 @@
// Attribute can be applied only to functions or variables.
if (isa<VarDecl>(D)) {
- D->addAttr(::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
return;
}
@@ -177,7 +177,7 @@
return;
}
- D->addAttr(::new (S.Context) DLLExportAttr());
+ D->addAttr(::new (S.Context) DLLExportAttr(Attr.getLoc(), S.Context));
}
namespace {
Modified: cfe/trunk/lib/Serialization/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/CMakeLists.txt?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/CMakeLists.txt (original)
+++ cfe/trunk/lib/Serialization/CMakeLists.txt Wed Aug 18 18:23:40 2010
@@ -13,6 +13,8 @@
add_dependencies(clangSerialization
ClangAttrClasses
ClangAttrList
+ ClangAttrPCHRead
+ ClangAttrPCHWrite
ClangDiagnosticFrontend
ClangDiagnosticLex
ClangDiagnosticSema
Modified: cfe/trunk/lib/Serialization/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/PCHReaderDecl.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/PCHReaderDecl.cpp Wed Aug 18 18:23:40 2010
@@ -148,8 +148,11 @@
cast_or_null<DeclContext>(Reader.GetDecl(Record[Idx++])));
D->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
D->setInvalidDecl(Record[Idx++]);
- if (Record[Idx++])
- D->initAttrs(Reader.ReadAttributes(Cursor));
+ if (Record[Idx++]) {
+ AttrVec Attrs;
+ Reader.ReadAttributes(Cursor, Attrs);
+ D->setAttrs(Attrs);
+ }
D->setImplicit(Record[Idx++]);
D->setUsed(Record[Idx++]);
D->setAccess((AccessSpecifier)Record[Idx++]);
@@ -1091,7 +1094,8 @@
//===----------------------------------------------------------------------===//
/// \brief Reads attributes from the current stream position.
-Attr *PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor) {
+void PCHReader::ReadAttributes(llvm::BitstreamCursor &DeclsCursor,
+ AttrVec &Attrs) {
unsigned Code = DeclsCursor.ReadCode();
assert(Code == llvm::bitc::UNABBREV_RECORD &&
"Expected unabbreviated record"); (void)Code;
@@ -1102,174 +1106,18 @@
assert(RecCode == pch::DECL_ATTR && "Expected attribute record");
(void)RecCode;
-#define SIMPLE_ATTR(Name) \
- case attr::Name: \
- New = ::new (*Context) Name##Attr(); \
- break
-
-#define STRING_ATTR(Name) \
- case attr::Name: \
- New = ::new (*Context) Name##Attr(*Context, ReadString(Record, Idx)); \
- break
-
-#define UNSIGNED_ATTR(Name) \
- case attr::Name: \
- New = ::new (*Context) Name##Attr(Record[Idx++]); \
- break
-
- Attr *Attrs = 0;
while (Idx < Record.size()) {
Attr *New = 0;
attr::Kind Kind = (attr::Kind)Record[Idx++];
- bool IsInherited = Record[Idx++];
-
- switch (Kind) {
- default:
- assert(0 && "Unknown attribute!");
- break;
- STRING_ATTR(Alias);
- SIMPLE_ATTR(AlignMac68k);
- UNSIGNED_ATTR(Aligned);
- SIMPLE_ATTR(AlwaysInline);
- SIMPLE_ATTR(AnalyzerNoReturn);
- STRING_ATTR(Annotate);
- STRING_ATTR(AsmLabel);
- SIMPLE_ATTR(BaseCheck);
-
- case attr::Blocks:
- New = ::new (*Context) BlocksAttr(
- (BlocksAttr::BlocksAttrTypes)Record[Idx++]);
- break;
-
- SIMPLE_ATTR(CDecl);
-
- case attr::Cleanup:
- New = ::new (*Context) CleanupAttr(
- cast<FunctionDecl>(GetDecl(Record[Idx++])));
- break;
-
- SIMPLE_ATTR(Const);
- UNSIGNED_ATTR(Constructor);
- SIMPLE_ATTR(DLLExport);
- SIMPLE_ATTR(DLLImport);
- SIMPLE_ATTR(Deprecated);
- UNSIGNED_ATTR(Destructor);
- SIMPLE_ATTR(FastCall);
- SIMPLE_ATTR(Final);
-
- case attr::Format: {
- std::string Type = ReadString(Record, Idx);
- unsigned FormatIdx = Record[Idx++];
- unsigned FirstArg = Record[Idx++];
- New = ::new (*Context) FormatAttr(*Context, Type, FormatIdx, FirstArg);
- break;
- }
-
- case attr::FormatArg: {
- unsigned FormatIdx = Record[Idx++];
- New = ::new (*Context) FormatArgAttr(FormatIdx);
- break;
- }
-
- case attr::Sentinel: {
- int sentinel = Record[Idx++];
- int nullPos = Record[Idx++];
- New = ::new (*Context) SentinelAttr(sentinel, nullPos);
- break;
- }
+ SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+ bool isInherited = Record[Idx++];
- SIMPLE_ATTR(GNUInline);
- SIMPLE_ATTR(Hiding);
-
- case attr::IBAction:
- New = ::new (*Context) IBActionAttr();
- break;
-
- case attr::IBOutlet:
- New = ::new (*Context) IBOutletAttr();
- break;
-
- case attr::IBOutletCollection: {
- QualType QT = GetType(Record[Idx++]);
- New = ::new (*Context) IBOutletCollectionAttr(QT);
- break;
- }
-
- SIMPLE_ATTR(Malloc);
- SIMPLE_ATTR(NoDebug);
- SIMPLE_ATTR(NoInline);
- SIMPLE_ATTR(NoReturn);
- SIMPLE_ATTR(NoThrow);
-
- case attr::NonNull: {
- unsigned Size = Record[Idx++];
- llvm::SmallVector<unsigned, 16> ArgNums;
- ArgNums.insert(ArgNums.end(), &Record[Idx], &Record[Idx] + Size);
- Idx += Size;
- New = ::new (*Context) NonNullAttr(*Context, ArgNums.data(), Size);
- break;
- }
-
- case attr::ReqdWorkGroupSize: {
- unsigned X = Record[Idx++];
- unsigned Y = Record[Idx++];
- unsigned Z = Record[Idx++];
- New = ::new (*Context) ReqdWorkGroupSizeAttr(X, Y, Z);
- break;
- }
-
- SIMPLE_ATTR(ObjCException);
- SIMPLE_ATTR(ObjCNSObject);
- SIMPLE_ATTR(CFReturnsNotRetained);
- SIMPLE_ATTR(CFReturnsRetained);
- SIMPLE_ATTR(NSReturnsNotRetained);
- SIMPLE_ATTR(NSReturnsRetained);
- SIMPLE_ATTR(Overloadable);
- SIMPLE_ATTR(Override);
- SIMPLE_ATTR(Packed);
- UNSIGNED_ATTR(MaxFieldAlignment);
- SIMPLE_ATTR(Pure);
- UNSIGNED_ATTR(Regparm);
- STRING_ATTR(Section);
- SIMPLE_ATTR(StdCall);
- SIMPLE_ATTR(ThisCall);
- SIMPLE_ATTR(TransparentUnion);
- SIMPLE_ATTR(Unavailable);
- SIMPLE_ATTR(Unused);
- SIMPLE_ATTR(Used);
-
- case attr::Visibility:
- New = ::new (*Context) VisibilityAttr(
- (VisibilityAttr::VisibilityTypes)Record[Idx++],
- (bool)Record[Idx++]);
- break;
-
- SIMPLE_ATTR(WarnUnusedResult);
- SIMPLE_ATTR(Weak);
- SIMPLE_ATTR(WeakRef);
- SIMPLE_ATTR(WeakImport);
- }
+#include "clang/Serialization/AttrPCHRead.inc"
assert(New && "Unable to decode attribute?");
- New->setInherited(IsInherited);
- New->setNext(Attrs);
- Attrs = New;
- }
-#undef UNSIGNED_ATTR
-#undef STRING_ATTR
-#undef SIMPLE_ATTR
-
- // The list of attributes was built backwards. Reverse the list
- // before returning it.
- Attr *PrevAttr = 0, *NextAttr = 0;
- while (Attrs) {
- NextAttr = Attrs->getNext();
- Attrs->setNext(PrevAttr);
- PrevAttr = Attrs;
- Attrs = NextAttr;
+ New->setInherited(isInherited);
+ Attrs.push_back(New);
}
-
- return PrevAttr;
}
//===----------------------------------------------------------------------===//
Modified: cfe/trunk/lib/Serialization/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/PCHWriter.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/PCHWriter.cpp Wed Aug 18 18:23:40 2010
@@ -1949,172 +1949,16 @@
//===----------------------------------------------------------------------===//
/// \brief Write a record containing the given attributes.
-void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
+void PCHWriter::WriteAttributeRecord(const AttrVec &Attrs) {
RecordData Record;
- for (; Attr; Attr = Attr->getNext()) {
- Record.push_back(Attr->getKind()); // FIXME: stable encoding, target attrs
- Record.push_back(Attr->isInherited());
- switch (Attr->getKind()) {
- default:
- assert(0 && "Does not support PCH writing for this attribute yet!");
- break;
- case attr::Alias:
- AddString(cast<AliasAttr>(Attr)->getAliasee(), Record);
- break;
-
- case attr::AlignMac68k:
- break;
-
- case attr::Aligned:
- Record.push_back(cast<AlignedAttr>(Attr)->getAlignment());
- break;
-
- case attr::AlwaysInline:
- break;
-
- case attr::AnalyzerNoReturn:
- break;
-
- case attr::Annotate:
- AddString(cast<AnnotateAttr>(Attr)->getAnnotation(), Record);
- break;
-
- case attr::AsmLabel:
- AddString(cast<AsmLabelAttr>(Attr)->getLabel(), Record);
- break;
-
- case attr::BaseCheck:
- break;
-
- case attr::Blocks:
- Record.push_back(cast<BlocksAttr>(Attr)->getType()); // FIXME: stable
- break;
-
- case attr::CDecl:
- break;
-
- case attr::Cleanup:
- AddDeclRef(cast<CleanupAttr>(Attr)->getFunctionDecl(), Record);
- break;
-
- case attr::Const:
- break;
-
- case attr::Constructor:
- Record.push_back(cast<ConstructorAttr>(Attr)->getPriority());
- break;
-
- case attr::DLLExport:
- case attr::DLLImport:
- case attr::Deprecated:
- break;
-
- case attr::Destructor:
- Record.push_back(cast<DestructorAttr>(Attr)->getPriority());
- break;
-
- case attr::FastCall:
- case attr::Final:
- break;
-
- case attr::Format: {
- const FormatAttr *Format = cast<FormatAttr>(Attr);
- AddString(Format->getType(), Record);
- Record.push_back(Format->getFormatIdx());
- Record.push_back(Format->getFirstArg());
- break;
- }
-
- case attr::FormatArg: {
- const FormatArgAttr *Format = cast<FormatArgAttr>(Attr);
- Record.push_back(Format->getFormatIdx());
- break;
- }
-
- case attr::Sentinel : {
- const SentinelAttr *Sentinel = cast<SentinelAttr>(Attr);
- Record.push_back(Sentinel->getSentinel());
- Record.push_back(Sentinel->getNullPos());
- break;
- }
-
- case attr::GNUInline:
- case attr::Hiding:
- case attr::IBAction:
- case attr::IBOutlet:
- case attr::Malloc:
- case attr::NoDebug:
- case attr::NoInline:
- case attr::NoReturn:
- case attr::NoThrow:
- break;
-
- case attr::IBOutletCollection: {
- const IBOutletCollectionAttr *ICA = cast<IBOutletCollectionAttr>(Attr);
- AddTypeRef(ICA->getType(), Record);
- break;
- }
-
- case attr::NonNull: {
- const NonNullAttr *NonNull = cast<NonNullAttr>(Attr);
- Record.push_back(NonNull->size());
- Record.insert(Record.end(), NonNull->begin(), NonNull->end());
- break;
- }
-
- case attr::CFReturnsNotRetained:
- case attr::CFReturnsRetained:
- case attr::NSReturnsNotRetained:
- case attr::NSReturnsRetained:
- case attr::ObjCException:
- case attr::ObjCNSObject:
- case attr::Overloadable:
- case attr::Override:
- break;
+ for (AttrVec::const_iterator i = Attrs.begin(), e = Attrs.end(); i != e; ++i){
+ const Attr * A = *i;
+ Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs
+ AddSourceLocation(A->getLocation(), Record);
+ Record.push_back(A->isInherited());
- case attr::MaxFieldAlignment:
- Record.push_back(cast<MaxFieldAlignmentAttr>(Attr)->getAlignment());
- break;
-
- case attr::Packed:
- break;
-
- case attr::Pure:
- break;
-
- case attr::Regparm:
- Record.push_back(cast<RegparmAttr>(Attr)->getNumParams());
- break;
-
- case attr::ReqdWorkGroupSize:
- Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getXDim());
- Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getYDim());
- Record.push_back(cast<ReqdWorkGroupSizeAttr>(Attr)->getZDim());
- break;
+#include "clang/Serialization/AttrPCHWrite.inc"
- case attr::Section:
- AddString(cast<SectionAttr>(Attr)->getName(), Record);
- break;
-
- case attr::StdCall:
- case attr::TransparentUnion:
- case attr::Unavailable:
- case attr::Unused:
- case attr::Used:
- break;
-
- case attr::Visibility:
- // FIXME: stable encoding
- Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility());
- Record.push_back(cast<VisibilityAttr>(Attr)->isFromPragma());
- break;
-
- case attr::WarnUnusedResult:
- case attr::Weak:
- case attr::WeakRef:
- case attr::WeakImport:
- break;
- }
}
Stream.EmitRecord(pch::DECL_ATTR, Record);
Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=111455&r1=111454&r2=111455&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Wed Aug 18 18:23:40 2010
@@ -1144,8 +1144,9 @@
bool CursorVisitor::VisitAttributes(Decl *D) {
- for (const Attr *A = D->getAttrs(); A; A = A->getNext())
- if (Visit(MakeCXCursor(A, D, TU)))
+ for (AttrVec::const_iterator i = D->attr_begin(), e = D->attr_end();
+ i != e; ++i)
+ if (Visit(MakeCXCursor(*i, D, TU)))
return true;
return false;
More information about the cfe-commits
mailing list