If a null statement was preceded by an empty macro keep its instantiation source location

in NullStmt.

llvm-svn: 130289
This commit is contained in:
Argyrios Kyrtzidis 2011-04-27 05:04:02 +00:00
parent 8b02cd0bea
commit f7620e4d49
8 changed files with 30 additions and 14 deletions

View File

@ -383,14 +383,15 @@ public:
class NullStmt : public Stmt {
SourceLocation SemiLoc;
/// \brief Whether the null statement was preceded by an empty macro, e.g:
/// \brief If the null statement was preceded by an empty macro this is
/// its instantiation source location, e.g:
/// @code
/// #define CALL(x)
/// CALL(0);
/// @endcode
bool LeadingEmptyMacro;
SourceLocation LeadingEmptyMacro;
public:
NullStmt(SourceLocation L, bool LeadingEmptyMacro = false)
NullStmt(SourceLocation L, SourceLocation LeadingEmptyMacro =SourceLocation())
: Stmt(NullStmtClass), SemiLoc(L), LeadingEmptyMacro(LeadingEmptyMacro) {}
/// \brief Build an empty null statement.
@ -399,7 +400,8 @@ public:
SourceLocation getSemiLoc() const { return SemiLoc; }
void setSemiLoc(SourceLocation L) { SemiLoc = L; }
bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro; }
bool hasLeadingEmptyMacro() const { return LeadingEmptyMacro.isValid(); }
SourceLocation getLeadingEmptyMacroLoc() const { return LeadingEmptyMacro; }
SourceRange getSourceRange() const { return SourceRange(SemiLoc); }

View File

@ -218,6 +218,10 @@ class Preprocessor : public llvm::RefCountedBase<Preprocessor> {
/// previous macro value.
llvm::DenseMap<IdentifierInfo*, std::vector<MacroInfo*> > PragmaPushMacroInfo;
/// \brief Instantiation source location for the last macro that expanded
/// to no tokens.
SourceLocation LastEmptyMacroInstantiationLoc;
// Various statistics we track for performance analysis.
unsigned NumDirectives, NumIncluded, NumDefined, NumUndefined, NumPragma;
unsigned NumIf, NumElse, NumEndif;
@ -366,6 +370,12 @@ public:
macro_iterator macro_begin(bool IncludeExternalMacros = true) const;
macro_iterator macro_end(bool IncludeExternalMacros = true) const;
/// \brief Instantiation source location for the last macro that expanded
/// to no tokens.
SourceLocation getLastEmptyMacroInstantiationLoc() const {
return LastEmptyMacroInstantiationLoc;
}
const std::string &getPredefines() const { return Predefines; }
/// setPredefines - Set the predefines for this Preprocessor. These
/// predefines are automatically injected when parsing the main file.

View File

@ -1882,7 +1882,7 @@ public:
StmtResult ActOnExprStmt(FullExprArg Expr);
StmtResult ActOnNullStmt(SourceLocation SemiLoc,
bool LeadingEmptyMacro = false);
SourceLocation LeadingEmptyMacroLoc = SourceLocation());
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R,
MultiStmtArg Elts,
bool isStmtExpr);

View File

@ -227,6 +227,9 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// If we started lexing a macro, enter the macro expansion body.
// Remember where the token is instantiated.
SourceLocation InstantiateLoc = Identifier.getLocation();
// If this macro expands to no tokens, don't bother to push it onto the
// expansion stack, only to take it right back off.
if (MI->getNumTokens() == 0) {
@ -249,6 +252,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
if (HadLeadingSpace) Identifier.setFlag(Token::LeadingSpace);
}
Identifier.setFlag(Token::LeadingEmptyMacro);
LastEmptyMacroInstantiationLoc = InstantiateLoc;
++NumFastMacroExpanded;
return false;
@ -267,9 +271,6 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
bool isAtStartOfLine = Identifier.isAtStartOfLine();
bool hasLeadingSpace = Identifier.hasLeadingSpace();
// Remember where the token is instantiated.
SourceLocation InstantiateLoc = Identifier.getLocation();
// Replace the result token.
Identifier = MI->getReplacementToken(0);

View File

@ -276,8 +276,10 @@ Retry:
case tok::l_brace: // C99 6.8.2: compound-statement
return ParseCompoundStatement(attrs);
case tok::semi: { // C99 6.8.3p3: expression[opt] ';'
bool LeadingEmptyMacro = Tok.hasLeadingEmptyMacro();
return Actions.ActOnNullStmt(ConsumeToken(), LeadingEmptyMacro);
SourceLocation LeadingEmptyMacroLoc;
if (Tok.hasLeadingEmptyMacro())
LeadingEmptyMacroLoc = PP.getLastEmptyMacroInstantiationLoc();
return Actions.ActOnNullStmt(ConsumeToken(), LeadingEmptyMacroLoc);
}
case tok::kw_if: // C99 6.8.4.1: if-statement

View File

@ -46,8 +46,9 @@ StmtResult Sema::ActOnExprStmt(FullExprArg expr) {
}
StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc, bool LeadingEmptyMacro) {
return Owned(new (Context) NullStmt(SemiLoc, LeadingEmptyMacro));
StmtResult Sema::ActOnNullStmt(SourceLocation SemiLoc,
SourceLocation LeadingEmptyMacroLoc) {
return Owned(new (Context) NullStmt(SemiLoc, LeadingEmptyMacroLoc));
}
StmtResult Sema::ActOnDeclStmt(DeclGroupPtrTy dg, SourceLocation StartLoc,

View File

@ -211,7 +211,7 @@ void ASTStmtReader::VisitStmt(Stmt *S) {
void ASTStmtReader::VisitNullStmt(NullStmt *S) {
VisitStmt(S);
S->setSemiLoc(ReadSourceLocation(Record, Idx));
S->LeadingEmptyMacro = Record[Idx++];
S->LeadingEmptyMacro = ReadSourceLocation(Record, Idx);
}
void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {

View File

@ -180,7 +180,7 @@ void ASTStmtWriter::VisitStmt(Stmt *S) {
void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
VisitStmt(S);
Writer.AddSourceLocation(S->getSemiLoc(), Record);
Record.push_back(S->LeadingEmptyMacro);
Writer.AddSourceLocation(S->LeadingEmptyMacro, Record);
Code = serialization::STMT_NULL;
}