leonardchan updated this revision to Diff 163604.
leonardchan marked 8 inline comments as done.
leonardchan added a comment.

- Removed default value for `getAttributedType` and added any macro identifier 
necessary as a fourth argument to `getAttributedType`
- Added tracking for `LateAttr`s to keep any found macro identifier, although I 
don't quite know how I can test this in the same fashion that I test with 
`address_space` since it doesn't get printed in the type.


Repository:
  rC Clang

https://reviews.llvm.org/D51329

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/Type.h
  include/clang/Parse/Parser.h
  include/clang/Sema/ParsedAttr.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDiagnostic.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Type.cpp
  lib/AST/TypePrinter.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprObjC.cpp
  lib/Sema/SemaObjCProperty.cpp
  lib/Sema/SemaType.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReader.cpp
  lib/Serialization/ASTWriter.cpp
  test/Sema/address_space_print_macro.c
  test/Sema/address_spaces.c

Index: test/Sema/address_spaces.c
===================================================================
--- test/Sema/address_spaces.c
+++ test/Sema/address_spaces.c
@@ -71,5 +71,5 @@
 
 // Clang extension doesn't forbid operations on pointers to different address spaces.
 char* cmp(_AS1 char *x,  _AS2 char *y) {
-  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('__attribute__((address_space(1))) char *' and '__attribute__((address_space(2))) char *') which are pointers to non-overlapping address spaces}}
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('_AS1 char *' and '_AS2 char *') which are pointers to non-overlapping address spaces}}
 }
Index: test/Sema/address_space_print_macro.c
===================================================================
--- /dev/null
+++ test/Sema/address_space_print_macro.c
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+#define AS1 __attribute__((address_space(1)))
+#define AS2 __attribute__((address_space(2), annotate("foo")))
+
+#define AS(i) address_space(i)
+#define AS3 __attribute__((AS(3)))
+
+#define ATTR __attribute__
+#define AS4 ATTR((AS(4)))
+#define AS5 __attribute__((address_space(5))) char
+
+char *cmp(AS1 char *x, AS2 char *y) {
+  return x < y ? x : y; // expected-error{{conditional operator with the second and third operands of type  ('AS1 char *' and 'AS2 char *') which are pointers to non-overlapping address spaces}}
+}
+
+__attribute__((address_space(1))) char test_array[10];
+void test3(void) {
+  extern void test3_helper(char *p); // expected-note{{passing argument to parameter 'p' here}}
+  test3_helper(test_array);          // expected-error{{passing '__attribute__((address_space(1))) char *' to parameter of type 'char *' changes address space of pointer}}
+}
+
+char AS2 *test4_array;
+void test4(void) {
+  extern void test3_helper(char *p); // expected-note{{passing argument to parameter 'p' here}}
+  test3_helper(test4_array);         // expected-error{{passing 'AS2 char *' to parameter of type 'char *' changes address space of pointer}}
+}
+
+void func() {
+  char AS1 *x;
+  char AS3 *x2;
+  AS4 char *x3;
+  AS5 *x4;
+  char *y;
+  y = x;  // expected-error{{assigning 'AS1 char *' to 'char *' changes address space of pointer}}
+  y = x2; // expected-error{{assigning 'AS3 char *' to 'char *' changes address space of pointer}}
+  y = x3; // expected-error{{assigning 'AS4 char *' to 'char *' changes address space of pointer}}
+  y = x4; // expected-error{{assigning '__attribute__((address_space(5))) char *' to 'char *' changes address space of pointer}}
+}
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -404,6 +404,7 @@
   Record.AddTypeRef(T->getModifiedType());
   Record.AddTypeRef(T->getEquivalentType());
   Record.push_back(T->getAttrKind());
