r308948 - [NFC] Use RAII to un-poison and then re-poison __VA_ARGS__
Faisal Vali via cfe-commits
cfe-commits at lists.llvm.org
Mon Jul 24 20:15:36 PDT 2017
Author: faisalv
Date: Mon Jul 24 20:15:36 2017
New Revision: 308948
URL: http://llvm.org/viewvc/llvm-project?rev=308948&view=rev
Log:
[NFC] Use RAII to un-poison and then re-poison __VA_ARGS__
- This will also be used for the forthcoming __VA_OPT__ feature approved for C++2a.
- recommended by rsmith during his review of the __VA_OPT__ patch (https://reviews.llvm.org/D35782)
Added:
cfe/trunk/include/clang/Lex/VariadicMacroSupport.h
Modified:
cfe/trunk/include/clang/Lex/Preprocessor.h
cfe/trunk/lib/Lex/PPDirectives.cpp
Modified: cfe/trunk/include/clang/Lex/Preprocessor.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=308948&r1=308947&r2=308948&view=diff
==============================================================================
--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)
+++ cfe/trunk/include/clang/Lex/Preprocessor.h Mon Jul 24 20:15:36 2017
@@ -96,6 +96,7 @@ enum MacroUse {
/// know anything about preprocessor-level issues like the \#include stack,
/// token expansion, etc.
class Preprocessor {
+ friend class VariadicMacroScopeGuard;
std::shared_ptr<PreprocessorOptions> PPOpts;
DiagnosticsEngine *Diags;
LangOptions &LangOpts;
Added: cfe/trunk/include/clang/Lex/VariadicMacroSupport.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/VariadicMacroSupport.h?rev=308948&view=auto
==============================================================================
--- cfe/trunk/include/clang/Lex/VariadicMacroSupport.h (added)
+++ cfe/trunk/include/clang/Lex/VariadicMacroSupport.h Mon Jul 24 20:15:36 2017
@@ -0,0 +1,56 @@
+//===- VariadicMacroSupport.h - scope-guards etc. -*- C++ -*---------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines support types to help with preprocessing variadic macro
+// (i.e. macros that use: ellipses __VA_ARGS__ ) definitions and
+// expansions.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+#define LLVM_CLANG_LEX_VARIADICMACROSUPPORT_H
+
+#include "clang/Lex/Preprocessor.h"
+
+namespace clang {
+
+/// An RAII class that tracks when the Preprocessor starts and stops lexing the
+/// definition of a (ISO C/C++) variadic macro. As an example, this is useful
+/// for unpoisoning and repoisoning certain identifiers (such as __VA_ARGS__)
+/// that are only allowed in this context. Also, being a friend of the
+/// Preprocessor class allows it to access PP's cached identifiers directly (as
+/// opposed to performing a lookup each time).
+class VariadicMacroScopeGuard {
+ const Preprocessor &PP;
+ IdentifierInfo &Ident__VA_ARGS__;
+
+public:
+ VariadicMacroScopeGuard(const Preprocessor &P)
+ : PP(P), Ident__VA_ARGS__(*PP.Ident__VA_ARGS__) {
+ assert(Ident__VA_ARGS__.isPoisoned() && "__VA_ARGS__ should be poisoned "
+ "outside an ISO C/C++ variadic "
+ "macro definition!");
+ }
+
+ /// Client code should call this function just before the Preprocessor is
+ /// about to Lex tokens from the definition of a variadic (ISO C/C++) macro.
+ void enterScope() { Ident__VA_ARGS__.setIsPoisoned(false); }
+
+ /// Client code should call this function as soon as the Preprocessor has
+ /// either completed lexing the macro's definition tokens, or an error occured
+ /// and the context is being exited. This function is idempotent (might be
+ /// explicitly called, and then reinvoked via the destructor).
+ void exitScope() { Ident__VA_ARGS__.setIsPoisoned(true); }
+
+ ~VariadicMacroScopeGuard() { exitScope(); }
+};
+
+} // end namespace clang
+
+#endif
Modified: cfe/trunk/lib/Lex/PPDirectives.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=308948&r1=308947&r2=308948&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)
+++ cfe/trunk/lib/Lex/PPDirectives.cpp Mon Jul 24 20:15:36 2017
@@ -33,6 +33,7 @@
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Lex/PTHLexer.h"
#include "clang/Lex/Token.h"
+#include "clang/Lex/VariadicMacroSupport.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/SmallVector.h"
@@ -2290,6 +2291,10 @@ MacroInfo *Preprocessor::ReadOptionalMac
Token Tok;
LexUnexpandedToken(Tok);
+ // Used to un-poison and then re-poison identifiers of the __VA_ARGS__ ilk
+ // within their appropriate context.
+ VariadicMacroScopeGuard VariadicMacroScopeGuard(*this);
+
// If this is a function-like macro definition, parse the argument list,
// marking each of the identifiers as being used as macro arguments. Also,
// check other constraints on the first token of the macro body.
@@ -2314,14 +2319,14 @@ MacroInfo *Preprocessor::ReadOptionalMac
return nullptr;
}
- // If this is a definition of a variadic C99 function-like macro, not using
- // the GNU named varargs extension, enabled __VA_ARGS__.
+ // If this is a definition of an ISO C/C++ variadic function-like macro (not
+ // using the GNU named varargs extension) inform our variadic scope guard
+ // which un-poisons and re-poisons certain identifiers (e.g. __VA_ARGS__)
+ // allowed only within the definition of a variadic macro.
- // "Poison" __VA_ARGS__, which can only appear in the expansion of a macro.
- // This gets unpoisoned where it is allowed.
- assert(Ident__VA_ARGS__->isPoisoned() && "__VA_ARGS__ should be poisoned!");
- if (MI->isC99Varargs())
- Ident__VA_ARGS__->setIsPoisoned(false);
+ if (MI->isC99Varargs()) {
+ VariadicMacroScopeGuard.enterScope();
+ }
// Read the first token after the arg list for down below.
LexUnexpandedToken(Tok);
@@ -2431,9 +2436,6 @@ MacroInfo *Preprocessor::ReadOptionalMac
} else {
Diag(Tok, diag::err_pp_stringize_not_parameter)
<< LastTok.is(tok::hashat);
-
- // Disable __VA_ARGS__ again.
- Ident__VA_ARGS__->setIsPoisoned(true);
return nullptr;
}
}
@@ -2448,9 +2450,6 @@ MacroInfo *Preprocessor::ReadOptionalMac
}
}
MI->setDefinitionEndLoc(LastTok.getLocation());
- // Disable __VA_ARGS__ again.
- Ident__VA_ARGS__->setIsPoisoned(true);
-
return MI;
}
/// HandleDefineDirective - Implements \#define. This consumes the entire macro
More information about the cfe-commits
mailing list