Meinersbur created this revision.
Herald added subscribers: cfe-commits, eraman.

Attempt to solve the the diagnostic marker order ('note: previous declaration 
here' pointing to a source location before the main error marker) from 
https://reviews.llvm.org/D48100.

The approach is to pass a `IsInherited` parameters. If false, the order if the 
diagnostic marker is reversed.

The actual reversal is only implemented for two diagnoses: 
`diag::err_mismatched_visibility` and 
`diag::err_ownership_returns_index_mismatch`. Test cases not adapted.


Repository:
  rC Clang

https://reviews.llvm.org/D50216

Files:
  include/clang/Sema/Sema.h
  lib/Parse/ParseCXXInlineMethods.cpp
  lib/Parse/ParseDeclCXX.cpp
  lib/Parse/ParseStmt.cpp
  lib/Sema/SemaAttr.cpp
  lib/Sema/SemaDecl.cpp
  lib/Sema/SemaDeclAttr.cpp
  lib/Sema/SemaDeclCXX.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaLambda.cpp
  lib/Sema/SemaObjCProperty.cpp
  lib/Sema/SemaTemplate.cpp

Index: lib/Sema/SemaTemplate.cpp
===================================================================
--- lib/Sema/SemaTemplate.cpp
+++ lib/Sema/SemaTemplate.cpp
@@ -1609,7 +1609,7 @@
   if (TUK == TUK_Definition)
     NewClass->startDefinition();
 
-  ProcessDeclAttributeList(S, NewClass, Attr);
+  ProcessDeclAttributeList(S, NewClass, Attr, true, false);
 
   if (PrevClassTemplate)
     mergeDeclAttributes(NewClass, PrevClassTemplate->getTemplatedDecl());
@@ -7711,7 +7711,7 @@
     }
   }
 
-  ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessDeclAttributeList(S, Specialization, Attr, true, false);
 
   // Add alignment attributes if necessary; these attributes are checked when
   // the ASTContext lays out the structure.
@@ -8763,7 +8763,7 @@
   Specialization->setBraceRange(SourceRange());
 
   bool PreviouslyDLLExported = Specialization->hasAttr<DLLExportAttr>();
-  ProcessDeclAttributeList(S, Specialization, Attr);
+  ProcessDeclAttributeList(S, Specialization, Attr, true, false);
 
   // Add the explicit instantiation into its lexical context. However,
   // since explicit instantiations are never found by name lookup, we
@@ -9167,7 +9167,8 @@
       Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
       if (PrevTemplate) {
         // Merge attributes.
-        ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes());
+        ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes(), true,
+                                 false);
       }
       if (TSK == TSK_ExplicitInstantiationDefinition)
         InstantiateVariableDefinition(D.getIdentifierLoc(), Prev);
@@ -9329,7 +9330,8 @@
       return (Decl*) nullptr;
   }
 
-  ProcessDeclAttributeList(S, Specialization, D.getDeclSpec().getAttributes());
+  ProcessDeclAttributeList(S, Specialization, D.getDeclSpec().getAttributes(),
+                           true, false);
 
   // In MSVC mode, dllimported explicit instantiation definitions are treated as
   // instantiation declarations.
Index: lib/Sema/SemaObjCProperty.cpp
===================================================================
--- lib/Sema/SemaObjCProperty.cpp
+++ lib/Sema/SemaObjCProperty.cpp
@@ -644,7 +644,7 @@
     PDecl->setInvalidDecl();
   }
 
-  ProcessDeclAttributes(S, PDecl, FD.D);
+  ProcessDeclAttributes(S, PDecl, FD.D, false);
 
   // Regardless of setter/getter attribute, we save the default getter/setter
   // selector names in anticipation of declaration of setter/getter methods.
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -919,7 +919,7 @@
     Method->addAttr(A);
 
   // Attributes on the lambda apply to the method.
-  ProcessDeclAttributes(CurScope, Method, ParamInfo);
+  ProcessDeclAttributes(CurScope, Method, ParamInfo, false);
 
   // CUDA lambdas get implicit attributes based on the scope in which they're
   // declared.
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -13381,7 +13381,7 @@
   }
 
   // Finally we can process decl attributes.
