Synchronize the representations of DeclarationName and Selector so
that bridging between the two is free. Saves ~4k of code size,
although I don't see any measurable performance difference
(unfortunately).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@156187 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h
index 1548a89..f359499 100644
--- a/include/clang/AST/DeclarationName.h
+++ b/include/clang/AST/DeclarationName.h
@@ -58,11 +58,14 @@
 private:
   /// StoredNameKind - The kind of name that is actually stored in the
   /// upper bits of the Ptr field. This is only used internally.
+  ///
+  /// Note: The entries here are synchronized with the entries in Selector,
+  /// for efficient translation between the two.
   enum StoredNameKind {
     StoredIdentifier = 0,
-    StoredObjCZeroArgSelector,
-    StoredObjCOneArgSelector,
-    StoredDeclarationNameExtra,
+    StoredObjCZeroArgSelector = 0x01,
+    StoredObjCOneArgSelector = 0x02,
+    StoredDeclarationNameExtra = 0x03,
     PtrMask = 0x03
   };
 
@@ -174,7 +177,7 @@
   }
 
   // Construct a declaration name from an Objective-C selector.
-  DeclarationName(Selector Sel);
+  DeclarationName(Selector Sel) : Ptr(Sel.InfoPtr) { }
 
   /// getUsingDirectiveName - Return name for all using-directives.
   static DeclarationName getUsingDirectiveName();
@@ -257,7 +260,13 @@
 
   /// getObjCSelector - Get the Objective-C selector stored in this
   /// declaration name.
-  Selector getObjCSelector() const;
+  Selector getObjCSelector() const {
+    assert((getNameKind() == ObjCZeroArgSelector ||
+            getNameKind() == ObjCOneArgSelector ||
+            getNameKind() == ObjCMultiArgSelector ||
+            Ptr == 0) && "Not a selector!");
+    return Selector(Ptr);
+  }
 
   /// getFETokenInfo/setFETokenInfo - The language front-end is
   /// allowed to associate arbitrary metadata with some kinds of
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index cc0080b..d79e28b 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -574,9 +574,10 @@
   friend class Diagnostic;
 
   enum IdentifierInfoFlag {
-    // MultiKeywordSelector = 0.
+    // Empty selector = 0.
     ZeroArg  = 0x1,
     OneArg   = 0x2,
+    MultiArg = 0x3,
     ArgFlags = ZeroArg|OneArg
   };
   uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo.
@@ -590,13 +591,18 @@
   Selector(MultiKeywordSelector *SI) {
     InfoPtr = reinterpret_cast<uintptr_t>(SI);
     assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo");
+    InfoPtr |= MultiArg;
   }
 
   IdentifierInfo *getAsIdentifierInfo() const {
-    if (getIdentifierInfoFlag())
+    if (getIdentifierInfoFlag() < MultiArg)
       return reinterpret_cast<IdentifierInfo *>(InfoPtr & ~ArgFlags);
     return 0;
   }
+  MultiKeywordSelector *getMultiKeywordSelector() const {
+    return reinterpret_cast<MultiKeywordSelector *>(InfoPtr & ~ArgFlags);
+  }
+  
   unsigned getIdentifierInfoFlag() const {
     return InfoPtr & ArgFlags;
   }
diff --git a/lib/AST/DeclarationName.cpp b/lib/AST/DeclarationName.cpp
index 895cd51..9eadf32 100644
--- a/lib/AST/DeclarationName.cpp
+++ b/lib/AST/DeclarationName.cpp
@@ -135,33 +135,6 @@
 
 } // end namespace clang
 
-DeclarationName::DeclarationName(Selector Sel) {
-  if (!Sel.getAsOpaquePtr()) {
-    Ptr = 0;
-    return;
-  }
-
-  switch (Sel.getNumArgs()) {
-  case 0:
-    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
-    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
-    Ptr |= StoredObjCZeroArgSelector;
-    break;
-
-  case 1:
-    Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());
-    assert((Ptr & PtrMask) == 0 && "Improperly aligned IdentifierInfo");
-    Ptr |= StoredObjCOneArgSelector;
-    break;
-
-  default:
-    Ptr = Sel.InfoPtr & ~Selector::ArgFlags;
-    assert((Ptr & PtrMask) == 0 && "Improperly aligned MultiKeywordSelector");
-    Ptr |= StoredDeclarationNameExtra;
-    break;
-  }
-}
-
 DeclarationName::NameKind DeclarationName::getNameKind() const {
   switch (getStoredNameKind()) {
   case StoredIdentifier:          return Identifier;
@@ -305,24 +278,6 @@
     return 0;
 }
 
-Selector DeclarationName::getObjCSelector() const {
-  switch (getNameKind()) {
-  case ObjCZeroArgSelector:
-    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 0);
-
-  case ObjCOneArgSelector:
-    return Selector(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask), 1);
-
-  case ObjCMultiArgSelector:
-    return Selector(reinterpret_cast<MultiKeywordSelector *>(Ptr & ~PtrMask));
-
-  default:
-    break;
-  }
-
-  return Selector();
-}
-
 void *DeclarationName::getFETokenInfoAsVoidSlow() const {
   switch (getNameKind()) {
   case Identifier:
diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp
index 43899f0..c7e83f4 100644
--- a/lib/Basic/IdentifierTable.cpp
+++ b/lib/Basic/IdentifierTable.cpp
@@ -335,22 +335,22 @@
 
 unsigned Selector::getNumArgs() const {
   unsigned IIF = getIdentifierInfoFlag();
-  if (IIF == ZeroArg)
+  if (IIF <= ZeroArg)
     return 0;
   if (IIF == OneArg)
     return 1;
-  // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
-  MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+  // We point to a MultiKeywordSelector.
+  MultiKeywordSelector *SI = getMultiKeywordSelector();
   return SI->getNumArgs();
 }
 
 IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
-  if (getIdentifierInfoFlag()) {
+  if (getIdentifierInfoFlag() < MultiArg) {
     assert(argIndex == 0 && "illegal keyword index");
     return getAsIdentifierInfo();
   }
-  // We point to a MultiKeywordSelector (pointer doesn't contain any flags).
-  MultiKeywordSelector *SI = reinterpret_cast<MultiKeywordSelector *>(InfoPtr);
+  // We point to a MultiKeywordSelector.
+  MultiKeywordSelector *SI = getMultiKeywordSelector();
   return SI->getIdentifierInfoForSlot(argIndex);
 }
 
@@ -375,7 +375,7 @@
   if (InfoPtr == 0)
     return "<null selector>";
 
-  if (InfoPtr & ArgFlags) {
+  if (getIdentifierInfoFlag() < MultiArg) {
     IdentifierInfo *II = getAsIdentifierInfo();
 
     // If the number of arguments is 0 then II is guaranteed to not be null.
@@ -388,8 +388,8 @@
     return II->getName().str() + ":";
   }
 
-  // We have a multiple keyword selector (no embedded flags).
-  return reinterpret_cast<MultiKeywordSelector *>(InfoPtr)->getName();
+  // We have a multiple keyword selector.
+  return getMultiKeywordSelector()->getName();
 }
 
 /// Interpreting the given string using the normal CamelCase