+  Record.AddIdentifierRef(T->getMacroIdentifier());
   Code = TYPE_ATTRIBUTED;
 }
 
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6168,14 +6168,16 @@
   }
 
   case TYPE_ATTRIBUTED: {
-    if (Record.size() != 3) {
+    if (Record.size() != 4) {
       Error("incorrect encoding of attributed type");
       return QualType();
     }
     QualType modifiedType = readType(*Loc.F, Record, Idx);
     QualType equivalentType = readType(*Loc.F, Record, Idx);
     AttributedType::Kind kind = static_cast<AttributedType::Kind>(Record[2]);
-    return Context.getAttributedType(kind, modifiedType, equivalentType);
+    IdentifierInfo *MacroII = GetIdentifierInfo(*Loc.F, Record, Idx);
+    return Context.getAttributedType(kind, modifiedType, equivalentType,
+                                     MacroII);
   }
 
   case TYPE_PAREN: {
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -6087,9 +6087,9 @@
       }
     }
 
-    result = SemaRef.Context.getAttributedType(TL.getAttrKind(),
-                                               modifiedType,
-                                               equivalentType);
+    result = SemaRef.Context.getAttributedType(TL.getAttrKind(), modifiedType,
+                                               equivalentType,
+                                               oldType->getMacroIdentifier());
   }
 
   AttributedTypeLoc newTL = TLB.push<AttributedTypeLoc>(result);
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -243,9 +243,9 @@
     /// Get an attributed type for the given attribute, and remember the Attr
     /// object so that we can attach it to the AttributedTypeLoc.
     QualType getAttributedType(Attr *A, QualType ModifiedType,
-                               QualType EquivType) {
-      QualType T =
-          sema.Context.getAttributedType(A->getKind(), ModifiedType, EquivType);
+                               QualType EquivType, IdentifierInfo *MacroII) {
+      QualType T = sema.Context.getAttributedType(A->getKind(), ModifiedType,
+                                                  EquivType, MacroII);
       AttrsForTypes.push_back({cast<AttributedType>(T.getTypePtr()), A});
       AttrsForTypesSorted = false;
       return T;
@@ -4258,7 +4258,8 @@
                 D.getDeclSpec().getEndLoc(),
                 D.getMutableDeclSpec().getAttributes())) {
           T = state.getAttributedType(
-              createNullabilityAttr(Context, *attr, *inferNullability), T, T);
+              createNullabilityAttr(Context, *attr, *inferNullability), T, T,
+              attr->getMacroIdentifier());
         }
       }
     }
@@ -5817,7 +5818,7 @@
       auto *ASAttr = ::new (Ctx) AddressSpaceAttr(
           Attr.getRange(), Ctx, Attr.getAttributeSpellingListIndex(),
           static_cast<unsigned>(T.getQualifiers().getAddressSpace()));
-      Type = State.getAttributedType(ASAttr, T, T);
+      Type = State.getAttributedType(ASAttr, T, T, Attr.getMacroIdentifier());
     } else {
       Attr.setInvalid();
     }
@@ -6012,8 +6013,8 @@
   if (!S.getLangOpts().ObjCAutoRefCount &&
       lifetime == Qualifiers::OCL_ExplicitNone) {
     type = state.getAttributedType(
-        createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr),
-        type, type);
+        createSimpleAttr<ObjCInertUnsafeUnretainedAttr>(S.Context, attr), type,
+        type, attr.getMacroIdentifier());
     return true;
   }
 
@@ -6027,7 +6028,7 @@
     type = state.getAttributedType(::new (S.Context) ObjCOwnershipAttr(
                                        attr.getRange(), S.Context, II,
                                        attr.getAttributeSpellingListIndex()),
-                                   origType, type);
+                                   origType, type, attr.getMacroIdentifier());
   }
 
   auto diagnoseOrDelay = [](Sema &S, SourceLocation loc,
@@ -6131,7 +6132,7 @@
     type = state.getAttributedType(
         ::new (S.Context) ObjCGCAttr(attr.getRange(), S.Context, II,
                                      attr.getAttributeSpellingListIndex()),
-        origType, type);
+        origType, type, attr.getMacroIdentifier());
 
   return true;
 }
