clang: lib/Sema/SemaStmtAsm.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

23#include "llvm/ADT/ArrayRef.h"

24#include "llvm/ADT/StringExtras.h"

25#include "llvm/ADT/StringSet.h"

26#include "llvm/MC/MCParser/MCAsmParser.h"

27#include

28using namespace clang;

29using namespace sema;

30

31

33 Expr *Parent = E;

34 Expr *ExprUnderCast = nullptr;

36

37 while (true) {

38 ParentsToUpdate.push_back(Parent);

39 if (auto *ParenE = dyn_cast(Parent)) {

40 Parent = ParenE->getSubExpr();

41 continue;

42 }

43

44 Expr *Child = nullptr;

45 CastExpr *ParentCast = dyn_cast(Parent);

46 if (ParentCast)

48 else

49 return;

50

51 if (auto *CastE = dyn_cast(Child))

52 if (CastE->getCastKind() == CK_LValueToRValue) {

53 ExprUnderCast = CastE->getSubExpr();

54

55 ParentCast->setSubExpr(ExprUnderCast);

56 break;

57 }

58 Parent = Child;

59 }

60

61

62 assert(ExprUnderCast &&

63 "Should be reachable only if LValueToRValue cast was found!");

64 auto ValueKind = ExprUnderCast->getValueKind();

65 for (Expr *E : ParentsToUpdate)

67}

68

69

70

77

78

79

80

81

82

83

84

86

88 return false;

89

91 return false;

92

93

94

96 if (E != E2 && E2->isLValue()) {

98

99 return false;

100 }

101

102

103 return true;

104}

105

106

107

108static bool

111 for (unsigned p = 0, e = AsmStrPieces.size(); p != e; ++p) {

114 continue;

115

116

117

119 return true;

120 }

121 return false;

122}

123

127 return false;

128 if (Func->hasAttr())

129 return false;

130

132 WorkList.push_back(E);

133 while (WorkList.size()) {

134 Expr *E = WorkList.pop_back_val();

137 S.Diag(Func->getAttr()->getLocation(), diag::note_attribute);

138 return true;

139 }

140 if (DeclRefExpr *DRE = dyn_cast(E)) {

142 S.Diag(DRE->getBeginLoc(), diag::err_asm_naked_parm_ref);

143 S.Diag(Func->getAttr()->getLocation(), diag::note_attribute);

144 return true;

145 }

146 }

148 if (Expr *E = dyn_cast_or_null(Child))

149 WorkList.push_back(E);

150 }

151 }

152 return false;

153}

154

155

156

159 bool is_input_expr) {

160 enum {

161 ExprBitfield = 0,

162 ExprVectorElt,

163 ExprGlobalRegVar,

164 ExprSafeType

165 } EType = ExprSafeType;

166

167

168

170 EType = ExprBitfield;

172 EType = ExprVectorElt;

174 EType = ExprGlobalRegVar;

175

176 if (EType != ExprSafeType) {

177 S.Diag(E->getBeginLoc(), diag::err_asm_non_addr_value_in_memory_constraint)

180 return true;

181 }

182

183 return false;

184}

185

186

187

192

193 const VarDecl *Variable = dyn_cast(AsmDeclRef->getDecl());

194 if (Variable && Variable->getStorageClass() == SC_Register) {

195 if (AsmLabelAttr *Attr = Variable->getAttr())

196 if (Target.isValidGCCRegisterName(Attr->getLabel()))

197 return Target.getNormalizedGCCRegisterName(Attr->getLabel(), true);

198 }

199 }

200 return "";

201}

202

203

204

205

208 Expr **Clobbers, int NumClobbers, unsigned NumLabels,

210 llvm::StringSet<> InOutVars;

211

212

