[cfe-commits] r173358 - in /cfe/trunk: include/clang/AST/Attr.h include/clang/Sema/AttributeList.h include/clang/Sema/CMakeLists.txt include/clang/Sema/Makefile include/clang/Sema/Sema.h lib/Sema/AttributeList.cpp lib/Sema/CMakeLists.txt lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/TargetAttributesSema.cpp test/Sema/attr-print.c test/SemaCXX/attr-print.cpp test/SemaCXX/cxx11-attr-print.cpp utils/TableGen/ClangAttrEmitter.cpp utils/TableGen/TableGen.cpp utils/TableGen/TableGenBackends.h

Michael Han fragmentshaders at gmail.com
Thu Jan 24 08:46:58 PST 2013


Author: hanm
Date: Thu Jan 24 10:46:58 2013
New Revision: 173358

URL: http://llvm.org/viewvc/llvm-project?rev=173358&view=rev
Log:
PR14922: when printing an attribute, use the real syntax of the attribute (GNU, C++11, MS Declspec) instead of hardcoded GNU syntax.

Introduce a spelling index to Attr class, which is an index into the attribute spelling list of an attribute defined in Attr.td. 
This index will determine the actual spelling used by an attribute, as it incorporates both the syntax and naming of the attribute.
When constructing an attribute AST node, the spelling index is computed based on attribute kind, scope (if it's a C++11 attribute), and
name, then passed to Attr that will use the index to print itself. 

Thanks to Richard Smith for the idea and review.


Added:
    cfe/trunk/test/Sema/attr-print.c
    cfe/trunk/test/SemaCXX/attr-print.cpp
    cfe/trunk/test/SemaCXX/cxx11-attr-print.cpp
Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/Sema/AttributeList.h
    cfe/trunk/include/clang/Sema/CMakeLists.txt
    cfe/trunk/include/clang/Sema/Makefile
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Sema/AttributeList.cpp
    cfe/trunk/lib/Sema/CMakeLists.txt
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/TargetAttributesSema.cpp
    cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
    cfe/trunk/utils/TableGen/TableGen.cpp
    cfe/trunk/utils/TableGen/TableGenBackends.h

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Thu Jan 24 10:46:58 2013
@@ -44,10 +44,14 @@
   unsigned AttrKind : 16;
 
 protected:
+  /// An index into the spelling list of an
+  /// attribute defined in Attr.td file.
+  unsigned SpellingListIndex : 4;
+
   bool Inherited : 1;
 
   virtual ~Attr();
-  
+
   void* operator new(size_t bytes) throw() {
     llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
   }
@@ -67,14 +71,17 @@
   }
 
 protected:
-  Attr(attr::Kind AK, SourceRange R)
-    : Range(R), AttrKind(AK), Inherited(false) {}
+  Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+    : Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
+  Inherited(false) {}
 
 public:
 
   attr::Kind getKind() const {
     return static_cast<attr::Kind>(AttrKind);
   }
+  
+  unsigned getSpellingListIndex() const { return SpellingListIndex; }
 
   SourceLocation getLocation() const { return Range.getBegin(); }
   SourceRange getRange() const { return Range; }
@@ -95,8 +102,8 @@
 class InheritableAttr : public Attr {
   virtual void anchor();
 protected:
-  InheritableAttr(attr::Kind AK, SourceRange R)
-    : Attr(AK, R) {}
+  InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex = 0)
+    : Attr(AK, R, SpellingListIndex) {}
 
 public:
   void setInherited(bool I) { Inherited = I; }
@@ -110,8 +117,9 @@
 class InheritableParamAttr : public InheritableAttr {
   virtual void anchor();
 protected:
-  InheritableParamAttr(attr::Kind AK, SourceRange R)
-    : InheritableAttr(AK, R) {}
+  InheritableParamAttr(attr::Kind AK, SourceRange R,
+                       unsigned SpellingListIndex = 0)
+    : InheritableAttr(AK, R, SpellingListIndex) {}
 
 public:
   // Implement isa/cast/dyncast/etc.

Modified: cfe/trunk/include/clang/Sema/AttributeList.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/AttributeList.h (original)
+++ cfe/trunk/include/clang/Sema/AttributeList.h Thu Jan 24 10:46:58 2013
@@ -340,6 +340,11 @@
            "Not a type_tag_for_datatype attribute");
     return getTypeTagForDatatypeDataSlot().MustBeNull;
   }
+
+  /// \brief Get an index into the attribute spelling list
+  /// defined in Attr.td. This index is used by an attribute
+  /// to pretty print itself.
+  unsigned getAttributeSpellingListIndex() const;
 };
 
 /// A factory, from which one makes pools, from which one creates

Modified: cfe/trunk/include/clang/Sema/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/CMakeLists.txt?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/CMakeLists.txt (original)
+++ cfe/trunk/include/clang/Sema/CMakeLists.txt Thu Jan 24 10:46:58 2013
@@ -11,4 +11,9 @@
 clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds
   -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
   SOURCE ../Basic/Attr.td
-  TARGET ClangAttrParsedAttrKinds)
\ No newline at end of file
+  TARGET ClangAttrParsedAttrKinds)
+
+clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index
+  -I ${CMAKE_CURRENT_SOURCE_DIR}/../../
+  SOURCE ../Basic/Attr.td
+  TARGET ClangAttrSpellingListIndex)

Modified: cfe/trunk/include/clang/Sema/Makefile
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Makefile?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Makefile (original)
+++ cfe/trunk/include/clang/Sema/Makefile Thu Jan 24 10:46:58 2013
@@ -1,6 +1,7 @@
 CLANG_LEVEL := ../../..
 TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
-BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc
+BUILT_SOURCES = AttrTemplateInstantiate.inc AttrParsedAttrList.inc AttrParsedAttrKinds.inc \
+        AttrSpellingListIndex.inc
 
 TABLEGEN_INC_FILES_COMMON = 1
 
@@ -24,4 +25,10 @@
 	$(Verb) $(ClangTableGen) -gen-clang-attr-parsed-attr-kinds -o \
 	  $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
 
+$(ObjDir)/AttrSpellingListIndex.inc.tmp : $(TD_SRC_DIR)/Attr.td \
+                                       $(CLANG_TBLGEN) $(ObjDir)/.dir
+	$(Echo) "Building Clang attribute spelling list index with tablegen"
+	$(Verb) $(ClangTableGen) -gen-clang-attr-spelling-index -o \
+	  $(call SYSPATH, $@) -I $(PROJ_SRC_DIR)/../../ $<
+
 

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Thu Jan 24 10:46:58 2013
@@ -1681,14 +1681,20 @@
                                           VersionTuple Obsoleted,
                                           bool IsUnavailable,
                                           StringRef Message,
-                                          bool Override);
+                                          bool Override,
+                                          unsigned AttrSpellingListIndex);
   VisibilityAttr *mergeVisibilityAttr(Decl *D, SourceRange Range,
-                                      VisibilityAttr::VisibilityType Vis);
-  DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range);
-  DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range);
+                                      VisibilityAttr::VisibilityType Vis,
+                                      unsigned AttrSpellingListIndex);
+  DLLImportAttr *mergeDLLImportAttr(Decl *D, SourceRange Range,
+                                    unsigned AttrSpellingListIndex);
+  DLLExportAttr *mergeDLLExportAttr(Decl *D, SourceRange Range,
+                                    unsigned AttrSpellingListIndex);
   FormatAttr *mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
-                              int FormatIdx, int FirstArg);
-  SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name);
+                              int FormatIdx, int FirstArg,
+                              unsigned AttrSpellingListIndex);
+  SectionAttr *mergeSectionAttr(Decl *D, SourceRange Range, StringRef Name,
+                                unsigned AttrSpellingListIndex);
   bool mergeDeclAttribute(NamedDecl *New, InheritableAttr *Attr,
                           bool Override);
 
@@ -6520,7 +6526,7 @@
 
   /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
   void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
-                      bool isDeclSpec);
+                      bool isDeclSpec, unsigned SpellingListIndex = 0);
   void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
                       bool isDeclSpec);
 

Modified: cfe/trunk/lib/Sema/AttributeList.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/AttributeList.cpp?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/AttributeList.cpp (original)
+++ cfe/trunk/lib/Sema/AttributeList.cpp Thu Jan 24 10:46:58 2013
@@ -125,3 +125,14 @@
 
   return ::getAttrKind(Buf);
 }
+
+unsigned AttributeList::getAttributeSpellingListIndex() const {
+  // Both variables will be used in tablegen generated
+  // attribute spell list index matching code.
+  StringRef Name = AttrName->getName();
+  StringRef Scope = ScopeName ? ScopeName->getName() : "";
+
+#include "clang/Sema/AttrSpellingListIndex.inc"
+
+}
+

