Author: Balázs Benics Date: 2025-12-17T10:14:27Z New Revision: 6bc779506107d3a2f3cbf266621fc19649f593c5
URL: https://github.com/llvm/llvm-project/commit/6bc779506107d3a2f3cbf266621fc19649f593c5 DIFF: https://github.com/llvm/llvm-project/commit/6bc779506107d3a2f3cbf266621fc19649f593c5.diff LOG: Reapply "[clang][analyzer] Format macro expansions" (#172479) This reverts commit ed5589b0dcec40e25675812a330e171ed0587644. We missed a link dependency so we had to revert this change. Now that is fixed, let's see if this one sticks. Added: Modified: clang/include/clang/Analysis/MacroExpansionContext.h clang/lib/Analysis/CMakeLists.txt clang/lib/Analysis/MacroExpansionContext.cpp clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp clang/test/Analysis/plist-macros-with-expansion-ctu.c clang/test/Analysis/plist-macros-with-expansion.c clang/test/Analysis/plist-macros-with-expansion.cpp clang/unittests/Analysis/MacroExpansionContextTest.cpp Removed: ################################################################################ diff --git a/clang/include/clang/Analysis/MacroExpansionContext.h b/clang/include/clang/Analysis/MacroExpansionContext.h index 2a27aba76656d..b2ef4fffe5e44 100644 --- a/clang/include/clang/Analysis/MacroExpansionContext.h +++ b/clang/include/clang/Analysis/MacroExpansionContext.h @@ -96,6 +96,13 @@ class MacroExpansionContext { std::optional<StringRef> getOriginalText(SourceLocation MacroExpansionLoc) const; + /// \param MacroExpansionLoc Must be the expansion location of a macro. + /// \return A formatted representation of the textual representation of the + /// token sequence which was substituted in place of the macro. + /// If no macro was expanded at that location, returns std::nullopt. + std::optional<StringRef> + getFormattedExpandedText(SourceLocation MacroExpansionLoc) const; + LLVM_DUMP_METHOD void dumpExpansionRangesToStream(raw_ostream &OS) const; LLVM_DUMP_METHOD void dumpExpandedTextsToStream(raw_ostream &OS) const; LLVM_DUMP_METHOD void dumpExpansionRanges() const; @@ -106,6 +113,7 @@ class MacroExpansionContext { using MacroExpansionText = SmallString<40>; using ExpansionMap = llvm::DenseMap<SourceLocation, MacroExpansionText>; using ExpansionRangeMap = llvm::DenseMap<SourceLocation, SourceLocation>; + using FormattedExpansionMap = llvm::DenseMap<SourceLocation, std::string>; /// Associates the textual representation of the expanded tokens at the given /// macro expansion location. @@ -115,6 +123,9 @@ class MacroExpansionContext { /// substitution starting from a given macro expansion location. ExpansionRangeMap ExpansionRanges; + /// Caches formatted macro expansions keyed by expansion location. + mutable FormattedExpansionMap FormattedExpandedTokens; + Preprocessor *PP = nullptr; SourceManager *SM = nullptr; const LangOptions &LangOpts; diff --git a/clang/lib/Analysis/CMakeLists.txt b/clang/lib/Analysis/CMakeLists.txt index 99a2ec684e149..c41f1fd77e5b7 100644 --- a/clang/lib/Analysis/CMakeLists.txt +++ b/clang/lib/Analysis/CMakeLists.txt @@ -40,7 +40,9 @@ add_clang_library(clangAnalysis clangAST clangASTMatchers clangBasic + clangFormat clangLex + clangToolingCore DEPENDS omp_gen diff --git a/clang/lib/Analysis/MacroExpansionContext.cpp b/clang/lib/Analysis/MacroExpansionContext.cpp index b212b7f245792..10b69b0c46685 100644 --- a/clang/lib/Analysis/MacroExpansionContext.cpp +++ b/clang/lib/Analysis/MacroExpansionContext.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/MacroExpansionContext.h" +#include "clang/Format/Format.h" #include "llvm/Support/Debug.h" #include <optional> @@ -132,6 +133,35 @@ MacroExpansionContext::getOriginalText(SourceLocation MacroExpansionLoc) const { LangOpts); } +std::optional<StringRef> MacroExpansionContext::getFormattedExpandedText( + SourceLocation MacroExpansionLoc) const { + std::optional<StringRef> ExpandedText = getExpandedText(MacroExpansionLoc); + if (!ExpandedText) + return std::nullopt; + + auto [It, Inserted] = + FormattedExpandedTokens.try_emplace(MacroExpansionLoc, ""); + if (!Inserted) + return StringRef(It->getSecond()); + + clang::format::FormatStyle Style = clang::format::getLLVMStyle(); + + std::string MacroCodeBlock = ExpandedText->str(); + + std::vector<clang::tooling::Range> Ranges; + Ranges.emplace_back(0, MacroCodeBlock.length()); + + clang::tooling::Replacements Replacements = clang::format::reformat( + Style, MacroCodeBlock, Ranges, "<macro-expansion>"); + + llvm::Expected<std::string> Result = + clang::tooling::applyAllReplacements(MacroCodeBlock, Replacements); + + It->getSecond() = Result ? std::move(*Result) : std::move(MacroCodeBlock); + + return StringRef(It->getSecond()); +} + void MacroExpansionContext::dumpExpansionRanges() const { dumpExpansionRangesToStream(llvm::dbgs()); } diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp index 3e3fff900cde8..4ea6208d549c3 100644 --- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp @@ -835,7 +835,7 @@ getExpandedMacro(SourceLocation MacroExpansionLoc, const SourceManager &SM) { if (auto CTUMacroExpCtx = CTU.getMacroExpansionContextForSourceLocation(MacroExpansionLoc)) { - return CTUMacroExpCtx->getExpandedText(MacroExpansionLoc); + return CTUMacroExpCtx->getFormattedExpandedText(MacroExpansionLoc); } - return MacroExpansions.getExpandedText(MacroExpansionLoc); + return MacroExpansions.getFormattedExpandedText(MacroExpansionLoc); } diff --git a/clang/test/Analysis/plist-macros-with-expansion-ctu.c b/clang/test/Analysis/plist-macros-with-expansion-ctu.c index 956088cc0f675..9dd1b146e9d3c 100644 --- a/clang/test/Analysis/plist-macros-with-expansion-ctu.c +++ b/clang/test/Analysis/plist-macros-with-expansion-ctu.c @@ -66,7 +66,7 @@ void test3(void) { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>M</string> -// CHECK-NEXT: <key>expansion</key><string>F1 (&X )</string> +// CHECK-NEXT: <key>expansion</key><string>F1 // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -89,7 +89,7 @@ void test4(void) { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>M</string> -// CHECK-NEXT: <key>expansion</key><string>F2 (&X )</string> +// CHECK-NEXT: <key>expansion</key><string>F2 // CHECK-NEXT: </dict> // CHECK-NEXT: </array> diff --git a/clang/test/Analysis/plist-macros-with-expansion.c b/clang/test/Analysis/plist-macros-with-expansion.c index 10c78938960aa..79227c5d60f4e 100644 --- a/clang/test/Analysis/plist-macros-with-expansion.c +++ b/clang/test/Analysis/plist-macros-with-expansion.c @@ -22,7 +22,7 @@ void test_strange_macro_expansion(void) { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>STRANGE_FN(path)</string> -// CHECK-NEXT: <key>expansion</key><string>STRANGE_FN (path ,0)</string> +// CHECK-NEXT: <key>expansion</key><string>STRANGE_FN // CHECK-NEXT: </dict> // CHECK-NEXT: </array> diff --git a/clang/test/Analysis/plist-macros-with-expansion.cpp b/clang/test/Analysis/plist-macros-with-expansion.cpp index d57bb0f2dd265..d140026f820d8 100644 --- a/clang/test/Analysis/plist-macros-with-expansion.cpp +++ b/clang/test/Analysis/plist-macros-with-expansion.cpp @@ -29,7 +29,7 @@ void nonFunctionLikeMacroTest() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>SET_PTR_VAR_TO_NULL</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =0</string> +// CHECK-NEXT: <key>expansion</key><string>ptr // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -53,7 +53,7 @@ void nonFunctionLikeNestedMacroTest() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>SET_PTR_VAR_TO_NULL_WITH_NESTED_MACRO</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =0</string> +// CHECK-NEXT: <key>expansion</key><string>ptr // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -84,7 +84,7 @@ void functionLikeMacroTest() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL(&ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>setToNull (&ptr )</string> +// CHECK-NEXT: <key>expansion</key><string>setToNull // CHECK-NEXT: </dict> // CHECK-NEXT: </array> @@ -115,7 +115,7 @@ void functionLikeNestedMacroTest() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL(&a)</string> -// CHECK-NEXT: <key>expansion</key><string>setToNull (&a )</string> +// CHECK-NEXT: <key>expansion</key><string>setToNull // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> @@ -125,9 +125,7 @@ void functionLikeNestedMacroTest() { // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>DEREF(a)</string> -// CHECK-NEXT: <key>expansion</key><string>{int b ;b =5;}print (a );*a </string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>{ //===----------------------------------------------------------------------===// // Tests for undefining and/or redifining macros. @@ -149,14 +147,12 @@ void undefinedMacroByTheEndOfParsingTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>141</integer> +// CHECK-NEXT: <key>line</key><integer>139</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>WILL_UNDEF_SET_NULL_TO_PTR(ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =nullptr ;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>ptr #define WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr) \ /* Nothing */ @@ -180,14 +176,12 @@ void macroRedefinedMultipleTimesTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>169</integer> +// CHECK-NEXT: <key>line</key><integer>165</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>WILL_REDIFINE_MULTIPLE_TIMES_SET_TO_NULL(ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =nullptr ;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>ptr #define WILL_UNDEF_SET_NULL_TO_PTR_2(ptr) \ ptr = nullptr; @@ -206,14 +200,12 @@ void undefinedMacroInsideAnotherMacroTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>200</integer> +// CHECK-NEXT: <key>line</key><integer>194</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>PASS_PTR_TO_MACRO_THAT_WILL_BE_UNDEFD(ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =nullptr ;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>ptr #undef WILL_UNDEF_SET_NULL_TO_PTR_2 @@ -243,14 +235,12 @@ void macroArgContainsCommaInStringTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>237</integer> +// CHECK-NEXT: <key>line</key><integer>229</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL_AND_PRINT(a, "Will this , cause a crash?")</string> -// CHECK-NEXT: <key>expansion</key><string>a =0;print ("Will this , cause a crash?")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>a void macroArgContainsLParenInStringTest() { int *a; @@ -263,14 +253,12 @@ void macroArgContainsLParenInStringTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>257</integer> +// CHECK-NEXT: <key>line</key><integer>247</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL_AND_PRINT(a, "Will this ( cause a crash?")</string> -// CHECK-NEXT: <key>expansion</key><string>a =0;print ("Will this ( cause a crash?")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>a void macroArgContainsRParenInStringTest() { int *a; @@ -283,14 +271,12 @@ void macroArgContainsRParenInStringTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>277</integer> +// CHECK-NEXT: <key>line</key><integer>265</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL_AND_PRINT(a, "Will this ) cause a crash?")</string> -// CHECK-NEXT: <key>expansion</key><string>a =0;print ("Will this ) cause a crash?")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>a #define CALL_FUNCTION(funcCall) \ funcCall @@ -308,14 +294,12 @@ void macroArgContainsLParenRParenTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>302</integer> +// CHECK-NEXT: <key>line</key><integer>288</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CALL_FUNCTION(setToNull(&a))</string> -// CHECK-NEXT: <key>expansion</key><string>setToNull (&a )</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>setToNull void setToNullAndPrint(int **vptr, const char *str) { setToNull(vptr); @@ -333,14 +317,12 @@ void macroArgContainsCommaLParenRParenTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>327</integer> +// CHECK-NEXT: <key>line</key><integer>311</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CALL_FUNCTION(setToNullAndPrint(&a, "Hello!"))</string> -// CHECK-NEXT: <key>expansion</key><string>setToNullAndPrint (&a ,"Hello!")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>setToNullAndPrint #define CALL_FUNCTION_WITH_TWO_PARAMS(funcCall, param1, param2) \ funcCall(param1, param2) @@ -356,14 +338,12 @@ void macroArgContainsCommaLParenRParenTest2() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>350</integer> +// CHECK-NEXT: <key>line</key><integer>332</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CALL_FUNCTION_WITH_TWO_PARAMS(setToNullAndPrint, &a, "Hello!")</string> -// CHECK-NEXT: <key>expansion</key><string>setToNullAndPrint (&a ,"Hello!")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>setToNullAndPrint #define CALL_LAMBDA(l) \ l() @@ -382,24 +362,22 @@ void commaInBracketsTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>376</integer> +// CHECK-NEXT: <key>line</key><integer>356</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CALL_LAMBDA(([&ptr, str] () mutable { TO_NULL(&ptr); }))</string> -// CHECK-NEXT: <key>expansion</key><string>([&ptr ,str ]()mutable {setToNull (&ptr );})()</string> -// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>expansion</key><string>( +// CHECK: </dict> // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>376</integer> +// CHECK-NEXT: <key>line</key><integer>356</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CALL_LAMBDA(([&ptr, str] () mutable { TO_NULL(&ptr); }))</string> -// CHECK-NEXT: <key>expansion</key><string>([&ptr ,str ]()mutable {setToNull (&ptr );})()</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>( #define PASTE_CODE(code) \ code @@ -421,7 +399,7 @@ void commaInBracesTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>408</integer> +// CHECK-NEXT: <key>line</key><integer>386</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -434,9 +412,7 @@ void commaInBracesTest() { // CHECK-NEXT: int *ptr = nullptr; // CHECK-NEXT: *ptr = 5; // CHECK-NEXT: })</string> -// CHECK-NEXT: <key>expansion</key><string>{int *ptr =nullptr ;*ptr =5;}</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>{ // Example taken from // https://gcc.gnu.org/onlinedocs/cpp/Macro-Arguments.html#Macro-Arguments. @@ -457,14 +433,12 @@ void emptyParamTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>451</integer> +// CHECK-NEXT: <key>line</key><integer>427</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>POTENTIALLY_EMPTY_PARAM(,ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>;ptr =nullptr </string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>; #define NESTED_EMPTY_PARAM(a, b) \ POTENTIALLY_EMPTY_PARAM(a, b); @@ -482,14 +456,12 @@ void nestedEmptyParamTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>476</integer> +// CHECK-NEXT: <key>line</key><integer>450</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>NESTED_EMPTY_PARAM(, ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>;ptr =nullptr ;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>; #define CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO(func, param) \ CALL_FUNCTION(func(param)) @@ -505,14 +477,12 @@ void lParenRParenInNestedMacro() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>499</integer> +// CHECK-NEXT: <key>line</key><integer>471</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CALL_FUNCTION_WITH_ONE_PARAM_THROUGH_MACRO(setToNull, &ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>setToNull (&ptr )</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>setToNull //===----------------------------------------------------------------------===// // Tests for variadic macro arguments. @@ -536,14 +506,12 @@ void variadicMacroArgumentTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>530</integer> +// CHECK-NEXT: <key>line</key><integer>500</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>VARIADIC_SET_TO_NULL(ptr, 1, 5, "haha!")</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =nullptr ;variadicFunc (1,5,"haha!")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>ptr void variadicMacroArgumentWithoutAnyArgumentTest() { int *ptr; @@ -558,14 +526,12 @@ void variadicMacroArgumentWithoutAnyArgumentTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>552</integer> +// CHECK-NEXT: <key>line</key><integer>520</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>VARIADIC_SET_TO_NULL(ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>ptr =nullptr ;variadicFunc ()</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>ptr //===----------------------------------------------------------------------===// // Tests for # and ##. @@ -586,14 +552,12 @@ void hashHashOperatorTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>580</integer> +// CHECK-NEXT: <key>line</key><integer>546</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>DECLARE_FUNC_AND_SET_TO_NULL(whatever, ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>void generated_whatever ();ptr =nullptr ;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>void generated_whatever void macroArgContainsHashHashInStringTest() { int *a; @@ -606,14 +570,12 @@ void macroArgContainsHashHashInStringTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>600</integer> +// CHECK-NEXT: <key>line</key><integer>564</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL_AND_PRINT(a, "Will this ## cause a crash?")</string> -// CHECK-NEXT: <key>expansion</key><string>a =0;print ("Will this ## cause a crash?")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>a #define PRINT_STR(str, ptr) \ print(#str); \ @@ -630,14 +592,12 @@ void hashOperatorTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>624</integer> +// CHECK-NEXT: <key>line</key><integer>586</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>PRINT_STR(Hello, ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>print ("Hello");ptr =nullptr </string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>print void macroArgContainsHashInStringTest() { int *a; @@ -650,14 +610,12 @@ void macroArgContainsHashInStringTest() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>644</integer> +// CHECK-NEXT: <key>line</key><integer>604</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>TO_NULL_AND_PRINT(a, "Will this # cause a crash?")</string> -// CHECK-NEXT: <key>expansion</key><string>a =0;print ("Will this # cause a crash?")</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>a //===----------------------------------------------------------------------===// // Tests for more complex macro expansions. @@ -708,14 +666,12 @@ void testVeryComplexAlgorithm() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>698</integer> +// CHECK-NEXT: <key>line</key><integer>656</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>EUCLIDEAN_ALGORITHM(A, B)</string> -// CHECK-NEXT: <key>expansion</key><string>if (A <0){A =-A ;}if (B <0){B =-B ;}return B /(B -B );</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>if #define YET_ANOTHER_SET_TO_NULL(x, y, z) \ print((void *) x); \ @@ -736,14 +692,12 @@ void test() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>730</integer> +// CHECK-NEXT: <key>line</key><integer>686</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>YET_ANOTHER_SET_TO_NULL(5, DO_NOTHING2("Remember the Vasa"), ptr)</string> -// CHECK-NEXT: <key>expansion</key><string>print ((void *)5);print ((void *)"Remember the Vasa");ptr =nullptr ;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>print int garbage_value; @@ -761,14 +715,12 @@ void recursiveMacroUser() { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>754</integer> +// CHECK-NEXT: <key>line</key><integer>708</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>value</string> -// CHECK-NEXT: <key>expansion</key><string>garbage_value </string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>garbage_value #define FOO(x) int foo() { return x; } #define APPLY_ZERO1(function) function(0) @@ -781,14 +733,12 @@ void useZeroApplier1() { (void)(1 / foo()); } // expected-warning{{Division by z // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>776</integer> +// CHECK-NEXT: <key>line</key><integer>728</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>APPLY_ZERO1(FOO)</string> -// CHECK-NEXT: <key>expansion</key><string>int foo (){return 0;}</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>int foo #define BAR(x) int bar() { return x; } #define APPLY_ZERO2 BAR(0) @@ -801,14 +751,12 @@ void useZeroApplier2() { (void)(1 / bar()); } // expected-warning{{Division by z // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>796</integer> +// CHECK-NEXT: <key>line</key><integer>746</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>APPLY_ZERO2</string> -// CHECK-NEXT: <key>expansion</key><string>int bar (){return 0;}</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>int void foo(int &x, const char *str); @@ -827,14 +775,12 @@ void mulitpleParamsResolveToVA_ARGS(void) { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>821</integer> +// CHECK-NEXT: <key>line</key><integer>769</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>DISPATCH(x, "LF1M healer")</string> -// CHECK-NEXT: <key>expansion</key><string>foo (x ,"LF1M healer");x =0;;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>foo void variadicCFunction(int &x, const char *str, ...); @@ -852,14 +798,12 @@ void concatVA_ARGS(void) { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>846</integer> +// CHECK-NEXT: <key>line</key><integer>792</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CONCAT_VA_ARGS(x, "You need to construct additional pylons.", 'c', 9)</string> -// CHECK-NEXT: <key>expansion</key><string>variadicCFunction (x ,"You need to construct additional pylons.",'c',9);x =0;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>variadicCFunction void concatVA_ARGSEmpty(void) { int x = 1; @@ -872,14 +816,12 @@ void concatVA_ARGSEmpty(void) { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>866</integer> +// CHECK-NEXT: <key>line</key><integer>810</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>CONCAT_VA_ARGS(x, "You need to construct")</string> -// CHECK-NEXT: <key>expansion</key><string>variadicCFunction (x ,"You need to construct");x =0;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>variadicCFunction #define STRINGIFIED_VA_ARGS(i, fmt, ...) variadicCFunction(i, fmt, #__VA_ARGS__); \ i = 0; @@ -895,14 +837,12 @@ void stringifyVA_ARGS(void) { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>889</integer> +// CHECK-NEXT: <key>line</key><integer>831</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>STRINGIFIED_VA_ARGS(x, "Additional supply depots required.", 'a', 10)</string> -// CHECK-NEXT: <key>expansion</key><string>variadicCFunction (x ,"Additional supply depots required.","'a', 10");x =0;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>variadicCFunction void stringifyVA_ARGSEmpty(void) { int x = 1; @@ -915,14 +855,12 @@ void stringifyVA_ARGSEmpty(void) { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>909</integer> +// CHECK-NEXT: <key>line</key><integer>849</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>STRINGIFIED_VA_ARGS(x, "Additional supply depots required.")</string> -// CHECK-NEXT: <key>expansion</key><string>variadicCFunction (x ,"Additional supply depots required.","");x =0;</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>variadicCFunction // bz44493: Support GNU-style named variadic arguments in plister #define BZ44493_GNUVA(i, args...) --(i); @@ -940,11 +878,9 @@ int bz44493(void) { // CHECK-NEXT: <dict> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>933</integer> +// CHECK-NEXT: <key>line</key><integer>871</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <key>name</key><string>BZ44493_GNUVA(a, "arg2")</string> -// CHECK-NEXT: <key>expansion</key><string>--(a );</string> -// CHECK-NEXT: </dict> -// CHECK-NEXT: </array> +// CHECK-NEXT: <key>expansion</key><string>--(a diff --git a/clang/unittests/Analysis/MacroExpansionContextTest.cpp b/clang/unittests/Analysis/MacroExpansionContextTest.cpp index 25a76edbfdc49..a9873a326240f 100644 --- a/clang/unittests/Analysis/MacroExpansionContextTest.cpp +++ b/clang/unittests/Analysis/MacroExpansionContextTest.cpp @@ -405,6 +405,43 @@ TEST_F(MacroExpansionContextTest, UnbalacedParenthesis) { EXPECT_EQ("f(f(1))", *Ctx->getOriginalText(at(13, 12))); } +TEST_F(MacroExpansionContextTest, FormattedExpandedTextNoneWhenNoExpansion) { + const auto Ctx = getMacroExpansionContextFor(R"code( + #define UNUSED 1 + int value = 0; + )code"); + EXPECT_FALSE(Ctx->getFormattedExpandedText(at(3, 3)).has_value()); +} + +TEST_F(MacroExpansionContextTest, + FormattedExpandedTextKeepsOriginalWhenStable) { + const auto Ctx = getMacroExpansionContextFor(R"code( + #define ANSWER 42 + int life = ANSWER; + )code"); + + const auto Expanded = Ctx->getExpandedText(at(3, 14)); + ASSERT_TRUE(Expanded.has_value()); + + EXPECT_EQ(*Expanded, *Ctx->getFormattedExpandedText(at(3, 14))); +} + +TEST_F(MacroExpansionContextTest, FormattedExpandedTextChangesWhenFormatting) { + const auto Ctx = getMacroExpansionContextFor(R"code( + #define ADD(x, y) (x+y* x) + int result = ADD(1,2); + )code"); + + const auto Expanded = Ctx->getExpandedText(at(3, 16)); + ASSERT_TRUE(Expanded.has_value()); + + const auto Formatted = Ctx->getFormattedExpandedText(at(3, 16)); + ASSERT_TRUE(Formatted.has_value()); + + EXPECT_EQ(*Formatted, *Ctx->getFormattedExpandedText(at(3, 16))); + EXPECT_NE(*Expanded, *Formatted); +} + } // namespace } // namespace analysis } // namespace clang _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