213 for (unsigned int i = 0; i < Exprs.size() - NumLabels; ++i) {

214 std::string Constraint =

216 StringRef InOutReg = Target.getConstraintRegister(

218 if (InOutReg != "")

219 InOutVars.insert(InOutReg);

220 }

221

222

223 for (int i = 0; i < NumClobbers; ++i) {

224 std::string Clobber =

226

227

228 if (Clobber == "cc" || Clobber == "memory" || Clobber == "unwind")

229 continue;

230 Clobber = Target.getNormalizedGCCRegisterName(Clobber, true);

231

232 if (InOutVars.count(Clobber))

234 }

236}

237

241

242 if (auto *SL = dyn_cast(Expr)) {

243 assert(SL->isOrdinary());

244 if (ForAsmLabel && SL->getString().empty()) {

246 << SL->getSourceRange();

247 }

248 return SL;

249 }

256 true))

258

259 if (ForAsmLabel && V.getArrayInitializedElts() == 0) {

261 }

262

266 return Res;

267}

268

270 bool IsVolatile, unsigned NumOutputs,

274 unsigned NumLabels,

276 unsigned NumClobbers = clobbers.size();

277

279

281 llvm::StringMap FeatureMap;

282 Context.getFunctionFeatureMap(FeatureMap, FD);

283

284 auto CreateGCCAsmStmt = [&] {

286 GCCAsmStmt(Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs,

287 Names, constraints.data(), Exprs.data(), asmString,

288 NumClobbers, clobbers.data(), NumLabels, RParenLoc);

289 };

290

291 if (asmString->getDependence() != ExprDependence::None ||

292 llvm::any_of(

293 constraints,

294 [](Expr *E) { return E->getDependence() != ExprDependence::None; }) ||

295 llvm::any_of(clobbers, [](Expr *E) {

296 return E->getDependence() != ExprDependence::None;

297 }))

298 return CreateGCCAsmStmt();

299

300 for (unsigned i = 0; i != NumOutputs; i++) {

301 Expr *Constraint = constraints[i];

302 StringRef OutputName;

303 if (Names[i])

304 OutputName = Names[i]->getName();

305

306 std::string ConstraintStr =

308

310 if (Context.getTargetInfo().validateOutputConstraint(Info) &&

313 diag::err_asm_invalid_output_constraint)

315 return CreateGCCAsmStmt();

316 }

317

321 Exprs[i] = ER.get();

322

323

324 Expr *OutputExpr = Exprs[i];

325

326

329

330

334

335

336

339 Diag(OutputExpr->getBeginLoc(), diag::err_asm_invalid_type)

340 << OutputExpr->getType() << 0

342

343 OutputConstraintInfos.push_back(Info);

344

345

347 continue;

348

351 switch (IsLV) {

353

354 break;

356

357 break;

361

362 break;

363 }

367 diag::err_dereference_incomplete_type))

369 [[fallthrough]];

370 default:

372 diag::err_asm_invalid_lvalue_in_output)

374 }

375

376 unsigned Size = Context.getTypeSize(OutputExpr->getType());

377 if (Context.getTargetInfo().validateOutputSize(

378 FeatureMap,

380 Size)) {

383 return CreateGCCAsmStmt();

384 }

385 }

386

388

389 for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) {

390 Expr *Constraint = constraints[i];

391

392 StringRef InputName;

393 if (Names[i])

394 InputName = Names[i]->getName();

395

396 std::string ConstraintStr =

398

400 if (Context.getTargetInfo().validateInputConstraint(OutputConstraintInfos,

401 Info)) {

403 diag::err_asm_invalid_input_constraint)

405 return CreateGCCAsmStmt();

406 }

407

411 Exprs[i] = ER.get();

412

413 Expr *InputExpr = Exprs[i];

414

417 diag::err_asm_pmf_through_constraint_not_permitted)

419

420

423

424

428

429

433 diag::err_asm_invalid_lvalue_in_input)

436 } else {

438 if (Result.isInvalid())

440

441 InputExpr = Exprs[i] = Result.get();

442

447

448

449 llvm::APSInt IntResult;

455 diag::err_invalid_asm_value_for_constraint)

458 }

459 }

460 }

461 }

462

