From 0251b266312d5cf24a788731e9fa1cfde5ce4f67 Mon Sep 17 00:00:00 2001 From: Peter Goodman Date: Mon, 19 Aug 2024 13:20:26 -0400 Subject: [PATCH] Mark two more methods as nullable. Add IsBuiltin and IsCommandLine to DefineMacroDirective. --- bin/BootstrapTypes/Globals.cpp | 8 ++++++++ bindings/python/src/Macro.cpp | 2 ++ include/pasta/AST/Decl.h | 4 ++-- include/pasta/AST/Macro.h | 7 +++++++ lib/AST/Decl.cpp | 10 ++++++++-- lib/AST/Macro.cpp | 31 +++++++++++++++++++++++++++++ lib/AST/Macro.h | 3 +++ lib/Compile/PatchedMacroTracker.cpp | 17 ++++++++++++++++ lib/Compile/PatchedMacroTracker.h | 1 + 9 files changed, 79 insertions(+), 4 deletions(-) diff --git a/bin/BootstrapTypes/Globals.cpp b/bin/BootstrapTypes/Globals.cpp index 0fd2ab94..d2b5f919 100644 --- a/bin/BootstrapTypes/Globals.cpp +++ b/bin/BootstrapTypes/Globals.cpp @@ -1712,6 +1712,14 @@ std::map, std::string> kConditionalNullptr{ {{"CXXRecordDecl", "NeedsOverloadResolutionForDestructor"}, SELF_IS_DEFINITION}, {{"CXXRecordDecl", "NeedsOverloadResolutionForMoveAssignment"}, SELF_IS_DEFINITION}, {{"CXXRecordDecl", "NeedsOverloadResolutionForMoveConstructor"}, SELF_IS_DEFINITION}, + {{"CXXRecordDecl", "DeviceLambdaManglingNumber"}, + " if (!self.isLambda()) {\n" + " return std::nullopt;\n" + " }\n"}, + {{"CXXRecordDecl", "LambdaIndexInContext"}, + " if (!self.isLambda()) {\n" + " return std::nullopt;\n" + " }\n"}, {{"NamedDecl", "ObjCFStringFormattingFamily"}, " if (!self.getIdentifier()) {\n" diff --git a/bindings/python/src/Macro.cpp b/bindings/python/src/Macro.cpp index 45c9e27e..226ace66 100644 --- a/bindings/python/src/Macro.cpp +++ b/bindings/python/src/Macro.cpp @@ -118,6 +118,8 @@ PASTA_FOR_EACH_MACRO_IMPL(PASTA_IGNORE, .def_prop_ro("num_explicit_parameters", &DefineMacroDirective::NumExplicitParameters) .def_prop_ro("is_variadic", &DefineMacroDirective::IsVariadic) .def_prop_ro("is_function_like", &DefineMacroDirective::IsFunctionLike) + .def_prop_ro("is_builtin", &DefineMacroDirective::IsBuiltin) + .def_prop_ro("is_command_linw", &DefineMacroDirective::IsCommandLine) .def_prop_ro("parameters", &DefineMacroDirective::Parameters); nb::class_(m, "MacroArgument") diff --git a/include/pasta/AST/Decl.h b/include/pasta/AST/Decl.h index d0f5b714..dbccd05a 100644 --- a/include/pasta/AST/Decl.h +++ b/include/pasta/AST/Decl.h @@ -2996,7 +2996,7 @@ class CXXRecordDecl : public RecordDecl { std::optional<::pasta::FunctionTemplateDecl> DependentLambdaCallOperator(void) const; std::optional<::pasta::ClassTemplateDecl> DescribedClassTemplate(void) const; std::optional<::pasta::CXXDestructorDecl> Destructor(void) const; - uint32_t DeviceLambdaManglingNumber(void) const; + std::optional DeviceLambdaManglingNumber(void) const; std::optional<::pasta::TemplateParameterList> GenericLambdaTemplateParameterList(void) const; std::optional<::pasta::CXXRecordDecl> InstantiatedFromMemberClass(void) const; std::optional<::pasta::CXXMethodDecl> LambdaCallOperator(void) const; @@ -3004,7 +3004,7 @@ class CXXRecordDecl : public RecordDecl { std::optional<::pasta::Decl> LambdaContextDeclaration(void) const; uint32_t LambdaDependencyKind(void) const; std::optional> LambdaExplicitTemplateParameters(void) const; - uint32_t LambdaIndexInContext(void) const; + std::optional LambdaIndexInContext(void) const; std::optional LambdaManglingNumber(void) const; // LambdaNumbering: (clang::CXXRecordDecl::LambdaNumbering) std::optional<::pasta::CXXMethodDecl> LambdaStaticInvoker(void) const; diff --git a/include/pasta/AST/Macro.h b/include/pasta/AST/Macro.h index 63337b8c..e1b01229 100644 --- a/include/pasta/AST/Macro.h +++ b/include/pasta/AST/Macro.h @@ -381,6 +381,13 @@ class DefineMacroDirective final : public MacroDirective { // arguments when used. bool IsFunctionLike(void) const noexcept; + // Is this a builtin macro? Builtin macros are defined in the compiler macro + // preamble. + bool IsBuiltin(void) const noexcept; + + // Is this defined at the command-line? + bool IsCommandLine(void) const noexcept; + // Parameters of this macro definition. MacroRange Parameters(void) const noexcept; }; diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 8c51874f..f887f8b9 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -8754,8 +8754,11 @@ std::optional<::pasta::CXXDestructorDecl> CXXRecordDecl::Destructor(void) const } } -uint32_t CXXRecordDecl::DeviceLambdaManglingNumber(void) const { +std::optional CXXRecordDecl::DeviceLambdaManglingNumber(void) const { auto &self = *const_cast(u.CXXRecordDecl); + if (!self.isLambda()) { + return std::nullopt; + } decltype(auto) val = self.getDeviceLambdaManglingNumber(); return val; } @@ -8841,8 +8844,11 @@ std::optional> CXXRecordDecl::LambdaExplicitTemp return ret; } -uint32_t CXXRecordDecl::LambdaIndexInContext(void) const { +std::optional CXXRecordDecl::LambdaIndexInContext(void) const { auto &self = *const_cast(u.CXXRecordDecl); + if (!self.isLambda()) { + return std::nullopt; + } decltype(auto) val = self.getLambdaIndexInContext(); return val; } diff --git a/lib/AST/Macro.cpp b/lib/AST/Macro.cpp index 1d3e3113..6717fc1b 100644 --- a/lib/AST/Macro.cpp +++ b/lib/AST/Macro.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #pragma GCC diagnostic pop @@ -897,6 +898,36 @@ bool DefineMacroDirective::IsFunctionLike(void) const noexcept { return 0u; } +// Is this a builtin macro? Builtin macros are defined in the compiler macro +// preamble. +bool DefineMacroDirective::IsBuiltin(void) const noexcept { + Node node = *reinterpret_cast(impl); + MacroNodeImpl *node_impl = std::get(node); + MacroDirectiveImpl *dir_impl = dynamic_cast(node_impl); + if (!dir_impl->defined_macro) { + assert(false); + return false; + } + + if (dir_impl->is_command_line) { + return false; + } + + const auto &ci = *ast->ci.get(); + const auto &sm = ci.getSourceManager(); + auto file_id = ast->orig_source_pp->getPredefinesFileID(); + auto def_loc = dir_impl->defined_macro->getDefinitionLoc(); + return file_id == sm.getDecomposedLoc(def_loc).first; +} + +// Is this defined at the command-line? +bool DefineMacroDirective::IsCommandLine(void) const noexcept { + Node node = *reinterpret_cast(impl); + MacroNodeImpl *node_impl = std::get(node); + MacroDirectiveImpl *dir_impl = dynamic_cast(node_impl); + return dir_impl->is_command_line; +} + // Does this definition accept a variable number of arguments? bool DefineMacroDirective::IsVariadic(void) const noexcept { Node node = *reinterpret_cast(impl); diff --git a/lib/AST/Macro.h b/lib/AST/Macro.h index 1e71e8b7..32762a1a 100644 --- a/lib/AST/Macro.h +++ b/lib/AST/Macro.h @@ -136,6 +136,9 @@ class MacroDirectiveImpl final : public MacroNodeImpl { // missing tokens when we come accross an EOD. bool collected_missing_tokens_on_eod{false}; + // Is this macro defined on the command-line? + bool is_command_line{false}; + // Return the offset of the marker token. DerivedTokenIndex marker_token_offset{~0u}; }; diff --git a/lib/Compile/PatchedMacroTracker.cpp b/lib/Compile/PatchedMacroTracker.cpp index 21302bae..51562b81 100644 --- a/lib/Compile/PatchedMacroTracker.cpp +++ b/lib/Compile/PatchedMacroTracker.cpp @@ -1052,6 +1052,7 @@ void PatchedMacroTracker::DoBeginDirective( ast->marker_offset_to_macro.emplace( ast->parsed_tokens.last_expansion_begin_offset.value(), directive); + directive->is_command_line = in_command_line; directive->parsed_begin_index = ast->parsed_tokens.last_expansion_begin_offset.value(); } @@ -2816,6 +2817,22 @@ void PatchedMacroTracker::FileChanged( clang::SourceLocation loc, clang::PPCallbacks::FileChangeReason reason, clang::SrcMgr::CharacteristicKind file_type, clang::FileID file_id) { + // Clang has a really annoying way of managing command-line defined macros. + // Instead of associated a specific `FileID` with them, it shoves them in + // as an implicit include into the predefines file ID using file change + // directives. + if (reason == clang::PPCallbacks::EnterFile) { + if (auto user_loc = sm.getPresumedLoc(loc); user_loc.isValid()) { + if (user_loc.getFilename() == llvm::StringRef("")) { + assert(!in_command_line); + in_command_line = true; + } + } + + } else if (reason == clang::PPCallbacks::ExitFile && in_command_line) { + in_command_line = false; + } + // Save off the Clang's current state of the `__COUNTER__` macro back to // be associated with the last `__COUNTER__` value associated with that // file hash. diff --git a/lib/Compile/PatchedMacroTracker.h b/lib/Compile/PatchedMacroTracker.h index a4bf2732..48cb4136 100644 --- a/lib/Compile/PatchedMacroTracker.h +++ b/lib/Compile/PatchedMacroTracker.h @@ -80,6 +80,7 @@ class PatchedMacroTracker : public clang::PPCallbacks { std::vector tok_data_vec; size_t next_tok_data{0}; + bool in_command_line{false}; std::vector popped_nodes;