]> granicus.if.org Git - clang/commitdiff
[Sema][Attr]Fix alignment attribute printing.
authorMichael Han <fragmentshaders@gmail.com>
Fri, 1 Feb 2013 01:19:17 +0000 (01:19 +0000)
committerMichael Han <fragmentshaders@gmail.com>
Fri, 1 Feb 2013 01:19:17 +0000 (01:19 +0000)
Remove "IsMSDeclspec" argument from Align attribute since the arguments in Attr.td should
only model those appear in source code. Introduce attribute Accessor, and teach TableGen
to generate syntax kind accessors for Align attribute, and use those accessors to decide
if an alignment attribute is a declspec attribute.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174133 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/Attr.td
include/clang/Sema/Sema.h
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaTemplateInstantiateDecl.cpp
test/Sema/attr-print.c
test/SemaCXX/attr-print.cpp
test/SemaCXX/cxx11-attr-print.cpp
utils/TableGen/ClangAttrEmitter.cpp

index 52ebbb41db85ec8815f6b000eaf58f9ce2a85c02..6d707562868a89786d31d9e87817d381a1305455 100644 (file)
@@ -93,6 +93,11 @@ class CXX11<string namespace, string name> : Spelling<name, "CXX11"> {
 }
 class Keyword<string name> : Spelling<name, "Keyword">;
 
+class Accessor<string name, list<Spelling> spellings> {
+  string Name = name;
+  list<Spelling> Spellings = spellings;
+}
+
 class Attr {
   // The various ways in which an attribute can be spelled in source
   list<Spelling> Spellings;
@@ -100,8 +105,10 @@ class Attr {
   list<AttrSubject> Subjects;
   // The arguments allowed on an attribute
   list<Argument> Args = [];
-  // Set to true for attributes with arguments which require delayed parsing. 
-  bit LateParsed = 0;  
+  // Accessors which should be generated for the attribute.
+  list<Accessor> Accessors = [];
+  // Set to true for attributes with arguments which require delayed parsing.
+  bit LateParsed = 0;
   // Set to false to prevent an attribute from being propagated from a template
   // to the instantiation.
   bit Clone = 1;
@@ -115,7 +122,7 @@ class Attr {
   bit Ignored = 0;
   // Set to true if each of the spellings is a distinct attribute.
   bit DistinctSpellings = 0;
-  // Any additional text that should be included verbatim in the class.  
+  // Any additional text that should be included verbatim in the class.
   code AdditionalMembers = [{}];
 }
 
@@ -140,7 +147,7 @@ class IgnoredAttr : Attr {
 def AddressSpace : Attr {
   let Spellings = [GNU<"address_space">];
   let Args = [IntArgument<"AddressSpace">];
-  let ASTNode = 0;  
+  let ASTNode = 0;
 }
 
 def Alias : InheritableAttr {
@@ -152,7 +159,11 @@ def Aligned : InheritableAttr {
   let Spellings = [GNU<"aligned">, Declspec<"align">, CXX11<"gnu", "aligned">,
                    Keyword<"alignas">, Keyword<"_Alignas">];
   let Subjects = [NonBitField, NormalVar, Tag];
-  let Args = [AlignedArgument<"Alignment">, BoolArgument<"IsMSDeclSpec">];
+  let Args = [AlignedArgument<"Alignment">];
+  let Accessors = [Accessor<"isGNU", [GNU<"aligned">, CXX11<"gnu","aligned">]>,
+                   Accessor<"isAlignas",
+                   [Keyword<"alignas">, Keyword<"_Alignas">]>,
+                   Accessor<"isDeclspec",[Declspec<"align">]>];
 }
 
 def AlignMac68k : InheritableAttr {
index 47b2de8bd1077eb9ea381ef179f5797df53a122d..4a27792092937bbfbbd7378d35100567cb33fb8e 100644 (file)
@@ -6531,9 +6531,9 @@ public:
 
   /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
   void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
-                      bool isDeclSpec, unsigned SpellingListIndex);
+                      unsigned SpellingListIndex);
   void AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *T,
-                      bool isDeclSpec, unsigned SpellingListIndex);
+                      unsigned SpellingListIndex);
 
   /// \brief The kind of conversion being performed.
   enum CheckedConversionKind {
index cb6e898020ce03bfe79c8e437d98f278ab3d9711..8500bff6bcbdbb4e6159fa9e95e5a0c6501f2a68 100644 (file)
@@ -3315,30 +3315,28 @@ static void handleAlignedAttr(Sema &S, Decl *D, const AttributeList &Attr) {
   //        ignored.
 
   if (Attr.getNumArgs() == 0) {
-    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context, 
-               true, 0, Attr.isDeclspecAttribute(),
-               Attr.getAttributeSpellingListIndex()));
+    D->addAttr(::new (S.Context) AlignedAttr(Attr.getRange(), S.Context,
+               true, 0, Attr.getAttributeSpellingListIndex()));
     return;
   }
 
-  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0), 
-                   Attr.isDeclspecAttribute(),
+  S.AddAlignedAttr(Attr.getRange(), D, Attr.getArg(0),
                    Attr.getAttributeSpellingListIndex());
 }
 