466 Diag(InputExpr->getBeginLoc(), diag::err_asm_invalid_type_in_input)

469 }

470 }

471

474 Diag(InputExpr->getBeginLoc(), diag::err_asm_invalid_type)

475 << InputExpr->getType() << 1

477

478 InputConstraintInfos.push_back(Info);

479

480 const Type *Ty = Exprs[i]->getType().getTypePtr();

482 continue;

483

486 diag::err_dereference_incomplete_type))

488

489 unsigned Size = Context.getTypeSize(Ty);

490 if (Context.getTargetInfo().validateInputSize(FeatureMap, ConstraintStr,

491 Size))

493 diag::err_asm_invalid_input_size)

495 }

496

497 std::optional UnwindClobberLoc;

498

499

500 for (unsigned i = 0; i != NumClobbers; i++) {

501 Expr *ClobberExpr = clobbers[i];

502

503 std::string Clobber =

505

506 if (Context.getTargetInfo().isValidClobber(Clobber)) {

508 diag::err_asm_unknown_register_name)

509 << Clobber;

511 Context, AsmLoc, IsSimple, IsVolatile, NumOutputs, NumInputs, Names,

512 constraints.data(), Exprs.data(), asmString, NumClobbers,

513 clobbers.data(), NumLabels, RParenLoc);

514 }

515

516 if (Clobber == "unwind") {

517 UnwindClobberLoc = ClobberExpr->getBeginLoc();

518 }

519 }

520

521

522 if (UnwindClobberLoc && NumLabels > 0) {

523 targetDiag(*UnwindClobberLoc, diag::err_asm_unwind_and_goto);

524 return CreateGCCAsmStmt();

525 }

526

528

529

530

531 auto GetLocation = [this](const Expr *Str, unsigned Offset) {

532 if (auto *SL = dyn_cast(Str))

535 };

536

538 unsigned DiagOffs;

539 if (unsigned DiagID = NS->AnalyzeAsmString(Pieces, Context, DiagOffs)) {

540 targetDiag(GetLocation(asmString, DiagOffs), DiagID)

542 return NS;

543 }

544

545

546 for (unsigned i = 0, e = Pieces.size(); i != e; ++i) {

548 if (!Piece.isOperand()) continue;

549

550

551 unsigned ConstraintIdx = Piece.getOperandNo();

552 unsigned NumOperands = NS->getNumOutputs() + NS->getNumInputs();

553

554 if (NS->isAsmGoto() && ConstraintIdx >= NumOperands)

555 continue;

556

557

558 if (ConstraintIdx >= NumOperands) {

559 unsigned I = 0, E = NS->getNumOutputs();

560

561 for (unsigned Cnt = ConstraintIdx - NumOperands; I != E; ++I)

562 if (OutputConstraintInfos[I].isReadWrite() && Cnt-- == 0) {

563 ConstraintIdx = I;

564 break;

565 }

566

567 assert(I != E && "Invalid operand number should have been caught in "

568 " AnalyzeAsmString");

569 }

570

571

572 Expr *Constraint = constraints[ConstraintIdx];

573 const Type *Ty = Exprs[ConstraintIdx]->getType().getTypePtr();

575 continue;

576

577 unsigned Size = Context.getTypeSize(Ty);

578 std::string SuggestedModifier;

579 if (Context.getTargetInfo().validateConstraintModifier(

581 Piece.getModifier(), Size, SuggestedModifier)) {

582 targetDiag(Exprs[ConstraintIdx]->getBeginLoc(),

583 diag::warn_asm_mismatched_size_modifier);

584

585 if (!SuggestedModifier.empty()) {

587 diag::note_asm_missing_constraint_modifier)

588 << SuggestedModifier;

590 SuggestedModifier = "%" + SuggestedModifier + Piece.getString();

592 SuggestedModifier);

593 }

594 }

595 }

596 }

597

598

599 unsigned NumAlternatives = ~0U;

