jdoerfert created this revision.
jdoerfert added reviewers: erichkeane, aaron.ballman, rjmccall, john.brawn.
Herald added a subscriber: bollu.
Herald added a project: clang.

ParsedAttr is used for `clang attribute push/pop` a utility that is
reusable in other contexts as well. This allows us to create "fake"
parsed attributes from other attributes, e.g., implicit ones.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D75210

Files:
  clang/include/clang/Sema/ParsedAttr.h
  clang/lib/Sema/ParsedAttr.cpp

Index: clang/lib/Sema/ParsedAttr.cpp
===================================================================
--- clang/lib/Sema/ParsedAttr.cpp
+++ clang/lib/Sema/ParsedAttr.cpp
@@ -42,10 +42,10 @@
   else if (HasParsedType)
     return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
                             detail::TypeTagForDatatypeData, ParsedType,
-                            detail::PropertyData>(0, 0, 0, 1, 0);
+                            detail::PropertyData, Attr *>(0, 0, 0, 1, 0, 0);
   return totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
                           detail::TypeTagForDatatypeData, ParsedType,
-                          detail::PropertyData>(NumArgs, 0, 0, 0, 0);
+                          detail::PropertyData, Attr *>(NumArgs, 0, 0, 0, 0, 0);
 }
 
 AttributeFactory::AttributeFactory() {
Index: clang/include/clang/Sema/ParsedAttr.h
===================================================================
--- clang/include/clang/Sema/ParsedAttr.h
+++ clang/include/clang/Sema/ParsedAttr.h
@@ -116,9 +116,10 @@
 ///
 class ParsedAttr final
     : public AttributeCommonInfo,
-      private llvm::TrailingObjects<
-          ParsedAttr, ArgsUnion, detail::AvailabilityData,
-          detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
+      private llvm::TrailingObjects<ParsedAttr, ArgsUnion,
+                                    detail::AvailabilityData,
+                                    detail::TypeTagForDatatypeData, ParsedType,
+                                    detail::PropertyData, Attr *> {
   friend TrailingObjects;
 
   size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
@@ -135,6 +136,7 @@
   size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
     return IsProperty;
   }
+  size_t numTrailingObjects(OverloadToken<Attr *>) const { return HasAttrPtr; }
 
 private:
   IdentifierInfo *MacroII = nullptr;
@@ -143,7 +145,7 @@
 
   /// The number of expression arguments this attribute has.
   /// The expressions themselves are stored after the object.
-  unsigned NumArgs : 16;
+  unsigned NumArgs : 15;
 
   /// True if already diagnosed as invalid.
   mutable unsigned Invalid : 1;
@@ -166,6 +168,9 @@
   /// True if this has a ParsedType
   unsigned HasParsedType : 1;
 
+  /// True if this has an attribute pointer.
+  unsigned HasAttrPtr : 1;
+
   /// True if the processing cache is valid.
   mutable unsigned HasProcessingCache : 1;
 
@@ -207,7 +212,8 @@
         EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
         UsedAsTypeAttr(false), IsAvailability(false),
         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
-        HasProcessingCache(false), IsPragmaClangAttribute(false) {
+        HasAttrPtr(false), HasProcessingCache(false),
+        IsPragmaClangAttribute(false) {
     if (numArgs)
       memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
   }
@@ -224,8 +230,9 @@
                             syntaxUsed),
         NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
-        HasProcessingCache(false), IsPragmaClangAttribute(false),
-        UnavailableLoc(unavailable), MessageExpr(messageExpr) {
+        HasAttrPtr(false), HasProcessingCache(false),
+        IsPragmaClangAttribute(false), UnavailableLoc(unavailable),
+        MessageExpr(messageExpr) {
     ArgsUnion PVal(Parm);
     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
     new (getAvailabilityData()) detail::AvailabilityData(
@@ -241,7 +248,7 @@
                             syntaxUsed),
         NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
         IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
-        HasParsedType(false), HasProcessingCache(false),
+        HasParsedType(false), HasAttrPtr(false), HasProcessingCache(false),
         IsPragmaClangAttribute(false) {
     ArgsUnion *Args = getArgsBuffer();
     Args[0] = Parm1;
@@ -258,7 +265,7 @@
                             syntaxUsed),
         NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
         IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
-        HasParsedType(false), HasProcessingCache(false),
+        HasParsedType(false), HasAttrPtr(false), HasProcessingCache(false),
         IsPragmaClangAttribute(false) {
     ArgsUnion PVal(ArgKind);
     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
@@ -276,7 +283,7 @@
                             syntaxUsed),
         NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
         IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
-        HasParsedType(true), HasProcessingCache(false),
+        HasParsedType(true), HasAttrPtr(false), HasProcessingCache(false),
         IsPragmaClangAttribute(false) {
     new (&getTypeBuffer()) ParsedType(typeArg);
   }
@@ -290,11 +297,25 @@
                             syntaxUsed),
         NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
         IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
-        HasParsedType(false), HasProcessingCache(false),
+        HasParsedType(false), HasAttrPtr(false), HasProcessingCache(false),
         IsPragmaClangAttribute(false) {
     new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
   }
 
+  /// Constructor for attributes with a single non-parsed attribute pointer as
+  /// argument.
+  ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
+             IdentifierInfo *scopeName, SourceLocation scopeLoc,
+             Attr *attrPtrArg, Syntax syntaxUsed)
+      : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc,
+                            syntaxUsed),
+        NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
+        IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
+        HasParsedType(false), HasAttrPtr(true), HasProcessingCache(false),
+        IsPragmaClangAttribute(false) {
+    new (&getAttrPtrBuffer())(Attr *)(attrPtrArg);
+  }
+
   /// Type tag information is stored immediately following the arguments, if
   /// any, at the end of the object.  They are mutually exclusive with
   /// availability slots.