Modified: cfe/trunk/lib/Sema/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/CMakeLists.txt?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/CMakeLists.txt (original)
+++ cfe/trunk/lib/Sema/CMakeLists.txt Thu Jan 24 10:46:58 2013
@@ -58,6 +58,7 @@
   ClangAttrList
   ClangAttrParsedAttrList
   ClangAttrParsedAttrKinds
+  ClangAttrSpellingListIndex
   ClangAttrTemplateInstantiate
   ClangCommentNodes
   ClangDeclNodes

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Jan 24 10:46:58 2013
@@ -1825,22 +1825,29 @@
 bool Sema::mergeDeclAttribute(NamedDecl *D, InheritableAttr *Attr,
                               bool Override) {
   InheritableAttr *NewAttr = NULL;
+  unsigned AttrSpellingListIndex = Attr->getSpellingListIndex();
   if (AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attr))
     NewAttr = mergeAvailabilityAttr(D, AA->getRange(), AA->getPlatform(),
                                     AA->getIntroduced(), AA->getDeprecated(),
                                     AA->getObsoleted(), AA->getUnavailable(),
-                                    AA->getMessage(), Override);
+                                    AA->getMessage(), Override,
+                                    AttrSpellingListIndex);
   else if (VisibilityAttr *VA = dyn_cast<VisibilityAttr>(Attr))
-    NewAttr = mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility());
+    NewAttr = mergeVisibilityAttr(D, VA->getRange(), VA->getVisibility(),
+                                  AttrSpellingListIndex);
   else if (DLLImportAttr *ImportA = dyn_cast<DLLImportAttr>(Attr))
-    NewAttr = mergeDLLImportAttr(D, ImportA->getRange());
+    NewAttr = mergeDLLImportAttr(D, ImportA->getRange(),
+                                 AttrSpellingListIndex);
   else if (DLLExportAttr *ExportA = dyn_cast<DLLExportAttr>(Attr))
-    NewAttr = mergeDLLExportAttr(D, ExportA->getRange());
+    NewAttr = mergeDLLExportAttr(D, ExportA->getRange(),
+                                 AttrSpellingListIndex);
   else if (FormatAttr *FA = dyn_cast<FormatAttr>(Attr))
     NewAttr = mergeFormatAttr(D, FA->getRange(), FA->getType(),
-                              FA->getFormatIdx(), FA->getFirstArg());
+                              FA->getFormatIdx(), FA->getFirstArg(),
+                              AttrSpellingListIndex);
   else if (SectionAttr *SA = dyn_cast<SectionAttr>(Attr))
-    NewAttr = mergeSectionAttr(D, SA->getRange(), SA->getName());
+    NewAttr = mergeSectionAttr(D, SA->getRange(), SA->getName(),
+                               AttrSpellingListIndex);
   else if (!DeclHasAttr(D, Attr))
     NewAttr = cast<InheritableAttr>(Attr->clone(Context));
 

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Jan 24 10:46:58 2013
@@ -505,18 +505,22 @@
   if (!checkGuardedVarAttrCommon(S, D, Attr))
     return;
 
