-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[CIR] Add support for accessing members of base classes #143195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This contains code dealing with C++ code generation of classes | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "CIRGenFunction.h" | ||
|
|
||
| #include "clang/AST/RecordLayout.h" | ||
| #include "clang/CIR/MissingFeatures.h" | ||
|
|
||
| using namespace clang; | ||
| using namespace clang::CIRGen; | ||
|
|
||
| Address | ||
| CIRGenFunction::getAddressOfBaseClass(Address value, | ||
| const CXXRecordDecl *derived, | ||
| CastExpr::path_const_iterator pathBegin, | ||
|
||
| CastExpr::path_const_iterator pathEnd, | ||
| bool nullCheckValue, SourceLocation loc) { | ||
| assert(pathBegin != pathEnd && "Base path should not be empty!"); | ||
|
|
||
| CastExpr::path_const_iterator start = pathBegin; | ||
|
|
||
| if ((*start)->isVirtual()) { | ||
| // The implementation here is actually complete, but let's flag this | ||
| // as an error until the rest of the virtual base class support is in place. | ||
| cgm.errorNYI(loc, "getAddrOfBaseClass: virtual base"); | ||
| return Address::invalid(); | ||
| } | ||
|
|
||
| // Compute the static offset of the ultimate destination within its | ||
| // allocating subobject (the virtual base, if there is one, or else | ||
| // the "complete" object that we see). | ||
| CharUnits nonVirtualOffset = | ||
| cgm.computeNonVirtualBaseClassOffset(derived, start, pathEnd); | ||
|
|
||
| // Get the base pointer type. | ||
| mlir::Type baseValueTy = convertType((pathEnd[-1])->getType()); | ||
| assert(!cir::MissingFeatures::addressSpace()); | ||
|
|
||
| // The if statement here is redundant now, but it will be needed when we add | ||
| // support for virtual base classes. | ||
| // If there is no virtual base, use cir.base_class_addr. It takes care of | ||
| // the adjustment and the null pointer check. | ||
| if (nonVirtualOffset.isZero()) { | ||
| assert(!cir::MissingFeatures::sanitizers()); | ||
| return builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, 0, | ||
| /*assumeNotNull=*/true); | ||
| } | ||
|
|
||
| assert(!cir::MissingFeatures::sanitizers()); | ||
|
|
||
| // Apply the offset | ||
| value = builder.createBaseClassAddr(getLoc(loc), value, baseValueTy, | ||
| nonVirtualOffset.getQuantity(), | ||
| /*assumeNotNull=*/true); | ||
|
|
||
| // Cast to the destination type. | ||
| value = value.withElementType(builder, baseValueTy); | ||
|
|
||
| return value; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
| #include "clang/AST/DeclBase.h" | ||
| #include "clang/AST/DeclOpenACC.h" | ||
| #include "clang/AST/GlobalDecl.h" | ||
| #include "clang/AST/RecordLayout.h" | ||
| #include "clang/Basic/SourceManager.h" | ||
| #include "clang/CIR/Dialect/IR/CIRDialect.h" | ||
| #include "clang/CIR/Interfaces/CIROpInterfaces.h" | ||
|
|
@@ -1677,6 +1678,34 @@ bool CIRGenModule::verifyModule() const { | |
| return mlir::verify(theModule).succeeded(); | ||
| } | ||
|
|
||
| // TODO(cir): this can be shared with LLVM codegen. | ||
| CharUnits CIRGenModule::computeNonVirtualBaseClassOffset( | ||
| const CXXRecordDecl *derivedClass, CastExpr::path_const_iterator start, | ||
|
||
| CastExpr::path_const_iterator end) { | ||
| CharUnits offset = CharUnits::Zero(); | ||
|
|
||
| const ASTContext &astContext = getASTContext(); | ||
| const CXXRecordDecl *rd = derivedClass; | ||
|
|
||
| for (CastExpr::path_const_iterator i = start; i != end; ++i) { | ||
|
||
| const CXXBaseSpecifier *base = *i; | ||
| assert(!base->isVirtual() && "Should not see virtual bases here!"); | ||
|
|
||
| // Get the layout. | ||
| const ASTRecordLayout &layout = astContext.getASTRecordLayout(rd); | ||
|
|
||
| const auto *baseDecl = cast<CXXRecordDecl>( | ||
| base->getType()->castAs<clang::RecordType>()->getDecl()); | ||
|
|
||
| // Add the offset. | ||
| offset += layout.getBaseClassOffset(baseDecl); | ||
|
|
||
| rd = baseDecl; | ||
| } | ||
|
|
||
| return offset; | ||
| } | ||
|
|
||
| DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc, | ||
| llvm::StringRef feature) { | ||
| unsigned diagID = diags.getCustomDiagID( | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be a good opportunity to get rid of the
(and)(https://llvm.github.io/clangir/Dialect/cir-style-guide.html).