diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 424d631..627a394 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -159,7 +159,7 @@
   return false;
 }
 
-bool PCHValidator::ReadTargetTriple(llvm::StringRef Triple) {
+bool PCHValidator::ReadTargetTriple(StringRef Triple) {
   if (Triple == PP.getTargetInfo().getTriple().str())
     return false;
 
@@ -170,14 +170,14 @@
 
 namespace {
   struct EmptyStringRef {
-    bool operator ()(llvm::StringRef r) const { return r.empty(); }
+    bool operator ()(StringRef r) const { return r.empty(); }
   };
   struct EmptyBlock {
     bool operator ()(const PCHPredefinesBlock &r) const {return r.Data.empty();}
   };
 }
 
-static bool EqualConcatenations(llvm::SmallVector<llvm::StringRef, 2> L,
+static bool EqualConcatenations(SmallVector<StringRef, 2> L,
                                 PCHPredefinesBlocks R) {
   // First, sum up the lengths.
   unsigned LL = 0, RL = 0;
@@ -197,7 +197,7 @@
   R.erase(std::remove_if(R.begin(), R.end(), EmptyBlock()), R.end());
 
   // Do it the hard way. At this point, both vectors must be non-empty.
-  llvm::StringRef LR = L[0], RR = R[0].Data;
+  StringRef LR = L[0], RR = R[0].Data;
   unsigned LI = 0, RI = 0, LN = L.size(), RN = R.size();
   (void) RN;
   for (;;) {
@@ -237,12 +237,12 @@
   }
 }
 
-static std::pair<FileID, llvm::StringRef::size_type>
-FindMacro(const PCHPredefinesBlocks &Buffers, llvm::StringRef MacroDef) {
-  std::pair<FileID, llvm::StringRef::size_type> Res;
+static std::pair<FileID, StringRef::size_type>
+FindMacro(const PCHPredefinesBlocks &Buffers, StringRef MacroDef) {
+  std::pair<FileID, StringRef::size_type> Res;
   for (unsigned I = 0, N = Buffers.size(); I != N; ++I) {
     Res.second = Buffers[I].Data.find(MacroDef);
-    if (Res.second != llvm::StringRef::npos) {
+    if (Res.second != StringRef::npos) {
       Res.first = Buffers[I].BufferID;
       break;
     }
@@ -251,7 +251,7 @@
 }
 
 bool PCHValidator::ReadPredefinesBuffer(const PCHPredefinesBlocks &Buffers,
-                                        llvm::StringRef OriginalFileName,
+                                        StringRef OriginalFileName,
                                         std::string &SuggestedPredefines,
                                         FileManager &FileMgr) {
   // We are in the context of an implicit include, so the predefines buffer will
@@ -262,9 +262,9 @@
   PCHInclude += "#include \"";
   PCHInclude += NormalizeDashIncludePath(OriginalFileName, FileMgr);
   PCHInclude += "\"\n";
-  std::pair<llvm::StringRef,llvm::StringRef> Split =
-    llvm::StringRef(PP.getPredefines()).split(PCHInclude.str());
-  llvm::StringRef Left =  Split.first, Right = Split.second;
+  std::pair<StringRef,StringRef> Split =
+    StringRef(PP.getPredefines()).split(PCHInclude.str());
+  StringRef Left =  Split.first, Right = Split.second;
   if (Left == PP.getPredefines()) {
     Error("Missing PCH include entry!");
     return true;
@@ -272,7 +272,7 @@
 
   // If the concatenation of all the PCH buffers is equal to the adjusted
   // command line, we're done.
-  llvm::SmallVector<llvm::StringRef, 2> CommandLine;
+  SmallVector<StringRef, 2> CommandLine;
   CommandLine.push_back(Left);
   CommandLine.push_back(Right);
   if (EqualConcatenations(CommandLine, Buffers))
@@ -282,18 +282,18 @@
 
   // The predefines buffers are different. Determine what the differences are,
   // and whether they require us to reject the PCH file.
-  llvm::SmallVector<llvm::StringRef, 8> PCHLines;
+  SmallVector<StringRef, 8> PCHLines;
   for (unsigned I = 0, N = Buffers.size(); I != N; ++I)
     Buffers[I].Data.split(PCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
 
-  llvm::SmallVector<llvm::StringRef, 8> CmdLineLines;
+  SmallVector<StringRef, 8> CmdLineLines;
   Left.split(CmdLineLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
 
   // Pick out implicit #includes after the PCH and don't consider them for
   // validation; we will insert them into SuggestedPredefines so that the
   // preprocessor includes them.
   std::string IncludesAfterPCH;
-  llvm::SmallVector<llvm::StringRef, 8> AfterPCHLines;
+  SmallVector<StringRef, 8> AfterPCHLines;
   Right.split(AfterPCHLines, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
   for (unsigned i = 0, e = AfterPCHLines.size(); i != e; ++i) {
     if (AfterPCHLines[i].startswith("#include ")) {
@@ -326,7 +326,7 @@
 
   // Determine which predefines that were used to build the PCH file are missing
   // from the command line.
-  std::vector<llvm::StringRef> MissingPredefines;
+  std::vector<StringRef> MissingPredefines;
   std::set_difference(PCHLines.begin(), PCHLines.end(),
                       CmdLineLines.begin(), CmdLineLines.end(),
                       std::back_inserter(MissingPredefines));
@@ -334,7 +334,7 @@
   bool MissingDefines = false;
   bool ConflictingDefines = false;
   for (unsigned I = 0, N = MissingPredefines.size(); I != N; ++I) {
-    llvm::StringRef Missing = MissingPredefines[I];
+    StringRef Missing = MissingPredefines[I];
     if (Missing.startswith("#include ")) {
       // An -include was specified when generating the PCH; it is included in
       // the PCH, just ignore it.
@@ -352,13 +352,13 @@
       = Missing.find_first_of("( \n\r", StartOfMacroName);
     assert(EndOfMacroName != std::string::npos &&
            "Couldn't find the end of the macro name");
-    llvm::StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
+    StringRef MacroName = Missing.slice(StartOfMacroName, EndOfMacroName);
 
     // Determine whether this macro was given a different definition on the
     // command line.
     std::string MacroDefStart = "#define " + MacroName.str();
     std::string::size_type MacroDefLen = MacroDefStart.size();
-    llvm::SmallVector<llvm::StringRef, 8>::iterator ConflictPos
+    SmallVector<StringRef, 8>::iterator ConflictPos
       = std::lower_bound(CmdLineLines.begin(), CmdLineLines.end(),
                          MacroDefStart);
     for (; ConflictPos != CmdLineLines.end(); ++ConflictPos) {
@@ -383,9 +383,9 @@
           << MacroName;
 
       // Show the definition of this macro within the PCH file.
-      std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
+      std::pair<FileID, StringRef::size_type> MacroLoc =
           FindMacro(Buffers, Missing);
-      assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
+      assert(MacroLoc.second!=StringRef::npos && "Unable to find macro!");
       SourceLocation PCHMissingLoc =
           SourceMgr.getLocForStartOfFile(MacroLoc.first)
             .getFileLocWithOffset(MacroLoc.second);
@@ -406,9 +406,9 @@
     }
 
     // Show the definition of this macro within the PCH file.
-    std::pair<FileID, llvm::StringRef::size_type> MacroLoc =
+    std::pair<FileID, StringRef::size_type> MacroLoc =
         FindMacro(Buffers, Missing);
-    assert(MacroLoc.second!=llvm::StringRef::npos && "Unable to find macro!");
+    assert(MacroLoc.second!=StringRef::npos && "Unable to find macro!");
     SourceLocation PCHMissingLoc =
         SourceMgr.getLocForStartOfFile(MacroLoc.first)
           .getFileLocWithOffset(MacroLoc.second);
@@ -422,12 +422,12 @@
   // parameters that were not present when building the PCH
   // file. Extra #defines are okay, so long as the identifiers being
   // defined were not used within the precompiled header.
-  std::vector<llvm::StringRef> ExtraPredefines;
+  std::vector<StringRef> ExtraPredefines;
   std::set_difference(CmdLineLines.begin(), CmdLineLines.end(),
                       PCHLines.begin(), PCHLines.end(),
                       std::back_inserter(ExtraPredefines));
   for (unsigned I = 0, N = ExtraPredefines.size(); I != N; ++I) {
-    llvm::StringRef &Extra = ExtraPredefines[I];
+    StringRef &Extra = ExtraPredefines[I];
     if (!Extra.startswith("#define ")) {
       Reader.Diag(diag::warn_pch_compiler_options_mismatch);
       return true;
@@ -440,7 +440,7 @@
       = Extra.find_first_of("( \n\r", StartOfMacroName);
     assert(EndOfMacroName != std::string::npos &&
            "Couldn't find the end of the macro name");
-    llvm::StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
+    StringRef MacroName = Extra.slice(StartOfMacroName, EndOfMacroName);
 
     // Check whether this name was used somewhere in the PCH file. If
     // so, defining it as a macro could change behavior, so we reject
@@ -529,7 +529,7 @@
     else if (N == 1)
       return SelTable.getUnarySelector(FirstII);
 
-    llvm::SmallVector<IdentifierInfo *, 16> Args;
+    SmallVector<IdentifierInfo *, 16> Args;
     Args.push_back(FirstII);
     for (unsigned I = 1; I != N; ++I)
       Args.push_back(Reader.DecodeIdentifierInfo(ReadUnalignedLE32(d)));
@@ -620,7 +620,7 @@
   }
 
   static unsigned ComputeHash(const internal_key_type& a) {
-    return llvm::HashString(llvm::StringRef(a.first, a.second));
+    return llvm::HashString(StringRef(a.first, a.second));
   }
 
   // This hopefully will just get inlined and removed by the optimizer.
@@ -660,7 +660,7 @@
       // and associate it with the persistent ID.
       IdentifierInfo *II = KnownII;
       if (!II)
-        II = &Reader.getIdentifierTable().getOwn(llvm::StringRef(k.first,
+        II = &Reader.getIdentifierTable().getOwn(StringRef(k.first,
                                                                  k.second));
       Reader.SetIdentifierInfo(ID, II);
       II->setIsFromAST();
@@ -688,7 +688,7 @@
     // the new IdentifierInfo.
     IdentifierInfo *II = KnownII;
     if (!II)
-      II = &Reader.getIdentifierTable().getOwn(llvm::StringRef(k.first,
+      II = &Reader.getIdentifierTable().getOwn(StringRef(k.first,
                                                                k.second));
     Reader.SetIdentifierInfo(ID, II);
 
@@ -717,7 +717,7 @@
     // name.
     if (Reader.getContext() == 0) return II;
     if (DataLen > 0) {
-      llvm::SmallVector<uint32_t, 4> DeclIDs;
+      SmallVector<uint32_t, 4> DeclIDs;
       for (; DataLen > 0; DataLen -= 4)
         DeclIDs.push_back(Reader.getGlobalDeclID(F, ReadUnalignedLE32(d)));
       Reader.SetGloballyVisibleDecls(II, DeclIDs);
@@ -968,12 +968,12 @@
   return false;
 }
 
-void ASTReader::Error(llvm::StringRef Msg) {
+void ASTReader::Error(StringRef Msg) {
   Error(diag::err_fe_pch_malformed, Msg);
 }
 
 void ASTReader::Error(unsigned DiagID,
-                      llvm::StringRef Arg1, llvm::StringRef Arg2) {
+                      StringRef Arg1, StringRef Arg2) {
   if (Diags.isDiagnosticInFlight())
     Diags.SetDelayedDiagnostic(DiagID, Arg1, Arg2);
   else
@@ -997,7 +997,7 @@
 /// \brief Read the line table in the source manager block.
 /// \returns true if there was an error.
 bool ASTReader::ParseLineTable(Module &F,
-                               llvm::SmallVectorImpl<uint64_t> &Record) {
+                               SmallVectorImpl<uint64_t> &Record) {
   unsigned Idx = 0;
   LineTableInfo &LineTable = SourceMgr.getLineTable();
 
@@ -1341,7 +1341,7 @@
     }
 
     llvm::MemoryBuffer *Buffer
-    = llvm::MemoryBuffer::getMemBuffer(llvm::StringRef(BlobStart, BlobLen - 1),
+    = llvm::MemoryBuffer::getMemBuffer(StringRef(BlobStart, BlobLen - 1),
                                        Name);
     FileID BufferID = SourceMgr.createFileIDForMemBuffer(Buffer, ID,
                                                          BaseOffset + Offset);
@@ -1349,7 +1349,7 @@
     if (strcmp(Name, "<built-in>") == 0) {
       PCHPredefinesBlock Block = {
         BufferID,
-        llvm::StringRef(BlobStart, BlobLen - 1)
+        StringRef(BlobStart, BlobLen - 1)
       };
       PCHPredefinesBuffers.push_back(Block);
     }
@@ -1422,7 +1422,7 @@
 
   Stream.JumpToBit(Offset);
   RecordData Record;
-  llvm::SmallVector<IdentifierInfo*, 16> MacroArgs;
+  SmallVector<IdentifierInfo*, 16> MacroArgs;
   MacroInfo *Macro = 0;
 
   while (true) {
@@ -1614,7 +1614,7 @@
     
     const char *FullFileNameStart = BlobStart + Record[3];
     const FileEntry *File
-      = PP->getFileManager().getFile(llvm::StringRef(FullFileNameStart,
+      = PP->getFileManager().getFile(StringRef(FullFileNameStart,
                                                      BlobLen - Record[3]));
     
     // FIXME: Stable encoding
@@ -1622,7 +1622,7 @@
       = static_cast<InclusionDirective::InclusionKind>(Record[5]);
     InclusionDirective *ID
       = new (PPRec) InclusionDirective(PPRec, Kind,
-                                       llvm::StringRef(BlobStart, Record[3]),
+                                       StringRef(BlobStart, Record[3]),
                                        Record[4],
                                        File,
                                  SourceRange(ReadSourceLocation(F, Record[1]),
@@ -1831,7 +1831,7 @@
   return MacroDefinitionsLoaded[ID - 1];
 }
 
-const FileEntry *ASTReader::getFileEntry(llvm::StringRef filenameStrRef) {
+const FileEntry *ASTReader::getFileEntry(StringRef filenameStrRef) {
   std::string Filename = filenameStrRef;
   MaybeAddSystemRootToFilename(Filename);
   const FileEntry *File = FileMgr.getFile(Filename);
@@ -2003,7 +2003,7 @@
 
       // Load the chained file, which is always a PCH file.
       // FIXME: This could end up being a module.
-      switch(ReadASTCore(llvm::StringRef(BlobStart, BlobLen), MK_PCH)) {
+      switch(ReadASTCore(StringRef(BlobStart, BlobLen), MK_PCH)) {
       case Failure: return Failure;
         // If we have to ignore the dependency, we'll have to ignore this too.
       case IgnorePCH: return IgnorePCH;
@@ -2222,7 +2222,7 @@
       while(Data < DataEnd) {
         uint32_t Offset = io::ReadUnalignedLE32(Data);
         uint16_t Len = io::ReadUnalignedLE16(Data);
-        llvm::StringRef Name = llvm::StringRef((const char*)Data, Len);
+        StringRef Name = StringRef((const char*)Data, Len);
         Module *OM = Modules.lookup(Name);
         if (!OM) {
           Error("SourceLocation remap refers to unknown module");
@@ -2319,8 +2319,8 @@
 
     case VERSION_CONTROL_BRANCH_REVISION: {
       const std::string &CurBranch = getClangFullRepositoryVersion();
-      llvm::StringRef ASTBranch(BlobStart, BlobLen);
-      if (llvm::StringRef(CurBranch) != ASTBranch && !DisableValidation) {
+      StringRef ASTBranch(BlobStart, BlobLen);
+      if (StringRef(CurBranch) != ASTBranch && !DisableValidation) {
         Diag(diag::warn_pch_different_branch) << ASTBranch << CurBranch;
         return IgnorePCH;
       }
@@ -2488,7 +2488,7 @@
         return Failure;
   
       case SM_SLOC_FILE_ENTRY: {
-        llvm::StringRef Filename(BlobStart, BlobLen);
+        StringRef Filename(BlobStart, BlobLen);
         const FileEntry *File = getFileEntry(Filename);
 
         if (File == 0) {
@@ -2576,7 +2576,7 @@
     // since de-serializing declarations or macro definitions can add
     // new entries into the identifier table, invalidating the
     // iterators.
-    llvm::SmallVector<IdentifierInfo *, 128> Identifiers;
+    SmallVector<IdentifierInfo *, 128> Identifiers;
     for (IdentifierTable::iterator Id = PP->getIdentifierTable().begin(),
                                 IdEnd = PP->getIdentifierTable().end();
          Id != IdEnd; ++Id)
@@ -2633,7 +2633,7 @@
   return Success;
 }
 
-ASTReader::ASTReadResult ASTReader::ReadASTCore(llvm::StringRef FileName,
+ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName,
                                                 ModuleKind Type) {
   Module *Prev = Chain.empty() ? 0 : Chain.back();
   Chain.push_back(new Module(Type));
@@ -2975,7 +2975,7 @@
 ///
 /// \returns true if the listener deems the file unacceptable, false otherwise.
 bool ASTReader::ParseLanguageOptions(
-                             const llvm::SmallVectorImpl<uint64_t> &Record) {
+                             const SmallVectorImpl<uint64_t> &Record) {
   if (Listener) {
     LangOptions LangOpts;
 
@@ -3305,7 +3305,7 @@
 
     unsigned Idx = 6;
     unsigned NumParams = Record[Idx++];
-    llvm::SmallVector<QualType, 16> ParamTypes;
+    SmallVector<QualType, 16> ParamTypes;
     for (unsigned I = 0; I != NumParams; ++I)
       ParamTypes.push_back(readType(*Loc.F, Record, Idx));
 
@@ -3317,7 +3317,7 @@
     EPI.ExceptionSpecType = EST;
     if (EST == EST_Dynamic) {
       EPI.NumExceptions = Record[Idx++];
-      llvm::SmallVector<QualType, 2> Exceptions;
+      SmallVector<QualType, 2> Exceptions;
       for (unsigned I = 0; I != EPI.NumExceptions; ++I)
         Exceptions.push_back(readType(*Loc.F, Record, Idx));
       EPI.Exceptions = Exceptions.data();
@@ -3451,7 +3451,7 @@
     unsigned Idx = 0;
     QualType Base = readType(*Loc.F, Record, Idx);
     unsigned NumProtos = Record[Idx++];
-    llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
+    SmallVector<ObjCProtocolDecl*, 4> Protos;
     for (unsigned I = 0; I != NumProtos; ++I)
       Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
     return Context->getObjCObjectType(Base, Protos.data(), NumProtos);
@@ -3517,7 +3517,7 @@
     NestedNameSpecifier *NNS = ReadNestedNameSpecifier(*Loc.F, Record, Idx);
     const IdentifierInfo *Name = this->GetIdentifierInfo(Record, Idx);
     unsigned NumArgs = Record[Idx++];
-    llvm::SmallVector<TemplateArgument, 8> Args;
+    SmallVector<TemplateArgument, 8> Args;
     Args.reserve(NumArgs);
     while (NumArgs--)
       Args.push_back(ReadTemplateArgument(*Loc.F, Record, Idx));
@@ -3546,7 +3546,7 @@
     unsigned Idx = 0;
     bool IsDependent = Record[Idx++];
     TemplateName Name = ReadTemplateName(*Loc.F, Record, Idx);
-    llvm::SmallVector<TemplateArgument, 8> Args;
+    SmallVector<TemplateArgument, 8> Args;
     ReadTemplateArgumentList(Args, *Loc.F, Record, Idx);
     QualType Underlying = readType(*Loc.F, Record, Idx);
     QualType T;
@@ -4060,7 +4060,7 @@
 
 ExternalLoadResult ASTReader::FindExternalLexicalDecls(const DeclContext *DC,
                                          bool (*isKindWeWant)(Decl::Kind),
-                                         llvm::SmallVectorImpl<Decl*> &Decls) {
+                                         SmallVectorImpl<Decl*> &Decls) {
   // There might be lexical decls in multiple parts of the chain, for the TU
   // at least.
   // DeclContextOffsets might reallocate as we load additional decls below,
@@ -4097,7 +4097,7 @@
     return DeclContext::lookup_result(DeclContext::lookup_iterator(0),
                                       DeclContext::lookup_iterator(0));
 
-  llvm::SmallVector<NamedDecl *, 64> Decls;
+  SmallVector<NamedDecl *, 64> Decls;
   // There might be visible decls in multiple parts of the chain, for the TU
   // and namespaces. For any given name, the last available results replace
   // all earlier ones. For this reason, we walk in reverse.
@@ -4129,7 +4129,7 @@
   assert(DC->hasExternalVisibleStorage() &&
          "DeclContext has no visible decls in storage");
 
-  llvm::SmallVector<NamedDecl *, 64> Decls;
+  SmallVector<NamedDecl *, 64> Decls;
   // There might be visible decls in multiple parts of the chain, for the TU
   // and namespaces.
   DeclContextInfos &Infos = DeclContextOffsets[DC];
@@ -4250,7 +4250,7 @@
 
 template<typename Key, typename Module, unsigned InitialCapacity>
 static void 
-dumpModuleIDMap(llvm::StringRef Name,
+dumpModuleIDMap(StringRef Name,
                 const ContinuousRangeMap<Key, Module *, 
                                          InitialCapacity> &Map) {
   if (Map.begin() == Map.end())
@@ -4268,7 +4268,7 @@
 template<typename Key, typename Module, typename Adjustment, 
          unsigned InitialCapacity>
 static void 
-dumpModuleIDOffsetMap(llvm::StringRef Name,
+dumpModuleIDOffsetMap(StringRef Name,
                       const ContinuousRangeMap<Key, 
                                                std::pair<Module *, 
                                                          Adjustment>, 
@@ -4499,7 +4499,7 @@
   public:
     explicit ASTIdentifierIterator(const ASTReader &Reader);
 
-    virtual llvm::StringRef Next();
+    virtual StringRef Next();
   };
 }
 
@@ -4511,11 +4511,11 @@
   End = IdTable->key_end();
 }
 
-llvm::StringRef ASTIdentifierIterator::Next() {
+StringRef ASTIdentifierIterator::Next() {
   while (Current == End) {
     // If we have exhausted all of our AST files, we're done.
     if (Index == 0)
-      return llvm::StringRef();
+      return StringRef();
 
     --Index;
     ASTIdentifierLookupTable *IdTable
@@ -4528,7 +4528,7 @@
   // the next one.
   std::pair<const char*, unsigned> Key = *Current;
   ++Current;
-  return llvm::StringRef(Key.first, Key.second);
+  return StringRef(Key.first, Key.second);
 }
 
 IdentifierIterator *ASTReader::getIdentifiers() const {
@@ -4564,7 +4564,7 @@
 }
 
 void ASTReader::ReadKnownNamespaces(
-                          llvm::SmallVectorImpl<NamespaceDecl *> &Namespaces) {
+                          SmallVectorImpl<NamespaceDecl *> &Namespaces) {
   Namespaces.clear();
   
   for (unsigned I = 0, N = KnownNamespaces.size(); I != N; ++I) {
@@ -4605,7 +4605,7 @@
 /// will not be placed onto the pending queue.
 void
 ASTReader::SetGloballyVisibleDecls(IdentifierInfo *II,
-                              const llvm::SmallVectorImpl<uint32_t> &DeclIDs,
+                              const SmallVectorImpl<uint32_t> &DeclIDs,
                                    bool Nonrecursive) {
   if (NumCurrentElementsDeserializing && !Nonrecursive) {
     PendingIdentifierInfos.push_back(PendingIdentifierInfo());
@@ -4661,7 +4661,7 @@
     unsigned StrLen = (((unsigned) StrLenPtr[0])
                        | (((unsigned) StrLenPtr[1]) << 8)) - 1;
     IdentifiersLoaded[ID]
-      = &PP->getIdentifierTable().get(llvm::StringRef(Str, StrLen));
+      = &PP->getIdentifierTable().get(StringRef(Str, StrLen));
     if (DeserializationListener)
       DeserializationListener->IdentifierRead(ID + 1, IdentifiersLoaded[ID]);
   }
@@ -4909,7 +4909,7 @@
   SourceLocation RAngleLoc = ReadSourceLocation(F, Record, Idx);
 
   unsigned NumParams = Record[Idx++];
-  llvm::SmallVector<NamedDecl *, 16> Params;
+  SmallVector<NamedDecl *, 16> Params;
   Params.reserve(NumParams);
   while (NumParams--)
     Params.push_back(ReadDeclAs<NamedDecl>(F, Record, Idx));
@@ -4922,7 +4922,7 @@
 
 void
 ASTReader::
-ReadTemplateArgumentList(llvm::SmallVector<TemplateArgument, 8> &TemplArgs,
+ReadTemplateArgumentList(SmallVector<TemplateArgument, 8> &TemplArgs,
                          Module &F, const RecordData &Record,
                          unsigned &Idx) {
   unsigned NumTemplateArgs = Record[Idx++];
@@ -5001,7 +5001,7 @@
       SourceLocation RParenLoc = ReadSourceLocation(F, Record, Idx);
       bool IsWritten = Record[Idx++];
       unsigned SourceOrderOrNumArrayIndices;
-      llvm::SmallVector<VarDecl *, 8> Indices;
+      SmallVector<VarDecl *, 8> Indices;
       if (IsWritten) {
         SourceOrderOrNumArrayIndices = Record[Idx++];
       } else {
diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp
index 30800fb..289b6c8 100644
--- a/lib/Serialization/ASTReaderDecl.cpp
+++ b/lib/Serialization/ASTReaderDecl.cpp
@@ -359,11 +359,11 @@
     TemplateSpecializationKind TSK = (TemplateSpecializationKind)Record[Idx++];
     
     // Template arguments.
-    llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+    SmallVector<TemplateArgument, 8> TemplArgs;
     Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
     
     // Template args as written.
-    llvm::SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
+    SmallVector<TemplateArgumentLoc, 8> TemplArgLocs;
     SourceLocation LAngleLoc, RAngleLoc;
     if (Record[Idx++]) {  // TemplateArgumentsAsWritten != 0
       unsigned NumTemplateArgLocs = Record[Idx++];
@@ -452,7 +452,7 @@
 
   // Read in the parameters.
   unsigned NumParams = Record[Idx++];
-  llvm::SmallVector<ParmVarDecl *, 16> Params;
+  SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
     Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
@@ -480,7 +480,7 @@
   MD->setResultTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
   MD->setEndLoc(ReadSourceLocation(Record, Idx));
   unsigned NumParams = Record[Idx++];
-  llvm::SmallVector<ParmVarDecl *, 16> Params;
+  SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
     Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
@@ -502,11 +502,11 @@
   
   // Read the directly referenced protocols and their SourceLocations.
   unsigned NumProtocols = Record[Idx++];
-  llvm::SmallVector<ObjCProtocolDecl *, 16> Protocols;
+  SmallVector<ObjCProtocolDecl *, 16> Protocols;
   Protocols.reserve(NumProtocols);
   for (unsigned I = 0; I != NumProtocols; ++I)
     Protocols.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  SmallVector<SourceLocation, 16> ProtoLocs;
   ProtoLocs.reserve(NumProtocols);
   for (unsigned I = 0; I != NumProtocols; ++I)
     ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
@@ -524,7 +524,7 @@
   
   // Read the ivars.
   unsigned NumIvars = Record[Idx++];
-  llvm::SmallVector<ObjCIvarDecl *, 16> IVars;
+  SmallVector<ObjCIvarDecl *, 16> IVars;
   IVars.reserve(NumIvars);
   for (unsigned I = 0; I != NumIvars; ++I)
     IVars.push_back(ReadDeclAs<ObjCIvarDecl>(Record, Idx));
@@ -553,11 +553,11 @@
   PD->setForwardDecl(Record[Idx++]);
   PD->setLocEnd(ReadSourceLocation(Record, Idx));
   unsigned NumProtoRefs = Record[Idx++];
-  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
   ProtoRefs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
     ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  SmallVector<SourceLocation, 16> ProtoLocs;
   ProtoLocs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
     ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
@@ -572,11 +572,11 @@
 void ASTDeclReader::VisitObjCClassDecl(ObjCClassDecl *CD) {
   VisitDecl(CD);
   unsigned NumClassRefs = Record[Idx++];
-  llvm::SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
+  SmallVector<ObjCInterfaceDecl *, 16> ClassRefs;
   ClassRefs.reserve(NumClassRefs);
   for (unsigned I = 0; I != NumClassRefs; ++I)
     ClassRefs.push_back(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
-  llvm::SmallVector<SourceLocation, 16> SLocs;
+  SmallVector<SourceLocation, 16> SLocs;
   SLocs.reserve(NumClassRefs);
   for (unsigned I = 0; I != NumClassRefs; ++I)
     SLocs.push_back(ReadSourceLocation(Record, Idx));
@@ -587,11 +587,11 @@
 void ASTDeclReader::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *FPD) {
   VisitDecl(FPD);
   unsigned NumProtoRefs = Record[Idx++];
-  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
   ProtoRefs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
     ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  SmallVector<SourceLocation, 16> ProtoLocs;
   ProtoLocs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
     ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
@@ -603,11 +603,11 @@
   VisitObjCContainerDecl(CD);
   CD->setClassInterface(ReadDeclAs<ObjCInterfaceDecl>(Record, Idx));
   unsigned NumProtoRefs = Record[Idx++];
-  llvm::SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
+  SmallVector<ObjCProtocolDecl *, 16> ProtoRefs;
   ProtoRefs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
     ProtoRefs.push_back(ReadDeclAs<ObjCProtocolDecl>(Record, Idx));
-  llvm::SmallVector<SourceLocation, 16> ProtoLocs;
+  SmallVector<SourceLocation, 16> ProtoLocs;
   ProtoLocs.reserve(NumProtoRefs);
   for (unsigned I = 0; I != NumProtoRefs; ++I)
     ProtoLocs.push_back(ReadSourceLocation(Record, Idx));
@@ -753,7 +753,7 @@
   BD->setBody(cast_or_null<CompoundStmt>(Reader.ReadStmt(F)));
   BD->setSignatureAsWritten(GetTypeSourceInfo(Record, Idx));
   unsigned NumParams = Record[Idx++];
-  llvm::SmallVector<ParmVarDecl *, 16> Params;
+  SmallVector<ParmVarDecl *, 16> Params;
   Params.reserve(NumParams);
   for (unsigned I = 0; I != NumParams; ++I)
     Params.push_back(ReadDeclAs<ParmVarDecl>(Record, Idx));
@@ -761,7 +761,7 @@
 
   bool capturesCXXThis = Record[Idx++];
   unsigned numCaptures = Record[Idx++];
-  llvm::SmallVector<BlockDecl::Capture, 16> captures;
+  SmallVector<BlockDecl::Capture, 16> captures;
   captures.reserve(numCaptures);
   for (unsigned i = 0; i != numCaptures; ++i) {
     VarDecl *decl = ReadDeclAs<VarDecl>(Record, Idx);
@@ -1109,7 +1109,7 @@
   if (D->getPreviousDeclaration() == 0) {
     // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of
     // the specializations.
-    llvm::SmallVector<serialization::DeclID, 2> SpecIDs;
+    SmallVector<serialization::DeclID, 2> SpecIDs;
     SpecIDs.push_back(0);
     
     // Specializations.
@@ -1147,7 +1147,7 @@
     if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(InstD)) {
       D->SpecializedTemplate = CTD;
     } else {
-      llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+      SmallVector<TemplateArgument, 8> TemplArgs;
       Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
       TemplateArgumentList *ArgList
         = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), 
@@ -1172,7 +1172,7 @@
     D->ExplicitInfo = ExplicitInfo;
   }
 
-  llvm::SmallVector<TemplateArgument, 8> TemplArgs;
+  SmallVector<TemplateArgument, 8> TemplArgs;
   Reader.ReadTemplateArgumentList(TemplArgs, F, Record, Idx);
   D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs.data(), 
                                                      TemplArgs.size());
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index f6c91b4..3559cce 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -114,7 +114,7 @@
 
 void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
   VisitStmt(S);
-  llvm::SmallVector<Stmt *, 16> Stmts;
+  SmallVector<Stmt *, 16> Stmts;
   unsigned NumStmts = Record[Idx++];
   while (NumStmts--)
     Stmts.push_back(Reader.ReadSubStmt());
@@ -259,7 +259,7 @@
     // Single declaration
     S->setDeclGroup(DeclGroupRef(ReadDecl(Record, Idx)));
   } else {
-    llvm::SmallVector<Decl *, 16> Decls;
+    SmallVector<Decl *, 16> Decls;
     Decls.reserve(Record.size() - Idx);    
     for (unsigned N = Record.size(); Idx != N; )
       Decls.push_back(ReadDecl(Record, Idx));
@@ -283,9 +283,9 @@
   S->setAsmString(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
 
   // Outputs and inputs
-  llvm::SmallVector<IdentifierInfo *, 16> Names;
-  llvm::SmallVector<StringLiteral*, 16> Constraints;
-  llvm::SmallVector<Stmt*, 16> Exprs;
+  SmallVector<IdentifierInfo *, 16> Names;
+  SmallVector<StringLiteral*, 16> Constraints;
+  SmallVector<Stmt*, 16> Exprs;
   for (unsigned I = 0, N = NumOutputs + NumInputs; I != N; ++I) {
     Names.push_back(Reader.GetIdentifierInfo(Record, Idx));
     Constraints.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
@@ -293,7 +293,7 @@
   }
 
   // Constraints
-  llvm::SmallVector<StringLiteral*, 16> Clobbers;
+  SmallVector<StringLiteral*, 16> Clobbers;
   for (unsigned I = 0; I != NumClobbers; ++I)
     Clobbers.push_back(cast_or_null<StringLiteral>(Reader.ReadSubStmt()));
 
@@ -634,7 +634,7 @@
   E->setEqualOrColonLoc(ReadSourceLocation(Record, Idx));
   E->setGNUSyntax(Record[Idx++]);
 
-  llvm::SmallVector<Designator, 4> Designators;
+  SmallVector<Designator, 4> Designators;
   while (Idx < Record.size()) {
     switch ((DesignatorTypes)Record[Idx++]) {
     case DESIG_FIELD_DECL: {
@@ -729,7 +729,7 @@
 
 void ASTStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) {
   VisitExpr(E);
-  llvm::SmallVector<Expr *, 16> Exprs;
+  SmallVector<Expr *, 16> Exprs;
   unsigned NumExprs = Record[Idx++];
   while (NumExprs--)
     Exprs.push_back(Reader.ReadSubExpr());
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index e291b7f..7620cb7 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -53,15 +53,15 @@
 using namespace clang::serialization;
 
 template <typename T, typename Allocator>
-static llvm::StringRef data(const std::vector<T, Allocator> &v) {
-  if (v.empty()) return llvm::StringRef();
-  return llvm::StringRef(reinterpret_cast<const char*>(&v[0]),
+static StringRef data(const std::vector<T, Allocator> &v) {
+  if (v.empty()) return StringRef();
+  return StringRef(reinterpret_cast<const char*>(&v[0]),
                          sizeof(T) * v.size());
 }
 
 template <typename T>
-static llvm::StringRef data(const llvm::SmallVectorImpl<T> &v) {
-  return llvm::StringRef(reinterpret_cast<const char*>(v.data()),
+static StringRef data(const SmallVectorImpl<T> &v) {
+  return StringRef(reinterpret_cast<const char*>(v.data()),
                          sizeof(T) * v.size());
 }
 
@@ -1137,7 +1137,7 @@
   }
 
   std::pair<unsigned,unsigned>
-    EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
+    EmitKeyDataLength(raw_ostream& Out, const char *path,
                       data_type_ref Data) {
     unsigned StrLen = strlen(path);
     clang::io::Emit16(Out, StrLen);
@@ -1146,11 +1146,11 @@
     return std::make_pair(StrLen + 1, DataLen);
   }
 
-  void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
+  void EmitKey(raw_ostream& Out, const char *path, unsigned KeyLen) {
     Out.write(path, KeyLen);
   }
 
-  void EmitData(llvm::raw_ostream &Out, key_type_ref,
+  void EmitData(raw_ostream &Out, key_type_ref,
                 data_type_ref Data, unsigned DataLen) {
     using namespace clang::io;
     uint64_t Start = Out.tell(); (void)Start;
@@ -1175,7 +1175,7 @@
   for (MemorizeStatCalls::iterator Stat = StatCalls.begin(),
                                 StatEnd = StatCalls.end();
        Stat != StatEnd; ++Stat, ++NumStatEntries) {
-    llvm::StringRef Filename = Stat->first();
+    StringRef Filename = Stat->first();
     Generator.insert(Filename.data(), Stat->second);
   }
 
@@ -1290,7 +1290,7 @@
     }
     
     std::pair<unsigned,unsigned>
-    EmitKeyDataLength(llvm::raw_ostream& Out, const char *path,
+    EmitKeyDataLength(raw_ostream& Out, const char *path,
                       data_type_ref Data) {
       unsigned StrLen = strlen(path);
       clang::io::Emit16(Out, StrLen);
@@ -1299,11 +1299,11 @@
       return std::make_pair(StrLen + 1, DataLen);
     }
     
-    void EmitKey(llvm::raw_ostream& Out, const char *path, unsigned KeyLen) {
+    void EmitKey(raw_ostream& Out, const char *path, unsigned KeyLen) {
       Out.write(path, KeyLen);
     }
     
-    void EmitData(llvm::raw_ostream &Out, key_type_ref,
+    void EmitData(raw_ostream &Out, key_type_ref,
                   data_type_ref Data, unsigned DataLen) {
       using namespace clang::io;
       uint64_t Start = Out.tell(); (void)Start;
@@ -1330,7 +1330,7 @@
 ///
 /// \param Chain Whether we're creating a chained AST file.
 void ASTWriter::WriteHeaderSearch(HeaderSearch &HS, StringRef isysroot) {
-  llvm::SmallVector<const FileEntry *, 16> FilesByUID;
+  SmallVector<const FileEntry *, 16> FilesByUID;
   HS.getFileMgr().GetUniqueIDMapping(FilesByUID);
   
   if (FilesByUID.size() > HS.header_file_size())
@@ -1338,7 +1338,7 @@
   
   HeaderFileInfoTrait GeneratorTrait(*this, HS);
   OnDiskChainedHashTableGenerator<HeaderFileInfoTrait> Generator;  
-  llvm::SmallVector<const char *, 4> SavedStrings;
+  SmallVector<const char *, 4> SavedStrings;
   unsigned NumHeaderSearchEntries = 0;
   for (unsigned UID = 0, LastUID = FilesByUID.size(); UID != LastUID; ++UID) {
     const FileEntry *File = FilesByUID[UID];
@@ -1492,11 +1492,11 @@
           = Content->getBuffer(PP.getDiagnostics(), PP.getSourceManager());
         const char *Name = Buffer->getBufferIdentifier();
         Stream.EmitRecordWithBlob(SLocBufferAbbrv, Record,
-                                  llvm::StringRef(Name, strlen(Name) + 1));
+                                  StringRef(Name, strlen(Name) + 1));
         Record.clear();
         Record.push_back(SM_SLOC_BUFFER_BLOB);
         Stream.EmitRecordWithBlob(SLocBufferBlobAbbrv, Record,
-                                  llvm::StringRef(Buffer->getBufferStart(),
+                                  StringRef(Buffer->getBufferStart(),
                                                   Buffer->getBufferSize() + 1));
 
         if (strcmp(Name, "<built-in>") == 0) {
@@ -1546,8 +1546,8 @@
     // The map consists solely of a blob with the following format:
     // *(offset:i32 len:i16 name:len*i8)
     // Sorted by offset.
-    typedef std::pair<uint32_t, llvm::StringRef> ModuleOffset;
-    llvm::SmallVector<ModuleOffset, 16> Modules;
+    typedef std::pair<uint32_t, StringRef> ModuleOffset;
+    SmallVector<ModuleOffset, 16> Modules;
     Modules.reserve(Chain->Modules.size());
     for (llvm::StringMap<Module*>::const_iterator
              I = Chain->Modules.begin(), E = Chain->Modules.end();
@@ -1564,7 +1564,7 @@
     llvm::SmallString<2048> Buffer;
     {
       llvm::raw_svector_ostream Out(Buffer);
-      for (llvm::SmallVector<ModuleOffset, 16>::iterator I = Modules.begin(),
+      for (SmallVector<ModuleOffset, 16>::iterator I = Modules.begin(),
                                                          E = Modules.end();
            I != E; ++I) {
         io::Emit32(Out, I->first);
@@ -1677,7 +1677,7 @@
   PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
 
   // Construct the list of macro definitions that need to be serialized.
-  llvm::SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2> 
+  SmallVector<std::pair<const IdentifierInfo *, MacroInfo *>, 2> 
     MacrosToEmit;
   llvm::SmallPtrSet<const IdentifierInfo*, 4> MacroDefinitionsSeen;
   for (Preprocessor::macro_iterator I = PP.macro_begin(Chain == 0), 
@@ -2010,7 +2010,7 @@
   uint64_t Offset = Stream.GetCurrentBitNo();
   RecordData Record;
   Record.push_back(DECL_CONTEXT_LEXICAL);
-  llvm::SmallVector<KindDeclIDPair, 64> Decls;
+  SmallVector<KindDeclIDPair, 64> Decls;
   for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
          D != DEnd; ++D)
     Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D)));
@@ -2073,7 +2073,7 @@
   }
 
   std::pair<unsigned,unsigned>
-    EmitKeyDataLength(llvm::raw_ostream& Out, Selector Sel,
+    EmitKeyDataLength(raw_ostream& Out, Selector Sel,
                       data_type_ref Methods) {
     unsigned KeyLen = 2 + (Sel.getNumArgs()? Sel.getNumArgs() * 4 : 4);
     clang::io::Emit16(Out, KeyLen);
@@ -2090,7 +2090,7 @@
     return std::make_pair(KeyLen, DataLen);
   }
 
-  void EmitKey(llvm::raw_ostream& Out, Selector Sel, unsigned) {
+  void EmitKey(raw_ostream& Out, Selector Sel, unsigned) {
     uint64_t Start = Out.tell();
     assert((Start >> 32) == 0 && "Selector key offset too large");
     Writer.SetSelectorOffset(Sel, Start);
@@ -2103,7 +2103,7 @@
                     Writer.getIdentifierRef(Sel.getIdentifierInfoForSlot(I)));
   }
 
-  void EmitData(llvm::raw_ostream& Out, key_type_ref,
+  void EmitData(raw_ostream& Out, key_type_ref,
                 data_type_ref Methods, unsigned DataLen) {
     uint64_t Start = Out.tell(); (void)Start;
     clang::io::Emit32(Out, Methods.ID);
@@ -2292,7 +2292,7 @@
   }
 
   std::pair<unsigned,unsigned>
-    EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II,
+    EmitKeyDataLength(raw_ostream& Out, const IdentifierInfo* II,
                       IdentID ID) {
     unsigned KeyLen = II->getLength() + 1;
     unsigned DataLen = 4; // 4 bytes for the persistent ID << 1
@@ -2314,7 +2314,7 @@
     return std::make_pair(KeyLen, DataLen);
   }
 
-  void EmitKey(llvm::raw_ostream& Out, const IdentifierInfo* II,
+  void EmitKey(raw_ostream& Out, const IdentifierInfo* II,
                unsigned KeyLen) {
     // Record the location of the key data.  This is used when generating
     // the mapping from persistent IDs to strings.
@@ -2322,7 +2322,7 @@
     Out.write(II->getNameStart(), KeyLen);
   }
 
-  void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II,
+  void EmitData(raw_ostream& Out, const IdentifierInfo* II,
                 IdentID ID, unsigned) {
     if (!isInterestingIdentifier(II)) {
       clang::io::Emit32(Out, ID << 1);
@@ -2352,9 +2352,9 @@
     // adds declarations to the end of the list (so we need to see the
     // struct "status" before the function "status").
     // Only emit declarations that aren't from a chained PCH, though.
-    llvm::SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
+    SmallVector<Decl *, 16> Decls(IdentifierResolver::begin(II),
                                         IdentifierResolver::end());
-    for (llvm::SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
+    for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
                                                       DEnd = Decls.rend();
          D != DEnd; ++D)
       clang::io::Emit32(Out, Writer.getDeclID(*D));
@@ -2485,7 +2485,7 @@
   }
 
   std::pair<unsigned,unsigned>
-    EmitKeyDataLength(llvm::raw_ostream& Out, DeclarationName Name,
+    EmitKeyDataLength(raw_ostream& Out, DeclarationName Name,
                       data_type_ref Lookup) {
     unsigned KeyLen = 1;
     switch (Name.getNameKind()) {
@@ -2514,7 +2514,7 @@
     return std::make_pair(KeyLen, DataLen);
   }
 
-  void EmitKey(llvm::raw_ostream& Out, DeclarationName Name, unsigned) {
+  void EmitKey(raw_ostream& Out, DeclarationName Name, unsigned) {
     using namespace clang::io;
 
     assert(Name.getNameKind() < 0x100 && "Invalid name kind ?");
@@ -2545,7 +2545,7 @@
     }
   }
 
-  void EmitData(llvm::raw_ostream& Out, key_type_ref,
+  void EmitData(raw_ostream& Out, key_type_ref,
                 data_type Lookup, unsigned DataLen) {
     uint64_t Start = Out.tell(); (void)Start;
     clang::io::Emit16(Out, Lookup.second - Lookup.first);
@@ -2705,7 +2705,7 @@
   }
 }
 
-void ASTWriter::AddString(llvm::StringRef Str, RecordDataImpl &Record) {
+void ASTWriter::AddString(StringRef Str, RecordDataImpl &Record) {
   Record.push_back(Str.size());
   Record.insert(Record.end(), Str.begin(), Str.end());
 }
@@ -2799,7 +2799,7 @@
   // declarations) for builtins.
   {
     IdentifierTable &Table = PP.getIdentifierTable();
-    llvm::SmallVector<const char *, 32> BuiltinNames;
+    SmallVector<const char *, 32> BuiltinNames;
     Context.BuiltinInfo.GetBuiltinNames(BuiltinNames,
                                         Context.getLangOptions().NoBuiltin);
     for (unsigned I = 0, N = BuiltinNames.size(); I != N; ++I)
@@ -3047,7 +3047,7 @@
   // We don't start with the translation unit, but with its decls that
   // don't come from the chained PCH.
   const TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
-  llvm::SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
+  SmallVector<KindDeclIDPair, 64> NewGlobalDecls;
   for (DeclContext::decl_iterator I = TU->noload_decls_begin(),
                                   E = TU->noload_decls_end();
        I != E; ++I) {
@@ -3307,7 +3307,7 @@
     return;
 
   RecordData Record;
-  for (llvm::SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator
+  for (SmallVector<std::pair<DeclID, uint64_t>, 16>::iterator
            I = ReplacedDecls.begin(), E = ReplacedDecls.end(); I != E; ++I) {
     Record.push_back(I->first);
     Record.push_back(I->second);
@@ -3617,7 +3617,7 @@
                                        RecordDataImpl &Record) {
   // Nested name specifiers usually aren't too long. I think that 8 would
   // typically accommodate the vast majority.
-  llvm::SmallVector<NestedNameSpecifier *, 8> NestedNames;
+  SmallVector<NestedNameSpecifier *, 8> NestedNames;
 
   // Push each of the NNS's onto a stack for serialization in reverse order.
   while (NNS) {
@@ -3660,7 +3660,7 @@
                                           RecordDataImpl &Record) {
   // Nested name specifiers usually aren't too long. I think that 8 would
   // typically accommodate the vast majority.
-  llvm::SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
+  SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
 
   // Push each of the nested-name-specifiers's onto a stack for
   // serialization in reverse order.
diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp
index 2b83494..45f8a32 100644
--- a/lib/Serialization/ASTWriterDecl.cpp
+++ b/lib/Serialization/ASTWriterDecl.cpp
@@ -1648,7 +1648,7 @@
   if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset);
 
   if (!W.Code)
-    llvm::report_fatal_error(llvm::StringRef("unexpected declaration kind '") +
+    llvm::report_fatal_error(StringRef("unexpected declaration kind '") +
                             D->getDeclKindName() + "'");
   Stream.EmitRecord(W.Code, Record, W.AbbrevToUse);
 
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 1d73ed4..0b5bc1f 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1428,7 +1428,7 @@
   }
 
   // Redirect ASTWriter::AddStmt to collect sub stmts.
-  llvm::SmallVector<Stmt *, 16> SubStmts;
+  SmallVector<Stmt *, 16> SubStmts;
   CollectedStmts = &SubStmts;
 
   Writer.Code = serialization::STMT_NULL_PTR;
diff --git a/lib/Serialization/ChainedIncludesSource.cpp b/lib/Serialization/ChainedIncludesSource.cpp
index a356dd6..a4a9f08 100644
--- a/lib/Serialization/ChainedIncludesSource.cpp
+++ b/lib/Serialization/ChainedIncludesSource.cpp
@@ -26,7 +26,7 @@
 using namespace clang;
 
 static ASTReader *createASTReader(CompilerInstance &CI,
-                                  llvm::StringRef pchFile,
+                                  StringRef pchFile,
                                   llvm::MemoryBuffer **memBufs,
                                   unsigned numBufs,
                              ASTDeserializationListener *deserialListener = 0) {
@@ -62,7 +62,7 @@
   llvm::OwningPtr<ChainedIncludesSource> source(new ChainedIncludesSource());
   InputKind IK = CI.getFrontendOpts().Inputs[0].first;
 
-  llvm::SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
+  SmallVector<llvm::MemoryBuffer *, 4> serialBufs;
 
   for (unsigned i = 0, e = includes.size(); i != e; ++i) {
     bool firstInclude = (i == 0);
@@ -98,7 +98,7 @@
                                                  &Clang->getPreprocessor());
     Clang->createASTContext();
 
-    llvm::SmallVector<char, 256> serialAST;
+    SmallVector<char, 256> serialAST;
     llvm::raw_svector_ostream OS(serialAST);
     llvm::OwningPtr<ASTConsumer> consumer;
     consumer.reset(new PCHGenerator(Clang->getPreprocessor(), "-",
@@ -115,10 +115,10 @@
                                              PP.getLangOptions());
     } else {
       assert(!serialBufs.empty());
-      llvm::SmallVector<llvm::MemoryBuffer *, 4> bufs;
+      SmallVector<llvm::MemoryBuffer *, 4> bufs;
       for (unsigned si = 0, se = serialBufs.size(); si != se; ++si) {
         bufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
-                             llvm::StringRef(serialBufs[si]->getBufferStart(),
+                             StringRef(serialBufs[si]->getBufferStart(),
                                              serialBufs[si]->getBufferSize())));
       }
       std::string pchName = includes[i-1];
@@ -140,7 +140,7 @@
     OS.flush();
     Clang->getDiagnosticClient().EndSourceFile();
     serialBufs.push_back(
-      llvm::MemoryBuffer::getMemBufferCopy(llvm::StringRef(serialAST.data(),
+      llvm::MemoryBuffer::getMemBufferCopy(StringRef(serialAST.data(),
                                                            serialAST.size())));
     source->CIs.push_back(Clang.take());
   }
@@ -188,7 +188,7 @@
 ExternalLoadResult 
 ChainedIncludesSource::FindExternalLexicalDecls(const DeclContext *DC,
                                       bool (*isKindWeWant)(Decl::Kind),
-                                      llvm::SmallVectorImpl<Decl*> &Result) {
+                                      SmallVectorImpl<Decl*> &Result) {
   return getFinalReader().FindExternalLexicalDecls(DC, isKindWeWant, Result);
 }
 void ChainedIncludesSource::CompleteType(TagDecl *Tag) {
diff --git a/lib/Serialization/GeneratePCH.cpp b/lib/Serialization/GeneratePCH.cpp
index 16352c8..3f3674e 100644
--- a/lib/Serialization/GeneratePCH.cpp
+++ b/lib/Serialization/GeneratePCH.cpp
@@ -30,7 +30,7 @@
                            const std::string &OutputFile,
                            bool Chaining,
                            StringRef isysroot,
-                           llvm::raw_ostream *OS)
+                           raw_ostream *OS)
   : PP(PP), OutputFile(OutputFile), isysroot(isysroot.str()), Out(OS), 
     SemaPtr(0), StatCalls(0), Stream(Buffer), Writer(Stream), Chaining(Chaining) {
   // Install a stat() listener to keep track of all of the stat()