-  D->addAttr(::new (S.Context) GuardedVarAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             GuardedVarAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
 }
 
 static void handlePtGuardedVarAttr(Sema &S, Decl *D,
-                           const AttributeList &Attr) {
+                                   const AttributeList &Attr) {
   if (!checkGuardedVarAttrCommon(S, D, Attr))
     return;
 
   if (!threadSafetyCheckIsPointer(S, D, Attr))
     return;
 
-  D->addAttr(::new (S.Context) PtGuardedVarAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             PtGuardedVarAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkGuardedByAttrCommon(Sema &S, Decl *D,
@@ -596,7 +600,9 @@
   if (!checkLockableAttrCommon(S, D, Attr))
     return;
 
-  D->addAttr(::new (S.Context) ScopedLockableAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ScopedLockableAttr(Attr.getRange(), S.Context,
+                                Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNoThreadSafetyAttr(Sema &S, Decl *D,
@@ -629,8 +635,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoAddressSafetyAnalysisAttr(Attr.getRange(),
-                                                           S.Context));
+  D->addAttr(::new (S.Context)
+             NoAddressSafetyAnalysisAttr(Attr.getRange(), S.Context,
+                                         Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkAcquireOrderAttrCommon(Sema &S, Decl *D,
@@ -675,8 +682,10 @@
     return;
 
   Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context) AcquiredAfterAttr(Attr.getRange(), S.Context,
-                                                 StartArg, Args.size()));
+  D->addAttr(::new (S.Context)
+             AcquiredAfterAttr(Attr.getRange(), S.Context,
+                               StartArg, Args.size(),
+                               Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleAcquiredBeforeAttr(Sema &S, Decl *D,
@@ -686,8 +695,10 @@
     return;
 
   Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context) AcquiredBeforeAttr(Attr.getRange(), S.Context,
-                                                  StartArg, Args.size()));
+  D->addAttr(::new (S.Context)
+             AcquiredBeforeAttr(Attr.getRange(), S.Context,
+                                StartArg, Args.size(),
+                                Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkLockFunAttrCommon(Sema &S, Decl *D,
@@ -718,9 +729,9 @@
 
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
-  D->addAttr(::new (S.Context) SharedLockFunctionAttr(Attr.getRange(),
-                                                      S.Context,
-                                                      StartArg, Size));
+  D->addAttr(::new (S.Context)
+             SharedLockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
+                                    Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleExclusiveLockFunctionAttr(Sema &S, Decl *D,
@@ -731,9 +742,10 @@
 
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
-  D->addAttr(::new (S.Context) ExclusiveLockFunctionAttr(Attr.getRange(),
-                                                         S.Context,
-                                                         StartArg, Size));
+  D->addAttr(::new (S.Context)
+             ExclusiveLockFunctionAttr(Attr.getRange(), S.Context,
+                                       StartArg, Size,
+                                       Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkTryLockFunAttrCommon(Sema &S, Decl *D,
@@ -770,10 +782,10 @@
 
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
-  D->addAttr(::new (S.Context) SharedTrylockFunctionAttr(Attr.getRange(),
-                                                         S.Context,
-                                                         Attr.getArg(0),
-                                                         StartArg, Size));
+  D->addAttr(::new (S.Context)
+             SharedTrylockFunctionAttr(Attr.getRange(), S.Context,
+                                       Attr.getArg(0), StartArg, Size,
+                                       Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleExclusiveTrylockFunctionAttr(Sema &S, Decl *D,
@@ -784,10 +796,10 @@
 
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
-  D->addAttr(::new (S.Context) ExclusiveTrylockFunctionAttr(Attr.getRange(),
-                                                            S.Context,
-                                                            Attr.getArg(0),
-                                                            StartArg, Size));
+  D->addAttr(::new (S.Context)
+             ExclusiveTrylockFunctionAttr(Attr.getRange(), S.Context,
+                                          Attr.getArg(0), StartArg, Size,
+                                          Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkLocksRequiredCommon(Sema &S, Decl *D,
@@ -819,10 +831,10 @@
     return;
 
   Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context) ExclusiveLocksRequiredAttr(Attr.getRange(),
-                                                          S.Context,
-                                                          StartArg,
-                                                          Args.size()));
+  D->addAttr(::new (S.Context)
+             ExclusiveLocksRequiredAttr(Attr.getRange(), S.Context,
+                                        StartArg, Args.size(),
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleSharedLocksRequiredAttr(Sema &S, Decl *D,
@@ -832,10 +844,10 @@
     return;
 
   Expr **StartArg = &Args[0];
-  D->addAttr(::new (S.Context) SharedLocksRequiredAttr(Attr.getRange(),
-                                                       S.Context,
-                                                       StartArg,
-                                                       Args.size()));
+  D->addAttr(::new (S.Context)
+             SharedLocksRequiredAttr(Attr.getRange(), S.Context,
+                                     StartArg, Args.size(),
+                                     Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleUnlockFunAttr(Sema &S, Decl *D,
@@ -856,8 +868,9 @@
   unsigned Size = Args.size();
   Expr **StartArg = Size == 0 ? 0 : &Args[0];
 
-  D->addAttr(::new (S.Context) UnlockFunctionAttr(Attr.getRange(), S.Context,
-                                                  StartArg, Size));
+  D->addAttr(::new (S.Context)
+             UnlockFunctionAttr(Attr.getRange(), S.Context, StartArg, Size,
+                                Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleLockReturnedAttr(Sema &S, Decl *D,
@@ -880,8 +893,9 @@
   if (Size == 0)
     return;
 
-  D->addAttr(::new (S.Context) LockReturnedAttr(Attr.getRange(), S.Context,
-                                                Args[0]));
+  D->addAttr(::new (S.Context)
+             LockReturnedAttr(Attr.getRange(), S.Context, Args[0],
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleLocksExcludedAttr(Sema &S, Decl *D,
@@ -905,8 +919,9 @@
     return;
   Expr **StartArg = &Args[0];
 
-  D->addAttr(::new (S.Context) LocksExcludedAttr(Attr.getRange(), S.Context,
-                                                 StartArg, Size));
+  D->addAttr(::new (S.Context)
+             LocksExcludedAttr(Attr.getRange(), S.Context, StartArg, Size,
+                               Attr.getAttributeSpellingListIndex()));
 }
 
 
@@ -940,14 +955,18 @@
       S.Diag(Attr.getLoc(), diag::warn_attribute_ignored_for_field_of_type)
         << Attr.getName() << FD->getType();
     else
-      FD->addAttr(::new (S.Context) PackedAttr(Attr.getRange(), S.Context));
+      FD->addAttr(::new (S.Context)
+                  PackedAttr(Attr.getRange(), S.Context,
+                             Attr.getAttributeSpellingListIndex()));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
 
 static void handleMsStructAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (RecordDecl *RD = dyn_cast<RecordDecl>(D))
-    RD->addAttr(::new (S.Context) MsStructAttr(Attr.getRange(), S.Context));
+    RD->addAttr(::new (S.Context)
+                MsStructAttr(Attr.getRange(), S.Context,
+                             Attr.getAttributeSpellingListIndex()));
   else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
@@ -960,7 +979,9 @@
   // The IBAction attributes only apply to instance methods.
   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
     if (MD->isInstanceMethod()) {
-      D->addAttr(::new (S.Context) IBActionAttr(Attr.getRange(), S.Context));
+      D->addAttr(::new (S.Context)
+                 IBActionAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
       return;
     }
 
@@ -1001,7 +1022,9 @@
   if (!checkIBOutletCommon(S, D, Attr))
     return;
 
-  D->addAttr(::new (S.Context) IBOutletAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             IBOutletAttr(Attr.getRange(), S.Context,
+                          Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleIBOutletCollection(Sema &S, Decl *D,
@@ -1035,8 +1058,10 @@
     S.Diag(Attr.getLoc(), diag::err_iboutletcollection_type) << II;
     return;
   }
-  D->addAttr(::new (S.Context) IBOutletCollectionAttr(Attr.getRange(),S.Context,
-                                                   QT, Attr.getParameterLoc()));
+  D->addAttr(::new (S.Context)
+             IBOutletCollectionAttr(Attr.getRange(),S.Context,
+                                    QT, Attr.getParameterLoc(),
+                                    Attr.getAttributeSpellingListIndex()));
 }
 
 static void possibleTransparentUnionPointerType(QualType &T) {
@@ -1119,8 +1144,10 @@
     << "alloc_size" << 0 /*function*/<< 1 /*pointer*/ << D->getSourceRange();
   }
 
-  D->addAttr(::new (S.Context) AllocSizeAttr(Attr.getRange(), S.Context,
-                                             SizeArgs.data(), SizeArgs.size()));
+  D->addAttr(::new (S.Context)
+             AllocSizeAttr(Attr.getRange(), S.Context,
+                           SizeArgs.data(), SizeArgs.size(),
+                           Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNonNullAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1208,8 +1235,9 @@
   unsigned *start = &NonNullArgs[0];
   unsigned size = NonNullArgs.size();
   llvm::array_pod_sort(start, start + size);
-  D->addAttr(::new (S.Context) NonNullAttr(Attr.getRange(), S.Context, start,
-                                           size));
+  D->addAttr(::new (S.Context)
+             NonNullAttr(Attr.getRange(), S.Context, start, size,
+                         Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleOwnershipAttr(Sema &S, Decl *D, const AttributeList &AL) {
@@ -1364,8 +1392,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) OwnershipAttr(AL.getLoc(), S.Context, K, Module,
-                                             start, size));
+  D->addAttr(::new (S.Context)
+             OwnershipAttr(AL.getLoc(), S.Context, K, Module, start, size,
+                           AL.getAttributeSpellingListIndex()));
 }
 
 static void handleWeakRefAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1438,7 +1467,9 @@
                                            Str->getString()));
   }
 
-  D->addAttr(::new (S.Context) WeakRefAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             WeakRefAttr(Attr.getRange(), S.Context,
+                         Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1466,7 +1497,8 @@
   // FIXME: check if target symbol exists in current file
 
   D->addAttr(::new (S.Context) AliasAttr(Attr.getRange(), S.Context,
-                                         Str->getString()));
+                                         Str->getString(),
+                                         Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1480,7 +1512,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) MinSizeAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             MinSizeAttr(Attr.getRange(), S.Context,
+                         Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1500,7 +1534,8 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context) ColdAttr(Attr.getRange(), S.Context,
+                                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleHotAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1520,7 +1555,8 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context) HotAttr(Attr.getRange(), S.Context,
+                                       Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNakedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1534,7 +1570,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NakedAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             NakedAttr(Attr.getRange(), S.Context,
+                       Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleAlwaysInlineAttr(Sema &S, Decl *D,
@@ -1551,7 +1589,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) AlwaysInlineAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             AlwaysInlineAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleTLSModelAttr(Sema &S, Decl *D,
@@ -1586,8 +1626,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) TLSModelAttr(Attr.getRange(), S.Context,
-                                            Model));
+  D->addAttr(::new (S.Context)
+             TLSModelAttr(Attr.getRange(), S.Context, Model,
+                          Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleMallocAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1600,7 +1641,9 @@
   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     QualType RetTy = FD->getResultType();
     if (RetTy->isAnyPointerType() || RetTy->isBlockPointerType()) {
-      D->addAttr(::new (S.Context) MallocAttr(Attr.getRange(), S.Context));
+      D->addAttr(::new (S.Context)
+                 MallocAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
       return;
     }
   }
@@ -1613,13 +1656,17 @@
   if (!checkAttributeNumArgs(S, Attr, 0))
     return;
 
-  D->addAttr(::new (S.Context) MayAliasAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             MayAliasAttr(Attr.getRange(), S.Context,
+                          Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNoCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   assert(!Attr.isInvalid());
   if (isa<VarDecl>(D))
-    D->addAttr(::new (S.Context) NoCommonAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               NoCommonAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
   else
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << ExpectedVariable;
@@ -1628,7 +1675,9 @@
 static void handleCommonAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   assert(!Attr.isInvalid());
   if (isa<VarDecl>(D))
-    D->addAttr(::new (S.Context) CommonAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CommonAttr(Attr.getRange(), S.Context,
+                          Attr.getAttributeSpellingListIndex()));
   else
     S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
       << Attr.getName() << ExpectedVariable;
@@ -1645,7 +1694,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoReturnAttr(attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             NoReturnAttr(attr.getRange(), S.Context,
+                          attr.getAttributeSpellingListIndex()));
 }
 
 bool Sema::CheckNoReturnAttr(const AttributeList &attr) {
@@ -1679,7 +1730,9 @@
     }
   }
   
-  D->addAttr(::new (S.Context) AnalyzerNoReturnAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             AnalyzerNoReturnAttr(Attr.getRange(), S.Context,
+                                  Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleCXX11NoReturnAttr(Sema &S, Decl *D,
@@ -1694,7 +1747,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) CXX11NoReturnAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             CXX11NoReturnAttr(Attr.getRange(), S.Context,
+                               Attr.getAttributeSpellingListIndex()));
 }
 
 // PS3 PPU-specific.
@@ -1755,7 +1810,9 @@
     count++;
   }
 
-  D->addAttr(::new (S.Context) VecReturnAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             VecReturnAttr(Attr.getRange(), S.Context,
+                           Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleDependencyAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1781,7 +1838,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) UnusedAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             UnusedAttr(Attr.getRange(), S.Context,
+                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleReturnsTwiceAttr(Sema &S, Decl *D,
@@ -1798,7 +1857,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ReturnsTwiceAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ReturnsTwiceAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleUsedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1819,7 +1880,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) UsedAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             UsedAttr(Attr.getRange(), S.Context,
+                      Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1848,8 +1911,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ConstructorAttr(Attr.getRange(), S.Context,
-                                               priority));
+  D->addAttr(::new (S.Context)
+             ConstructorAttr(Attr.getRange(), S.Context, priority,
+                             Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -1878,8 +1942,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) DestructorAttr(Attr.getRange(), S.Context,
-                                              priority));
+  D->addAttr(::new (S.Context)
+             DestructorAttr(Attr.getRange(), S.Context, priority,
+                            Attr.getAttributeSpellingListIndex()));
 }
 
 template <typename AttrTy>
@@ -1903,7 +1968,8 @@
     Str = SE->getString();
   }
 
-  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str));
+  D->addAttr(::new (S.Context) AttrTy(Attr.getRange(), S.Context, Str,
+                                      Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleArcWeakrefUnavailableAttr(Sema &S, Decl *D, 
@@ -1914,8 +1980,9 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) ArcWeakrefUnavailableAttr(
-                                          Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ArcWeakrefUnavailableAttr(Attr.getRange(), S.Context,
+                                       Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCRootClassAttr(Sema &S, Decl *D, 
@@ -1931,11 +1998,13 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) ObjCRootClassAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ObjCRootClassAttr(Attr.getRange(), S.Context,
+                               Attr.getAttributeSpellingListIndex()));
 }
 
-static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D, 
-                                            const AttributeList &Attr) {
+static void handleObjCRequiresPropertyDefsAttr(Sema &S, Decl *D,
+                                               const AttributeList &Attr) {
   if (!isa<ObjCInterfaceDecl>(D)) {
     S.Diag(Attr.getLoc(), diag::err_suppress_autosynthesis);
     return;
@@ -1947,8 +2016,9 @@
     return;
   }
   
-  D->addAttr(::new (S.Context) ObjCRequiresPropertyDefsAttr(
-                                 Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ObjCRequiresPropertyDefsAttr(Attr.getRange(), S.Context,
+                                          Attr.getAttributeSpellingListIndex()));
 }
 
 static bool checkAvailabilityAttr(Sema &S, SourceRange Range,
@@ -2015,7 +2085,8 @@
                                               VersionTuple Obsoleted,
                                               bool IsUnavailable,
                                               StringRef Message,
-                                              bool Override) {
+                                              bool Override,
+                                              unsigned AttrSpellingListIndex) {
   VersionTuple MergedIntroduced = Introduced;
   VersionTuple MergedDeprecated = Deprecated;
   VersionTuple MergedObsoleted = Obsoleted;
@@ -2123,7 +2194,8 @@
                              MergedDeprecated, MergedObsoleted)) {
     return ::new (Context) AvailabilityAttr(Range, Context, Platform,
                                             Introduced, Deprecated,
-                                            Obsoleted, IsUnavailable, Message);
+                                            Obsoleted, IsUnavailable, Message,
+                                            AttrSpellingListIndex);
   }
   return NULL;
 }
@@ -2132,7 +2204,8 @@
                                    const AttributeList &Attr) {
   IdentifierInfo *Platform = Attr.getParameterName();
   SourceLocation PlatformLoc = Attr.getParameterLoc();
-
+  unsigned Index = Attr.getAttributeSpellingListIndex();
+  
   if (AvailabilityAttr::getPrettyPlatformName(Platform->getName()).empty())
     S.Diag(PlatformLoc, diag::warn_availability_unknown_platform)
       << Platform;
@@ -2159,13 +2232,15 @@
                                                       Deprecated.Version,
                                                       Obsoleted.Version,
                                                       IsUnavailable, Str,
-                                                      /*Override=*/false);
+                                                      /*Override=*/false,
+                                                      Index);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
 
 VisibilityAttr *Sema::mergeVisibilityAttr(Decl *D, SourceRange Range,
-                                          VisibilityAttr::VisibilityType Vis) {
+                                          VisibilityAttr::VisibilityType Vis,
+                                          unsigned AttrSpellingListIndex) {
   if (isa<TypedefNameDecl>(D)) {
     Diag(Range.getBegin(), diag::warn_attribute_ignored) << "visibility";
     return NULL;
@@ -2179,7 +2254,8 @@
     Diag(Range.getBegin(), diag::note_previous_attribute);
     D->dropAttr<VisibilityAttr>();
   }
-  return ::new (Context) VisibilityAttr(Range, Context, Vis);
+  return ::new (Context) VisibilityAttr(Range, Context, Vis,
+                                        AttrSpellingListIndex);
 }
 
 static void handleVisibilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2199,7 +2275,7 @@
 
   StringRef TypeStr = Str->getString();
   VisibilityAttr::VisibilityType type;
-
+  
   if (TypeStr == "default")
     type = VisibilityAttr::Default;
   else if (TypeStr == "hidden")
@@ -2220,7 +2296,9 @@
     return;
   }
 
-  VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type);
+  unsigned Index = Attr.getAttributeSpellingListIndex();
+  VisibilityAttr *NewAttr = S.mergeVisibilityAttr(D, Attr.getRange(), type,
+                                                  Index);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -2289,7 +2367,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) ObjCExceptionAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ObjCExceptionAttr(Attr.getRange(), S.Context,
+                               Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCNSObject(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2320,7 +2400,9 @@
     // case.    
     S.Diag(D->getLocation(), diag::warn_nsobject_attribute);
   }
-  D->addAttr(::new (S.Context) ObjCNSObjectAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             ObjCNSObjectAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static void
@@ -2335,7 +2417,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) OverloadableAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             OverloadableAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleBlocksAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2359,7 +2443,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) BlocksAttr(Attr.getRange(), S.Context, type));
+  D->addAttr(::new (S.Context)
+             BlocksAttr(Attr.getRange(), S.Context, type,
+                        Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2451,8 +2537,9 @@
       << Attr.getName() << ExpectedFunctionMethodOrBlock;
     return;
   }
-  D->addAttr(::new (S.Context) SentinelAttr(Attr.getRange(), S.Context, sentinel,
-                                            nullPos));
+  D->addAttr(::new (S.Context)
+             SentinelAttr(Attr.getRange(), S.Context, sentinel, nullPos,
+                          Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleWarnUnusedResult(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2478,7 +2565,9 @@
       return;
     }
   
-  D->addAttr(::new (S.Context) WarnUnusedResultAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context) 
+             WarnUnusedResultAttr(Attr.getRange(), S.Context,
+                                  Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleWeakAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2500,7 +2589,9 @@
 
   NamedDecl *nd = cast<NamedDecl>(D);
 
-  nd->addAttr(::new (S.Context) WeakAttr(Attr.getRange(), S.Context));
+  nd->addAttr(::new (S.Context)
+              WeakAttr(Attr.getRange(), S.Context,
+                       Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleWeakImportAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2527,7 +2618,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) WeakImportAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             WeakImportAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
 }
 
 // Handles reqd_work_group_size and work_group_size_hint.
@@ -2577,15 +2670,18 @@
   if (Attr.getKind() == AttributeList::AT_ReqdWorkGroupSize)
     D->addAttr(::new (S.Context)
                  ReqdWorkGroupSizeAttr(Attr.getRange(), S.Context,
-                                       WGSize[0], WGSize[1], WGSize[2]));
+                                       WGSize[0], WGSize[1], WGSize[2],
+                                       Attr.getAttributeSpellingListIndex()));
   else
     D->addAttr(::new (S.Context)
                  WorkGroupSizeHintAttr(Attr.getRange(), S.Context,
-                                       WGSize[0], WGSize[1], WGSize[2]));
+                                       WGSize[0], WGSize[1], WGSize[2],
+                                       Attr.getAttributeSpellingListIndex()));
 }
 
 SectionAttr *Sema::mergeSectionAttr(Decl *D, SourceRange Range,
-                                    StringRef Name) {
+                                    StringRef Name,
+                                    unsigned AttrSpellingListIndex) {
   if (SectionAttr *ExistingAttr = D->getAttr<SectionAttr>()) {
     if (ExistingAttr->getName() == Name)
       return NULL;
@@ -2593,7 +2689,8 @@
     Diag(Range.getBegin(), diag::note_previous_attribute);
     return NULL;
   }
-  return ::new (Context) SectionAttr(Range, Context, Name);
+  return ::new (Context) SectionAttr(Range, Context, Name,
+                                     AttrSpellingListIndex);
 }
 
 static void handleSectionAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2623,8 +2720,10 @@
     S.Diag(SE->getLocStart(), diag::err_attribute_section_local_variable);
     return;
   }
+  
+  unsigned Index = Attr.getAttributeSpellingListIndex();
   SectionAttr *NewAttr = S.mergeSectionAttr(D, Attr.getRange(),
-                                            SE->getString());
+                                            SE->getString(), Index);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -2641,7 +2740,9 @@
     if (Existing->getLocation().isInvalid())
       Existing->setRange(Attr.getRange());
   } else {
-    D->addAttr(::new (S.Context) NoThrowAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               NoThrowAttr(Attr.getRange(), S.Context,
+                           Attr.getAttributeSpellingListIndex()));
   }
 }
 
@@ -2656,7 +2757,9 @@
    if (Existing->getLocation().isInvalid())
      Existing->setRange(Attr.getRange());
   } else {
-    D->addAttr(::new (S.Context) ConstAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               ConstAttr(Attr.getRange(), S.Context,
+                         Attr.getAttributeSpellingListIndex() ));
   }
 }
 
@@ -2665,7 +2768,9 @@
   if (!checkAttributeNumArgs(S, Attr, 0))
     return;
 
-  D->addAttr(::new (S.Context) PureAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             PureAttr(Attr.getRange(), S.Context,
+                      Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleCleanupAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -2724,7 +2829,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) CleanupAttr(Attr.getRange(), S.Context, FD));
+  D->addAttr(::new (S.Context)
+             CleanupAttr(Attr.getRange(), S.Context, FD,
+                         Attr.getAttributeSpellingListIndex()));
   S.MarkFunctionReferenced(Attr.getParameterLoc(), FD);
 }
 
@@ -2799,8 +2906,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) FormatArgAttr(Attr.getRange(), S.Context,
-                                             Idx.getZExtValue()));
+  D->addAttr(::new (S.Context)
+             FormatArgAttr(Attr.getRange(), S.Context, Idx.getZExtValue(),
+                           Attr.getAttributeSpellingListIndex()));
 }
 
 enum FormatAttrKind {
@@ -2875,12 +2983,14 @@
     Attr.setInvalid();
     return;
   }
-  D->addAttr(::new (S.Context) InitPriorityAttr(Attr.getRange(), S.Context,
-                                                prioritynum));
+  D->addAttr(::new (S.Context)
+             InitPriorityAttr(Attr.getRange(), S.Context, prioritynum,
+                              Attr.getAttributeSpellingListIndex()));
 }
 
 FormatAttr *Sema::mergeFormatAttr(Decl *D, SourceRange Range, StringRef Format,
-                                  int FormatIdx, int FirstArg) {
+                                  int FormatIdx, int FirstArg,
+                                  unsigned AttrSpellingListIndex) {
   // Check whether we already have an equivalent format attribute.
   for (specific_attr_iterator<FormatAttr>
          i = D->specific_attr_begin<FormatAttr>(),
@@ -2898,8 +3008,8 @@
     }
   }
 
-  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx,
-                                    FirstArg);
+  return ::new (Context) FormatAttr(Range, Context, Format, FormatIdx, FirstArg,
+                                    AttrSpellingListIndex);
 }
 
 /// Handle __attribute__((format(type,idx,firstarg))) attributes based on
@@ -3039,7 +3149,8 @@
 
   FormatAttr *NewAttr = S.mergeFormatAttr(D, Attr.getRange(), Format,
                                           Idx.getZExtValue(),
-                                          FirstArg.getZExtValue());
+                                          FirstArg.getZExtValue(),
+                                          Attr.getAttributeSpellingListIndex());
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -3108,7 +3219,9 @@
     }
   }
 
-  RD->addAttr(::new (S.Context) TransparentUnionAttr(Attr.getRange(), S.Context));
+  RD->addAttr(::new (S.Context)
+              TransparentUnionAttr(Attr.getRange(), S.Context,
+                                   Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleAnnotateAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3133,8 +3246,10 @@
       if ((*i)->getAnnotation() == SE->getString())
           return;
   }
-  D->addAttr(::new (S.Context) AnnotateAttr(Attr.getRange(), S.Context,
-                                            SE->getString()));
+  
+  D->addAttr(::new (S.Context)
+             AnnotateAttr(Attr.getRange(), S.Context, SE->getString(),
+                          Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3150,16 +3265,18 @@
 
   if (Attr.getNumArgs() == 0) {
     D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, 
-               true, 0, Attr.isDeclspecAttribute()));
+               true, 0, Attr.isDeclspecAttribute(),
+               Attr.getAttributeSpellingListIndex()));
     return;
   }
 
   S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0), 
-                   Attr.isDeclspecAttribute());
+                   Attr.isDeclspecAttribute(),
+                   Attr.getAttributeSpellingListIndex());
 }
 
 void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 
-                          bool isDeclSpec) {
+                          bool isDeclSpec, unsigned SpellingListIndex) {
   // FIXME: Handle pack-expansions here.
   if (DiagnoseUnexpandedParameterPack(E))
     return;
@@ -3167,7 +3284,7 @@
   if (E->isTypeDependent() || E->isValueDependent()) {
     // Save dependent expressions in the AST to be instantiated.
     D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E, 
-                                           isDeclSpec));
+                                           isDeclSpec, SpellingListIndex));
     return;
   }
   
@@ -3196,7 +3313,7 @@
   }
 
   D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(), 
