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
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp
index bc0e720..47a7e62 100644
--- a/lib/Frontend/PCHReader.cpp
+++ b/lib/Frontend/PCHReader.cpp
@@ -1536,6 +1536,17 @@
   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 566df35..0362e8a 100644
--- a/lib/Frontend/PCHWriter.cpp
+++ b/lib/Frontend/PCHWriter.cpp
@@ -1892,6 +1892,7 @@
   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.