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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

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

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

26#include

27using namespace clang;

28using namespace sema;

29

30

33 Expr *ExprUnderCast = nullptr;

35

36 while (true) {

37 ParentsToUpdate.push_back(Parent);

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

39 Parent = ParenE->getSubExpr();

40 continue;

41 }

42

43 Expr *Child = nullptr;

45 if (ParentCast)

47 else

48 return;

49

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

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

52 ExprUnderCast = CastE->getSubExpr();

53

54 ParentCast->setSubExpr(ExprUnderCast);

55 break;

56 }

58 }

59

60

61 assert(ExprUnderCast &&

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

63 auto ValueKind = ExprUnderCast->getValueKind();

64 for (Expr *E : ParentsToUpdate)

66}

67

68

69

72 S.Diag(LVal->getBeginLoc(), diag::warn_invalid_asm_cast_lvalue)

75}

76

77

78

79

80

81

82

83

85

87 return false;

88

90 return false;

91

92

93

97

98 return false;

99 }

100

101

102 return true;

103}

104

105

106

107static bool

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

113 continue;

114

115

116

118 return true;

119 }

120 return false;

121}

122

126 return false;

127 if (Func->hasAttr())

128 return false;

129

131 WorkList.push_back(E);

132 while (WorkList.size()) {

133 Expr *E = WorkList.pop_back_val();

134 if (isa(E)) {

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

137 return true;

138 }

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

140 if (isa(DRE->getDecl())) {

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

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

143 return true;

144 }

145 }

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

148 WorkList.push_back(E);

149 }

150 }

151 return false;

152}

153

154

155

158 bool is_input_expr) {

159 enum {

160 ExprBitfield = 0,

161 ExprVectorElt,

162 ExprGlobalRegVar,

163 ExprSafeType

164 } EType = ExprSafeType;

165

166

167

169 EType = ExprBitfield;

171 EType = ExprVectorElt;

173 EType = ExprGlobalRegVar;

174

175 if (EType != ExprSafeType) {

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

179 return true;

180 }

181

182 return false;

183}

184

185

186

191

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

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

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

197 }

198 }

199 return "";

200}

201

202

203

204

208 unsigned NumLabels,

210 llvm::StringSet<> InOutVars;

211

212

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

214 StringRef Constraint = Constraints[i]->getString();

215 StringRef InOutReg = Target.getConstraintRegister(

217 if (InOutReg != "")

218 InOutVars.insert(InOutReg);

219 }

220

221

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

223 StringRef Clobber = Clobbers[i]->getString();

224

225

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

227 continue;

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

229

230 if (InOutVars.count(Clobber))

232 }

234}

235

237 bool IsVolatile, unsigned NumOutputs,

241 unsigned NumLabels,

243 unsigned NumClobbers = clobbers.size();

245 reinterpret_cast<StringLiteral**>(constraints.data());

246 StringLiteral *AsmString = cast(asmString);

248

250

251

253

255 llvm::StringMap FeatureMap;

257

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

260 assert(Literal->isOrdinary());

261

262 StringRef OutputName;

263 if (Names[i])

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

265

270 diag::err_asm_invalid_output_constraint)

274 NumInputs, Names, Constraints, Exprs.data(), AsmString,

275 NumClobbers, Clobbers, NumLabels, RParenLoc);

276 }

277

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

282

283

284 Expr *OutputExpr = Exprs[i];

285

286

289

290

294

295

296

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

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

302

303 OutputConstraintInfos.push_back(Info);

304

305

307 continue;

308

311 switch (IsLV) {

313

314 break;

316

317 break;

321

322 break;

323 }

327 diag::err_dereference_incomplete_type))

329 [[fallthrough]];

330 default:

332 diag::err_asm_invalid_lvalue_in_output)

334 }

335

338 FeatureMap, Literal->getString(), Size)) {

343 NumInputs, Names, Constraints, Exprs.data(), AsmString,

344 NumClobbers, Clobbers, NumLabels, RParenLoc);

345 }

346 }

347

349

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

352 assert(Literal->isOrdinary());

353

354 StringRef InputName;

355 if (Names[i])

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

357

360 Info)) {

361 targetDiag(Literal->getBeginLoc(), diag::err_asm_invalid_input_constraint)

365 NumInputs, Names, Constraints, Exprs.data(), AsmString,

366 NumClobbers, Clobbers, NumLabels, RParenLoc);

367 }

368

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

373

374 Expr *InputExpr = Exprs[i];

375

378 diag::err_asm_pmf_through_constraint_not_permitted)

380

381

384

385

389

390

394 diag::err_asm_invalid_lvalue_in_input)

397 } else {

399 if (Result.isInvalid())

401

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

403

408

409

410 llvm::APSInt IntResult;

416 diag::err_invalid_asm_value_for_constraint)

419 }

420 }

421 }

422 }

423

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

430 }

431 }

432

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

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

438

439 InputConstraintInfos.push_back(Info);

440

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

443 continue;

444

447 diag::err_dereference_incomplete_type))

