summaryrefslogtreecommitdiff
path: root/lib/Lex/PPMacroExpansion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/PPMacroExpansion.cpp')
-rw-r--r--lib/Lex/PPMacroExpansion.cpp95
1 files changed, 72 insertions, 23 deletions
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 2ade6df9456a..aebebaac46ac 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -12,25 +12,49 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Lex/Preprocessor.h"
#include "clang/Basic/Attributes.h"
#include "clang/Basic/FileManager.h"
-#include "clang/Basic/SourceManager.h"
+#include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/LangOptions.h"
+#include "clang/Basic/ObjCRuntime.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/CodeCompletionHandler.h"
+#include "clang/Lex/DirectoryLookup.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/MacroInfo.h"
-#include "llvm/ADT/STLExtras.h"
+#include "clang/Lex/Preprocessor.h"
+#include "clang/Lex/PreprocessorLexer.h"
+#include "clang/Lex/PTHLexer.h"
+#include "clang/Lex/Token.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/raw_ostream.h"
-#include <cstdio>
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
#include <ctime>
+#include <string>
+#include <tuple>
+#include <utility>
+
using namespace clang;
MacroDirective *
@@ -68,12 +92,35 @@ void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
}
void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
+ MacroDirective *ED,
MacroDirective *MD) {
+ // Normally, when a macro is defined, it goes through appendMacroDirective()
+ // above, which chains a macro to previous defines, undefs, etc.
+ // However, in a pch, the whole macro history up to the end of the pch is
+ // stored, so ASTReader goes through this function instead.
+ // However, built-in macros are already registered in the Preprocessor
+ // ctor, and ASTWriter stops writing the macro chain at built-in macros,
+ // so in that case the chain from the pch needs to be spliced to the existing
+ // built-in.
+
assert(II && MD);
MacroState &StoredMD = CurSubmoduleState->Macros[II];
- assert(!StoredMD.getLatest() &&
- "the macro history was modified before initializing it from a pch");
- StoredMD = MD;
+
+ if (auto *OldMD = StoredMD.getLatest()) {
+ // shouldIgnoreMacro() in ASTWriter also stops at macros from the
+ // predefines buffer in module builds. However, in module builds, modules
+ // are loaded completely before predefines are processed, so StoredMD
+ // will be nullptr for them when they're loaded. StoredMD should only be
+ // non-nullptr for builtins read from a pch file.
+ assert(OldMD->getMacroInfo()->isBuiltinMacro() &&
+ "only built-ins should have an entry here");
+ assert(!OldMD->getPrevious() && "builtin should only have a single entry");
+ ED->setPrevious(OldMD);
+ StoredMD.setLatest(MD);
+ } else {
+ StoredMD = MD;
+ }
+
// Setup the identifier as having associated macro history.
II->setHasMacroDefinition(true);
if (!MD->isDefined() && LeafModuleMacros.find(II) == LeafModuleMacros.end())
@@ -286,7 +333,6 @@ static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
return Id;
}
-
/// RegisterBuiltinMacros - Register builtin macros, such as __LINE__ with the
/// identifier table.
void Preprocessor::RegisterBuiltinMacros() {
@@ -367,10 +413,8 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
// If this is a function-like macro invocation, it's safe to trivially expand
// as long as the identifier is not a macro argument.
return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end();
-
}
-
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
/// lexed is a '('. If so, consume the token and return true, if not, this
/// method should have no observable side-effect on the lexed tokens.
@@ -390,8 +434,7 @@ bool Preprocessor::isNextPPTokenLParen() {
// macro stack.
if (CurPPLexer)
return false;
- for (unsigned i = IncludeMacroStack.size(); i != 0; --i) {
- IncludeStackInfo &Entry = IncludeMacroStack[i-1];
+ for (const IncludeStackInfo &Entry : llvm::reverse(IncludeMacroStack)) {
if (Entry.TheLexer)
Val = Entry.TheLexer->isNextPPTokenLParen();
else if (Entry.ThePTHLexer)
@@ -480,8 +523,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
} else {
Callbacks->MacroExpands(Identifier, M, ExpansionRange, Args);
if (!DelayedMacroExpandsCallbacks.empty()) {
- for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
- MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
+ for (const MacroExpandsInfo &Info : DelayedMacroExpandsCallbacks) {
// FIXME: We lose macro args info with delayed callback.
Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range,
/*Args=*/nullptr);
@@ -735,14 +777,14 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
assert(Tok.isOneOf(tok::l_paren, tok::comma) &&
"only expect argument separators here");
- unsigned ArgTokenStart = ArgTokens.size();
+ size_t ArgTokenStart = ArgTokens.size();
SourceLocation ArgStartLoc = Tok.getLocation();
// C99 6.10.3p11: Keep track of the number of l_parens we have seen. Note
// that we already consumed the first one.
unsigned NumParens = 0;
- while (1) {
+ while (true) {
// Read arguments as unexpanded tokens. This avoids issues, e.g., where
// an argument value in a macro could expand to ',' or '(' or ')'.
LexUnexpandedToken(Tok);
@@ -987,10 +1029,10 @@ Token *Preprocessor::cacheMacroExpandedTokens(TokenLexer *tokLexer,
if (cacheNeedsToGrow) {
// Go through all the TokenLexers whose 'Tokens' pointer points in the
// buffer and update the pointers to the (potential) new buffer array.
- for (unsigned i = 0, e = MacroExpandingLexersStack.size(); i != e; ++i) {
+ for (const auto &Lexer : MacroExpandingLexersStack) {
TokenLexer *prevLexer;
size_t tokIndex;
- std::tie(prevLexer, tokIndex) = MacroExpandingLexersStack[i];
+ std::tie(prevLexer, tokIndex) = Lexer;
prevLexer->Tokens = MacroExpandedTokens.data() + tokIndex;
}
}
@@ -1043,7 +1085,6 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc,
}
}
-
/// HasFeature - Return true if we recognize and implement the feature
/// specified by the identifier as a standard language feature.
static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
@@ -1090,6 +1131,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_rtti", LangOpts.RTTI && LangOpts.RTTIData)
.Case("enumerator_attributes", true)
.Case("nullability", true)
+ .Case("nullability_on_arrays", true)
.Case("memory_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Memory))
.Case("thread_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Thread))
.Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow))
@@ -1171,7 +1213,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
.Case("cxx_user_literals", LangOpts.CPlusPlus11)
.Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
- // C++1y features
+ // C++14 features
.Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus14)
.Case("cxx_binary_literals", LangOpts.CPlusPlus14)
.Case("cxx_contextual_conversions", LangOpts.CPlusPlus14)
@@ -1181,6 +1223,9 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
.Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus14)
.Case("cxx_return_type_deduction", LangOpts.CPlusPlus14)
.Case("cxx_variable_templates", LangOpts.CPlusPlus14)
+ // NOTE: For features covered by SD-6, it is preferable to provide *only*
+ // the SD-6 macro and not a __has_feature check.
+
// C++ TSes
//.Case("cxx_runtime_arrays", LangOpts.CPlusPlusTSArrays)
//.Case("cxx_concepts", LangOpts.CPlusPlusTSConcepts)
@@ -1264,7 +1309,7 @@ static bool HasExtension(const Preprocessor &PP, StringRef Extension) {
.Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
.Case("cxx_rvalue_references", LangOpts.CPlusPlus)
.Case("cxx_variadic_templates", LangOpts.CPlusPlus)
- // C++1y features supported by other languages as extensions.
+ // C++14 features supported by other languages as extensions.
.Case("cxx_binary_literals", true)
.Case("cxx_init_captures", LangOpts.CPlusPlus11)
.Case("cxx_variable_templates", LangOpts.CPlusPlus)
@@ -1400,7 +1445,11 @@ static bool EvaluateHasIncludeNext(Token &Tok,
// Preprocessor::HandleIncludeNextDirective.
const DirectoryLookup *Lookup = PP.GetCurDirLookup();
const FileEntry *LookupFromFile = nullptr;
- if (PP.isInPrimaryFile()) {
+ if (PP.isInPrimaryFile() && PP.getLangOpts().IsHeaderFile) {
+ // If the main file is a header, then it's either for PCH/AST generation,
+ // or libclang opened it. Either way, handle it as a normal include below
+ // and do not complain about __has_include_next.
+ } else if (PP.isInPrimaryFile()) {
Lookup = nullptr;
PP.Diag(Tok, diag::pp_include_next_in_primary);
} else if (PP.getCurrentSubmodule()) {
@@ -1796,7 +1845,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
[this](Token &Tok, bool &HasLexedNextToken) -> int {
IdentifierInfo *II = ExpectFeatureIdentifierInfo(Tok, *this,
diag::err_expected_id_building_module);
- return getLangOpts().CompilingModule && II &&
+ return getLangOpts().isCompilingModule() && II &&
(II->getName() == getLangOpts().CurrentModule);
});
} else if (II == Ident__MODULE__) {