-void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E, 
-                          bool isDeclSpec, unsigned SpellingListIndex) {
+void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
+                          unsigned SpellingListIndex) {
   // FIXME: Handle pack-expansions here.
   if (DiagnoseUnexpandedParameterPack(E))
     return;
 
   if (E->isTypeDependent() || E->isValueDependent()) {
     // Save dependent expressions in the AST to be instantiated.
-    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E, 
-                                           isDeclSpec, SpellingListIndex));
+    D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, E,
+                                           SpellingListIndex));
     return;
   }
-  
+
   SourceLocation AttrLoc = AttrRange.getBegin();
   // FIXME: Cache the number on the Attr object?
   llvm::APSInt Alignment(32);
@@ -3353,26 +3351,30 @@ void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
       << E->getSourceRange();
     return;
   }
-  if (isDeclSpec) {
+
+  AlignedAttr *Attr = ::new (Context) AlignedAttr(AttrRange, Context, true,
+                                                  ICE.take(),
+                                                  SpellingListIndex);
+
+  if (Attr->isDeclspec()) {
     // We've already verified it's a power of 2, now let's make sure it's
     // 8192 or less.
     if (Alignment.getZExtValue() > 8192) {
-      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192) 
+      Diag(AttrLoc, diag::err_attribute_aligned_greater_than_8192)
         << E->getSourceRange();
       return;
     }
   }
 
-  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, true, ICE.take(), 
-                                         isDeclSpec, SpellingListIndex));
+  D->addAttr(Attr);
 }
 
-void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS, 
-                          bool isDeclSpec, unsigned SpellingListIndex) {
+void Sema::AddAlignedAttr(SourceRange AttrRange, Decl *D, TypeSourceInfo *TS,
+                          unsigned SpellingListIndex) {
   // FIXME: Cache the number on the Attr object if non-dependent?
   // FIXME: Perform checking of type validity
-  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS, 
-                                         isDeclSpec, SpellingListIndex));
+  D->addAttr(::new (Context) AlignedAttr(AttrRange, Context, false, TS,
+                                         SpellingListIndex));
   return;
 }
 
index f5405ff383b61e2b63c9fae85a675f6af2c0a4e9..c146e9dd4494f1ca4cb7293feedd8e8cf2900b58 100644 (file)
@@ -79,8 +79,7 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
           ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(),
                                         TemplateArgs);
           if (!Result.isInvalid())
-            AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(), 
-                           Aligned->getIsMSDeclSpec(),
+            AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>(),
                            Aligned->getSpellingListIndex());
         } else {
           TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(),
@@ -89,7 +88,6 @@ void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs,
                                              DeclarationName());
           if (Result)
             AddAlignedAttr(Aligned->getLocation(), New, Result,
-                           Aligned->getIsMSDeclSpec(),
                            Aligned->getSpellingListIndex());
         }
         continue;
index b523c18cab8c53966604f1eeefe52cd074273232..2659508e562580f292bf334d71a3cb7d6e0cc3e9 100644 (file)
@@ -1,13 +1,10 @@
 // RUN: %clang_cc1 %s -ast-print -fms-extensions | FileCheck %s
 
-// FIXME: we need to fix the "BoolArgument<"IsMSDeclSpec">"
-// hack in Attr.td for attribute "Aligned".
-
-// CHECK: int x __attribute__((aligned(4, 0)));
+// CHECK: int x __attribute__((aligned(4)));
 int x __attribute__((aligned(4)));
 
 // FIXME: Print this at a valid location for a __declspec attr.
-// CHECK: int y __declspec(align(4, 1));
+// CHECK: int y __declspec(align(4));
 __declspec(align(4)) int y;
 
 // CHECK: void foo() __attribute__((const));
index c7335c5e3bf8774f4c1d92cfd7e02d671e2cb7cc..2e7478904f1246b81735eba372eec9023fe14b2d 100644 (file)
@@ -1,12 +1,10 @@
 // RUN: %clang_cc1 %s -ast-print -fms-extensions | FileCheck %s
 
-// FIXME: align attribute print
-
-// CHECK: int x __attribute__((aligned(4, 0)));
+// CHECK: int x __attribute__((aligned(4)));
 int x __attribute__((aligned(4)));
 
 // FIXME: Print this at a valid location for a __declspec attr.