@@ -312,6 +333,13 @@
     return *getTrailingObjects<ParsedType>();
   }
 
+  /// The attribute pointer immediately follows the object and are mutually
+  /// exclusive with arguments.
+  Attr *&getAttrPtrBuffer() { return *getTrailingObjects<Attr *>(); }
+  Attr *const &getAttrPtrBuffer() const {
+    return *getTrailingObjects<Attr *>();
+  }
+
   /// The property data immediately follows the object is is mutually exclusive
   /// with arguments.
   detail::PropertyData &getPropertyDataBuffer() {
@@ -336,6 +364,8 @@
 
   bool hasParsedType() const { return HasParsedType; }
 
+  bool hasAttrPtr() const { return HasAttrPtr; }
+
   /// Is this the Microsoft __declspec(property) attribute?
   bool isDeclspecPropertyAttribute() const  {
     return IsProperty;
@@ -457,6 +487,11 @@
     return getTypeBuffer();
   }
 
+  const Attr *getAttrPtr() const {
+    assert(hasAttrPtr() && "Not an attribute pointer attribute");
+    return getAttrPtrBuffer();
+  }
+
   IdentifierInfo *getPropertyDataGetter() const {
     assert(isDeclspecPropertyAttribute() &&
            "Not a __delcspec(property) attribute");
@@ -546,18 +581,18 @@
 class AttributeFactory {
 public:
   enum {
-    AvailabilityAllocSize =
-        ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
-                                     detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(1, 1, 0, 0, 0),
-    TypeTagForDatatypeAllocSize =
-        ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
-                                     detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(1, 0, 1, 0, 0),
-    PropertyAllocSize =
-        ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
-                                     detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(0, 0, 0, 0, 1),
+    AvailabilityAllocSize = ParsedAttr::totalSizeToAlloc<
+        ArgsUnion, detail::AvailabilityData, detail::TypeTagForDatatypeData,
+        ParsedType, detail::PropertyData, Attr *>(1, 1, 0, 0, 0, 0),
+    TypeTagForDatatypeAllocSize = ParsedAttr::totalSizeToAlloc<
+        ArgsUnion, detail::AvailabilityData, detail::TypeTagForDatatypeData,
+        ParsedType, detail::PropertyData, Attr *>(1, 0, 1, 0, 0, 0),
+    PropertyAllocSize = ParsedAttr::totalSizeToAlloc<
+        ArgsUnion, detail::AvailabilityData, detail::TypeTagForDatatypeData,
+        ParsedType, detail::PropertyData, Attr *>(0, 0, 0, 0, 1, 0),
+    AttrPtrAllocSize = ParsedAttr::totalSizeToAlloc<
+        ArgsUnion, detail::AvailabilityData, detail::TypeTagForDatatypeData,
+        ParsedType, detail::PropertyData, Attr *>(0, 0, 0, 0, 0, 1),
   };
 
 private:
@@ -652,13 +687,14 @@
     size_t temp =
         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
                                      detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(numArgs, 0, 0, 0, 0);
+                                     detail::PropertyData, Attr *>(numArgs, 0,
+                                                                   0, 0, 0, 0);
     (void)temp;
     void *memory = allocate(
         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
                                      detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(numArgs, 0, 0, 0,
-                                                           0));
+                                     detail::PropertyData, Attr *>(numArgs, 0,
+                                                                   0, 0, 0, 0));
     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
                                        args, numArgs, syntax, ellipsisLoc));
   }
@@ -684,7 +720,8 @@
     void *memory = allocate(
         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
                                      detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(3, 0, 0, 0, 0));
+                                     detail::PropertyData, Attr *>(3, 0, 0, 0,
+                                                                   0, 0));
     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
                                        Param1, Param2, Param3, syntax));
   }
@@ -709,7 +746,8 @@
     void *memory = allocate(
         ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
                                      detail::TypeTagForDatatypeData, ParsedType,
-                                     detail::PropertyData>(0, 0, 0, 1, 0));
+                                     detail::PropertyData, Attr *>(0, 0, 0, 1,
+                                                                   0, 0));
     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
                                        typeArg, syntaxUsed));
   }
@@ -723,6 +761,16 @@
     return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
                                        getterId, setterId, syntaxUsed));
   }
+
+  ParsedAttr *createAttrPtrAttribute(IdentifierInfo *attrName,
+                                     SourceRange attrRange,
+                                     IdentifierInfo *scopeName,
+                                     SourceLocation scopeLoc, Attr *attrPtrArg,
+                                     ParsedAttr::Syntax syntaxUsed) {
+    void *memory = allocate(AttributeFactory::AttrPtrAllocSize);
+    return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
+                                       attrPtrArg, syntaxUsed));
+  }
 };
 
 class ParsedAttributesView {
@@ -923,6 +971,16 @@
     return attr;
   }
 
+  ParsedAttr *addNewAttrPtrAttr(IdentifierInfo *attrName, SourceRange attrRange,
+                                IdentifierInfo *scopeName,
+                                SourceLocation scopeLoc, Attr *attrPtrArg,
+                                ParsedAttr::Syntax syntaxUsed) {
+    ParsedAttr *attr = pool.createAttrPtrAttribute(
+        attrName, attrRange, scopeName, scopeLoc, attrPtrArg, syntaxUsed);
+    addAtEnd(attr);
+    return attr;
+  }
+
 private:
   mutable AttributePool pool;
 };
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to