449

452 Literal->getString(), Size))

454 diag::err_asm_invalid_input_size)

456 }

457

458 std::optional UnwindClobberLoc;

459

460

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

463 assert(Literal->isOrdinary());

464

465 StringRef Clobber = Literal->getString();

466

468 targetDiag(Literal->getBeginLoc(), diag::err_asm_unknown_register_name)

469 << Clobber;

472 NumInputs, Names, Constraints, Exprs.data(), AsmString,

473 NumClobbers, Clobbers, NumLabels, RParenLoc);

474 }

475

476 if (Clobber == "unwind") {

477 UnwindClobberLoc = Literal->getBeginLoc();

478 }

479 }

480

481

482 if (UnwindClobberLoc && NumLabels > 0) {

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

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

486 Names, Constraints, Exprs.data(), AsmString, NumClobbers,

487 Clobbers, NumLabels, RParenLoc);

488 }

489

492 NumInputs, Names, Constraints, Exprs.data(),

493 AsmString, NumClobbers, Clobbers, NumLabels,

494 RParenLoc);

495

496

498 unsigned DiagOffs;

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

502 return NS;

503 }

504

505

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

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

509

510

511 unsigned ConstraintIdx = Piece.getOperandNo();

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

513

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

515 continue;

516

517

518 if (ConstraintIdx >= NumOperands) {

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

520

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

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

523 ConstraintIdx = I;

524 break;

525 }

526

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

528 " AnalyzeAsmString");

529 }

530

531

532 StringLiteral *Literal = Constraints[ConstraintIdx];

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

535 continue;

536

538 std::string SuggestedModifier;

540 Literal->getString(), Piece.getModifier(), Size,

541 SuggestedModifier)) {

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

543 diag::warn_asm_mismatched_size_modifier);

544

545 if (!SuggestedModifier.empty()) {

547 diag::note_asm_missing_constraint_modifier)

548 << SuggestedModifier;

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

551 }

552 }

553 }

554

555

556 unsigned NumAlternatives = ~0U;

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

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

561 if (NumAlternatives == ~0U) {

562 NumAlternatives = AltCount;

563 } else if (NumAlternatives != AltCount) {

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

565 diag::err_asm_unexpected_constraint_alternatives)

566 << NumAlternatives << AltCount;

567 return NS;

568 }

569 }

571 ~0U);

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

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

576 if (NumAlternatives == ~0U) {

577 NumAlternatives = AltCount;

578 } else if (NumAlternatives != AltCount) {

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

580 diag::err_asm_unexpected_constraint_alternatives)

581 << NumAlternatives << AltCount;

582 return NS;

583 }

584

585

586

587

589

591 unsigned InputOpNo = i+NumOutputs;

592 Expr *OutputExpr = Exprs[TiedTo];

593 Expr *InputExpr = Exprs[InputOpNo];

594

595

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

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

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

599 diag::err_asm_input_duplicate_match)

600 << TiedTo;

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

602 diag::note_asm_input_duplicate_first)

603 << TiedTo;

604 return NS;

605 }

606 InputMatchedToOutput[TiedTo] = i;

607

609 continue;

610

614 continue;

615

616

617

618 enum AsmDomain {

619 AD_Int, AD_FP, AD_Other

620 } InputDomain, OutputDomain;

621

623 InputDomain = AD_Int;

625 InputDomain = AD_FP;

626 else

627 InputDomain = AD_Other;

628

630 OutputDomain = AD_Int;

632 OutputDomain = AD_FP;

633 else

634 OutputDomain = AD_Other;

635

636

637

638

639

640

641

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

645 InputDomain != AD_Other)

646 continue;

647

648

649

650

651 bool SmallerValueMentioned = false;

652

653

654

656

657

658

659 SmallerValueMentioned |= InSize < OutSize;

660 }

662

663

664 SmallerValueMentioned |= OutSize < InSize;

665 }

666

667

668

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

670

671

672

673

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

675 OutputConstraintInfos[TiedTo].allowsRegister()) {

676

677

678

682 return NS;

683 }

684

685 continue;

686 }

687

688

689

690

691

692 if (InputDomain == AD_Int && OutputDomain == AD_Int &&

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

698 Exprs[InputOpNo] = InputExpr;

699 NS->setInputExpr(i, InputExpr);

700 continue;

701 }

702

706 return NS;

707 }

708

709

712 NumLabels,

714 if (ConstraintLoc.isValid())

715 targetDiag(ConstraintLoc, diag::error_inoutput_conflict_with_clobber);

716

717

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

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

721 if (Names[i])

722 NamedOperandList.emplace_back(

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

724

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

726

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

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

730 return LHS.first == RHS.first;

731 });

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

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

734 diag::error_duplicate_asm_operand_name)

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

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

739 }

740 if (NS->isAsmGoto())

742

745 return NS;

746}

747

749 llvm::InlineAsmIdentifierInfo &Info) {

753 return Info.setLabel(Res);

755 bool IsEnum = isaclang::EnumType(T);

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

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

758 IsEnum = true;

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

761

762 return Info.setLabel(Res);

763 }

