Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions clang/docs/LanguageExtensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5738,6 +5738,40 @@ in user headers or code. This is controlled by ``-Wpedantic-macros``. Final
macros will always warn on redefinition, including situations with identical
bodies and in system headers.

Macro Scope
===========

Clang supports the pragma ``#pragma clang scope`` which is provided with an
argument ``push`` or ``pop`` to denote entering and leaving macro scopes. On
entering a macro scope all macro definitions and undefinitions are recorded so
that they can be reverted on leaving the scope.

.. code-block:: c

#define NUM_DOGGOS 2

#pragma clang scope push
#define NUM_DOGGOS 3
#pragma clang scope pop // NUM_DOGGOS is restored to 2

#pragma clang scope push
#undef NUM_DOGGOS
#pragma clang scope pop // NUM_DOGGOS is restored to 2

#undef NUM_DOGGOS
#pragma clang scope push
#define NUM_DOGGOS 1
#pragma clang scope pop // NUM_DOGGOS is restored to undefined

A macro scope can be used to wrap header includes to isolate headers from
leaking macros to the outer source file.

.. code-block:: c

#pragma clang scope push
#include <SomeSystemHeader.h>
#pragma clang scope pop // None of the defines from the included header persist.

Line Control
============

Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ def warn_pragma_diagnostic_invalid :
ExtWarn<"pragma diagnostic expected 'error', 'warning', 'ignored', 'fatal',"
" 'push', or 'pop'">,
InGroup<UnknownPragmas>;
def warn_pragma_diagnostic_cannot_pop :
ExtWarn<"pragma diagnostic pop could not pop, no matching push">,
def warn_pragma_cannot_pop :
ExtWarn<"pragma %select{diagnostic|scope}0 pop could not pop, no matching push">,
InGroup<UnknownPragmas>;
def warn_pragma_diagnostic_invalid_option :
ExtWarn<"pragma diagnostic expected option name (e.g. \"-Wundef\")">,
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Lex/Preprocessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,10 @@ class Preprocessor {
/// Warning information for macro annotations.
llvm::DenseMap<const IdentifierInfo *, MacroAnnotations> AnnotationInfos;

using MacroScopeVec = llvm::SmallVector<std::pair<IdentifierInfo *, MacroDirective *> >;
MacroScopeVec *CurScope = nullptr;
llvm::SmallVector<MacroScopeVec> MacroScopeStack;

/// A "freelist" of MacroArg objects that can be
/// reused for quick allocation.
MacroArgs *MacroArgCache = nullptr;
Expand Down Expand Up @@ -2896,6 +2900,9 @@ class Preprocessor {
AnnotationInfos[II].FinalAnnotationLoc = AnnotationLoc;
}

void pushMacroScope();
void popMacroScope(SourceLocation Loc);

const MacroAnnotations &getMacroAnnotations(const IdentifierInfo *II) const {
return AnnotationInfos.find(II)->second;
}
Expand Down
Loading
Loading