|
29 | 29 | #include "clang/AST/Type.h" |
30 | 30 | #include "clang/Basic/IdentifierTable.h" |
31 | 31 | #include "clang/Basic/LLVM.h" |
| 32 | +#include "clang/Basic/LangOptions.h" |
32 | 33 | #include "clang/Basic/Module.h" |
33 | 34 | #include "clang/Basic/ObjCRuntime.h" |
34 | 35 | #include "clang/Basic/PartialDiagnostic.h" |
@@ -410,79 +411,6 @@ bool Decl::isFileContextDecl() const { |
410 | 411 | return DC && DC->isFileContext(); |
411 | 412 | } |
412 | 413 |
|
413 | | -bool Decl::isFlexibleArrayMemberLike( |
414 | | - ASTContext &Ctx, const Decl *D, QualType Ty, |
415 | | - LangOptions::StrictFlexArraysLevelKind StrictFlexArraysLevel, |
416 | | - bool IgnoreTemplateOrMacroSubstitution) { |
417 | | - // For compatibility with existing code, we treat arrays of length 0 or |
418 | | - // 1 as flexible array members. |
419 | | - const auto *CAT = Ctx.getAsConstantArrayType(Ty); |
420 | | - if (CAT) { |
421 | | - using FAMKind = LangOptions::StrictFlexArraysLevelKind; |
422 | | - |
423 | | - llvm::APInt Size = CAT->getSize(); |
424 | | - if (StrictFlexArraysLevel == FAMKind::IncompleteOnly) |
425 | | - return false; |
426 | | - |
427 | | - // GCC extension, only allowed to represent a FAM. |
428 | | - if (Size.isZero()) |
429 | | - return true; |
430 | | - |
431 | | - if (StrictFlexArraysLevel == FAMKind::ZeroOrIncomplete && Size.uge(1)) |
432 | | - return false; |
433 | | - |
434 | | - if (StrictFlexArraysLevel == FAMKind::OneZeroOrIncomplete && Size.uge(2)) |
435 | | - return false; |
436 | | - } else if (!Ctx.getAsIncompleteArrayType(Ty)) { |
437 | | - return false; |
438 | | - } |
439 | | - |
440 | | - if (const auto *OID = dyn_cast_if_present<ObjCIvarDecl>(D)) |
441 | | - return OID->getNextIvar() == nullptr; |
442 | | - |
443 | | - const auto *FD = dyn_cast_if_present<FieldDecl>(D); |
444 | | - if (!FD) |
445 | | - return false; |
446 | | - |
447 | | - if (CAT) { |
448 | | - // GCC treats an array memeber of a union as an FAM if the size is one or |
449 | | - // zero. |
450 | | - llvm::APInt Size = CAT->getSize(); |
451 | | - if (FD->getParent()->isUnion() && (Size.isZero() || Size.isOne())) |
452 | | - return true; |
453 | | - } |
454 | | - |
455 | | - // Don't consider sizes resulting from macro expansions or template argument |
456 | | - // substitution to form C89 tail-padded arrays. |
457 | | - if (IgnoreTemplateOrMacroSubstitution) { |
458 | | - TypeSourceInfo *TInfo = FD->getTypeSourceInfo(); |
459 | | - while (TInfo) { |
460 | | - TypeLoc TL = TInfo->getTypeLoc(); |
461 | | - |
462 | | - // Look through typedefs. |
463 | | - if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) { |
464 | | - const TypedefNameDecl *TDL = TTL.getTypedefNameDecl(); |
465 | | - TInfo = TDL->getTypeSourceInfo(); |
466 | | - continue; |
467 | | - } |
468 | | - |
469 | | - if (auto CTL = TL.getAs<ConstantArrayTypeLoc>()) { |
470 | | - if (const Expr *SizeExpr = |
471 | | - dyn_cast_if_present<IntegerLiteral>(CTL.getSizeExpr()); |
472 | | - !SizeExpr || SizeExpr->getExprLoc().isMacroID()) |
473 | | - return false; |
474 | | - } |
475 | | - |
476 | | - break; |
477 | | - } |
478 | | - } |
479 | | - |
480 | | - // Test that the field is the last in the structure. |
481 | | - RecordDecl::field_iterator FI( |
482 | | - DeclContext::decl_iterator(const_cast<FieldDecl *>(FD))); |
483 | | - return ++FI == FD->getParent()->field_end(); |
484 | | -} |
485 | | - |
486 | 414 | TranslationUnitDecl *Decl::getTranslationUnitDecl() { |
487 | 415 | if (auto *TUD = dyn_cast<TranslationUnitDecl>(this)) |
488 | 416 | return TUD; |
|
0 commit comments