-  ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo);
+  ProcessDeclAttributes(CurScope, CurBlock->TheDecl, ParamInfo, false);
 
   // Put the parameter variables in scope.
   for (auto AI : CurBlock->TheDecl->parameters()) {
Index: lib/Sema/SemaDeclObjC.cpp
===================================================================
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -1059,7 +1059,7 @@
     }
   }
 
-  ProcessDeclAttributeList(TUScope, IDecl, AttrList);
+  ProcessDeclAttributeList(TUScope, IDecl, AttrList, true, false);
   AddPragmaAttributes(TUScope, IDecl);
   PushOnScopeChains(IDecl, TUScope);
 
@@ -1246,7 +1246,7 @@
     PDecl->startDefinition();
   }
 
-  ProcessDeclAttributeList(TUScope, PDecl, AttrList);
+  ProcessDeclAttributeList(TUScope, PDecl, AttrList, true, false);
   AddPragmaAttributes(TUScope, PDecl);
 
   // Merge attributes from previous declarations.
@@ -1774,7 +1774,7 @@
     PushOnScopeChains(PDecl, TUScope);
     CheckObjCDeclScope(PDecl);
 
-    ProcessDeclAttributeList(TUScope, PDecl, attrList);
+    ProcessDeclAttributeList(TUScope, PDecl, attrList, true, false);
     AddPragmaAttributes(TUScope, PDecl);
 
     if (PrevDecl)
@@ -1861,7 +1861,7 @@
   // Process the attributes before looking at protocols to ensure that the
   // availability attribute is attached to the category to provide availability
   // checking for protocol uses.
-  ProcessDeclAttributeList(TUScope, CDecl, AttrList);
+  ProcessDeclAttributeList(TUScope, CDecl, AttrList, true, false);
   AddPragmaAttributes(TUScope, CDecl);
 
   if (NumProtoRefs) {
@@ -4603,7 +4603,7 @@
       CvtQTToAstBitMask(ArgInfo[i].DeclSpec.getObjCDeclQualifier()));
 
     // Apply the attributes to the parameter.
-    ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs);
+    ProcessDeclAttributeList(TUScope, Param, ArgInfo[i].ArgAttrs, true, false);
     AddPragmaAttributes(TUScope, Param);
 
     if (Param->hasAttr<BlocksAttr>()) {
@@ -4633,7 +4633,7 @@
   ObjCMethod->setObjCDeclQualifier(
     CvtQTToAstBitMask(ReturnQT.getObjCDeclQualifier()));
 
-  ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList);
+  ProcessDeclAttributeList(TUScope, ObjCMethod, AttrList, true, false);
   AddPragmaAttributes(TUScope, ObjCMethod);
 
   // Add the method now.
@@ -4924,7 +4924,7 @@
   if (D.getIdentifier())
     IdResolver.AddDecl(New);
 
-  ProcessDeclAttributes(S, New, D);
+  ProcessDeclAttributes(S, New, D, false);
 
   if (New->hasAttr<BlocksAttr>())
     Diag(New->getLocation(), diag::err_block_on_nonlocal);
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -2706,7 +2706,7 @@
   AccessSpecDecl *ASDecl = AccessSpecDecl::Create(Context, Access, CurContext,
                                                   ASLoc, ColonLoc);
   CurContext->addHiddenDecl(ASDecl);
-  return ProcessAccessDeclAttributeList(ASDecl, Attrs);
+  return ProcessAccessDeclAttributeList(ASDecl, Attrs, false);
 }
 
 /// CheckOverrideControl - Check C++11 override control semantics.
@@ -8804,7 +8804,7 @@
   if (IsInvalid)
     Namespc->setInvalidDecl();
 
-  ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
+  ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList, true, false);
   AddPragmaAttributes(DeclRegionScope, Namespc);
 
   // FIXME: Should we be merging attributes?
@@ -9322,7 +9322,7 @@
   }
 
   if (UDir)
-    ProcessDeclAttributeList(S, UDir, AttrList);
+    ProcessDeclAttributeList(S, UDir, AttrList, true, false);
 
   return UDir;
 }
