aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-07-07 16:35:42 +0000
committerDouglas Gregor <dgregor@apple.com>2009-07-07 16:35:42 +0000
commitc29f77b769bcc5b6dc85e72c8e3cc2e348e5cf25 (patch)
tree7d74f6f2933d40483d1d762e4f634c3e153f090e
parent0d3c26c76997688eaf7e51764a66815652e09642 (diff)
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
-rw-r--r--include/clang/AST/ASTContext.h13
-rw-r--r--include/clang/Frontend/PCHBitCodes.h4
-rw-r--r--lib/AST/ASTContext.cpp15
-rw-r--r--lib/Frontend/PCHReader.cpp11
-rw-r--r--lib/Frontend/PCHWriter.cpp1
-rw-r--r--lib/Sema/SemaDecl.cpp15
-rw-r--r--test/PCH/pr4489.c14
7 files changed, 62 insertions, 11 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index e85eac59a7..fbd56023d6 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -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.
diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h
index 8efaf26cc8..0de6b69432 100644
--- a/include/clang/Frontend/PCHBitCodes.h
+++ b/include/clang/Frontend/PCHBitCodes.h
@@ -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.
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 08607d5ed2..c59a5d703b 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -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;
}
}
}
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index bc0e7208d3..47a7e6264a 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -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
diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp
index 566df350f6..0362e8a490 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -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.
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index f148e8d0e1..a1ab68ac2a 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -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);
}
diff --git a/test/PCH/pr4489.c b/test/PCH/pr4489.c
index 51988113ec..7730819e92 100644
--- a/test/PCH/pr4489.c
+++ b/test/PCH/pr4489.c
@@ -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");
} \ No newline at end of file