#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
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
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;
}
IdentifierInfo::~IdentifierInfo() {
- delete Macro;
+ if (MacroInfo *Macro = getMacroInfo())
+ delete Macro;
}
//===----------------------------------------------------------------------===//
/// 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.
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();
/// 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
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
} // end namespace clang
+
+/// Define DenseMapInfo so that Selectors can be used as keys in DenseMap and
+/// DenseSets.
namespace llvm {
template <>
struct DenseMapInfo<clang::Selector> {