@@ -6341,7 +6342,7 @@
     return true;
   }
 
-  Type = State.getAttributedType(A, Type, Type);
+  Type = State.getAttributedType(A, Type, Type, PAttr.getMacroIdentifier());
   return false;
 }
 
@@ -6473,7 +6474,8 @@
 
   // Form the attributed type.
   type = state.getAttributedType(
-      createNullabilityAttr(S.Context, attr, nullability), type, type);
+      createNullabilityAttr(S.Context, attr, nullability), type, type,
+      attr.getMacroIdentifier());
   return false;
 }
 
@@ -6486,7 +6488,8 @@
   if (isa<ObjCTypeParamType>(type)) {
     // Build the attributed type to record where __kindof occurred.
     type = state.getAttributedType(
-        createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, type);
+        createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, type,
+        attr.getMacroIdentifier());
     return false;
   }
 
@@ -6521,13 +6524,15 @@
              "multiple spellings for __kindof?");
       Attr *A = createNullabilityAttr(S.Context, attr, *nullability);
       A->setImplicit(true);
-      equivType = state.getAttributedType(A, equivType, equivType);
+      equivType = state.getAttributedType(A, equivType, equivType,
+                                          attr.getMacroIdentifier());
     }
   }
 
   // Build the attributed type to record where __kindof occurred.
-  type = state.getAttributedType(
-      createSimpleAttr<ObjCKindOfAttr>(S.Context, attr), type, equivType);
+  type =
+      state.getAttributedType(createSimpleAttr<ObjCKindOfAttr>(S.Context, attr),
+                              type, equivType, attr.getMacroIdentifier());
   return false;
 }
 
@@ -6712,8 +6717,8 @@
       type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
     }
     type = state.getAttributedType(
-        createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr),
-        origType, type);
+        createSimpleAttr<NSReturnsRetainedAttr>(S.Context, attr), origType,
+        type, attr.getMacroIdentifier());
     return true;
   }
 
@@ -6847,7 +6852,8 @@
     Equivalent =
       unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
   }
-  type = state.getAttributedType(CCAttr, type, Equivalent);
+  type = state.getAttributedType(CCAttr, type, Equivalent,
+                                 attr.getMacroIdentifier());
   return true;
 }
 
@@ -7209,7 +7215,7 @@
   if (State.getDeclarator().isDeclarationOfFunction()) {
     CurType = State.getAttributedType(
         createSimpleAttr<LifetimeBoundAttr>(State.getSema().Context, Attr),
-        CurType, CurType);
+        CurType, CurType, Attr.getMacroIdentifier());
   } else {
     Attr.diagnoseAppertainsTo(State.getSema(), nullptr);
   }
Index: lib/Sema/SemaObjCProperty.cpp
===================================================================
--- lib/Sema/SemaObjCProperty.cpp
+++ lib/Sema/SemaObjCProperty.cpp
@@ -2384,8 +2384,9 @@
       QualType modifiedTy = resultTy;
       if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)) {
         if (*nullability == NullabilityKind::Unspecified)
-          resultTy = Context.getAttributedType(attr::TypeNonNull,
-                                               modifiedTy, modifiedTy);
+          resultTy = Context.getAttributedType(
+              attr::TypeNonNull, modifiedTy, modifiedTy,
+              resultTy->getAs<AttributedType>()->getMacroIdentifier());
       }
     }
 
@@ -2458,8 +2459,9 @@
         QualType modifiedTy = paramTy;
         if (auto nullability = AttributedType::stripOuterNullability(modifiedTy)){
           if (*nullability == NullabilityKind::Unspecified)
-            paramTy = Context.getAttributedType(attr::TypeNullable,
-                                                modifiedTy, modifiedTy);
+            paramTy = Context.getAttributedType(
+                attr::TypeNullable, modifiedTy, modifiedTy,
+                paramTy->getAs<AttributedType>()->getMacroIdentifier());
         }
       }
 