600 for (unsigned i = 0, e = OutputConstraintInfos.size(); i != e; ++i) {

603 unsigned AltCount = ConstraintStr.count(',') + 1;

604 if (NumAlternatives == ~0U) {

605 NumAlternatives = AltCount;

606 } else if (NumAlternatives != AltCount) {

607 targetDiag(NS->getOutputExpr(i)->getBeginLoc(),

608 diag::err_asm_unexpected_constraint_alternatives)

609 << NumAlternatives << AltCount;

610 return NS;

611 }

612 }

614 ~0U);

615 for (unsigned i = 0, e = InputConstraintInfos.size(); i != e; ++i) {

618 unsigned AltCount = ConstraintStr.count(',') + 1;

619 if (NumAlternatives == ~0U) {

620 NumAlternatives = AltCount;

621 } else if (NumAlternatives != AltCount) {

622 targetDiag(NS->getInputExpr(i)->getBeginLoc(),

623 diag::err_asm_unexpected_constraint_alternatives)

624 << NumAlternatives << AltCount;

625 return NS;

626 }

627

628

629

630

632

634 unsigned InputOpNo = i+NumOutputs;

635 Expr *OutputExpr = Exprs[TiedTo];

636 Expr *InputExpr = Exprs[InputOpNo];

637

638

639 assert(TiedTo < InputMatchedToOutput.size() && "TiedTo value out of range");

640 if (InputMatchedToOutput[TiedTo] != ~0U) {

641 targetDiag(NS->getInputExpr(i)->getBeginLoc(),

642 diag::err_asm_input_duplicate_match)

643 << TiedTo;

644 targetDiag(NS->getInputExpr(InputMatchedToOutput[TiedTo])->getBeginLoc(),

645 diag::note_asm_input_duplicate_first)

646 << TiedTo;

647 return NS;

648 }

649 InputMatchedToOutput[TiedTo] = i;

650

652 continue;

653

656 if (Context.hasSameType(InTy, OutTy))

657 continue;

658

659

660

661 enum AsmDomain {

662 AD_Int, AD_FP, AD_Other

663 } InputDomain, OutputDomain;

664

666 InputDomain = AD_Int;

668 InputDomain = AD_FP;

669 else

670 InputDomain = AD_Other;

671

673 OutputDomain = AD_Int;

675 OutputDomain = AD_FP;

676 else

677 OutputDomain = AD_Other;

678

679

680

681

682

683

684

685 uint64_t OutSize = Context.getTypeSize(OutTy);

686 uint64_t InSize = Context.getTypeSize(InTy);

687 if (OutSize == InSize && InputDomain == OutputDomain &&

688 InputDomain != AD_Other)

689 continue;

690

691

692

693

694 bool SmallerValueMentioned = false;

695

696

697

699

700

701

702 SmallerValueMentioned |= InSize < OutSize;

703 }

705

706

707 SmallerValueMentioned |= OutSize < InSize;

708 }

709

710

711

712 bool FPTiedToInt = (InputDomain == AD_FP) ^ (OutputDomain == AD_FP);

713

714

715

716

717 if (!SmallerValueMentioned && !FPTiedToInt && InputDomain != AD_Other &&

718 OutputConstraintInfos[TiedTo].allowsRegister()) {

719

720

721

723 Context.getIntTypeForBitwidth(OutSize, false).isNull()) {

725 return NS;

726 }

727

728 continue;

729 }

730

731

732

733

734

735 if (InputDomain == AD_Int && OutputDomain == AD_Int &&

739 (OutTy->isBooleanType() ? CK_IntegralToBoolean : CK_IntegralCast);

741 Exprs[InputOpNo] = InputExpr;

742 NS->setInputExpr(i, InputExpr);

743 continue;

744 }

745

749 return NS;

750 }

751

752

754 Exprs, constraints.data(), clobbers.data(), NumClobbers, NumLabels,

756 if (ConstraintLoc.isValid())

757 targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);

758

759

760 typedef std::pair<StringRef , Expr *> NamedOperand;

