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.

llvm-svn: 68828
This commit is contained in:
Chris Lattner 2009-04-10 21:41:48 +00:00
parent 1156565c48
commit 34321bcd0b
3 changed files with 120 additions and 0 deletions

View File

@ -107,6 +107,7 @@ class PCHReader : public ExternalASTSource {
PCHReadResult ReadPCHBlock();
bool ReadSourceManagerBlock();
bool ReadPreprocessorBlock();
bool ParseLanguageOptions(const llvm::SmallVectorImpl<uint64_t> &Record);
QualType ReadTypeRecord(uint64_t Offset);

View File

@ -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;
}

View File

@ -573,6 +573,8 @@ void PCHWriter::WritePreprocessor(const Preprocessor &PP) {
// macros.
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
// order so that output is reproducible.
MacroInfo *MI = I->second;
// Don't emit builtin macros like __LINE__ to the PCH file unless they have