@@ -10425,7 +10425,7 @@
   if (Invalid)
     NewTD->setInvalidDecl();
 
-  ProcessDeclAttributeList(S, NewTD, AttrList);
+  ProcessDeclAttributeList(S, NewTD, AttrList, true, false);
   AddPragmaAttributes(S, NewTD);
 
   CheckTypedefForVariablyModifiedType(S, NewTD);
@@ -13539,7 +13539,7 @@
   Decl *ED = EmptyDecl::Create(Context, CurContext, SemiLoc);
   // Attribute declarations appertain to empty declaration so we handle
   // them here.
-  ProcessDeclAttributeList(S, ED, AttrList);
+  ProcessDeclAttributeList(S, ED, AttrList, true, false);
 
   CurContext->addDecl(ED);
   return ED;
@@ -13724,7 +13724,7 @@
   else
     CurContext->addDecl(ExDecl);
 
-  ProcessDeclAttributes(S, ExDecl, D);
+  ProcessDeclAttributes(S, ExDecl, D, false);
   return ExDecl;
 }
 
@@ -15443,7 +15443,7 @@
   const ParsedAttr::PropertyData &Data = MSPropertyAttr.getPropertyData();
   MSPropertyDecl *NewPD = MSPropertyDecl::Create(
       Context, Record, Loc, II, T, TInfo, TSSL, Data.GetterId, Data.SetterId);
-  ProcessDeclAttributes(TUScope, NewPD, D);
+  ProcessDeclAttributes(TUScope, NewPD, D, false);
   NewPD->setAccess(AS);
 
   if (NewPD->isInvalidDecl())
Index: lib/Sema/SemaDeclAttr.cpp
===================================================================
--- lib/Sema/SemaDeclAttr.cpp
+++ lib/Sema/SemaDeclAttr.cpp
@@ -1600,7 +1600,8 @@
   return false;
 }
 
-static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+static void handleOwnershipAttr(Sema &S, Decl *D, const ParsedAttr &AL,
+                                bool IsInherited) {
   // This attribute must be applied to a function declaration. The first
   // argument to the attribute must be an identifier, the name of the resource,
   // for example: malloc. The following arguments must be argument indexes, the
@@ -1687,10 +1688,12 @@
         // A returns attribute conflicts with any other returns attribute using
         // a different index.
         if (std::find(I->args_begin(), I->args_end(), Idx) == I->args_end()) {
-          S.Diag(I->getLocation(), diag::err_ownership_returns_index_mismatch)
+          S.Diag(IsInherited ? I->getLocation() : AL.getLoc(),
+                 diag::err_ownership_returns_index_mismatch)
               << I->args_begin()->getSourceIndex();
           if (I->args_size())
-            S.Diag(AL.getLoc(), diag::note_ownership_returns_index_mismatch)
+            S.Diag(IsInherited ? AL.getLoc() : I->getLocation(),
+                   diag::note_ownership_returns_index_mismatch)
                 << Idx.getSourceIndex() << Ex->getSourceRange();
           return;
         }
@@ -2475,35 +2478,41 @@
 template <class T>
 static T *mergeVisibilityAttr(Sema &S, Decl *D, SourceRange range,
                               typename T::VisibilityType value,
-                              unsigned attrSpellingListIndex) {
+                              unsigned attrSpellingListIndex,
+                              bool IsInherited) {
   T *existingAttr = D->getAttr<T>();
   if (existingAttr) {
     typename T::VisibilityType existingValue = existingAttr->getVisibility();
     if (existingValue == value)
       return nullptr;
-    S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
-    S.Diag(range.getBegin(), diag::note_previous_attribute);
+    S.Diag(IsInherited ? existingAttr->getLocation() : range.getBegin(),
+           diag::err_mismatched_visibility);
+    S.Diag(IsInherited ? range.getBegin() : existingAttr->getLocation(),
+           diag::note_previous_attribute);
+    // S.Diag(existingAttr->getLocation(), diag::err_mismatched_visibility);
+    // S.Diag(range.getBegin(), diag::note_previous_attribute);
     D->dropAttr<T>();
   }
   return ::new (S.Context) T(range, S.Context, value, attrSpellingListIndex);
 }
 
 VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
                                           VisibilityAttr::VisibilityType Vis,
-                                          unsigned AttrSpellingListIndex) {
-  return ::mergeVisibilityAttr<VisibilityAttr>(*this, D, Range, Vis,
-                                               AttrSpellingListIndex);
+                                          unsigned AttrSpellingListIndex,
+                                          bool IsInherited) {
+  return ::mergeVisibilityAttr<VisibilityAttr>(
+      *this, D, Range, Vis, AttrSpellingListIndex, IsInherited);
 }
 
-TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
-                                      TypeVisibilityAttr::VisibilityType Vis,
-                                      unsigned AttrSpellingListIndex) {
-  return ::mergeVisibilityAttr<TypeVisibilityAttr>(*this, D, Range, Vis,
-                                                   AttrSpellingListIndex);
+TypeVisibilityAttr *Sema::mergeTypeVisibilityAttr(
+    Decl *D, SourceRange Range, TypeVisibilityAttr::VisibilityType Vis,
+    unsigned AttrSpellingListIndex, bool IsInherited) {
+  return ::mergeVisibilityAttr<TypeVisibilityAttr>(
+      *this, D, Range, Vis, AttrSpellingListIndex, IsInherited);
 }
 
 static void handleVisibilityAttr(Sema &S, Decl *D, const ParsedAttr &AL,
-                                 bool isTypeVisibility) {
+                                 bool isTypeVisibility, bool IsInherited) {
   // Visibility attributes don't mean anything on a typedef.
   if (isa<TypedefNameDecl>(D)) {
     S.Diag(AL.getRange().getBegin(), diag::warn_attribute_ignored)
@@ -2545,11 +2554,11 @@
   unsigned Index = AL.getAttributeSpellingListIndex();
   Attr *newAttr;
   if (isTypeVisibility) {
-    newAttr = S.mergeTypeVisibilityAttr(D, AL.getRange(),
-                                    (TypeVisibilityAttr::VisibilityType) type,
-                                        Index);
+    newAttr = S.mergeTypeVisibilityAttr(
+        D, AL.getRange(), (TypeVisibilityAttr::VisibilityType)type, Index,
+        IsInherited);
   } else {
-    newAttr = S.mergeVisibilityAttr(D, AL.getRange(), type, Index);
+    newAttr = S.mergeVisibilityAttr(D, AL.getRange(), type, Index, IsInherited);
   }
   if (newAttr)
     D->addAttr(newAttr);
@@ -5948,7 +5957,8 @@
 /// silently ignore it if a GNU attribute.
 static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
                                  const ParsedAttr &AL,
-                                 bool IncludeCXX11Attributes) {
+                                 bool IncludeCXX11Attributes,
+                                 bool IsInherited) {
   if (AL.isInvalid() || AL.getKind() == ParsedAttr::IgnoredAttribute)
     return;
 
@@ -6190,7 +6200,7 @@
     handleSimpleAttribute<OverloadableAttr>(S, D, AL);
     break;
   case ParsedAttr::AT_Ownership:
-    handleOwnershipAttr(S, D, AL);
+    handleOwnershipAttr(S, D, AL, IsInherited);
     break;
   case ParsedAttr::AT_Cold:
     handleSimpleAttributeWithExclusions<ColdAttr, HotAttr>(S, D, AL);
@@ -6340,10 +6350,10 @@
     handleSimpleAttribute<UsedAttr>(S, D, AL);
     break;
   case ParsedAttr::AT_Visibility:
-    handleVisibilityAttr(S, D, AL, false);
+    handleVisibilityAttr(S, D, AL, false, IsInherited);
     break;
   case ParsedAttr::AT_TypeVisibility:
-    handleVisibilityAttr(S, D, AL, true);
+    handleVisibilityAttr(S, D, AL, true, IsInherited);
     break;
   case ParsedAttr::AT_WarnUnused:
     handleSimpleAttribute<WarnUnusedAttr>(S, D, AL);
@@ -6611,12 +6621,13 @@
 /// attribute list to the specified decl, ignoring any type attributes.
 void Sema::ProcessDeclAttributeList(Scope *S, Decl *D,
                                     const ParsedAttributesView &AttrList,
-                                    bool IncludeCXX11Attributes) {
+                                    bool IncludeCXX11Attributes,
+                                    bool IsInherited) {
   if (AttrList.empty())
     return;
 
   for (const ParsedAttr &AL : AttrList)
-    ProcessDeclAttribute(*this, S, D, AL, IncludeCXX11Attributes);
+    ProcessDeclAttribute(*this, S, D, AL, IncludeCXX11Attributes, IsInherited);
 
   // FIXME: We should be able to handle these cases in TableGen.
   // GCC accepts
@@ -6683,11 +6694,13 @@
 
 // Annotation attributes are the only attributes allowed after an access
 // specifier.
-bool Sema::ProcessAccessDeclAttributeList(
-    AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList) {
+bool Sema::ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
+                                          const ParsedAttributesView &AttrList,
+                                          bool IsInherited) {
   for (const ParsedAttr &AL : AttrList) {
     if (AL.getKind() == ParsedAttr::AT_Annotate) {
-      ProcessDeclAttribute(*this, nullptr, ASDecl, AL, AL.isCXX11Attribute());
+      ProcessDeclAttribute(*this, nullptr, ASDecl, AL, AL.isCXX11Attribute(),
+                           IsInherited);
     } else {
       Diag(AL.getLoc(), diag::err_only_annotate_after_access_spec);
       return true;
@@ -6825,21 +6838,23 @@
 /// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in
 /// it, apply them to D.  This is a bit tricky because PD can have attributes
 /// specified in many different places, and we need to find and apply them all.
-void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD) {
+void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
+                                 bool IsInherited) {
   // Apply decl attributes from the DeclSpec if present.
   if (!PD.getDeclSpec().getAttributes().empty())
-    ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes());
+    ProcessDeclAttributeList(S, D, PD.getDeclSpec().getAttributes(),
+                             IsInherited, false);
 
   // Walk the declarator structure, applying decl attributes that were in a type
   // position to the decl itself.  This handles cases like:
   //   int *__attr__(x)** D;
   // when X is a decl attribute.
   for (unsigned i = 0, e = PD.getNumTypeObjects(); i != e; ++i)
     ProcessDeclAttributeList(S, D, PD.getTypeObject(i).getAttrs(),
-                             /*IncludeCXX11Attributes=*/false);
+                             /*IncludeCXX11Attributes=*/false, IsInherited);
 
   // Finally, apply any attributes on the decl itself.
-  ProcessDeclAttributeList(S, D, PD.getAttributes());
+  ProcessDeclAttributeList(S, D, PD.getAttributes(), true, IsInherited);
 
   // Apply additional attributes specified by '#pragma clang attribute'.
   AddPragmaAttributes(S, D);
Index: lib/Sema/SemaDecl.cpp
===================================================================
--- lib/Sema/SemaDecl.cpp
+++ lib/Sema/SemaDecl.cpp
@@ -2415,7 +2415,8 @@
 
 static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
                                const InheritableAttr *Attr,
-                               Sema::AvailabilityMergeKind AMK) {
+                               Sema::AvailabilityMergeKind AMK,
+                               bool IsInherited) {
   // This function copies an attribute Attr from a previous declaration to the
   // new declaration D if the new declaration doesn't itself have that attribute
   // yet or if that attribute allows duplicates.
@@ -2435,10 +2436,10 @@
                                       AttrSpellingListIndex);
   else if (const auto *VA = dyn_cast<VisibilityAttr>(Attr))
     NewAttr = S.mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
-                                    AttrSpellingListIndex);
+                                    AttrSpellingListIndex, IsInherited);
   else if (const auto *VA = dyn_cast<TypeVisibilityAttr>(Attr))
     NewAttr = S.mergeTypeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
-                                        AttrSpellingListIndex);
+                                        AttrSpellingListIndex, IsInherited);
   else if (const auto *ImportA = dyn_cast<DLLImportAttr>(Attr))
     NewAttr = S.mergeDLLImportAttr(D, ImportA->getRange(),
                                    AttrSpellingListIndex);
