summaryrefslogtreecommitdiffstats
path: root/lib/Lex/PPMacroExpansion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex/PPMacroExpansion.cpp')
-rw-r--r--lib/Lex/PPMacroExpansion.cpp456
1 files changed, 202 insertions, 254 deletions
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index eee4342..21451f5 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -14,25 +14,26 @@
#include "clang/Lex/Preprocessor.h"
#include "MacroArgs.h"
-#include "clang/Lex/MacroInfo.h"
-#include "clang/Basic/SourceManager.h"
#include "clang/Basic/FileManager.h"
+#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
-#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/CodeCompletionHandler.h"
#include "clang/Lex/ExternalPreprocessorSource.h"
-#include "clang/Lex/LiteralSupport.h"
-#include "llvm/ADT/StringSwitch.h"
+#include "clang/Lex/LexDiagnostic.h"
+#include "clang/Lex/MacroInfo.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <ctime>
using namespace clang;
-MacroInfo *Preprocessor::getMacroInfoHistory(IdentifierInfo *II) const {
+MacroDirective *
+Preprocessor::getMacroDirectiveHistory(const IdentifierInfo *II) const {
assert(II->hadMacroDefinition() && "Identifier has not been not a macro!");
macro_iterator Pos = Macros.find(II);
@@ -40,125 +41,31 @@ MacroInfo *Preprocessor::getMacroInfoHistory(IdentifierInfo *II) const {
return Pos->second;
}
-/// setMacroInfo - Specify a macro for this identifier.
-///
-void Preprocessor::setMacroInfo(IdentifierInfo *II, MacroInfo *MI) {
- assert(MI && "MacroInfo should be non-zero!");
- assert(MI->getUndefLoc().isInvalid() &&
- "Undefined macros cannot be registered");
-
- MacroInfo *&StoredMI = Macros[II];
- MI->setPreviousDefinition(StoredMI);
- StoredMI = MI;
- II->setHasMacroDefinition(MI->getUndefLoc().isInvalid());
- if (II->isFromAST())
- II->setChangedSinceDeserialization();
-}
-
-void Preprocessor::addLoadedMacroInfo(IdentifierInfo *II, MacroInfo *MI,
- MacroInfo *Hint) {
- assert(MI && "Missing macro?");
- assert(MI->isFromAST() && "Macro is not from an AST?");
- assert(!MI->getPreviousDefinition() && "Macro already in chain?");
-
- MacroInfo *&StoredMI = Macros[II];
-
- // Easy case: this is the first macro definition for this macro.
- if (!StoredMI) {
- StoredMI = MI;
-
- if (MI->isDefined())
- II->setHasMacroDefinition(true);
- return;
- }
-
- // If this macro is a definition and this identifier has been neither
- // defined nor undef'd in the current translation unit, add this macro
- // to the end of the chain of definitions.
- if (MI->isDefined() && StoredMI->isFromAST()) {
- // Simple case: if this is the first actual definition, just put it at
- // th beginning.
- if (!StoredMI->isDefined()) {
- MI->setPreviousDefinition(StoredMI);
- StoredMI = MI;
-
- II->setHasMacroDefinition(true);
- return;
- }
-
- // Find the end of the definition chain.
- MacroInfo *Prev;
- MacroInfo *PrevPrev = StoredMI;
- bool Ambiguous = StoredMI->isAmbiguous();
- bool MatchedOther = false;
- do {
- Prev = PrevPrev;
-
- // If the macros are not identical, we have an ambiguity.
- if (!Prev->isIdenticalTo(*MI, *this)) {
- if (!Ambiguous) {
- Ambiguous = true;
- StoredMI->setAmbiguous(true);
- }
- } else {
- MatchedOther = true;
- }
- } while ((PrevPrev = Prev->getPreviousDefinition()) &&
- PrevPrev->isDefined());
-
- // If there are ambiguous definitions, and we didn't match any other
- // definition, then mark us as ambiguous.
- if (Ambiguous && !MatchedOther)
- MI->setAmbiguous(true);
-
- // Wire this macro information into the chain.
- MI->setPreviousDefinition(Prev->getPreviousDefinition());
- Prev->setPreviousDefinition(MI);
- return;
- }
-
- // The macro is not a definition; put it at the end of the list.
- MacroInfo *Prev = Hint? Hint : StoredMI;
- while (Prev->getPreviousDefinition())
- Prev = Prev->getPreviousDefinition();
- Prev->setPreviousDefinition(MI);
-}
-
-void Preprocessor::makeLoadedMacroInfoVisible(IdentifierInfo *II,
- MacroInfo *MI) {
- assert(MI->isFromAST() && "Macro must be from the AST");
-
- MacroInfo *&StoredMI = Macros[II];
- if (StoredMI == MI) {
- // Easy case: this is the first macro anyway.
- II->setHasMacroDefinition(MI->isDefined());
- return;
- }
-
- // Go find the macro and pull it out of the list.
- // FIXME: Yes, this is O(N), and making a pile of macros visible or hidden
- // would be quadratic, but it's extremely rare.
- MacroInfo *Prev = StoredMI;
- while (Prev->getPreviousDefinition() != MI)
- Prev = Prev->getPreviousDefinition();
- Prev->setPreviousDefinition(MI->getPreviousDefinition());
- MI->setPreviousDefinition(0);
-
- // Add the macro back to the list.
- addLoadedMacroInfo(II, MI);
-
- II->setHasMacroDefinition(StoredMI->isDefined());
- if (II->isFromAST())
+void Preprocessor::appendMacroDirective(IdentifierInfo *II, MacroDirective *MD){
+ assert(MD && "MacroDirective should be non-zero!");
+ assert(!MD->getPrevious() && "Already attached to a MacroDirective history.");
+
+ MacroDirective *&StoredMD = Macros[II];
+ MD->setPrevious(StoredMD);
+ StoredMD = MD;
+ II->setHasMacroDefinition(MD->isDefined());
+ bool isImportedMacro = isa<DefMacroDirective>(MD) &&
+ cast<DefMacroDirective>(MD)->isImported();
+ if (II->isFromAST() && !isImportedMacro)
II->setChangedSinceDeserialization();
}
-/// \brief Undefine a macro for this identifier.
-void Preprocessor::clearMacroInfo(IdentifierInfo *II) {
- assert(II->hasMacroDefinition() && "Macro is not defined!");
- assert(Macros[II]->getUndefLoc().isValid() && "Macro is still defined!");
- II->setHasMacroDefinition(false);
- if (II->isFromAST())
- II->setChangedSinceDeserialization();
+void Preprocessor::setLoadedMacroDirective(IdentifierInfo *II,
+ MacroDirective *MD) {
+ assert(II && MD);
+ MacroDirective *&StoredMD = Macros[II];
+ assert(!StoredMD &&
+ "the macro history was modified before initializing it from a pch");
+ StoredMD = MD;
+ // Setup the identifier as having associated macro history.
+ II->setHasMacroDefinition(true);
+ if (!MD->isDefined())
+ II->setHasMacroDefinition(false);
}
/// RegisterBuiltinMacro - Register the specified identifier in the identifier
@@ -170,7 +77,7 @@ static IdentifierInfo *RegisterBuiltinMacro(Preprocessor &PP, const char *Name){
// Mark it as being a macro that is builtin.
MacroInfo *MI = PP.AllocateMacroInfo(SourceLocation());
MI->setIsBuiltinMacro();
- PP.setMacroInfo(Id, MI);
+ PP.appendDefMacroDirective(Id, MI);
return Id;
}
@@ -303,7 +210,11 @@ bool Preprocessor::isNextPPTokenLParen() {
/// HandleMacroExpandedIdentifier - If an identifier token is read that is to be
/// expanded as a macro, handle it and return the next token as 'Identifier'.
bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
- MacroInfo *MI) {
+ MacroDirective *MD) {
+ MacroDirective::DefInfo Def = MD->getDefinition();
+ assert(Def.isValid());
+ MacroInfo *MI = Def.getMacroInfo();
+
// If this is a macro expansion in the "#if !defined(x)" line for the file,
// then the macro could expand to different things in other contexts, we need
// to disable the optimization in this case.
@@ -311,7 +222,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// If this is a builtin macro, like __LINE__ or _Pragma, handle it specially.
if (MI->isBuiltinMacro()) {
- if (Callbacks) Callbacks->MacroExpands(Identifier, MI,
+ if (Callbacks) Callbacks->MacroExpands(Identifier, MD,
Identifier.getLocation());
ExpandBuiltinMacro(Identifier);
return false;
@@ -364,13 +275,13 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// MacroExpands callbacks still happen in source order, queue this
// callback to have it happen after the function macro callback.
DelayedMacroExpandsCallbacks.push_back(
- MacroExpandsInfo(Identifier, MI, ExpansionRange));
+ MacroExpandsInfo(Identifier, MD, ExpansionRange));
} else {
- Callbacks->MacroExpands(Identifier, MI, ExpansionRange);
+ Callbacks->MacroExpands(Identifier, MD, ExpansionRange);
if (!DelayedMacroExpandsCallbacks.empty()) {
for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
- Callbacks->MacroExpands(Info.Tok, Info.MI, Info.Range);
+ Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range);
}
DelayedMacroExpandsCallbacks.clear();
}
@@ -378,16 +289,17 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
}
// If the macro definition is ambiguous, complain.
- if (MI->isAmbiguous()) {
+ if (Def.getDirective()->isAmbiguous()) {
Diag(Identifier, diag::warn_pp_ambiguous_macro)
<< Identifier.getIdentifierInfo();
Diag(MI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_chosen)
<< Identifier.getIdentifierInfo();
- for (MacroInfo *PrevMI = MI->getPreviousDefinition();
- PrevMI && PrevMI->isDefined();
- PrevMI = PrevMI->getPreviousDefinition()) {
- if (PrevMI->isAmbiguous()) {
- Diag(PrevMI->getDefinitionLoc(), diag::note_pp_ambiguous_macro_other)
+ for (MacroDirective::DefInfo PrevDef = Def.getPreviousDefinition();
+ PrevDef && !PrevDef.isUndefined();
+ PrevDef = PrevDef.getPreviousDefinition()) {
+ if (PrevDef.getDirective()->isAmbiguous()) {
+ Diag(PrevDef.getMacroInfo()->getDefinitionLoc(),
+ diag::note_pp_ambiguous_macro_other)
<< Identifier.getIdentifierInfo();
}
}
@@ -455,7 +367,10 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
if (MacroInfo *NewMI = getMacroInfo(NewII))
if (!NewMI->isEnabled() || NewMI == MI) {
Identifier.setFlag(Token::DisableExpand);
- Diag(Identifier, diag::pp_disabled_macro_expansion);
+ // Don't warn for "#define X X" like "#define bool bool" from
+ // stdbool.h.
+ if (NewMI != MI || MI->isFunctionLike())
+ Diag(Identifier, diag::pp_disabled_macro_expansion);
}
}
@@ -497,9 +412,13 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// argument is separated by an EOF token. Use a SmallVector so we can avoid
// heap allocations in the common case.
SmallVector<Token, 64> ArgTokens;
+ bool ContainsCodeCompletionTok = false;
unsigned NumActuals = 0;
while (Tok.isNot(tok::r_paren)) {
+ if (ContainsCodeCompletionTok && (Tok.is(tok::eof) || Tok.is(tok::eod)))
+ break;
+
assert((Tok.is(tok::l_paren) || Tok.is(tok::comma)) &&
"only expect argument separators here");
@@ -516,10 +435,20 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
LexUnexpandedToken(Tok);
if (Tok.is(tok::eof) || Tok.is(tok::eod)) { // "#if f(<eof>" & "#if f(\n"
- Diag(MacroName, diag::err_unterm_macro_invoc);
- // Do not lose the EOF/EOD. Return it to the client.
- MacroName = Tok;
- return 0;
+ if (!ContainsCodeCompletionTok) {
+ Diag(MacroName, diag::err_unterm_macro_invoc);
+ Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+ << MacroName.getIdentifierInfo();
+ // Do not lose the EOF/EOD. Return it to the client.
+ MacroName = Tok;
+ return 0;
+ } else {
+ // Do not lose the EOF/EOD.
+ Token *Toks = new Token[1];
+ Toks[0] = Tok;
+ EnterTokenStream(Toks, 1, true, true);
+ break;
+ }
} else if (Tok.is(tok::r_paren)) {
// If we found the ) token, the macro arg list is done.
if (NumParens-- == 0) {
@@ -550,6 +479,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
if (!MI->isEnabled())
Tok.setFlag(Token::DisableExpand);
} else if (Tok.is(tok::code_completion)) {
+ ContainsCodeCompletionTok = true;
if (CodeComplete)
CodeComplete->CodeCompleteMacroArgument(MacroName.getIdentifierInfo(),
MI, NumActuals);
@@ -572,16 +502,20 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
if (ArgTokens.size() != ArgTokenStart)
ArgStartLoc = ArgTokens[ArgTokenStart].getLocation();
- // Emit the diagnostic at the macro name in case there is a missing ).
- // Emitting it at the , could be far away from the macro name.
- Diag(ArgStartLoc, diag::err_too_many_args_in_macro_invoc);
- return 0;
+ if (!ContainsCodeCompletionTok) {
+ // Emit the diagnostic at the macro name in case there is a missing ).
+ // Emitting it at the , could be far away from the macro name.
+ Diag(ArgStartLoc, diag::err_too_many_args_in_macro_invoc);
+ Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+ << MacroName.getIdentifierInfo();
+ return 0;
+ }
}
// Empty arguments are standard in C99 and C++0x, and are supported as an extension in
// other modes.
if (ArgTokens.size() == ArgTokenStart && !LangOpts.C99)
- Diag(Tok, LangOpts.CPlusPlus0x ?
+ Diag(Tok, LangOpts.CPlusPlus11 ?
diag::warn_cxx98_compat_empty_fnmacro_arg :
diag::ext_empty_fnmacro_arg);
@@ -593,8 +527,10 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
EOFTok.setLength(0);
ArgTokens.push_back(EOFTok);
++NumActuals;
- assert(NumFixedArgsLeft != 0 && "Too many arguments parsed");
- --NumFixedArgsLeft;
+ if (!ContainsCodeCompletionTok || NumFixedArgsLeft != 0) {
+ assert(NumFixedArgsLeft != 0 && "Too many arguments parsed");
+ --NumFixedArgsLeft;
+ }
}
// Okay, we either found the r_paren. Check to see if we parsed too few
@@ -604,6 +540,17 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// See MacroArgs instance var for description of this.
bool isVarargsElided = false;
+ if (ContainsCodeCompletionTok) {
+ // Recover from not-fully-formed macro invocation during code-completion.
+ Token EOFTok;
+ EOFTok.startToken();
+ EOFTok.setKind(tok::eof);
+ EOFTok.setLocation(Tok.getLocation());
+ EOFTok.setLength(0);
+ for (; NumActuals < MinArgsExpected; ++NumActuals)
+ ArgTokens.push_back(EOFTok);
+ }
+
if (NumActuals < MinArgsExpected) {
// There are several cases where too few arguments is ok, handle them now.
if (NumActuals == 0 && MinArgsExpected == 1) {
@@ -619,9 +566,14 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// Varargs where the named vararg parameter is missing: OK as extension.
// #define A(x, ...)
// A("blah")
- Diag(Tok, diag::ext_missing_varargs_arg);
- Diag(MI->getDefinitionLoc(), diag::note_macro_here)
- << MacroName.getIdentifierInfo();
+ //
+ // If the macro contains the comma pasting extension, the diagnostic
+ // is suppressed; we know we'll get another diagnostic later.
+ if (!MI->hasCommaPasting()) {
+ Diag(Tok, diag::ext_missing_varargs_arg);
+ Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+ << MacroName.getIdentifierInfo();
+ }
// Remember this occurred, allowing us to elide the comma when used for
// cases like:
@@ -630,9 +582,11 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// #define C(...) blah(a, ## __VA_ARGS__)
// A(x) B(x) C()
isVarargsElided = true;
- } else {
+ } else if (!ContainsCodeCompletionTok) {
// Otherwise, emit the error.
Diag(Tok, diag::err_too_few_args_in_macro_invoc);
+ Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+ << MacroName.getIdentifierInfo();
return 0;
}
@@ -648,10 +602,13 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
if (NumActuals == 0 && MinArgsExpected == 2)
ArgTokens.push_back(Tok);
- } else if (NumActuals > MinArgsExpected && !MI->isVariadic()) {
+ } else if (NumActuals > MinArgsExpected && !MI->isVariadic() &&
+ !ContainsCodeCompletionTok) {
// Emit the diagnostic at the macro name in case there is a missing ).
// Emitting it at the , could be far away from the macro name.
Diag(MacroName, diag::err_too_many_args_in_macro_invoc);
+ Diag(MI->getDefinitionLoc(), diag::note_macro_here)
+ << MacroName.getIdentifierInfo();
return 0;
}
@@ -745,7 +702,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
Feature = Feature.substr(2, Feature.size() - 4);
return llvm::StringSwitch<bool>(Feature)
- .Case("address_sanitizer", LangOpts.SanitizeAddress)
+ .Case("address_sanitizer", LangOpts.Sanitize.Address)
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_availability", true)
.Case("attribute_availability_with_message", true)
@@ -767,6 +724,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("cxx_exceptions", LangOpts.Exceptions)
.Case("cxx_rtti", LangOpts.RTTI)
.Case("enumerator_attributes", true)
+ .Case("memory_sanitizer", LangOpts.Sanitize.Memory)
+ .Case("thread_sanitizer", LangOpts.Sanitize.Thread)
// Objective-C features
.Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
@@ -776,6 +735,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("objc_instancetype", LangOpts.ObjC2)
.Case("objc_modules", LangOpts.ObjC2 && LangOpts.Modules)
.Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
+ .Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword?
.Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
.Case("ownership_holds", true)
.Case("ownership_returns", true)
@@ -792,41 +752,41 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("c_generic_selections", LangOpts.C11)
.Case("c_static_assert", LangOpts.C11)
// C++11 features
- .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus0x)
- .Case("cxx_alias_templates", LangOpts.CPlusPlus0x)
- .Case("cxx_alignas", LangOpts.CPlusPlus0x)
- .Case("cxx_atomic", LangOpts.CPlusPlus0x)
- .Case("cxx_attributes", LangOpts.CPlusPlus0x)
- .Case("cxx_auto_type", LangOpts.CPlusPlus0x)
- .Case("cxx_constexpr", LangOpts.CPlusPlus0x)
- .Case("cxx_decltype", LangOpts.CPlusPlus0x)
- .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus0x)
- .Case("cxx_default_function_template_args", LangOpts.CPlusPlus0x)
- .Case("cxx_defaulted_functions", LangOpts.CPlusPlus0x)
- .Case("cxx_delegating_constructors", LangOpts.CPlusPlus0x)
- .Case("cxx_deleted_functions", LangOpts.CPlusPlus0x)
- .Case("cxx_explicit_conversions", LangOpts.CPlusPlus0x)
- .Case("cxx_generalized_initializers", LangOpts.CPlusPlus0x)
- .Case("cxx_implicit_moves", LangOpts.CPlusPlus0x)
+ .Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
+ .Case("cxx_alias_templates", LangOpts.CPlusPlus11)
+ .Case("cxx_alignas", LangOpts.CPlusPlus11)
+ .Case("cxx_atomic", LangOpts.CPlusPlus11)
+ .Case("cxx_attributes", LangOpts.CPlusPlus11)
+ .Case("cxx_auto_type", LangOpts.CPlusPlus11)
+ .Case("cxx_constexpr", LangOpts.CPlusPlus11)
+ .Case("cxx_decltype", LangOpts.CPlusPlus11)
+ .Case("cxx_decltype_incomplete_return_types", LangOpts.CPlusPlus11)
+ .Case("cxx_default_function_template_args", LangOpts.CPlusPlus11)
+ .Case("cxx_defaulted_functions", LangOpts.CPlusPlus11)
+ .Case("cxx_delegating_constructors", LangOpts.CPlusPlus11)
+ .Case("cxx_deleted_functions", LangOpts.CPlusPlus11)
+ .Case("cxx_explicit_conversions", LangOpts.CPlusPlus11)
+ .Case("cxx_generalized_initializers", LangOpts.CPlusPlus11)
+ .Case("cxx_implicit_moves", LangOpts.CPlusPlus11)
//.Case("cxx_inheriting_constructors", false)
- .Case("cxx_inline_namespaces", LangOpts.CPlusPlus0x)
- .Case("cxx_lambdas", LangOpts.CPlusPlus0x)
- .Case("cxx_local_type_template_args", LangOpts.CPlusPlus0x)
- .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus0x)
- .Case("cxx_noexcept", LangOpts.CPlusPlus0x)
- .Case("cxx_nullptr", LangOpts.CPlusPlus0x)
- .Case("cxx_override_control", LangOpts.CPlusPlus0x)
- .Case("cxx_range_for", LangOpts.CPlusPlus0x)
- .Case("cxx_raw_string_literals", LangOpts.CPlusPlus0x)
- .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus0x)
- .Case("cxx_rvalue_references", LangOpts.CPlusPlus0x)
- .Case("cxx_strong_enums", LangOpts.CPlusPlus0x)
- .Case("cxx_static_assert", LangOpts.CPlusPlus0x)
- .Case("cxx_trailing_return", LangOpts.CPlusPlus0x)
- .Case("cxx_unicode_literals", LangOpts.CPlusPlus0x)
- .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus0x)
- .Case("cxx_user_literals", LangOpts.CPlusPlus0x)
- .Case("cxx_variadic_templates", LangOpts.CPlusPlus0x)
+ .Case("cxx_inline_namespaces", LangOpts.CPlusPlus11)
+ .Case("cxx_lambdas", LangOpts.CPlusPlus11)
+ .Case("cxx_local_type_template_args", LangOpts.CPlusPlus11)
+ .Case("cxx_nonstatic_member_init", LangOpts.CPlusPlus11)
+ .Case("cxx_noexcept", LangOpts.CPlusPlus11)
+ .Case("cxx_nullptr", LangOpts.CPlusPlus11)
+ .Case("cxx_override_control", LangOpts.CPlusPlus11)
+ .Case("cxx_range_for", LangOpts.CPlusPlus11)
+ .Case("cxx_raw_string_literals", LangOpts.CPlusPlus11)
+ .Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus11)
+ .Case("cxx_rvalue_references", LangOpts.CPlusPlus11)
+ .Case("cxx_strong_enums", LangOpts.CPlusPlus11)
+ .Case("cxx_static_assert", LangOpts.CPlusPlus11)
+ .Case("cxx_trailing_return", LangOpts.CPlusPlus11)
+ .Case("cxx_unicode_literals", LangOpts.CPlusPlus11)
+ .Case("cxx_unrestricted_unions", LangOpts.CPlusPlus11)
+ .Case("cxx_user_literals", LangOpts.CPlusPlus11)
+ .Case("cxx_variadic_templates", LangOpts.CPlusPlus11)
// Type traits
.Case("has_nothrow_assign", LangOpts.CPlusPlus)
.Case("has_nothrow_copy", LangOpts.CPlusPlus)
@@ -840,10 +800,6 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("is_base_of", LangOpts.CPlusPlus)
.Case("is_class", LangOpts.CPlusPlus)
.Case("is_convertible_to", LangOpts.CPlusPlus)
- // __is_empty is available only if the horrible
- // "struct __is_empty" parsing hack hasn't been needed in this
- // translation unit. If it has, __is_empty reverts to a normal
- // identifier and __has_feature(is_empty) evaluates false.
.Case("is_empty", LangOpts.CPlusPlus)
.Case("is_enum", LangOpts.CPlusPlus)
.Case("is_final", LangOpts.CPlusPlus)
@@ -926,9 +882,15 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
IdentifierInfo *II, Preprocessor &PP,
const DirectoryLookup *LookupFrom) {
// Save the location of the current token. If a '(' is later found, use
- // that location. If no, use the end of this location instead.
+ // that location. If not, use the end of this location instead.
SourceLocation LParenLoc = Tok.getLocation();
+ // These expressions are only allowed within a preprocessor directive.
+ if (!PP.isParsingIfOrElifDirective()) {
+ PP.Diag(LParenLoc, diag::err_pp_directive_required) << II->getName();
+ return false;
+ }
+
// Get '('.
PP.LexNonComment(Tok);
@@ -946,8 +908,14 @@ static bool EvaluateHasIncludeCommon(Token &Tok,
// Save '(' location for possible missing ')' message.
LParenLoc = Tok.getLocation();
- // Get the file name.
- PP.getCurrentLexer()->LexIncludeFilename(Tok);
+ if (PP.getCurrentLexer()) {
+ // Get the file name.
+ PP.getCurrentLexer()->LexIncludeFilename(Tok);
+ } else {
+ // We're in a macro, so we can't use LexIncludeFilename; just
+ // grab the next token.
+ PP.Lex(Tok);
+ }
}
// Reserve a buffer to get the spelling.
@@ -1223,15 +1191,15 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
IdentifierInfo *FeatureII = 0;
// Read the '('.
- Lex(Tok);
+ LexUnexpandedToken(Tok);
if (Tok.is(tok::l_paren)) {
// Read the identifier
- Lex(Tok);
+ LexUnexpandedToken(Tok);
if (Tok.is(tok::identifier) || Tok.is(tok::kw_const)) {
FeatureII = Tok.getIdentifierInfo();
// Read the ')'.
- Lex(Tok);
+ LexUnexpandedToken(Tok);
if (Tok.is(tok::r_paren))
IsValid = true;
}
@@ -1275,69 +1243,49 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) {
bool IsValid = false;
bool Value = false;
// Read the '('.
- Lex(Tok);
+ LexUnexpandedToken(Tok);
do {
- if (Tok.is(tok::l_paren)) {
- // Read the string.
- Lex(Tok);
-
- // We need at least one string literal.
- if (!Tok.is(tok::string_literal)) {
- StartLoc = Tok.getLocation();
- IsValid = false;
- // Eat tokens until ')'.
- do Lex(Tok); while (!(Tok.is(tok::r_paren) || Tok.is(tok::eod)));
- break;
- }
-
- // String concatenation allows multiple strings, which can even come
- // from macro expansion.
- SmallVector<Token, 4> StrToks;
- while (Tok.is(tok::string_literal)) {
- // Complain about, and drop, any ud-suffix.
- if (Tok.hasUDSuffix())
- Diag(Tok, diag::err_invalid_string_udl);
- StrToks.push_back(Tok);
+ if (Tok.isNot(tok::l_paren)) {
+ Diag(StartLoc, diag::err_warning_check_malformed);
+ break;
+ }
+
+ LexUnexpandedToken(Tok);
+ std::string WarningName;
+ SourceLocation StrStartLoc = Tok.getLocation();
+ if (!FinishLexStringLiteral(Tok, WarningName, "'__has_warning'",
+ /*MacroExpansion=*/false)) {
+ // Eat tokens until ')'.
+ while (Tok.isNot(tok::r_paren) && Tok.isNot(tok::eod) &&
+ Tok.isNot(tok::eof))
LexUnexpandedToken(Tok);
- }
-
- // Is the end a ')'?
- if (!(IsValid = Tok.is(tok::r_paren)))
- break;
-
- // Concatenate and parse the strings.
- StringLiteralParser Literal(&StrToks[0], StrToks.size(), *this);
- assert(Literal.isAscii() && "Didn't allow wide strings in");
- if (Literal.hadError)
- break;
- if (Literal.Pascal) {
- Diag(Tok, diag::warn_pragma_diagnostic_invalid);
- break;
- }
-
- StringRef WarningName(Literal.GetString());
-
- if (WarningName.size() < 3 || WarningName[0] != '-' ||
- WarningName[1] != 'W') {
- Diag(StrToks[0].getLocation(), diag::warn_has_warning_invalid_option);
- break;
- }
-
- // Finally, check if the warning flags maps to a diagnostic group.
- // We construct a SmallVector here to talk to getDiagnosticIDs().
- // Although we don't use the result, this isn't a hot path, and not
- // worth special casing.
- llvm::SmallVector<diag::kind, 10> Diags;
- Value = !getDiagnostics().getDiagnosticIDs()->
- getDiagnosticsInGroup(WarningName.substr(2), Diags);
+ break;
+ }
+
+ // Is the end a ')'?
+ if (!(IsValid = Tok.is(tok::r_paren))) {
+ Diag(StartLoc, diag::err_warning_check_malformed);
+ break;
+ }
+
+ if (WarningName.size() < 3 || WarningName[0] != '-' ||
+ WarningName[1] != 'W') {
+ Diag(StrStartLoc, diag::warn_has_warning_invalid_option);
+ break;
}
+
+ // Finally, check if the warning flags maps to a diagnostic group.
+ // We construct a SmallVector here to talk to getDiagnosticIDs().
+ // Although we don't use the result, this isn't a hot path, and not
+ // worth special casing.
+ SmallVector<diag::kind, 10> Diags;
+ Value = !getDiagnostics().getDiagnosticIDs()->
+ getDiagnosticsInGroup(WarningName.substr(2), Diags);
} while (false);
-
- if (!IsValid)
- Diag(StartLoc, diag::err_warning_check_malformed);
OS << (int)Value;
- Tok.setKind(tok::numeric_constant);
+ if (IsValid)
+ Tok.setKind(tok::numeric_constant);
} else if (II == Ident__building_module) {
// The argument to this builtin should be an identifier. The
// builtin evaluates to 1 when that identifier names the module we are
OpenPOWER on IntegriCloud