-// CHECK: int y __declspec(align(4, 1));
+// CHECK: int y __declspec(align(4));
 __declspec(align(4)) int y;
 
 // CHECK: void foo() __attribute__((const));
index b4f5859409bfc06bdee3bba30ef40475372fd3c7..336e7b3f7677f509e3311f71795c2d7ca6b1d0cc 100644 (file)
@@ -1,14 +1,13 @@
 // RUN: %clang_cc1 -std=c++11 -ast-print -fms-extensions %s | FileCheck %s
-// FIXME: align attribute print
-
-// CHECK: int x __attribute__((aligned(4, 0)));
+//
+// CHECK: int x __attribute__((aligned(4)));
 int x __attribute__((aligned(4)));
 
 // FIXME: Print this at a valid location for a __declspec attr.
-// CHECK: int y __declspec(align(4, 1));
+// CHECK: int y __declspec(align(4));
 __declspec(align(4)) int y;
 
-// CHECK: gnu::aligned(4, 0)]];
+// CHECK: gnu::aligned(4)]];
 int z [[gnu::aligned(4)]];
 
 // CHECK: __attribute__((deprecated("warning")));
@@ -17,10 +16,10 @@ int a __attribute__((deprecated("warning")));
 // CHECK: gnu::deprecated("warning")]];
 int b [[gnu::deprecated("warning")]];
 
-// CHECK: int cxx11_alignas alignas(4, 0);
+// CHECK: int cxx11_alignas alignas(4);
 alignas(4) int cxx11_alignas;
 
-// CHECK: int c11_alignas _Alignas(alignof(int), 0);
+// CHECK: int c11_alignas _Alignas(alignof(int));
 _Alignas(int) int c11_alignas;
 
 // CHECK: void foo() __attribute__((const));
index 65a009c214eb345c837385119e33dce81d091c65..544ec29faba598461c7f1e46d10fd5f2f1f15c1a 100644 (file)
@@ -829,6 +829,51 @@ static void writePrettyPrintFunction(Record &R, std::vector<Argument*> &Args,
   OS << "}\n\n";
 }
 
+/// \brief Return the index of a spelling in a spelling list.
+static unsigned getSpellingListIndex(const std::vector<Record*> &SpellingList,
+                                     const Record &Spelling) {
+  assert(SpellingList.size() && "Spelling list is empty!");
+
+  for (unsigned Index = 0; Index < SpellingList.size(); ++Index) {
+    Record *S = SpellingList[Index];
+    if (S->getValueAsString("Variety") != Spelling.getValueAsString("Variety"))
+      continue;
+    if (S->getValueAsString("Variety") == "CXX11" &&
+        S->getValueAsString("Namespace") !=
+        Spelling.getValueAsString("Namespace"))
+      continue;
+    if (S->getValueAsString("Name") != Spelling.getValueAsString("Name"))
+      continue;
+
+    return Index;
+  }
+
+  llvm_unreachable("Unknown spelling!");
+}
+
+static void writeAttrAccessorDefinition(Record &R, raw_ostream &OS) {
+  std::vector<Record*> Accessors = R.getValueAsListOfDefs("Accessors");
+  for (std::vector<Record*>::const_iterator I = Accessors.begin(),
+       E = Accessors.end(); I != E; ++I) {
+    Record *Accessor = *I;
+    std::string Name = Accessor->getValueAsString("Name");
+    std::vector<Record*> Spellings = Accessor->getValueAsListOfDefs(
+      "Spellings");
+    std::vector<Record*> SpellingList = R.getValueAsListOfDefs("Spellings");
+    assert(SpellingList.size() &&
+           "Attribute with empty spelling list can't have accessors!");
+
+    OS << "  bool " << Name << "() const { return SpellingListIndex == ";
+    for (unsigned Index = 0; Index < Spellings.size(); ++Index) {
+      OS << getSpellingListIndex(SpellingList, *Spellings[Index]);
+      if (Index != Spellings.size() -1)
+        OS << " ||\n    SpellingListIndex == ";
+      else
+        OS << "; }\n";
+    }
+  }
+}
+
 namespace clang {
 
 // Emits the class definitions for attributes.
@@ -903,6 +948,8 @@ void EmitClangAttrClass(RecordKeeper &Records, raw_ostream &OS) {
     OS << "  virtual void printPretty(raw_ostream &OS,\n"
        << "                           const PrintingPolicy &Policy) const;\n";
 
+    writeAttrAccessorDefinition(R, OS);
+
     for (ai = Args.begin(); ai != ae; ++ai) {
       (*ai)->writeAccessors(OS);
       OS << "\n\n";