762 for (unsigned i = 0, e = NumOutputs + NumInputs + NumLabels; i != e; ++i)

763 if (Names[i])

764 NamedOperandList.emplace_back(

765 std::make_pair(Names[i]->getName(), Exprs[i]));

766

767 llvm::stable_sort(NamedOperandList, llvm::less_first());

768

770 std::adjacent_find(begin(NamedOperandList), end(NamedOperandList),

771 [](const NamedOperand &LHS, const NamedOperand &RHS) {

772 return LHS.first == RHS.first;

773 });

774 if (Found != NamedOperandList.end()) {

775 Diag((Found + 1)->second->getBeginLoc(),

776 diag::error_duplicate_asm_operand_name)

777 << (Found + 1)->first;

778 Diag(Found->second->getBeginLoc(), diag::note_duplicate_asm_operand_name)

781 }

782 if (NS->isAsmGoto())

784

787 return NS;

788}

789

791 llvm::InlineAsmIdentifierInfo &Info) {

794 if (T->isFunctionType() || T->isDependentType())

795 return Info.setLabel(Res);

798 if (DeclRefExpr *DRE = dyn_castclang::DeclRefExpr(Res))

799 if (DRE->getDecl()->getKind() == Decl::EnumConstant)

800 IsEnum = true;

802 return Info.setEnum(Eval.Val.getInt().getSExtValue());

803

804 return Info.setLabel(Res);

805 }

806 unsigned Size = Context.getTypeSizeInChars(T).getQuantity();

807 unsigned Type = Size;

808 if (const auto *ATy = Context.getAsArrayType(T))

809 Type = Context.getTypeSizeInChars(ATy->getElementType()).getQuantity();

810 bool IsGlobalLV = false;

813 Info.setVar(Res, IsGlobalLV, Size, Type);

814}

815

819 bool IsUnevaluatedContext) {

820

821 if (IsUnevaluatedContext)

825

827 false,

828 false,

829 nullptr,

830 true);

831

832 if (IsUnevaluatedContext)

834

836

839

840

843

845

846 if (T->isDependentType()) {

848 }

849

850

851 if (T->isFunctionType()) {

853 }

854

855

858 }

859

861}

862

865 Offset = 0;

867 Member.split(Members, ".");

868

870

871

874 FoundDecl = PT->getPointeeType()->getAsTagDecl();

875 } else {

879 FoundDecl = BaseResult.getFoundDecl();

880 }

881

882 if (!FoundDecl)

883 return true;

884

885 for (StringRef NextMember : Members) {

886 const RecordType *RT = nullptr;

887 if (VarDecl *VD = dyn_cast(FoundDecl))

888 RT = VD->getType()->getAsCanonical();

889 else if (TypedefNameDecl *TD = dyn_cast(FoundDecl)) {

891

892 QualType QT = TD->getUnderlyingType();

896 } else if (TypeDecl *TD = dyn_cast(FoundDecl))

899 else if (FieldDecl *TD = dyn_cast(FoundDecl))

900 RT = TD->getType()->getAsCanonical();

901 if (!RT)

902 return true;

903

905 diag::err_asm_incomplete_type))

906 return true;

907

910

911 RecordDecl *RD = RT->getDecl()->getDefinitionOrSelf();

913 return true;

914

916 return true;

918

919

920 FieldDecl *FD = dyn_cast(FoundDecl);

921 if (!FD)

922 return true;

923

928 }

929

930 return false;

931}

932

936

938 if (T->isDependentType()) {

940 NameInfo.setLoc(AsmLoc);

945 nullptr, NameInfo, nullptr);

946 }

947

948 auto *RD = T->getAsRecordDecl();

949

950 if (!RD)

952

955

958

959

961 if (!FD)

962 FD = dyn_cast(FieldResult.getFoundDecl());

963 if (!FD)

965

966

969 SourceLocation(), nullptr, FieldResult, nullptr, nullptr);

970

972}

973

976 StringRef AsmString,

977 unsigned NumOutputs, unsigned NumInputs,

