From 6e40f59ed4491f87e5197aa3814dc4dcc9f5644b Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron@aaronballman.com>
Date: Thu, 21 Nov 2013 00:28:23 +0000
Subject: [PATCH] Implemented DefaultIntArgument in the table generator and
 start using it in semantic analysis. Removes some magic numbers.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@195287 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/clang/Basic/Attr.td         |  4 ++--
 lib/Sema/SemaDeclAttr.cpp           |  8 ++++----
 utils/TableGen/ClangAttrEmitter.cpp | 24 ++++++++++++++++++++++--
 3 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 27a27e33a78..bcca1d25ef7 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -321,7 +321,7 @@ def Const : InheritableAttr {
 
 def Constructor : InheritableAttr {
   let Spellings = [GNU<"constructor">, CXX11<"gnu", "constructor">];
-  let Args = [IntArgument<"Priority", 1>];
+  let Args = [DefaultIntArgument<"Priority", 65535>];
 }
 
 def CUDAConstant : InheritableAttr {
@@ -377,7 +377,7 @@ def Deprecated : InheritableAttr {
 
 def Destructor : InheritableAttr {
   let Spellings = [GNU<"destructor">, CXX11<"gnu", "destructor">];
-  let Args = [IntArgument<"Priority", 1>];
+  let Args = [DefaultIntArgument<"Priority", 65535>];
 }
 
 def ExtVectorType : Attr {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 16725675a41..23395cacfec 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -2035,7 +2035,7 @@ static void handleConstructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     return;
   }
 
-  int priority = 65535; // FIXME: Do not hardcode such constants.
+  int priority = ConstructorAttr::DefaultPriority;
   if (Attr.getNumArgs() > 0) {
     Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
@@ -2067,7 +2067,7 @@ static void handleDestructorAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     return;
   }
 
-  int priority = 65535; // FIXME: Do not hardcode such constants.
+  int priority = DestructorAttr::DefaultPriority;
   if (Attr.getNumArgs() > 0) {
     Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
@@ -2562,7 +2562,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     return;
   }
 
-  unsigned sentinel = 0;
+  unsigned sentinel = (unsigned)SentinelAttr::DefaultSentinel;
   if (Attr.getNumArgs() > 0) {
     Expr *E = Attr.getArgAsExpr(0);
     llvm::APSInt Idx(32);
@@ -2583,7 +2583,7 @@ static void handleSentinelAttr(Sema &S, Decl *D, const AttributeList &Attr) {
     sentinel = Idx.getZExtValue();
   }
 
-  unsigned nullPos = 0;
+  unsigned nullPos = (unsigned)SentinelAttr::DefaultNullPos;
   if (Attr.getNumArgs() > 1) {
     Expr *E = Attr.getArgAsExpr(1);
     llvm::APSInt Idx(32);
diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp
index 653d7b79e28..71eaf131dd3 100644
--- a/utils/TableGen/ClangAttrEmitter.cpp
+++ b/utils/TableGen/ClangAttrEmitter.cpp
@@ -222,6 +222,22 @@ namespace {
     }
   };
 
+  class DefaultSimpleArgument : public SimpleArgument {
+    int64_t Default;
+
+  public:
+    DefaultSimpleArgument(Record &Arg, StringRef Attr,
+                          std::string T, int64_t Default)
+      : SimpleArgument(Arg, Attr, T), Default(Default) {}
+
+    void writeAccessors(raw_ostream &OS) const {
+      SimpleArgument::writeAccessors(OS);
+
+      OS << "\n\n  static const " << getType() << " Default" << getUpperName()
+         << " = " << Default << ";";
+    }
+  };
+
   class StringArgument : public Argument {
   public:
     StringArgument(Record &Arg, StringRef Attr)
@@ -871,6 +887,9 @@ static Argument *createArgument(Record &Arg, StringRef Attr,
     Ptr = new SimpleArgument(Arg, Attr, "IdentifierInfo *");
   else if (ArgName == "BoolArgument") Ptr = new SimpleArgument(Arg, Attr, 
                                                                "bool");
+  else if (ArgName == "DefaultIntArgument")
+    Ptr = new DefaultSimpleArgument(Arg, Attr, "int",
+                                    Arg.getValueAsInt("Default"));
   else if (ArgName == "IntArgument") Ptr = new SimpleArgument(Arg, Attr, "int");
   else if (ArgName == "StringArgument") Ptr = new StringArgument(Arg, Attr);
   else if (ArgName == "TypeArgument") Ptr = new TypeArgument(Arg, Attr);
@@ -888,9 +907,10 @@ static Argument *createArgument(Record &Arg, StringRef Attr,
     Ptr = new VersionArgument(Arg, Attr);
 
   if (!Ptr) {
+    // Search in reverse order so that the most-derived type is handled first.
     std::vector<Record*> Bases = Search->getSuperClasses();
-    for (std::vector<Record*>::iterator i = Bases.begin(), e = Bases.end();
-         i != e; ++i) {
+    for (std::vector<Record*>::reverse_iterator i = Bases.rbegin(),
+         e = Bases.rend(); i != e; ++i) {
       Ptr = createArgument(Arg, Attr, *i);
       if (Ptr)
         break;
-- 
GitLab