From f7620e4d4913c4cae8a956593f1509aa40edc02f Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 27 Apr 2011 05:04:02 +0000 Subject: [PATCH] If a null statement was preceded by an empty macro keep its instantiation source location in NullStmt. llvm-svn: 130289 --- clang/include/clang/AST/Stmt.h | 10 ++++++---- clang/include/clang/Lex/Preprocessor.h | 10 ++++++++++ clang/include/clang/Sema/Sema.h | 2 +- clang/lib/Lex/PPMacroExpansion.cpp | 7 ++++--- clang/lib/Parse/ParseStmt.cpp | 6 ++++-- clang/lib/Sema/SemaStmt.cpp | 5 +++-- clang/lib/Serialization/ASTReaderStmt.cpp | 2 +- clang/lib/Serialization/ASTWriterStmt.cpp | 2 +- 8 files changed, 30 insertions(+), 14 deletions(-) diff --git a/clang/include/clang/AST/Stmt.h b/clang/include/clang/AST/Stmt.h index 97dbce045f9a..3bbe6ce5105d 100644 --- a/clang/include/clang/AST/Stmt.h +++ b/clang/include/clang/AST/Stmt.h @@ -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); } diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index af3631de526c..86f9c43c3fac 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -218,6 +218,10 @@ class Preprocessor : public llvm::RefCountedBase { /// previous macro value. llvm::DenseMap > 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. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b3d4890fdafe..da6755fad0ff 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -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); diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 29f9cd6e3239..32b2188af58c 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -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); diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 3aec4ea2107a..5138cc159546 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -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 diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 5e21a3675887..38f3bf9e924b 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -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, diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 608aafc3ce48..3435fd92d3e6 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -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) { diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 19cd834dd454..53fb9738e621 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -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; }