982 bool IsSimple = (NumOutputs != 0 || NumInputs != 0);

984

985 bool InvalidOperand = false;

986 for (uint64_t I = 0; I < NumOutputs + NumInputs; ++I) {

987 Expr *E = Exprs[I];

989 InvalidOperand = true;

991 << E->getType() << (I < NumOutputs)

994 InvalidOperand = true;

996 Diag(E->getBeginLoc(), diag::err_ms_asm_bitfield_unsupported)

999 }

1000 }

1001 if (InvalidOperand)

1003

1006 true, AsmToks, NumOutputs, NumInputs,

1007 Constraints, Exprs, AsmString,

1008 Clobbers, EndLoc);

1009 return NS;

1010}

1011

1014 bool AlwaysCreate) {

1016 Location);

1017

1019

1021 } else {

1022

1023 std::string InternalName;

1024 llvm::raw_string_ostream OS(InternalName);

1025

1026

1027

1028

1029

1030 OS << "__MSASMLABEL_.${:uid}__";

1031 for (char C : ExternalLabelName) {

1032 OS << C;

1033

1034 if (C == '$')

1035 OS << '$';

1036 }

1038 }

1039 if (AlwaysCreate) {

1040

1041

1042

1044 }

1045

1047

1048 return Label;

1049}

Defines the clang::Expr interface and subclasses for C++ expressions.

llvm::MachO::Target Target

Defines the clang::Preprocessor interface.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

static bool isOperandMentioned(unsigned OpNo, ArrayRef< GCCAsmStmt::AsmStringPiece > AsmStrPieces)

isOperandMentioned - Return true if the specified operand # is mentioned anywhere in the decomposed a...

Definition SemaStmtAsm.cpp:109

static SourceLocation getClobberConflictLocation(MultiExprArg Exprs, Expr **Constraints, Expr **Clobbers, int NumClobbers, unsigned NumLabels, const TargetInfo &Target, ASTContext &Cont)

Definition SemaStmtAsm.cpp:207

static bool CheckAsmLValue(Expr *E, Sema &S)

CheckAsmLValue - GNU C has an extremely ugly extension whereby they silently ignore "noop" casts in p...

Definition SemaStmtAsm.cpp:85

static StringRef extractRegisterName(const Expr *Expression, const TargetInfo &Target)

Definition SemaStmtAsm.cpp:188

static bool CheckNakedParmReference(Expr *E, Sema &S)

Definition SemaStmtAsm.cpp:124

static bool checkExprMemoryConstraintCompat(Sema &S, Expr *E, TargetInfo::ConstraintInfo &Info, bool is_input_expr)

Returns true if given expression is not compatible with inline assembly's memory constraint; false ot...

Definition SemaStmtAsm.cpp:157

static void removeLValueToRValueCast(Expr *E)

Remove the upper-level LValueToRValue cast from an expression.

Definition SemaStmtAsm.cpp:32

static void emitAndFixInvalidAsmCastLValue(const Expr *LVal, Expr *BadArgument, Sema &S)

Emit a warning about usage of "noop"-like casts for lvalues (GNU extension) and fix the argument with...

Definition SemaStmtAsm.cpp:71

Defines the clang::TypeLoc interface and its subclasses.

APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...

bool toIntegralConstant(APSInt &Result, QualType SrcTy, const ASTContext &Ctx) const

Try to convert this value to an integral constant.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

uint64_t getFieldOffset(unsigned FieldNo) const

getFieldOffset - Get the offset of the given field index, in bits.

Attr - This represents one attribute.

static CXXDependentScopeMemberExpr * Create(const ASTContext &Ctx, Expr *Base, QualType BaseType, bool IsArrow, SourceLocation OperatorLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs)

Represents a C++ nested-name-specifier or a global scope specifier.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

SourceLocation getBegin() const

CharUnits - This is an opaque type for sizes expressed in character units.

ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...

void SetResult(APValue Value, const ASTContext &Context)

static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)

A reference to a declared variable, function, enum, etc.

