diff options
-rw-r--r-- | include/clang/AST/Attr.h | 22 | ||||
-rw-r--r-- | include/clang/Basic/Attr.td | 154 | ||||
-rw-r--r-- | include/clang/Basic/AttrKinds.h | 1 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 10 | ||||
-rw-r--r-- | lib/Serialization/ASTReaderDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 1 |
6 files changed, 102 insertions, 88 deletions
diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index eab0139a16..d8f0979a8a 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -58,9 +58,10 @@ class Attr { private: SourceLocation Loc; unsigned AttrKind : 16; - bool Inherited : 1; protected: + bool Inherited : 1; + virtual ~Attr(); void* operator new(size_t bytes) throw() { @@ -99,9 +100,6 @@ public: SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } - bool isInherited() const { return Inherited; } - void setInherited(bool I) { Inherited = I; } - // Clone this attribute. virtual Attr* clone(ASTContext &C) const = 0; @@ -109,6 +107,22 @@ public: static bool classof(const Attr *) { return true; } }; +class InheritableAttr : public Attr { +protected: + InheritableAttr(attr::Kind AK, SourceLocation L) + : Attr(AK, L) {} + +public: + bool isInherited() const { return Inherited; } + void setInherited(bool I) { Inherited = I; } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { + return A->getKind() <= attr::LAST_INHERITABLE; + } + static bool classof(const InheritableAttr *) { return true; } +}; + #include "clang/AST/Attrs.inc" /// AttrVec - A vector of Attr, which is how they are stored on the AST. diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td index 9e5dd79f13..d3039d2c17 100644 --- a/include/clang/Basic/Attr.td +++ b/include/clang/Basic/Attr.td @@ -89,92 +89,94 @@ class Attr { code AdditionalMembers = [{}]; } +class InheritableAttr : Attr; + // // Attributes begin here // -def Alias : Attr { +def Alias : InheritableAttr { let Spellings = ["alias"]; let Args = [StringArgument<"Aliasee">]; } -def Aligned : Attr { +def Aligned : InheritableAttr { let Spellings = ["align", "aligned"]; let Subjects = [NonBitField, NormalVar, Tag]; let Args = [AlignedArgument<"Alignment">]; let Namespaces = ["", "std"]; } -def AlignMac68k : Attr { +def AlignMac68k : InheritableAttr { let Spellings = []; } -def AlwaysInline : Attr { +def AlwaysInline : InheritableAttr { let Spellings = ["always_inline"]; } -def AnalyzerNoReturn : Attr { +def AnalyzerNoReturn : InheritableAttr { let Spellings = ["analyzer_noreturn"]; } -def Annotate : Attr { +def Annotate : InheritableAttr { let Spellings = ["annotate"]; let Args = [StringArgument<"Annotation">]; } -def AsmLabel : Attr { +def AsmLabel : InheritableAttr { let Spellings = []; let Args = [StringArgument<"Label">]; } -def BaseCheck : Attr { +def BaseCheck : InheritableAttr { let Spellings = ["base_check"]; let Subjects = [CXXRecord]; let Namespaces = ["", "std"]; } -def Blocks : Attr { +def Blocks : InheritableAttr { let Spellings = ["blocks"]; let Args = [EnumArgument<"Type", "BlockType", ["byref"], ["ByRef"]>]; } -def CarriesDependency : Attr { +def CarriesDependency : InheritableAttr { let Spellings = ["carries_dependency"]; let Subjects = [ParmVar, Function]; let Namespaces = ["", "std"]; } -def CDecl : Attr { +def CDecl : InheritableAttr { let Spellings = ["cdecl", "__cdecl"]; } -def CFReturnsRetained : Attr { +def CFReturnsRetained : InheritableAttr { let Spellings = ["cf_returns_retained"]; } -def CFReturnsNotRetained : Attr { +def CFReturnsNotRetained : InheritableAttr { let Spellings = ["cf_returns_not_retained"]; } -def Cleanup : Attr { +def Cleanup : InheritableAttr { let Spellings = ["cleanup"]; let Args = [FunctionArgument<"FunctionDecl">]; } -def Common : Attr { +def Common : InheritableAttr { let Spellings = ["common"]; } -def Const : Attr { +def Const : InheritableAttr { let Spellings = ["const"]; } -def Constructor : Attr { +def Constructor : InheritableAttr { let Spellings = ["constructor"]; let Args = [IntArgument<"Priority">]; } -def CUDAConstant : Attr { +def CUDAConstant : InheritableAttr { let Spellings = ["constant"]; } @@ -182,7 +184,7 @@ def CUDADevice : Attr { let Spellings = ["device"]; } -def CUDAGlobal : Attr { +def CUDAGlobal : InheritableAttr { let Spellings = ["global"]; } @@ -190,120 +192,120 @@ def CUDAHost : Attr { let Spellings = ["host"]; } -def CUDALaunchBounds : Attr { +def CUDALaunchBounds : InheritableAttr { let Spellings = ["launch_bounds"]; let Args = [IntArgument<"MaxThreads">, DefaultIntArgument<"MinBlocks", 0>]; } -def CUDAShared : Attr { +def CUDAShared : InheritableAttr { let Spellings = ["shared"]; } -def Deprecated : Attr { +def Deprecated : InheritableAttr { let Spellings = ["deprecated"]; let Args = [StringArgument<"Message">]; } -def Destructor : Attr { +def Destructor : InheritableAttr { let Spellings = ["destructor"]; let Args = [IntArgument<"Priority">]; } -def DLLExport : Attr { +def DLLExport : InheritableAttr { let Spellings = ["dllexport"]; } -def DLLImport : Attr { +def DLLImport : InheritableAttr { let Spellings = ["dllimport"]; } -def FastCall : Attr { +def FastCall : InheritableAttr { let Spellings = ["fastcall", "__fastcall"]; } -def Final : Attr { +def Final : InheritableAttr { let Spellings = ["final"]; let Subjects = [CXXRecord, CXXVirtualMethod]; let Namespaces = ["", "std"]; } -def Format : Attr { +def Format : InheritableAttr { let Spellings = ["format"]; let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">, IntArgument<"FirstArg">]; } -def FormatArg : Attr { +def FormatArg : InheritableAttr { let Spellings = ["format_arg"]; let Args = [IntArgument<"FormatIdx">]; } -def GNUInline : Attr { +def GNUInline : InheritableAttr { let Spellings = ["gnu_inline"]; } -def Hiding : Attr { +def Hiding : InheritableAttr { let Spellings = ["hiding"]; let Subjects = [Field, CXXMethod]; let Namespaces = ["", "std"]; } -def IBAction : Attr { +def IBAction : InheritableAttr { let Spellings = ["ibaction"]; } -def IBOutlet : Attr { +def IBOutlet : InheritableAttr { let Spellings = ["iboutlet"]; } -def IBOutletCollection : Attr { +def IBOutletCollection : InheritableAttr { let Spellings = ["iboutletcollection"]; let Args = [TypeArgument<"Interface">]; } -def Malloc : Attr { +def Malloc : InheritableAttr { let Spellings = ["malloc"]; } -def MaxFieldAlignment : Attr { +def MaxFieldAlignment : InheritableAttr { let Spellings = []; let Args = [UnsignedArgument<"Alignment">]; } -def MayAlias : Attr { +def MayAlias : InheritableAttr { let Spellings = ["may_alias"]; } -def MSP430Interrupt : Attr { +def MSP430Interrupt : InheritableAttr { let Spellings = []; let Args = [UnsignedArgument<"Number">]; } -def MBlazeInterruptHandler : Attr { +def MBlazeInterruptHandler : InheritableAttr { let Spellings = []; } -def MBlazeSaveVolatiles : Attr { +def MBlazeSaveVolatiles : InheritableAttr { let Spellings = []; } -def Naked : Attr { +def Naked : InheritableAttr { let Spellings = ["naked"]; } -def NoCommon : Attr { +def NoCommon : InheritableAttr { let Spellings = ["nocommon"]; } -def NoDebug : Attr { +def NoDebug : InheritableAttr { let Spellings = ["nodebug"]; } -def NoInline : Attr { +def NoInline : InheritableAttr { let Spellings = ["noinline"]; } -def NonNull : Attr { +def NonNull : InheritableAttr { let Spellings = ["nonnull"]; let Args = [VariadicUnsignedArgument<"Args">]; let AdditionalMembers = @@ -316,39 +318,39 @@ def NonNull : Attr { } }]; } -def NoReturn : Attr { +def NoReturn : InheritableAttr { let Spellings = ["noreturn"]; // FIXME: Does GCC allow this on the function instead? let Subjects = [Function]; let Namespaces = ["", "std"]; } -def NoInstrumentFunction : Attr { +def NoInstrumentFunction : InheritableAttr { let Spellings = ["no_instrument_function"]; let Subjects = [Function]; } -def NoThrow : Attr { +def NoThrow : InheritableAttr { let Spellings = ["nothrow"]; } -def NSReturnsRetained : Attr { +def NSReturnsRetained : InheritableAttr { let Spellings = ["ns_returns_retained"]; } -def NSReturnsNotRetained : Attr { +def NSReturnsNotRetained : InheritableAttr { let Spellings = ["ns_returns_not_retained"]; } -def ObjCException : Attr { +def ObjCException : InheritableAttr { let Spellings = ["objc_exception"]; } -def ObjCNSObject : Attr { +def ObjCNSObject : InheritableAttr { let Spellings = ["NSOjbect"]; } -def Override : Attr { +def Override : InheritableAttr { let Spellings = ["override"]; let Subjects = [CXXVirtualMethod]; let Namespaces = ["", "std"]; @@ -358,7 +360,7 @@ def Overloadable : Attr { let Spellings = ["overloadable"]; } -def Ownership : Attr { +def Ownership : InheritableAttr { let Spellings = ["ownership_holds", "ownership_returns", "ownership_takes"]; let Args = [EnumArgument<"OwnKind", "OwnershipKind", ["ownership_holds", "ownership_returns", "ownership_takes"], @@ -366,104 +368,104 @@ def Ownership : Attr { StringArgument<"Module">, VariadicUnsignedArgument<"Args">]; } -def Packed : Attr { +def Packed : InheritableAttr { let Spellings = ["packed"]; } -def Pure : Attr { +def Pure : InheritableAttr { let Spellings = ["pure"]; } -def Regparm : Attr { +def Regparm : InheritableAttr { let Spellings = ["regparm"]; let Args = [UnsignedArgument<"NumParams">]; } -def ReqdWorkGroupSize : Attr { +def ReqdWorkGroupSize : InheritableAttr { let Spellings = ["reqd_work_group_size"]; let Args = [UnsignedArgument<"XDim">, UnsignedArgument<"YDim">, UnsignedArgument<"ZDim">]; } -def InitPriority : Attr { +def InitPriority : InheritableAttr { let Spellings = ["init_priority"]; let Args = [UnsignedArgument<"Priority">]; } -def Section : Attr { +def Section : InheritableAttr { let Spellings = ["section"]; let Args = [StringArgument<"Name">]; } -def Sentinel : Attr { +def Sentinel : InheritableAttr { let Spellings = ["sentinel"]; let Args = [DefaultIntArgument<"Sentinel", 0>, DefaultIntArgument<"NullPos", 0>]; } -def StdCall : Attr { +def StdCall : InheritableAttr { let Spellings = ["stdcall", "__stdcall"]; } -def ThisCall : Attr { +def ThisCall : InheritableAttr { let Spellings = ["thiscall", "__thiscall"]; } -def Pascal : Attr { +def Pascal : InheritableAttr { let Spellings = ["pascal", "__pascal"]; } -def TransparentUnion : Attr { +def TransparentUnion : InheritableAttr { let Spellings = ["transparent_union"]; } -def Unavailable : Attr { +def Unavailable : InheritableAttr { let Spellings = ["unavailable"]; let Args = [StringArgument<"Message">]; } -def Unused : Attr { +def Unused : InheritableAttr { let Spellings = ["unused"]; } -def Used : Attr { +def Used : InheritableAttr { let Spellings = ["used"]; } -def Uuid : Attr { +def Uuid : InheritableAttr { let Spellings = ["uuid"]; let Args = [StringArgument<"Guid">]; let Subjects = [CXXRecord]; } -def Visibility : Attr { +def Visibility : InheritableAttr { let Spellings = ["visibility"]; let Args = [EnumArgument<"Visibility", "VisibilityType", ["default", "hidden", "internal", "protected"], ["Default", "Hidden", "Hidden", "Protected"]>]; } -def VecReturn : Attr { +def VecReturn : InheritableAttr { let Spellings = ["vecreturn"]; let Subjects = [CXXRecord]; } -def WarnUnusedResult : Attr { +def WarnUnusedResult : InheritableAttr { let Spellings = ["warn_unused_result"]; } -def Weak : Attr { +def Weak : InheritableAttr { let Spellings = ["weak"]; } -def WeakImport : Attr { +def WeakImport : InheritableAttr { let Spellings = ["weak_import"]; } -def WeakRef : Attr { +def WeakRef : InheritableAttr { let Spellings = ["weakref"]; } -def X86ForceAlignArgPointer : Attr { +def X86ForceAlignArgPointer : InheritableAttr { let Spellings = []; } diff --git a/include/clang/Basic/AttrKinds.h b/include/clang/Basic/AttrKinds.h index 822573b734..65c4f98c95 100644 --- a/include/clang/Basic/AttrKinds.h +++ b/include/clang/Basic/AttrKinds.h @@ -21,6 +21,7 @@ namespace attr { // Kind - This is a list of all the recognized kinds of attributes. enum Kind { #define ATTR(X) X, +#define LAST_INHERITABLE_ATTR(X) X, LAST_INHERITABLE = X, #include "clang/Basic/AttrList.inc" NUM_ATTRS }; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index a3c3242a4e..8c78c0dd76 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -1019,11 +1019,11 @@ static void MergeDeclAttributes(Decl *New, Decl *Old, ASTContext &C) { // 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); + for (specific_attr_iterator<InheritableAttr> + i = Old->specific_attr_begin<InheritableAttr>(), + e = Old->specific_attr_end<InheritableAttr>(); i != e; ++i) { + if (!DeclHasAttr(New, *i)) { + InheritableAttr *NewAttr = cast<InheritableAttr>((*i)->clone(C)); NewAttr->setInherited(true); New->addAttr(NewAttr); } diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index 190f584a04..36eaee1d5f 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -1253,12 +1253,10 @@ void ASTReader::ReadAttributes(PerFileData &F, AttrVec &Attrs, Attr *New = 0; attr::Kind Kind = (attr::Kind)Record[Idx++]; SourceLocation Loc = ReadSourceLocation(F, Record, Idx); - bool isInherited = Record[Idx++]; #include "clang/Serialization/AttrPCHRead.inc" assert(New && "Unable to decode attribute?"); - New->setInherited(isInherited); Attrs.push_back(New); } } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 8a6461fb4f..1e296e8514 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2284,7 +2284,6 @@ void ASTWriter::WriteAttributes(const AttrVec &Attrs, RecordDataImpl &Record) { const Attr * A = *i; Record.push_back(A->getKind()); // FIXME: stable encoding, target attrs AddSourceLocation(A->getLocation(), Record); - Record.push_back(A->isInherited()); #include "clang/Serialization/AttrPCHWrite.inc" |