summaryrefslogtreecommitdiffstats
path: root/lib/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Lex')
-rw-r--r--lib/Lex/Lexer.cpp17
-rw-r--r--lib/Lex/LiteralSupport.cpp9
-rw-r--r--lib/Lex/MacroArgs.cpp2
-rw-r--r--lib/Lex/MacroArgs.h125
-rw-r--r--lib/Lex/ModuleMap.cpp60
-rw-r--r--lib/Lex/PPDirectives.cpp19
-rw-r--r--lib/Lex/PPMacroExpansion.cpp29
-rw-r--r--lib/Lex/Pragma.cpp267
-rw-r--r--lib/Lex/PreprocessingRecord.cpp3
-rw-r--r--lib/Lex/Preprocessor.cpp8
-rw-r--r--lib/Lex/TokenLexer.cpp2
11 files changed, 232 insertions, 309 deletions
diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp
index ed4666a..9958287 100644
--- a/lib/Lex/Lexer.cpp
+++ b/lib/Lex/Lexer.cpp
@@ -557,6 +557,7 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer,
SourceLocation FileLoc = SourceLocation::getFromRawEncoding(StartOffset);
Lexer TheLexer(FileLoc, LangOpts, Buffer->getBufferStart(),
Buffer->getBufferStart(), Buffer->getBufferEnd());
+ TheLexer.SetCommentRetentionState(true);
// StartLoc will differ from FileLoc if there is a BOM that was skipped.
SourceLocation StartLoc = TheLexer.getSourceLocation();
@@ -565,6 +566,7 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer,
Token TheTok;
Token IfStartTok;
unsigned IfCount = 0;
+ SourceLocation ActiveCommentLoc;
unsigned MaxLineOffset = 0;
if (MaxLines) {
@@ -612,13 +614,17 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer,
}
// Comments are okay; skip over them.
- if (TheTok.getKind() == tok::comment)
+ if (TheTok.getKind() == tok::comment) {
+ if (ActiveCommentLoc.isInvalid())
+ ActiveCommentLoc = TheTok.getLocation();
continue;
+ }
if (TheTok.isAtStartOfLine() && TheTok.getKind() == tok::hash) {
// This is the start of a preprocessor directive.
Token HashTok = TheTok;
InPreprocessorDirective = true;
+ ActiveCommentLoc = SourceLocation();
// Figure out which directive this is. Since we're lexing raw tokens,
// we don't have an identifier table available. Instead, just look at
@@ -689,7 +695,14 @@ Lexer::ComputePreamble(const llvm::MemoryBuffer *Buffer,
break;
} while (true);
- SourceLocation End = IfCount? IfStartTok.getLocation() : TheTok.getLocation();
+ SourceLocation End;
+ if (IfCount)
+ End = IfStartTok.getLocation();
+ else if (ActiveCommentLoc.isValid())
+ End = ActiveCommentLoc; // don't truncate a decl comment.
+ else
+ End = TheTok.getLocation();
+
return std::make_pair(End.getRawEncoding() - StartLoc.getRawEncoding(),
IfCount? IfStartTok.isAtStartOfLine()
: TheTok.isAtStartOfLine());
diff --git a/lib/Lex/LiteralSupport.cpp b/lib/Lex/LiteralSupport.cpp
index 91da822..09f4a68 100644
--- a/lib/Lex/LiteralSupport.cpp
+++ b/lib/Lex/LiteralSupport.cpp
@@ -686,8 +686,13 @@ void NumericLiteralParser::ParseNumberStartingWithZero(SourceLocation TokLoc) {
// Handle simple binary numbers 0b01010
if (*s == 'b' || *s == 'B') {
- // 0b101010 is a GCC extension.
- PP.Diag(TokLoc, diag::ext_binary_literal);
+ // 0b101010 is a C++1y / GCC extension.
+ PP.Diag(TokLoc,
+ PP.getLangOpts().CPlusPlus1y
+ ? diag::warn_cxx11_compat_binary_literal
+ : PP.getLangOpts().CPlusPlus
+ ? diag::ext_binary_literal_cxx1y
+ : diag::ext_binary_literal);
++s;
radix = 2;
DigitsBegin = s;
diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp
index f6e781a..d2dc04b 100644
--- a/lib/Lex/MacroArgs.cpp
+++ b/lib/Lex/MacroArgs.cpp
@@ -11,7 +11,7 @@
//
//===----------------------------------------------------------------------===//
-#include "MacroArgs.h"
+#include "clang/Lex/MacroArgs.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Preprocessor.h"
diff --git a/lib/Lex/MacroArgs.h b/lib/Lex/MacroArgs.h
deleted file mode 100644
index 1fd295e..0000000
--- a/lib/Lex/MacroArgs.h
+++ /dev/null
@@ -1,125 +0,0 @@
-//===--- MacroArgs.h - Formal argument info for Macros ----------*- 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 the MacroArgs interface.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_MACROARGS_H
-#define LLVM_CLANG_MACROARGS_H
-
-#include "clang/Basic/LLVM.h"
-#include "llvm/ADT/ArrayRef.h"
-#include <vector>
-
-namespace clang {
- class MacroInfo;
- class Preprocessor;
- class Token;
- class SourceLocation;
-
-/// MacroArgs - An instance of this class captures information about
-/// the formal arguments specified to a function-like macro invocation.
-class MacroArgs {
- /// NumUnexpArgTokens - The number of raw, unexpanded tokens for the
- /// arguments. All of the actual argument tokens are allocated immediately
- /// after the MacroArgs object in memory. This is all of the arguments
- /// concatenated together, with 'EOF' markers at the end of each argument.
- unsigned NumUnexpArgTokens;
-
- /// VarargsElided - True if this is a C99 style varargs macro invocation and
- /// there was no argument specified for the "..." argument. If the argument
- /// was specified (even empty) or this isn't a C99 style varargs function, or
- /// if in strict mode and the C99 varargs macro had only a ... argument, this
- /// is false.
- bool VarargsElided;
-
- /// PreExpArgTokens - Pre-expanded tokens for arguments that need them. Empty
- /// if not yet computed. This includes the EOF marker at the end of the
- /// stream.
- std::vector<std::vector<Token> > PreExpArgTokens;
-
- /// StringifiedArgs - This contains arguments in 'stringified' form. If the
- /// stringified form of an argument has not yet been computed, this is empty.
- std::vector<Token> StringifiedArgs;
-
- /// ArgCache - This is a linked list of MacroArgs objects that the
- /// Preprocessor owns which we use to avoid thrashing malloc/free.
- MacroArgs *ArgCache;
-
- MacroArgs(unsigned NumToks, bool varargsElided)
- : NumUnexpArgTokens(NumToks), VarargsElided(varargsElided), ArgCache(0) {}
- ~MacroArgs() {}
-public:
- /// MacroArgs ctor function - Create a new MacroArgs object with the specified
- /// macro and argument info.
- static MacroArgs *create(const MacroInfo *MI,
- ArrayRef<Token> UnexpArgTokens,
- bool VarargsElided, Preprocessor &PP);
-
- /// destroy - Destroy and deallocate the memory for this object.
- ///
- void destroy(Preprocessor &PP);
-
- /// ArgNeedsPreexpansion - If we can prove that the argument won't be affected
- /// by pre-expansion, return false. Otherwise, conservatively return true.
- bool ArgNeedsPreexpansion(const Token *ArgTok, Preprocessor &PP) const;
-
- /// getUnexpArgument - Return a pointer to the first token of the unexpanded
- /// token list for the specified formal.
- ///
- const Token *getUnexpArgument(unsigned Arg) const;
-
- /// getArgLength - Given a pointer to an expanded or unexpanded argument,
- /// return the number of tokens, not counting the EOF, that make up the
- /// argument.
- static unsigned getArgLength(const Token *ArgPtr);
-
- /// getPreExpArgument - Return the pre-expanded form of the specified
- /// argument.
- const std::vector<Token> &
- getPreExpArgument(unsigned Arg, const MacroInfo *MI, Preprocessor &PP);
-
- /// getStringifiedArgument - Compute, cache, and return the specified argument
- /// that has been 'stringified' as required by the # operator.
- const Token &getStringifiedArgument(unsigned ArgNo, Preprocessor &PP,
- SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd);
-
- /// getNumArguments - Return the number of arguments passed into this macro
- /// invocation.
- unsigned getNumArguments() const { return NumUnexpArgTokens; }
-
-
- /// isVarargsElidedUse - Return true if this is a C99 style varargs macro
- /// invocation and there was no argument specified for the "..." argument. If
- /// the argument was specified (even empty) or this isn't a C99 style varargs
- /// function, or if in strict mode and the C99 varargs macro had only a ...
- /// argument, this returns false.
- bool isVarargsElidedUse() const { return VarargsElided; }
-
- /// StringifyArgument - Implement C99 6.10.3.2p2, converting a sequence of
- /// tokens into the literal string token that should be produced by the C #
- /// preprocessor operator. If Charify is true, then it should be turned into
- /// a character literal for the Microsoft charize (#@) extension.
- ///
- static Token StringifyArgument(const Token *ArgToks,
- Preprocessor &PP, bool Charify,
- SourceLocation ExpansionLocStart,
- SourceLocation ExpansionLocEnd);
-
-
- /// deallocate - This should only be called by the Preprocessor when managing
- /// its freelist.
- MacroArgs *deallocate();
-};
-
-} // end namespace clang
-
-#endif
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 0c03201..3e7a44c 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -83,7 +83,7 @@ Module *ModuleMap::resolveModuleId(const ModuleId &Id, Module *Mod,
return Context;
}
-ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
+ModuleMap::ModuleMap(FileManager &FileMgr, DiagnosticConsumer &DC,
const LangOptions &LangOpts, const TargetInfo *Target,
HeaderSearch &HeaderInfo)
: LangOpts(LangOpts), Target(Target), HeaderInfo(HeaderInfo),
@@ -92,7 +92,8 @@ ModuleMap::ModuleMap(FileManager &FileMgr, const DiagnosticConsumer &DC,
IntrusiveRefCntPtr<DiagnosticIDs> DiagIDs(new DiagnosticIDs);
Diags = IntrusiveRefCntPtr<DiagnosticsEngine>(
new DiagnosticsEngine(DiagIDs, new DiagnosticOptions));
- Diags->setClient(DC.clone(*Diags), /*ShouldOwnClient=*/true);
+ Diags->setClient(new ForwardingDiagnosticConsumer(DC),
+ /*ShouldOwnClient=*/true);
SourceMgr = new SourceManager(*Diags, FileMgr);
}
@@ -149,6 +150,24 @@ static StringRef sanitizeFilenameAsIdentifier(StringRef Name,
return Name;
}
+/// \brief Determine whether the given file name is the name of a builtin
+/// header, supplied by Clang to replace, override, or augment existing system
+/// headers.
+static bool isBuiltinHeader(StringRef FileName) {
+ return llvm::StringSwitch<bool>(FileName)
+ .Case("float.h", true)
+ .Case("iso646.h", true)
+ .Case("limits.h", true)
+ .Case("stdalign.h", true)
+ .Case("stdarg.h", true)
+ .Case("stdbool.h", true)
+ .Case("stddef.h", true)
+ .Case("stdint.h", true)
+ .Case("tgmath.h", true)
+ .Case("unwind.h", true)
+ .Default(false);
+}
+
Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
HeadersMap::iterator Known = Headers.find(File);
if (Known != Headers.end()) {
@@ -158,6 +177,25 @@ Module *ModuleMap::findModuleForHeader(const FileEntry *File) {
return Known->second.getModule();
}
+
+ // If we've found a builtin header within Clang's builtin include directory,
+ // load all of the module maps to see if it will get associated with a
+ // specific module (e.g., in /usr/include).
+ if (File->getDir() == BuiltinIncludeDir &&
+ isBuiltinHeader(llvm::sys::path::filename(File->getName()))) {
+ SmallVector<Module *, 4> AllModules;
+ HeaderInfo.collectAllModules(AllModules);
+
+ // Check again.
+ Known = Headers.find(File);
+ if (Known != Headers.end()) {
+ // If a header is not available, don't report that it maps to anything.
+ if (!Known->second.isAvailable())
+ return 0;
+
+ return Known->second.getModule();
+ }
+ }
const DirectoryEntry *Dir = File->getDir();
SmallVector<const DirectoryEntry *, 2> SkippedDirs;
@@ -1266,24 +1304,6 @@ static void appendSubframeworkPaths(Module *Mod,
}
}
-/// \brief Determine whether the given file name is the name of a builtin
-/// header, supplied by Clang to replace, override, or augment existing system
-/// headers.
-static bool isBuiltinHeader(StringRef FileName) {
- return llvm::StringSwitch<bool>(FileName)
- .Case("float.h", true)
- .Case("iso646.h", true)
- .Case("limits.h", true)
- .Case("stdalign.h", true)
- .Case("stdarg.h", true)
- .Case("stdbool.h", true)
- .Case("stddef.h", true)
- .Case("stdint.h", true)
- .Case("tgmath.h", true)
- .Case("unwind.h", true)
- .Default(false);
-}
-
/// \brief Parse a header declaration.
///
/// header-declaration:
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 07c1867..50a0cb5 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -61,9 +61,12 @@ MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L,
unsigned SubModuleID) {
LLVM_STATIC_ASSERT(llvm::AlignOf<MacroInfo>::Alignment >= sizeof(SubModuleID),
"alignment for MacroInfo is less than the ID");
- MacroInfo *MI =
- (MacroInfo*)BP.Allocate(sizeof(MacroInfo) + sizeof(SubModuleID),
- llvm::AlignOf<MacroInfo>::Alignment);
+ DeserializedMacroInfoChain *MIChain =
+ BP.Allocate<DeserializedMacroInfoChain>();
+ MIChain->Next = DeserialMIChainHead;
+ DeserialMIChainHead = MIChain;
+
+ MacroInfo *MI = &MIChain->MI;
new (MI) MacroInfo(L);
MI->FromASTFile = true;
MI->setOwningModuleID(SubModuleID);
@@ -793,7 +796,8 @@ void Preprocessor::HandleDirective(Token &Result) {
/// GetLineValue - Convert a numeric token into an unsigned value, emitting
/// Diagnostic DiagID if it is invalid, and returning the value in Val.
static bool GetLineValue(Token &DigitTok, unsigned &Val,
- unsigned DiagID, Preprocessor &PP) {
+ unsigned DiagID, Preprocessor &PP,
+ bool IsGNULineDirective=false) {
if (DigitTok.isNot(tok::numeric_constant)) {
PP.Diag(DigitTok, DiagID);
@@ -817,7 +821,7 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
for (unsigned i = 0; i != ActualLength; ++i) {
if (!isDigit(DigitTokBegin[i])) {
PP.Diag(PP.AdvanceToTokenCharacter(DigitTok.getLocation(), i),
- diag::err_pp_line_digit_sequence);
+ diag::err_pp_line_digit_sequence) << IsGNULineDirective;
PP.DiscardUntilEndOfDirective();
return true;
}
@@ -832,7 +836,8 @@ static bool GetLineValue(Token &DigitTok, unsigned &Val,
}
if (DigitTokBegin[0] == '0' && Val)
- PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal);
+ PP.Diag(DigitTok.getLocation(), diag::warn_pp_line_decimal)
+ << IsGNULineDirective;
return false;
}
@@ -998,7 +1003,7 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
// line # limit other than it fit in 32-bits.
unsigned LineNo;
if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer,
- *this))
+ *this, true))
return;
Token StrTok;
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 21451f5..24c6217 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -13,7 +13,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Lex/Preprocessor.h"
-#include "MacroArgs.h"
+#include "clang/Lex/MacroArgs.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -223,7 +223,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, MD,
- Identifier.getLocation());
+ Identifier.getLocation(),/*Args=*/0);
ExpandBuiltinMacro(Identifier);
return false;
}
@@ -277,11 +277,12 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
DelayedMacroExpandsCallbacks.push_back(
MacroExpandsInfo(Identifier, MD, ExpansionRange));
} else {
- Callbacks->MacroExpands(Identifier, MD, ExpansionRange);
+ Callbacks->MacroExpands(Identifier, MD, ExpansionRange, Args);
if (!DelayedMacroExpandsCallbacks.empty()) {
for (unsigned i=0, e = DelayedMacroExpandsCallbacks.size(); i!=e; ++i) {
MacroExpandsInfo &Info = DelayedMacroExpandsCallbacks[i];
- Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range);
+ // FIXME: We lose macro args info with delayed callback.
+ Callbacks->MacroExpands(Info.Tok, Info.MD, Info.Range, /*Args=*/0);
}
DelayedMacroExpandsCallbacks.clear();
}
@@ -751,6 +752,8 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("c_atomic", LangOpts.C11)
.Case("c_generic_selections", LangOpts.C11)
.Case("c_static_assert", LangOpts.C11)
+ .Case("c_thread_local",
+ LangOpts.C11 && PP.getTargetInfo().isTLSSupported())
// C++11 features
.Case("cxx_access_control_sfinae", LangOpts.CPlusPlus11)
.Case("cxx_alias_templates", LangOpts.CPlusPlus11)
@@ -768,7 +771,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.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_inheriting_constructors", LangOpts.CPlusPlus11)
.Case("cxx_inline_namespaces", LangOpts.CPlusPlus11)
.Case("cxx_lambdas", LangOpts.CPlusPlus11)
.Case("cxx_local_type_template_args", LangOpts.CPlusPlus11)
@@ -782,11 +785,23 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("cxx_rvalue_references", LangOpts.CPlusPlus11)
.Case("cxx_strong_enums", LangOpts.CPlusPlus11)
.Case("cxx_static_assert", LangOpts.CPlusPlus11)
+ .Case("cxx_thread_local",
+ LangOpts.CPlusPlus11 && PP.getTargetInfo().isTLSSupported())
.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)
+ // C++1y features
+ .Case("cxx_binary_literals", LangOpts.CPlusPlus1y)
+ //.Case("cxx_contextual_conversions", LangOpts.CPlusPlus1y)
+ //.Case("cxx_generalized_capture", LangOpts.CPlusPlus1y)
+ //.Case("cxx_generic_lambda", LangOpts.CPlusPlus1y)
+ //.Case("cxx_relaxed_constexpr", LangOpts.CPlusPlus1y)
+ //.Case("cxx_return_type_deduction", LangOpts.CPlusPlus1y)
+ //.Case("cxx_runtime_array", LangOpts.CPlusPlus1y)
+ .Case("cxx_aggregate_nsdmi", LangOpts.CPlusPlus1y)
+ //.Case("cxx_variable_templates", LangOpts.CPlusPlus1y)
// Type traits
.Case("has_nothrow_assign", LangOpts.CPlusPlus)
.Case("has_nothrow_copy", LangOpts.CPlusPlus)
@@ -847,7 +862,7 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("c_atomic", true)
.Case("c_generic_selections", true)
.Case("c_static_assert", true)
- // C++0x features supported by other languages as extensions.
+ // C++11 features supported by other languages as extensions.
.Case("cxx_atomic", LangOpts.CPlusPlus)
.Case("cxx_deleted_functions", LangOpts.CPlusPlus)
.Case("cxx_explicit_conversions", LangOpts.CPlusPlus)
@@ -858,6 +873,8 @@ static bool HasExtension(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("cxx_range_for", LangOpts.CPlusPlus)
.Case("cxx_reference_qualified_functions", LangOpts.CPlusPlus)
.Case("cxx_rvalue_references", LangOpts.CPlusPlus)
+ // C++1y features supported by other languages as extensions.
+ .Case("cxx_binary_literals", true)
.Default(false);
}
diff --git a/lib/Lex/Pragma.cpp b/lib/Lex/Pragma.cpp
index 95e8a8c..b2ae4c9 100644
--- a/lib/Lex/Pragma.cpp
+++ b/lib/Lex/Pragma.cpp
@@ -254,14 +254,15 @@ void Preprocessor::Handle_Pragma(Token &Tok) {
"Invalid string token!");
// Remove escaped quotes and escapes.
- for (unsigned i = 1, e = StrVal.size(); i < e-2; ++i) {
- if (StrVal[i] == '\\' &&
- (StrVal[i+1] == '\\' || StrVal[i+1] == '"')) {
+ unsigned ResultPos = 1;
+ for (unsigned i = 1, e = StrVal.size() - 2; i != e; ++i) {
+ if (StrVal[i] != '\\' ||
+ (StrVal[i + 1] != '\\' && StrVal[i + 1] != '"')) {
// \\ -> '\' and \" -> '"'.
- StrVal.erase(StrVal.begin()+i);
- --e;
+ StrVal[ResultPos++] = StrVal[i];
}
}
+ StrVal.erase(StrVal.begin() + ResultPos, StrVal.end() - 2);
}
// Remove the front quote, replacing it with a space, so that the pragma
@@ -434,8 +435,9 @@ void Preprocessor::HandlePragmaSystemHeader(Token &SysHeaderTok) {
// Emit a line marker. This will change any source locations from this point
// forward to realize they are in a system header.
// Create a line note with this information.
- SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine(), FilenameID,
- false, false, true, false);
+ SourceMgr.AddLineNote(SysHeaderTok.getLocation(), PLoc.getLine()+1,
+ FilenameID, /*IsEntry=*/false, /*IsExit=*/false,
+ /*IsSystem=*/true, /*IsExternC=*/false);
}
/// HandlePragmaDependency - Handle \#pragma GCC dependency "foo" blah.
@@ -491,126 +493,7 @@ void Preprocessor::HandlePragmaDependency(Token &DependencyTok) {
}
}
-/// \brief Handle the microsoft \#pragma comment extension.
-///
-/// The syntax is:
-/// \code
-/// #pragma comment(linker, "foo")
-/// \endcode
-/// 'linker' is one of five identifiers: compiler, exestr, lib, linker, user.
-/// "foo" is a string, which is fully macro expanded, and permits string
-/// concatenation, embedded escape characters etc. See MSDN for more details.
-void Preprocessor::HandlePragmaComment(Token &Tok) {
- SourceLocation CommentLoc = Tok.getLocation();
- Lex(Tok);
- if (Tok.isNot(tok::l_paren)) {
- Diag(CommentLoc, diag::err_pragma_comment_malformed);
- return;
- }
-
- // Read the identifier.
- Lex(Tok);
- if (Tok.isNot(tok::identifier)) {
- Diag(CommentLoc, diag::err_pragma_comment_malformed);
- return;
- }
-
- // Verify that this is one of the 5 whitelisted options.
- // FIXME: warn that 'exestr' is deprecated.
- const IdentifierInfo *II = Tok.getIdentifierInfo();
- if (!II->isStr("compiler") && !II->isStr("exestr") && !II->isStr("lib") &&
- !II->isStr("linker") && !II->isStr("user")) {
- Diag(Tok.getLocation(), diag::err_pragma_comment_unknown_kind);
- return;
- }
-
- // Read the optional string if present.
- Lex(Tok);
- std::string ArgumentString;
- if (Tok.is(tok::comma) && !LexStringLiteral(Tok, ArgumentString,
- "pragma comment",
- /*MacroExpansion=*/true))
- return;
-
- // FIXME: If the kind is "compiler" warn if the string is present (it is
- // ignored).
- // FIXME: 'lib' requires a comment string.
- // FIXME: 'linker' requires a comment string, and has a specific list of
- // things that are allowable.
-
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
- return;
- }
- Lex(Tok); // eat the r_paren.
-
- if (Tok.isNot(tok::eod)) {
- Diag(Tok.getLocation(), diag::err_pragma_comment_malformed);
- return;
- }
-
- // If the pragma is lexically sound, notify any interested PPCallbacks.
- if (Callbacks)
- Callbacks->PragmaComment(CommentLoc, II, ArgumentString);
-}
-
-/// HandlePragmaMessage - Handle the microsoft and gcc \#pragma message
-/// extension. The syntax is:
-/// \code
-/// #pragma message(string)
-/// \endcode
-/// OR, in GCC mode:
-/// \code
-/// #pragma message string
-/// \endcode
-/// string is a string, which is fully macro expanded, and permits string
-/// concatenation, embedded escape characters, etc... See MSDN for more details.
-void Preprocessor::HandlePragmaMessage(Token &Tok) {
- SourceLocation MessageLoc = Tok.getLocation();
- Lex(Tok);
- bool ExpectClosingParen = false;
- switch (Tok.getKind()) {
- case tok::l_paren:
- // We have a MSVC style pragma message.
- ExpectClosingParen = true;
- // Read the string.
- Lex(Tok);
- break;
- case tok::string_literal:
- // We have a GCC style pragma message, and we just read the string.
- break;
- default:
- Diag(MessageLoc, diag::err_pragma_message_malformed);
- return;
- }
-
- std::string MessageString;
- if (!FinishLexStringLiteral(Tok, MessageString, "pragma message",
- /*MacroExpansion=*/true))
- return;
-
- if (ExpectClosingParen) {
- if (Tok.isNot(tok::r_paren)) {
- Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
- return;
- }
- Lex(Tok); // eat the r_paren.
- }
-
- if (Tok.isNot(tok::eod)) {
- Diag(Tok.getLocation(), diag::err_pragma_message_malformed);
- return;
- }
-
- // Output the message.
- Diag(MessageLoc, diag::warn_pragma_message) << MessageString;
-
- // If the pragma is lexically sound, notify any interested PPCallbacks.
- if (Callbacks)
- Callbacks->PragmaMessage(MessageLoc, MessageString);
-}
-
-/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
+/// ParsePragmaPushOrPopMacro - Handle parsing of pragma push_macro/pop_macro.
/// Return the IdentifierInfo* associated with the macro to push or pop.
IdentifierInfo *Preprocessor::ParsePragmaPushOrPopMacro(Token &Tok) {
// Remember the pragma token location.
@@ -995,10 +878,40 @@ struct PragmaDebugHandler : public PragmaHandler {
llvm::CrashRecoveryContext *CRC =llvm::CrashRecoveryContext::GetCurrent();
if (CRC)
CRC->HandleCrash();
+ } else if (II->isStr("captured")) {
+ HandleCaptured(PP);
} else {
PP.Diag(Tok, diag::warn_pragma_debug_unexpected_command)
<< II->getName();
}
+
+ PPCallbacks *Callbacks = PP.getPPCallbacks();
+ if (Callbacks)
+ Callbacks->PragmaDebug(Tok.getLocation(), II->getName());
+ }
+
+ void HandleCaptured(Preprocessor &PP) {
+ // Skip if emitting preprocessed output.
+ if (PP.isPreprocessedOutput())
+ return;
+
+ Token Tok;
+ PP.LexUnexpandedToken(Tok);
+
+ if (Tok.isNot(tok::eod)) {
+ PP.Diag(Tok, diag::ext_pp_extra_tokens_at_eol)
+ << "pragma clang __debug captured";
+ return;
+ }
+
+ SourceLocation NameLoc = Tok.getLocation();
+ Token *Toks = PP.getPreprocessorAllocator().Allocate<Token>(1);
+ Toks->startToken();
+ Toks->setKind(tok::annot_pragma_captured);
+ Toks->setLocation(NameLoc);
+
+ PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+ /*OwnsTokens=*/false);
}
// Disable MSVC warning about runtime stack overflow.
@@ -1086,15 +999,6 @@ public:
}
};
-/// PragmaCommentHandler - "\#pragma comment ...".
-struct PragmaCommentHandler : public PragmaHandler {
- PragmaCommentHandler() : PragmaHandler("comment") {}
- virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &CommentTok) {
- PP.HandlePragmaComment(CommentTok);
- }
-};
-
/// PragmaIncludeAliasHandler - "\#pragma include_alias("...")".
struct PragmaIncludeAliasHandler : public PragmaHandler {
PragmaIncludeAliasHandler() : PragmaHandler("include_alias") {}
@@ -1104,12 +1008,88 @@ struct PragmaIncludeAliasHandler : public PragmaHandler {
}
};
-/// PragmaMessageHandler - "\#pragma message("...")".
+/// PragmaMessageHandler - Handle the microsoft and gcc \#pragma message
+/// extension. The syntax is:
+/// \code
+/// #pragma message(string)
+/// \endcode
+/// OR, in GCC mode:
+/// \code
+/// #pragma message string
+/// \endcode
+/// string is a string, which is fully macro expanded, and permits string
+/// concatenation, embedded escape characters, etc... See MSDN for more details.
+/// Also handles \#pragma GCC warning and \#pragma GCC error which take the same
+/// form as \#pragma message.
struct PragmaMessageHandler : public PragmaHandler {
- PragmaMessageHandler() : PragmaHandler("message") {}
+private:
+ const PPCallbacks::PragmaMessageKind Kind;
+ const StringRef Namespace;
+
+ static const char* PragmaKind(PPCallbacks::PragmaMessageKind Kind,
+ bool PragmaNameOnly = false) {
+ switch (Kind) {
+ case PPCallbacks::PMK_Message:
+ return PragmaNameOnly ? "message" : "pragma message";
+ case PPCallbacks::PMK_Warning:
+ return PragmaNameOnly ? "warning" : "pragma warning";
+ case PPCallbacks::PMK_Error:
+ return PragmaNameOnly ? "error" : "pragma error";
+ }
+ llvm_unreachable("Unknown PragmaMessageKind!");
+ }
+
+public:
+ PragmaMessageHandler(PPCallbacks::PragmaMessageKind Kind,
+ StringRef Namespace = StringRef())
+ : PragmaHandler(PragmaKind(Kind, true)), Kind(Kind), Namespace(Namespace) {}
+
virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
- Token &CommentTok) {
- PP.HandlePragmaMessage(CommentTok);
+ Token &Tok) {
+ SourceLocation MessageLoc = Tok.getLocation();
+ PP.Lex(Tok);
+ bool ExpectClosingParen = false;
+ switch (Tok.getKind()) {
+ case tok::l_paren:
+ // We have a MSVC style pragma message.
+ ExpectClosingParen = true;
+ // Read the string.
+ PP.Lex(Tok);
+ break;
+ case tok::string_literal:
+ // We have a GCC style pragma message, and we just read the string.
+ break;
+ default:
+ PP.Diag(MessageLoc, diag::err_pragma_message_malformed) << Kind;
+ return;
+ }
+
+ std::string MessageString;
+ if (!PP.FinishLexStringLiteral(Tok, MessageString, PragmaKind(Kind),
+ /*MacroExpansion=*/true))
+ return;
+
+ if (ExpectClosingParen) {
+ if (Tok.isNot(tok::r_paren)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
+ return;
+ }
+ PP.Lex(Tok); // eat the r_paren.
+ }
+
+ if (Tok.isNot(tok::eod)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_message_malformed) << Kind;
+ return;
+ }
+
+ // Output the message.
+ PP.Diag(MessageLoc, (Kind == PPCallbacks::PMK_Error)
+ ? diag::err_pragma_message
+ : diag::warn_pragma_message) << MessageString;
+
+ // If the pragma is lexically sound, notify any interested PPCallbacks.
+ if (PPCallbacks *Callbacks = PP.getPPCallbacks())
+ Callbacks->PragmaMessage(MessageLoc, Namespace, Kind, MessageString);
}
};
@@ -1257,13 +1237,17 @@ void Preprocessor::RegisterBuiltinPragmas() {
AddPragmaHandler(new PragmaMarkHandler());
AddPragmaHandler(new PragmaPushMacroHandler());
AddPragmaHandler(new PragmaPopMacroHandler());
- AddPragmaHandler(new PragmaMessageHandler());
+ AddPragmaHandler(new PragmaMessageHandler(PPCallbacks::PMK_Message));
// #pragma GCC ...
AddPragmaHandler("GCC", new PragmaPoisonHandler());
AddPragmaHandler("GCC", new PragmaSystemHeaderHandler());
AddPragmaHandler("GCC", new PragmaDependencyHandler());
AddPragmaHandler("GCC", new PragmaDiagnosticHandler("GCC"));
+ AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Warning,
+ "GCC"));
+ AddPragmaHandler("GCC", new PragmaMessageHandler(PPCallbacks::PMK_Error,
+ "GCC"));
// #pragma clang ...
AddPragmaHandler("clang", new PragmaPoisonHandler());
AddPragmaHandler("clang", new PragmaSystemHeaderHandler());
@@ -1278,7 +1262,6 @@ void Preprocessor::RegisterBuiltinPragmas() {
// MS extensions.
if (LangOpts.MicrosoftExt) {
- AddPragmaHandler(new PragmaCommentHandler());
AddPragmaHandler(new PragmaIncludeAliasHandler());
AddPragmaHandler(new PragmaRegionHandler("region"));
AddPragmaHandler(new PragmaRegionHandler("endregion"));
diff --git a/lib/Lex/PreprocessingRecord.cpp b/lib/Lex/PreprocessingRecord.cpp
index b10e7f7..426b922 100644
--- a/lib/Lex/PreprocessingRecord.cpp
+++ b/lib/Lex/PreprocessingRecord.cpp
@@ -406,7 +406,8 @@ void PreprocessingRecord::Defined(const Token &MacroNameTok,
}
void PreprocessingRecord::MacroExpands(const Token &Id,const MacroDirective *MD,
- SourceRange Range) {
+ SourceRange Range,
+ const MacroArgs *Args) {
addMacroExpansion(Id, MD->getMacroInfo(), Range);
}
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 53c45dc..66f23f1 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -26,7 +26,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Lex/Preprocessor.h"
-#include "MacroArgs.h"
+#include "clang/Lex/MacroArgs.h"
#include "clang/Basic/FileManager.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
@@ -67,7 +67,8 @@ Preprocessor::Preprocessor(IntrusiveRefCntPtr<PreprocessorOptions> PPOpts,
CodeComplete(0), CodeCompletionFile(0), CodeCompletionOffset(0),
CodeCompletionReached(0), SkipMainFilePreamble(0, true), CurPPLexer(0),
CurDirLookup(0), CurLexerKind(CLK_Lexer), Callbacks(0),
- MacroArgCache(0), Record(0), MIChainHead(0), MICache(0) {
+ MacroArgCache(0), Record(0), MIChainHead(0), MICache(0),
+ DeserialMIChainHead(0) {
OwnsHeaderSearch = OwnsHeaders;
ScratchBuf = new ScratchBuffer(SourceMgr);
@@ -153,6 +154,9 @@ Preprocessor::~Preprocessor() {
for (unsigned i = 0, e = NumCachedTokenLexers; i != e; ++i)
delete TokenLexerCache[i];
+ for (DeserializedMacroInfoChain *I = DeserialMIChainHead ; I ; I = I->Next)
+ I->MI.Destroy();
+
// Free any cached MacroArgs.
for (MacroArgs *ArgList = MacroArgCache; ArgList; )
ArgList = ArgList->deallocate();
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 5b41fe9..07753c7 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -12,7 +12,7 @@
//===----------------------------------------------------------------------===//
#include "clang/Lex/TokenLexer.h"
-#include "MacroArgs.h"
+#include "clang/Lex/MacroArgs.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/LexDiagnostic.h"
#include "clang/Lex/MacroInfo.h"
OpenPOWER on IntegriCloud