diff options
Diffstat (limited to 'lib/Frontend')
| -rw-r--r-- | lib/Frontend/ASTUnit.cpp | 35 | ||||
| -rw-r--r-- | lib/Frontend/AnalysisConsumer.cpp | 5 | ||||
| -rw-r--r-- | lib/Frontend/CacheTokens.cpp | 24 | ||||
| -rw-r--r-- | lib/Frontend/GeneratePCH.cpp | 2 | ||||
| -rw-r--r-- | lib/Frontend/InitHeaderSearch.cpp | 13 | ||||
| -rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 16 | ||||
| -rw-r--r-- | lib/Frontend/PCHReader.cpp | 270 | ||||
| -rw-r--r-- | lib/Frontend/PCHReaderDecl.cpp | 81 | ||||
| -rw-r--r-- | lib/Frontend/PCHWriter.cpp | 273 | ||||
| -rw-r--r-- | lib/Frontend/PCHWriterDecl.cpp | 196 | ||||
| -rw-r--r-- | lib/Frontend/PrintPreprocessedOutput.cpp | 4 | ||||
| -rw-r--r-- | lib/Frontend/RewriteMacros.cpp | 8 | ||||
| -rw-r--r-- | lib/Frontend/RewriteObjC.cpp | 18 | ||||
| -rw-r--r-- | lib/Frontend/TextDiagnosticPrinter.cpp | 6 | 
14 files changed, 552 insertions, 399 deletions
| diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index d3475b5236d9..c0415bf550f8 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -21,11 +21,20 @@  #include "clang/Basic/TargetInfo.h"  #include "clang/Basic/Diagnostic.h"  #include "llvm/Support/Compiler.h" +#include "llvm/System/Path.h"  using namespace clang; -ASTUnit::ASTUnit(Diagnostic &_Diags) : Diags(_Diags) { } -ASTUnit::~ASTUnit() { } +ASTUnit::ASTUnit(DiagnosticClient *diagClient) : tempFile(false) {       +  Diags.setClient(diagClient ? diagClient : new TextDiagnosticBuffer()); +} +ASTUnit::~ASTUnit() {  +  if (tempFile) +    llvm::sys::Path(getPCHFileName()).eraseFromDisk(); +   +  //  The ASTUnit object owns the DiagnosticClient. +  delete Diags.getClient(); +}  namespace { @@ -80,17 +89,18 @@ const std::string &ASTUnit::getOriginalSourceFileName() {    return dyn_cast<PCHReader>(Ctx->getExternalSource())->getOriginalSourceFile();  } -FileManager &ASTUnit::getFileManager() { -  return HeaderInfo->getFileMgr(); +const std::string &ASTUnit::getPCHFileName() { +  return dyn_cast<PCHReader>(Ctx->getExternalSource())->getFileName();  }  ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, -                                  Diagnostic &Diags, -                                  FileManager &FileMgr, -                                  std::string *ErrMsg) { -  llvm::OwningPtr<ASTUnit> AST(new ASTUnit(Diags)); - -  AST->HeaderInfo.reset(new HeaderSearch(FileMgr)); +                                  std::string *ErrMsg, +                                  DiagnosticClient *diagClient, +                                  bool OnlyLocalDecls, +                                  bool UseBumpAllocator) { +  llvm::OwningPtr<ASTUnit> AST(new ASTUnit(diagClient)); +  AST->OnlyLocalDecls = OnlyLocalDecls; +  AST->HeaderInfo.reset(new HeaderSearch(AST->getFileManager()));    // Gather Info for preprocessor construction later on. @@ -103,7 +113,8 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,    llvm::OwningPtr<PCHReader> Reader;    llvm::OwningPtr<ExternalASTSource> Source; -  Reader.reset(new PCHReader(AST->getSourceManager(), FileMgr, AST->Diags)); +  Reader.reset(new PCHReader(AST->getSourceManager(), AST->getFileManager(), +                             AST->Diags));    Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple,                                             Predefines, Counter)); @@ -138,7 +149,7 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename,                                  PP.getIdentifierTable(),                                  PP.getSelectorTable(),                                  PP.getBuiltinInfo(), -                                /* FreeMemory = */ true, +                                /* FreeMemory = */ !UseBumpAllocator,                                  /* size_reserve = */0));    ASTContext &Context = *AST->Ctx.get(); diff --git a/lib/Frontend/AnalysisConsumer.cpp b/lib/Frontend/AnalysisConsumer.cpp index 276599470b78..55f274005909 100644 --- a/lib/Frontend/AnalysisConsumer.cpp +++ b/lib/Frontend/AnalysisConsumer.cpp @@ -196,7 +196,7 @@ void AnalysisConsumer::HandleTopLevelSingleDecl(Decl *D) {      case Decl::Function: {        FunctionDecl* FD = cast<FunctionDecl>(D); -      if (Opts.AnalyzeSpecificFunction.size() > 0 && +      if (!Opts.AnalyzeSpecificFunction.empty() &&            Opts.AnalyzeSpecificFunction != FD->getIdentifier()->getName())          break; @@ -273,6 +273,9 @@ void AnalysisConsumer::HandleCode(Decl *D, Stmt* Body, Actions& actions) {        !Ctx->getSourceManager().isFromMainFile(D->getLocation()))      return; +  // Clear the AnalysisManager of old AnalysisContexts. +  Mgr->ClearContexts(); +      // Dispatch on the actions.    for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I)      (*I)(*Mgr, D);   diff --git a/lib/Frontend/CacheTokens.cpp b/lib/Frontend/CacheTokens.cpp index e7fc5660ad20..339a1c466bc9 100644 --- a/lib/Frontend/CacheTokens.cpp +++ b/lib/Frontend/CacheTokens.cpp @@ -20,11 +20,12 @@  #include "clang/Basic/OnDiskHashTable.h"  #include "clang/Lex/Lexer.h"  #include "clang/Lex/Preprocessor.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/raw_ostream.h"  #include "llvm/System/Path.h" -#include "llvm/ADT/StringMap.h"  // FIXME: put this somewhere else?  #ifndef S_ISDIR @@ -69,7 +70,7 @@ public:    bool isFile() const { return Kind == IsFE; } -  const char* getCString() const { +  llvm::StringRef getString() const {      return Kind == IsFE ? FE->getName() : Path;    } @@ -113,14 +114,14 @@ public:    typedef const PTHEntry& data_type_ref;    static unsigned ComputeHash(PTHEntryKeyVariant V) { -    return BernsteinHash(V.getCString()); +    return llvm::HashString(V.getString());    }    static std::pair<unsigned,unsigned>    EmitKeyDataLength(llvm::raw_ostream& Out, PTHEntryKeyVariant V,                      const PTHEntry& E) { -    unsigned n = strlen(V.getCString()) + 1 + 1; +    unsigned n = V.getString().size() + 1 + 1;      ::Emit16(Out, n);      unsigned m = V.getRepresentationLength() + (V.isFile() ? 4 + 4 : 0); @@ -133,7 +134,7 @@ public:      // Emit the entry kind.      ::Emit8(Out, (unsigned) V.getKind());      // Emit the string. -    Out.write(V.getCString(), n - 1); +    Out.write(V.getString().data(), n - 1);    }    static void EmitData(llvm::raw_ostream& Out, PTHEntryKeyVariant V, @@ -516,7 +517,7 @@ public:    ~StatListener() {}    int stat(const char *path, struct stat *buf) { -    int result = ::stat(path, buf); +    int result = StatSysCallCache::stat(path, buf);      if (result != 0) // Failed 'stat'.        PM.insert(path, PTHEntry()); @@ -553,7 +554,8 @@ void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {    PTHWriter PW(*OS, PP);    // Install the 'stat' system call listener in the FileManager. -  PP.getFileManager().setStatCache(new StatListener(PW.getPM())); +  StatListener *StatCache = new StatListener(PW.getPM()); +  PP.getFileManager().addStatCache(StatCache, /*AtBeginning=*/true);    // Lex through the entire file.  This will populate SourceManager with    // all of the header information. @@ -562,7 +564,7 @@ void clang::CacheTokens(Preprocessor &PP, llvm::raw_fd_ostream* OS) {    do { PP.Lex(Tok); } while (Tok.isNot(tok::eof));    // Generate the PTH file. -  PP.getFileManager().setStatCache(0); +  PP.getFileManager().removeStatCache(StatCache);    PW.GeneratePTH(&MainFileName);  } @@ -584,12 +586,12 @@ public:    typedef data_type data_type_ref;    static unsigned ComputeHash(PTHIdKey* key) { -    return BernsteinHash(key->II->getName()); +    return llvm::HashString(key->II->getName());    }    static std::pair<unsigned,unsigned>    EmitKeyDataLength(llvm::raw_ostream& Out, const PTHIdKey* key, uint32_t) { -    unsigned n = strlen(key->II->getName()) + 1; +    unsigned n = key->II->getLength() + 1;      ::Emit16(Out, n);      return std::make_pair(n, sizeof(uint32_t));    } @@ -598,7 +600,7 @@ public:      // Record the location of the key data.  This is used when generating      // the mapping from persistent IDs to strings.      key->FileOffset = Out.tell(); -    Out.write(key->II->getName(), n); +    Out.write(key->II->getNameStart(), n);    }    static void EmitData(llvm::raw_ostream& Out, PTHIdKey*, uint32_t pID, diff --git a/lib/Frontend/GeneratePCH.cpp b/lib/Frontend/GeneratePCH.cpp index bc45cc422585..0e4f83ff09f5 100644 --- a/lib/Frontend/GeneratePCH.cpp +++ b/lib/Frontend/GeneratePCH.cpp @@ -53,7 +53,7 @@ PCHGenerator::PCHGenerator(const Preprocessor &PP,    // Install a stat() listener to keep track of all of the stat()    // calls.    StatCalls = new MemorizeStatCalls; -  PP.getFileManager().setStatCache(StatCalls); +  PP.getFileManager().addStatCache(StatCalls, /*AtBeginning=*/true);  }  void PCHGenerator::HandleTranslationUnit(ASTContext &Ctx) { diff --git a/lib/Frontend/InitHeaderSearch.cpp b/lib/Frontend/InitHeaderSearch.cpp index 822a5baf5972..25316bed9fb4 100644 --- a/lib/Frontend/InitHeaderSearch.cpp +++ b/lib/Frontend/InitHeaderSearch.cpp @@ -369,6 +369,12 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,                                        "x86_64-unknown-linux-gnu",                                        "x86_64-unknown-linux-gnu",                                        triple); +          // Gentoo x86 2009.1 stable +          AddGnuCPlusPlusIncludePaths( +             "/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4", +             "i686-pc-linux-gnu", +             "i686-pc-linux-gnu", +             triple);            // Gentoo x86 2009.0 stable            AddGnuCPlusPlusIncludePaths(               "/usr/lib/gcc/i686-pc-linux-gnu/4.3.2/include/g++-v4", @@ -386,6 +392,11 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,                                        "i486-pc-linux-gnu",                                        "i486-pc-linux-gnu",                                        triple); +          // Ubuntu 9.04 +          AddGnuCPlusPlusIncludePaths("/usr/include/c++/4.3", +                                      "i486-linux-gnu", +                                      "i486-linux-gnu", +                                      triple);            // Gentoo amd64 stable            AddGnuCPlusPlusIncludePaths(               "/usr/lib/gcc/x86_64-pc-linux-gnu/4.1.2/include/g++-v4", @@ -400,6 +411,8 @@ void InitHeaderSearch::AddDefaultSystemIncludePaths(const LangOptions &Lang,            AddPath("/usr/include/c++/4.2", System, true, false, false);            break;          case llvm::Triple::Solaris: +          // Solaris - Fall though.. +        case llvm::Triple::AuroraUX:            // AuroraUX            AddGnuCPlusPlusIncludePaths("/opt/gcc4/include/c++/4.2.4",                                        "i386-pc-solaris2.11", diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 0f3b4b8236be..b1a0a5ee8d51 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -317,13 +317,22 @@ static void InitializePredefinedMacros(const TargetInfo &TI,      DefineBuiltinMacro(Buf, "_GNU_SOURCE=1");    } -  // Filter out some microsoft extensions when trying to parse in ms-compat -  // mode.    if (LangOpts.Microsoft) { +    // Filter out some microsoft extensions when trying to parse in ms-compat +    // mode.      DefineBuiltinMacro(Buf, "__int8=__INT8_TYPE__");      DefineBuiltinMacro(Buf, "__int16=__INT16_TYPE__");      DefineBuiltinMacro(Buf, "__int32=__INT32_TYPE__");      DefineBuiltinMacro(Buf, "__int64=__INT64_TYPE__"); +    // Work around some issues with Visual C++ headerws. +    if (LangOpts.CPlusPlus) { +      // Since we define wchar_t in C++ mode. +      DefineBuiltinMacro(Buf, "_WCHAR_T_DEFINED=1"); +      DefineBuiltinMacro(Buf, "_NATIVE_WCHAR_T_DEFINED=1"); +      // FIXME:  This should be temporary until we have a __pragma +      // solution, to avoid some errors flagged in VC++ headers. +      DefineBuiltinMacro(Buf, "_CRT_SECURE_CPP_OVERLOAD_SECURE_NAMES=0"); +    }    }    if (LangOpts.Optimize) @@ -365,8 +374,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,    DefineType("__INTPTR_TYPE__", TI.getIntPtrType(), Buf);    DefineType("__SIZE_TYPE__", TI.getSizeType(), Buf);    DefineType("__WCHAR_TYPE__", TI.getWCharType(), Buf); -  // FIXME: TargetInfo hookize __WINT_TYPE__. -  DefineBuiltinMacro(Buf, "__WINT_TYPE__=int"); +  DefineType("__WINT_TYPE__", TI.getWIntType(), Buf);    DefineFloatMacros(Buf, "FLT", &TI.getFloatFormat());    DefineFloatMacros(Buf, "DBL", &TI.getDoubleFormat()); diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index e61668dd3177..9c6059b1c7c0 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -18,6 +18,7 @@  #include "clang/AST/ASTContext.h"  #include "clang/AST/Expr.h"  #include "clang/AST/Type.h" +#include "clang/AST/TypeLocVisitor.h"  #include "clang/Lex/MacroInfo.h"  #include "clang/Lex/Preprocessor.h"  #include "clang/Lex/HeaderSearch.h" @@ -27,6 +28,7 @@  #include "clang/Basic/FileManager.h"  #include "clang/Basic/TargetInfo.h"  #include "clang/Basic/Version.h" +#include "llvm/ADT/StringExtras.h"  #include "llvm/Bitcode/BitstreamReader.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/MemoryBuffer.h" @@ -335,8 +337,6 @@ void PCHValidator::ReadCounter(unsigned Value) {    PP.setCounterValue(Value);  } - -  //===----------------------------------------------------------------------===//  // PCH reader implementation  //===----------------------------------------------------------------------===// @@ -345,7 +345,7 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,                       const char *isysroot)    : Listener(new PCHValidator(PP, *this)), SourceMgr(PP.getSourceManager()),      FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()), -    SemaObj(0), PP(&PP), Context(Context), Consumer(0), +    SemaObj(0), PP(&PP), Context(Context), StatCache(0), Consumer(0),      IdentifierTableData(0), IdentifierLookupTable(0),      IdentifierOffsets(0),      MethodPoolLookupTable(0), MethodPoolLookupTableData(0), @@ -362,7 +362,7 @@ PCHReader::PCHReader(Preprocessor &PP, ASTContext *Context,  PCHReader::PCHReader(SourceManager &SourceMgr, FileManager &FileMgr,                       Diagnostic &Diags, const char *isysroot)    : SourceMgr(SourceMgr), FileMgr(FileMgr), Diags(Diags), -    SemaObj(0), PP(0), Context(0), Consumer(0), +    SemaObj(0), PP(0), Context(0), StatCache(0), Consumer(0),      IdentifierTableData(0), IdentifierLookupTable(0),      IdentifierOffsets(0),      MethodPoolLookupTable(0), MethodPoolLookupTableData(0), @@ -383,7 +383,7 @@ Expr *PCHReader::ReadDeclExpr() {  }  Expr *PCHReader::ReadTypeExpr() { -  return dyn_cast_or_null<Expr>(ReadStmt(Stream)); +  return dyn_cast_or_null<Expr>(ReadStmt(DeclsCursor));  } @@ -411,7 +411,7 @@ public:      unsigned R = 5381;      for (unsigned I = 0; I != N; ++I)        if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I)) -        R = clang::BernsteinHashPartial(II->getName(), II->getLength(), R); +        R = llvm::HashString(II->getName(), R);      return R;    } @@ -521,7 +521,7 @@ public:    }    static unsigned ComputeHash(const internal_key_type& a) { -    return BernsteinHash(a.first, a.second); +    return llvm::HashString(llvm::StringRef(a.first, a.second));    }    // This hopefully will just get inlined and removed by the optimizer. @@ -731,7 +731,7 @@ class VISIBILITY_HIDDEN PCHStatLookupTrait {    typedef PCHStatData data_type;    static unsigned ComputeHash(const char *path) { -    return BernsteinHash(path); +    return llvm::HashString(path);    }    static internal_key_type GetInternalKey(const char *path) { return path; } @@ -794,7 +794,7 @@ public:      // If we don't get a hit in the PCH file just forward to 'stat'.      if (I == Cache->end()) {        ++NumStatMisses; -      return ::stat(path, buf); +      return StatSysCallCache::stat(path, buf);      }      ++NumStatHits; @@ -1158,15 +1158,7 @@ PCHReader::ReadPCHBlock() {      if (Code == llvm::bitc::ENTER_SUBBLOCK) {        switch (Stream.ReadSubBlockID()) { -      case pch::TYPES_BLOCK_ID: // Skip types block (lazily loaded) -      default:  // Skip unknown content. -        if (Stream.SkipBlock()) { -          Error("malformed block record in PCH file"); -          return Failure; -        } -        break; - -      case pch::DECLS_BLOCK_ID: +      case pch::DECLTYPES_BLOCK_ID:          // We lazily load the decls block, but we want to set up the          // DeclsCursor cursor to point into it.  Clone our current bitcode          // cursor to it, enter the block and read the abbrevs in that block. @@ -1174,7 +1166,7 @@ PCHReader::ReadPCHBlock() {          DeclsCursor = Stream;          if (Stream.SkipBlock() ||  // Skip with the main cursor.              // Read the abbrevs. -            ReadBlockAbbrevs(DeclsCursor, pch::DECLS_BLOCK_ID)) { +            ReadBlockAbbrevs(DeclsCursor, pch::DECLTYPES_BLOCK_ID)) {            Error("malformed block record in PCH file");            return Failure;          } @@ -1352,13 +1344,16 @@ PCHReader::ReadPCHBlock() {        }        break; -    case pch::STAT_CACHE: -      FileMgr.setStatCache( -                  new PCHStatCache((const unsigned char *)BlobStart + Record[0], -                                   (const unsigned char *)BlobStart, -                                   NumStatHits, NumStatMisses)); +    case pch::STAT_CACHE: { +      PCHStatCache *MyStatCache =  +        new PCHStatCache((const unsigned char *)BlobStart + Record[0], +                         (const unsigned char *)BlobStart, +                         NumStatHits, NumStatMisses); +      FileMgr.addStatCache(MyStatCache); +      StatCache = MyStatCache;        break; - +    } +              case pch::EXT_VECTOR_DECLS:        if (!ExtVectorDecls.empty()) {          Error("duplicate EXT_VECTOR_DECLS record in PCH file"); @@ -1466,7 +1461,8 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {          SourceMgr.ClearPreallocatedSLocEntries();          // Remove the stat cache. -        FileMgr.setStatCache(0); +        if (StatCache) +          FileMgr.removeStatCache((PCHStatCache*)StatCache);          return IgnorePCH;        } @@ -1509,7 +1505,7 @@ PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) {        IdentifierInfo *II = Identifiers[I];        // Look in the on-disk hash table for an entry for        PCHIdentifierLookupTrait Info(*this, II); -      std::pair<const char*, unsigned> Key(II->getName(), II->getLength()); +      std::pair<const char*, unsigned> Key(II->getNameStart(), II->getLength());        PCHIdentifierLookupTable::iterator Pos = IdTable->find(Key, &Info);        if (Pos == IdTable->end())          continue; @@ -1593,6 +1589,11 @@ void PCHReader::InitializeContext(ASTContext &Ctx) {    if (unsigned ObjCClassRedef        = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS_REDEFINITION])      Context->ObjCClassRedefinitionType = GetType(ObjCClassRedef); +  if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_DESCRIPTOR]) +    Context->setBlockDescriptorType(GetType(String)); +  if (unsigned String +      = SpecialTypes[pch::SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR]) +    Context->setBlockDescriptorExtendedType(GetType(String));  }  /// \brief Retrieve the name of the original source file name @@ -1770,15 +1771,15 @@ void PCHReader::ReadComments(std::vector<SourceRange> &Comments) {  QualType PCHReader::ReadTypeRecord(uint64_t Offset) {    // Keep track of where we are in the stream, then jump back there    // after reading this type. -  SavedStreamPosition SavedPosition(Stream); +  SavedStreamPosition SavedPosition(DeclsCursor);    // Note that we are loading a type record.    LoadingTypeOrDecl Loading(*this); -  Stream.JumpToBit(Offset); +  DeclsCursor.JumpToBit(Offset);    RecordData Record; -  unsigned Code = Stream.ReadCode(); -  switch ((pch::TypeCode)Stream.ReadRecord(Code, Record)) { +  unsigned Code = DeclsCursor.ReadCode(); +  switch ((pch::TypeCode)DeclsCursor.ReadRecord(Code, Record)) {    case pch::TYPE_EXT_QUAL: {      assert(Record.size() == 2 &&             "Incorrect encoding of extended qualifier type"); @@ -1839,30 +1840,6 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {                                           ASM, IndexTypeQuals);    } -  case pch::TYPE_CONSTANT_ARRAY_WITH_EXPR: { -    QualType ElementType = GetType(Record[0]); -    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1]; -    unsigned IndexTypeQuals = Record[2]; -    SourceLocation LBLoc = SourceLocation::getFromRawEncoding(Record[3]); -    SourceLocation RBLoc = SourceLocation::getFromRawEncoding(Record[4]); -    unsigned Idx = 5; -    llvm::APInt Size = ReadAPInt(Record, Idx); -    return Context->getConstantArrayWithExprType(ElementType, -                                                 Size, ReadTypeExpr(), -                                                 ASM, IndexTypeQuals, -                                                 SourceRange(LBLoc, RBLoc)); -  } - -  case pch::TYPE_CONSTANT_ARRAY_WITHOUT_EXPR: { -    QualType ElementType = GetType(Record[0]); -    ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1]; -    unsigned IndexTypeQuals = Record[2]; -    unsigned Idx = 3; -    llvm::APInt Size = ReadAPInt(Record, Idx); -    return Context->getConstantArrayWithoutExprType(ElementType, Size, -                                                    ASM, IndexTypeQuals); -  } -    case pch::TYPE_INCOMPLETE_ARRAY: {      QualType ElementType = GetType(Record[0]);      ArrayType::ArraySizeModifier ASM = (ArrayType::ArraySizeModifier)Record[1]; @@ -1987,20 +1964,184 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {      return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos);    } -  case pch::TYPE_OBJC_PROTOCOL_LIST: { +  case pch::TYPE_SUBST_TEMPLATE_TYPE_PARM: {      unsigned Idx = 0; -    QualType OIT = GetType(Record[Idx++]); -    unsigned NumProtos = Record[Idx++]; -    llvm::SmallVector<ObjCProtocolDecl*, 4> Protos; -    for (unsigned I = 0; I != NumProtos; ++I) -      Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++]))); -    return Context->getObjCProtocolListType(OIT, Protos.data(), NumProtos); +    QualType Parm = GetType(Record[Idx++]); +    QualType Replacement = GetType(Record[Idx++]); +    return +      Context->getSubstTemplateTypeParmType(cast<TemplateTypeParmType>(Parm), +                                            Replacement);    }    }    // Suppress a GCC warning    return QualType();  } +namespace { + +class TypeLocReader : public TypeLocVisitor<TypeLocReader> { +  PCHReader &Reader; +  const PCHReader::RecordData &Record; +  unsigned &Idx; + +public: +  TypeLocReader(PCHReader &Reader, const PCHReader::RecordData &Record, +                unsigned &Idx) +    : Reader(Reader), Record(Record), Idx(Idx) { } + +  // We want compile-time assurance that we've enumerated all of +  // these, so unfortunately we have to declare them first, then +  // define them out-of-line. +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ +  void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); +#include "clang/AST/TypeLocNodes.def" + +  void VisitFunctionTypeLoc(FunctionTypeLoc); +  void VisitArrayTypeLoc(ArrayTypeLoc); +}; + +} + +void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { +  // nothing to do +} +void TypeLocReader::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitFixedWidthIntTypeLoc(FixedWidthIntTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitComplexTypeLoc(ComplexTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitPointerTypeLoc(PointerTypeLoc TL) { +  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { +  TL.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { +  TL.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { +  TL.setAmpAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { +  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitArrayTypeLoc(ArrayTypeLoc TL) { +  TL.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  if (Record[Idx++]) +    TL.setSizeExpr(Reader.ReadDeclExpr()); +  else +    TL.setSizeExpr(0); +} +void TypeLocReader::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitDependentSizedArrayTypeLoc( +                                            DependentSizedArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocReader::VisitDependentSizedExtVectorTypeLoc( +                                        DependentSizedExtVectorTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitVectorTypeLoc(VectorTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitFunctionTypeLoc(FunctionTypeLoc TL) { +  TL.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) { +    TL.setArg(i, cast_or_null<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); +  } +} +void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { +  VisitFunctionTypeLoc(TL); +} +void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { +  VisitFunctionTypeLoc(TL); +} +void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc( +                                            SubstTemplateTypeParmTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTemplateSpecializationTypeLoc( +                                           TemplateSpecializationTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitTypenameTypeLoc(TypenameTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { +  TL.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) +    TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); +} +void TypeLocReader::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { +  TL.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); +  TL.setHasBaseTypeAsWritten(Record[Idx++]); +  TL.setHasProtocolsAsWritten(Record[Idx++]); +  if (TL.hasProtocolsAsWritten()) +    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) +      TL.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); +} + +DeclaratorInfo *PCHReader::GetDeclaratorInfo(const RecordData &Record, +                                             unsigned &Idx) { +  QualType InfoTy = GetType(Record[Idx++]); +  if (InfoTy.isNull()) +    return 0; + +  DeclaratorInfo *DInfo = getContext()->CreateDeclaratorInfo(InfoTy); +  TypeLocReader TLR(*this, Record, Idx); +  for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) +    TLR.Visit(TL); +  return DInfo; +}  QualType PCHReader::GetType(pch::TypeID ID) {    unsigned FastQuals = ID & Qualifiers::FastMask; @@ -2374,7 +2515,10 @@ IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) {      // All of the strings in the PCH file are preceded by a 16-bit      // length. Extract that 16-bit length to avoid having to execute      // strlen(). -    const char *StrLenPtr = Str - 2; +    // NOTE: 'StrLenPtr' is an 'unsigned char*' so that we load bytes as +    //  unsigned integers.  This is important to avoid integer overflow when +    //  we cast them to 'unsigned'. +    const unsigned char *StrLenPtr = (const unsigned char*) Str - 2;      unsigned StrLen = (((unsigned) StrLenPtr[0])                         | (((unsigned) StrLenPtr[1]) << 8)) - 1;      IdentifiersLoaded[ID - 1] diff --git a/lib/Frontend/PCHReaderDecl.cpp b/lib/Frontend/PCHReaderDecl.cpp index b6732561dff0..d1cb461640b7 100644 --- a/lib/Frontend/PCHReaderDecl.cpp +++ b/lib/Frontend/PCHReaderDecl.cpp @@ -18,7 +18,6 @@  #include "clang/AST/DeclVisitor.h"  #include "clang/AST/DeclGroup.h"  #include "clang/AST/Expr.h" -#include "clang/AST/TypeLocVisitor.h"  using namespace clang; @@ -86,6 +85,7 @@ void PCHDeclReader::VisitDecl(Decl *D) {    D->setImplicit(Record[Idx++]);    D->setUsed(Record[Idx++]);    D->setAccess((AccessSpecifier)Record[Idx++]); +  D->setPCHLevel(Record[Idx++] + 1);  }  void PCHDeclReader::VisitTranslationUnitDecl(TranslationUnitDecl *TU) { @@ -149,84 +149,11 @@ void PCHDeclReader::VisitEnumConstantDecl(EnumConstantDecl *ECD) {    ECD->setInitVal(Reader.ReadAPSInt(Record, Idx));  } -namespace { - -class TypeLocReader : public TypeLocVisitor<TypeLocReader> { -  PCHReader &Reader; -  const PCHReader::RecordData &Record; -  unsigned &Idx; - -public: -  TypeLocReader(PCHReader &Reader, const PCHReader::RecordData &Record, -                unsigned &Idx) -    : Reader(Reader), Record(Record), Idx(Idx) { } - -#define ABSTRACT_TYPELOC(CLASS) -#define TYPELOC(CLASS, PARENT) \ -    void Visit##CLASS(CLASS TyLoc); -#include "clang/AST/TypeLocNodes.def" - -  void VisitTypeLoc(TypeLoc TyLoc) { -    assert(0 && "A type loc wrapper was not handled!"); -  } -}; - -} - -void TypeLocReader::VisitQualifiedLoc(QualifiedLoc TyLoc) { -  // nothing to do -} -void TypeLocReader::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { -  TyLoc.setStartLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitTypedefLoc(TypedefLoc TyLoc) { -  TyLoc.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) { -  TyLoc.setNameLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) { -  TyLoc.setLAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  TyLoc.setRAngleLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  for (unsigned i = 0, e = TyLoc.getNumProtocols(); i != e; ++i) -    TyLoc.setProtocolLoc(i, SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitPointerLoc(PointerLoc TyLoc) { -  TyLoc.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitBlockPointerLoc(BlockPointerLoc TyLoc) { -  TyLoc.setCaretLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitMemberPointerLoc(MemberPointerLoc TyLoc) { -  TyLoc.setStarLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitReferenceLoc(ReferenceLoc TyLoc) { -  TyLoc.setAmpLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -} -void TypeLocReader::VisitFunctionLoc(FunctionLoc TyLoc) { -  TyLoc.setLParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  TyLoc.setRParenLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i) -    TyLoc.setArg(i, cast<ParmVarDecl>(Reader.GetDecl(Record[Idx++]))); -} -void TypeLocReader::VisitArrayLoc(ArrayLoc TyLoc) { -  TyLoc.setLBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  TyLoc.setRBracketLoc(SourceLocation::getFromRawEncoding(Record[Idx++])); -  if (Record[Idx++]) -    TyLoc.setSizeExpr(Reader.ReadDeclExpr()); -} -  void PCHDeclReader::VisitDeclaratorDecl(DeclaratorDecl *DD) {    VisitValueDecl(DD); -  QualType InfoTy = Reader.GetType(Record[Idx++]); -  if (InfoTy.isNull()) -    return; - -  DeclaratorInfo *DInfo = Reader.getContext()->CreateDeclaratorInfo(InfoTy); -  TypeLocReader TLR(Reader, Record, Idx); -  for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) -    TLR.Visit(TL); -  DD->setDeclaratorInfo(DInfo); +  DeclaratorInfo *DInfo = Reader.GetDeclaratorInfo(Record, Idx); +  if (DInfo) +    DD->setDeclaratorInfo(DInfo);  }  void PCHDeclReader::VisitFunctionDecl(FunctionDecl *FD) { diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 64a678ea450b..fb48df332121 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -19,6 +19,7 @@  #include "clang/AST/DeclContextInternals.h"  #include "clang/AST/Expr.h"  #include "clang/AST/Type.h" +#include "clang/AST/TypeLocVisitor.h"  #include "clang/Lex/MacroInfo.h"  #include "clang/Lex/Preprocessor.h"  #include "clang/Lex/HeaderSearch.h" @@ -30,6 +31,7 @@  #include "clang/Basic/Version.h"  #include "llvm/ADT/APFloat.h"  #include "llvm/ADT/APInt.h" +#include "llvm/ADT/StringExtras.h"  #include "llvm/Bitcode/BitstreamWriter.h"  #include "llvm/Support/Compiler.h"  #include "llvm/Support/MemoryBuffer.h" @@ -117,23 +119,6 @@ void PCHTypeWriter::VisitConstantArrayType(const ConstantArrayType *T) {    Code = pch::TYPE_CONSTANT_ARRAY;  } -void PCHTypeWriter -::VisitConstantArrayWithExprType(const ConstantArrayWithExprType *T) { -  VisitArrayType(T); -  Writer.AddSourceLocation(T->getLBracketLoc(), Record); -  Writer.AddSourceLocation(T->getRBracketLoc(), Record); -  Writer.AddAPInt(T->getSize(), Record); -  Writer.AddStmt(T->getSizeExpr()); -  Code = pch::TYPE_CONSTANT_ARRAY_WITH_EXPR; -} - -void PCHTypeWriter -::VisitConstantArrayWithoutExprType(const ConstantArrayWithoutExprType *T) { -  VisitArrayType(T); -  Writer.AddAPInt(T->getSize(), Record); -  Code = pch::TYPE_CONSTANT_ARRAY_WITHOUT_EXPR; -} -  void PCHTypeWriter::VisitIncompleteArrayType(const IncompleteArrayType *T) {    VisitArrayType(T);    Code = pch::TYPE_INCOMPLETE_ARRAY; @@ -225,6 +210,14 @@ void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) {  }  void +PCHTypeWriter::VisitSubstTemplateTypeParmType( +                                        const SubstTemplateTypeParmType *T) { +  Writer.AddTypeRef(QualType(T->getReplacedParameter(), 0), Record); +  Writer.AddTypeRef(T->getReplacementType(), Record); +  Code = pch::TYPE_SUBST_TEMPLATE_TYPE_PARM; +} + +void  PCHTypeWriter::VisitTemplateSpecializationType(                                         const TemplateSpecializationType *T) {    // FIXME: Serialize this type (C++ only) @@ -255,13 +248,150 @@ PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {    Code = pch::TYPE_OBJC_OBJECT_POINTER;  } -void PCHTypeWriter::VisitObjCProtocolListType(const ObjCProtocolListType *T) { -  Writer.AddTypeRef(T->getBaseType(), Record); -  Record.push_back(T->getNumProtocols()); -  for (ObjCProtocolListType::qual_iterator I = T->qual_begin(), -       E = T->qual_end(); I != E; ++I) -    Writer.AddDeclRef(*I, Record); -  Code = pch::TYPE_OBJC_PROTOCOL_LIST; +namespace { + +class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { +  PCHWriter &Writer; +  PCHWriter::RecordData &Record; + +public: +  TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record) +    : Writer(Writer), Record(Record) { } + +#define ABSTRACT_TYPELOC(CLASS, PARENT) +#define TYPELOC(CLASS, PARENT) \ +    void Visit##CLASS##TypeLoc(CLASS##TypeLoc TyLoc); +#include "clang/AST/TypeLocNodes.def" + +  void VisitArrayTypeLoc(ArrayTypeLoc TyLoc); +  void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc); +}; + +} + +void TypeLocWriter::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { +  // nothing to do +} +void TypeLocWriter::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitFixedWidthIntTypeLoc(FixedWidthIntTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitComplexTypeLoc(ComplexTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitPointerTypeLoc(PointerTypeLoc TL) { +  Writer.AddSourceLocation(TL.getStarLoc(), Record); +} +void TypeLocWriter::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) { +  Writer.AddSourceLocation(TL.getCaretLoc(), Record); +} +void TypeLocWriter::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) { +  Writer.AddSourceLocation(TL.getAmpLoc(), Record); +} +void TypeLocWriter::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) { +  Writer.AddSourceLocation(TL.getAmpAmpLoc(), Record); +} +void TypeLocWriter::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) { +  Writer.AddSourceLocation(TL.getStarLoc(), Record); +} +void TypeLocWriter::VisitArrayTypeLoc(ArrayTypeLoc TL) { +  Writer.AddSourceLocation(TL.getLBracketLoc(), Record); +  Writer.AddSourceLocation(TL.getRBracketLoc(), Record); +  Record.push_back(TL.getSizeExpr() ? 1 : 0); +  if (TL.getSizeExpr()) +    Writer.AddStmt(TL.getSizeExpr()); +} +void TypeLocWriter::VisitConstantArrayTypeLoc(ConstantArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitIncompleteArrayTypeLoc(IncompleteArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitDependentSizedArrayTypeLoc( +                                            DependentSizedArrayTypeLoc TL) { +  VisitArrayTypeLoc(TL); +} +void TypeLocWriter::VisitDependentSizedExtVectorTypeLoc( +                                        DependentSizedExtVectorTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitVectorTypeLoc(VectorTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitExtVectorTypeLoc(ExtVectorTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitFunctionTypeLoc(FunctionTypeLoc TL) { +  Writer.AddSourceLocation(TL.getLParenLoc(), Record); +  Writer.AddSourceLocation(TL.getRParenLoc(), Record); +  for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i) +    Writer.AddDeclRef(TL.getArg(i), Record); +} +void TypeLocWriter::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { +  VisitFunctionTypeLoc(TL); +} +void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { +  VisitFunctionTypeLoc(TL); +} +void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitSubstTemplateTypeParmTypeLoc( +                                            SubstTemplateTypeParmTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTemplateSpecializationTypeLoc( +                                           TemplateSpecializationTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitQualifiedNameTypeLoc(QualifiedNameTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitTypenameTypeLoc(TypenameTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +} +void TypeLocWriter::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) { +  Writer.AddSourceLocation(TL.getNameLoc(), Record); +  Writer.AddSourceLocation(TL.getLAngleLoc(), Record); +  Writer.AddSourceLocation(TL.getRAngleLoc(), Record); +  for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) +    Writer.AddSourceLocation(TL.getProtocolLoc(i), Record); +} +void TypeLocWriter::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) { +  Writer.AddSourceLocation(TL.getStarLoc(), Record); +  Writer.AddSourceLocation(TL.getLAngleLoc(), Record); +  Writer.AddSourceLocation(TL.getRAngleLoc(), Record); +  Record.push_back(TL.hasBaseTypeAsWritten()); +  Record.push_back(TL.hasProtocolsAsWritten()); +  if (TL.hasProtocolsAsWritten()) +    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) +      Writer.AddSourceLocation(TL.getProtocolLoc(i), Record);  }  //===----------------------------------------------------------------------===// @@ -411,8 +541,8 @@ void PCHWriter::WriteBlockInfoBlock() {    RECORD(PP_MACRO_FUNCTION_LIKE);    RECORD(PP_TOKEN); -  // Types block. -  BLOCK(TYPES_BLOCK); +  // Decls and Types block. +  BLOCK(DECLTYPES_BLOCK);    RECORD(TYPE_EXT_QUAL);    RECORD(TYPE_FIXED_WIDTH_INT);    RECORD(TYPE_COMPLEX); @@ -435,12 +565,6 @@ void PCHWriter::WriteBlockInfoBlock() {    RECORD(TYPE_ENUM);    RECORD(TYPE_OBJC_INTERFACE);    RECORD(TYPE_OBJC_OBJECT_POINTER); -  RECORD(TYPE_OBJC_PROTOCOL_LIST); -  // Statements and Exprs can occur in the Types block. -  AddStmtsExprs(Stream, Record); - -  // Decls block. -  BLOCK(DECLS_BLOCK);    RECORD(DECL_ATTR);    RECORD(DECL_TRANSLATION_UNIT);    RECORD(DECL_TYPEDEF); @@ -470,7 +594,7 @@ void PCHWriter::WriteBlockInfoBlock() {    RECORD(DECL_BLOCK);    RECORD(DECL_CONTEXT_LEXICAL);    RECORD(DECL_CONTEXT_VISIBLE); -  // Statements and Exprs can occur in the Decls block. +  // Statements and Exprs can occur in the Decls and Types block.    AddStmtsExprs(Stream, Record);  #undef RECORD  #undef BLOCK @@ -662,7 +786,7 @@ public:    typedef const data_type& data_type_ref;    static unsigned ComputeHash(const char *path) { -    return BernsteinHash(path); +    return llvm::HashString(path);    }    std::pair<unsigned,unsigned> @@ -878,10 +1002,10 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,    std::vector<uint32_t> SLocEntryOffsets;    RecordData PreloadSLocs;    SLocEntryOffsets.reserve(SourceMgr.sloc_entry_size() - 1); -  for (SourceManager::sloc_entry_iterator -         SLoc = SourceMgr.sloc_entry_begin() + 1, -         SLocEnd = SourceMgr.sloc_entry_end(); -       SLoc != SLocEnd; ++SLoc) { +  for (unsigned I = 1, N = SourceMgr.sloc_entry_size(); I != N; ++I) { +    // Get this source location entry. +    const SrcMgr::SLocEntry *SLoc = &SourceMgr.getSLocEntry(I); +          // Record the offset of this source-location entry.      SLocEntryOffsets.push_back(Stream.GetCurrentBitNo()); @@ -956,9 +1080,8 @@ void PCHWriter::WriteSourceManagerBlock(SourceManager &SourceMgr,        // Compute the token length for this macro expansion.        unsigned NextOffset = SourceMgr.getNextOffset(); -      SourceManager::sloc_entry_iterator NextSLoc = SLoc; -      if (++NextSLoc != SLocEnd) -        NextOffset = NextSLoc->getOffset(); +      if (I + 1 != N) +        NextOffset = SourceMgr.getSLocEntry(I + 1).getOffset();        Record.push_back(NextOffset - SLoc->getOffset() - 1);        Stream.EmitRecordWithAbbrev(SLocInstantiationAbbrv, Record);      } @@ -1019,6 +1142,7 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {    // Loop over all the macro definitions that are live at the end of the file,    // emitting each to the PP section. +  // FIXME: Make sure that this sees macros defined in included PCH files.    for (Preprocessor::macro_iterator I = PP.macro_begin(), E = PP.macro_end();         I != E; ++I) {      // FIXME: This emits macros in hash table order, we should do it in a stable @@ -1152,22 +1276,6 @@ void PCHWriter::WriteType(QualType T) {    FlushStmts();  } -/// \brief Write a block containing all of the types. -void PCHWriter::WriteTypesBlock(ASTContext &Context) { -  // Enter the types block. -  Stream.EnterSubblock(pch::TYPES_BLOCK_ID, 2); - -  // Emit all of the types that need to be emitted (so far). -  while (!TypesToEmit.empty()) { -    QualType T = TypesToEmit.front(); -    TypesToEmit.pop(); -    WriteType(T); -  } - -  // Exit the types block -  Stream.ExitBlock(); -} -  //===----------------------------------------------------------------------===//  // Declaration Serialization  //===----------------------------------------------------------------------===// @@ -1266,7 +1374,7 @@ public:      unsigned R = 5381;      for (unsigned I = 0; I != N; ++I)        if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(I)) -        R = clang::BernsteinHashPartial(II->getName(), II->getLength(), R); +        R = llvm::HashString(II->getName(), R);      return R;    } @@ -1475,13 +1583,13 @@ public:      : Writer(Writer), PP(PP) { }    static unsigned ComputeHash(const IdentifierInfo* II) { -    return clang::BernsteinHash(II->getName()); +    return llvm::HashString(II->getName());    }    std::pair<unsigned,unsigned>      EmitKeyDataLength(llvm::raw_ostream& Out, const IdentifierInfo* II,                        pch::IdentID ID) { -    unsigned KeyLen = strlen(II->getName()) + 1; +    unsigned KeyLen = II->getLength() + 1;      unsigned DataLen = 4; // 4 bytes for the persistent ID << 1      if (isInterestingIdentifier(II)) {        DataLen += 2; // 2 bytes for builtin ID, flags @@ -1506,7 +1614,7 @@ public:      // Record the location of the key data.  This is used when generating      // the mapping from persistent IDs to strings.      Writer.SetIdentifierOffset(II, Out.tell()); -    Out.write(II->getName(), KeyLen); +    Out.write(II->getNameStart(), KeyLen);    }    void EmitData(llvm::raw_ostream& Out, const IdentifierInfo* II, @@ -1810,7 +1918,7 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,    // The translation unit is the first declaration we'll emit.    DeclIDs[Context.getTranslationUnitDecl()] = 1; -  DeclsToEmit.push(Context.getTranslationUnitDecl()); +  DeclTypesToEmit.push(Context.getTranslationUnitDecl());    // Make sure that we emit IdentifierInfos (and any attached    // declarations) for builtins. @@ -1858,7 +1966,6 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,    if (StatCalls && !isysroot)      WriteStatCache(*StatCalls, isysroot);    WriteSourceManagerBlock(Context.getSourceManager(), PP, isysroot); -  WritePreprocessor(PP);    WriteComments(Context);    // Write the record of special types.    Record.clear(); @@ -1875,17 +1982,25 @@ void PCHWriter::WritePCH(Sema &SemaRef, MemorizeStatCalls *StatCalls,    AddTypeRef(Context.getsigjmp_bufType(), Record);    AddTypeRef(Context.ObjCIdRedefinitionType, Record);    AddTypeRef(Context.ObjCClassRedefinitionType, Record); +  AddTypeRef(Context.getRawBlockdescriptorType(), Record); +  AddTypeRef(Context.getRawBlockdescriptorExtendedType(), Record);    Stream.EmitRecord(pch::SPECIAL_TYPES, Record);    // Keep writing types and declarations until all types and    // declarations have been written. -  do { -    if (!DeclsToEmit.empty()) -      WriteDeclsBlock(Context); -    if (!TypesToEmit.empty()) -      WriteTypesBlock(Context); -  } while (!(DeclsToEmit.empty() && TypesToEmit.empty())); - +  Stream.EnterSubblock(pch::DECLTYPES_BLOCK_ID, 3); +  WriteDeclsBlockAbbrevs(); +  while (!DeclTypesToEmit.empty()) { +    DeclOrType DOT = DeclTypesToEmit.front(); +    DeclTypesToEmit.pop(); +    if (DOT.isType()) +      WriteType(DOT.getType()); +    else +      WriteDecl(Context, DOT.getDecl()); +  } +  Stream.ExitBlock(); +   +  WritePreprocessor(PP);    WriteMethodPool(SemaRef);    WriteIdentifierTable(PP); @@ -1991,6 +2106,18 @@ void PCHWriter::AddSelectorRef(const Selector SelRef, RecordData &Record) {    Record.push_back(SID);  } +void PCHWriter::AddDeclaratorInfo(DeclaratorInfo *DInfo, RecordData &Record) { +  if (DInfo == 0) { +    AddTypeRef(QualType(), Record); +    return; +  } + +  AddTypeRef(DInfo->getType(), Record); +  TypeLocWriter TLW(*this, Record); +  for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) +    TLW.Visit(TL);   +} +  void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {    if (T.isNull()) {      Record.push_back(pch::PREDEF_TYPE_NULL_ID); @@ -2007,7 +2134,7 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {        // Assign it a new ID.  This is the only time we enqueue a        // qualified type, and it has no CV qualifiers.        ID = NextTypeID++; -      TypesToEmit.push(T); +      DeclTypesToEmit.push(T);      }      // Encode the type qualifiers in the type reference. @@ -2061,7 +2188,7 @@ void PCHWriter::AddTypeRef(QualType T, RecordData &Record) {      // We haven't seen this type before. Assign it a new ID and put it      // into the queue of types to emit.      ID = NextTypeID++; -    TypesToEmit.push(T); +    DeclTypesToEmit.push(T);    }    // Encode the type qualifiers in the type reference. @@ -2079,7 +2206,7 @@ void PCHWriter::AddDeclRef(const Decl *D, RecordData &Record) {      // We haven't seen this declaration before. Give it a new ID and      // enqueue it in the list of declarations to emit.      ID = DeclIDs.size(); -    DeclsToEmit.push(const_cast<Decl *>(D)); +    DeclTypesToEmit.push(const_cast<Decl *>(D));    }    Record.push_back(ID); diff --git a/lib/Frontend/PCHWriterDecl.cpp b/lib/Frontend/PCHWriterDecl.cpp index ef7c5ec4b1a6..fbd9929e49d7 100644 --- a/lib/Frontend/PCHWriterDecl.cpp +++ b/lib/Frontend/PCHWriterDecl.cpp @@ -14,7 +14,6 @@  #include "clang/Frontend/PCHWriter.h"  #include "clang/AST/DeclVisitor.h"  #include "clang/AST/Expr.h" -#include "clang/AST/TypeLocVisitor.h"  #include "llvm/Bitcode/BitstreamWriter.h"  #include <cstdio> @@ -88,6 +87,7 @@ void PCHDeclWriter::VisitDecl(Decl *D) {    Record.push_back(D->isImplicit());    Record.push_back(D->isUsed());    Record.push_back(D->getAccess()); +  Record.push_back(D->getPCHLevel());  }  void PCHDeclWriter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { @@ -149,84 +149,10 @@ void PCHDeclWriter::VisitEnumConstantDecl(EnumConstantDecl *D) {    Writer.AddAPSInt(D->getInitVal(), Record);    Code = pch::DECL_ENUM_CONSTANT;  } -namespace { - -class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> { -  PCHWriter &Writer; -  PCHWriter::RecordData &Record; - -public: -  TypeLocWriter(PCHWriter &Writer, PCHWriter::RecordData &Record) -    : Writer(Writer), Record(Record) { } - -#define ABSTRACT_TYPELOC(CLASS) -#define TYPELOC(CLASS, PARENT) \ -    void Visit##CLASS(CLASS TyLoc); -#include "clang/AST/TypeLocNodes.def" - -  void VisitTypeLoc(TypeLoc TyLoc) { -    assert(0 && "A type loc wrapper was not handled!"); -  } -}; - -} - -void TypeLocWriter::VisitQualifiedLoc(QualifiedLoc TyLoc) { -  // nothing to do here -} -void TypeLocWriter::VisitDefaultTypeSpecLoc(DefaultTypeSpecLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getStartLoc(), Record); -} -void TypeLocWriter::VisitTypedefLoc(TypedefLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getNameLoc(), Record); -} -void TypeLocWriter::VisitObjCInterfaceLoc(ObjCInterfaceLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getNameLoc(), Record); -} -void TypeLocWriter::VisitObjCProtocolListLoc(ObjCProtocolListLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getLAngleLoc(), Record); -  Writer.AddSourceLocation(TyLoc.getRAngleLoc(), Record); -  for (unsigned i = 0, e = TyLoc.getNumProtocols(); i != e; ++i) -    Writer.AddSourceLocation(TyLoc.getProtocolLoc(i), Record); -} -void TypeLocWriter::VisitPointerLoc(PointerLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getStarLoc(), Record); -} -void TypeLocWriter::VisitBlockPointerLoc(BlockPointerLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getCaretLoc(), Record); -} -void TypeLocWriter::VisitMemberPointerLoc(MemberPointerLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getStarLoc(), Record); -} -void TypeLocWriter::VisitReferenceLoc(ReferenceLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getAmpLoc(), Record); -} -void TypeLocWriter::VisitFunctionLoc(FunctionLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getLParenLoc(), Record); -  Writer.AddSourceLocation(TyLoc.getRParenLoc(), Record); -  for (unsigned i = 0, e = TyLoc.getNumArgs(); i != e; ++i) -    Writer.AddDeclRef(TyLoc.getArg(i), Record); -} -void TypeLocWriter::VisitArrayLoc(ArrayLoc TyLoc) { -  Writer.AddSourceLocation(TyLoc.getLBracketLoc(), Record); -  Writer.AddSourceLocation(TyLoc.getRBracketLoc(), Record); -  Record.push_back(TyLoc.getSizeExpr() ? 1 : 0); -  if (TyLoc.getSizeExpr()) -    Writer.AddStmt(TyLoc.getSizeExpr()); -}  void PCHDeclWriter::VisitDeclaratorDecl(DeclaratorDecl *D) {    VisitValueDecl(D); -  DeclaratorInfo *DInfo = D->getDeclaratorInfo(); -  if (DInfo == 0) { -    Writer.AddTypeRef(QualType(), Record); -    return; -  } - -  Writer.AddTypeRef(DInfo->getTypeLoc().getSourceType(), Record); -  TypeLocWriter TLW(Writer, Record); -  for (TypeLoc TL = DInfo->getTypeLoc(); !TL.isNull(); TL = TL.getNextTypeLoc()) -    TLW.Visit(TL); +  Writer.AddDeclaratorInfo(D->getDeclaratorInfo(), Record);  }  void PCHDeclWriter::VisitFunctionDecl(FunctionDecl *D) { @@ -448,6 +374,7 @@ void PCHDeclWriter::VisitParmVarDecl(ParmVarDecl *D) {        !D->isImplicit() &&        !D->isUsed() &&        D->getAccess() == AS_none && +      D->getPCHLevel() == 0 &&        D->getStorageClass() == 0 &&        !D->hasCXXDirectInitializer() && // Can params have this ever?        D->getObjCDeclQualifier() == 0) @@ -523,6 +450,7 @@ void PCHWriter::WriteDeclsBlockAbbrevs() {    Abv->Add(BitCodeAbbrevOp(0));                       // isImplicit    Abv->Add(BitCodeAbbrevOp(0));                       // isUsed    Abv->Add(BitCodeAbbrevOp(AS_none));                 // C++ AccessSpecifier +  Abv->Add(BitCodeAbbrevOp(0));                       // PCH level    // NamedDecl    Abv->Add(BitCodeAbbrevOp(0));                       // NameKind = Identifier @@ -607,80 +535,64 @@ static bool isRequiredDecl(const Decl *D, ASTContext &Context) {    }  } -/// \brief Write a block containing all of the declarations. -void PCHWriter::WriteDeclsBlock(ASTContext &Context) { -  // Enter the declarations block. -  Stream.EnterSubblock(pch::DECLS_BLOCK_ID, 3); - -  // Output the abbreviations that we will use in this block. -  WriteDeclsBlockAbbrevs(); - -  // Emit all of the declarations. +void PCHWriter::WriteDecl(ASTContext &Context, Decl *D) {    RecordData Record;    PCHDeclWriter W(*this, Context, Record); -  while (!DeclsToEmit.empty()) { -    // Pull the next declaration off the queue -    Decl *D = DeclsToEmit.front(); -    DeclsToEmit.pop(); - -    // If this declaration is also a DeclContext, write blocks for the -    // declarations that lexically stored inside its context and those -    // declarations that are visible from its context. These blocks -    // are written before the declaration itself so that we can put -    // their offsets into the record for the declaration. -    uint64_t LexicalOffset = 0; -    uint64_t VisibleOffset = 0; -    DeclContext *DC = dyn_cast<DeclContext>(D); -    if (DC) { -      LexicalOffset = WriteDeclContextLexicalBlock(Context, DC); -      VisibleOffset = WriteDeclContextVisibleBlock(Context, DC); -    } -    // Determine the ID for this declaration -    pch::DeclID &ID = DeclIDs[D]; -    if (ID == 0) -      ID = DeclIDs.size(); +  // If this declaration is also a DeclContext, write blocks for the +  // declarations that lexically stored inside its context and those +  // declarations that are visible from its context. These blocks +  // are written before the declaration itself so that we can put +  // their offsets into the record for the declaration. +  uint64_t LexicalOffset = 0; +  uint64_t VisibleOffset = 0; +  DeclContext *DC = dyn_cast<DeclContext>(D); +  if (DC) { +    LexicalOffset = WriteDeclContextLexicalBlock(Context, DC); +    VisibleOffset = WriteDeclContextVisibleBlock(Context, DC); +  } -    unsigned Index = ID - 1; +  // Determine the ID for this declaration +  pch::DeclID &ID = DeclIDs[D]; +  if (ID == 0) +    ID = DeclIDs.size(); -    // Record the offset for this declaration -    if (DeclOffsets.size() == Index) -      DeclOffsets.push_back(Stream.GetCurrentBitNo()); -    else if (DeclOffsets.size() < Index) { -      DeclOffsets.resize(Index+1); -      DeclOffsets[Index] = Stream.GetCurrentBitNo(); -    } +  unsigned Index = ID - 1; -    // Build and emit a record for this declaration -    Record.clear(); -    W.Code = (pch::DeclCode)0; -    W.AbbrevToUse = 0; -    W.Visit(D); -    if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); - -    if (!W.Code) { -      fprintf(stderr, "Cannot serialize declaration of kind %s\n", -              D->getDeclKindName()); -      assert(false && "Unhandled declaration kind while generating PCH"); -      exit(-1); -    } -    Stream.EmitRecord(W.Code, Record, W.AbbrevToUse); +  // Record the offset for this declaration +  if (DeclOffsets.size() == Index) +    DeclOffsets.push_back(Stream.GetCurrentBitNo()); +  else if (DeclOffsets.size() < Index) { +    DeclOffsets.resize(Index+1); +    DeclOffsets[Index] = Stream.GetCurrentBitNo(); +  } -    // If the declaration had any attributes, write them now. -    if (D->hasAttrs()) -      WriteAttributeRecord(D->getAttrs()); +  // Build and emit a record for this declaration +  Record.clear(); +  W.Code = (pch::DeclCode)0; +  W.AbbrevToUse = 0; +  W.Visit(D); +  if (DC) W.VisitDeclContext(DC, LexicalOffset, VisibleOffset); + +  if (!W.Code) { +    fprintf(stderr, "Cannot serialize declaration of kind %s\n", +            D->getDeclKindName()); +    assert(false && "Unhandled declaration kind while generating PCH"); +    exit(-1); +  } +  Stream.EmitRecord(W.Code, Record, W.AbbrevToUse); -    // Flush any expressions that were written as part of this declaration. -    FlushStmts(); +  // If the declaration had any attributes, write them now. +  if (D->hasAttrs()) +    WriteAttributeRecord(D->getAttrs()); -    // Note "external" declarations so that we can add them to a record in the -    // PCH file later. -    // -    // FIXME: This should be renamed, the predicate is much more complicated. -    if (isRequiredDecl(D, Context)) -      ExternalDefinitions.push_back(ID); -  } +  // Flush any expressions that were written as part of this declaration. +  FlushStmts(); -  // Exit the declarations block -  Stream.ExitBlock(); +  // Note "external" declarations so that we can add them to a record in the +  // PCH file later. +  // +  // FIXME: This should be renamed, the predicate is much more complicated. +  if (isRequiredDecl(D, Context)) +    ExternalDefinitions.push_back(Index + 1);  } diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp index 492b31a0ec39..f3cb20619ed5 100644 --- a/lib/Frontend/PrintPreprocessedOutput.cpp +++ b/lib/Frontend/PrintPreprocessedOutput.cpp @@ -399,7 +399,7 @@ static void PrintPreprocessedTokens(Preprocessor &PP, Token &Tok,      }      if (IdentifierInfo *II = Tok.getIdentifierInfo()) { -      OS.write(II->getName(), II->getLength()); +      OS << II->getName();      } else if (Tok.isLiteral() && !Tok.needsCleaning() &&                 Tok.getLiteralData()) {        OS.write(Tok.getLiteralData(), Tok.getLength()); @@ -434,7 +434,7 @@ namespace {    struct SortMacrosByID {      typedef std::pair<IdentifierInfo*, MacroInfo*> id_macro_pair;      bool operator()(const id_macro_pair &LHS, const id_macro_pair &RHS) const { -      return strcmp(LHS.first->getName(), RHS.first->getName()) < 0; +      return LHS.first->getName() < RHS.first->getName();      }    };  } diff --git a/lib/Frontend/RewriteMacros.cpp b/lib/Frontend/RewriteMacros.cpp index d92f5c78e690..b5d59c0aa401 100644 --- a/lib/Frontend/RewriteMacros.cpp +++ b/lib/Frontend/RewriteMacros.cpp @@ -128,13 +128,13 @@ void clang::RewriteMacrosInInput(Preprocessor &PP, llvm::raw_ostream *OS) {        // comment the line out.        if (RawTokens[CurRawTok].is(tok::identifier)) {          const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo(); -        if (!strcmp(II->getName(), "warning")) { +        if (II->getName() == "warning") {            // Comment out #warning.            RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//"); -        } else if (!strcmp(II->getName(), "pragma") && +        } else if (II->getName() == "pragma" &&                     RawTokens[CurRawTok+1].is(tok::identifier) && -                  !strcmp(RawTokens[CurRawTok+1].getIdentifierInfo()->getName(), -                          "mark")){ +                   (RawTokens[CurRawTok+1].getIdentifierInfo()->getName() == +                    "mark")) {            // Comment out #pragma mark.            RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//");          } diff --git a/lib/Frontend/RewriteObjC.cpp b/lib/Frontend/RewriteObjC.cpp index 55ab78e638bb..0ea0a58d5239 100644 --- a/lib/Frontend/RewriteObjC.cpp +++ b/lib/Frontend/RewriteObjC.cpp @@ -675,7 +675,7 @@ static std::string getIvarAccessString(ObjCInterfaceDecl *ClassDecl,    S = "((struct ";    S += ClassDecl->getIdentifier()->getName();    S += "_IMPL *)self)->"; -  S += OID->getNameAsCString(); +  S += OID->getName();    return S;  } @@ -2265,7 +2265,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {    if (clsName) { // class message.      // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle      // the 'super' idiom within a class method. -    if (!strcmp(clsName->getName(), "super")) { +    if (clsName->getName() == "super") {        MsgSendFlavor = MsgSendSuperFunctionDecl;        if (MsgSendStretFlavor)          MsgSendStretFlavor = MsgSendSuperStretFunctionDecl; @@ -2289,9 +2289,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {        llvm::SmallVector<Expr*, 8> ClsExprs;        QualType argType = Context->getPointerType(Context->CharTy);        ClsExprs.push_back(StringLiteral::Create(*Context, -                                        SuperDecl->getIdentifier()->getName(), -                                        SuperDecl->getIdentifier()->getLength(), -                                        false, argType, SourceLocation())); +                                     SuperDecl->getIdentifier()->getNameStart(), +                                     SuperDecl->getIdentifier()->getLength(), +                                     false, argType, SourceLocation()));        CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,                                                     &ClsExprs[0],                                                     ClsExprs.size()); @@ -2343,7 +2343,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {        llvm::SmallVector<Expr*, 8> ClsExprs;        QualType argType = Context->getPointerType(Context->CharTy);        ClsExprs.push_back(StringLiteral::Create(*Context, -                                               clsName->getName(), +                                               clsName->getNameStart(),                                                 clsName->getLength(),                                                 false, argType,                                                 SourceLocation())); @@ -2375,9 +2375,9 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {        llvm::SmallVector<Expr*, 8> ClsExprs;        QualType argType = Context->getPointerType(Context->CharTy);        ClsExprs.push_back(StringLiteral::Create(*Context, -                                        SuperDecl->getIdentifier()->getName(), -                                        SuperDecl->getIdentifier()->getLength(), -                                        false, argType, SourceLocation())); +                                     SuperDecl->getIdentifier()->getNameStart(), +                                     SuperDecl->getIdentifier()->getLength(), +                                     false, argType, SourceLocation()));        CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,                                                     &ClsExprs[0],                                                     ClsExprs.size()); diff --git a/lib/Frontend/TextDiagnosticPrinter.cpp b/lib/Frontend/TextDiagnosticPrinter.cpp index 63d9a50b368b..14769c187393 100644 --- a/lib/Frontend/TextDiagnosticPrinter.cpp +++ b/lib/Frontend/TextDiagnosticPrinter.cpp @@ -214,6 +214,7 @@ static void SelectInterestingSourceRegion(std::string &SourceLine,      // Move the end of the interesting region right until we've      // pulled in something else interesting.      if (CaretEnd != SourceLength) { +      assert(CaretEnd < SourceLength && "Unexpected caret position!");        unsigned NewEnd = CaretEnd;        // Skip over any whitespace we see here; we're looking for @@ -320,6 +321,11 @@ void TextDiagnosticPrinter::EmitCaretDiagnostic(SourceLocation Loc,    while (*LineEnd != '\n' && *LineEnd != '\r' && *LineEnd != '\0')      ++LineEnd; +  // FIXME: This shouldn't be necessary, but the CaretEndColNo can extend past +  // the source line length as currently being computed. See +  // test/Misc/message-length.c. +  CaretEndColNo = std::min(CaretEndColNo, unsigned(LineEnd - LineStart)); +    // Copy the line of code into an std::string for ease of manipulation.    std::string SourceLine(LineStart, LineEnd); | 
