clang 8.0.0

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