765 unsigned Type = Size;

768 bool IsGlobalLV = false;

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

772}

773

777 bool IsUnevaluatedContext) {

778

779 if (IsUnevaluatedContext)

783

785 false,

786 false,

787 nullptr,

788 true);

789

790 if (IsUnevaluatedContext)

792

794

797

798

801

803

806 }

807

808

811 }

812

813

816 }

817

819}

820

823 Offset = 0;

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

826

828

829

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

833 } else {

837 FoundDecl = BaseResult.getFoundDecl();

838 }

839

840 if (!FoundDecl)

841 return true;

842

843 for (StringRef NextMember : Members) {

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

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

849

850 QualType QT = TD->getUnderlyingType();

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

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

858 if (!RT)

859 return true;

860

862 diag::err_asm_incomplete_type))

863 return true;

864

867

869 return true;

870

872 return true;

874

875

876 FieldDecl *FD = dyn_cast(FoundDecl);

877 if (!FD)

878 return true;

879

884 }

885

886 return false;

887}

888

892

896 NameInfo.setLoc(AsmLoc);

901 nullptr, NameInfo, nullptr);

902 }

903

905

906 if (!RT)

908

911

914

915

917 if (!FD)

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

919 if (!FD)

921

922

925 SourceLocation(), nullptr, FieldResult, nullptr, nullptr);

926

928}

929

932 StringRef AsmString,

933 unsigned NumOutputs, unsigned NumInputs,

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

940

941 bool InvalidOperand = false;

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

943 Expr *E = Exprs[I];

945 InvalidOperand = true;

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

950 InvalidOperand = true;

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

955 }

956 }

957 if (InvalidOperand)

959

962 true, AsmToks, NumOutputs, NumInputs,

963 Constraints, Exprs, AsmString,

964 Clobbers, EndLoc);

965 return NS;

966}

967

970 bool AlwaysCreate) {

972 Location);

973

974 if (Label->isMSAsmLabel()) {

975

977 } else {

978

979 std::string InternalName;

980 llvm::raw_string_ostream OS(InternalName);

981

982

983

984

985

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

987 for (char C : ExternalLabelName) {

989

990 if (C == '$')

991 OS << '$';

992 }

993 Label->setMSAsmLabel(OS.str());

994 }

995 if (AlwaysCreate) {

996

997

998

999 Label->setMSAsmLabelResolved();

1000 }

1001

1002 Label->setLocation(Location);

1003

1005}

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

llvm::MachO::Target Target

Defines the clang::Preprocessor interface.

static std::string getName(const CallEvent &Call)

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

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

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

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

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

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

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

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

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

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...

static void removeLValueToRValueCast(Expr *E)

Remove the upper-level LValueToRValue cast from an expression.

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...

Defines the clang::TypeLoc interface and its subclasses.

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 ...

const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const

Get or compute information about the layout of the specified record (struct/union/class) D,...

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const

getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth,...

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

const TargetInfo & getTargetInfo() const

CharUnits toCharUnitsFromBits(int64_t BitSize) const

Convert a size in bits to a size in characters.

void getFunctionFeatureMap(llvm::StringMap< bool > &FeatureMap, const FunctionDecl *) const

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.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

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

SourceLocation getLocation() const

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.

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.

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

StringRef getName() const

Return the actual identifier string.

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

Represents the declaration of a label.

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.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

RecordDecl * getDecl() const

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

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)

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)

void CleanupVarDeclMarking()

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

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.

const LangOptions & LangOpts

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

Perform marking for a reference to an arbitrary declaration.

DeclContext * getCurLexicalContext() const

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)

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

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

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)

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)

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

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)

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

StringLiteral - This represents a string literal expression, e.g.

SourceLocation getBeginLoc() const LLVM_READONLY

StringRef getString() const

Exposes information about the current target.

bool validateInputConstraint(MutableArrayRef< ConstraintInfo > OutputConstraints, ConstraintInfo &info) const

virtual bool validateOutputSize(const llvm::StringMap< bool > &FeatureMap, StringRef, unsigned) const

virtual bool validateInputSize(const llvm::StringMap< bool > &FeatureMap, StringRef, unsigned) const

virtual bool validateConstraintModifier(StringRef, char, unsigned, std::string &) const

bool validateOutputConstraint(ConstraintInfo &Info) const

bool isValidClobber(StringRef Name) const

Returns whether the passed in string is a valid clobber in an inline asm statement.

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 isFunctionType() const

bool isRealFloatingType() const

Floating point categories.

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.

StorageClass getStorageClass() const

Returns the storage class as written in the source.

Defines the clang::TargetInfo interface.

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

@ Result

The result type of a method or function.

ActionResult< Expr * > ExprResult

CastKind

CastKind - The kind of operation required for a conversion.

const FunctionProtoType * T

ActionResult< CXXBaseSpecifier * > BaseResult

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

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