comparison clang-tools-extra/clangd/Hover.cpp @ 223:5f17cb93ff66 llvm-original

LLVM13 (2021/7/18)
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 18 Jul 2021 22:43:00 +0900
parents 79ff65ed7e25
children c4bab56944e8
comparison
equal deleted inserted replaced
222:81f6424ef0e3 223:5f17cb93ff66
26 #include "clang/AST/DeclTemplate.h" 26 #include "clang/AST/DeclTemplate.h"
27 #include "clang/AST/Expr.h" 27 #include "clang/AST/Expr.h"
28 #include "clang/AST/ExprCXX.h" 28 #include "clang/AST/ExprCXX.h"
29 #include "clang/AST/OperationKinds.h" 29 #include "clang/AST/OperationKinds.h"
30 #include "clang/AST/PrettyPrinter.h" 30 #include "clang/AST/PrettyPrinter.h"
31 #include "clang/AST/RecordLayout.h"
31 #include "clang/AST/RecursiveASTVisitor.h" 32 #include "clang/AST/RecursiveASTVisitor.h"
32 #include "clang/AST/Type.h" 33 #include "clang/AST/Type.h"
33 #include "clang/Basic/SourceLocation.h" 34 #include "clang/Basic/SourceLocation.h"
34 #include "clang/Basic/Specifiers.h" 35 #include "clang/Basic/Specifiers.h"
35 #include "clang/Basic/TokenKinds.h" 36 #include "clang/Basic/TokenKinds.h"
585 if (const Expr *Init = Var->getInit()) 586 if (const Expr *Init = Var->getInit())
586 HI.Value = printExprValue(Init, Ctx); 587 HI.Value = printExprValue(Init, Ctx);
587 } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) { 588 } else if (const auto *ECD = dyn_cast<EnumConstantDecl>(D)) {
588 // Dependent enums (e.g. nested in template classes) don't have values yet. 589 // Dependent enums (e.g. nested in template classes) don't have values yet.
589 if (!ECD->getType()->isDependentType()) 590 if (!ECD->getType()->isDependentType())
590 HI.Value = ECD->getInitVal().toString(10); 591 HI.Value = toString(ECD->getInitVal(), 10);
591 } 592 }
592 593
593 HI.Definition = printDefinition(D, PP); 594 HI.Definition = printDefinition(D, PP);
594 return HI; 595 return HI;
595 } 596 }
768 769
769 if (const auto *FD = llvm::dyn_cast<FieldDecl>(&ND)) { 770 if (const auto *FD = llvm::dyn_cast<FieldDecl>(&ND)) {
770 const auto *Record = FD->getParent(); 771 const auto *Record = FD->getParent();
771 if (Record) 772 if (Record)
772 Record = Record->getDefinition(); 773 Record = Record->getDefinition();
773 if (Record && !Record->isInvalidDecl() && !Record->isDependentType()) { 774 if (Record && !Record->isInvalidDecl() && !Record->isDependentType() &&
774 HI.Offset = Ctx.getFieldOffset(FD) / 8; 775 !FD->isBitField()) {
775 if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) 776 const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Record);
776 HI.Size = Size->getQuantity(); 777 HI.Offset = Layout.getFieldOffset(FD->getFieldIndex()) / 8;
778 if (auto Size = Ctx.getTypeSizeInCharsIfKnown(FD->getType())) {
779 HI.Size = FD->isZeroSize(Ctx) ? 0 : Size->getQuantity();
780 unsigned EndOfField = *HI.Offset + *HI.Size;
781
782 // Calculate padding following the field.
783 if (!Record->isUnion() &&
784 FD->getFieldIndex() + 1 < Layout.getFieldCount()) {
785 // Measure padding up to the next class field.
786 unsigned NextOffset =
787 Layout.getFieldOffset(FD->getFieldIndex() + 1) / 8;
788 if (NextOffset >= EndOfField) // next field could be a bitfield!
789 HI.Padding = NextOffset - EndOfField;
790 } else {
791 // Measure padding up to the end of the object.
792 HI.Padding = Layout.getSize().getQuantity() - EndOfField;
793 }
794 }
795 // Offset in a union is always zero, so not really useful to report.
796 if (Record->isUnion())
797 HI.Offset.reset();
777 } 798 }
778 return; 799 return;
779 } 800 }
780 } 801 }
781 802
1011 1032
1012 if (Offset) 1033 if (Offset)
1013 Output.addParagraph().appendText( 1034 Output.addParagraph().appendText(
1014 llvm::formatv("Offset: {0} byte{1}", *Offset, *Offset == 1 ? "" : "s") 1035 llvm::formatv("Offset: {0} byte{1}", *Offset, *Offset == 1 ? "" : "s")
1015 .str()); 1036 .str());
1016 if (Size) 1037 if (Size) {
1017 Output.addParagraph().appendText( 1038 auto &P = Output.addParagraph().appendText(
1018 llvm::formatv("Size: {0} byte{1}", *Size, *Size == 1 ? "" : "s").str()); 1039 llvm::formatv("Size: {0} byte{1}", *Size, *Size == 1 ? "" : "s").str());
1040 if (Padding && *Padding != 0)
1041 P.appendText(llvm::formatv(" (+{0} padding)", *Padding).str());
1042 }
1019 1043
1020 if (CalleeArgInfo) { 1044 if (CalleeArgInfo) {
1021 assert(CallPassType); 1045 assert(CallPassType);
1022 std::string Buffer; 1046 std::string Buffer;
1023 llvm::raw_string_ostream OS(Buffer); 1047 llvm::raw_string_ostream OS(Buffer);