2008-04-11 15:06:57 +08:00
|
|
|
//===- IdentifierResolver.h - Lexical Scope Name lookup ---------*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2008-04-12 09:50:47 +08:00
|
|
|
// This file defines the IdentifierResolver class, which is used for lexical
|
2008-11-18 04:34:05 +08:00
|
|
|
// scoped lookup, based on declaration names.
|
2008-04-11 15:06:57 +08:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#ifndef LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
|
|
|
|
#define LLVM_CLANG_AST_SEMA_IDENTIFIERRESOLVER_H
|
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
#include "clang/Basic/IdentifierTable.h"
|
|
|
|
#include "clang/Parse/Scope.h"
|
|
|
|
#include "clang/AST/Decl.h"
|
2008-11-18 04:34:05 +08:00
|
|
|
#include "clang/AST/DeclarationName.h"
|
2008-06-25 07:08:34 +08:00
|
|
|
#include "clang/AST/DeclCXX.h"
|
2008-05-10 07:39:43 +08:00
|
|
|
|
2008-04-11 15:06:57 +08:00
|
|
|
namespace clang {
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// IdentifierResolver - Keeps track of shadowed decls on enclosing
|
|
|
|
/// scopes. It manages the shadowing chains of declaration names and
|
|
|
|
/// implements efficent decl lookup based on a declaration name.
|
2008-04-11 15:06:57 +08:00
|
|
|
class IdentifierResolver {
|
2008-05-10 07:39:43 +08:00
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// IdDeclInfo - Keeps track of information about decls associated
|
|
|
|
/// to a particular declaration name. IdDeclInfos are lazily
|
|
|
|
/// constructed and assigned to a declaration name the first time a
|
|
|
|
/// decl with that declaration name is shadowed in some scope.
|
2008-05-10 07:39:43 +08:00
|
|
|
class IdDeclInfo {
|
|
|
|
public:
|
|
|
|
typedef llvm::SmallVector<NamedDecl*, 2> DeclsTy;
|
|
|
|
|
|
|
|
inline DeclsTy::iterator decls_begin() { return Decls.begin(); }
|
|
|
|
inline DeclsTy::iterator decls_end() { return Decls.end(); }
|
|
|
|
|
2009-01-06 03:45:36 +08:00
|
|
|
void AddDecl(NamedDecl *D) { Decls.push_back(D); }
|
2008-05-10 07:39:43 +08:00
|
|
|
|
|
|
|
/// AddShadowed - Add a decl by putting it directly above the 'Shadow' decl.
|
|
|
|
/// Later lookups will find the 'Shadow' decl first. The 'Shadow' decl must
|
|
|
|
/// be already added to the scope chain and must be in the same context as
|
|
|
|
/// the decl that we want to add.
|
2008-09-10 03:28:27 +08:00
|
|
|
void AddShadowed(NamedDecl *D, NamedDecl *Shadow);
|
2008-05-10 07:39:43 +08:00
|
|
|
|
|
|
|
/// RemoveDecl - Remove the decl from the scope chain.
|
|
|
|
/// The decl must already be part of the decl chain.
|
2008-09-10 03:28:27 +08:00
|
|
|
void RemoveDecl(NamedDecl *D);
|
2008-05-10 07:39:43 +08:00
|
|
|
|
2009-03-02 08:19:53 +08:00
|
|
|
/// Replaces the Old declaration with the New declaration. If the
|
|
|
|
/// replacement is successful, returns true. If the old
|
|
|
|
/// declaration was not found, returns false.
|
|
|
|
bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
|
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
private:
|
|
|
|
DeclsTy Decls;
|
|
|
|
};
|
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
public:
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// iterator - Iterate over the decls of a specified declaration name.
|
2008-07-18 01:49:50 +08:00
|
|
|
/// It will walk or not the parent declaration contexts depending on how
|
|
|
|
/// it was instantiated.
|
|
|
|
class iterator {
|
2008-12-24 05:05:05 +08:00
|
|
|
public:
|
|
|
|
typedef NamedDecl * value_type;
|
|
|
|
typedef NamedDecl * reference;
|
|
|
|
typedef NamedDecl * pointer;
|
|
|
|
typedef std::input_iterator_tag iterator_category;
|
|
|
|
typedef std::ptrdiff_t difference_type;
|
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
/// Ptr - There are 3 forms that 'Ptr' represents:
|
|
|
|
/// 1) A single NamedDecl. (Ptr & 0x1 == 0)
|
|
|
|
/// 2) A IdDeclInfo::DeclsTy::iterator that traverses only the decls of the
|
|
|
|
/// same declaration context. (Ptr & 0x3 == 0x1)
|
|
|
|
/// 3) A IdDeclInfo::DeclsTy::iterator that traverses the decls of parent
|
|
|
|
/// declaration contexts too. (Ptr & 0x3 == 0x3)
|
2008-05-10 07:39:43 +08:00
|
|
|
uintptr_t Ptr;
|
2008-07-18 01:49:50 +08:00
|
|
|
typedef IdDeclInfo::DeclsTy::iterator BaseIter;
|
2008-05-10 07:39:43 +08:00
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
/// A single NamedDecl. (Ptr & 0x1 == 0)
|
|
|
|
iterator(NamedDecl *D) {
|
2008-05-10 07:39:43 +08:00
|
|
|
Ptr = reinterpret_cast<uintptr_t>(D);
|
2008-07-18 01:49:50 +08:00
|
|
|
assert((Ptr & 0x1) == 0 && "Invalid Ptr!");
|
2008-05-10 07:39:43 +08:00
|
|
|
}
|
2008-07-18 01:49:50 +08:00
|
|
|
/// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
|
|
|
|
/// contexts depending on 'LookInParentCtx'.
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
iterator(BaseIter I) {
|
2008-07-18 01:49:50 +08:00
|
|
|
Ptr = reinterpret_cast<uintptr_t>(I) | 0x1;
|
2008-05-10 07:39:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool isIterator() const { return (Ptr & 0x1); }
|
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
BaseIter getIterator() const {
|
|
|
|
assert(isIterator() && "Ptr not an iterator!");
|
|
|
|
return reinterpret_cast<BaseIter>(Ptr & ~0x3);
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
friend class IdentifierResolver;
|
|
|
|
public:
|
2008-08-01 18:20:48 +08:00
|
|
|
iterator() : Ptr(0) {}
|
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
NamedDecl *operator*() const {
|
|
|
|
if (isIterator())
|
|
|
|
return *getIterator();
|
|
|
|
else
|
|
|
|
return reinterpret_cast<NamedDecl*>(Ptr);
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
bool operator==(const iterator &RHS) const {
|
2008-05-10 07:39:43 +08:00
|
|
|
return Ptr == RHS.Ptr;
|
|
|
|
}
|
2008-07-18 01:49:50 +08:00
|
|
|
bool operator!=(const iterator &RHS) const {
|
2008-05-10 07:39:43 +08:00
|
|
|
return Ptr != RHS.Ptr;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
// Preincrement.
|
2008-07-18 01:49:50 +08:00
|
|
|
iterator& operator++() {
|
|
|
|
if (!isIterator()) // common case.
|
2008-05-10 07:39:43 +08:00
|
|
|
Ptr = 0;
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
else {
|
|
|
|
NamedDecl *D = **this;
|
|
|
|
void *InfoPtr = D->getDeclName().getFETokenInfo<void>();
|
|
|
|
assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
|
|
|
|
IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
BaseIter I = getIterator();
|
|
|
|
if (I != Info->decls_begin())
|
|
|
|
*this = iterator(I-1);
|
|
|
|
else // No more decls.
|
|
|
|
*this = iterator();
|
|
|
|
}
|
2008-05-10 07:39:43 +08:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
uintptr_t getAsOpaqueValue() const { return Ptr; }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-01-15 06:20:51 +08:00
|
|
|
static iterator getFromOpaqueValue(uintptr_t P) {
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
iterator Result;
|
2009-01-15 06:20:51 +08:00
|
|
|
Result.Ptr = P;
|
|
|
|
return Result;
|
|
|
|
}
|
2008-07-18 01:49:50 +08:00
|
|
|
};
|
2008-05-10 07:39:43 +08:00
|
|
|
|
Eliminated LookupCriteria, whose creation was causing a bottleneck for
LookupName et al. Instead, use an enum and a bool to describe its
contents.
Optimized the C/Objective-C path through LookupName, eliminating any
unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
some code and arguments that are no longer used.
Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
over to LookupName, LookupQualifiedName, or LookupParsedName, as
appropriate.
All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
-disable-free. Plus, we're down to three name-lookup routines.
llvm-svn: 63354
2009-01-30 09:04:22 +08:00
|
|
|
/// begin - Returns an iterator for decls with the name 'Name'.
|
|
|
|
static iterator begin(DeclarationName Name);
|
2008-05-10 07:39:43 +08:00
|
|
|
|
2008-07-18 01:49:50 +08:00
|
|
|
/// end - Returns an iterator that has 'finished'.
|
|
|
|
static iterator end() {
|
|
|
|
return iterator();
|
2008-05-10 07:39:43 +08:00
|
|
|
}
|
|
|
|
|
2008-05-14 18:49:47 +08:00
|
|
|
/// isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true
|
|
|
|
/// if 'D' is in Scope 'S', otherwise 'S' is ignored and isDeclInScope returns
|
|
|
|
/// true if 'D' belongs to the given declaration context.
|
2008-12-12 00:49:14 +08:00
|
|
|
bool isDeclInScope(Decl *D, DeclContext *Ctx, ASTContext &Context,
|
|
|
|
Scope *S = 0) const;
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-04-12 09:50:47 +08:00
|
|
|
/// AddDecl - Link the decl to its shadowed decl chain.
|
2008-05-10 07:39:43 +08:00
|
|
|
void AddDecl(NamedDecl *D);
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
/// AddShadowedDecl - Link the decl to its shadowed decl chain putting it
|
2008-05-16 01:26:35 +08:00
|
|
|
/// after the decl that the iterator points to, thus the 'Shadow' decl will be
|
2008-05-10 07:39:43 +08:00
|
|
|
/// encountered before the 'D' decl.
|
|
|
|
void AddShadowedDecl(NamedDecl *D, NamedDecl *Shadow);
|
2008-04-11 15:06:57 +08:00
|
|
|
|
2008-04-12 09:50:47 +08:00
|
|
|
/// RemoveDecl - Unlink the decl from its shadowed decl chain.
|
2008-04-11 15:06:57 +08:00
|
|
|
/// The decl must already be part of the decl chain.
|
|
|
|
void RemoveDecl(NamedDecl *D);
|
|
|
|
|
2009-03-02 08:19:53 +08:00
|
|
|
/// Replace the decl Old with the new declaration New on its
|
|
|
|
/// identifier chain. Returns true if the old declaration was found
|
|
|
|
/// (and, therefore, replaced).
|
|
|
|
bool ReplaceDecl(NamedDecl *Old, NamedDecl *New);
|
|
|
|
|
Lazy deserialization of the declaration chains associated with
identifiers from a precompiled header.
This patch changes the primary name lookup method for entities within
a precompiled header. Previously, we would load all of the names of
declarations at translation unit scope into a large DenseMap (inside
the TranslationUnitDecl's DeclContext), and then perform a special
"last resort" lookup into this DeclContext when we knew there was a
PCH file (see Sema::LookupName). Now, when we see an identifier named
for the first time, we load all of the declarations with that name
that are visible from the translation unit into the IdentifierInfo's
chain of declarations. Thus, the explicit "look into the translation
unit's DeclContext" code is gone, and Sema effectively uses the same
IdentifierInfo-based name lookup mechanism whether we are using a PCH
file or not.
This approach should help PCH scale with the size of the input program
rather than the size of the PCH file. The "Hello, World!" application
with Carbon.h as a PCH file now loads 20% of the identifiers in the
PCH file rather than 85% of the identifiers.
90% of the 20% of identifiers loaded are actually loaded when we
deserialize the preprocessor state. The next step is to make the
preprocessor load macros lazily, which should drastically reduce the
number of types, declarations, and identifiers loaded for "Hello,
World".
llvm-svn: 69737
2009-04-22 06:25:48 +08:00
|
|
|
/// \brief Link the declaration into the chain of declarations for
|
|
|
|
/// the given identifier.
|
|
|
|
///
|
|
|
|
/// This is a lower-level routine used by the PCH reader to link a
|
|
|
|
/// declaration into a specific IdentifierInfo before the
|
|
|
|
/// declaration actually has a name.
|
|
|
|
void AddDeclToIdentifierChain(IdentifierInfo *II, NamedDecl *D);
|
|
|
|
|
2008-09-10 05:32:02 +08:00
|
|
|
explicit IdentifierResolver(const LangOptions &LangOpt);
|
2008-05-10 07:39:43 +08:00
|
|
|
~IdentifierResolver();
|
2008-04-11 15:06:57 +08:00
|
|
|
|
|
|
|
private:
|
2008-09-10 05:32:02 +08:00
|
|
|
const LangOptions &LangOpt;
|
|
|
|
|
2008-05-10 07:39:43 +08:00
|
|
|
class IdDeclInfoMap;
|
|
|
|
IdDeclInfoMap *IdDeclInfos;
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// FETokenInfo contains a Decl pointer if lower bit == 0.
|
2008-05-10 07:39:43 +08:00
|
|
|
static inline bool isDeclPtr(void *Ptr) {
|
|
|
|
return (reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 0;
|
|
|
|
}
|
|
|
|
|
2008-11-18 04:34:05 +08:00
|
|
|
/// FETokenInfo contains a IdDeclInfo pointer if lower bit == 1.
|
2008-05-10 07:39:43 +08:00
|
|
|
static inline IdDeclInfo *toIdDeclInfo(void *Ptr) {
|
|
|
|
assert((reinterpret_cast<uintptr_t>(Ptr) & 0x1) == 1
|
|
|
|
&& "Ptr not a IdDeclInfo* !");
|
|
|
|
return reinterpret_cast<IdDeclInfo*>(
|
|
|
|
reinterpret_cast<uintptr_t>(Ptr) & ~0x1
|
|
|
|
);
|
|
|
|
}
|
2008-04-11 15:06:57 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
} // end namespace clang
|
|
|
|
|
|
|
|
#endif
|