void markUsed(ASTContext &C)

Mark the declaration used, in the sense of odr-use.

SourceLocation getLocation() const

void setLocation(SourceLocation L)

This represents one expression.

Expr * IgnoreParenNoopCasts(const ASTContext &Ctx) LLVM_READONLY

Skip past any parentheses and casts which do not change the value (including ptr->int casts of the sa...

isModifiableLvalueResult isModifiableLvalue(ASTContext &Ctx, SourceLocation *Loc=nullptr) const

isModifiableLvalue - C99 6.3.2.1: an lvalue that does not have array type, does not have an incomplet...

bool isValueDependent() const

Determines whether the value of this expression depends on.

ExprValueKind getValueKind() const

getValueKind - The value kind that this expression produces.

bool refersToVectorElement() const

Returns whether this expression refers to a vector element.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

bool EvaluateAsLValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsLValue - Evaluate an expression to see if we can fold it to an lvalue with link time known ...

bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const

isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

FieldDecl * getSourceBitField()

If this expression refers to a bit-field, retrieve the declaration of that bit-field.

bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const

EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...

void setValueKind(ExprValueKind Cat)

setValueKind - Set the value kind produced by this expression.

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

bool refersToBitField() const

Returns true if this expression is a gl-value that potentially refers to a bit-field.

bool refersToGlobalRegisterVar() const

Returns whether this expression refers to a global register variable.

ExprDependence getDependence() const

Represents a member of a struct/union/class.

unsigned getFieldIndex() const

Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

Represents a function declaration or definition.

AsmStringPiece - this is part of a decomposed asm string specification (for use with the AnalyzeAsmSt...

const std::string & getString() const

unsigned getOperandNo() const

CharSourceRange getRange() const

char getModifier() const

getModifier - Get the modifier for this operand, if present.

This represents a GCC inline-assembly statement extension.

static std::string ExtractStringFromGCCAsmStmtComponent(const Expr *E)

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

Represents the declaration of a label.

void setMSAsmLabel(StringRef Name)

void setMSAsmLabelResolved()

bool isMSAsmLabel() const

Represents the results of name lookup.

NamedDecl * getFoundDecl() const

Fetch the unique decl found by this lookup.

bool isSingleResult() const

Determines if this names a single result which is not an unresolved value using decl.

This represents a Microsoft inline-assembly statement extension.

This represents a decl that may have a name.

A C++ nested-name-specifier augmented with source location information.

PointerType - C99 6.7.5.1 - Pointer Declarators.

A (possibly-)qualified type.

Represents a struct/union/class.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

Sema - This implements semantic analysis and AST building for C.

QualType getCurrentThisType()

Try to retrieve the type of the 'this' pointer.

Scope * getCurScope() const

Retrieve the parser's current scope.

ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)

@ LookupOrdinaryName

Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....

@ LookupMemberName

Member name lookup, which finds the names of class/struct/union members.

StmtResult ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef< Token > AsmToks, StringRef AsmString, unsigned NumOutputs, unsigned NumInputs, ArrayRef< StringRef > Constraints, ArrayRef< StringRef > Clobbers, ArrayRef< Expr * > Exprs, SourceLocation EndLoc)

Definition SemaStmtAsm.cpp:974

void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)

ExprResult ActOnIdExpression(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool HasTrailingLParen, bool IsAddressOfOperand, CorrectionCandidateCallback *CCC=nullptr, bool IsInlineAsmIdentifier=false, Token *KeywordReplacement=nullptr)

void setFunctionHasBranchIntoScope()

ExprResult LookupInlineAsmIdentifier(CXXScopeSpec &SS, SourceLocation TemplateKWLoc, UnqualifiedId &Id, bool IsUnevaluatedContext)

Definition SemaStmtAsm.cpp:816

void CleanupVarDeclMarking()

ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)

ASTContext & getASTContext() const

void PopExpressionEvaluationContext()

ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)

ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.

const LangOptions & getLangOpts() const