@@ -2713,7 +2714,7 @@
     if (isa<UsedAttr>(I))
       continue;
 
-    if (mergeDeclAttribute(*this, New, I, LocalAMK))
+    if (mergeDeclAttribute(*this, New, I, LocalAMK, true))
       foundAny = true;
   }
 
@@ -5752,7 +5753,7 @@
   if (!NewTD) return nullptr;
 
   // Handle attributes prior to checking for duplicates in MergeVarDecl
-  ProcessDeclAttributes(S, NewTD, D);
+  ProcessDeclAttributes(S, NewTD, D, false);
 
   CheckTypedefForVariablyModifiedType(S, NewTD);
 
@@ -6732,7 +6733,7 @@
   }
 
   // Handle attributes prior to checking for duplicates in MergeVarDecl
-  ProcessDeclAttributes(S, NewVD, D);
+  ProcessDeclAttributes(S, NewVD, D, false);
 
   if (getLangOpts().CUDA || getLangOpts().OpenMPIsDevice) {
     if (EmitTLSUnsupportedError &&
@@ -8832,7 +8833,7 @@
   }
 
   // Handle attributes.
-  ProcessDeclAttributes(S, NewFD, D);
+  ProcessDeclAttributes(S, NewFD, D, false);
 
   if (getLangOpts().OpenCL) {
     // OpenCL v1.1 s6.5: Using an address space qualifier in a function return
@@ -12394,7 +12395,7 @@
   if (II)
     IdResolver.AddDecl(New);
 
-  ProcessDeclAttributes(S, New, D);
+  ProcessDeclAttributes(S, New, D, false);
 
   if (D.getDeclSpec().isModulePrivateSpecified())
     Diag(New->getLocation(), diag::err_module_private_local)
@@ -13304,7 +13305,7 @@
   // Always attach attributes to the underlying decl.
   if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))
     D = TD->getTemplatedDecl();
