aboutsummaryrefslogtreecommitdiff
path: root/lib/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/MacroInfo.cpp5
-rw-r--r--lib/Lex/PPDirectives.cpp37
-rw-r--r--lib/Lex/PPLexerChange.cpp23
3 files changed, 61 insertions, 4 deletions
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 5a7af56398..3d0c9a1c2b 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -27,7 +27,8 @@ MacroInfo::MacroInfo(SourceLocation DefLoc) : Location(DefLoc) {
IsAllowRedefinitionsWithoutWarning = false;
IsWarnIfUnused = false;
IsDefinitionLengthCached = false;
-
+ IsPublic = true;
+
ArgumentList = 0;
NumArguments = 0;
}
@@ -48,6 +49,8 @@ MacroInfo::MacroInfo(const MacroInfo &MI, llvm::BumpPtrAllocator &PPAllocator) {
IsWarnIfUnused = MI.IsWarnIfUnused;
IsDefinitionLengthCached = MI.IsDefinitionLengthCached;
DefinitionLength = MI.DefinitionLength;
+ IsPublic = MI.IsPublic;
+
ArgumentList = 0;
NumArguments = 0;
setArgumentList(MI.ArgumentList, MI.NumArguments, PPAllocator);
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index de50c750e4..9446d51f9d 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -666,6 +666,8 @@ TryAgain:
case tok::pp___export_macro__:
return HandleMacroExportDirective(Result);
+ case tok::pp___private_macro__:
+ return HandleMacroPrivateDirective(Result);
}
break;
}
@@ -1035,13 +1037,44 @@ void Preprocessor::HandleMacroExportDirective(Token &Tok) {
// If the macro is not defined, this is an error.
if (MI == 0) {
- Diag(MacroNameTok, diag::err_pp_export_non_macro)
+ Diag(MacroNameTok, diag::err_pp_visibility_non_macro)
<< MacroNameTok.getIdentifierInfo();
return;
}
// Note that this macro has now been exported.
- MI->setExportLocation(MacroNameTok.getLocation());
+ MI->setVisibility(/*IsPublic=*/true, MacroNameTok.getLocation());
+
+ // If this macro definition came from a PCH file, mark it
+ // as having changed since serialization.
+ if (MI->isFromAST())
+ MI->setChangedAfterLoad();
+}
+
+/// \brief Handle a #__private_macro__ directive.
+void Preprocessor::HandleMacroPrivateDirective(Token &Tok) {
+ Token MacroNameTok;
+ ReadMacroName(MacroNameTok, 2);
+
+ // Error reading macro name? If so, diagnostic already issued.
+ if (MacroNameTok.is(tok::eod))
+ return;
+
+ // Check to see if this is the last token on the #__private_macro__ line.
+ CheckEndOfDirective("__private_macro__");
+
+ // Okay, we finally have a valid identifier to undef.
+ MacroInfo *MI = getMacroInfo(MacroNameTok.getIdentifierInfo());
+
+ // If the macro is not defined, this is an error.
+ if (MI == 0) {
+ Diag(MacroNameTok, diag::err_pp_visibility_non_macro)
+ << MacroNameTok.getIdentifierInfo();
+ return;
+ }
+
+ // Note that this macro has now been marked private.
+ MI->setVisibility(/*IsPublic=*/false, MacroNameTok.getLocation());
// If this macro definition came from a PCH file, mark it
// as having changed since serialization.
diff --git a/lib/Lex/PPLexerChange.cpp b/lib/Lex/PPLexerChange.cpp
index 25a98ae47b..da6c8aa589 100644
--- a/lib/Lex/PPLexerChange.cpp
+++ b/lib/Lex/PPLexerChange.cpp
@@ -16,6 +16,7 @@
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "llvm/Support/MemoryBuffer.h"
using namespace clang;
@@ -211,8 +212,28 @@ bool Preprocessor::HandleEndOfFile(Token &Result, bool isEndOfMacro) {
CurPPLexer->MIOpt.GetControllingMacroAtEndOfFile()) {
// Okay, this has a controlling macro, remember in HeaderFileInfo.
if (const FileEntry *FE =
- SourceMgr.getFileEntryForID(CurPPLexer->getFileID()))
+ SourceMgr.getFileEntryForID(CurPPLexer->getFileID())) {
HeaderInfo.SetFileControllingMacro(FE, ControllingMacro);
+
+ // Controlling macros are implicitly private.
+ if (MacroInfo *MI = getMacroInfo(
+ const_cast<IdentifierInfo *>(ControllingMacro))) {
+ if (MI->getVisibilityLocation().isInvalid()) {
+ // FIXME: HACK! Mark controlling macros from system headers as
+ // exported, along with our own Clang headers. This is a gross
+ // hack to deal with the fact that system headers are included in
+ // many places within module headers, but are not themselves
+ // modularized.
+ if ((StringRef(FE->getName()).find("lib/clang")
+ == StringRef::npos) &&
+ (StringRef(FE->getName()).find("usr/include")
+ == StringRef::npos) &&
+ (StringRef(FE->getName()).find("usr/local/include")
+ == StringRef::npos))
+ MI->setVisibility(false, SourceLocation());
+ }
+ }
+ }
}
}