bool RequireCompleteExprType(Expr *E, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type of the given expression is complete.

bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)

If the given type contains an unexpanded parameter pack, diagnose the error.

const LangOptions & LangOpts

void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)

Perform marking for a reference to an arbitrary declaration.

DeclContext * getCurLexicalContext() const

bool EvaluateAsString(Expr *Message, APValue &Result, ASTContext &Ctx, StringEvaluationContext EvalContext, bool ErrorOnInvalidMessage)

SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

void FillInlineAsmIdentifierInfo(Expr *Res, llvm::InlineAsmIdentifierInfo &Info)

Definition SemaStmtAsm.cpp:790

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

bool LookupInlineAsmField(StringRef Base, StringRef Member, unsigned &Offset, SourceLocation AsmLoc)

Definition SemaStmtAsm.cpp:863

LabelDecl * LookupOrCreateLabel(IdentifierInfo *II, SourceLocation IdentLoc, SourceLocation GnuLabelLoc=SourceLocation())

LookupOrCreateLabel - Do a name lookup of a label with the specified name.

ExprResult LookupInlineAsmVarDeclField(Expr *RefExpr, StringRef Member, SourceLocation AsmLoc)

Definition SemaStmtAsm.cpp:934

void setFunctionHasBranchProtectedScope()

@ UnevaluatedAbstract

The current expression occurs within an unevaluated operand that unconditionally permits abstract ref...

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)

Perform qualified name lookup into a given context.

void DiscardCleanupsInEvaluationContext()

LabelDecl * GetOrCreateMSAsmLabel(StringRef ExternalLabelName, SourceLocation Location, bool AlwaysCreate)

Definition SemaStmtAsm.cpp:1012

SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD=nullptr)

ExprResult ActOnGCCAsmStmtString(Expr *Stm, bool ForAsmLabel)

Definition SemaStmtAsm.cpp:238

bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)

Perform unqualified name lookup starting from a given scope.

StmtResult ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple, bool IsVolatile, unsigned NumOutputs, unsigned NumInputs, IdentifierInfo **Names, MultiExprArg Constraints, MultiExprArg Exprs, Expr *AsmString, MultiExprArg Clobbers, unsigned NumLabels, SourceLocation RParenLoc)

Definition SemaStmtAsm.cpp:269

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

Stmt - This represents one statement.

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

Exposes information about the current target.

Represents a declaration of a type.

The base class of the type hierarchy.

bool isStructureType() const

bool isBooleanType() const

bool isPointerType() const

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isBitIntType() const

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

bool isMemberPointerType() const

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

bool isRealFloatingType() const

Floating point categories.

const T * getAsCanonical() const

If this type is canonically the specified type, return its canonical type cast to that specified type...

const T * getAs() const

Member-template getAs'.

Base class for declarations which introduce a typedef-name.

Represents a C++ unqualified-id that has been parsed.

Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...

Represents a variable declaration or definition.

Defines the clang::TargetInfo interface.

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

MutableArrayRef< Expr * > MultiExprArg

@ Result

The result type of a method or function.

const FunctionProtoType * T

ActionResult< CXXBaseSpecifier * > BaseResult

CastKind

CastKind - The kind of operation required for a conversion.

ActionResult< Expr * > ExprResult

ActionResult< Stmt * > StmtResult

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

void setLoc(SourceLocation L)

setLoc - Sets the main location of the declaration name.

void setName(DeclarationName N)

setName - Sets the embedded declaration name.

EvalResult is a struct with detailed info about an evaluated expression.

APValue Val

Val - This is the value the expression can be folded to.

bool isGlobalLValue() const

Return true if the evaluated lvalue expression is global.

const std::string & getConstraintStr() const

unsigned getTiedOperand() const

bool allowsMemory() const

bool isValidAsmImmediate(const llvm::APInt &Value) const

bool requiresImmediateConstant() const

bool hasTiedOperand() const

Return true if this input operand is a matching constraint that ties it to an output operand.

bool allowsRegister() const