-                                         isDeclSpec));
+                                         isDeclSpec, SpellingListIndex));
 }
 
 void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, 
@@ -3399,7 +3516,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoDebugAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             NoDebugAttr(Attr.getRange(), S.Context,
+                         Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNoInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3414,7 +3533,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoInlineAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             NoInlineAttr(Attr.getRange(), S.Context,
+             Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNoInstrumentFunctionAttr(Sema &S, Decl *D,
@@ -3430,8 +3551,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NoInstrumentFunctionAttr(Attr.getRange(),
-                                                        S.Context));
+  D->addAttr(::new (S.Context)
+             NoInstrumentFunctionAttr(Attr.getRange(), S.Context,
+                                      Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleConstantAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3448,7 +3570,9 @@
       return;
     }
 
-    D->addAttr(::new (S.Context) CUDAConstantAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CUDAConstantAttr(Attr.getRange(), S.Context,
+                                Attr.getAttributeSpellingListIndex()));
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "constant";
   }
@@ -3468,7 +3592,9 @@
       return;
     }
 
-    D->addAttr(::new (S.Context) CUDADeviceAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CUDADeviceAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "device";
   }
@@ -3501,7 +3627,9 @@
       return;
     }
 
-    D->addAttr(::new (S.Context) CUDAGlobalAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CUDAGlobalAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "global";
   }
