]> granicus.if.org Git - clang/commitdiff
First step to fixing a long lived layering violation: this
authorChris Lattner <sabre@nondot.org>
Sun, 7 Oct 2007 07:09:52 +0000 (07:09 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 7 Oct 2007 07:09:52 +0000 (07:09 +0000)
moves the MacroInfo pointer to a side hash table (which currently
lives in IdentifierTable.cpp).  This removes a pointer from
Identifier info, but doesn't shrink it, as it requires a new bit
be added.  This strange approach with the 'hasmacro' bit is needed
to not lose preprocessor performance.

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

Lex/IdentifierTable.cpp
include/clang/Lex/IdentifierTable.h

index fd64dec0ae40ad422b589cb3e018fc8aa69e5bde..b1c2c63f233fe6e756b85cfe2a3553039fe74c64 100644 (file)
 #include "llvm/ADT/DenseMap.h"
 using namespace clang;
 
+static llvm::DenseMap<const IdentifierInfo*, MacroInfo*> Macros;
+
+MacroInfo *IdentifierInfo::getMacroInfoInternal() const {
+  return Macros[this];
+}
+void IdentifierInfo::setMacroInfo(MacroInfo *I) {
+  if (I == 0) {
+    if (HasMacro) {
+      Macros.erase(this);
+      HasMacro = false;
+    }
+  } else {
+    Macros[this] = I;
+    HasMacro = true;
+  }
+}
+
+
 //===----------------------------------------------------------------------===//
 // Token Implementation
 //===----------------------------------------------------------------------===//
@@ -40,11 +58,11 @@ tok::ObjCKeywordKind Token::getObjCKeywordID() const {
 //===----------------------------------------------------------------------===//
 
 IdentifierInfo::IdentifierInfo() {
-  Macro = 0;
   TokenID = tok::identifier;
   PPID = tok::pp_not_keyword;
   ObjCID = tok::objc_not_keyword;
   BuiltinID = 0;
+  HasMacro = false;
   IsExtension = false;
   IsPoisoned = false;
   IsOtherTargetMacro = false;
@@ -54,7 +72,8 @@ IdentifierInfo::IdentifierInfo() {
 }
 
 IdentifierInfo::~IdentifierInfo() {
-  delete Macro;
+  if (MacroInfo *Macro = getMacroInfo())
+    delete Macro;
 }
 
 //===----------------------------------------------------------------------===//
index 132f71551a8f24717d09a2ec38102dc2c0a694ff..ed9f971f45339d9fde3d3a31cb29a6a5c6490f45 100644 (file)
@@ -37,11 +37,11 @@ namespace clang {
 /// variable or function name).  The preprocessor keeps this information in a
 /// set, and all tok::identifier tokens have a pointer to one of these.  
 class IdentifierInfo {
-  MacroInfo *Macro;                // Set if this identifier is #define'd.
   tok::TokenKind TokenID      : 8; // Front-end token ID or tok::identifier.
+  unsigned BuiltinID          : 9; // ID if this is a builtin (__builtin_inf).
   tok::PPKeywordKind PPID     : 5; // ID for preprocessor command like #'ifdef'.
   tok::ObjCKeywordKind ObjCID : 5; // ID for objc @ keyword like @'protocol'.
-  unsigned BuiltinID          : 9; // ID if this is a builtin (__builtin_inf).
+  bool HasMacro               : 1; // True if there is a #define for this.
   bool IsExtension            : 1; // True if identifier is a lang extension.
   bool IsPoisoned             : 1; // True if identifier is poisoned.
   bool IsOtherTargetMacro     : 1; // True if ident is macro on another target.
@@ -49,6 +49,7 @@ class IdentifierInfo {
   bool IsNonPortableBuiltin   : 1; // True if builtin varies across targets.
   void *FETokenInfo;               // Managed by the language front-end.
   IdentifierInfo(const IdentifierInfo&);  // NONCOPYABLE.
+  void operator=(const IdentifierInfo&);  // NONASSIGNABLE.
 public:
   IdentifierInfo();
   ~IdentifierInfo();
@@ -72,8 +73,10 @@ public:
   
   /// getMacroInfo - Return macro information about this identifier, or null if
   /// it is not a macro.
-  MacroInfo *getMacroInfo() const { return Macro; }
-  void setMacroInfo(MacroInfo *I) { Macro = I; }
+  MacroInfo *getMacroInfo() const {
+    return HasMacro ? getMacroInfoInternal() : 0;
+  }
+  void setMacroInfo(MacroInfo *I);
   
   /// get/setTokenID - If this is a source-language token (e.g. 'for'), this API
   /// can be used to cause the lexer to map identifiers to source-language
@@ -137,6 +140,8 @@ public:
   template<typename T>
   T *getFETokenInfo() const { return static_cast<T*>(FETokenInfo); }
   void setFETokenInfo(void *T) { FETokenInfo = T; }
+private:
+  MacroInfo *getMacroInfoInternal() const;
 };
 
 /// IdentifierTable - This table implements an efficient mapping from strings to
@@ -274,6 +279,9 @@ public:
 
 }  // end namespace clang
 
+
+/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
+/// DenseSets.
 namespace llvm {
 template <>
 struct DenseMapInfo<clang::Selector> {