-  ProcessDeclAttributeList(S, D, Attrs);
+  ProcessDeclAttributeList(S, D, Attrs, true, false);
 
   if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(D))
     if (Method->isStatic())
@@ -14761,7 +14762,7 @@
   if (TUK == TUK_Definition)
     New->startDefinition();
 
-  ProcessDeclAttributeList(S, New, Attrs);
+  ProcessDeclAttributeList(S, New, Attrs, true, false);
   AddPragmaAttributes(S, New);
 
   // If this has an identifier, add it to the scope stack.
@@ -15337,7 +15338,7 @@
   // representation, not a parser representation.
   if (D) {
     // FIXME: The current scope is almost... but not entirely... correct here.
-    ProcessDeclAttributes(getCurScope(), NewFD, *D);
+    ProcessDeclAttributes(getCurScope(), NewFD, *D, false);
 
     if (NewFD->hasAttrs())
       CheckAlignasUnderalignment(NewFD);
@@ -15514,7 +15515,7 @@
   }
 
   // Process attributes attached to the ivar.
-  ProcessDeclAttributes(S, NewID, D);
+  ProcessDeclAttributes(S, NewID, D, false);
 
   if (D.isInvalidType())
     NewID->setInvalidDecl();
@@ -15899,7 +15900,7 @@
       Record->completeDefinition();
 
     // Handle attributes before checking the layout.
-    ProcessDeclAttributeList(S, Record, Attrs);
+    ProcessDeclAttributeList(S, Record, Attrs, true, false);
 
     // We may have deferred checking for a deleted destructor. Check now.
     if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) {
@@ -16328,7 +16329,7 @@
   }
 
   // Process attributes.
-  ProcessDeclAttributeList(S, New, Attrs);
+  ProcessDeclAttributeList(S, New, Attrs, true, false);
   AddPragmaAttributes(S, New);
 
   // Register this decl in the current scope stack.
@@ -16525,7 +16526,7 @@
   EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
   QualType EnumType = Context.getTypeDeclType(Enum);
 