@@ -3520,7 +3648,9 @@
       return;
     }
 
-    D->addAttr(::new (S.Context) CUDAHostAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CUDAHostAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "host";
   }
@@ -3532,14 +3662,15 @@
     if (!checkAttributeNumArgs(S, Attr, 0))
       return;
 
-
     if (!isa<VarDecl>(D)) {
       S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type)
         << Attr.getName() << ExpectedVariable;
       return;
     }
 
-    D->addAttr(::new (S.Context) CUDASharedAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CUDASharedAttr(Attr.getRange(), S.Context,
+                              Attr.getAttributeSpellingListIndex()));
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "shared";
   }
@@ -3562,7 +3693,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) GNUInlineAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             GNUInlineAttr(Attr.getRange(), S.Context,
+                           Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleCallConvAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -3583,19 +3716,29 @@
 
   switch (Attr.getKind()) {
   case AttributeList::AT_FastCall:
-    D->addAttr(::new (S.Context) FastCallAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               FastCallAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
     return;
   case AttributeList::AT_StdCall:
-    D->addAttr(::new (S.Context) StdCallAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               StdCallAttr(Attr.getRange(), S.Context,
+                           Attr.getAttributeSpellingListIndex()));
     return;
   case AttributeList::AT_ThisCall:
-    D->addAttr(::new (S.Context) ThisCallAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               ThisCallAttr(Attr.getRange(), S.Context,
+                            Attr.getAttributeSpellingListIndex()));
     return;
   case AttributeList::AT_CDecl:
-    D->addAttr(::new (S.Context) CDeclAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CDeclAttr(Attr.getRange(), S.Context,
+                         Attr.getAttributeSpellingListIndex()));
     return;
   case AttributeList::AT_Pascal:
-    D->addAttr(::new (S.Context) PascalAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               PascalAttr(Attr.getRange(), S.Context,
+                          Attr.getAttributeSpellingListIndex()));
     return;
   case AttributeList::AT_Pcs: {
     PcsAttr::PCSType PCS;
@@ -3610,14 +3753,20 @@
       llvm_unreachable("unexpected calling convention in pcs attribute");
     }
 
-    D->addAttr(::new (S.Context) PcsAttr(Attr.getRange(), S.Context, PCS));
+    D->addAttr(::new (S.Context)
+               PcsAttr(Attr.getRange(), S.Context, PCS,
+                       Attr.getAttributeSpellingListIndex()));
     return;
   }
   case AttributeList::AT_PnaclCall:
-    D->addAttr(::new (S.Context) PnaclCallAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               PnaclCallAttr(Attr.getRange(), S.Context,
+                             Attr.getAttributeSpellingListIndex()));
     return;
   case AttributeList::AT_IntelOclBicc:
-    D->addAttr(::new (S.Context) IntelOclBiccAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               IntelOclBiccAttr(Attr.getRange(), S.Context,
+                                Attr.getAttributeSpellingListIndex()));
     return;
 
   default:
@@ -3706,7 +3855,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) RegparmAttr(Attr.getRange(), S.Context, numParams));
+  D->addAttr(::new (S.Context)
+             RegparmAttr(Attr.getRange(), S.Context, numParams,
+                         Attr.getAttributeSpellingListIndex()));
 }
 
 /// Checks a regparm attribute, returning true if it is ill-formed and
