]> granicus.if.org Git - clang/commitdiff
If a null statement was preceded by an empty macro keep its instantiation source...
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 27 Apr 2011 05:04:02 +0000 (05:04 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Wed, 27 Apr 2011 05:04:02 +0000 (05:04 +0000)
in NullStmt.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@130289 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Stmt.h
include/clang/Lex/Preprocessor.h
include/clang/Sema/Sema.h
lib/Lex/PPMacroExpansion.cpp
lib/Parse/ParseStmt.cpp
lib/Sema/SemaStmt.cpp
lib/Serialization/ASTReaderStmt.cpp
lib/Serialization/ASTWriterStmt.cpp

index 97dbce045f9a73ed6a1eccc92ab4e397d50276b8..3bbe6ce5105db77a1bc8e38495f7ef61e2662dba 100644 (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); }
 
index af3631de526cfec8b8e05f49366ab0a993546923..86f9c43c3fac06c3b3651f02b2434d2b6ed27902 100644 (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.
index b3d4890fdafefd3e299deb97e8ee68eb102faa24..da6755fad0ff905ac9dd175f5f232ef12f8aeab9 100644 (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);
index 29f9cd6e323983ff485fe0193c8da2cddc98464e..32b2188af58cde5e6c6533234b229806847f112d 100644 (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);
 
index 3aec4ea2107afb27e91928fc7bc7e8bafc2c27cc..5138cc159546a34225548cd302ade0d8501cdedb 100644 (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
index 5e21a367588730625d7ed3a75c90ef580a577ca0..38f3bf9e924b49a483b32213c4f3f8679fd29849 100644 (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,
index 608aafc3ce4875de8d39b4b49e9c7747da6b8010..3435fd92d3e6393abf9182f6acdac5b9227536c4 100644 (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) {
index 19cd834dd45453b49365c6599e6a8c1f6ea03a40..53fb9738e62104fabf96969d32609ad7635fc032 100644 (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;
 }