summaryrefslogtreecommitdiffstats
path: root/include/clang/Lex
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Lex')
-rw-r--r--include/clang/Lex/CMakeLists.txt6
-rw-r--r--include/clang/Lex/ExternalPreprocessorSource.h3
-rw-r--r--include/clang/Lex/HeaderMap.h2
-rw-r--r--include/clang/Lex/HeaderSearch.h61
-rw-r--r--include/clang/Lex/LexDiagnostic.h2
-rw-r--r--include/clang/Lex/Lexer.h53
-rw-r--r--include/clang/Lex/LiteralSupport.h31
-rw-r--r--include/clang/Lex/MacroInfo.h13
-rw-r--r--include/clang/Lex/Makefile13
-rw-r--r--include/clang/Lex/PPCallbacks.h139
-rw-r--r--include/clang/Lex/PTHManager.h6
-rw-r--r--include/clang/Lex/Pragma.h31
-rw-r--r--include/clang/Lex/PreprocessingRecord.h93
-rw-r--r--include/clang/Lex/Preprocessor.h106
-rw-r--r--include/clang/Lex/PreprocessorLexer.h12
-rw-r--r--include/clang/Lex/Token.h42
16 files changed, 529 insertions, 84 deletions
diff --git a/include/clang/Lex/CMakeLists.txt b/include/clang/Lex/CMakeLists.txt
new file mode 100644
index 0000000..b823e83
--- /dev/null
+++ b/include/clang/Lex/CMakeLists.txt
@@ -0,0 +1,6 @@
+set(LLVM_TARGET_DEFINITIONS ../Basic/Attr.td)
+tablegen(AttrSpellings.inc
+ -gen-clang-attr-spelling-list
+ -I ${CMAKE_CURRENT_SOURCE_DIR}/../../)
+add_custom_target(ClangAttrSpellings
+ DEPENDS AttrSpellings.inc)
diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h
index 791d3fe..dbf7389 100644
--- a/include/clang/Lex/ExternalPreprocessorSource.h
+++ b/include/clang/Lex/ExternalPreprocessorSource.h
@@ -27,6 +27,9 @@ public:
/// \brief Read the set of macros defined by this external macro source.
virtual void ReadDefinedMacros() = 0;
+
+ /// \brief Read the definition for the given macro.
+ virtual void LoadMacroDefinition(IdentifierInfo *II) = 0;
};
}
diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h
index 9837e29..8a5c83e 100644
--- a/include/clang/Lex/HeaderMap.h
+++ b/include/clang/Lex/HeaderMap.h
@@ -43,7 +43,7 @@ public:
/// HeaderMap::Create - This attempts to load the specified file as a header
/// map. If it doesn't look like a HeaderMap, it gives up and returns null.
- static const HeaderMap *Create(const FileEntry *FE);
+ static const HeaderMap *Create(const FileEntry *FE, FileManager &FM);
/// LookupFile - Check to see if the specified relative filename is located in
/// this HeaderMap. If so, open it and return its FileEntry.
diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h
index 80b38de..30bd4f5 100644
--- a/include/clang/Lex/HeaderSearch.h
+++ b/include/clang/Lex/HeaderSearch.h
@@ -29,7 +29,7 @@ class IdentifierInfo;
/// file that is #included.
struct HeaderFileInfo {
/// isImport - True if this is a #import'd or #pragma once file.
- bool isImport : 1;
+ unsigned isImport : 1;
/// DirInfo - Keep track of whether this is a system header, and if so,
/// whether it is C++ clean or not. This can be set by the include paths or
@@ -37,10 +37,24 @@ struct HeaderFileInfo {
/// SrcMgr::CharacteristicKind.
unsigned DirInfo : 2;
+ /// \brief Whether this header file info was supplied by an external source.
+ unsigned External : 1;
+
+ /// \brief Whether this structure is considered to already have been
+ /// "resolved", meaning that it was loaded from the external source.
+ unsigned Resolved : 1;
+
/// NumIncludes - This is the number of times the file has been included
/// already.
unsigned short NumIncludes;
+ /// \brief The ID number of the controlling macro.
+ ///
+ /// This ID number will be non-zero when there is a controlling
+ /// macro whose IdentifierInfo may not yet have been loaded from
+ /// external storage.
+ unsigned ControllingMacroID;
+
/// ControllingMacro - If this file has a #ifndef XXX (or equivalent) guard
/// that protects the entire contents of the file, this is the identifier
/// for the macro that controls whether or not it has any effect.
@@ -51,27 +65,40 @@ struct HeaderFileInfo {
/// external storage.
const IdentifierInfo *ControllingMacro;
- /// \brief The ID number of the controlling macro.
- ///
- /// This ID number will be non-zero when there is a controlling
- /// macro whose IdentifierInfo may not yet have been loaded from
- /// external storage.
- unsigned ControllingMacroID;
-
HeaderFileInfo()
- : isImport(false), DirInfo(SrcMgr::C_User),
- NumIncludes(0), ControllingMacro(0), ControllingMacroID(0) {}
+ : isImport(false), DirInfo(SrcMgr::C_User), External(false),
+ Resolved(false), NumIncludes(0), ControllingMacroID(0),
+ ControllingMacro(0) {}
/// \brief Retrieve the controlling macro for this header file, if
/// any.
const IdentifierInfo *getControllingMacro(ExternalIdentifierLookup *External);
+
+ /// \brief Determine whether this is a non-default header file info, e.g.,
+ /// it corresponds to an actual header we've included or tried to include.
+ bool isNonDefault() const {
+ return isImport || NumIncludes || ControllingMacro || ControllingMacroID;
+ }
};
+/// \brief An external source of header file information, which may supply
+/// information about header files already included.
+class ExternalHeaderFileInfoSource {
+public:
+ virtual ~ExternalHeaderFileInfoSource();
+
+ /// \brief Retrieve the header file information for the given file entry.
+ ///
+ /// \returns Header file information for the given file entry, with the
+ /// \c External bit set. If the file entry is not known, return a
+ /// default-constructed \c HeaderFileInfo.
+ virtual HeaderFileInfo GetHeaderFileInfo(const FileEntry *FE) = 0;
+};
+
/// HeaderSearch - This class encapsulates the information needed to find the
/// file referenced by a #include or #include_next, (sub-)framework lookup, etc.
class HeaderSearch {
FileManager &FileMgr;
-
/// #include search path information. Requests for #include "x" search the
/// directory of the #including file first, then each directory in SearchDirs
/// consequtively. Requests for <x> search the current dir first, then each
@@ -108,6 +135,9 @@ class HeaderSearch {
/// macros into IdentifierInfo pointers, as needed.
ExternalIdentifierLookup *ExternalLookup;
+ /// \brief Entity used to look up stored header file information.
+ ExternalHeaderFileInfoSource *ExternalSource;
+
// Various statistics we track for performance analysis.
unsigned NumIncluded;
unsigned NumMultiIncludeFileOptzn;
@@ -142,6 +172,15 @@ public:
ExternalLookup = EIL;
}
+ ExternalIdentifierLookup *getExternalLookup() const {
+ return ExternalLookup;
+ }
+
+ /// \brief Set the external source of header information.
+ void SetExternalSource(ExternalHeaderFileInfoSource *ES) {
+ ExternalSource = ES;
+ }
+
/// LookupFile - Given a "foo" or <foo> reference, look up the indicated file,
/// return null on failure. isAngled indicates whether the file reference is
/// a <> reference. If successful, this returns 'UsedDir', the
diff --git a/include/clang/Lex/LexDiagnostic.h b/include/clang/Lex/LexDiagnostic.h
index 2d941e4..5fcb8eb 100644
--- a/include/clang/Lex/LexDiagnostic.h
+++ b/include/clang/Lex/LexDiagnostic.h
@@ -15,7 +15,7 @@
namespace clang {
namespace diag {
enum {
-#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,CATEGORY) ENUM,
+#define DIAG(ENUM,FLAGS,DEFAULT_MAPPING,DESC,GROUP,SFINAE,ACCESS,CATEGORY) ENUM,
#define LEXSTART
#include "clang/Basic/DiagnosticLexKinds.inc"
#undef DIAG
diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h
index 9e0fb7e..fc9a8de 100644
--- a/include/clang/Lex/Lexer.h
+++ b/include/clang/Lex/Lexer.h
@@ -211,6 +211,32 @@ public:
/// and " characters. This does not add surrounding ""'s to the string.
static void Stringify(llvm::SmallVectorImpl<char> &Str);
+
+ /// getSpelling - This method is used to get the spelling of a token into a
+ /// preallocated buffer, instead of as an std::string. The caller is required
+ /// to allocate enough space for the token, which is guaranteed to be at least
+ /// Tok.getLength() bytes long. The length of the actual result is returned.
+ ///
+ /// Note that this method may do two possible things: it may either fill in
+ /// the buffer specified with characters, or it may *change the input pointer*
+ /// to point to a constant buffer with the data already in it (avoiding a
+ /// copy). The caller is not allowed to modify the returned buffer pointer
+ /// if an internal buffer is returned.
+ static unsigned getSpelling(const Token &Tok, const char *&Buffer,
+ const SourceManager &SourceMgr,
+ const LangOptions &Features,
+ bool *Invalid = 0);
+
+ /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
+ /// token is the characters used to represent the token in the source file
+ /// after trigraph expansion and escaped-newline folding. In particular, this
+ /// wants to get the true, uncanonicalized, spelling of things like digraphs
+ /// UCNs, etc.
+ static std::string getSpelling(const Token &Tok,
+ const SourceManager &SourceMgr,
+ const LangOptions &Features,
+ bool *Invalid = 0);
+
/// MeasureTokenLength - Relex the token at the specified location and return
/// its length in bytes in the input file. If the token needs cleaning (e.g.
/// includes a trigraph or an escaped newline) then this count includes bytes
@@ -228,6 +254,33 @@ public:
const SourceManager &SM,
const LangOptions &LangOpts);
+ /// AdvanceToTokenCharacter - If the current SourceLocation specifies a
+ /// location at the start of a token, return a new location that specifies a
+ /// character within the token. This handles trigraphs and escaped newlines.
+ static SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
+ unsigned Character,
+ const SourceManager &SM,
+ const LangOptions &Features);
+
+ /// \brief Computes the source location just past the end of the
+ /// token at this source location.
+ ///
+ /// This routine can be used to produce a source location that
+ /// points just past the end of the token referenced by \p Loc, and
+ /// is generally used when a diagnostic needs to point just after a
+ /// token where it expected something different that it received. If
+ /// the returned source location would not be meaningful (e.g., if
+ /// it points into a macro), this routine returns an invalid
+ /// source location.
+ ///
+ /// \param Offset an offset from the end of the token, where the source
+ /// location should refer to. The default offset (0) produces a source
+ /// location pointing just past the end of the token; an offset of 1 produces
+ /// a source location pointing to the last character in the token, etc.
+ static SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset,
+ const SourceManager &SM,
+ const LangOptions &Features);
+
/// \brief Compute the preamble of the given file.
///
/// The preamble of a file contains the initial comments, include directives,
diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h
index ba46fb1..bf2c06b 100644
--- a/include/clang/Lex/LiteralSupport.h
+++ b/include/clang/Lex/LiteralSupport.h
@@ -15,10 +15,11 @@
#ifndef CLANG_LITERALSUPPORT_H
#define CLANG_LITERALSUPPORT_H
-#include <string>
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/System/DataTypes.h"
+#include "llvm/Support/DataTypes.h"
+#include <cctype>
+#include <string>
namespace clang {
@@ -27,6 +28,8 @@ class Preprocessor;
class Token;
class SourceLocation;
class TargetInfo;
+class SourceManager;
+class LangOptions;
/// NumericLiteralParser - This performs strict semantic analysis of the content
/// of a ppnumber, classifying it as either integer, floating, or erroneous,
@@ -138,8 +141,11 @@ public:
/// wide string analysis and Translation Phase #6 (concatenation of string
/// literals) (C99 5.1.1.2p1).
class StringLiteralParser {
- Preprocessor &PP;
-
+ const SourceManager &SM;
+ const LangOptions &Features;
+ const TargetInfo &Target;
+ Diagnostic *Diags;
+
unsigned MaxTokenLength;
unsigned SizeBound;
unsigned wchar_tByteWidth;
@@ -148,6 +154,14 @@ class StringLiteralParser {
public:
StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
Preprocessor &PP, bool Complain = true);
+ StringLiteralParser(const Token *StringToks, unsigned NumStringToks,
+ const SourceManager &sm, const LangOptions &features,
+ const TargetInfo &target, Diagnostic *diags = 0)
+ : SM(sm), Features(features), Target(target), Diags(diags) {
+ init(StringToks, NumStringToks);
+ }
+
+
bool hadError;
bool AnyWide;
bool Pascal;
@@ -163,8 +177,13 @@ public:
/// getOffsetOfStringByte - This function returns the offset of the
/// specified byte of the string data represented by Token. This handles
/// advancing over escape sequences in the string.
- static unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo,
- Preprocessor &PP, bool Complain = true);
+ ///
+ /// If the Diagnostics pointer is non-null, then this will do semantic
+ /// checking of the string literal and emit errors and warnings.
+ unsigned getOffsetOfStringByte(const Token &TheTok, unsigned ByteNo) const;
+
+private:
+ void init(const Token *StringToks, unsigned NumStringToks);
};
} // end namespace clang
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 90f95b7..717c300 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -82,6 +82,9 @@ private:
/// AllowRedefinitionsWithoutWarning - True if this macro can be redefined
/// without emitting a warning.
bool IsAllowRedefinitionsWithoutWarning : 1;
+
+ /// \brief Must warn if the macro is unused at the end of translation unit.
+ bool IsWarnIfUnused : 1;
~MacroInfo() {
assert(ArgumentList == 0 && "Didn't call destroy before dtor!");
@@ -138,6 +141,11 @@ public:
IsAllowRedefinitionsWithoutWarning = Val;
}
+ /// \brief Set the value of the IsWarnIfUnused flag.
+ void setIsWarnIfUnused(bool val) {
+ IsWarnIfUnused = val;
+ }
+
/// setArgumentList - Set the specified list of identifiers as the argument
/// list for this macro.
void setArgumentList(IdentifierInfo* const *List, unsigned NumArgs,
@@ -201,6 +209,11 @@ public:
return IsAllowRedefinitionsWithoutWarning;
}
+ /// \brief Return true if we should emit a warning if the macro is unused.
+ bool isWarnIfUnused() const {
+ return IsWarnIfUnused;
+ }
+
/// getNumTokens - Return the number of tokens that this macro expands to.
///
unsigned getNumTokens() const {
diff --git a/include/clang/Lex/Makefile b/include/clang/Lex/Makefile
new file mode 100644
index 0000000..9874bcf
--- /dev/null
+++ b/include/clang/Lex/Makefile
@@ -0,0 +1,13 @@
+CLANG_LEVEL := ../../..
+TD_SRC_DIR = $(PROJ_SRC_DIR)/../Basic
+BUILT_SOURCES = AttrSpellings.inc
+
+TABLEGEN_INC_FILES_COMMON = 1
+
+include $(CLANG_LEVEL)/Makefile
+
+$(ObjDir)/AttrSpellings.inc.tmp : $(TD_SRC_DIR)/Attr.td $(TBLGEN) \
+ $(ObjDir)/.dir
+ $(Echo) "Building Clang attribute spellings with tblgen"
+ $(Verb) $(TableGen) -gen-clang-attr-spelling-list -o $(call SYSPATH, $@) \
+ -I $(PROJ_SRC_DIR)/../../ $<
diff --git a/include/clang/Lex/PPCallbacks.h b/include/clang/Lex/PPCallbacks.h
index 782f2d5..b2a80a6 100644
--- a/include/clang/Lex/PPCallbacks.h
+++ b/include/clang/Lex/PPCallbacks.h
@@ -54,12 +54,43 @@ public:
SrcMgr::CharacteristicKind FileType) {
}
+ /// \brief This callback is invoked whenever an inclusion directive of
+ /// any kind (\c #include, \c #import, etc.) has been processed, regardless
+ /// of whether the inclusion will actually result in an inclusion.
+ ///
+ /// \param HashLoc The location of the '#' that starts the inclusion
+ /// directive.
+ ///
+ /// \param IncludeTok The token that indicates the kind of inclusion
+ /// directive, e.g., 'include' or 'import'.
+ ///
+ /// \param FileName The name of the file being included, as written in the
+ /// source code.
+ ///
+ /// \param IsAngled Whether the file name was enclosed in angle brackets;
+ /// otherwise, it was enclosed in quotes.
+ ///
+ /// \param File The actual file that may be included by this inclusion
+ /// directive.
+ ///
+ /// \param EndLoc The location of the last token within the inclusion
+ /// directive.
+ virtual void InclusionDirective(SourceLocation HashLoc,
+ const Token &IncludeTok,
+ llvm::StringRef FileName,
+ bool IsAngled,
+ const FileEntry *File,
+ SourceLocation EndLoc) {
+ }
+
/// EndOfMainFile - This callback is invoked when the end of the main file is
/// reach, no subsequent callbacks will be made.
virtual void EndOfMainFile() {
}
/// Ident - This callback is invoked when a #ident or #sccs directive is read.
+ /// \param Loc The location of the directive.
+ /// \param str The text of the directive.
///
virtual void Ident(SourceLocation Loc, const std::string &str) {
}
@@ -73,6 +104,8 @@ public:
/// PragmaMessage - This callback is invoked when a #pragma message directive
/// is read.
+ /// \param Loc The location of the message directive.
+ /// \param str The text of the message directive.
///
virtual void PragmaMessage(SourceLocation Loc, llvm::StringRef Str) {
}
@@ -80,17 +113,48 @@ public:
/// MacroExpands - This is called by
/// Preprocessor::HandleMacroExpandedIdentifier when a macro invocation is
/// found.
- virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
}
/// MacroDefined - This hook is called whenever a macro definition is seen.
- virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
+ virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
}
/// MacroUndefined - This hook is called whenever a macro #undef is seen.
/// MI is released immediately following this callback.
- virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
- const MacroInfo *MI) {
+ virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ }
+
+ /// If -- This hook is called whenever an #if is seen.
+ /// \param Range The SourceRange of the expression being tested.
+ // FIXME: better to pass in a list (or tree!) of Tokens.
+ virtual void If(SourceRange Range) {
+ }
+
+ /// Elif -- This hook is called whenever an #elif is seen.
+ /// \param Range The SourceRange of the expression being tested.
+ // FIXME: better to pass in a list (or tree!) of Tokens.
+ virtual void Elif(SourceRange Range) {
+ }
+
+ /// Ifdef -- This hook is called whenever an #ifdef is seen.
+ /// \param Loc The location of the token being tested.
+ /// \param II Information on the token being tested.
+ virtual void Ifdef(const Token &MacroNameTok) {
+ }
+
+ /// Ifndef -- This hook is called whenever an #ifndef is seen.
+ /// \param Loc The location of the token being tested.
+ /// \param II Information on the token being tested.
+ virtual void Ifndef(const Token &MacroNameTok) {
+ }
+
+ /// Else -- This hook is called whenever an #else is seen.
+ virtual void Else() {
+ }
+
+ /// Endif -- This hook is called whenever an #endif is seen.
+ virtual void Endif() {
}
};
@@ -119,6 +183,18 @@ public:
Second->FileSkipped(ParentFile, FilenameTok, FileType);
}
+ virtual void InclusionDirective(SourceLocation HashLoc,
+ const Token &IncludeTok,
+ llvm::StringRef FileName,
+ bool IsAngled,
+ const FileEntry *File,
+ SourceLocation EndLoc) {
+ First->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
+ EndLoc);
+ Second->InclusionDirective(HashLoc, IncludeTok, FileName, IsAngled, File,
+ EndLoc);
+ }
+
virtual void EndOfMainFile() {
First->EndOfMainFile();
Second->EndOfMainFile();
@@ -140,20 +216,55 @@ public:
Second->PragmaMessage(Loc, Str);
}
- virtual void MacroExpands(const Token &Id, const MacroInfo* MI) {
- First->MacroExpands(Id, MI);
- Second->MacroExpands(Id, MI);
+ virtual void MacroExpands(const Token &MacroNameTok, const MacroInfo* MI) {
+ First->MacroExpands(MacroNameTok, MI);
+ Second->MacroExpands(MacroNameTok, MI);
+ }
+
+ virtual void MacroDefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ First->MacroDefined(MacroNameTok, MI);
+ Second->MacroDefined(MacroNameTok, MI);
+ }
+
+ virtual void MacroUndefined(const Token &MacroNameTok, const MacroInfo *MI) {
+ First->MacroUndefined(MacroNameTok, MI);
+ Second->MacroUndefined(MacroNameTok, MI);
+ }
+
+ /// If -- This hook is called whenever an #if is seen.
+ virtual void If(SourceRange Range) {
+ First->If(Range);
+ Second->If(Range);
+ }
+
+ /// Elif -- This hook is called whenever an #if is seen.
+ virtual void Elif(SourceRange Range) {
+ First->Elif(Range);
+ Second->Elif(Range);
+ }
+
+ /// Ifdef -- This hook is called whenever an #ifdef is seen.
+ virtual void Ifdef(const Token &MacroNameTok) {
+ First->Ifdef(MacroNameTok);
+ Second->Ifdef(MacroNameTok);
+ }
+
+ /// Ifndef -- This hook is called whenever an #ifndef is seen.
+ virtual void Ifndef(const Token &MacroNameTok) {
+ First->Ifndef(MacroNameTok);
+ Second->Ifndef(MacroNameTok);
}
- virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI) {
- First->MacroDefined(II, MI);
- Second->MacroDefined(II, MI);
+ /// Else -- This hook is called whenever an #else is seen.
+ virtual void Else() {
+ First->Else();
+ Second->Else();
}
- virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
- const MacroInfo *MI) {
- First->MacroUndefined(Loc, II, MI);
- Second->MacroUndefined(Loc, II, MI);
+ /// Endif -- This hook is called whenever an #endif is seen.
+ virtual void Endif() {
+ First->Endif();
+ Second->Endif();
}
};
diff --git a/include/clang/Lex/PTHManager.h b/include/clang/Lex/PTHManager.h
index 5e8a4f1..094b7ef 100644
--- a/include/clang/Lex/PTHManager.h
+++ b/include/clang/Lex/PTHManager.h
@@ -31,7 +31,7 @@ namespace clang {
class FileEntry;
class PTHLexer;
class Diagnostic;
-class StatSysCallCache;
+class FileSystemStatCache;
class PTHManager : public IdentifierInfoLookup {
friend class PTHLexer;
@@ -128,11 +128,11 @@ public:
/// It is the responsibility of the caller to 'delete' the returned object.
PTHLexer *CreateLexer(FileID FID);
- /// createStatCache - Returns a StatSysCallCache object for use with
+ /// createStatCache - Returns a FileSystemStatCache object for use with
/// FileManager objects. These objects use the PTH data to speed up
/// calls to stat by memoizing their results from when the PTH file
/// was generated.
- StatSysCallCache *createStatCache();
+ FileSystemStatCache *createStatCache();
};
} // end namespace clang
diff --git a/include/clang/Lex/Pragma.h b/include/clang/Lex/Pragma.h
index c68555b..8bd2236 100644
--- a/include/clang/Lex/Pragma.h
+++ b/include/clang/Lex/Pragma.h
@@ -25,6 +25,28 @@ namespace clang {
class IdentifierInfo;
class PragmaNamespace;
+ /**
+ * \brief Describes how the pragma was introduced, e.g., with #pragma,
+ * _Pragma, or __pragma.
+ */
+ enum PragmaIntroducerKind {
+ /**
+ * \brief The pragma was introduced via #pragma.
+ */
+ PIK_HashPragma,
+
+ /**
+ * \brief The pragma was introduced via the C99 _Pragma(string-literal).
+ */
+ PIK__Pragma,
+
+ /**
+ * \brief The pragma was introduced via the Microsoft
+ * __pragma(token-string).
+ */
+ PIK___pragma
+ };
+
/// PragmaHandler - Instances of this interface defined to handle the various
/// pragmas that the language front-end uses. Each handler optionally has a
/// name (e.g. "pack") and the HandlePragma method is invoked when a pragma with
@@ -42,7 +64,8 @@ public:
virtual ~PragmaHandler();
llvm::StringRef getName() const { return Name; }
- virtual void HandlePragma(Preprocessor &PP, Token &FirstToken) = 0;
+ virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) = 0;
/// getIfNamespace - If this is a namespace, return it. This is equivalent to
/// using a dynamic_cast, but doesn't require RTTI.
@@ -55,7 +78,8 @@ class EmptyPragmaHandler : public PragmaHandler {
public:
EmptyPragmaHandler();
- virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+ virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken);
};
/// PragmaNamespace - This PragmaHandler subdivides the namespace of pragmas,
@@ -90,7 +114,8 @@ public:
return Handlers.empty();
}
- virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+ virtual void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken);
virtual PragmaNamespace *getIfNamespace() { return this; }
};
diff --git a/include/clang/Lex/PreprocessingRecord.h b/include/clang/Lex/PreprocessingRecord.h
index 730f04f..afd7ae1 100644
--- a/include/clang/Lex/PreprocessingRecord.h
+++ b/include/clang/Lex/PreprocessingRecord.h
@@ -35,6 +35,7 @@ void operator delete(void* ptr, clang::PreprocessingRecord& PR,
namespace clang {
class MacroDefinition;
+ class FileEntry;
/// \brief Base class that describes a preprocessed entity, which may be a
/// preprocessor directive or macro instantiation.
@@ -54,8 +55,12 @@ namespace clang {
/// \brief A macro definition.
MacroDefinitionKind,
+ /// \brief An inclusion directive, such as \c #include, \c
+ /// #import, or \c #include_next.
+ InclusionDirectiveKind,
+
FirstPreprocessingDirective = PreprocessingDirectiveKind,
- LastPreprocessingDirective = MacroDefinitionKind
+ LastPreprocessingDirective = InclusionDirectiveKind
};
private:
@@ -173,6 +178,66 @@ namespace clang {
}
static bool classof(const MacroDefinition *) { return true; }
};
+
+ /// \brief Record the location of an inclusion directive, such as an
+ /// \c #include or \c #import statement.
+ class InclusionDirective : public PreprocessingDirective {
+ public:
+ /// \brief The kind of inclusion directives known to the
+ /// preprocessor.
+ enum InclusionKind {
+ /// \brief An \c #include directive.
+ Include,
+ /// \brief An Objective-C \c #import directive.
+ Import,
+ /// \brief A GNU \c #include_next directive.
+ IncludeNext,
+ /// \brief A Clang \c #__include_macros directive.
+ IncludeMacros
+ };
+
+ private:
+ /// \brief The name of the file that was included, as written in
+ /// the source.
+ llvm::StringRef FileName;
+
+ /// \brief Whether the file name was in quotation marks; otherwise, it was
+ /// in angle brackets.
+ unsigned InQuotes : 1;
+
+ /// \brief The kind of inclusion directive we have.
+ ///
+ /// This is a value of type InclusionKind.
+ unsigned Kind : 2;
+
+ /// \brief The file that was included.
+ const FileEntry *File;
+
+ public:
+ InclusionDirective(PreprocessingRecord &PPRec,
+ InclusionKind Kind, llvm::StringRef FileName,
+ bool InQuotes, const FileEntry *File, SourceRange Range);
+
+ /// \brief Determine what kind of inclusion directive this is.
+ InclusionKind getKind() const { return static_cast<InclusionKind>(Kind); }
+
+ /// \brief Retrieve the included file name as it was written in the source.
+ llvm::StringRef getFileName() const { return FileName; }
+
+ /// \brief Determine whether the included file name was written in quotes;
+ /// otherwise, it was written in angle brackets.
+ bool wasInQuotes() const { return InQuotes; }
+
+ /// \brief Retrieve the file entry for the actual file that was included
+ /// by this directive.
+ const FileEntry *getFile() const { return File; }
+
+ // Implement isa/cast/dyncast/etc.
+ static bool classof(const PreprocessedEntity *PE) {
+ return PE->getKind() == InclusionDirectiveKind;
+ }
+ static bool classof(const InclusionDirective *) { return true; }
+ };
/// \brief An abstract class that should be subclassed by any external source
/// of preprocessing record entries.
@@ -183,6 +248,10 @@ namespace clang {
/// \brief Read any preallocated preprocessed entities from the external
/// source.
virtual void ReadPreprocessedEntities() = 0;
+
+ /// \brief Read the preprocessed entity at the given offset.
+ virtual PreprocessedEntity *
+ ReadPreprocessedEntityAtOffset(uint64_t Offset) = 0;
};
/// \brief A record of the steps taken while preprocessing a source file,
@@ -229,13 +298,22 @@ namespace clang {
iterator end(bool OnlyLocalEntities = false);
const_iterator begin(bool OnlyLocalEntities = false) const;
const_iterator end(bool OnlyLocalEntities = false) const;
-
+
/// \brief Add a new preprocessed entity to this record.
void addPreprocessedEntity(PreprocessedEntity *Entity);
/// \brief Set the external source for preprocessed entities.
void SetExternalSource(ExternalPreprocessingRecordSource &Source,
unsigned NumPreallocatedEntities);
+
+ /// \brief Retrieve the external source for preprocessed entities.
+ ExternalPreprocessingRecordSource *getExternalSource() const {
+ return ExternalSource;
+ }
+
+ unsigned getNumPreallocatedEntities() const {
+ return NumPreallocatedEntities;
+ }
/// \brief Set the preallocated entry at the given index to the given
/// preprocessed entity.
@@ -256,9 +334,14 @@ namespace clang {
MacroDefinition *findMacroDefinition(const MacroInfo *MI);
virtual void MacroExpands(const Token &Id, const MacroInfo* MI);
- virtual void MacroDefined(const IdentifierInfo *II, const MacroInfo *MI);
- virtual void MacroUndefined(SourceLocation Loc, const IdentifierInfo *II,
- const MacroInfo *MI);
+ virtual void MacroDefined(const Token &Id, const MacroInfo *MI);
+ virtual void MacroUndefined(const Token &Id, const MacroInfo *MI);
+ virtual void InclusionDirective(SourceLocation HashLoc,
+ const Token &IncludeTok,
+ llvm::StringRef FileName,
+ bool IsAngled,
+ const FileEntry *File,
+ SourceLocation EndLoc);
};
} // end namespace clang
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 6b9b89e..018f7e9 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_LEX_PREPROCESSOR_H
#define LLVM_CLANG_LEX_PREPROCESSOR_H
+#include "clang/Lex/MacroInfo.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/PTHLexer.h"
#include "clang/Lex/PPCallbacks.h"
@@ -24,6 +25,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
@@ -82,6 +84,7 @@ class Preprocessor {
IdentifierInfo *Ident__VA_ARGS__; // __VA_ARGS__
IdentifierInfo *Ident__has_feature; // __has_feature
IdentifierInfo *Ident__has_builtin; // __has_builtin
+ IdentifierInfo *Ident__has_attribute; // __has_attribute
IdentifierInfo *Ident__has_include; // __has_include
IdentifierInfo *Ident__has_include_next; // __has_include_next
@@ -194,10 +197,15 @@ class Preprocessor {
/// to the actual definition of the macro.
llvm::DenseMap<IdentifierInfo*, MacroInfo*> Macros;
- /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
- /// allocation.
- /// FIXME: why not use a singly linked list?
- std::vector<MacroInfo*> MICache;
+ /// \brief Macros that we want to warn because they are not used at the end
+ /// of the translation unit; we store just their SourceLocations instead
+ /// something like MacroInfo*. The benefit of this is that when we are
+ /// deserializing from PCH, we don't need to deserialize identifier & macros
+ /// just so that we can report that they are unused, we just warn using
+ /// the SourceLocations of this set (that will be filled by the ASTReader).
+ /// We are using SmallPtrSet instead of a vector for faster removal.
+ typedef llvm::SmallPtrSet<SourceLocation, 32> WarnUnusedMacroLocsTy;
+ WarnUnusedMacroLocsTy WarnUnusedMacroLocs;
/// MacroArgCache - This is a "freelist" of MacroArg objects that can be
/// reused for quick allocation.
@@ -251,6 +259,22 @@ private: // Cached tokens state.
/// invoked (at which point the last position is popped).
std::vector<CachedTokensTy::size_type> BacktrackPositions;
+ struct MacroInfoChain {
+ MacroInfo MI;
+ MacroInfoChain *Next;
+ MacroInfoChain *Prev;
+ };
+
+ /// MacroInfos are managed as a chain for easy disposal. This is the head
+ /// of that list.
+ MacroInfoChain *MIChainHead;
+
+ /// MICache - A "freelist" of MacroInfo objects that can be reused for quick
+ /// allocation.
+ MacroInfoChain *MICache;
+
+ MacroInfo *getInfoForMacro(IdentifierInfo *II) const;
+
public:
Preprocessor(Diagnostic &diags, const LangOptions &opts,
const TargetInfo &target,
@@ -324,7 +348,10 @@ public:
/// getMacroInfo - Given an identifier, return the MacroInfo it is #defined to
/// or null if it isn't #define'd.
MacroInfo *getMacroInfo(IdentifierInfo *II) const {
- return II->hasMacroDefinition() ? Macros.find(II)->second : 0;
+ if (!II->hasMacroDefinition())
+ return 0;
+
+ return getInfoForMacro(II);
}
/// setMacroInfo - Specify a macro for this identifier.
@@ -591,6 +618,9 @@ public:
/// for which we are performing code completion.
bool isCodeCompletionFile(SourceLocation FileLoc) const;
+ /// \brief Determine if we are performing code completion.
+ bool isCodeCompletionEnabled() const { return CodeCompletionFile != 0; }
+
/// \brief Instruct the preprocessor to skip part of the main
/// the main source file.
///
@@ -607,12 +637,11 @@ public:
/// the specified Token's location, translating the token's start
/// position in the current buffer into a SourcePosition object for rendering.
DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID) {
- return Diags->Report(FullSourceLoc(Loc, getSourceManager()), DiagID);
+ return Diags->Report(Loc, DiagID);
}
DiagnosticBuilder Diag(const Token &Tok, unsigned DiagID) {
- return Diags->Report(FullSourceLoc(Tok.getLocation(), getSourceManager()),
- DiagID);
+ return Diags->Report(Tok.getLocation(), DiagID);
}
/// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
@@ -622,17 +651,9 @@ public:
/// UCNs, etc.
///
/// \param Invalid If non-NULL, will be set \c true if an error occurs.
- std::string getSpelling(const Token &Tok, bool *Invalid = 0) const;
-
- /// getSpelling() - Return the 'spelling' of the Tok token. The spelling of a
- /// token is the characters used to represent the token in the source file
- /// after trigraph expansion and escaped-newline folding. In particular, this
- /// wants to get the true, uncanonicalized, spelling of things like digraphs
- /// UCNs, etc.
- static std::string getSpelling(const Token &Tok,
- const SourceManager &SourceMgr,
- const LangOptions &Features,
- bool *Invalid = 0);
+ std::string getSpelling(const Token &Tok, bool *Invalid = 0) const {
+ return Lexer::getSpelling(Tok, SourceMgr, Features, Invalid);
+ }
/// getSpelling - This method is used to get the spelling of a token into a
/// preallocated buffer, instead of as an std::string. The caller is required
@@ -645,7 +666,9 @@ public:
/// copy). The caller is not allowed to modify the returned buffer pointer
/// if an internal buffer is returned.
unsigned getSpelling(const Token &Tok, const char *&Buffer,
- bool *Invalid = 0) const;
+ bool *Invalid = 0) const {
+ return Lexer::getSpelling(Tok, Buffer, SourceMgr, Features, Invalid);
+ }
/// getSpelling - This method is used to get the spelling of a token into a
/// SmallVector. Note that the returned StringRef may not point to the
@@ -692,7 +715,9 @@ public:
/// location should refer to. The default offset (0) produces a source
/// location pointing just past the end of the token; an offset of 1 produces
/// a source location pointing to the last character in the token, etc.
- SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0);
+ SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset = 0) {
+ return Lexer::getLocForEndOfToken(Loc, Offset, SourceMgr, Features);
+ }
/// DumpToken - Print the token to stderr, used for debugging.
///
@@ -702,7 +727,10 @@ public:
/// AdvanceToTokenCharacter - Given a location that specifies the start of a
/// token, return a new location that specifies a character within the token.
- SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,unsigned Char);
+ SourceLocation AdvanceToTokenCharacter(SourceLocation TokStart,
+ unsigned Char) const {
+ return Lexer::AdvanceToTokenCharacter(TokStart, Char, SourceMgr, Features);
+ }
/// IncrementPasteCounter - Increment the counters for the number of token
/// paste operations performed. If fast was specified, this is a 'fast paste'
@@ -726,10 +754,10 @@ public:
// Preprocessor callback methods. These are invoked by a lexer as various
// directives and events are found.
- /// LookUpIdentifierInfo - Given a tok::identifier token, look up the
- /// identifier information for the token and install it into the token.
- IdentifierInfo *LookUpIdentifierInfo(Token &Identifier,
- const char *BufPtr = 0) const;
+ /// LookUpIdentifierInfo - Given a tok::raw_identifier token, look up the
+ /// identifier information for the token and install it into the token,
+ /// updating the token kind accordingly.
+ IdentifierInfo *LookUpIdentifierInfo(Token &Identifier) const;
/// HandleIdentifier - This callback is invoked when the lexer reads an
/// identifier and has filled in the tokens IdentifierInfo member. This
@@ -812,7 +840,12 @@ public:
/// This code concatenates and consumes tokens up to the '>' token. It
/// returns false if the > was found, otherwise it returns true if it finds
/// and consumes the EOM marker.
- bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer);
+ bool ConcatenateIncludeName(llvm::SmallString<128> &FilenameBuffer,
+ SourceLocation &End);
+
+ /// LexOnOffSwitch - Lex an on-off-switch (C99 6.10.6p2) and verify that it is
+ /// followed by EOM. Return true if the token is not a valid on-off-switch.
+ bool LexOnOffSwitch(tok::OnOffSwitch &OOS);
private:
@@ -909,8 +942,8 @@ private:
/// is not enclosed within a string literal.
void HandleMicrosoft__pragma(Token &Tok);
- void Handle_Pragma(const std::string &StrVal, SourceLocation PragmaLoc,
- SourceLocation RParenLoc);
+ void Handle_Pragma(unsigned Introducer, const std::string &StrVal,
+ SourceLocation PragmaLoc, SourceLocation RParenLoc);
/// EnterSourceFileWithLexer - Add a lexer to the top of the include stack and
/// start lexing tokens from it instead of the current buffer.
@@ -961,12 +994,13 @@ private:
void HandleIdentSCCSDirective(Token &Tok);
// File inclusion.
- void HandleIncludeDirective(Token &Tok,
+ void HandleIncludeDirective(SourceLocation HashLoc,
+ Token &Tok,
const DirectoryLookup *LookupFrom = 0,
bool isImport = false);
- void HandleIncludeNextDirective(Token &Tok);
- void HandleIncludeMacrosDirective(Token &Tok);
- void HandleImportDirective(Token &Tok);
+ void HandleIncludeNextDirective(SourceLocation HashLoc, Token &Tok);
+ void HandleIncludeMacrosDirective(SourceLocation HashLoc, Token &Tok);
+ void HandleImportDirective(SourceLocation HashLoc, Token &Tok);
// Macro handling.
void HandleDefineDirective(Token &Tok);
@@ -981,7 +1015,7 @@ private:
void HandleElifDirective(Token &Tok);
// Pragmas.
- void HandlePragmaDirective();
+ void HandlePragmaDirective(unsigned Introducer);
public:
void HandlePragmaOnce(Token &OnceTok);
void HandlePragmaMark();
@@ -997,6 +1031,10 @@ public:
// Return true and store the first token only if any CommentHandler
// has inserted some tokens and getCommentRetentionState() is false.
bool HandleComment(Token &Token, SourceRange Comment);
+
+ /// \brief A macro is used, update information about macros that need unused
+ /// warnings.
+ void markMacroAsUsed(MacroInfo *MI);
};
/// \brief Abstract base class that describes a handler that will receive
diff --git a/include/clang/Lex/PreprocessorLexer.h b/include/clang/Lex/PreprocessorLexer.h
index 477a213..d833293 100644
--- a/include/clang/Lex/PreprocessorLexer.h
+++ b/include/clang/Lex/PreprocessorLexer.h
@@ -155,6 +155,18 @@ public:
/// getFileEntry - Return the FileEntry corresponding to this FileID. Like
/// getFileID(), this only works for lexers with attached preprocessors.
const FileEntry *getFileEntry() const;
+
+ /// \brief Iterator that traverses the current stack of preprocessor
+ /// conditional directives (#if/#ifdef/#ifndef).
+ typedef llvm::SmallVectorImpl<PPConditionalInfo>::const_iterator
+ conditional_iterator;
+
+ conditional_iterator conditional_begin() const {
+ return ConditionalStack.begin();
+ }
+ conditional_iterator conditional_end() const {
+ return ConditionalStack.end();
+ }
};
} // end namespace clang
diff --git a/include/clang/Lex/Token.h b/include/clang/Lex/Token.h
index 954b36e..edcfcc10d 100644
--- a/include/clang/Lex/Token.h
+++ b/include/clang/Lex/Token.h
@@ -76,7 +76,8 @@ public:
StartOfLine = 0x01, // At start of line or only after whitespace.
LeadingSpace = 0x02, // Whitespace exists before this token.
DisableExpand = 0x04, // This identifier may never be macro expanded.
- NeedsCleaning = 0x08 // Contained an escaped newline or trigraph.
+ NeedsCleaning = 0x08, // Contained an escaped newline or trigraph.
+ LeadingEmptyMacro = 0x10 // Empty macro exists before this token.
};
tok::TokenKind getKind() const { return (tok::TokenKind)Kind; }
@@ -87,6 +88,12 @@ public:
bool is(tok::TokenKind K) const { return Kind == (unsigned) K; }
bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; }
+ /// isAnyIdentifier - Return true if this is a raw identifier (when lexing
+ /// in raw mode) or a non-keyword identifier (when lexing in non-raw mode).
+ bool isAnyIdentifier() const {
+ return is(tok::identifier) || is(tok::raw_identifier);
+ }
+
/// isLiteral - Return true if this is a "literal", like a numeric
/// constant, string, etc.
bool isLiteral() const {
@@ -96,9 +103,11 @@ public:
}
bool isAnnotation() const {
- return is(tok::annot_typename) ||
- is(tok::annot_cxxscope) ||
- is(tok::annot_template_id);
+#define ANNOTATION(NAME) \
+ if (is(tok::annot_##NAME)) \
+ return true;
+#include "clang/Basic/TokenKinds.def"
+ return false;
}
/// getLocation - Return a source location identifier for the specified
@@ -153,7 +162,10 @@ public:
}
IdentifierInfo *getIdentifierInfo() const {
- assert(!isAnnotation() && "Used IdentInfo on annotation token!");
+ assert(isNot(tok::raw_identifier) &&
+ "getIdentifierInfo() on a tok::raw_identifier token!");
+ assert(!isAnnotation() &&
+ "getIdentifierInfo() on an annotation token!");
if (isLiteral()) return 0;
return (IdentifierInfo*) PtrData;
}
@@ -161,6 +173,18 @@ public:
PtrData = (void*) II;
}
+ /// getRawIdentifierData - For a raw identifier token (i.e., an identifier
+ /// lexed in raw mode), returns a pointer to the start of it in the text
+ /// buffer if known, null otherwise.
+ const char *getRawIdentifierData() const {
+ assert(is(tok::raw_identifier));
+ return reinterpret_cast<const char*>(PtrData);
+ }
+ void setRawIdentifierData(const char *Ptr) {
+ assert(is(tok::raw_identifier));
+ PtrData = const_cast<char*>(Ptr);
+ }
+
/// getLiteralData - For a literal token (numeric constant, string, etc), this
/// returns a pointer to the start of it in the text buffer if known, null
/// otherwise.
@@ -231,7 +255,13 @@ public:
/// newlines in it.
///
bool needsCleaning() const { return (Flags & NeedsCleaning) ? true : false; }
-
+
+ /// \brief Return true if this token has an empty macro before it.
+ ///
+ bool hasLeadingEmptyMacro() const {
+ return (Flags & LeadingEmptyMacro) ? true : false;
+ }
+
};
/// PPConditionalInfo - Information about the conditional stack (#if directives)
OpenPOWER on IntegriCloud