Implementation of pre-compiled headers (PCH) based on lazy
de-serialization of abstract syntax trees.

PCH support serializes the contents of the abstract syntax tree (AST)
to a bitstream. When the PCH file is read, declarations are serialized
as-needed. For example, a declaration of a variable "x" will be
deserialized only when its VarDecl can be found by a client, e.g.,
based on name lookup for "x" or traversing the entire contents of the
owner of "x".

This commit provides the framework for serialization and (lazy)
deserialization, along with support for variable and typedef
declarations (along with several kinds of types). More
declarations/types, along with important auxiliary structures (source
manager, preprocessor, etc.), will follow.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68732 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 474c1e4..b024d36 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -524,6 +524,12 @@
       return false;
   }
 
+  // __builtin_va_list gets redeclared in the built-in definitions
+  // buffer when using PCH. Don't complain about such redefinitions.
+  if (Context.getExternalSource() && 
+      strcmp(SourceMgr.getBufferName(New->getLocation()), "<built-in>") == 0)
+    return false;
+
   Diag(New->getLocation(), diag::err_redefinition) << New->getDeclName();
   Diag(Old->getLocation(), diag::note_previous_definition);
   return true;
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index 0b11d9c..cd82507 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -878,6 +878,17 @@
         // We have a single lookup result.
         return LookupResult::CreateLookupResult(Context, *I);
       }
+
+    /// If the context has an external AST source attached, look at
+    /// translation unit scope.
+    if (Context.getExternalSource()) {
+      DeclContext::lookup_iterator I, E;
+      for (llvm::tie(I, E) 
+             = Context.getTranslationUnitDecl()->lookup(Context, Name); 
+           I != E; ++I)
+        if (isAcceptableLookupResult(*I, NameKind, IDNS))
+          return LookupResult::CreateLookupResult(Context, I, E);
+    }
   } else {
     // Perform C++ unqualified name lookup.
     std::pair<bool, LookupResult> MaybeResult =