зеркало из https://github.com/microsoft/clang-1.git
When deserializing a declaration, don't look for redeclarations if its
kind indicates that it can never be redeclared. Good for a 1% speedup, and redeclaration searching drops off the profile. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173054 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5a04f9fc2b
Коммит
9cfdc03fe7
|
@ -141,5 +141,68 @@ const Decl *serialization::getDefinitiveDeclContext(const DeclContext *DC) {
|
|||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
bool serialization::isRedeclarableDeclKind(unsigned Kind) {
|
||||
switch (static_cast<Decl::Kind>(Kind)) {
|
||||
case Decl::TranslationUnit: // Special case of a "merged" declaration.
|
||||
case Decl::Namespace:
|
||||
case Decl::NamespaceAlias: // FIXME: Not yet redeclarable, but will be.
|
||||
case Decl::Typedef:
|
||||
case Decl::TypeAlias:
|
||||
case Decl::Enum:
|
||||
case Decl::Record:
|
||||
case Decl::CXXRecord:
|
||||
case Decl::ClassTemplateSpecialization:
|
||||
case Decl::ClassTemplatePartialSpecialization:
|
||||
case Decl::Function:
|
||||
case Decl::CXXMethod:
|
||||
case Decl::CXXConstructor:
|
||||
case Decl::CXXDestructor:
|
||||
case Decl::CXXConversion:
|
||||
case Decl::Var:
|
||||
case Decl::FunctionTemplate:
|
||||
case Decl::ClassTemplate:
|
||||
case Decl::TypeAliasTemplate:
|
||||
case Decl::ObjCProtocol:
|
||||
case Decl::ObjCInterface:
|
||||
return true;
|
||||
|
||||
// Never redeclarable.
|
||||
case Decl::UsingDirective:
|
||||
case Decl::Label:
|
||||
case Decl::UnresolvedUsingTypename:
|
||||
case Decl::TemplateTypeParm:
|
||||
case Decl::EnumConstant:
|
||||
case Decl::UnresolvedUsingValue:
|
||||
case Decl::IndirectField:
|
||||
case Decl::Field:
|
||||
case Decl::ObjCIvar:
|
||||
case Decl::ObjCAtDefsField:
|
||||
case Decl::ImplicitParam:
|
||||
case Decl::ParmVar:
|
||||
case Decl::NonTypeTemplateParm:
|
||||
case Decl::TemplateTemplateParm:
|
||||
case Decl::Using:
|
||||
case Decl::UsingShadow:
|
||||
case Decl::ObjCMethod:
|
||||
case Decl::ObjCCategory:
|
||||
case Decl::ObjCCategoryImpl:
|
||||
case Decl::ObjCImplementation:
|
||||
case Decl::ObjCProperty:
|
||||
case Decl::ObjCCompatibleAlias:
|
||||
case Decl::LinkageSpec:
|
||||
case Decl::ObjCPropertyImpl:
|
||||
case Decl::FileScopeAsm:
|
||||
case Decl::AccessSpec:
|
||||
case Decl::Friend:
|
||||
case Decl::FriendTemplate:
|
||||
case Decl::StaticAssert:
|
||||
case Decl::Block:
|
||||
case Decl::ClassScopeFunctionSpecialization:
|
||||
case Decl::Import:
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm_unreachable("Unhandled declaration kind");
|
||||
}
|
||||
|
|
|
@ -70,6 +70,9 @@ unsigned ComputeHash(Selector Sel);
|
|||
/// multiple definitions.
|
||||
const Decl *getDefinitiveDeclContext(const DeclContext *DC);
|
||||
|
||||
/// \brief Determine whether the given declaration kind is redeclarable.
|
||||
bool isRedeclarableDeclKind(unsigned Kind);
|
||||
|
||||
} // namespace serialization
|
||||
|
||||
} // namespace clang
|
||||
|
|
|
@ -116,29 +116,25 @@ namespace clang {
|
|||
ASTReader &Reader;
|
||||
GlobalDeclID FirstID;
|
||||
mutable bool Owning;
|
||||
Decl::Kind DeclKind;
|
||||
|
||||
void operator=(RedeclarableResult &) LLVM_DELETED_FUNCTION;
|
||||
|
||||
public:
|
||||
RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID)
|
||||
: Reader(Reader), FirstID(FirstID), Owning(true) { }
|
||||
RedeclarableResult(ASTReader &Reader, GlobalDeclID FirstID,
|
||||
Decl::Kind DeclKind)
|
||||
: Reader(Reader), FirstID(FirstID), Owning(true), DeclKind(DeclKind) { }
|
||||
|
||||
RedeclarableResult(const RedeclarableResult &Other)
|
||||
: Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning)
|
||||
: Reader(Other.Reader), FirstID(Other.FirstID), Owning(Other.Owning) ,
|
||||
DeclKind(Other.DeclKind)
|
||||
{
|
||||
Other.Owning = false;
|
||||
}
|
||||
|
||||
~RedeclarableResult() {
|
||||
// FIXME: We want to suppress this when the declaration is local to
|
||||
// a function, since there's no reason to search other AST files
|
||||
// for redeclarations (they can't exist). However, this is hard to
|
||||
// do locally because the declaration hasn't necessarily loaded its
|
||||
// declaration context yet. Also, local externs still have the function
|
||||
// as their (semantic) declaration context, which is wrong and would
|
||||
// break this optimize.
|
||||
|
||||
if (FirstID && Owning && Reader.PendingDeclChainsKnown.insert(FirstID))
|
||||
if (FirstID && Owning && isRedeclarableDeclKind(DeclKind) &&
|
||||
Reader.PendingDeclChainsKnown.insert(FirstID))
|
||||
Reader.PendingDeclChains.push_back(FirstID);
|
||||
}
|
||||
|
||||
|
@ -151,7 +147,7 @@ namespace clang {
|
|||
Owning = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Class used to capture the result of searching for an existing
|
||||
/// declaration of a specific kind and name, along with the ability
|
||||
/// to update the place where this result was found (the declaration
|
||||
|
@ -1562,7 +1558,8 @@ ASTDeclReader::VisitRedeclarable(Redeclarable<T> *D) {
|
|||
|
||||
// The result structure takes care to note that we need to load the
|
||||
// other declaration chains for this ID.
|
||||
return RedeclarableResult(Reader, FirstDeclID);
|
||||
return RedeclarableResult(Reader, FirstDeclID,
|
||||
static_cast<T *>(D)->getKind());
|
||||
}
|
||||
|
||||
/// \brief Attempts to merge the given declaration (D) with another declaration
|
||||
|
|
|
@ -1277,7 +1277,10 @@ template <typename T>
|
|||
void ASTDeclWriter::VisitRedeclarable(Redeclarable<T> *D) {
|
||||
T *First = D->getFirstDeclaration();
|
||||
if (First->getMostRecentDecl() != First) {
|
||||
// There is more than one declaration of this entity, so we will need to
|
||||
assert(isRedeclarableDeclKind(static_cast<T *>(D)->getKind()) &&
|
||||
"Not considered redeclarable?");
|
||||
|
||||
// There is more than one declaration of this entity, so we will need to
|
||||
// write a redeclaration chain.
|
||||
Writer.AddDeclRef(First, Record);
|
||||
Writer.Redeclarations.insert(First);
|
||||
|
|
Загрузка…
Ссылка в новой задаче