diff options
Diffstat (limited to 'contrib/llvm/tools/clang/include/clang/AST/Stmt.h')
-rw-r--r-- | contrib/llvm/tools/clang/include/clang/AST/Stmt.h | 287 |
1 files changed, 255 insertions, 32 deletions
diff --git a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h index cf8fc24..74c9ec2 100644 --- a/contrib/llvm/tools/clang/include/clang/AST/Stmt.h +++ b/contrib/llvm/tools/clang/include/clang/AST/Stmt.h @@ -16,10 +16,12 @@ #include "clang/AST/DeclGroup.h" #include "clang/AST/StmtIterator.h" +#include "clang/Basic/CapturedStmt.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include <string> @@ -31,6 +33,7 @@ namespace llvm { namespace clang { class ASTContext; class Attr; + class CapturedDecl; class Decl; class Expr; class IdentifierInfo; @@ -39,6 +42,7 @@ namespace clang { class PrinterHelper; struct PrintingPolicy; class QualType; + class RecordDecl; class SourceManager; class StringLiteral; class SwitchStmt; @@ -1384,7 +1388,6 @@ protected: unsigned NumInputs; unsigned NumClobbers; - IdentifierInfo **Names; Stmt **Exprs; AsmStmt(StmtClass SC, SourceLocation asmloc, bool issimple, bool isvolatile, @@ -1392,10 +1395,12 @@ protected: Stmt (SC), AsmLoc(asmloc), IsSimple(issimple), IsVolatile(isvolatile), NumOutputs(numoutputs), NumInputs(numinputs), NumClobbers(numclobbers) { } + friend class ASTStmtReader; + public: /// \brief Build an empty inline-assembly statement. explicit AsmStmt(StmtClass SC, EmptyShell Empty) : - Stmt(SC, Empty), Names(0), Exprs(0) { } + Stmt(SC, Empty), Exprs(0) { } SourceLocation getAsmLoc() const { return AsmLoc; } void setAsmLoc(SourceLocation L) { AsmLoc = L; } @@ -1418,17 +1423,6 @@ public: unsigned getNumOutputs() const { return NumOutputs; } - IdentifierInfo *getOutputIdentifier(unsigned i) const { - return Names[i]; - } - - StringRef getOutputName(unsigned i) const { - if (IdentifierInfo *II = getOutputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - /// getOutputConstraint - Return the constraint string for the specified /// output operand. All output constraints are known to be non-empty (either /// '=' or '+'). @@ -1451,17 +1445,6 @@ public: unsigned getNumInputs() const { return NumInputs; } - IdentifierInfo *getInputIdentifier(unsigned i) const { - return Names[i + NumOutputs]; - } - - StringRef getInputName(unsigned i) const { - if (IdentifierInfo *II = getInputIdentifier(i)) - return II->getName(); - - return StringRef(); - } - /// getInputConstraint - Return the specified input constraint. Unlike output /// constraints, these can be empty. StringRef getInputConstraint(unsigned i) const; @@ -1532,6 +1515,9 @@ class GCCAsmStmt : public AsmStmt { // FIXME: If we wanted to, we could allocate all of these in one big array. StringLiteral **Constraints; StringLiteral **Clobbers; + IdentifierInfo **Names; + + friend class ASTStmtReader; public: GCCAsmStmt(ASTContext &C, SourceLocation asmloc, bool issimple, @@ -1542,7 +1528,7 @@ public: /// \brief Build an empty inline-assembly statement. explicit GCCAsmStmt(EmptyShell Empty) : AsmStmt(GCCAsmStmtClass, Empty), - Constraints(0), Clobbers(0) { } + Constraints(0), Clobbers(0), Names(0) { } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } @@ -1607,6 +1593,17 @@ public: //===--- Output operands ---===// + IdentifierInfo *getOutputIdentifier(unsigned i) const { + return Names[i]; + } + + StringRef getOutputName(unsigned i) const { + if (IdentifierInfo *II = getOutputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + StringRef getOutputConstraint(unsigned i) const; const StringLiteral *getOutputConstraintLiteral(unsigned i) const { @@ -1624,6 +1621,17 @@ public: //===--- Input operands ---===// + IdentifierInfo *getInputIdentifier(unsigned i) const { + return Names[i + NumOutputs]; + } + + StringRef getInputName(unsigned i) const { + if (IdentifierInfo *II = getInputIdentifier(i)) + return II->getName(); + + return StringRef(); + } + StringRef getInputConstraint(unsigned i) const; const StringLiteral *getInputConstraintLiteral(unsigned i) const { @@ -1640,6 +1648,7 @@ public: return const_cast<GCCAsmStmt*>(this)->getInputExpr(i); } +private: void setOutputsAndInputsAndClobbers(ASTContext &C, IdentifierInfo **Names, StringLiteral **Constraints, @@ -1648,6 +1657,7 @@ public: unsigned NumInputs, StringLiteral **Clobbers, unsigned NumClobbers); +public: //===--- Other ---===// @@ -1674,7 +1684,7 @@ public: /// class MSAsmStmt : public AsmStmt { SourceLocation LBraceLoc, EndLoc; - std::string AsmStr; + StringRef AsmStr; unsigned NumAsmToks; @@ -1682,11 +1692,13 @@ class MSAsmStmt : public AsmStmt { StringRef *Constraints; StringRef *Clobbers; + friend class ASTStmtReader; + public: MSAsmStmt(ASTContext &C, SourceLocation asmloc, SourceLocation lbraceloc, bool issimple, bool isvolatile, ArrayRef<Token> asmtoks, unsigned numoutputs, unsigned numinputs, - ArrayRef<IdentifierInfo*> names, ArrayRef<StringRef> constraints, + ArrayRef<StringRef> constraints, ArrayRef<Expr*> exprs, StringRef asmstr, ArrayRef<StringRef> clobbers, SourceLocation endloc); @@ -1705,10 +1717,7 @@ public: Token *getAsmToks() { return AsmToks; } //===--- Asm String Analysis ---===// - - const std::string *getAsmString() const { return &AsmStr; } - std::string *getAsmString() { return &AsmStr; } - void setAsmString(StringRef &E) { AsmStr = E.str(); } + StringRef getAsmString() const { return AsmStr; } /// Assemble final IR asm string. std::string generateAsmString(ASTContext &C) const; @@ -1716,6 +1725,7 @@ public: //===--- Output operands ---===// StringRef getOutputConstraint(unsigned i) const { + assert(i < NumOutputs); return Constraints[i]; } @@ -1728,6 +1738,7 @@ public: //===--- Input operands ---===// StringRef getInputConstraint(unsigned i) const { + assert(i < NumInputs); return Constraints[i + NumOutputs]; } @@ -1740,7 +1751,27 @@ public: //===--- Other ---===// - StringRef getClobber(unsigned i) const { return Clobbers[i]; } + ArrayRef<StringRef> getAllConstraints() const { + return ArrayRef<StringRef>(Constraints, NumInputs + NumOutputs); + } + ArrayRef<StringRef> getClobbers() const { + return ArrayRef<StringRef>(Clobbers, NumClobbers); + } + ArrayRef<Expr*> getAllExprs() const { + return ArrayRef<Expr*>(reinterpret_cast<Expr**>(Exprs), + NumInputs + NumOutputs); + } + + StringRef getClobber(unsigned i) const { return getClobbers()[i]; } + +private: + void initialize(ASTContext &C, + StringRef AsmString, + ArrayRef<Token> AsmToks, + ArrayRef<StringRef> Constraints, + ArrayRef<Expr*> Exprs, + ArrayRef<StringRef> Clobbers); +public: SourceLocation getLocStart() const LLVM_READONLY { return AsmLoc; } SourceLocation getLocEnd() const LLVM_READONLY { return EndLoc; } @@ -1882,6 +1913,198 @@ public: } }; +/// \brief This captures a statement into a function. For example, the following +/// pragma annotated compound statement can be represented as a CapturedStmt, +/// and this compound statement is the body of an anonymous outlined function. +/// @code +/// #pragma omp parallel +/// { +/// compute(); +/// } +/// @endcode +class CapturedStmt : public Stmt { +public: + /// \brief The different capture forms: by 'this' or by reference, etc. + enum VariableCaptureKind { + VCK_This, + VCK_ByRef + }; + + /// \brief Describes the capture of either a variable or 'this'. + class Capture { + llvm::PointerIntPair<VarDecl *, 1, VariableCaptureKind> VarAndKind; + SourceLocation Loc; + + public: + /// \brief Create a new capture. + /// + /// \param Loc The source location associated with this capture. + /// + /// \param Kind The kind of capture (this, ByRef, ...). + /// + /// \param Var The variable being captured, or null if capturing this. + /// + Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0) + : VarAndKind(Var, Kind), Loc(Loc) { + switch (Kind) { + case VCK_This: + assert(Var == 0 && "'this' capture cannot have a variable!"); + break; + case VCK_ByRef: + assert(Var && "capturing by reference must have a variable!"); + break; + } + } + + /// \brief Determine the kind of capture. + VariableCaptureKind getCaptureKind() const { return VarAndKind.getInt(); } + + /// \brief Retrieve the source location at which the variable or 'this' was + /// first used. + SourceLocation getLocation() const { return Loc; } + + /// \brief Determine whether this capture handles the C++ 'this' pointer. + bool capturesThis() const { return getCaptureKind() == VCK_This; } + + /// \brief Determine whether this capture handles a variable. + bool capturesVariable() const { return getCaptureKind() != VCK_This; } + + /// \brief Retrieve the declaration of the variable being captured. + /// + /// This operation is only valid if this capture does not capture 'this'. + VarDecl *getCapturedVar() const { + assert(!capturesThis() && "No variable available for 'this' capture"); + return VarAndKind.getPointer(); + } + friend class ASTStmtReader; + }; + +private: + /// \brief The number of variable captured, including 'this'. + unsigned NumCaptures; + + /// \brief The pointer part is the implicit the outlined function and the + /// int part is the captured region kind, 'CR_Default' etc. + llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind; + + /// \brief The record for captured variables, a RecordDecl or CXXRecordDecl. + RecordDecl *TheRecordDecl; + + /// \brief Construct a captured statement. + CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures, + ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD); + + /// \brief Construct an empty captured statement. + CapturedStmt(EmptyShell Empty, unsigned NumCaptures); + + Stmt **getStoredStmts() const { + return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1); + } + + Capture *getStoredCaptures() const; + + void setCapturedStmt(Stmt *S) { getStoredStmts()[NumCaptures] = S; } + +public: + static CapturedStmt *Create(ASTContext &Context, Stmt *S, + CapturedRegionKind Kind, + ArrayRef<Capture> Captures, + ArrayRef<Expr *> CaptureInits, + CapturedDecl *CD, RecordDecl *RD); + + static CapturedStmt *CreateDeserialized(ASTContext &Context, + unsigned NumCaptures); + + /// \brief Retrieve the statement being captured. + Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; } + const Stmt *getCapturedStmt() const { + return const_cast<CapturedStmt *>(this)->getCapturedStmt(); + } + + /// \brief Retrieve the outlined function declaration. + CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); } + const CapturedDecl *getCapturedDecl() const { + return const_cast<CapturedStmt *>(this)->getCapturedDecl(); + } + + /// \brief Set the outlined function declaration. + void setCapturedDecl(CapturedDecl *D) { + assert(D && "null CapturedDecl"); + CapDeclAndKind.setPointer(D); + } + + /// \brief Retrieve the captured region kind. + CapturedRegionKind getCapturedRegionKind() const { + return CapDeclAndKind.getInt(); + } + + /// \brief Set the captured region kind. + void setCapturedRegionKind(CapturedRegionKind Kind) { + CapDeclAndKind.setInt(Kind); + } + + /// \brief Retrieve the record declaration for captured variables. + const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; } + + /// \brief Set the record declaration for captured variables. + void setCapturedRecordDecl(RecordDecl *D) { + assert(D && "null RecordDecl"); + TheRecordDecl = D; + } + + /// \brief True if this variable has been captured. + bool capturesVariable(const VarDecl *Var) const; + + /// \brief An iterator that walks over the captures. + typedef Capture *capture_iterator; + typedef const Capture *const_capture_iterator; + + /// \brief Retrieve an iterator pointing to the first capture. + capture_iterator capture_begin() { return getStoredCaptures(); } + const_capture_iterator capture_begin() const { return getStoredCaptures(); } + + /// \brief Retrieve an iterator pointing past the end of the sequence of + /// captures. + capture_iterator capture_end() const { + return getStoredCaptures() + NumCaptures; + } + + /// \brief Retrieve the number of captures, including 'this'. + unsigned capture_size() const { return NumCaptures; } + + /// \brief Iterator that walks over the capture initialization arguments. + typedef Expr **capture_init_iterator; + + /// \brief Retrieve the first initialization argument. + capture_init_iterator capture_init_begin() const { + return reinterpret_cast<Expr **>(getStoredStmts()); + } + + /// \brief Retrieve the iterator pointing one past the last initialization + /// argument. + capture_init_iterator capture_init_end() const { + return capture_init_begin() + NumCaptures; + } + + SourceLocation getLocStart() const LLVM_READONLY { + return getCapturedStmt()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getCapturedStmt()->getLocEnd(); + } + SourceRange getSourceRange() const LLVM_READONLY { + return getCapturedStmt()->getSourceRange(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CapturedStmtClass; + } + + child_range children(); + + friend class ASTStmtReader; +}; + } // end namespace clang #endif |