clang  6.0.0svn
MacroPPCallbacks.cpp
Go to the documentation of this file.
1 //===--- MacroPPCallbacks.cpp ---------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains implementation for the macro preprocessors callbacks.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "MacroPPCallbacks.h"
15 #include "CGDebugInfo.h"
17 #include "clang/Parse/Parser.h"
18 
19 using namespace clang;
20 
21 void MacroPPCallbacks::writeMacroDefinition(const IdentifierInfo &II,
22  const MacroInfo &MI,
23  Preprocessor &PP, raw_ostream &Name,
24  raw_ostream &Value) {
25  Name << II.getName();
26 
27  if (MI.isFunctionLike()) {
28  Name << '(';
29  if (!MI.param_empty()) {
31  for (; AI + 1 != E; ++AI) {
32  Name << (*AI)->getName();
33  Name << ',';
34  }
35 
36  // Last argument.
37  if ((*AI)->getName() == "__VA_ARGS__")
38  Name << "...";
39  else
40  Name << (*AI)->getName();
41  }
42 
43  if (MI.isGNUVarargs())
44  // #define foo(x...)
45  Name << "...";
46 
47  Name << ')';
48  }
49 
50  SmallString<128> SpellingBuffer;
51  bool First = true;
52  for (const auto &T : MI.tokens()) {
53  if (!First && T.hasLeadingSpace())
54  Value << ' ';
55 
56  Value << PP.getSpelling(T, SpellingBuffer);
57  First = false;
58  }
59 }
60 
62  : Gen(Gen), PP(PP), Status(NoScope) {}
63 
64 // This is the expected flow of enter/exit compiler and user files:
65 // - Main File Enter
66 // - <built-in> file enter
67 // {Compiler macro definitions} - (Line=0, no scope)
68 // - (Optional) <command line> file enter
69 // {Command line macro definitions} - (Line=0, no scope)
70 // - (Optional) <command line> file exit
71 // {Command line file includes} - (Line=0, Main file scope)
72 // {macro definitions and file includes} - (Line!=0, Parent scope)
73 // - <built-in> file exit
74 // {User code macro definitions and file includes} - (Line!=0, Parent scope)
75 
76 llvm::DIMacroFile *MacroPPCallbacks::getCurrentScope() {
77  if (Status == MainFileScope || Status == CommandLineIncludeScope)
78  return Scopes.back();
79  return nullptr;
80 }
81 
82 SourceLocation MacroPPCallbacks::getCorrectLocation(SourceLocation Loc) {
83  if (Status == MainFileScope || EnteredCommandLineIncludeFiles)
84  return Loc;
85 
86  // While parsing skipped files, location of macros is invalid.
87  // Invalid location represents line zero.
88  return SourceLocation();
89 }
90 
92  StringRef Filename(SM.getPresumedLoc(Loc).getFilename());
93  return Filename.equals("<built-in>");
94 }
95 
97  StringRef Filename(SM.getPresumedLoc(Loc).getFilename());
98  return Filename.equals("<command line>");
99 }
100 
101 void MacroPPCallbacks::updateStatusToNextScope() {
102  switch (Status) {
103  case NoScope:
104  Status = InitializedScope;
105  break;
106  case InitializedScope:
107  Status = BuiltinScope;
108  break;
109  case BuiltinScope:
110  Status = CommandLineIncludeScope;
111  break;
112  case CommandLineIncludeScope:
113  Status = MainFileScope;
114  break;
115  case MainFileScope:
116  llvm_unreachable("There is no next scope, already in the final scope");
117  }
118 }
119 
120 void MacroPPCallbacks::FileEntered(SourceLocation Loc) {
121  SourceLocation LineLoc = getCorrectLocation(LastHashLoc);
122  switch (Status) {
123  case NoScope:
124  updateStatusToNextScope();
125  break;
126  case InitializedScope:
127  updateStatusToNextScope();
128  return;
129  case BuiltinScope:
130  if (isCommandLineFile(PP.getSourceManager(), Loc))
131  return;
132  updateStatusToNextScope();
133  LLVM_FALLTHROUGH;
134  case CommandLineIncludeScope:
135  EnteredCommandLineIncludeFiles++;
136  break;
137  case MainFileScope:
138  break;
139  }
140 
141  Scopes.push_back(Gen->getCGDebugInfo()->CreateTempMacroFile(getCurrentScope(),
142  LineLoc, Loc));
143 }
144 
145 void MacroPPCallbacks::FileExited(SourceLocation Loc) {
146  switch (Status) {
147  default:
148  llvm_unreachable("Do not expect to exit a file from current scope");
149  case BuiltinScope:
150  if (!isBuiltinFile(PP.getSourceManager(), Loc))
151  // Skip next scope and change status to MainFileScope.
152  Status = MainFileScope;
153  return;
154  case CommandLineIncludeScope:
155  if (!EnteredCommandLineIncludeFiles) {
156  updateStatusToNextScope();
157  return;
158  }
159  EnteredCommandLineIncludeFiles--;
160  break;
161  case MainFileScope:
162  break;
163  }
164 
165  Scopes.pop_back();
166 }
167 
170  FileID PrevFID) {
171  // Only care about enter file or exit file changes.
172  if (Reason == EnterFile)
173  FileEntered(Loc);
174  else if (Reason == ExitFile)
175  FileExited(Loc);
176 }
177 
179  SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName,
180  bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File,
181  StringRef SearchPath, StringRef RelativePath, const Module *Imported) {
182 
183  // Record the line location of the current included file.
184  LastHashLoc = HashLoc;
185 }
186 
187 void MacroPPCallbacks::MacroDefined(const Token &MacroNameTok,
188  const MacroDirective *MD) {
189  IdentifierInfo *Id = MacroNameTok.getIdentifierInfo();
190  SourceLocation location = getCorrectLocation(MacroNameTok.getLocation());
191  std::string NameBuffer, ValueBuffer;
192  llvm::raw_string_ostream Name(NameBuffer);
193  llvm::raw_string_ostream Value(ValueBuffer);
194  writeMacroDefinition(*Id, *MD->getMacroInfo(), PP, Name, Value);
195  Gen->getCGDebugInfo()->CreateMacro(getCurrentScope(),
196  llvm::dwarf::DW_MACINFO_define, location,
197  Name.str(), Value.str());
198 }
199 
200 void MacroPPCallbacks::MacroUndefined(const Token &MacroNameTok,
201  const MacroDefinition &MD,
202  const MacroDirective *Undef) {
203  IdentifierInfo *Id = MacroNameTok.getIdentifierInfo();
204  SourceLocation location = getCorrectLocation(MacroNameTok.getLocation());
205  Gen->getCGDebugInfo()->CreateMacro(getCurrentScope(),
206  llvm::dwarf::DW_MACINFO_undef, location,
207  Id->getName(), "");
208 }
param_iterator param_begin() const
Definition: MacroInfo.h:181
A description of the current definition of a macro.
Definition: MacroInfo.h:564
static bool isCommandLineFile(SourceManager &SM, SourceLocation Loc)
CharacteristicKind
Indicates whether a file or directory holds normal user code, system code, or system code which is im...
Definition: SourceManager.h:78
static bool isBuiltinFile(SourceManager &SM, SourceLocation Loc)
One of these records is kept for each identifier that is lexed.
Token - This structure provides full information about a lexed token.
Definition: Token.h:35
llvm::DIMacro * CreateMacro(llvm::DIMacroFile *Parent, unsigned MType, SourceLocation LineLoc, StringRef Name, StringRef Value)
Create debug info for a macro defined by a #define directive or a macro undefined by a #undef directi...
Describes a module or submodule.
Definition: Module.h:65
param_iterator param_end() const
Definition: MacroInfo.h:182
StringRef getSpelling(SourceLocation loc, SmallVectorImpl< char > &buffer, bool *invalid=nullptr) const
Return the &#39;spelling&#39; of the token at the given location; does not go up to the spelling location or ...
void InclusionDirective(SourceLocation HashLoc, const Token &IncludeTok, StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, const Module *Imported) override
Callback invoked whenever a directive (#xxx) is processed.
The primary public interface to the Clang code generator.
Definition: ModuleBuilder.h:44
IdentifierInfo *const * param_iterator
Parameters - The list of parameters for a function-like macro.
Definition: MacroInfo.h:179
void FileChanged(SourceLocation Loc, FileChangeReason Reason, SrcMgr::CharacteristicKind FileType, FileID PrevFID=FileID()) override
Callback invoked whenever a source file is entered or exited.
StringRef Filename
Definition: Format.cpp:1345
Represents a character-granular source range.
int Id
Definition: ASTDiff.cpp:191
const FunctionProtoType * T
llvm::DIMacroFile * CreateTempMacroFile(llvm::DIMacroFile *Parent, SourceLocation LineLoc, SourceLocation FileLoc)
Create debug info for a file referenced by an #include directive.
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file. ...
Definition: Token.h:124
const SourceManager & SM
Definition: Format.cpp:1337
SourceManager & getSourceManager() const
Definition: Preprocessor.h:819
const char * getFilename() const
Return the presumed filename of this location.
Encapsulates changes to the "macros namespace" (the location where the macro name became active...
Definition: MacroInfo.h:291
Encodes a location in the source.
IdentifierInfo * getIdentifierInfo() const
Definition: Token.h:177
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
const MacroInfo * getMacroInfo() const
Definition: MacroInfo.h:391
bool param_empty() const
Definition: MacroInfo.h:180
void MacroUndefined(const Token &MacroNameTok, const MacroDefinition &MD, const MacroDirective *Undef) override
Hook called whenever a macro #undef is seen.
StringRef getName() const
Return the actual identifier string.
An opaque identifier used by SourceManager which refers to a source file (MemoryBuffer) along with it...
Dataflow Directional Tag Classes.
bool isFunctionLike() const
Definition: MacroInfo.h:200
PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const
Returns the "presumed" location of a SourceLocation specifies.
Encapsulates the data about a macro definition (e.g.
Definition: MacroInfo.h:40
void MacroDefined(const Token &MacroNameTok, const MacroDirective *MD) override
Hook called whenever a macro definition is seen.
ArrayRef< Token > tokens() const
Definition: MacroInfo.h:246
bool isGNUVarargs() const
Definition: MacroInfo.h:207
MacroPPCallbacks(CodeGenerator *Gen, Preprocessor &PP)
CodeGen::CGDebugInfo * getCGDebugInfo()
Return debug info code generator.
This class handles loading and caching of source files into memory.
Engages in a tight little dance with the lexer to efficiently preprocess tokens.
Definition: Preprocessor.h:127