@@ -3786,9 +3937,11 @@
       }
     }
 
-    D->addAttr(::new (S.Context) CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
-                                                      MaxThreads.getZExtValue(),
-                                                     MinBlocks.getZExtValue()));
+    D->addAttr(::new (S.Context)
+               CUDALaunchBoundsAttr(Attr.getRange(), S.Context,
+                                    MaxThreads.getZExtValue(),
+                                    MinBlocks.getZExtValue(),
+                                    Attr.getAttributeSpellingListIndex()));
   } else {
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "launch_bounds";
   }
@@ -3839,12 +3992,10 @@
     }
   }
 
-  D->addAttr(::new (S.Context) ArgumentWithTypeTagAttr(Attr.getRange(),
-                                                       S.Context,
-                                                       ArgumentKind,
-                                                       ArgumentIdx,
-                                                       TypeTagIdx,
-                                                       IsPointer));
+  D->addAttr(::new (S.Context)
+             ArgumentWithTypeTagAttr(Attr.getRange(), S.Context, ArgumentKind,
+                                     ArgumentIdx, TypeTagIdx, IsPointer,
+                                     Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleTypeTagForDatatypeAttr(Sema &S, Decl *D,
@@ -3858,13 +4009,12 @@
 
   QualType MatchingCType = S.GetTypeFromParser(Attr.getMatchingCType(), NULL);
 
-  D->addAttr(::new (S.Context) TypeTagForDatatypeAttr(
-                                  Attr.getRange(),
-                                  S.Context,
-                                  PointerKind,
-                                  MatchingCType,
-                                  Attr.getLayoutCompatible(),
-                                  Attr.getMustBeNull()));
+  D->addAttr(::new (S.Context)
+             TypeTagForDatatypeAttr(Attr.getRange(), S.Context, PointerKind,
+                                    MatchingCType,
+                                    Attr.getLayoutCompatible(),
+                                    Attr.getMustBeNull(),
+                                    Attr.getAttributeSpellingListIndex()));
 }
 
 //===----------------------------------------------------------------------===//
@@ -3906,9 +4056,13 @@
   }
 
   if (cf)
-    param->addAttr(::new (S.Context) CFConsumedAttr(Attr.getRange(), S.Context));
+    param->addAttr(::new (S.Context)
+                   CFConsumedAttr(Attr.getRange(), S.Context,
+                                  Attr.getAttributeSpellingListIndex()));
   else
-    param->addAttr(::new (S.Context) NSConsumedAttr(Attr.getRange(), S.Context));
+    param->addAttr(::new (S.Context)
+                   NSConsumedAttr(Attr.getRange(), S.Context,
+                                  Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNSConsumesSelfAttr(Sema &S, Decl *D,
@@ -3919,7 +4073,9 @@
     return;
   }
 
-  D->addAttr(::new (S.Context) NSConsumesSelfAttr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             NSConsumesSelfAttr(Attr.getRange(), S.Context,
+                                Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
@@ -3971,24 +4127,29 @@
     default:
       llvm_unreachable("invalid ownership attribute");
     case AttributeList::AT_NSReturnsAutoreleased:
-      D->addAttr(::new (S.Context) NSReturnsAutoreleasedAttr(Attr.getRange(),
-                                                             S.Context));
+      D->addAttr(::new (S.Context)
+                 NSReturnsAutoreleasedAttr(Attr.getRange(), S.Context,
+                                           Attr.getAttributeSpellingListIndex()));
       return;
     case AttributeList::AT_CFReturnsNotRetained:
-      D->addAttr(::new (S.Context) CFReturnsNotRetainedAttr(Attr.getRange(),
-                                                            S.Context));
+      D->addAttr(::new (S.Context)
+                 CFReturnsNotRetainedAttr(Attr.getRange(), S.Context,
+                                          Attr.getAttributeSpellingListIndex()));
       return;
     case AttributeList::AT_NSReturnsNotRetained:
-      D->addAttr(::new (S.Context) NSReturnsNotRetainedAttr(Attr.getRange(),
-                                                            S.Context));
+      D->addAttr(::new (S.Context)
+                 NSReturnsNotRetainedAttr(Attr.getRange(), S.Context,
+                                          Attr.getAttributeSpellingListIndex()));
       return;
     case AttributeList::AT_CFReturnsRetained:
-      D->addAttr(::new (S.Context) CFReturnsRetainedAttr(Attr.getRange(),
-                                                         S.Context));
+      D->addAttr(::new (S.Context)
+                 CFReturnsRetainedAttr(Attr.getRange(), S.Context,
+                                       Attr.getAttributeSpellingListIndex()));
       return;
     case AttributeList::AT_NSReturnsRetained:
-      D->addAttr(::new (S.Context) NSReturnsRetainedAttr(Attr.getRange(),
-                                                         S.Context));
+      D->addAttr(::new (S.Context)
+                 NSReturnsRetainedAttr(Attr.getRange(), S.Context,
+                                       Attr.getAttributeSpellingListIndex()));
       return;
   };
 }
@@ -4018,8 +4179,9 @@
     return;
   }
 
-  method->addAttr(
-    ::new (S.Context) ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context));
+  method->addAttr(::new (S.Context)
+                  ObjCReturnsInnerPointerAttr(attr.getRange(), S.Context,
+                                              attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCRequiresSuperAttr(Sema &S, Decl *D,
@@ -4045,8 +4207,9 @@
     return;
   }
   
-  method->addAttr(
-    ::new (S.Context) ObjCRequiresSuperAttr(attr.getRange(), S.Context));
+  method->addAttr(::new (S.Context)
+                  ObjCRequiresSuperAttr(attr.getRange(), S.Context,
+                                        attr.getAttributeSpellingListIndex()));
 }
 
 /// Handle cf_audited_transfer and cf_unknown_transfer.
@@ -4076,11 +4239,13 @@
 
   // All clear;  add the attribute.
   if (IsAudited) {
-    D->addAttr(
-      ::new (S.Context) CFAuditedTransferAttr(A.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CFAuditedTransferAttr(A.getRange(), S.Context,
+                                     A.getAttributeSpellingListIndex()));
   } else {
-    D->addAttr(
-      ::new (S.Context) CFUnknownTransferAttr(A.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               CFUnknownTransferAttr(A.getRange(), S.Context,
+                                     A.getAttributeSpellingListIndex()));
   }
 }
 
@@ -4110,8 +4275,9 @@
     }
   }
 
-  D->addAttr(::new (S.Context) NSBridgedAttr(Attr.getRange(), S.Context,
-                                             ParmName));
+  D->addAttr(::new (S.Context)
+             NSBridgedAttr(Attr.getRange(), S.Context, ParmName,
+                           Attr.getAttributeSpellingListIndex()));
 }
 
 static void handleObjCOwnershipAttr(Sema &S, Decl *D,
@@ -4165,7 +4331,8 @@
   }
 
   D->addAttr(::new (S.Context)
-                 ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context));
+             ObjCPreciseLifetimeAttr(Attr.getRange(), S.Context,
+                                     Attr.getAttributeSpellingListIndex()));
 }
 
 //===----------------------------------------------------------------------===//
@@ -4220,8 +4387,9 @@
       I++;
     }
 
-    D->addAttr(::new (S.Context) UuidAttr(Attr.getRange(), S.Context,
-                                          Str->getString()));
+    D->addAttr(::new (S.Context)
+               UuidAttr(Attr.getRange(), S.Context, Str->getString(),
+                        Attr.getAttributeSpellingListIndex()));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "uuid";
 }
