forked from OSchip/llvm-project
Implement the __TIME__ and __DATE__ builtin macros.
llvm-svn: 38597
This commit is contained in:
parent
7d6a4f6746
commit
c673f905d8
|
@ -26,26 +26,6 @@ MacroExpander::MacroExpander(LexerToken &Tok, Preprocessor &pp)
|
|||
}
|
||||
|
||||
|
||||
/// getInstantiationLoc - Return a SourceLocation that specifies a macro
|
||||
/// instantiation whose physical location is PhysLoc but the logical location
|
||||
/// is InstantiationLoc.
|
||||
SourceLocation MacroExpander::
|
||||
getInstantiationLoc(Preprocessor &PP,
|
||||
SourceLocation PhysLoc, SourceLocation InstantiationLoc) {
|
||||
// The token's current location indicate where the token was lexed from. We
|
||||
// need this information to compute the spelling of the token, but any
|
||||
// diagnostics for the expanded token should appear as if they came from
|
||||
// InstantiationLoc. Pull this information together into a new SourceLocation
|
||||
// that captures all of this.
|
||||
unsigned CharFilePos = PhysLoc.getRawFilePos();
|
||||
unsigned CharFileID = PhysLoc.getFileID();
|
||||
|
||||
unsigned InstantiationFileID =
|
||||
PP.getSourceManager().createFileIDForMacroExp(InstantiationLoc, CharFileID);
|
||||
return SourceLocation(InstantiationFileID, CharFilePos);
|
||||
}
|
||||
|
||||
|
||||
/// Lex - Lex and return a token from this macro stream.
|
||||
///
|
||||
void MacroExpander::Lex(LexerToken &Tok) {
|
||||
|
@ -56,9 +36,13 @@ void MacroExpander::Lex(LexerToken &Tok) {
|
|||
// Get the next token to return.
|
||||
Tok = Macro.getReplacementToken(CurToken++);
|
||||
|
||||
// Update the tokens location to include both its logical and physical
|
||||
// locations.
|
||||
Tok.SetLocation(getInstantiationLoc(PP, Tok.getLocation(), InstantiateLoc));
|
||||
// The token's current location indicate where the token was lexed from. We
|
||||
// need this information to compute the spelling of the token, but any
|
||||
// diagnostics for the expanded token should appear as if they came from
|
||||
// InstantiationLoc. Pull this information together into a new SourceLocation
|
||||
// that captures all of this.
|
||||
Tok.SetLocation(PP.getSourceManager().getInstantiationLoc(Tok.getLocation(),
|
||||
InstantiateLoc));
|
||||
|
||||
// If this is the first token, set the lexical properties of the token to
|
||||
// match the lexical properties of the macro identifier.
|
||||
|
|
|
@ -434,6 +434,8 @@ IdentifierTokenInfo *Preprocessor::RegisterBuiltinMacro(const char *Name) {
|
|||
void Preprocessor::RegisterBuiltinMacros() {
|
||||
// FIXME: implement them all, including _Pragma.
|
||||
Ident__LINE__ = RegisterBuiltinMacro("__LINE__");
|
||||
Ident__DATE__ = RegisterBuiltinMacro("__DATE__");
|
||||
Ident__TIME__ = RegisterBuiltinMacro("__TIME__");
|
||||
}
|
||||
|
||||
|
||||
|
@ -498,8 +500,7 @@ void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
|
|||
// Update the tokens location to include both its logical and physical
|
||||
// locations.
|
||||
SourceLocation Loc =
|
||||
MacroExpander::getInstantiationLoc(*this, Identifier.getLocation(),
|
||||
InstantiateLoc);
|
||||
SourceMgr.getInstantiationLoc(Identifier.getLocation(), InstantiateLoc);
|
||||
Identifier.SetLocation(Loc);
|
||||
|
||||
// Since this is not an identifier token, it can't be macro expanded, so
|
||||
|
@ -516,6 +517,27 @@ void Preprocessor::HandleMacroExpandedIdentifier(LexerToken &Identifier,
|
|||
return Lex(Identifier);
|
||||
}
|
||||
|
||||
/// ComputeDATE_TIME - Compute the current time, enter it into the specified
|
||||
/// scratch buffer, then return DATELoc/TIMELoc locations with the position of
|
||||
/// the identifier tokens inserted.
|
||||
static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
|
||||
ScratchBuffer *ScratchBuf) {
|
||||
time_t TT = time(0);
|
||||
struct tm *TM = localtime(&TT);
|
||||
|
||||
static const char * const Months[] = {
|
||||
"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"
|
||||
};
|
||||
|
||||
char TmpBuffer[100];
|
||||
sprintf(TmpBuffer, "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday,
|
||||
TM->tm_year+1900);
|
||||
DATELoc = ScratchBuf->getToken(TmpBuffer, strlen(TmpBuffer));
|
||||
|
||||
sprintf(TmpBuffer, "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec);
|
||||
TIMELoc = ScratchBuf->getToken(TmpBuffer, strlen(TmpBuffer));
|
||||
}
|
||||
|
||||
/// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
|
||||
/// as a builtin macro, handle it and return the next token as 'Tok'.
|
||||
void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI) {
|
||||
|
@ -524,6 +546,7 @@ void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI) {
|
|||
assert(ITI && "Can't be a macro without id info!");
|
||||
char TmpBuffer[100];
|
||||
|
||||
|
||||
if (ITI == Ident__LINE__) {
|
||||
// __LINE__ expands to a simple numeric value.
|
||||
sprintf(TmpBuffer, "%u", SourceMgr.getLineNumber(Tok.getLocation()));
|
||||
|
@ -533,7 +556,24 @@ void Preprocessor::ExpandBuiltinMacro(LexerToken &Tok, MacroInfo *MI) {
|
|||
Tok.SetLocation(ScratchBuf->getToken(TmpBuffer, Length, Tok.getLocation()));
|
||||
Tok.SetIdentifierInfo(0);
|
||||
Tok.ClearFlag(LexerToken::NeedsCleaning);
|
||||
return;
|
||||
} else if (ITI == Ident__DATE__) {
|
||||
if (!DATELoc.isValid())
|
||||
ComputeDATE_TIME(DATELoc, TIMELoc, ScratchBuf);
|
||||
Tok.SetKind(tok::string_literal);
|
||||
Tok.SetLength(strlen("\"Mmm dd yyyy\""));
|
||||
Tok.SetLocation(SourceMgr.getInstantiationLoc(DATELoc, Tok.getLocation()));
|
||||
Tok.SetIdentifierInfo(0);
|
||||
Tok.ClearFlag(LexerToken::NeedsCleaning);
|
||||
|
||||
} else if (ITI == Ident__TIME__) {
|
||||
if (!TIMELoc.isValid())
|
||||
ComputeDATE_TIME(DATELoc, TIMELoc, ScratchBuf);
|
||||
Tok.SetKind(tok::string_literal);
|
||||
Tok.SetLength(strlen("\"hh:mm:ss\""));
|
||||
Tok.SetLocation(SourceMgr.getInstantiationLoc(TIMELoc, Tok.getLocation()));
|
||||
Tok.SetIdentifierInfo(0);
|
||||
Tok.ClearFlag(LexerToken::NeedsCleaning);
|
||||
|
||||
} else {
|
||||
assert(0 && "Unknown identifier!");
|
||||
}
|
||||
|
|
|
@ -50,13 +50,6 @@ public:
|
|||
|
||||
MacroInfo &getMacro() const { return Macro; }
|
||||
|
||||
/// getInstantiationLoc - Return a SourceLocation that specifies a macro
|
||||
/// instantiation whose physical location is PhysLoc but the logical location
|
||||
/// is InstantiationLoc.
|
||||
static SourceLocation getInstantiationLoc(Preprocessor &PP,
|
||||
SourceLocation PhysLoc,
|
||||
SourceLocation InstantiationLoc);
|
||||
|
||||
/// Lex - Lex and return a token from this macro stream.
|
||||
void Lex(LexerToken &Tok);
|
||||
};
|
||||
|
|
|
@ -94,6 +94,8 @@ class Preprocessor {
|
|||
|
||||
/// Identifiers for builtin macros.
|
||||
IdentifierTokenInfo *Ident__LINE__; // __LINE__
|
||||
IdentifierTokenInfo *Ident__DATE__, *Ident__TIME__; // __DATE__, __TIME__
|
||||
SourceLocation DATELoc, TIMELoc;
|
||||
public:
|
||||
enum FileChangeReason {
|
||||
EnterFile, ExitFile, SystemHeaderPragma, RenameFile
|
||||
|
|
Loading…
Reference in New Issue