Index: lib/Sema/SemaExprObjC.cpp
===================================================================
--- lib/Sema/SemaExprObjC.cpp
+++ lib/Sema/SemaExprObjC.cpp
@@ -569,7 +569,10 @@
       if (Nullability)
         BoxedType = Context.getAttributedType(
             AttributedType::getNullabilityAttrKind(*Nullability), BoxedType,
-            BoxedType);
+            BoxedType,
+            BoxingMethod->getReturnType()
+                ->getAs<AttributedType>()
+                ->getMacroIdentifier());
     }
   } else if (ValueType->isBuiltinType()) {
     // The other types we support are numeric, char and BOOL/bool. We could also
@@ -1262,9 +1265,9 @@
   if (auto nullability = AttributedType::stripOuterNullability(T)) {
     if (T == Context.getObjCInstanceType()) {
       return Context.getAttributedType(
-               AttributedType::getNullabilityAttrKind(*nullability),
-               Context.getObjCIdType(),
-               Context.getObjCIdType());
+          AttributedType::getNullabilityAttrKind(*nullability),
+          Context.getObjCIdType(), Context.getObjCIdType(),
+          origType->getAs<AttributedType>()->getMacroIdentifier());
     }
 
     return origType;
@@ -1296,16 +1299,15 @@
   // result type to the returned result.
   auto transferNullability = [&](QualType type) -> QualType {
     // If the method's result type has nullability, extract it.
-    if (auto nullability = Method->getSendResultType(ReceiverType)
-                             ->getNullability(Context)){
+    QualType MethodResultTy = Method->getSendResultType(ReceiverType);
+    if (auto nullability = MethodResultTy->getNullability(Context)) {
       // Strip off any outer nullability sugar from the provided type.
       (void)AttributedType::stripOuterNullability(type);
 
       // Form a new attributed type using the method result type's nullability.
       return Context.getAttributedType(
-               AttributedType::getNullabilityAttrKind(*nullability),
-               type,
-               type);
+          AttributedType::getNullabilityAttrKind(*nullability), type, type,
+          MethodResultTy->getAs<AttributedType>()->getMacroIdentifier());
     }
 
     return type;
@@ -1408,8 +1410,8 @@
     auto newNullability
       = static_cast<NullabilityKind>(newResultNullabilityIdx-1);
     return Context.getAttributedType(
-             AttributedType::getNullabilityAttrKind(newNullability),
-             resultType, resultType);
+        AttributedType::getNullabilityAttrKind(newNullability), resultType,
+        resultType, nullptr);
   }
 
   return resultType;
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -7266,7 +7266,7 @@
 
   // Create a new AttributedType with the new nullability kind.
   auto NewAttr = AttributedType::getNullabilityAttrKind(MergedKind);
-  return Ctx.getAttributedType(NewAttr, ResTy, ResTy);
+  return Ctx.getAttributedType(NewAttr, ResTy, ResTy, nullptr);
 }
 
 /// ActOnConditionalOp - Parse a ?: operation.  Note that 'LHS' may be null
