r360109 - Recommit r359859 "[Attribute/Diagnostics] Print macro if definition is an attribute declaration"

Jonas Devlieghere via cfe-commits cfe-commits at lists.llvm.org
Tue May 7 15:49:53 PDT 2019


Hi Leonard,

My personal rule of thumb is that if I can fix it in something like 30
minutes or less, I'll leave the bot red and commit a fix. Otherwise I'll
revert my change. The problem with leaving the bot red is that if something
else breaks, that person doesn't get a signal, and issue start to pile up.

When I see a bot is red and it's blocking me, I will usually send an e-mail
and wait about the same time for a reply, before reverting the change
myself.

Cheers,
Jonas

On Tue, May 7, 2019 at 11:20 AM Leonard Chan <leonardchan at google.com> wrote:

> Thanks! It turns out that we weren't running debuginfo-tests. Trying to
> find a mac I can ssh into to reproduce this.
>
> Another side question: is there usually an etiquette for how long a
> greendragon bot is allowed to stay broken? I don't want to leave it that
> way for too long while working on my fix if it bothers others too much.
>
> Thanks,
> Leonard
>
> On Tue, May 7, 2019 at 10:13 AM Jonas Devlieghere <jonas at devlieghere.com>
> wrote:
>
>> Hi Leonard,
>>
>> The test that is asserting is part of the debuginfo test. (
>> https://github.com/llvm-project/debuginfo-tests)
>> The reason that it's only failing on the non-incremental bot is because
>> the incremental one isn't running those, I believe.
>>
>> RA stands for Release/Asserts.
>>
>> Hope that helps!
>>
>> Cheers,
>> Jonas
>>
>> On Tue, May 7, 2019 at 9:44 AM Leonard Chan <leonardchan at google.com>
>> wrote:
>>
>>> Yup, sorry for the delay. I submitted it overnight thinking it would be
>>> fixed this time. I have one more way that I think should fix it, but before
>>> trying it out, do you know any tips on how I can try to reproduce this
>>> locally? I see that you're running these on an x64 mac, but I can't seem to
>>> trigger this on our own mac builders. Also as a side question, do you what
>>> RA stands for in "Clang Stage 1: cmake, incremental RA, using system
>>> compiler
>>> <http://green.lab.llvm.org/green/job/clang-stage1-cmake-RA-incremental/>"?
>>> It seems that I'm only breaking the non-incremental RA jobs, bit the
>>> incremental one still works fine with my change.
>>>
>>> Thanks,
>>> Leonard
>>>
>>> On Tue, May 7, 2019, 09:26 Jonas Devlieghere <jonas at devlieghere.com>
>>> wrote:
>>>
>>>> Hi Leonard,
>>>>
>>>> It appears that your patch is still triggering an assertion on
>>>> GreenDragon:
>>>> http://green.lab.llvm.org/green/job/clang-stage1-configure-RA/56255/consoleFull#312501878d489585b-5106-414a-ac11-3ff90657619c
>>>>
>>>> Can you please have a look?
>>>>
>>>> Thanks,
>>>> Jonas
>>>>
>>>>
>>>> On Mon, May 6, 2019 at 8:17 PM Leonard Chan via cfe-commits <
>>>> cfe-commits at lists.llvm.org> wrote:
>>>>
>>>>> Author: leonardchan
>>>>> Date: Mon May  6 20:20:17 2019
>>>>> New Revision: 360109
>>>>>
>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=360109&view=rev
>>>>> Log:
>>>>> Recommit r359859 "[Attribute/Diagnostics] Print macro if definition is
>>>>> an attribute declaration"
>>>>>
>>>>> Updated with fix for read of uninitialized memory.
>>>>>
>>>>> Added:
>>>>>     cfe/trunk/test/Frontend/macro_defined_type.cpp
>>>>>     cfe/trunk/test/Sema/address_space_print_macro.c
>>>>> Modified:
>>>>>     cfe/trunk/include/clang/AST/ASTContext.h
>>>>>     cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>>>>>     cfe/trunk/include/clang/AST/Type.h
>>>>>     cfe/trunk/include/clang/AST/TypeLoc.h
>>>>>     cfe/trunk/include/clang/AST/TypeNodes.def
>>>>>     cfe/trunk/include/clang/Parse/Parser.h
>>>>>     cfe/trunk/include/clang/Sema/ParsedAttr.h
>>>>>     cfe/trunk/include/clang/Sema/Sema.h
>>>>>     cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>>>>>     cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
>>>>>     cfe/trunk/lib/AST/ASTContext.cpp
>>>>>     cfe/trunk/lib/AST/ASTDiagnostic.cpp
>>>>>     cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
>>>>>     cfe/trunk/lib/AST/ItaniumMangle.cpp
>>>>>     cfe/trunk/lib/AST/Type.cpp
>>>>>     cfe/trunk/lib/AST/TypePrinter.cpp
>>>>>     cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
>>>>>     cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>>>>>     cfe/trunk/lib/Parse/ParseDecl.cpp
>>>>>     cfe/trunk/lib/Sema/SemaExpr.cpp
>>>>>     cfe/trunk/lib/Sema/SemaStmt.cpp
>>>>>     cfe/trunk/lib/Sema/SemaType.cpp
>>>>>     cfe/trunk/lib/Sema/TreeTransform.h
>>>>>     cfe/trunk/lib/Serialization/ASTReader.cpp
>>>>>     cfe/trunk/lib/Serialization/ASTWriter.cpp
>>>>>     cfe/trunk/test/Sema/address_spaces.c
>>>>>     cfe/trunk/test/SemaObjC/externally-retained.m
>>>>>     cfe/trunk/test/SemaObjC/gc-attributes.m
>>>>>     cfe/trunk/test/SemaObjC/mrc-weak.m
>>>>>     cfe/trunk/test/SemaObjCXX/gc-attributes.mm
>>>>>     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=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
>>>>> +++ cfe/trunk/include/clang/AST/ASTContext.h Mon May  6 20:20:17 2019
>>>>> @@ -1441,6 +1441,9 @@ public:
>>>>>
>>>>>    QualType getParenType(QualType NamedType) const;
>>>>>
>>>>> +  QualType getMacroQualifiedType(QualType UnderlyingTy,
>>>>> +                                 const IdentifierInfo *MacroII) const;
>>>>> +
>>>>>    QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
>>>>>                               NestedNameSpecifier *NNS, QualType
>>>>> NamedType,
>>>>>                               TagDecl *OwnedTagDecl = nullptr) const;
>>>>>
>>>>> Modified: cfe/trunk/include/clang/AST/RecursiveASTVisitor.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/RecursiveASTVisitor.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/AST/RecursiveASTVisitor.h (original)
>>>>> +++ cfe/trunk/include/clang/AST/RecursiveASTVisitor.h Mon May  6
>>>>> 20:20:17 2019
>>>>> @@ -1065,6 +1065,9 @@ DEF_TRAVERSE_TYPE(AttributedType,
>>>>>
>>>>>  DEF_TRAVERSE_TYPE(ParenType, {
>>>>> TRY_TO(TraverseType(T->getInnerType())); })
>>>>>
>>>>> +DEF_TRAVERSE_TYPE(MacroQualifiedType,
>>>>> +                  { TRY_TO(TraverseType(T->getUnderlyingType())); })
>>>>> +
>>>>>  DEF_TRAVERSE_TYPE(ElaboratedType, {
>>>>>    if (T->getQualifier()) {
>>>>>      TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
>>>>> @@ -1308,6 +1311,9 @@ DEF_TRAVERSE_TYPELOC(InjectedClassNameTy
>>>>>
>>>>>  DEF_TRAVERSE_TYPELOC(ParenType, {
>>>>> TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
>>>>>
>>>>> +DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
>>>>> +                     { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
>>>>> +
>>>>>  DEF_TRAVERSE_TYPELOC(AttributedType,
>>>>>                       { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc()));
>>>>> })
>>>>>
>>>>>
>>>>> Modified: cfe/trunk/include/clang/AST/Type.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/AST/Type.h (original)
>>>>> +++ cfe/trunk/include/clang/AST/Type.h Mon May  6 20:20:17 2019
>>>>> @@ -4184,6 +4184,41 @@ public:
>>>>>    static bool classof(const Type *T) { return T->getTypeClass() ==
>>>>> Typedef; }
>>>>>  };
>>>>>
>>>>> +/// Sugar type that represents a type that was qualified by a
>>>>> qualifier written
>>>>> +/// as a macro invocation.
>>>>> +class MacroQualifiedType : public Type {
>>>>> +  friend class ASTContext; // ASTContext creates these.
>>>>> +
>>>>> +  QualType UnderlyingTy;
>>>>> +  const IdentifierInfo *MacroII;
>>>>> +
>>>>> +  MacroQualifiedType(QualType UnderlyingTy, QualType CanonTy,
>>>>> +                     const IdentifierInfo *MacroII)
>>>>> +      : Type(MacroQualified, CanonTy, UnderlyingTy->isDependentType(),
>>>>> +             UnderlyingTy->isInstantiationDependentType(),
>>>>> +             UnderlyingTy->isVariablyModifiedType(),
>>>>> +             UnderlyingTy->containsUnexpandedParameterPack()),
>>>>> +        UnderlyingTy(UnderlyingTy), MacroII(MacroII) {
>>>>> +    assert(isa<AttributedType>(UnderlyingTy) &&
>>>>> +           "Expected a macro qualified type to only wrap attributed
>>>>> types.");
>>>>> +  }
>>>>> +
>>>>> +public:
>>>>> +  const IdentifierInfo *getMacroIdentifier() const { return MacroII; }
>>>>> +  QualType getUnderlyingType() const { return UnderlyingTy; }
>>>>> +
>>>>> +  /// Return this attributed type's modified type with no qualifiers
>>>>> attached to
>>>>> +  /// it.
>>>>> +  QualType getModifiedType() const;
>>>>> +
>>>>> +  bool isSugared() const { return true; }
>>>>> +  QualType desugar() const;
>>>>> +
>>>>> +  static bool classof(const Type *T) {
>>>>> +    return T->getTypeClass() == MacroQualified;
>>>>> +  }
>>>>> +};
>>>>> +
>>>>>  /// Represents a `typeof` (or __typeof__) expression (a GCC
>>>>> extension).
>>>>>  class TypeOfExprType : public Type {
>>>>>    Expr *TOExpr;
>>>>> @@ -6805,6 +6840,8 @@ template <typename T> const T *Type::get
>>>>>        Ty = P->desugar().getTypePtr();
>>>>>      else if (const auto *A = dyn_cast<AdjustedType>(Ty))
>>>>>        Ty = A->desugar().getTypePtr();
>>>>> +    else if (const auto *M = dyn_cast<MacroQualifiedType>(Ty))
>>>>> +      Ty = M->desugar().getTypePtr();
>>>>>      else
>>>>>        break;
>>>>>    }
>>>>>
>>>>> Modified: cfe/trunk/include/clang/AST/TypeLoc.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeLoc.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/AST/TypeLoc.h (original)
>>>>> +++ cfe/trunk/include/clang/AST/TypeLoc.h Mon May  6 20:20:17 2019
>>>>> @@ -173,6 +173,9 @@ public:
>>>>>
>>>>>    TypeLoc IgnoreParens() const;
>>>>>
>>>>> +  /// Strips MacroDefinitionTypeLocs from a type location.
>>>>> +  TypeLoc IgnoreMacroDefinitions() const;
>>>>> +
>>>>>    /// Find a type with the location of an explicit type qualifier.
>>>>>    ///
>>>>>    /// The result, if non-null, will be one of:
>>>>> @@ -1080,6 +1083,39 @@ public:
>>>>>    }
>>>>>  };
>>>>>
>>>>> +struct MacroQualifiedLocInfo {
>>>>> +  SourceLocation ExpansionLoc;
>>>>> +};
>>>>> +
>>>>> +class MacroQualifiedTypeLoc
>>>>> +    : public ConcreteTypeLoc<UnqualTypeLoc, MacroQualifiedTypeLoc,
>>>>> +                             MacroQualifiedType,
>>>>> MacroQualifiedLocInfo> {
>>>>> +public:
>>>>> +  void initializeLocal(ASTContext &Context, SourceLocation Loc) {
>>>>> +    setExpansionLoc(Loc);
>>>>> +  }
>>>>> +
>>>>> +  TypeLoc getInnerLoc() const { return getInnerTypeLoc(); }
>>>>> +
>>>>> +  const IdentifierInfo *getMacroIdentifier() const {
>>>>> +    return getTypePtr()->getMacroIdentifier();
>>>>> +  }
>>>>> +
>>>>> +  SourceLocation getExpansionLoc() const {
>>>>> +    return this->getLocalData()->ExpansionLoc;
>>>>> +  }
>>>>> +
>>>>> +  void setExpansionLoc(SourceLocation Loc) {
>>>>> +    this->getLocalData()->ExpansionLoc = Loc;
>>>>> +  }
>>>>> +
>>>>> +  QualType getInnerType() const { return
>>>>> getTypePtr()->getUnderlyingType(); }
>>>>> +
>>>>> +  SourceRange getLocalSourceRange() const {
>>>>> +    return getInnerLoc().getLocalSourceRange();
>>>>> +  }
>>>>> +};
>>>>> +
>>>>>  struct ParenLocInfo {
>>>>>    SourceLocation LParenLoc;
>>>>>    SourceLocation RParenLoc;
>>>>> @@ -2289,6 +2325,8 @@ inline T TypeLoc::getAsAdjusted() const
>>>>>        Cur = ETL.getNamedTypeLoc();
>>>>>      else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
>>>>>        Cur = ATL.getOriginalLoc();
>>>>> +    else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
>>>>> +      Cur = MQL.getInnerLoc();
>>>>>      else
>>>>>        break;
>>>>>    }
>>>>>
>>>>> Modified: cfe/trunk/include/clang/AST/TypeNodes.def
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/TypeNodes.def?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/AST/TypeNodes.def (original)
>>>>> +++ cfe/trunk/include/clang/AST/TypeNodes.def Mon May  6 20:20:17 2019
>>>>> @@ -82,6 +82,7 @@ TYPE(FunctionNoProto, FunctionType)
>>>>>  DEPENDENT_TYPE(UnresolvedUsing, Type)
>>>>>  NON_CANONICAL_TYPE(Paren, Type)
>>>>>  NON_CANONICAL_TYPE(Typedef, Type)
>>>>> +NON_CANONICAL_TYPE(MacroQualified, Type)
>>>>>  NON_CANONICAL_TYPE(Adjusted, Type)
>>>>>  NON_CANONICAL_TYPE(Decayed, AdjustedType)
>>>>>  NON_CANONICAL_UNLESS_DEPENDENT_TYPE(TypeOfExpr, Type)
>>>>>
>>>>> Modified: cfe/trunk/include/clang/Parse/Parser.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/Parse/Parser.h (original)
>>>>> +++ cfe/trunk/include/clang/Parse/Parser.h Mon May  6 20:20:17 2019
>>>>> @@ -1158,6 +1158,7 @@ private:
>>>>>      Parser *Self;
>>>>>      CachedTokens Toks;
>>>>>      IdentifierInfo &AttrName;
>>>>> +    IdentifierInfo *MacroII = nullptr;
>>>>>      SourceLocation AttrNameLoc;
>>>>>      SmallVector<Decl*, 2> Decls;
>>>>>
>>>>>
>>>>> Modified: cfe/trunk/include/clang/Sema/ParsedAttr.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/Sema/ParsedAttr.h (original)
>>>>> +++ cfe/trunk/include/clang/Sema/ParsedAttr.h Mon May  6 20:20:17 2019
>>>>> @@ -167,6 +167,8 @@ public:
>>>>>  private:
>>>>>    IdentifierInfo *AttrName;
>>>>>    IdentifierInfo *ScopeName;
>>>>> +  IdentifierInfo *MacroII = nullptr;
>>>>> +  SourceLocation MacroExpansionLoc;
>>>>>    SourceRange AttrRange;
>>>>>    SourceLocation ScopeLoc;
>>>>>    SourceLocation EllipsisLoc;
>>>>> @@ -547,6 +549,27 @@ public:
>>>>>      return getPropertyDataBuffer().SetterId;
>>>>>    }
>>>>>
>>>>> +  /// Set the macro identifier info object that this parsed attribute
>>>>> was
>>>>> +  /// declared in if it was declared in a macro. Also set the
>>>>> expansion location
>>>>> +  /// of the macro.
>>>>> +  void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation
>>>>> Loc) {
>>>>> +    MacroII = MacroName;
>>>>> +    MacroExpansionLoc = Loc;
>>>>> +  }
>>>>> +
>>>>> +  /// 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; }
>>>>> +
>>>>> +  SourceLocation getMacroExpansionLoc() const {
>>>>> +    assert(hasMacroIdentifier() && "Can only get the macro expansion
>>>>> location "
>>>>> +                                   "if this attribute has a macro
>>>>> identifier.");
>>>>> +    return MacroExpansionLoc;
>>>>> +  }
>>>>> +
>>>>>    /// Get an index into the attribute spelling list
>>>>>    /// defined in Attr.td. This index is used by an attribute
>>>>>    /// to pretty print itself.
>>>>>
>>>>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>>>> +++ cfe/trunk/include/clang/Sema/Sema.h Mon May  6 20:20:17 2019
>>>>> @@ -3506,7 +3506,7 @@ public:
>>>>>    // Check if there is an explicit attribute, but only look through
>>>>> parens.
>>>>>    // The intent is to look for an attribute on the current
>>>>> declarator, but not
>>>>>    // one that came from a typedef.
>>>>> -  bool hasExplicitCallingConv(QualType &T);
>>>>> +  bool hasExplicitCallingConv(QualType T);
>>>>>
>>>>>    /// Get the outermost AttributedType node that sets a calling
>>>>> convention.
>>>>>    /// Valid types should not have multiple attributes with different
>>>>> CCs.
>>>>>
>>>>> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
>>>>> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon May  6
>>>>> 20:20:17 2019
>>>>> @@ -1173,7 +1173,10 @@ namespace serialization {
>>>>>        TYPE_DEPENDENT_ADDRESS_SPACE = 47,
>>>>>
>>>>>        /// A dependentSizedVectorType record.
>>>>> -      TYPE_DEPENDENT_SIZED_VECTOR = 48
>>>>> +      TYPE_DEPENDENT_SIZED_VECTOR = 48,
>>>>> +
>>>>> +      /// A type defined in a macro.
>>>>> +      TYPE_MACRO_QUALIFIED = 49
>>>>>      };
>>>>>
>>>>>      /// The type IDs for special types constructed by semantic
>>>>>
>>>>> Modified: cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp (original)
>>>>> +++ cfe/trunk/lib/ARCMigrate/TransGCAttrs.cpp Mon May  6 20:20:17 2019
>>>>> @@ -68,6 +68,9 @@ public:
>>>>>          if (handleAttr(Attr, D))
>>>>>            break;
>>>>>          TL = Attr.getModifiedLoc();
>>>>> +      } else if (MacroQualifiedTypeLoc MDTL =
>>>>> +                     TL.getAs<MacroQualifiedTypeLoc>()) {
>>>>> +        TL = MDTL.getInnerLoc();
>>>>>        } else if (ArrayTypeLoc Arr = TL.getAs<ArrayTypeLoc>()) {
>>>>>          TL = Arr.getElementLoc();
>>>>>        } else if (PointerTypeLoc PT = TL.getAs<PointerTypeLoc>()) {
>>>>>
>>>>> Modified: cfe/trunk/lib/AST/ASTContext.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
>>>>> +++ cfe/trunk/lib/AST/ASTContext.cpp Mon May  6 20:20:17 2019
>>>>> @@ -2047,6 +2047,10 @@ TypeInfo ASTContext::getTypeInfoImpl(con
>>>>>    case Type::Paren:
>>>>>      return
>>>>> getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
>>>>>
>>>>> +  case Type::MacroQualified:
>>>>> +    return getTypeInfo(
>>>>> +
>>>>> cast<MacroQualifiedType>(T)->getUnderlyingType().getTypePtr());
>>>>> +
>>>>>    case Type::ObjCTypeParam:
>>>>>      return
>>>>> getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
>>>>>
>>>>> @@ -3929,7 +3933,7 @@ QualType ASTContext::getAttributedType(a
>>>>>
>>>>>    QualType canon = getCanonicalType(equivalentType);
>>>>>    type = new (*this, TypeAlignment)
>>>>> -           AttributedType(canon, attrKind, modifiedType,
>>>>> equivalentType);
>>>>> +      AttributedType(canon, attrKind, modifiedType, equivalentType);
>>>>>
>>>>>    Types.push_back(type);
>>>>>    AttributedTypes.InsertNode(type, insertPos);
>>>>> @@ -4210,6 +4214,19 @@ ASTContext::getParenType(QualType InnerT
>>>>>    return QualType(T, 0);
>>>>>  }
>>>>>
>>>>> +QualType
>>>>> +ASTContext::getMacroQualifiedType(QualType UnderlyingTy,
>>>>> +                                  const IdentifierInfo *MacroII)
>>>>> const {
>>>>> +  QualType Canon = UnderlyingTy;
>>>>> +  if (!Canon.isCanonical())
>>>>> +    Canon = getCanonicalType(UnderlyingTy);
>>>>> +
>>>>> +  auto *newType = new (*this, TypeAlignment)
>>>>> +      MacroQualifiedType(UnderlyingTy, Canon, MacroII);
>>>>> +  Types.push_back(newType);
>>>>> +  return QualType(newType, 0);
>>>>> +}
>>>>> +
>>>>>  QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword
>>>>> Keyword,
>>>>>                                            NestedNameSpecifier *NNS,
>>>>>                                            const IdentifierInfo *Name,
>>>>>
>>>>> Modified: cfe/trunk/lib/AST/ASTDiagnostic.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTDiagnostic.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/AST/ASTDiagnostic.cpp (original)
>>>>> +++ cfe/trunk/lib/AST/ASTDiagnostic.cpp Mon May  6 20:20:17 2019
>>>>> @@ -41,6 +41,11 @@ static QualType Desugar(ASTContext &Cont
>>>>>        QT = PT->desugar();
>>>>>        continue;
>>>>>      }
>>>>> +    // ... or a macro defined type ...
>>>>> +    if (const MacroQualifiedType *MDT =
>>>>> dyn_cast<MacroQualifiedType>(Ty)) {
>>>>> +      QT = MDT->desugar();
>>>>> +      continue;
>>>>> +    }
>>>>>      // ...or a substituted template type parameter ...
>>>>>      if (const SubstTemplateTypeParmType *ST =
>>>>>            dyn_cast<SubstTemplateTypeParmType>(Ty)) {
>>>>>
>>>>> Modified: cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp (original)
>>>>> +++ cfe/trunk/lib/AST/ASTStructuralEquivalence.cpp Mon May  6 20:20:17
>>>>> 2019
>>>>> @@ -595,6 +595,13 @@ static bool IsStructurallyEquivalent(Str
>>>>>        return false;
>>>>>      break;
>>>>>
>>>>> +  case Type::MacroQualified:
>>>>> +    if (!IsStructurallyEquivalent(
>>>>> +            Context,
>>>>> cast<MacroQualifiedType>(T1)->getUnderlyingType(),
>>>>> +            cast<MacroQualifiedType>(T2)->getUnderlyingType()))
>>>>> +      return false;
>>>>> +    break;
>>>>> +
>>>>>    case Type::Typedef:
>>>>>      if (!IsStructurallyEquivalent(Context,
>>>>> cast<TypedefType>(T1)->getDecl(),
>>>>>                                    cast<TypedefType>(T2)->getDecl()))
>>>>>
>>>>> Modified: cfe/trunk/lib/AST/ItaniumMangle.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ItaniumMangle.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/AST/ItaniumMangle.cpp (original)
>>>>> +++ cfe/trunk/lib/AST/ItaniumMangle.cpp Mon May  6 20:20:17 2019
>>>>> @@ -1963,6 +1963,7 @@ bool CXXNameMangler::mangleUnresolvedTyp
>>>>>    case Type::ObjCTypeParam:
>>>>>    case Type::Atomic:
>>>>>    case Type::Pipe:
>>>>> +  case Type::MacroQualified:
>>>>>      llvm_unreachable("type is illegal as a nested name specifier");
>>>>>
>>>>>    case Type::SubstTemplateTypeParmPack:
>>>>>
>>>>> Modified: cfe/trunk/lib/AST/Type.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/AST/Type.cpp (original)
>>>>> +++ cfe/trunk/lib/AST/Type.cpp Mon May  6 20:20:17 2019
>>>>> @@ -973,6 +973,7 @@ public:
>>>>>
>>>>>    SUGARED_TYPE_CLASS(Typedef)
>>>>>    SUGARED_TYPE_CLASS(ObjCTypeParam)
>>>>> +  SUGARED_TYPE_CLASS(MacroQualified)
>>>>>
>>>>>    QualType VisitAdjustedType(const AdjustedType *T) {
>>>>>      QualType originalType = recurse(T->getOriginalType());
>>>>> @@ -1735,6 +1736,10 @@ namespace {
>>>>>        return Visit(T->getModifiedType());
>>>>>      }
>>>>>
>>>>> +    Type *VisitMacroQualifiedType(const MacroQualifiedType *T) {
>>>>> +      return Visit(T->getUnderlyingType());
>>>>> +    }
>>>>> +
>>>>>      Type *VisitAdjustedType(const AdjustedType *T) {
>>>>>        return Visit(T->getOriginalType());
>>>>>      }
>>>>> @@ -3160,6 +3165,20 @@ QualType TypedefType::desugar() const {
>>>>>    return getDecl()->getUnderlyingType();
>>>>>  }
>>>>>
>>>>> +QualType MacroQualifiedType::desugar() const { return
>>>>> getUnderlyingType(); }
>>>>> +
>>>>> +QualType MacroQualifiedType::getModifiedType() const {
>>>>> +  // Step over MacroQualifiedTypes from the same macro to find the
>>>>> type
>>>>> +  // ultimately qualified by the macro qualifier.
>>>>> +  QualType Inner =
>>>>> cast<AttributedType>(getUnderlyingType())->getModifiedType();
>>>>> +  while (auto *InnerMQT = dyn_cast<MacroQualifiedType>(Inner)) {
>>>>> +    if (InnerMQT->getMacroIdentifier() != getMacroIdentifier())
>>>>> +      break;
>>>>> +    Inner = InnerMQT->getModifiedType();
>>>>> +  }
>>>>> +  return Inner;
>>>>> +}
>>>>> +
>>>>>  TypeOfExprType::TypeOfExprType(Expr *E, QualType can)
>>>>>      : Type(TypeOfExpr, can, E->isTypeDependent(),
>>>>>             E->isInstantiationDependent(),
>>>>>
>>>>> Modified: cfe/trunk/lib/AST/TypePrinter.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/TypePrinter.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/AST/TypePrinter.cpp (original)
>>>>> +++ cfe/trunk/lib/AST/TypePrinter.cpp Mon May  6 20:20:17 2019
>>>>> @@ -259,6 +259,7 @@ bool TypePrinter::canPrefixQualifiers(co
>>>>>      case Type::Paren:
>>>>>      case Type::PackExpansion:
>>>>>      case Type::SubstTemplateTypeParm:
>>>>> +    case Type::MacroQualified:
>>>>>        CanPrefixQualifiers = false;
>>>>>        break;
>>>>>
>>>>> @@ -963,6 +964,21 @@ void TypePrinter::printTypedefBefore(con
>>>>>    printTypeSpec(T->getDecl(), OS);
>>>>>  }
>>>>>
>>>>> +void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType
>>>>> *T,
>>>>> +                                            raw_ostream &OS) {
>>>>> +  StringRef MacroName = T->getMacroIdentifier()->getName();
>>>>> +  OS << MacroName << " ";
>>>>> +
>>>>> +  // Since this type is meant to print the macro instead of the whole
>>>>> attribute,
>>>>> +  // we trim any attributes and go directly to the original modified
>>>>> type.
>>>>> +  printBefore(T->getModifiedType(), OS);
>>>>> +}
>>>>> +
>>>>> +void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType
>>>>> *T,
>>>>> +                                           raw_ostream &OS) {
>>>>> +  printAfter(T->getModifiedType(), OS);
>>>>> +}
>>>>> +
>>>>>  void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream
>>>>> &OS) {}
>>>>>
>>>>>  void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,
>>>>>
>>>>> Modified: cfe/trunk/lib/CodeGen/CGDebugInfo.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDebugInfo.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/CodeGen/CGDebugInfo.cpp (original)
>>>>> +++ cfe/trunk/lib/CodeGen/CGDebugInfo.cpp Mon May  6 20:20:17 2019
>>>>> @@ -2844,6 +2844,9 @@ static QualType UnwrapTypeForDebugInfo(Q
>>>>>      case Type::Paren:
>>>>>        T = cast<ParenType>(T)->getInnerType();
>>>>>        break;
>>>>> +    case Type::MacroQualified:
>>>>> +      T = cast<MacroQualifiedType>(T)->getUnderlyingType();
>>>>> +      break;
>>>>>      case Type::SubstTemplateTypeParm:
>>>>>        T = cast<SubstTemplateTypeParmType>(T)->getReplacementType();
>>>>>        break;
>>>>> @@ -3023,6 +3026,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNod
>>>>>    case Type::DeducedTemplateSpecialization:
>>>>>    case Type::Elaborated:
>>>>>    case Type::Paren:
>>>>> +  case Type::MacroQualified:
>>>>>    case Type::SubstTemplateTypeParm:
>>>>>    case Type::TypeOfExpr:
>>>>>    case Type::TypeOf:
>>>>>
>>>>> Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
>>>>> +++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Mon May  6 20:20:17 2019
>>>>> @@ -2149,6 +2149,7 @@ void CodeGenFunction::EmitVariablyModifi
>>>>>      case Type::Attributed:
>>>>>      case Type::SubstTemplateTypeParm:
>>>>>      case Type::PackExpansion:
>>>>> +    case Type::MacroQualified:
>>>>>        // Keep walking after single level desugaring.
>>>>>        type = type.getSingleStepDesugaredType(getContext());
>>>>>        break;
>>>>>
>>>>> Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
>>>>> +++ cfe/trunk/lib/Parse/ParseDecl.cpp Mon May  6 20:20:17 2019
>>>>> @@ -85,6 +85,23 @@ static bool isAttributeLateParsed(const
>>>>>  #undef CLANG_ATTR_LATE_PARSED_LIST
>>>>>  }
>>>>>
>>>>> +/// Check if the a start and end source location expand to the same
>>>>> macro.
>>>>> +bool FindLocsWithCommonFileID(Preprocessor &PP, SourceLocation
>>>>> StartLoc,
>>>>> +                              SourceLocation EndLoc) {
>>>>> +  if (!StartLoc.isMacroID() || !EndLoc.isMacroID())
>>>>> +    return false;
>>>>> +
>>>>> +  SourceManager &SM = PP.getSourceManager();
>>>>> +  if (SM.getFileID(StartLoc) != SM.getFileID(EndLoc))
>>>>> +    return false;
>>>>> +
>>>>> +  bool AttrStartIsInMacro =
>>>>> +      Lexer::isAtStartOfMacroExpansion(StartLoc, SM,
>>>>> PP.getLangOpts());
>>>>> +  bool AttrEndIsInMacro =
>>>>> +      Lexer::isAtEndOfMacroExpansion(EndLoc, SM, PP.getLangOpts());
>>>>> +  return AttrStartIsInMacro && AttrEndIsInMacro;
>>>>> +}
>>>>> +
>>>>>  /// ParseGNUAttributes - Parse a non-empty attributes list.
>>>>>  ///
>>>>>  /// [GNU] attributes:
>>>>> @@ -133,7 +150,10 @@ void Parser::ParseGNUAttributes(ParsedAt
>>>>>    assert(Tok.is(tok::kw___attribute) && "Not a GNU attribute list!");
>>>>>
>>>>>    while (Tok.is(tok::kw___attribute)) {
>>>>> -    ConsumeToken();
>>>>> +    SourceLocation AttrTokLoc = ConsumeToken();
>>>>> +    unsigned OldNumAttrs = attrs.size();
>>>>> +    unsigned OldNumLateAttrs = LateAttrs ? LateAttrs->size() : 0;
>>>>> +
>>>>>      if (ExpectAndConsume(tok::l_paren,
>>>>> diag::err_expected_lparen_after,
>>>>>                           "attribute")) {
>>>>>        SkipUntil(tok::r_paren, StopAtSemi); // skip until ) or ;
>>>>> @@ -201,6 +221,24 @@ void Parser::ParseGNUAttributes(ParsedAt
>>>>>        SkipUntil(tok::r_paren, StopAtSemi);
>>>>>      if (endLoc)
>>>>>        *endLoc = Loc;
>>>>> +
>>>>> +    // If this was declared in a macro, attach the macro
>>>>> IdentifierInfo to the
>>>>> +    // parsed attribute.
>>>>> +    if (FindLocsWithCommonFileID(PP, AttrTokLoc, Loc)) {
>>>>> +      auto &SM = PP.getSourceManager();
>>>>> +      CharSourceRange ExpansionRange =
>>>>> SM.getExpansionRange(AttrTokLoc);
>>>>> +      StringRef FoundName =
>>>>> +          Lexer::getSourceText(ExpansionRange, SM, PP.getLangOpts());
>>>>> +      IdentifierInfo *MacroII = PP.getIdentifierInfo(FoundName);
>>>>> +
>>>>> +      for (unsigned i = OldNumAttrs; i < attrs.size(); ++i)
>>>>> +        attrs[i].setMacroIdentifier(MacroII,
>>>>> ExpansionRange.getBegin());
>>>>> +
>>>>> +      if (LateAttrs) {
>>>>> +        for (unsigned i = OldNumLateAttrs; i < LateAttrs->size(); ++i)
>>>>> +          (*LateAttrs)[i]->MacroII = MacroII;
>>>>> +      }
>>>>> +    }
>>>>>    }
>>>>>  }
>>>>>
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
>>>>> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon May  6 20:20:17 2019
>>>>> @@ -4096,6 +4096,7 @@ static void captureVariablyModifiedType(
>>>>>      case Type::Attributed:
>>>>>      case Type::SubstTemplateTypeParm:
>>>>>      case Type::PackExpansion:
>>>>> +    case Type::MacroQualified:
>>>>>        // Keep walking after single level desugaring.
>>>>>        T = T.getSingleStepDesugaredType(Context);
>>>>>        break;
>>>>> @@ -13695,8 +13696,8 @@ void Sema::ActOnBlockArguments(SourceLoc
>>>>>    // Look for an explicit signature in that function type.
>>>>>    FunctionProtoTypeLoc ExplicitSignature;
>>>>>
>>>>> -  if ((ExplicitSignature =
>>>>> -           Sig->getTypeLoc().getAsAdjusted<FunctionProtoTypeLoc>())) {
>>>>> +  if ((ExplicitSignature = Sig->getTypeLoc()
>>>>> +
>>>>>  .getAsAdjusted<FunctionProtoTypeLoc>())) {
>>>>>
>>>>>      // Check whether that explicit signature was synthesized by
>>>>>      // GetTypeForDeclarator.  If so, don't save that as part of the
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
>>>>> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Mon May  6 20:20:17 2019
>>>>> @@ -3390,10 +3390,10 @@ bool LocalTypedefNameReferencer::VisitRe
>>>>>  }
>>>>>
>>>>>  TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const {
>>>>> -  TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens();
>>>>> -  while (auto ATL = TL.getAs<AttributedTypeLoc>())
>>>>> -    TL = ATL.getModifiedLoc().IgnoreParens();
>>>>> -  return TL.castAs<FunctionProtoTypeLoc>().getReturnLoc();
>>>>> +  return FD->getTypeSourceInfo()
>>>>> +      ->getTypeLoc()
>>>>> +      .getAsAdjusted<FunctionProtoTypeLoc>()
>>>>> +      .getReturnLoc();
>>>>>  }
>>>>>
>>>>>  /// Deduce the return type for a function from a returned expression,
>>>>> per
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/SemaType.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/SemaType.cpp (original)
>>>>> +++ cfe/trunk/lib/Sema/SemaType.cpp Mon May  6 20:20:17 2019
>>>>> @@ -182,6 +182,10 @@ namespace {
>>>>>      SmallVector<TypeAttrPair, 8> AttrsForTypes;
>>>>>      bool AttrsForTypesSorted = true;
>>>>>
>>>>> +    /// MacroQualifiedTypes mapping to macro expansion locations that
>>>>> will be
>>>>> +    /// stored in a MacroQualifiedTypeLoc.
>>>>> +    llvm::DenseMap<const MacroQualifiedType *, SourceLocation>
>>>>> LocsForMacros;
>>>>> +
>>>>>      /// Flag to indicate we parsed a noderef attribute. This is used
>>>>> for
>>>>>      /// validating that noderef was used on a pointer or array.
>>>>>      bool parsedNoDeref;
>>>>> @@ -295,6 +299,19 @@ namespace {
>>>>>        llvm_unreachable("no Attr* for AttributedType*");
>>>>>      }
>>>>>
>>>>> +    SourceLocation
>>>>> +    getExpansionLocForMacroQualifiedType(const MacroQualifiedType
>>>>> *MQT) const {
>>>>> +      auto FoundLoc = LocsForMacros.find(MQT);
>>>>> +      assert(FoundLoc != LocsForMacros.end() &&
>>>>> +             "Unable to find macro expansion location for
>>>>> MacroQualifedType");
>>>>> +      return FoundLoc->second;
>>>>> +    }
>>>>> +
>>>>> +    void setExpansionLocForMacroQualifiedType(const
>>>>> MacroQualifiedType *MQT,
>>>>> +                                              SourceLocation Loc) {
>>>>> +      LocsForMacros[MQT] = Loc;
>>>>> +    }
>>>>> +
>>>>>      void setParsedNoDeref(bool parsed) { parsedNoDeref = parsed; }
>>>>>
>>>>>      bool didParseNoDeref() const { return parsedNoDeref; }
>>>>> @@ -5644,6 +5661,9 @@ namespace {
>>>>>        assert(Chunk.Kind == DeclaratorChunk::Pipe);
>>>>>        TL.setKWLoc(Chunk.Loc);
>>>>>      }
>>>>> +    void VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
>>>>> +      TL.setExpansionLoc(Chunk.Loc);
>>>>> +    }
>>>>>
>>>>>      void VisitTypeLoc(TypeLoc TL) {
>>>>>        llvm_unreachable("unsupported TypeLoc kind in declarator!");
>>>>> @@ -5722,6 +5742,12 @@ GetTypeSourceInfoForDeclarator(TypeProce
>>>>>        CurrTL = ATL.getValueLoc().getUnqualifiedLoc();
>>>>>      }
>>>>>
>>>>> +    while (MacroQualifiedTypeLoc TL =
>>>>> CurrTL.getAs<MacroQualifiedTypeLoc>()) {
>>>>> +      TL.setExpansionLoc(
>>>>> +
>>>>> State.getExpansionLocForMacroQualifiedType(TL.getTypePtr()));
>>>>> +      CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
>>>>> +    }
>>>>> +
>>>>>      while (AttributedTypeLoc TL = CurrTL.getAs<AttributedTypeLoc>()) {
>>>>>        fillAttributedTypeLoc(TL, State);
>>>>>        CurrTL = TL.getNextTypeLoc().getUnqualifiedLoc();
>>>>> @@ -6982,12 +7008,16 @@ static bool handleFunctionTypeAttr(TypeP
>>>>>    return true;
>>>>>  }
>>>>>
>>>>> -bool Sema::hasExplicitCallingConv(QualType &T) {
>>>>> -  QualType R = T.IgnoreParens();
>>>>> -  while (const AttributedType *AT = dyn_cast<AttributedType>(R)) {
>>>>> +bool Sema::hasExplicitCallingConv(QualType T) {
>>>>> +  const AttributedType *AT;
>>>>> +
>>>>> +  // Stop if we'd be stripping off a typedef sugar node to reach the
>>>>> +  // AttributedType.
>>>>> +  while ((AT = T->getAs<AttributedType>()) &&
>>>>> +         AT->getAs<TypedefType>() == T->getAs<TypedefType>()) {
>>>>>      if (AT->isCallingConv())
>>>>>        return true;
>>>>> -    R = AT->getModifiedType().IgnoreParens();
>>>>> +    T = AT->getModifiedType();
>>>>>    }
>>>>>    return false;
>>>>>  }
>>>>> @@ -7572,6 +7602,18 @@ static void processTypeAttrs(TypeProcess
>>>>>          distributeFunctionTypeAttr(state, attr, type);
>>>>>        break;
>>>>>      }
>>>>> +
>>>>> +    // Handle attributes that are defined in a macro. We do not want
>>>>> this to be
>>>>> +    // applied to ObjC builtin attributes.
>>>>> +    if (isa<AttributedType>(type) && attr.hasMacroIdentifier() &&
>>>>> +        !type.getQualifiers().hasObjCLifetime() &&
>>>>> +        !type.getQualifiers().hasObjCGCAttr()) {
>>>>> +      const IdentifierInfo *MacroII = attr.getMacroIdentifier();
>>>>> +      type = state.getSema().Context.getMacroQualifiedType(type,
>>>>> MacroII);
>>>>> +      state.setExpansionLocForMacroQualifiedType(
>>>>> +          cast<MacroQualifiedType>(type.getTypePtr()),
>>>>> +          attr.getMacroExpansionLoc());
>>>>> +    }
>>>>>    }
>>>>>
>>>>>    if (!state.getSema().getLangOpts().OpenCL ||
>>>>>
>>>>> Modified: cfe/trunk/lib/Sema/TreeTransform.h
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Sema/TreeTransform.h (original)
>>>>> +++ cfe/trunk/lib/Sema/TreeTransform.h Mon May  6 20:20:17 2019
>>>>> @@ -883,6 +883,12 @@ public:
>>>>>      return SemaRef.Context.getTypeDeclType(Typedef);
>>>>>    }
>>>>>
>>>>> +  /// Build a new MacroDefined type.
>>>>> +  QualType RebuildMacroQualifiedType(QualType T,
>>>>> +                                     const IdentifierInfo *MacroII) {
>>>>> +    return SemaRef.Context.getMacroQualifiedType(T, MacroII);
>>>>> +  }
>>>>> +
>>>>>    /// Build a new class/struct/union type.
>>>>>    QualType RebuildRecordType(RecordDecl *Record) {
>>>>>      return SemaRef.Context.getTypeDeclType(Record);
>>>>> @@ -6193,6 +6199,27 @@ TreeTransform<Derived>::TransformParenTy
>>>>>    return Result;
>>>>>  }
>>>>>
>>>>> +template <typename Derived>
>>>>> +QualType
>>>>> +TreeTransform<Derived>::TransformMacroQualifiedType(TypeLocBuilder
>>>>> &TLB,
>>>>> +
>>>>> MacroQualifiedTypeLoc TL) {
>>>>> +  QualType Inner = getDerived().TransformType(TLB, TL.getInnerLoc());
>>>>> +  if (Inner.isNull())
>>>>> +    return QualType();
>>>>> +
>>>>> +  QualType Result = TL.getType();
>>>>> +  if (getDerived().AlwaysRebuild() || Inner !=
>>>>> TL.getInnerLoc().getType()) {
>>>>> +    Result =
>>>>> +        getDerived().RebuildMacroQualifiedType(Inner,
>>>>> TL.getMacroIdentifier());
>>>>> +    if (Result.isNull())
>>>>> +      return QualType();
>>>>> +  }
>>>>> +
>>>>> +  MacroQualifiedTypeLoc NewTL =
>>>>> TLB.push<MacroQualifiedTypeLoc>(Result);
>>>>> +  NewTL.setExpansionLoc(TL.getExpansionLoc());
>>>>> +  return Result;
>>>>> +}
>>>>> +
>>>>>  template<typename Derived>
>>>>>  QualType TreeTransform<Derived>::TransformDependentNameType(
>>>>>      TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
>>>>>
>>>>> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
>>>>> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon May  6 20:20:17 2019
>>>>> @@ -6200,6 +6200,16 @@ QualType ASTReader::readTypeRecord(unsig
>>>>>      return Context.getParenType(InnerType);
>>>>>    }
>>>>>
>>>>> +  case TYPE_MACRO_QUALIFIED: {
>>>>> +    if (Record.size() != 2) {
>>>>> +      Error("incorrect encoding of macro defined type");
>>>>> +      return QualType();
>>>>> +    }
>>>>> +    QualType UnderlyingTy = readType(*Loc.F, Record, Idx);
>>>>> +    IdentifierInfo *MacroII = GetIdentifierInfo(*Loc.F, Record, Idx);
>>>>> +    return Context.getMacroQualifiedType(UnderlyingTy, MacroII);
>>>>> +  }
>>>>> +
>>>>>    case TYPE_PACK_EXPANSION: {
>>>>>      if (Record.size() != 2) {
>>>>>        Error("incorrect encoding of pack expansion type");
>>>>> @@ -6521,6 +6531,10 @@ void TypeLocReader::VisitAdjustedTypeLoc
>>>>>    // nothing to do
>>>>>  }
>>>>>
>>>>> +void TypeLocReader::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc
>>>>> TL) {
>>>>> +  TL.setExpansionLoc(ReadSourceLocation());
>>>>> +}
>>>>> +
>>>>>  void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
>>>>>    TL.setCaretLoc(ReadSourceLocation());
>>>>>  }
>>>>>
>>>>> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
>>>>> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon May  6 20:20:17 2019
>>>>> @@ -516,6 +516,12 @@ void ASTTypeWriter::VisitParenType(const
>>>>>    Code = TYPE_PAREN;
>>>>>  }
>>>>>
>>>>> +void ASTTypeWriter::VisitMacroQualifiedType(const MacroQualifiedType
>>>>> *T) {
>>>>> +  Record.AddTypeRef(T->getUnderlyingType());
>>>>> +  Record.AddIdentifierRef(T->getMacroIdentifier());
>>>>> +  Code = TYPE_MACRO_QUALIFIED;
>>>>> +}
>>>>> +
>>>>>  void ASTTypeWriter::VisitElaboratedType(const ElaboratedType *T) {
>>>>>    Record.push_back(T->getKeyword());
>>>>>    Record.AddNestedNameSpecifier(T->getQualifier());
>>>>> @@ -802,6 +808,10 @@ void TypeLocWriter::VisitParenTypeLoc(Pa
>>>>>    Record.AddSourceLocation(TL.getRParenLoc());
>>>>>  }
>>>>>
>>>>> +void TypeLocWriter::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc
>>>>> TL) {
>>>>> +  Record.AddSourceLocation(TL.getExpansionLoc());
>>>>> +}
>>>>> +
>>>>>  void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
>>>>>    Record.AddSourceLocation(TL.getElaboratedKeywordLoc());
>>>>>    Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
>>>>> @@ -1219,6 +1229,7 @@ void ASTWriter::WriteBlockInfoBlock() {
>>>>>    RECORD(TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION);
>>>>>    RECORD(TYPE_DEPENDENT_SIZED_ARRAY);
>>>>>    RECORD(TYPE_PAREN);
>>>>> +  RECORD(TYPE_MACRO_QUALIFIED);
>>>>>    RECORD(TYPE_PACK_EXPANSION);
>>>>>    RECORD(TYPE_ATTRIBUTED);
>>>>>    RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK);
>>>>>
>>>>> Added: cfe/trunk/test/Frontend/macro_defined_type.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/macro_defined_type.cpp?rev=360109&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/Frontend/macro_defined_type.cpp (added)
>>>>> +++ cfe/trunk/test/Frontend/macro_defined_type.cpp Mon May  6 20:20:17
>>>>> 2019
>>>>> @@ -0,0 +1,15 @@
>>>>> +// RUN: %clang_cc1 -fsyntax-only -verify %s
>>>>> +
>>>>> +#define NODEREF __attribute__((noderef))
>>>>> +
>>>>> +void Func() {
>>>>> +  int NODEREF i; // expected-warning{{'noderef' can only be used on
>>>>> an array or pointer type}}
>>>>> +  int NODEREF *i_ptr;
>>>>> +
>>>>> +  // There should be no difference whether a macro defined type is
>>>>> used or not.
>>>>> +  auto __attribute__((noderef)) *auto_i_ptr = i_ptr;
>>>>> +  auto __attribute__((noderef)) auto_i = i; //
>>>>> expected-warning{{'noderef' can only be used on an array or pointer type}}
>>>>> +
>>>>> +  auto NODEREF *auto_i_ptr2 = i_ptr;
>>>>> +  auto NODEREF auto_i2 = i; // expected-warning{{'noderef' can only
>>>>> be used on an array or pointer type}}
>>>>> +}
>>>>>
>>>>> Added: cfe/trunk/test/Sema/address_space_print_macro.c
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/address_space_print_macro.c?rev=360109&view=auto
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/Sema/address_space_print_macro.c (added)
>>>>> +++ cfe/trunk/test/Sema/address_space_print_macro.c Mon May  6
>>>>> 20:20:17 2019
>>>>> @@ -0,0 +1,67 @@
>>>>> +// RUN: %clang_cc1 %s -fsyntax-only -verify
>>>>> +
>>>>> +#define AS1 __attribute__((address_space(1)))
>>>>> +#define AS2 __attribute__((address_space(2), annotate("foo")))
>>>>> +#define AS_ND __attribute__((address_space(2), noderef))
>>>>> +
>>>>> +#define AS(i) address_space(i)
>>>>> +#define AS3 __attribute__((AS(3)))
>>>>> +#define AS5 __attribute__((address_space(5))) char
>>>>> +
>>>>> +void normal_case() {
>>>>> +  int *p = 0;
>>>>> +  __attribute__((address_space(1))) int *q = p; //
>>>>> expected-error{{initializing '__attribute__((address_space(1))) int *' with
>>>>> an expression of type 'int *' changes address space of pointer}}
>>>>> +}
>>>>> +
>>>>> +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;
>>>>> +  AS5 *x3;
>>>>> +  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
>>>>> '__attribute__((address_space(5))) char *' to 'char *' changes address
>>>>> space of pointer}}
>>>>> +}
>>>>> +
>>>>> +void multiple_attrs(AS_ND int *x) {
>>>>> +  __attribute__((address_space(2))) int *y = x; //
>>>>> expected-warning{{casting to dereferenceable pointer removes 'noderef'
>>>>> attribute}}
>>>>> +}
>>>>> +
>>>>> +void override_macro_name() {
>>>>> +#define ATTRS __attribute__((noderef)) // expected-note{{previous
>>>>> definition is here}}
>>>>> +  ATTRS
>>>>> +#define ATTRS __attribute__((address_space(1))) //
>>>>> expected-warning{{'ATTRS' macro redefined}}
>>>>> +  ATTRS
>>>>> +  int *x;
>>>>> +
>>>>> +  int AS_ND *y = x; // expected-error{{initializing 'AS_ND int *'
>>>>> with an expression of type 'ATTRS int *' changes address space of pointer}}
>>>>> +}
>>>>> +
>>>>> +void partial_macro_declaration() {
>>>>> +#define ATTRS2 __attribute__((noderef))
>>>>> +  ATTRS2 __attribute__((address_space(1))) int *x;
>>>>> +
>>>>> +  int AS_ND *y = x; // expected-error{{initializing 'AS_ND int *'
>>>>> with an expression of type 'ATTRS2 int __attribute__((address_space(1))) *'
>>>>> changes address space of pointer}}
>>>>> +
>>>>> +  // The attribute not wrapped with a macro should be printed
>>>>> regularly.
>>>>> +#define ATTRS3 __attribute__((address_space(1)))
>>>>> +  ATTRS3 __attribute__((noderef)) int *x2;
>>>>> +
>>>>> +  int AS_ND *y2 = x2; // expected-error{{initializing 'AS_ND int *'
>>>>> with an expression of type 'ATTRS3 int * __attribute__((noderef))' changes
>>>>> address space of pointer}}
>>>>> +}
>>>>>
>>>>> Modified: cfe/trunk/test/Sema/address_spaces.c
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/address_spaces.c?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/Sema/address_spaces.c (original)
>>>>> +++ cfe/trunk/test/Sema/address_spaces.c Mon May  6 20:20:17 2019
>>>>> @@ -71,7 +71,7 @@ __attribute__((address_space("12"))) int
>>>>>
>>>>>  // 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}}
>>>>>  }
>>>>>
>>>>>  struct SomeStruct {
>>>>>
>>>>> Modified: cfe/trunk/test/SemaObjC/externally-retained.m
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/externally-retained.m?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/SemaObjC/externally-retained.m (original)
>>>>> +++ cfe/trunk/test/SemaObjC/externally-retained.m Mon May  6 20:20:17
>>>>> 2019
>>>>> @@ -68,6 +68,12 @@ void (^blk)(ObjCTy *, ObjCTy *) =
>>>>>    second = 0; // expected-error{{variable declared with
>>>>> 'objc_externally_retained' cannot be modified in ARC}}
>>>>>  };
>>>>>
>>>>> +void (^blk2)(ObjCTy *, ObjCTy *) =
>>>>> +    ^(__strong ObjCTy *first, ObjCTy *second)
>>>>> __attribute__((objc_externally_retained)) {
>>>>> +  first = 0;
>>>>> +  second = 0; // expected-error{{variable declared with
>>>>> 'objc_externally_retained' cannot be modified in ARC}}
>>>>> +};
>>>>> +
>>>>>  void test8(EXT_RET ObjCTy *x) {} //
>>>>> expected-warning{{'objc_externally_retained' attribute only applies to
>>>>> variables}}
>>>>>
>>>>>  #pragma clang attribute
>>>>> ext_ret.push(__attribute__((objc_externally_retained)),
>>>>> apply_to=any(function, block, objc_method))
>>>>>
>>>>> Modified: cfe/trunk/test/SemaObjC/gc-attributes.m
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/gc-attributes.m?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/SemaObjC/gc-attributes.m (original)
>>>>> +++ cfe/trunk/test/SemaObjC/gc-attributes.m Mon May  6 20:20:17 2019
>>>>> @@ -9,7 +9,7 @@ void test_f0() {
>>>>>    A *a;
>>>>>    static __weak A *a2;
>>>>>    f0(&a);
>>>>> -  f0(&a2); // expected-warning{{passing 'A *__weak *' to parameter of
>>>>> type 'A *__strong *' discards qualifiers}}
>>>>> +  f0(&a2); // expected-warning{{passing 'A *__weak *' to parameter of
>>>>> type 'A *__strong *' discards qualifiers}}
>>>>>  }
>>>>>
>>>>>  void f1(__weak A**); // expected-note{{passing argument to parameter
>>>>> here}}
>>>>> @@ -18,7 +18,7 @@ void test_f1() {
>>>>>    A *a;
>>>>>    __strong A *a2;
>>>>>    f1(&a);
>>>>> -  f1(&a2); // expected-warning{{passing 'A *__strong *' to parameter
>>>>> of type 'A *__weak *' discards qualifiers}}
>>>>> +  f1(&a2); // expected-warning{{passing 'A *__strong *' to parameter
>>>>> of type 'A *__weak *' discards qualifiers}}
>>>>>  }
>>>>>
>>>>>  // These qualifiers should silently expand to nothing in GC mode.
>>>>>
>>>>> Modified: cfe/trunk/test/SemaObjC/mrc-weak.m
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/mrc-weak.m?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/SemaObjC/mrc-weak.m (original)
>>>>> +++ cfe/trunk/test/SemaObjC/mrc-weak.m Mon May  6 20:20:17 2019
>>>>> @@ -62,6 +62,6 @@ void test_unsafe_unretained_cast(id *val
>>>>>
>>>>>  void test_cast_qualifier_inference(__weak id *value) {
>>>>>    __weak id *a = (id*) value;
>>>>> -  __unsafe_unretained id *b = (id*) value; // expected-error
>>>>> {{initializing 'id *' with an expression of type '__weak id *' changes
>>>>> retain/release properties of pointer}}
>>>>> +  __unsafe_unretained id *b = (id *)value; // expected-error
>>>>> {{initializing '__unsafe_unretained id *' with an expression of type
>>>>> '__weak id *' changes retain/release properties of pointer}}
>>>>>  }
>>>>>
>>>>>
>>>>> Modified: cfe/trunk/test/SemaObjCXX/gc-attributes.mm
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/gc-attributes.mm?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/test/SemaObjCXX/gc-attributes.mm (original)
>>>>> +++ cfe/trunk/test/SemaObjCXX/gc-attributes.mm Mon May  6 20:20:17
>>>>> 2019
>>>>> @@ -3,7 +3,7 @@
>>>>>  @interface A
>>>>>  @end
>>>>>
>>>>> -void f0(__strong A**); // expected-note{{candidate function not
>>>>> viable: 1st argument ('A *__weak *') has __weak ownership, but parameter
>>>>> has __strong ownership}}
>>>>> +void f0(__strong A **); // expected-note{{candidate function not
>>>>> viable: 1st argument ('A *__weak *') has __weak ownership, but parameter
>>>>> has __strong ownership}}
>>>>>
>>>>>  void test_f0() {
>>>>>    A *a;
>>>>> @@ -12,7 +12,7 @@ void test_f0() {
>>>>>    f0(&a2); // expected-error{{no matching function}}
>>>>>  }
>>>>>
>>>>> -void f1(__weak A**); // expected-note{{candidate function not viable:
>>>>> 1st argument ('A *__strong *') has __strong ownership, but parameter has
>>>>> __weak ownership}}
>>>>> +void f1(__weak A **); // expected-note{{candidate function not
>>>>> viable: 1st argument ('A *__strong *') has __strong ownership, but
>>>>> parameter has __weak ownership}}
>>>>>
>>>>>  void test_f1() {
>>>>>    A *a;
>>>>>
>>>>> Modified: cfe/trunk/tools/libclang/CIndex.cpp
>>>>> URL:
>>>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=360109&r1=360108&r2=360109&view=diff
>>>>>
>>>>> ==============================================================================
>>>>> --- cfe/trunk/tools/libclang/CIndex.cpp (original)
>>>>> +++ cfe/trunk/tools/libclang/CIndex.cpp Mon May  6 20:20:17 2019
>>>>> @@ -1614,6 +1614,10 @@ bool CursorVisitor::VisitParenTypeLoc(Pa
>>>>>    return Visit(TL.getInnerLoc());
>>>>>  }
>>>>>
>>>>> +bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc
>>>>> TL) {
>>>>> +  return Visit(TL.getInnerLoc());
>>>>> +}
>>>>> +
>>>>>  bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
>>>>>    return Visit(TL.getPointeeLoc());
>>>>>  }
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> cfe-commits mailing list
>>>>> cfe-commits at lists.llvm.org
>>>>> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>>>
>>>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20190507/094d15ca/attachment-0001.html>


More information about the cfe-commits mailing list