From: Chris Lattner Date: Sat, 11 Apr 2009 21:15:38 +0000 (+0000) Subject: now that we have an identifier table in the PCH file, finish hooking up X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7356a31327be9b3c3434a0c88746028980da5684;p=clang now that we have an identifier table in the PCH file, finish hooking up macro deserialization. We now correctly install II's in tokens, handle function-like macros, etc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68882 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index eb7d470704..dc8b6cc7c0 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -155,9 +155,6 @@ namespace clang { // The macros in the PP section are a PP_MACRO_* instance followed by a // list of PP_TOKEN instances for each token in the definition. - // FIXME: TEMP HACK UNTIL WE HAVE IDENTIFIER INFO IDs. - PP_MACRO_NAME = 4, - /// \brief An object-like macro definition. /// [PP_MACRO_OBJECT_LIKE, IdentInfoID, SLoc, IsUsed] PP_MACRO_OBJECT_LIKE = 1, diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index c934b0e2d7..b59790ddaf 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -137,9 +137,9 @@ public: typedef llvm::SmallVector RecordData; PCHReader(Preprocessor &PP, ASTContext &Context) - : PP(PP), Context(Context), Buffer() { } + : PP(PP), Context(Context), IdentifierTable(0) { } - ~PCHReader(); + ~PCHReader() {} PCHReadResult ReadPCH(const std::string &FileName); @@ -195,8 +195,11 @@ public: /// \brief Report a diagnostic. DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); - const IdentifierInfo *GetIdentifierInfo(const RecordData &Record, - unsigned &Idx); + IdentifierInfo *DecodeIdentifierInfo(unsigned Idx); + + IdentifierInfo *GetIdentifierInfo(const RecordData &Record, unsigned &Idx) { + return DecodeIdentifierInfo(Record[Idx++]); + } DeclarationName ReadDeclarationName(const RecordData &Record, unsigned &Idx); }; diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index b21beed307..b916deaa69 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -286,7 +286,6 @@ bool PCHReader::ReadPreprocessorBlock() { if (Stream.EnterSubBlock(pch::PREPROCESSOR_BLOCK_ID)) return Error("Malformed preprocessor block record"); - std::string CurName; // FIXME: HACK. RecordData Record; llvm::SmallVector MacroArgs; MacroInfo *LastMacro = 0; @@ -320,21 +319,11 @@ bool PCHReader::ReadPreprocessorBlock() { default: // Default behavior: ignore unknown records. break; - case pch::PP_MACRO_NAME: - // Set CurName. FIXME: This is a hack and should be removed when we have - // identifier id's. - CurName.clear(); - for (unsigned i = 0, e = Record.size(); i != e; ++i) - CurName += (char)Record[i]; - break; - case pch::PP_MACRO_OBJECT_LIKE: case pch::PP_MACRO_FUNCTION_LIKE: { - unsigned IdentInfo = Record[0]; - IdentInfo = IdentInfo; // FIXME: Decode into identifier info*. - assert(!CurName.empty()); - IdentifierInfo *II = PP.getIdentifierInfo(CurName.c_str()); - + IdentifierInfo *II = DecodeIdentifierInfo(Record[0]); + if (II == 0) + return Error("Macro must have a name"); SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]); bool isUsed = Record[2]; @@ -348,7 +337,7 @@ bool PCHReader::ReadPreprocessorBlock() { MacroArgs.clear(); unsigned NumArgs = Record[5]; for (unsigned i = 0; i != NumArgs; ++i) - ; // FIXME: Decode macro arg names: MacroArgs.push_back(Record[6+i]); + MacroArgs.push_back(DecodeIdentifierInfo(Record[6+i])); // Install function-like macro info. MI->setIsFunctionLike(); @@ -376,8 +365,8 @@ bool PCHReader::ReadPreprocessorBlock() { Tok.startToken(); Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0])); Tok.setLength(Record[1]); - unsigned IdentInfo = Record[2]; - IdentInfo = IdentInfo; // FIXME: Handle this right. + if (IdentifierInfo *II = DecodeIdentifierInfo(Record[2])) + Tok.setIdentifierInfo(II); Tok.setKind((tok::TokenKind)Record[3]); Tok.setFlag((Token::TokenFlags)Record[4]); LastMacro->AddTokenToBody(Tok); @@ -393,15 +382,29 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { return Failure; } + uint64_t PreprocessorBlockBit = 0; + // Read all of the records and blocks for the PCH file. RecordData Record; while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code == llvm::bitc::END_BLOCK) { + // If we saw the preprocessor block, read it now. + if (PreprocessorBlockBit) { + uint64_t SavedPos = Stream.GetCurrentBitNo(); + Stream.JumpToBit(PreprocessorBlockBit); + if (ReadPreprocessorBlock()) { + Error("Malformed preprocessor block"); + return Failure; + } + Stream.JumpToBit(SavedPos); + } + if (Stream.ReadBlockEnd()) { Error("Error at end of module block"); return Failure; } + return Success; } @@ -416,6 +419,20 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { } break; + case pch::PREPROCESSOR_BLOCK_ID: + // Skip the preprocessor block for now, but remember where it is. We + // want to read it in after the identifier table. + if (PreprocessorBlockBit) { + Error("Multiple preprocessor blocks found."); + return Failure; + } + PreprocessorBlockBit = Stream.GetCurrentBitNo(); + if (Stream.SkipBlock()) { + Error("Malformed block record"); + return Failure; + } + break; + case pch::SOURCE_MANAGER_BLOCK_ID: switch (ReadSourceManagerBlock()) { case Success: @@ -429,13 +446,6 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { return IgnorePCH; } break; - - case pch::PREPROCESSOR_BLOCK_ID: - if (ReadPreprocessorBlock()) { - Error("Malformed preprocessor block"); - return Failure; - } - break; } continue; } @@ -514,8 +524,6 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { return Failure; } -PCHReader::~PCHReader() { } - PCHReader::PCHReadResult PCHReader::ReadPCH(const std::string &FileName) { // Set the PCH file name. this->FileName = FileName; @@ -946,24 +954,22 @@ void PCHReader::PrintStats() { std::fprintf(stderr, "\n"); } -const IdentifierInfo *PCHReader::GetIdentifierInfo(const RecordData &Record, - unsigned &Idx) { - pch::IdentID ID = Record[Idx++]; +IdentifierInfo *PCHReader::DecodeIdentifierInfo(unsigned ID) { if (ID == 0) return 0; - + if (!IdentifierTable || IdentifierData.empty()) { Error("No identifier table in PCH file"); return 0; } - + if (IdentifierData[ID - 1] & 0x01) { uint64_t Offset = IdentifierData[ID - 1]; IdentifierData[ID - 1] = reinterpret_cast( - &Context.Idents.get(IdentifierTable + Offset)); + &Context.Idents.get(IdentifierTable + Offset)); } - - return reinterpret_cast(IdentifierData[ID - 1]); + + return reinterpret_cast(IdentifierData[ID - 1]); } DeclarationName diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index c595fefca4..6faf37fb29 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -582,17 +582,7 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) { if (MI->isBuiltinMacro()) continue; - IdentifierInfo *II = I->first; - - // FIXME: Emit a PP_MACRO_NAME for testing. This should be removed when we - // have identifierinfo id's. - for (unsigned i = 0, e = II->getLength(); i != e; ++i) - Record.push_back(II->getName()[i]); - S.EmitRecord(pch::PP_MACRO_NAME, Record); - Record.clear(); - - // FIXME: Output the identifier Info ID #! - Record.push_back((intptr_t)II); + AddIdentifierRef(I->first, Record); Record.push_back(MI->getDefinitionLoc().getRawEncoding()); Record.push_back(MI->isUsed()); @@ -607,8 +597,7 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) { Record.push_back(MI->getNumArgs()); for (MacroInfo::arg_iterator I = MI->arg_begin(), E = MI->arg_end(); I != E; ++I) - // FIXME: Output the identifier Info ID #! - Record.push_back((intptr_t)II); + AddIdentifierRef(*I, Record); } S.EmitRecord(Code, Record); Record.clear(); @@ -623,10 +612,9 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) { Record.push_back(Tok.getLocation().getRawEncoding()); Record.push_back(Tok.getLength()); - // FIXME: Output the identifier Info ID #! // FIXME: When reading literal tokens, reconstruct the literal pointer if // it is needed. - Record.push_back((intptr_t)Tok.getIdentifierInfo()); + AddIdentifierRef(Tok.getIdentifierInfo(), Record); // FIXME: Should translate token kind to a stable encoding. Record.push_back(Tok.getKind()); diff --git a/test/PCH/variables.c b/test/PCH/variables.c index 4001469f6f..749b7b6741 100644 --- a/test/PCH/variables.c +++ b/test/PCH/variables.c @@ -15,3 +15,4 @@ double z; // expected-error{{redefinition}} int Q = A_MACRO_IN_THE_PCH; +int R = FUNCLIKE_MACRO(A_MACRO_, IN_THE_PCH); \ No newline at end of file diff --git a/test/PCH/variables.h b/test/PCH/variables.h index d8dd2cf331..7b27671328 100644 --- a/test/PCH/variables.h +++ b/test/PCH/variables.h @@ -15,4 +15,4 @@ float z; int MAKE_HAPPY(Very); #define A_MACRO_IN_THE_PCH 492 -#define FUNCLIKE_MACRO(X, Y) X ## Y \ No newline at end of file +#define FUNCLIKE_MACRO(X, Y) X ## Y