@@ -4235,13 +4403,19 @@
   AttributeList::Kind Kind = Attr.getKind();
   if (Kind == AttributeList::AT_SingleInheritance)
     D->addAttr(
-        ::new (S.Context) SingleInheritanceAttr(Attr.getRange(), S.Context));
+        ::new (S.Context)
+               SingleInheritanceAttr(Attr.getRange(), S.Context,
+                                     Attr.getAttributeSpellingListIndex()));
   else if (Kind == AttributeList::AT_MultipleInheritance)
     D->addAttr(
-        ::new (S.Context) MultipleInheritanceAttr(Attr.getRange(), S.Context));
+        ::new (S.Context)
+               MultipleInheritanceAttr(Attr.getRange(), S.Context,
+                                       Attr.getAttributeSpellingListIndex()));
   else if (Kind == AttributeList::AT_VirtualInheritance)
     D->addAttr(
-        ::new (S.Context) VirtualInheritanceAttr(Attr.getRange(), S.Context));
+        ::new (S.Context)
+               VirtualInheritanceAttr(Attr.getRange(), S.Context,
+                                      Attr.getAttributeSpellingListIndex()));
 }
 
 static void handlePortabilityAttr(Sema &S, Decl *D, const AttributeList &Attr) {
@@ -4249,20 +4423,25 @@
     AttributeList::Kind Kind = Attr.getKind();
     if (Kind == AttributeList::AT_Ptr32)
       D->addAttr(
-          ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context));
+          ::new (S.Context) Ptr32Attr(Attr.getRange(), S.Context,
+                                      Attr.getAttributeSpellingListIndex()));
     else if (Kind == AttributeList::AT_Ptr64)
       D->addAttr(
-          ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context));
+          ::new (S.Context) Ptr64Attr(Attr.getRange(), S.Context,
+                                      Attr.getAttributeSpellingListIndex()));
     else if (Kind == AttributeList::AT_Win64)
       D->addAttr(
-          ::new (S.Context) Win64Attr(Attr.getRange(), S.Context));
+          ::new (S.Context) Win64Attr(Attr.getRange(), S.Context,
+                                      Attr.getAttributeSpellingListIndex()));
   } else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }
 
 static void handleForceInlineAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   if (S.LangOpts.MicrosoftExt)
-    D->addAttr(::new (S.Context) ForceInlineAttr(Attr.getRange(), S.Context));
+    D->addAttr(::new (S.Context)
+               ForceInlineAttr(Attr.getRange(), S.Context,
+                               Attr.getAttributeSpellingListIndex()));
   else
     S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << Attr.getName();
 }

Modified: cfe/trunk/lib/Sema/TargetAttributesSema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TargetAttributesSema.cpp?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TargetAttributesSema.cpp (original)
+++ cfe/trunk/lib/Sema/TargetAttributesSema.cpp Thu Jan 24 10:46:58 2013
@@ -151,7 +151,8 @@
                                                            S.Context));
 }
 
-DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range) {
+DLLImportAttr *Sema::mergeDLLImportAttr(Decl *D, SourceRange Range,
+                                        unsigned AttrSpellingListIndex) {
   if (D->hasAttr<DLLExportAttr>()) {
     Diag(Range.getBegin(), diag::warn_attribute_ignored) << "dllimport";
     return NULL;
@@ -160,7 +161,8 @@
   if (D->hasAttr<DLLImportAttr>())
     return NULL;
 
-  return ::new (Context) DLLImportAttr(Range, Context);
+  return ::new (Context) DLLImportAttr(Range, Context,
+                                       AttrSpellingListIndex);
 }
 
 static void HandleDLLImportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -189,12 +191,14 @@
     return;
   }
 
-  DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange());
+  unsigned Index = Attr.getAttributeSpellingListIndex();
+  DLLImportAttr *NewAttr = S.mergeDLLImportAttr(D, Attr.getRange(), Index);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
 
-DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range) {
+DLLExportAttr *Sema::mergeDLLExportAttr(Decl *D, SourceRange Range,
+                                        unsigned AttrSpellingListIndex) {
   if (DLLImportAttr *Import = D->getAttr<DLLImportAttr>()) {
     Diag(Import->getLocation(), diag::warn_attribute_ignored) << "dllimport";
     D->dropAttr<DLLImportAttr>();
@@ -203,7 +207,8 @@
   if (D->hasAttr<DLLExportAttr>())
     return NULL;
 
-  return ::new (Context) DLLExportAttr(Range, Context);
+  return ::new (Context) DLLExportAttr(Range, Context,
+                                       AttrSpellingListIndex);
 }
 
 static void HandleDLLExportAttr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -229,7 +234,8 @@
     return;
   }
 
-  DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange());
+  unsigned Index = Attr.getAttributeSpellingListIndex();
+  DLLExportAttr *NewAttr = S.mergeDLLExportAttr(D, Attr.getRange(), Index);
   if (NewAttr)
     D->addAttr(NewAttr);
 }
@@ -274,7 +280,8 @@
       << Attr.getName() << /* function */0;
     return;
   }
-  D->addAttr(::new (S.Context) Mips16Attr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context) Mips16Attr(Attr.getRange(), S.Context,
+                                          Attr.getAttributeSpellingListIndex()));
 }
 
 static void HandleNoMips16Attr(Decl *D, const AttributeList &Attr, Sema &S) {
@@ -289,7 +296,9 @@
       << Attr.getName() << /* function */0;
     return;
   }
-  D->addAttr(::new (S.Context) NoMips16Attr(Attr.getRange(), S.Context));
+  D->addAttr(::new (S.Context)
+             NoMips16Attr(Attr.getRange(), S.Context,
+                          Attr.getAttributeSpellingListIndex()));
 }
 
 namespace {

Added: cfe/trunk/test/Sema/attr-print.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/attr-print.c?rev=173358&view=auto
==============================================================================
--- cfe/trunk/test/Sema/attr-print.c (added)
+++ cfe/trunk/test/Sema/attr-print.c Thu Jan 24 10:46:58 2013
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -ast-print | FileCheck %s
+
+// FIXME: we need to fix the "BoolArgument<"IsMSDeclSpec">"
+// hack in Attr.td for attribute "Aligned".
+
+// CHECK: int x __attribute__((aligned(4, 0)));
+int x __attribute__((aligned(4)));
+
+// CHECK: int y __attribute__((align(4, 0)));
+int y __attribute__((align(4)));
+
+// CHECK: void foo() __attribute__((const));
+void foo() __attribute__((const));
+
+// CHECK: void bar() __attribute__((__const));
+void bar() __attribute__((__const));

Added: cfe/trunk/test/SemaCXX/attr-print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-print.cpp?rev=173358&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/attr-print.cpp (added)
+++ cfe/trunk/test/SemaCXX/attr-print.cpp Thu Jan 24 10:46:58 2013
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 %s -ast-print | FileCheck %s
+
+// FIXME: align attribute print
+
+// CHECK: int x __attribute__((aligned(4, 0)));
+int x __attribute__((aligned(4)));
+
+// CHECK: int y __attribute__((align(4, 0)));
+int y __attribute__((align(4)));
+
+// CHECK: void foo() __attribute__((const));
+void foo() __attribute__((const));
+
+// CHECK: void bar() __attribute__((__const));
+void bar() __attribute__((__const));

Added: cfe/trunk/test/SemaCXX/cxx11-attr-print.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx11-attr-print.cpp?rev=173358&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx11-attr-print.cpp (added)
+++ cfe/trunk/test/SemaCXX/cxx11-attr-print.cpp Thu Jan 24 10:46:58 2013
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -std=c++11 -ast-print %s | FileCheck %s
+// FIXME: align attribute print
+
+// CHECK: int x __attribute__((aligned(4, 0)));
+int x __attribute__((aligned(4)));
+
+// CHECK: int y __attribute__((align(4, 0)));
+int y __attribute__((align(4)));
+
+// CHECK: gnu::aligned(4, 0)]];
+int z [[gnu::aligned(4)]];
+
+// CHECK: __attribute__((deprecated("warning")));
+int a __attribute__((deprecated("warning")));
+
+// CHECK: gnu::deprecated("warning")]];
+int b [[gnu::deprecated("warning")]];
+
+// CHECK: void foo() __attribute__((const));
+void foo() __attribute__((const));
+
+// CHECK: void bar() __attribute__((__const));
+void bar() __attribute__((__const));
+
+// CHECK: int f1() __attribute__((warn_unused_result));
+int f1() __attribute__((warn_unused_result));
+
+// CHECK: clang::warn_unused_result]];
+int f2 [[clang::warn_unused_result]] ();
+
+// CHECK: gnu::warn_unused_result]];
+int f3 [[gnu::warn_unused_result]] ();
+
+// FIXME: ast-print need to print C++11
+// attribute after function declare-id.
+// CHECK: noreturn]];
+void f4 [[noreturn]] ();
+
+// CHECK: std::noreturn]];
+void f5 [[std::noreturn]] ();
+
+// CHECK: __attribute__((gnu_inline));
+inline void f6() __attribute__((gnu_inline));
+
+// CHECK: gnu::gnu_inline]];
+inline void f7 [[gnu::gnu_inline]] ();
+
+// arguments printing
+// CHECK: __attribute__((format("printf", 2, 3)));
+void f8 (void *, const char *, ...) __attribute__ ((format (printf, 2, 3)));

Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original)
+++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Thu Jan 24 10:46:58 2013
@@ -735,6 +735,82 @@
      << "  OS << \"";
 }
 