-  ProcessDeclAttributeList(S, Enum, Attrs);
+  ProcessDeclAttributeList(S, Enum, Attrs, true, false);
 
   if (Enum->isDependentType()) {
     for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
Index: lib/Sema/SemaAttr.cpp
===================================================================
--- lib/Sema/SemaAttr.cpp
+++ lib/Sema/SemaAttr.cpp
@@ -662,7 +662,7 @@
     PragmaAttributeCurrentTargetDecl = D;
     ParsedAttributesView Attrs;
     Attrs.addAtEnd(Attribute);
-    ProcessDeclAttributeList(S, D, Attrs);
+    ProcessDeclAttributeList(S, D, Attrs, true, false);
     PragmaAttributeCurrentTargetDecl = nullptr;
   }
 }
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp
+++ lib/Parse/ParseStmt.cpp
@@ -627,7 +627,7 @@
 
   LabelDecl *LD = Actions.LookupOrCreateLabel(IdentTok.getIdentifierInfo(),
                                               IdentTok.getLocation());
-  Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs);
+  Actions.ProcessDeclAttributeList(Actions.CurScope, LD, attrs, true, false);
   attrs.clear();
 
   return Actions.ActOnLabelStmt(IdentTok.getLocation(), LD, ColonLoc,
Index: lib/Parse/ParseDeclCXX.cpp
===================================================================
--- lib/Parse/ParseDeclCXX.cpp
+++ lib/Parse/ParseDeclCXX.cpp
@@ -2761,7 +2761,8 @@
         ThisDecl = VT->getTemplatedDecl();
 
       if (ThisDecl)
-        Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs);
+        Actions.ProcessDeclAttributeList(getCurScope(), ThisDecl, AccessAttrs,
+                                         true, false);
     }
 
     // Error recovery might have converted a non-static member into a static
Index: lib/Parse/ParseCXXInlineMethods.cpp
===================================================================
--- lib/Parse/ParseCXXInlineMethods.cpp
+++ lib/Parse/ParseCXXInlineMethods.cpp
@@ -44,7 +44,8 @@
                                            TemplateParams, nullptr,
                                            VS, ICIS_NoInit);
     if (FnD) {
-      Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs);
+      Actions.ProcessDeclAttributeList(getCurScope(), FnD, AccessAttrs, true,
+                                       false);
       if (PureSpecLoc.isValid())
         Actions.ActOnPureSpecifier(FnD, PureSpecLoc);
     }
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -2426,12 +2426,14 @@
                                           bool IsStrict, StringRef Replacement,
                                           AvailabilityMergeKind AMK,
                                           unsigned AttrSpellingListIndex);
-  TypeVisibilityAttr *mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
-                                       TypeVisibilityAttr::VisibilityType Vis,
-                                              unsigned AttrSpellingListIndex);
+  TypeVisibilityAttr *
+  mergeTypeVisibilityAttr(Decl *D, SourceRange Range,
+                          TypeVisibilityAttr::VisibilityType Vis,
+                          unsigned AttrSpellingListIndex, bool IsInherited);
   VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range,
                                       VisibilityAttr::VisibilityType Vis,
-                                      unsigned AttrSpellingListIndex);
+                                      unsigned AttrSpellingListIndex,
+                                      bool IsInherited);
   UuidAttr *mergeUuidAttr(Decl *D, SourceRange Range,
                           unsigned AttrSpellingListIndex, StringRef Uuid);
   DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
@@ -3330,14 +3332,18 @@
 
   void ProcessPragmaWeak(Scope *S, Decl *D);
   // Decl attributes - this routine is the top level dispatcher.
-  void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD);
+  void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD,
+                             bool IsInherited);
   // Helper for delayed processing of attributes.
   void ProcessDeclAttributeDelayed(Decl *D,
                                    const ParsedAttributesView &AttrList);
-  void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AL,
-                             bool IncludeCXX11Attributes = true);
+  void ProcessDeclAttributeList(Scope *S, Decl *D,
+                                const ParsedAttributesView &AL,
+                                bool IncludeCXX11Attributes /*=true*/,
+                                bool IsInherited);
   bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl,
-                                   const ParsedAttributesView &AttrList);
+                                      const ParsedAttributesView &AttrList,
+                                      bool IsInherited);
 
   void checkUnusedDeclAttributes(Declarator &D);
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to