Index: lib/Sema/SemaDeclObjC.cpp
===================================================================
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -4428,8 +4428,8 @@
 
   // Otherwise, provide the result with the same nullability.
   return S.Context.getAttributedType(
-           AttributedType::getNullabilityAttrKind(*prevNullability),
-           type, type);
+      AttributedType::getNullabilityAttrKind(*prevNullability), type, type,
+      nullptr);
 }
 
 /// Merge information from the declaration of a method in the \@interface
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2784,8 +2784,8 @@
     } else {
       QualType NewT = NewParam->getType();
       NewT = S.Context.getAttributedType(
-                         AttributedType::getNullabilityAttrKind(*Oldnullability),
-                         NewT, NewT);
+          AttributedType::getNullabilityAttrKind(*Oldnullability), NewT, NewT,
+          OldParam->getType()->getAs<AttributedType>()->getMacroIdentifier());
       NewParam->setType(NewT);
     }
   }
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -135,6 +135,10 @@
   assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
 
   while (Tok.is(tok::kw___attribute)) {
+    Token AttrTok = Tok;
+    unsigned OldNumAttrs = attrs.size();
+    unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
+
     ConsumeToken();
     if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after,
                          "attribute")) {
@@ -203,6 +207,35 @@
       SkipUntil(tok::r_paren, StopAtSemi);
     if (endLoc)
       *endLoc = Loc;
+
+    // If this was declared in a macro, attatch the macro IdentifierInfo to the
+    // parsed attribute.
+    SourceLocation AttrTokLoc = AttrTok.getLocation();
+    auto &SrcMgr = PP.getSourceManager();
+    bool AttrStartIsInMacro =
+        (AttrTokLoc.isMacroID() && Lexer::isAtStartOfMacroExpansion(
+                                       AttrTokLoc, SrcMgr, PP.getLangOpts()));
+    bool AttrEndIsInMacro =
+        (Loc.isMacroID() &&
+         Lexer::isAtEndOfMacroExpansion(Loc, SrcMgr, PP.getLangOpts()));
+    bool WholeAttrIsInMacro =
+        (AttrStartIsInMacro && AttrEndIsInMacro &&
+         SrcMgr.getExpansionLoc(AttrTokLoc) == SrcMgr.getExpansionLoc(Loc));
+
+    if (WholeAttrIsInMacro) {
+      StringRef name = Lexer::getSourceText(
+          SrcMgr.getExpansionRange(AttrTokLoc), SrcMgr, PP.getLangOpts());
+      IdentifierInfo *MacroII = PP.getIdentifierInfo(name);
+
+      for (unsigned i = OldNumAttrs; i < attrs.size(); ++i)
+        attrs[i].setMacroIdentifier(MacroII);
+
+      if (LateAttrs) {
+        for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i) {
+          (*LateAttrs)[i]->MacroII = MacroII;
+        }
+      }
+    }
   }
 }
 
Index: lib/AST/TypePrinter.cpp
===================================================================
--- lib/AST/TypePrinter.cpp
+++ lib/AST/TypePrinter.cpp
@@ -1364,7 +1364,18 @@
   if (T->getAttrKind() == attr::ObjCKindOf)
     OS << "__kindof ";
 
-  printBefore(T->getModifiedType(), OS);
+  if (T->getAttrKind() == attr::AddressSpace && T->hasMacroIdentifier()) {
+    OS << T->getMacroIdentifier()->getName() << " ";
+
+    // Remove the underlying address_space so it won't be printed.
+    SplitQualType SplitTy = T->getModifiedType().split();
+    Qualifiers Quals = SplitTy.Quals;
+    if (Quals.getAddressSpace() >= LangAS::FirstTargetAddressSpace)
+      Quals.removeAddressSpace();
+    printBefore(SplitTy.Ty, Quals, OS);
+  } else {
+    printBefore(T->getModifiedType(), OS);
+  }
 
   if (T->isMSTypeSpec()) {
     switch (T->getAttrKind()) {
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -1004,8 +1004,8 @@
           == T->getEquivalentType().getAsOpaquePtr())
       return QualType(T, 0);
 
-    return Ctx.getAttributedType(T->getAttrKind(), modifiedType,
-                                 equivalentType);
+    return Ctx.getAttributedType(T->getAttrKind(), modifiedType, equivalentType,
+                                 T->getMacroIdentifier());
   }
 
   QualType VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) {
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -986,8 +986,9 @@
       return {};
   }
 
