зеркало из https://github.com/microsoft/clang-1.git
Make ASTContext explicitly keep track of the declaration for the C
FILE type, rather than using name lookup to find FILE within the translation unit. Within precompiled headers, FILE is treated as yet another "special type" (like __builtin_va_list). This change should provide a performance improvement (not verified), since the lookup into the translation unit declaration forces the (otherwise unneeded) construction of a large hash table. More importantly, with precompiled headers, the construction of that table requires deserializing most of the top-level declarations from the precompiled header, which are then unused. Fixes PR 4509. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@74911 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
0d3c26c769
Коммит
c29f77b769
|
@ -126,6 +126,9 @@ class ASTContext {
|
|||
|
||||
RecordDecl *ObjCFastEnumerationStateTypeDecl;
|
||||
|
||||
/// \brief The type for the C FILE type.
|
||||
TypeDecl *FILEDecl;
|
||||
|
||||
/// \brief Keeps track of all declaration attributes.
|
||||
///
|
||||
/// Since so few decls have attrs, we keep them in a hash map instead of
|
||||
|
@ -447,6 +450,16 @@ public:
|
|||
|
||||
void setObjCFastEnumerationStateType(QualType T);
|
||||
|
||||
/// \brief Set the type for the C FILE type.
|
||||
void setFILEDecl(TypeDecl *FILEDecl) { this->FILEDecl = FILEDecl; }
|
||||
|
||||
/// \brief Retrieve the C FILE type.
|
||||
QualType getFILEType() {
|
||||
if (FILEDecl)
|
||||
return getTypeDeclType(FILEDecl);
|
||||
return QualType();
|
||||
}
|
||||
|
||||
/// getObjCEncodingForType - Emit the ObjC type encoding for the
|
||||
/// given type into \arg S. If \arg NameFields is specified then
|
||||
/// record field names are also encoded.
|
||||
|
|
|
@ -419,7 +419,9 @@ namespace clang {
|
|||
/// \brief CFConstantString type
|
||||
SPECIAL_TYPE_CF_CONSTANT_STRING = 5,
|
||||
/// \brief Objective-C fast enumeration state type
|
||||
SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6
|
||||
SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6,
|
||||
/// \brief C FILE typedef type
|
||||
SPECIAL_TYPE_FILE = 7
|
||||
};
|
||||
|
||||
/// \brief Record codes for each kind of declaration.
|
||||
|
|
|
@ -36,7 +36,8 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM,
|
|||
Builtin::Context &builtins,
|
||||
bool FreeMem, unsigned size_reserve) :
|
||||
GlobalNestedNameSpecifier(0), CFConstantStringTypeDecl(0),
|
||||
ObjCFastEnumerationStateTypeDecl(0), SourceMgr(SM), LangOpts(LOpts),
|
||||
ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0),
|
||||
SourceMgr(SM), LangOpts(LOpts),
|
||||
LoadedExternalComments(false), FreeMemory(FreeMem), Target(t),
|
||||
Idents(idents), Selectors(sels),
|
||||
BuiltinInfo(builtins), ExternalSource(0), PrintingPolicy(LOpts) {
|
||||
|
@ -3844,16 +3845,12 @@ static QualType DecodeTypeFromStr(const char *&Str, ASTContext &Context,
|
|||
break;
|
||||
}
|
||||
case 'P': {
|
||||
IdentifierInfo *II = &Context.Idents.get("FILE");
|
||||
DeclContext::lookup_result Lookup
|
||||
= Context.getTranslationUnitDecl()->lookup(II);
|
||||
if (Lookup.first != Lookup.second && isa<TypeDecl>(*Lookup.first)) {
|
||||
Type = Context.getTypeDeclType(cast<TypeDecl>(*Lookup.first));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
Type = Context.getFILEType();
|
||||
if (Type.isNull()) {
|
||||
Error = ASTContext::GE_Missing_FILE;
|
||||
return QualType();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1536,6 +1536,17 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {
|
|||
if (unsigned FastEnum
|
||||
= SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
|
||||
Context->setObjCFastEnumerationStateType(GetType(FastEnum));
|
||||
if (unsigned File = SpecialTypes[pch::SPECIAL_TYPE_FILE]) {
|
||||
QualType FileType = GetType(File);
|
||||
assert(!FileType.isNull() && "FILE type is NULL");
|
||||
if (const TypedefType *Typedef = FileType->getAsTypedefType())
|
||||
Context->setFILEDecl(Typedef->getDecl());
|
||||
else {
|
||||
const TagType *Tag = FileType->getAsTagType();
|
||||
assert(Tag && "Invalid FILE type in PCH file");
|
||||
Context->setFILEDecl(Tag->getDecl());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Retrieve the name of the original source file name
|
||||
|
|
|
@ -1892,6 +1892,7 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,
|
|||
AddTypeRef(Context.getObjCClassType(), Record);
|
||||
AddTypeRef(Context.getRawCFConstantStringType(), Record);
|
||||
AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
|
||||
AddTypeRef(Context.getFILEType(), Record);
|
||||
Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
|
||||
|
||||
// Write the record containing external, unnamed definitions.
|
||||
|
|
|
@ -1691,6 +1691,14 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If this is the C FILE type, notify the AST context.
|
||||
if (IdentifierInfo *II = NewTD->getIdentifier())
|
||||
if (!NewTD->isInvalidDecl() &&
|
||||
NewTD->getDeclContext()->getLookupContext()->isTranslationUnit() &&
|
||||
II->isStr("FILE"))
|
||||
Context.setFILEDecl(NewTD);
|
||||
|
||||
return NewTD;
|
||||
}
|
||||
|
||||
|
@ -3768,6 +3776,13 @@ CreateNewDecl:
|
|||
CurContext->addDecl(New);
|
||||
}
|
||||
|
||||
// If this is the C FILE type, notify the AST context.
|
||||
if (IdentifierInfo *II = New->getIdentifier())
|
||||
if (!New->isInvalidDecl() &&
|
||||
New->getDeclContext()->getLookupContext()->isTranslationUnit() &&
|
||||
II->isStr("FILE"))
|
||||
Context.setFILEDecl(New);
|
||||
|
||||
OwnedDecl = true;
|
||||
return DeclPtrTy::make(New);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// RUN: clang -x c-header -o %t.pch %s &&
|
||||
// RUN: clang -include %t -x c /dev/null -emit-llvm -S -o -
|
||||
// PR 4489: Crash with PCH
|
||||
|
||||
// PR 4492: Crash with PCH (round two)
|
||||
// PR 4509: Crash with PCH (round three)
|
||||
typedef struct _IO_FILE FILE;
|
||||
extern int fprintf (struct _IO_FILE *__restrict __stream,
|
||||
__const char *__restrict __format, ...);
|
||||
|
@ -25,4 +26,15 @@ void x0(void)
|
|||
{
|
||||
extern char z0;
|
||||
fprintf (0, "a");
|
||||
}
|
||||
|
||||
void x1(void)
|
||||
{
|
||||
fprintf (0, "asdf");
|
||||
}
|
||||
|
||||
void y1(void)
|
||||
{
|
||||
extern char e;
|
||||
fprintf (0, "asdf");
|
||||
}
|
Загрузка…
Ссылка в новой задаче