+static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
+                                     raw_ostream &OS) {
+  std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
+
+  OS << "void " << R.getName() << "Attr::printPretty("
+    << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
+
+  if (Spellings.size() == 0) {
+    OS << "}\n\n";
+    return;
+  }
+
+  OS <<
+    "  switch (SpellingListIndex) {\n"
+    "  default:\n"
+    "    llvm_unreachable(\"Unknown attribute spelling!\");\n"
+    "    break;\n";
+
+  for (unsigned I = 0; I < Spellings.size(); ++ I) {
+    llvm::SmallString<16> Prefix;
+    llvm::SmallString<8> Suffix;
+    // The actual spelling of the name and namespace (if applicable)
+    // of an attribute without considering prefix and suffix.
+    llvm::SmallString<64> Spelling;
+    std::string Name = Spellings[I]->getValueAsString("Name");
+    std::string Variety = Spellings[I]->getValueAsString("Variety");
+
+    if (Variety == "GNU") {
+      Prefix = " __attribute__((";
+      Suffix = "))";
+    } else if (Variety == "CXX11") {
+      Prefix = " [[";
+      Suffix = "]]";
+      std::string Namespace = Spellings[I]->getValueAsString("Namespace");
+      if (Namespace != "") {
+        Spelling += Namespace;
+        Spelling += "::";
+      }
+    } else if (Variety == "Declspec") {
+      Prefix = " __declspec(";
+      Suffix = ")";
+    } else {
+      llvm_unreachable("Unkown attribute syntax variety!");
+    }
+
+    Spelling += Name;
+
+    OS <<
+      "  case " << I << " : {\n"
+      "    OS << \"" + Prefix.str() + Spelling.str();
+
+    if (Args.size()) OS << "(";
+    if (Spelling == "availability") {
+      writeAvailabilityValue(OS);
+    } else {
+      for (std::vector<Argument*>::const_iterator I = Args.begin(),
+           E = Args.end(); I != E; ++ I) {
+        if (I != Args.begin()) OS << ", ";
+        (*I)->writeValue(OS);
+      }
+    }
+
+    if (Args.size()) OS << ")";
+    OS << Suffix.str() + "\";\n";
+
+    OS <<
+      "    break;\n"
+      "  }\n";
+  }
+
+  // End of the switch statement.
+  OS << "}\n";
+  // End of the print function.
+  OS << "}\n\n";
+}
+
 namespace clang {
 
 // Emits the class definitions for attributes.
@@ -783,9 +859,12 @@
       (*ai)->writeCtorParameters(OS);
       OS << "\n";
     }
-    
+
+    OS << "              , ";
+    OS << "unsigned SI = 0\n";
+
     OS << "             )\n";
-    OS << "    : " << SuperName << "(attr::" << R.getName() << ", R)\n";
+    OS << "    : " << SuperName << "(attr::" << R.getName() << ", R, SI)\n";
 
     for (ai = Args.begin(); ai != ae; ++ai) {
       OS << "              , ";
@@ -841,7 +920,6 @@
       continue;
     
     std::vector<Record*> ArgRecords = R.getValueAsListOfDefs("Args");
-    std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
     std::vector<Argument*> Args;
     for (ri = ArgRecords.begin(), re = ArgRecords.end(); ri != re; ++ri)
       Args.push_back(createArgument(**ri, R.getName()));
@@ -858,24 +936,7 @@
     }
     OS << ");\n}\n\n";
 
-    OS << "void " << R.getName() << "Attr::printPretty("
-       << "raw_ostream &OS, const PrintingPolicy &Policy) const {\n";
-    if (Spellings.begin() != Spellings.end()) {
-      std::string Spelling = (*Spellings.begin())->getValueAsString("Name");
-      OS << "  OS << \" __attribute__((" << Spelling;
-      if (Args.size()) OS << "(";
-      if (Spelling == "availability") {
-        writeAvailabilityValue(OS);
-      } else {
-        for (ai = Args.begin(); ai != ae; ++ai) {
-          if (ai!=Args.begin()) OS <<", ";
-          (*ai)->writeValue(OS);
-        }
-      }
-      if (Args.size()) OS << ")";
-      OS << "))\";\n";
-    }
-    OS << "}\n\n";
+    writePrettyPrintFunction(R, Args, OS);
   }
 }
 
@@ -1044,6 +1105,64 @@
 
 }
 
+void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS) {
+  OS << "// This file is generated by TableGen. Do not edit it. \n\n";
+
+  OS <<
+    "  unsigned Index = 0;\n"
+    "  switch (AttrKind) {\n"
+    "  default:\n"
+    "    llvm_unreachable(\"Unknown attribute kind!\");\n"
+    "    break;\n";
+
+  std::vector<Record*> Attrs = Records.getAllDerivedDefinitions("Attr");
+  for (std::vector<Record*>::const_iterator I = Attrs.begin(), E = Attrs.end();
+       I != E; ++I) {
+    Record &R = **I;
+    // We only care about attributes that participate in Sema checking, so
+    // skip those attributes that are not able to make their way to Sema.
+    if (!R.getValueAsBit("SemaHandler"))
+      continue;
+
+    std::vector<Record*> Spellings = R.getValueAsListOfDefs("Spellings");
+    // Each distinct spelling yields an attribute kind.
+    if (R.getValueAsBit("DistinctSpellings")) {
+      for (unsigned I = 0; I < Spellings.size(); ++ I) {
+        OS <<
+          "  case AT_" << Spellings[I]->getValueAsString("Name") << ": \n"
+          "    Index = " << I << ";\n"
+          "  break;\n";
+      }
+    } else {
+      OS << "  case AT_" << R.getName() << " : {\n";
+      for (unsigned I = 0; I < Spellings.size(); ++ I) {
+        SmallString<16> Namespace;
+        if (Spellings[I]->getValueAsString("Variety") == "CXX11")
+          Namespace = Spellings[I]->getValueAsString("Namespace");
+        else
+          Namespace = "";
+
+        OS << "    if (Name == \""
+          << Spellings[I]->getValueAsString("Name") << "\" && "
+          << "SyntaxUsed == "
+          << StringSwitch<unsigned>(Spellings[I]->getValueAsString("Variety"))
+            .Case("GNU", 0)
+            .Case("CXX11", 1)
+            .Case("Declspec", 2)
+            .Default(0)
+          << " && Scope == \"" << Namespace << "\")\n"
+          << "        return " << I << ";\n";
+      }
+
+      OS << "    break;\n";
+      OS << "  }\n";
+    }
+  }
+
+  OS << "  }\n";
+  OS << "  return Index;\n";
+}
+
 // Emits the LateParsed property for attributes.
 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS) {
   OS << "// This file is generated by TableGen. Do not edit.\n\n";

Modified: cfe/trunk/utils/TableGen/TableGen.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGen.cpp?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGen.cpp (original)
+++ cfe/trunk/utils/TableGen/TableGen.cpp Thu Jan 24 10:46:58 2013
@@ -29,6 +29,7 @@
   GenClangAttrPCHRead,
   GenClangAttrPCHWrite,
   GenClangAttrSpellingList,
+  GenClangAttrSpellingListIndex,
   GenClangAttrLateParsedList,
   GenClangAttrTemplateInstantiate,
   GenClangAttrParsedAttrList,
@@ -70,6 +71,9 @@
                     clEnumValN(GenClangAttrSpellingList,
                                "gen-clang-attr-spelling-list",
                                "Generate a clang attribute spelling list"),
+                    clEnumValN(GenClangAttrSpellingListIndex,
+                               "gen-clang-attr-spelling-index",
+                               "Generate a clang attribute spelling index"),
                     clEnumValN(GenClangAttrLateParsedList,
                                "gen-clang-attr-late-parsed-list",
                                "Generate a clang attribute LateParsed list"),
@@ -144,6 +148,9 @@
   case GenClangAttrSpellingList:
     EmitClangAttrSpellingList(Records, OS);
     break;
+  case GenClangAttrSpellingListIndex:
+    EmitClangAttrSpellingListIndex(Records, OS);
+    break;
   case GenClangAttrLateParsedList:
     EmitClangAttrLateParsedList(Records, OS);
     break;

Modified: cfe/trunk/utils/TableGen/TableGenBackends.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/TableGenBackends.h?rev=173358&r1=173357&r2=173358&view=diff
==============================================================================
--- cfe/trunk/utils/TableGen/TableGenBackends.h (original)
+++ cfe/trunk/utils/TableGen/TableGenBackends.h Thu Jan 24 10:46:58 2013
@@ -35,6 +35,7 @@
 void EmitClangAttrPCHRead(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrPCHWrite(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrSpellingList(RecordKeeper &Records, raw_ostream &OS);
+void EmitClangAttrSpellingListIndex(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrLateParsedList(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrTemplateInstantiate(RecordKeeper &Records, raw_ostream &OS);
 void EmitClangAttrParsedAttrList(RecordKeeper &Records, raw_ostream &OS);





More information about the cfe-commits mailing list