-  return Importer.getToContext().getAttributedType(T->getAttrKind(),
-    ToModifiedType, ToEquivalentType);
+  return Importer.getToContext().getAttributedType(
+      T->getAttrKind(), ToModifiedType, ToEquivalentType,
+      T->getMacroIdentifier());
 }
 
 QualType ASTNodeImporter::VisitTemplateTypeParmType(
Index: lib/AST/ASTDiagnostic.cpp
===================================================================
--- lib/AST/ASTDiagnostic.cpp
+++ lib/AST/ASTDiagnostic.cpp
@@ -74,19 +74,22 @@
       QualType RT = Desugar(Context, SugarRT, DesugarReturn);
       if (auto nullability = AttributedType::stripOuterNullability(SugarRT)) {
         RT = Context.getAttributedType(
-            AttributedType::getNullabilityAttrKind(*nullability), RT, RT);
+            AttributedType::getNullabilityAttrKind(*nullability), RT, RT,
+            FT->getReturnType()->getAs<AttributedType>()->getMacroIdentifier());
       }
 
       bool DesugarArgument = false;
       SmallVector<QualType, 4> Args;
       const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT);
       if (FPT) {
         for (QualType SugarPT : FPT->param_types()) {
           QualType PT = Desugar(Context, SugarPT, DesugarArgument);
+          QualType OldSugarPT = SugarPT;
           if (auto nullability =
                   AttributedType::stripOuterNullability(SugarPT)) {
             PT = Context.getAttributedType(
-                AttributedType::getNullabilityAttrKind(*nullability), PT, PT);
+                AttributedType::getNullabilityAttrKind(*nullability), PT, PT,
+                OldSugarPT->getAs<AttributedType>()->getMacroIdentifier());
           }
           Args.push_back(PT);
         }
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -2708,7 +2708,8 @@
     return getAttributedType(
         AT->getAttrKind(),
         getFunctionTypeWithExceptionSpec(AT->getModifiedType(), ESI),
-        getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI));
+        getFunctionTypeWithExceptionSpec(AT->getEquivalentType(), ESI),
+        AT->getMacroIdentifier());
 
   // Anything else must be a function type. Rebuild it with the new exception
   // specification.
@@ -3878,17 +3879,18 @@
 
 QualType ASTContext::getAttributedType(attr::Kind attrKind,
                                        QualType modifiedType,
-                                       QualType equivalentType) {
+                                       QualType equivalentType,
+                                       const IdentifierInfo *MacroII) {
   llvm::FoldingSetNodeID id;
-  AttributedType::Profile(id, attrKind, modifiedType, equivalentType);
+  AttributedType::Profile(id, attrKind, modifiedType, equivalentType, MacroII);
 
   void *insertPos = nullptr;
   AttributedType *type = AttributedTypes.FindNodeOrInsertPos(id, insertPos);
   if (type) return QualType(type, 0);
 
   QualType canon = getCanonicalType(equivalentType);
   type = new (*this, TypeAlignment)
-           AttributedType(canon, attrKind, modifiedType, equivalentType);
+      AttributedType(canon, attrKind, modifiedType, equivalentType, MacroII);
 
   Types.push_back(type);
   AttributedTypes.InsertNode(type, insertPos);
@@ -5461,7 +5463,8 @@
   // int x[_Nullable] -> int * _Nullable
   if (auto Nullability = Ty->getNullability(*this)) {
     Result = const_cast<ASTContext *>(this)->getAttributedType(
-        AttributedType::getNullabilityAttrKind(*Nullability), Result, Result);
+        AttributedType::getNullabilityAttrKind(*Nullability), Result, Result,
+        Ty->getAs<AttributedType>()->getMacroIdentifier());
   }
   return Result;
 }
Index: include/clang/Sema/ParsedAttr.h
===================================================================
--- include/clang/Sema/ParsedAttr.h
+++ include/clang/Sema/ParsedAttr.h
@@ -168,6 +168,7 @@
 private:
   IdentifierInfo *AttrName;
   IdentifierInfo *ScopeName;
