diff options
author | Chris Lattner <sabre@nondot.org> | 2009-04-10 21:41:48 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-04-10 21:41:48 +0000 |
commit | 42d42b5b84603032e57add333b5b44e0ef99bd9e (patch) | |
tree | 2196e0d3db1a11385b93e067622251482654ad56 /lib/Frontend/PCHReader.cpp | |
parent | f908c519c1625e81d9e33d8a2a306a92834fe317 (diff) |
add support for reading macros. This does all the reading (with a bunch of
fixme's, e.g. for tokens with identifiers) but does not actually install
them. Some details with the predefines buffer needs to be sorted out first.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68828 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/PCHReader.cpp')
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 9eb881ce0f..d5923086c7 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -15,6 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/Type.h" +#include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" @@ -193,6 +194,115 @@ bool PCHReader::ReadSourceManagerBlock() { } } +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<IdentifierInfo*, 16> MacroArgs; + MacroInfo *LastMacro = 0; + + while (true) { + unsigned Code = Stream.ReadCode(); + switch (Code) { + case llvm::bitc::END_BLOCK: + if (Stream.ReadBlockEnd()) + return Error("Error at end of preprocessor block"); + return false; + + case llvm::bitc::ENTER_SUBBLOCK: + // No known subblocks, always skip them. + Stream.ReadSubBlockID(); + if (Stream.SkipBlock()) + return Error("Malformed block record"); + continue; + + case llvm::bitc::DEFINE_ABBREV: + Stream.ReadAbbrevRecord(); + continue; + default: break; + } + + // Read a record. + Record.clear(); + pch::PreprocessorRecordTypes RecType = + (pch::PreprocessorRecordTypes)Stream.ReadRecord(Code, Record); + switch (RecType) { + 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()); + + SourceLocation Loc = SourceLocation::getFromRawEncoding(Record[1]); + bool isUsed = Record[2]; + + MacroInfo *MI = PP.AllocateMacroInfo(Loc); + MI->setIsUsed(isUsed); + + if (RecType == pch::PP_MACRO_FUNCTION_LIKE) { + // Decode function-like macro info. + bool isC99VarArgs = Record[3]; + bool isGNUVarArgs = Record[4]; + MacroArgs.clear(); + unsigned NumArgs = Record[5]; + for (unsigned i = 0; i != NumArgs; ++i) + ; // FIXME: Decode macro arg names: MacroArgs.push_back(Record[6+i]); + + // Install function-like macro info. + MI->setIsFunctionLike(); + if (isC99VarArgs) MI->setIsC99Varargs(); + if (isGNUVarArgs) MI->setIsGNUVarargs(); + MI->setArgumentList(&MacroArgs[0], MacroArgs.size(), + PP.getPreprocessorAllocator()); + } + + // Finally, install the macro. + II = II; +#if 0 + // FIXME: Do this when predefines buffer is worked out. + PP.setMacroInfo(II, MI); +#endif + + // Remember that we saw this macro last so that we add the tokens that + // form its body to it. + LastMacro = MI; + break; + } + + case pch::PP_TOKEN: { + // If we see a TOKEN before a PP_MACRO_*, then the file is eroneous, just + // pretend we didn't see this. + if (LastMacro == 0) break; + + Token Tok; + Tok.startToken(); + Tok.setLocation(SourceLocation::getFromRawEncoding(Record[0])); + Tok.setLength(Record[1]); + unsigned IdentInfo = Record[2]; + IdentInfo = IdentInfo; // FIXME: Handle this right. + Tok.setKind((tok::TokenKind)Record[3]); + Tok.setFlag((Token::TokenFlags)Record[4]); + LastMacro->AddTokenToBody(Tok); + break; + } + } + } +} + PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { if (Stream.EnterSubBlock(pch::PCH_BLOCK_ID)) { Error("Malformed block record"); @@ -228,6 +338,13 @@ PCHReader::PCHReadResult PCHReader::ReadPCHBlock() { return Failure; } break; + + case pch::PREPROCESSOR_BLOCK_ID: + if (ReadPreprocessorBlock()) { + Error("Malformed preprocessor block"); + return Failure; + } + break; } continue; } |