+  IdentifierInfo *MacroII = nullptr;
   SourceRange AttrRange;
   SourceLocation ScopeLoc;
   SourceLocation EllipsisLoc;
@@ -534,6 +535,17 @@
     return getPropertyDataBuffer().SetterId;
   }
 
+  /// Set the macro identifier info object that this parsed attribute was
+  /// declared in if it was declared in a macro.
+  void setMacroIdentifier(IdentifierInfo *MacroName) { MacroII = MacroName; }
+
+  /// Returns true if this attribute was declared in a macro.
+  bool hasMacroIdentifier() const { return MacroII != nullptr; }
+
+  /// Return the macro identifier if this attribute was declared in a macro.
+  /// nullptr is returned if it was not declared in a macro.
+  IdentifierInfo *getMacroIdentifier() const { return MacroII; }
+
   /// Get an index into the attribute spelling list
   /// defined in Attr.td. This index is used by an attribute
   /// to pretty print itself.
Index: include/clang/Parse/Parser.h
===================================================================
--- include/clang/Parse/Parser.h
+++ include/clang/Parse/Parser.h
@@ -1114,6 +1114,7 @@
     Parser *Self;
     CachedTokens Toks;
     IdentifierInfo &AttrName;
+    IdentifierInfo *MacroII = nullptr;
     SourceLocation AttrNameLoc;
     SmallVector<Decl*, 2> Decls;
 
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -4315,13 +4315,18 @@
   QualType ModifiedType;
   QualType EquivalentType;
 
+  // If the attribute this type holds was declared entirely in a macro, we store
+  // the macro identifier information. This can be used for printing the macro
+  // name instead of the attribute.
+  const IdentifierInfo *MacroII;
+
   AttributedType(QualType canon, attr::Kind attrKind, QualType modified,
-                 QualType equivalent)
+                 QualType equivalent, const IdentifierInfo *macroII)
       : Type(Attributed, canon, equivalent->isDependentType(),
              equivalent->isInstantiationDependentType(),
              equivalent->isVariablyModifiedType(),
              equivalent->containsUnexpandedParameterPack()),
-        ModifiedType(modified), EquivalentType(equivalent) {
+        ModifiedType(modified), EquivalentType(equivalent), MacroII(macroII) {
     AttributedTypeBits.AttrKind = attrKind;
   }
 
@@ -4333,6 +4338,11 @@
   QualType getModifiedType() const { return ModifiedType; }
   QualType getEquivalentType() const { return EquivalentType; }
 
+  /// Retrieve the type macro identifier info object that this type was created
+  /// with (if available).
+  const IdentifierInfo *getMacroIdentifier() const { return MacroII; }
+  bool hasMacroIdentifier() const { return MacroII != nullptr; }
+
   bool isSugared() const { return true; }
   QualType desugar() const { return getEquivalentType(); }
 
@@ -4387,14 +4397,16 @@
   static Optional<NullabilityKind> stripOuterNullability(QualType &T);
 
   void Profile(llvm::FoldingSetNodeID &ID) {
-    Profile(ID, getAttrKind(), ModifiedType, EquivalentType);
+    Profile(ID, getAttrKind(), ModifiedType, EquivalentType, MacroII);
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID, Kind attrKind,
-                      QualType modified, QualType equivalent) {
+                      QualType modified, QualType equivalent,
+                      const IdentifierInfo *macroII) {
     ID.AddInteger(attrKind);
     ID.AddPointer(modified.getAsOpaquePtr());
     ID.AddPointer(equivalent.getAsOpaquePtr());
+    ID.AddPointer(macroII);
   }
 
   static bool classof(const Type *T) {
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1423,9 +1423,9 @@
 
   QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
 
-  QualType getAttributedType(attr::Kind attrKind,
-                             QualType modifiedType,
-                             QualType equivalentType);
+  QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
+                             QualType equivalentType,
+                             const IdentifierInfo *MacroII);
 
   QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced,
                                         QualType Replacement) const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to