diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-01-15 15:39:40 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-01-15 15:39:40 +0000 |
commit | a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824 (patch) | |
tree | a6082d4d1d1e9ddaea09a6a04bb4a47da95d642d /include/clang | |
parent | bb1e3bc1e0be2b8f891db46457a8943451bf4d8b (diff) | |
download | FreeBSD-src-a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824.zip FreeBSD-src-a3fa5c7f1b5e2ba4d6ec033dc0e2376326b05824.tar.gz |
Update clang to r93512.
Diffstat (limited to 'include/clang')
46 files changed, 749 insertions, 262 deletions
diff --git a/include/clang/AST/APValue.h b/include/clang/AST/APValue.h index 94d258d..9d4bff8 100644 --- a/include/clang/AST/APValue.h +++ b/include/clang/AST/APValue.h @@ -18,6 +18,7 @@ #include "llvm/ADT/APFloat.h" namespace clang { + class CharUnits; class Expr; /// APValue - This class implements a discriminated union of [uninitialized] @@ -47,10 +48,6 @@ private: ComplexAPFloat() : Real(0.0), Imag(0.0) {} }; - struct LV { - Expr* Base; - uint64_t Offset; - }; struct Vec { APValue *Elts; unsigned NumElts; @@ -88,9 +85,11 @@ public: APValue(const APValue &RHS) : Kind(Uninitialized) { *this = RHS; } - APValue(Expr* B, uint64_t O) : Kind(Uninitialized) { + APValue(Expr* B, const CharUnits &O) : Kind(Uninitialized) { MakeLValue(); setLValue(B, O); } + APValue(Expr* B); + ~APValue() { MakeUninit(); } @@ -164,14 +163,8 @@ public: return const_cast<APValue*>(this)->getComplexFloatImag(); } - Expr* getLValueBase() const { - assert(isLValue() && "Invalid accessor"); - return ((const LV*)(const void*)Data)->Base; - } - uint64_t getLValueOffset() const { - assert(isLValue() && "Invalid accessor"); - return ((const LV*)(const void*)Data)->Offset; - } + Expr* getLValueBase() const; + CharUnits getLValueOffset() const; void setInt(const APSInt &I) { assert(isInt() && "Invalid accessor"); @@ -202,11 +195,7 @@ public: ((ComplexAPFloat*)(char*)Data)->Real = R; ((ComplexAPFloat*)(char*)Data)->Imag = I; } - void setLValue(Expr *B, uint64_t O) { - assert(isLValue() && "Invalid accessor"); - ((LV*)(char*)Data)->Base = B; - ((LV*)(char*)Data)->Offset = O; - } + void setLValue(Expr *B, const CharUnits &O); const APValue &operator=(const APValue &RHS); @@ -237,11 +226,7 @@ private: new ((void*)(char*)Data) ComplexAPFloat(); Kind = ComplexFloat; } - void MakeLValue() { - assert(isUninit() && "Bad state change"); - new ((void*)(char*)Data) LV(); - Kind = LValue; - } + void MakeLValue(); }; inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const APValue &V) { diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index bcab46d..5db8e20 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -699,8 +699,8 @@ public: ObjCProtocolDecl *rProto); /// getObjCEncodingTypeSize returns size of type for objective-c encoding - /// purpose. - int getObjCEncodingTypeSize(QualType t); + /// purpose in characters. + CharUnits getObjCEncodingTypeSize(QualType t); /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by /// Sema. id is always a (typedef for a) pointer type, a pointer to a struct. @@ -898,17 +898,18 @@ public: return getCanonicalType(T1) == getCanonicalType(T2); } - /// \brief Returns this type as a completely-unqualified array type, capturing - /// the qualifiers in Quals. This only operates on canonical types in order - /// to ensure the ArrayType doesn't itself have qualifiers. + /// \brief Returns this type as a completely-unqualified array type, + /// capturing the qualifiers in Quals. This will remove the minimal amount of + /// sugaring from the types, similar to the behavior of + /// QualType::getUnqualifiedType(). /// - /// \param T is the canonicalized QualType, which may be an ArrayType + /// \param T is the qualified type, which may be an ArrayType /// /// \param Quals will receive the full set of qualifiers that were - /// applied to the element type of the array. + /// applied to the array. /// /// \returns if this is an array type, the completely unqualified array type - /// that corresponds to it. Otherwise, returns this->getUnqualifiedType(). + /// that corresponds to it. Otherwise, returns T.getUnqualifiedType(). QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals); /// \brief Determine whether the given types are equivalent after @@ -996,7 +997,10 @@ public: const IncompleteArrayType *getAsIncompleteArrayType(QualType T) { return dyn_cast_or_null<IncompleteArrayType>(getAsArrayType(T)); } - + const DependentSizedArrayType *getAsDependentSizedArrayType(QualType T) { + return dyn_cast_or_null<DependentSizedArrayType>(getAsArrayType(T)); + } + /// getBaseElementType - Returns the innermost element type of an array type. /// For example, will return "int" for int[m][n] QualType getBaseElementType(const ArrayType *VAT); diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 2c7ab9d..03ab0f0 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -55,8 +55,6 @@ public: Cleanup, Const, Constructor, - DLLExport, - DLLImport, Deprecated, Destructor, FastCall, @@ -93,7 +91,12 @@ public: Visibility, WarnUnusedResult, Weak, - WeakImport + WeakImport, + + FIRST_TARGET_ATTRIBUTE, + DLLExport, + DLLImport, + MSP430Interrupt }; private: @@ -158,7 +161,7 @@ public: class ATTR##Attr : public Attr { \ public: \ ATTR##Attr() : Attr(ATTR) {} \ - virtual Attr *clone(ASTContext &C) const { return ::new (C) ATTR##Attr; }\ + virtual Attr *clone(ASTContext &C) const; \ static bool classof(const Attr *A) { return A->getKind() == ATTR; } \ static bool classof(const ATTR##Attr *A) { return true; } \ } @@ -174,9 +177,7 @@ public: /// getAlignment - The specified alignment in bits. unsigned getAlignment() const { return Alignment; } - virtual Attr* clone(ASTContext &C) const { - return ::new (C) PragmaPackAttr(Alignment); - } + virtual Attr* clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -203,9 +204,7 @@ public: return Alignment; } - virtual Attr* clone(ASTContext &C) const { - return ::new (C) AlignedAttr(Alignment); - } + virtual Attr* clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -221,7 +220,7 @@ public: const std::string& getAnnotation() const { return Annotation; } - virtual Attr* clone(ASTContext &C) const { return ::new (C) AnnotateAttr(Annotation); } + virtual Attr* clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -237,7 +236,7 @@ public: const std::string& getLabel() const { return Label; } - virtual Attr* clone(ASTContext &C) const { return ::new (C) AsmLabelAttr(Label); } + virtual Attr* clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -255,7 +254,7 @@ public: const std::string& getAliasee() const { return Aliasee; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) AliasAttr(Aliasee); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Alias; } @@ -269,7 +268,7 @@ public: int getPriority() const { return priority; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) ConstructorAttr(priority); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Constructor; } @@ -283,7 +282,7 @@ public: int getPriority() const { return priority; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) DestructorAttr(priority); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Destructor; } @@ -294,7 +293,7 @@ class GNUInlineAttr : public Attr { public: GNUInlineAttr() : Attr(GNUInline) {} - virtual Attr *clone(ASTContext &C) const { return ::new (C) GNUInlineAttr; } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -307,7 +306,7 @@ class IBOutletAttr : public Attr { public: IBOutletAttr() : Attr(IBOutletKind) {} - virtual Attr *clone(ASTContext &C) const { return ::new (C) IBOutletAttr; } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -329,7 +328,7 @@ public: const std::string& getName() const { return Name; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) SectionAttr(Name); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -374,7 +373,7 @@ public: return ArgNums ? std::binary_search(ArgNums, ArgNums+Size, arg) : true; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) NonNullAttr(ArgNums, Size); } + virtual Attr *clone(ASTContext &C) const; static bool classof(const Attr *A) { return A->getKind() == NonNull; } static bool classof(const NonNullAttr *A) { return true; } @@ -392,9 +391,7 @@ public: int getFormatIdx() const { return formatIdx; } int getFirstArg() const { return firstArg; } - virtual Attr *clone(ASTContext &C) const { - return ::new (C) FormatAttr(Type, formatIdx, firstArg); - } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Format; } @@ -407,9 +404,7 @@ public: FormatArgAttr(int idx) : Attr(FormatArg), formatIdx(idx) {} int getFormatIdx() const { return formatIdx; } - virtual Attr *clone(ASTContext &C) const { - return ::new (C) FormatArgAttr(formatIdx); - } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == FormatArg; } @@ -424,9 +419,7 @@ public: int getSentinel() const { return sentinel; } int getNullPos() const { return NullPos; } - virtual Attr *clone(ASTContext &C) const { - return ::new (C) SentinelAttr(sentinel, NullPos); - } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Sentinel; } @@ -449,15 +442,13 @@ public: VisibilityTypes getVisibility() const { return VisibilityType; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) VisibilityAttr(VisibilityType); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Visibility; } static bool classof(const VisibilityAttr *A) { return true; } }; -DEF_SIMPLE_ATTR(DLLImport); -DEF_SIMPLE_ATTR(DLLExport); DEF_SIMPLE_ATTR(FastCall); DEF_SIMPLE_ATTR(StdCall); DEF_SIMPLE_ATTR(CDecl); @@ -471,9 +462,7 @@ public: virtual bool isMerged() const { return false; } - virtual Attr *clone(ASTContext &C) const { - return ::new (C) OverloadableAttr; - } + virtual Attr *clone(ASTContext &C) const; static bool classof(const Attr *A) { return A->getKind() == Overloadable; } static bool classof(const OverloadableAttr *) { return true; } @@ -491,7 +480,7 @@ public: BlocksAttrTypes getType() const { return BlocksAttrType; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) BlocksAttr(BlocksAttrType); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Blocks; } @@ -508,7 +497,7 @@ public: const FunctionDecl *getFunctionDecl() const { return FD; } - virtual Attr *clone(ASTContext &C) const { return ::new (C) CleanupAttr(FD); } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Cleanup; } @@ -527,9 +516,7 @@ public: unsigned getNumParams() const { return NumParams; } - virtual Attr *clone(ASTContext &C) const { - return ::new (C) RegparmAttr(NumParams); - } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { return A->getKind() == Regparm; } @@ -546,9 +533,7 @@ public: unsigned getYDim() const { return Y; } unsigned getZDim() const { return Z; } - virtual Attr *clone(ASTContext &C) const { - return ::new (C) ReqdWorkGroupSizeAttr(X, Y, Z); - } + virtual Attr *clone(ASTContext &C) const; // Implement isa/cast/dyncast/etc. static bool classof(const Attr *A) { @@ -566,6 +551,25 @@ DEF_SIMPLE_ATTR(BaseCheck); DEF_SIMPLE_ATTR(Hiding); DEF_SIMPLE_ATTR(Override); +// Target-specific attributes +DEF_SIMPLE_ATTR(DLLImport); +DEF_SIMPLE_ATTR(DLLExport); + +class MSP430InterruptAttr : public Attr { + unsigned Number; + +public: + MSP430InterruptAttr(unsigned n) : Attr(MSP430Interrupt), Number(n) {} + + unsigned getNumber() const { return Number; } + + virtual Attr *clone(ASTContext &C) const; + + // Implement isa/cast/dyncast/etc. + static bool classof(const Attr *A) { return A->getKind() == MSP430Interrupt; } + static bool classof(const MSP430InterruptAttr *A) { return true; } +}; + #undef DEF_SIMPLE_ATTR } // end namespace clang diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index 7b2833c..0bb4b76 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -36,12 +36,12 @@ namespace clang { /// in character units. class CharUnits { public: - typedef int64_t RawType; + typedef int64_t QuantityType; private: - RawType Quantity; + QuantityType Quantity; - explicit CharUnits(RawType C) : Quantity(C) {} + explicit CharUnits(QuantityType C) : Quantity(C) {} public: @@ -58,8 +58,8 @@ namespace clang { return CharUnits(1); } - /// fromRaw - Construct a CharUnits quantity from a raw integer type. - static CharUnits fromRaw(RawType Quantity) { + /// fromQuantity - Construct a CharUnits quantity from a raw integer type. + static CharUnits fromQuantity(QuantityType Quantity) { return CharUnits(Quantity); } @@ -103,26 +103,26 @@ namespace clang { /// isOne - Test whether the quantity equals one. bool isOne() const { return Quantity == 1; } - /// isPositive - Test whether the quanity is greater than zero. + /// isPositive - Test whether the quantity is greater than zero. bool isPositive() const { return Quantity > 0; } /// isNegative - Test whether the quantity is less than zero. bool isNegative() const { return Quantity < 0; } // Arithmetic operators. - CharUnits operator* (RawType N) const { + CharUnits operator* (QuantityType N) const { return CharUnits(Quantity * N); } - CharUnits operator/ (RawType N) const { + CharUnits operator/ (QuantityType N) const { return CharUnits(Quantity / N); } - RawType operator/ (const CharUnits &Other) const { + QuantityType operator/ (const CharUnits &Other) const { return Quantity / Other.Quantity; } - CharUnits operator% (RawType N) const { + CharUnits operator% (QuantityType N) const { return CharUnits(Quantity % N); } - RawType operator% (const CharUnits &Other) const { + QuantityType operator% (const CharUnits &Other) const { return Quantity % Other.Quantity; } CharUnits operator+ (const CharUnits &Other) const { @@ -134,14 +134,14 @@ namespace clang { // Conversions. - /// getRaw - Get the raw integer representation of this quantity. - RawType getRaw() const { return Quantity; } + /// getQuantity - Get the raw integer representation of this quantity. + QuantityType getQuantity() const { return Quantity; } }; // class CharUnit } // namespace clang -inline clang::CharUnits operator* (clang::CharUnits::RawType Scale, +inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU) { return CU * Scale; } diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index d0d94aa..21b5909 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1184,6 +1184,8 @@ public: OverloadedOperatorKind getOverloadedOperator() const; + const IdentifierInfo *getLiteralIdentifier() const; + /// \brief If this function is an instantiation of a member function /// of a class template specialization, retrieves the function from /// which it was instantiated. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index 02581c1..336a895 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -393,6 +393,9 @@ public: return reverse_base_class_const_iterator(vbases_begin()); } + /// \brief Determine whether this class has any dependent base classes. + bool hasAnyDependentBases() const; + /// Iterator access to method members. The method iterator visits /// all method members of the class, including non-instance methods, /// special methods, etc. diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index ba17eb1..920d31f 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -289,7 +289,9 @@ struct ObjCMethodList { /// ObjCProtocolDecl, and ObjCImplDecl. /// class ObjCContainerDecl : public NamedDecl, public DeclContext { - SourceLocation AtEndLoc; // marks the end of the method container. + // These two locations in the range mark the end of the method container. + // The first points to the '@' token, and the second to the 'end' token. + SourceRange AtEnd; public: ObjCContainerDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -351,11 +353,15 @@ public: IdentifierInfo *PropertyId) const; // Marks the end of the container. - SourceLocation getAtEndLoc() const { return AtEndLoc; } - void setAtEndLoc(SourceLocation L) { AtEndLoc = L; } + SourceRange getAtEndRange() const { + return AtEnd; + } + void setAtEndRange(SourceRange atEnd) { + AtEnd = atEnd; + } virtual SourceRange getSourceRange() const { - return SourceRange(getLocation(), getAtEndLoc()); + return SourceRange(getLocation(), getAtEndRange().getEnd()); } // Implement isa/cast/dyncast/etc. diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index fcb4ae5..59d7e43 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -190,6 +190,14 @@ public: /// getNameKind - Determine what kind of name this is. NameKind getNameKind() const; + /// \brief Determines whether the name itself is dependent, e.g., because it + /// involves a C++ type that is itself dependent. + /// + /// Note that this does not capture all of the notions of "dependent name", + /// because an identifier can be a dependent name if it is used as the + /// callee in a call expression with dependent arguments. + bool isDependentName() const; + /// getName - Retrieve the human-readable string for this name. std::string getAsString() const; @@ -301,6 +309,7 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) { class DeclarationNameTable { void *CXXSpecialNamesImpl; // Actually a FoldingSet<CXXSpecialName> * CXXOperatorIdName *CXXOperatorNames; // Operator names + void *CXXLiteralOperatorNames; // Actually a FoldingSet<...> * DeclarationNameTable(const DeclarationNameTable&); // NONCOPYABLE DeclarationNameTable& operator=(const DeclarationNameTable&); // NONCOPYABLE diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 0cb22df..cfbae9f 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -241,6 +241,11 @@ public: /// stack based objects. bool EvaluateAsAny(EvalResult &Result, ASTContext &Ctx) const; + /// EvaluateAsBooleanCondition - Return true if this is a constant + /// which we we can fold and convert to a boolean condition using + /// any crazy technique that we want to. + bool EvaluateAsBooleanCondition(bool &Result, ASTContext &Ctx) const; + /// isEvaluatable - Call Evaluate to see if this expression can be constant /// folded, but discard the result. bool isEvaluatable(ASTContext &Ctx) const; @@ -2552,7 +2557,7 @@ private: unsigned NumSubExprs : 16; - DesignatedInitExpr(QualType Ty, unsigned NumDesignators, + DesignatedInitExpr(ASTContext &C, QualType Ty, unsigned NumDesignators, const Designator *Designators, SourceLocation EqualOrColonLoc, bool GNUSyntax, Expr **IndexExprs, unsigned NumIndexExprs, @@ -2565,6 +2570,8 @@ private: protected: virtual void DoDestroy(ASTContext &C); + void DestroyDesignators(ASTContext &C); + public: /// A field designator, e.g., ".x". struct FieldDesignator { @@ -2732,7 +2739,8 @@ public: Designator *getDesignator(unsigned Idx) { return &designators_begin()[Idx]; } - void setDesignators(const Designator *Desigs, unsigned NumDesigs); + void setDesignators(ASTContext &C, const Designator *Desigs, + unsigned NumDesigs); Expr *getArrayIndex(const Designator& D); Expr *getArrayRangeStart(const Designator& D); @@ -2779,7 +2787,7 @@ public: /// \brief Replaces the designator at index @p Idx with the series /// of designators in [First, Last). - void ExpandDesignator(unsigned Idx, const Designator *First, + void ExpandDesignator(ASTContext &C, unsigned Idx, const Designator *First, const Designator *Last); virtual SourceRange getSourceRange() const; diff --git a/include/clang/AST/ExprCXX.h b/include/clang/AST/ExprCXX.h index d0e21f5..55d5108e 100644 --- a/include/clang/AST/ExprCXX.h +++ b/include/clang/AST/ExprCXX.h @@ -324,17 +324,21 @@ public: /// @endcode class CXXThisExpr : public Expr { SourceLocation Loc; - + bool Implicit : 1; + public: - CXXThisExpr(SourceLocation L, QualType Type) + CXXThisExpr(SourceLocation L, QualType Type, bool isImplicit) : Expr(CXXThisExprClass, Type, // 'this' is type-dependent if the class type of the enclosing // member function is dependent (C++ [temp.dep.expr]p2) Type->isDependentType(), Type->isDependentType()), - Loc(L) { } + Loc(L), Implicit(isImplicit) { } virtual SourceRange getSourceRange() const { return SourceRange(Loc); } + bool isImplicit() const { return Implicit; } + void setImplicit(bool I) { Implicit = I; } + static bool classof(const Stmt *T) { return T->getStmtClass() == CXXThisExprClass; } diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index 33edadc..d058f83 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -1116,6 +1116,7 @@ class AsmStmt : public Stmt { bool IsSimple; bool IsVolatile; + bool MSAsm; unsigned NumOutputs; unsigned NumInputs; @@ -1126,7 +1127,7 @@ class AsmStmt : public Stmt { llvm::SmallVector<StringLiteral*, 4> Clobbers; public: - AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, + AsmStmt(SourceLocation asmloc, bool issimple, bool isvolatile, bool msasm, unsigned numoutputs, unsigned numinputs, std::string *names, StringLiteral **constraints, Expr **exprs, StringLiteral *asmstr, unsigned numclobbers, @@ -1143,7 +1144,9 @@ public: bool isVolatile() const { return IsVolatile; } void setVolatile(bool V) { IsVolatile = V; } bool isSimple() const { return IsSimple; } - void setSimple(bool V) { IsSimple = false; } + void setSimple(bool V) { IsSimple = V; } + bool isMSAsm() const { return MSAsm; } + void setMSAsm(bool V) { MSAsm = V; } //===--- Asm String Analysis ---===// diff --git a/include/clang/AST/TypeLoc.h b/include/clang/AST/TypeLoc.h index 3e74d07..c36c0ff 100644 --- a/include/clang/AST/TypeLoc.h +++ b/include/clang/AST/TypeLoc.h @@ -1029,18 +1029,88 @@ class ComplexTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, ComplexType> { }; -// FIXME: location of the 'typeof' and parens (the expression is -// carried by the type). -class TypeOfExprTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - TypeOfExprTypeLoc, - TypeOfExprType> { +struct TypeofLocInfo { + SourceLocation TypeofLoc; + SourceLocation LParenLoc; + SourceLocation RParenLoc; }; -// FIXME: location of the 'typeof' and parens; also the TypeSourceInfo -// for the inner type, or (maybe) just express that inline to the TypeLoc. -class TypeOfTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc, - TypeOfTypeLoc, - TypeOfType> { +struct TypeOfExprTypeLocInfo : public TypeofLocInfo { +}; + +struct TypeOfTypeLocInfo : public TypeofLocInfo { + TypeSourceInfo* UnderlyingTInfo; +}; + +template <class Derived, class TypeClass, class LocalData = TypeofLocInfo> +class TypeofLikeTypeLoc + : public ConcreteTypeLoc<UnqualTypeLoc, Derived, TypeClass, LocalData> { +public: + SourceLocation getTypeofLoc() const { + return this->getLocalData()->TypeofLoc; + } + void setTypeofLoc(SourceLocation Loc) { + this->getLocalData()->TypeofLoc = Loc; + } + + SourceLocation getLParenLoc() const { + return this->getLocalData()->LParenLoc; + } + void setLParenLoc(SourceLocation Loc) { + this->getLocalData()->LParenLoc = Loc; + } + + SourceLocation getRParenLoc() const { + return this->getLocalData()->RParenLoc; + } + void setRParenLoc(SourceLocation Loc) { + this->getLocalData()->RParenLoc = Loc; + } + + SourceRange getParensRange() const { + return SourceRange(getLParenLoc(), getRParenLoc()); + } + void setParensRange(SourceRange range) { + setLParenLoc(range.getBegin()); + setRParenLoc(range.getEnd()); + } + + SourceRange getSourceRange() const { + return SourceRange(getTypeofLoc(), getRParenLoc()); + } + + void initializeLocal(SourceLocation Loc) { + setTypeofLoc(Loc); + setLParenLoc(Loc); + setRParenLoc(Loc); + } +}; + +class TypeOfExprTypeLoc : public TypeofLikeTypeLoc<TypeOfExprTypeLoc, + TypeOfExprType, + TypeOfExprTypeLocInfo> { +public: + Expr* getUnderlyingExpr() const { + return getTypePtr()->getUnderlyingExpr(); + } + // Reimplemented to account for GNU/C++ extension + // typeof unary-expression + // where there are no parentheses. + SourceRange getSourceRange() const; +}; + +class TypeOfTypeLoc + : public TypeofLikeTypeLoc<TypeOfTypeLoc, TypeOfType, TypeOfTypeLocInfo> { +public: + QualType getUnderlyingType() const { + return this->getTypePtr()->getUnderlyingType(); + } + TypeSourceInfo* getUnderlyingTInfo() const { + return this->getLocalData()->UnderlyingTInfo; + } + void setUnderlyingTInfo(TypeSourceInfo* TI) const { + this->getLocalData()->UnderlyingTInfo = TI; + } }; // FIXME: location of the 'decltype' and parens. diff --git a/include/clang/Analysis/PathSensitive/BugReporter.h b/include/clang/Analysis/PathSensitive/BugReporter.h index ccebf01..6f6681a 100644 --- a/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/include/clang/Analysis/PathSensitive/BugReporter.h @@ -23,7 +23,6 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/ImmutableSet.h" #include <list> @@ -104,9 +103,9 @@ public: // BugReporter. const Stmt* getStmt() const; - const std::string& getDescription() const { return Description; } + const llvm::StringRef getDescription() const { return Description; } - const std::string& getShortDescription() const { + const llvm::StringRef getShortDescription() const { return ShortDescription.empty() ? Description : ShortDescription; } @@ -444,7 +443,7 @@ public: // FIXME: Move out-of-line (virtual function). SourceLocation getLocation() const { return L; } - void addString(const std::string& s) { Strs.push_back(s); } + void addString(llvm::StringRef s) { Strs.push_back(s); } typedef std::list<std::string>::const_iterator str_iterator; str_iterator str_begin() const { return Strs.begin(); } diff --git a/include/clang/Analysis/PathSensitive/ConstraintManager.h b/include/clang/Analysis/PathSensitive/ConstraintManager.h index 37a1408..c829280 100644 --- a/include/clang/Analysis/PathSensitive/ConstraintManager.h +++ b/include/clang/Analysis/PathSensitive/ConstraintManager.h @@ -25,6 +25,7 @@ namespace clang { class GRState; class GRStateManager; +class GRSubEngine; class SVal; class ConstraintManager { @@ -64,8 +65,10 @@ public: virtual bool canReasonAbout(SVal X) const = 0; }; -ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr); -ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr); +ConstraintManager* CreateBasicConstraintManager(GRStateManager& statemgr, + GRSubEngine &subengine); +ConstraintManager* CreateRangeConstraintManager(GRStateManager& statemgr, + GRSubEngine &subengine); } // end clang namespace diff --git a/include/clang/Analysis/PathSensitive/GRExprEngine.h b/include/clang/Analysis/PathSensitive/GRExprEngine.h index e05c624..fb0e883 100644 --- a/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -87,9 +87,11 @@ class GRExprEngine : public GRSubEngine { // this object be placed at the very end of member variables so that its // destructor is called before the rest of the GRExprEngine is destroyed. GRBugReporter BR; + + llvm::OwningPtr<GRTransferFuncs> TF; public: - GRExprEngine(AnalysisManager &mgr); + GRExprEngine(AnalysisManager &mgr, GRTransferFuncs *tf); ~GRExprEngine(); @@ -104,18 +106,14 @@ public: SValuator &getSValuator() { return SVator; } - GRTransferFuncs& getTF() { return *StateMgr.TF; } + GRTransferFuncs& getTF() { return *TF; } BugReporter& getBugReporter() { return BR; } GRStmtNodeBuilder &getBuilder() { assert(Builder); return *Builder; } - /// setTransferFunctions - void setTransferFunctionsAndCheckers(GRTransferFuncs* tf); - - void setTransferFunctions(GRTransferFuncs& tf) { - setTransferFunctionsAndCheckers(&tf); - } + // FIXME: Remove once GRTransferFuncs is no longer referenced. + void setTransferFunction(GRTransferFuncs* tf); /// ViewGraph - Visualize the ExplodedGraph created by executing the /// simulation. @@ -173,6 +171,10 @@ public: /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. void ProcessEndPath(GREndPathNodeBuilder& builder); + + /// EvalAssume - Callback function invoked by the ConstraintManager when + /// making assumptions about state values. + const GRState *ProcessAssume(const GRState *state, SVal cond, bool assumption); GRStateManager& getStateManager() { return StateMgr; } const GRStateManager& getStateManager() const { return StateMgr; } @@ -351,6 +353,10 @@ protected: void VisitCXXThisExpr(CXXThisExpr *TE, ExplodedNode *Pred, ExplodedNodeSet & Dst); + /// Create a C++ temporary object for an rvalue. + void CreateCXXTemporaryObject(Expr *Ex, ExplodedNode *Pred, + ExplodedNodeSet &Dst); + /// EvalEagerlyAssume - Given the nodes in 'Src', eagerly assume symbolic /// expressions of the form 'x != 0' and generate new nodes (stored in Dst) /// with those assumptions. diff --git a/include/clang/Analysis/PathSensitive/GRState.h b/include/clang/Analysis/PathSensitive/GRState.h index 424b0d7..11cdac0 100644 --- a/include/clang/Analysis/PathSensitive/GRState.h +++ b/include/clang/Analysis/PathSensitive/GRState.h @@ -40,10 +40,10 @@ namespace clang { class GRStateManager; -class GRTransferFuncs; class Checker; -typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&); +typedef ConstraintManager* (*ConstraintManagerCreator)(GRStateManager&, + GRSubEngine&); typedef StoreManager* (*StoreManagerCreator)(GRStateManager&); //===----------------------------------------------------------------------===// @@ -159,10 +159,6 @@ public: BasicValueFactory &getBasicVals() const; SymbolManager &getSymbolManager() const; - GRTransferFuncs &getTransferFuncs() const; - - std::vector<std::pair<void *, Checker *> >::iterator checker_begin() const; - std::vector<std::pair<void *, Checker *> >::iterator checker_end() const; //==---------------------------------------------------------------------==// // Constraints on values. @@ -391,9 +387,8 @@ public: //===----------------------------------------------------------------------===// class GRStateManager { - friend class GRExprEngine; friend class GRState; - + friend class GRExprEngine; // FIXME: Remove. private: EnvironmentManager EnvMgr; llvm::OwningPtr<StoreManager> StoreMgr; @@ -416,27 +411,20 @@ private: ValueManager ValueMgr; /// Alloc - A BumpPtrAllocator to allocate states. - llvm::BumpPtrAllocator& Alloc; - - /// TF - Object that represents a bundle of transfer functions - /// for manipulating and creating SVals. - GRTransferFuncs* TF; - - /// Reference to all checkers in GRExprEngine. - std::vector<std::pair<void *, Checker*> > *Checkers; + llvm::BumpPtrAllocator &Alloc; public: - GRStateManager(ASTContext& Ctx, StoreManagerCreator CreateStoreManager, ConstraintManagerCreator CreateConstraintManager, - llvm::BumpPtrAllocator& alloc) + llvm::BumpPtrAllocator& alloc, + GRSubEngine &subeng) : EnvMgr(alloc), GDMFactory(alloc), ValueMgr(alloc, Ctx, *this), Alloc(alloc) { StoreMgr.reset((*CreateStoreManager)(*this)); - ConstraintMgr.reset((*CreateConstraintManager)(*this)); + ConstraintMgr.reset((*CreateConstraintManager)(*this, subeng)); } ~GRStateManager(); @@ -446,10 +434,6 @@ public: ASTContext &getContext() { return ValueMgr.getContext(); } const ASTContext &getContext() const { return ValueMgr.getContext(); } - GRTransferFuncs& getTransferFuncs() { return *TF; } - - std::vector<std::pair<void *, Checker *> > &getCheckers() { return *Checkers;} - BasicValueFactory &getBasicVals() { return ValueMgr.getBasicValueFactory(); } @@ -702,20 +686,6 @@ inline SymbolManager &GRState::getSymbolManager() const { return getStateManager().getSymbolManager(); } -inline GRTransferFuncs &GRState::getTransferFuncs() const { - return getStateManager().getTransferFuncs(); -} - -inline std::vector<std::pair<void *, Checker *> >::iterator -GRState::checker_begin() const { - return getStateManager().getCheckers().begin(); -} - -inline std::vector<std::pair<void *, Checker *> >::iterator -GRState::checker_end() const { - return getStateManager().getCheckers().end(); -} - template<typename T> const GRState *GRState::add(typename GRStateTrait<T>::key_type K) const { return getStateManager().add<T>(this, K, get_context<T>()); diff --git a/include/clang/Analysis/PathSensitive/GRSubEngine.h b/include/clang/Analysis/PathSensitive/GRSubEngine.h index 330742d..5b383fa 100644 --- a/include/clang/Analysis/PathSensitive/GRSubEngine.h +++ b/include/clang/Analysis/PathSensitive/GRSubEngine.h @@ -13,6 +13,8 @@ #ifndef LLVM_CLANG_ANALYSIS_GRSUBENGINE_H #define LLVM_CLANG_ANALYSIS_GRSUBENGINE_H +#include "clang/Analysis/PathSensitive/SVals.h" + namespace clang { class Stmt; @@ -62,8 +64,12 @@ public: /// ProcessEndPath - Called by GRCoreEngine. Used to generate end-of-path /// nodes when the control reaches the end of a function. virtual void ProcessEndPath(GREndPathNodeBuilder& builder) = 0; + + /// EvalAssume - Called by ConstraintManager. Used to call checker-specific + /// logic for handling assumptions on symbolic values. + virtual const GRState* ProcessAssume(const GRState *state, + SVal cond, bool assumption) = 0; }; - } #endif diff --git a/include/clang/Analysis/PathSensitive/MemRegion.h b/include/clang/Analysis/PathSensitive/MemRegion.h index b57cfd7..3bcedbe 100644 --- a/include/clang/Analysis/PathSensitive/MemRegion.h +++ b/include/clang/Analysis/PathSensitive/MemRegion.h @@ -65,6 +65,7 @@ public: BlockTextRegionKind, BlockDataRegionKind, CompoundLiteralRegionKind, + CXXThisRegionKind, StringRegionKind, ElementRegionKind, // Decl Regions. @@ -99,17 +100,13 @@ public: const MemRegion *StripCasts() const; - bool hasStackStorage() const; - - bool hasParametersStorage() const; - - bool hasGlobalsStorage() const; - bool hasGlobalsOrParametersStorage() const; - bool hasHeapStorage() const; - - bool hasHeapOrStackStorage() const; + bool hasStackStorage() const; + + bool hasStackNonParametersStorage() const; + + bool hasStackParametersStorage() const; virtual void dumpToStream(llvm::raw_ostream& os) const; @@ -634,6 +631,36 @@ public: return R->getKind() == VarRegionKind; } }; + +/// CXXThisRegion - Represents the region for the implicit 'this' parameter +/// in a call to a C++ method. This region doesn't represent the object +/// referred to by 'this', but rather 'this' itself. +class CXXThisRegion : public TypedRegion { + friend class MemRegionManager; + CXXThisRegion(const PointerType *thisPointerTy, + const MemRegion *sReg) + : TypedRegion(sReg, CXXThisRegionKind), ThisPointerTy(thisPointerTy) {} + + static void ProfileRegion(llvm::FoldingSetNodeID &ID, + const PointerType *PT, + const MemRegion *sReg); + + void Profile(llvm::FoldingSetNodeID &ID) const; + +public: + QualType getValueType(ASTContext &C) const { + return QualType(ThisPointerTy, 0); + } + + void dumpToStream(llvm::raw_ostream& os) const; + + static bool classof(const MemRegion* R) { + return R->getKind() == CXXThisRegionKind; + } + +private: + const PointerType *ThisPointerTy; +}; class FieldRegion : public DeclRegion { friend class MemRegionManager; @@ -725,21 +752,21 @@ public: } }; +// C++ temporary object associated with an expression. class CXXObjectRegion : public TypedRegion { friend class MemRegionManager; - // T - The object type. - QualType T; + Expr const *Ex; - CXXObjectRegion(QualType t, const MemRegion *sReg) - : TypedRegion(sReg, CXXObjectRegionKind), T(t) {} + CXXObjectRegion(Expr const *E, MemRegion const *sReg) + : TypedRegion(sReg, CXXObjectRegionKind), Ex(E) {} static void ProfileRegion(llvm::FoldingSetNodeID &ID, - QualType T, const MemRegion *sReg); + Expr const *E, const MemRegion *sReg); public: QualType getValueType(ASTContext& C) const { - return T; + return Ex->getType(); } void Profile(llvm::FoldingSetNodeID &ID) const; @@ -824,6 +851,11 @@ public: const CompoundLiteralRegion* getCompoundLiteralRegion(const CompoundLiteralExpr* CL, const LocationContext *LC); + + /// getCXXThisRegion - Retrieve the [artifical] region associated with the + /// parameter 'this'. + const CXXThisRegion *getCXXThisRegion(QualType thisPointerTy, + const LocationContext *LC); /// getSymbolicRegion - Retrieve or create a "symbolic" memory region. const SymbolicRegion* getSymbolicRegion(SymbolRef sym); @@ -869,7 +901,8 @@ public: const ObjCIvarRegion *getObjCIvarRegion(const ObjCIvarDecl* ivd, const MemRegion* superRegion); - const CXXObjectRegion *getCXXObjectRegion(QualType T); + const CXXObjectRegion *getCXXObjectRegion(Expr const *Ex, + LocationContext const *LC); const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD); const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, diff --git a/include/clang/Analysis/PathSensitive/SValuator.h b/include/clang/Analysis/PathSensitive/SValuator.h index e63eb12..4a4b502 100644 --- a/include/clang/Analysis/PathSensitive/SValuator.h +++ b/include/clang/Analysis/PathSensitive/SValuator.h @@ -28,8 +28,10 @@ class SValuator { protected: ValueManager &ValMgr; +public: + // FIXME: Make these protected again one RegionStoreManager correctly + // handles loads from differening bound value types. virtual SVal EvalCastNL(NonLoc val, QualType castTy) = 0; - virtual SVal EvalCastL(Loc val, QualType castTy) = 0; public: diff --git a/include/clang/Analysis/PathSensitive/Store.h b/include/clang/Analysis/PathSensitive/Store.h index 52d73da..70c17ac 100644 --- a/include/clang/Analysis/PathSensitive/Store.h +++ b/include/clang/Analysis/PathSensitive/Store.h @@ -103,9 +103,6 @@ public: virtual SVal getLValueElement(QualType elementType, SVal offset, SVal Base)=0; - // T - the object type. - Loc getThisObject(QualType T); - // FIXME: Make out-of-line. virtual DefinedOrUnknownSVal getSizeInElements(const GRState *state, const MemRegion *region) { @@ -192,7 +189,8 @@ protected: /// CastRetrievedVal - Used by subclasses of StoreManager to implement /// implicit casts that arise from loads from regions that are reinterpreted /// as another region. - SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy); + SVal CastRetrievedVal(SVal val, const TypedRegion *R, QualType castTy, + bool performTestOnly = true); }; // FIXME: Do we still need this? diff --git a/include/clang/Basic/Diagnostic.h b/include/clang/Basic/Diagnostic.h index a2ccea7..c5d6d7c 100644 --- a/include/clang/Basic/Diagnostic.h +++ b/include/clang/Basic/Diagnostic.h @@ -781,6 +781,11 @@ public: /// formal arguments into the %0 slots. The result is appended onto the Str /// array. void FormatDiagnostic(llvm::SmallVectorImpl<char> &OutStr) const; + + /// FormatDiagnostic - Format the given format-string into the + /// output buffer using the arguments stored in this diagnostic. + void FormatDiagnostic(const char *DiagStr, const char *DiagEnd, + llvm::SmallVectorImpl<char> &OutStr) const; }; /// DiagnosticClient - This is an abstract interface implemented by clients of diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index efbc787..dfb6f8d 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -81,5 +81,7 @@ def warn_drv_clang_unsupported : Warning< "the clang compiler does not support '%0'">; def warn_drv_assuming_mfloat_abi_is : Warning< "unknown platform, assuming -mfloat-abi=%0">; +def warn_ignoring_ftabstop_value : Warning< + "ignoring invalid -ftabstop value '%0', using default value %1">; } diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td index d8b5f2d..26a80b5 100644 --- a/include/clang/Basic/DiagnosticLexKinds.td +++ b/include/clang/Basic/DiagnosticLexKinds.td @@ -84,6 +84,9 @@ def err_exponent_has_no_digits : Error<"exponent has no digits">; def ext_imaginary_constant : Extension<"imaginary constants are an extension">; def err_hexconstant_requires_exponent : Error< "hexadecimal floating constants require an exponent">; +def ext_hexconstant_cplusplus : ExtWarn< + "hexadecimal floating constants are a C99 feature that is incompatible with " + "C++0x">; def ext_hexconstant_invalid : Extension< "hexadecimal floating constants are a C99 feature">; def ext_binary_literal : Extension< @@ -169,6 +172,9 @@ def err_pp_hash_error : Error<"#error%0">; def err_pp_file_not_found : Error<"'%0' file not found">, DefaultFatal; def err_pp_error_opening_file : Error< "error opening file '%0': %1">, DefaultFatal; +def warn_pp_relative_include_from_framework : Warning< + "published framework headers should always #import headers within the " + "framework with framework paths">, InGroup<DiagGroup<"framework-headers">>; def err_pp_empty_filename : Error<"empty filename">; def err_pp_include_too_deep : Error<"#include nested too deeply">; def err_pp_expects_filename : Error<"expected \"FILENAME\" or <FILENAME>">; diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index 98a74a5..c6d0605 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -261,6 +261,8 @@ def err_attributes_not_allowed : Error<"an attribute list cannot appear here">; /// C++ Templates def err_expected_template : Error<"expected template">; +def err_unknown_template_name : Error< + "unknown template name %0">; def err_expected_comma_greater : Error< "expected ',' or '>' in template-parameter-list">; def err_expected_type_id_after : Error<"expected type-id after '%0'">; @@ -289,6 +291,16 @@ def err_explicit_instantiation_with_definition : Error< "definition is meant to be an explicit specialization, add '<>' after the " "'template' keyword">; +// Constructor template diagnostics. +def err_out_of_line_constructor_template_id : Error< + "out-of-line constructor for %0 cannot have template arguments">; +def err_out_of_line_template_id_names_constructor : Error< + "qualified reference to %0 is a constructor name rather than a " + "template name wherever a constructor can be declared">; +def err_out_of_line_type_names_constructor : Error< + "qualified reference to %0 is a constructor name rather than a " + "type wherever a constructor can be declared">; + def err_expected_qualified_after_typename : Error< "expected a qualified name after 'typename'">; def err_typename_refers_to_non_type_template : Error< diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 155633b..7e59f88 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -89,7 +89,7 @@ def warn_decl_in_param_list : Warning< def warn_implicit_function_decl : Warning< "implicit declaration of function %0">, InGroup<ImplicitFunctionDeclare>, DefaultIgnore; -def ext_implicit_function_decl : Extension< +def ext_implicit_function_decl : ExtWarn< "implicit declaration of function %0 is invalid in C99">, InGroup<ImplicitFunctionDeclare>; @@ -160,6 +160,8 @@ def warn_suggest_noreturn_function : Warning< def warn_suggest_noreturn_block : Warning< "block could be attribute 'noreturn'">, InGroup<DiagGroup<"missing-noreturn">>, DefaultIgnore; +def warn_unreachable : Warning<"will never be executed">, + InGroup<DiagGroup<"unreachable-code">>, DefaultIgnore; /// Built-in functions. def ext_implicit_lib_function_decl : ExtWarn< @@ -683,6 +685,8 @@ def err_attribute_not_string : Error< "argument to %0 attribute was not a string literal">; def err_attribute_section_invalid_for_target : Error< "argument to 'section' attribute is not valid for this target: %0">; +def err_attribute_section_local_variable : Error< + "'section' attribute is not valid on local variables">; def err_attribute_aligned_not_power_of_two : Error< "requested alignment is not a power of 2">; def warn_redeclaration_without_attribute_prev_attribute_ignored : Warning< @@ -895,18 +899,61 @@ def err_ovl_ambiguous_member_call : Error< "call to member function %0 is ambiguous">; def err_ovl_deleted_member_call : Error< "call to %select{unavailable|deleted}0 member function %1">; -def err_ovl_candidate : Note<"candidate function">; -def err_ovl_candidate_not_viable : Note<"function not viable because" - " of ambiguity in conversion of argument %0">; +def note_ovl_candidate : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "is the implicit default constructor|" + "is the implicit copy constructor|" + "is the implicit copy assignment operator}0%1">; +// Note that we don't treat templates differently for this diagnostic. +def note_ovl_candidate_arity : Note<"candidate " + "%select{function|function|constructor|function|function|constructor|" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)}0 not viable: requires" + "%select{ at least| at most|}2 %3 argument%s3, but %4 %plural{1:was|:were}4 " + "provided">; +def note_ovl_candidate_deleted : Note< + "candidate %select{function|function|constructor|" + "function |function |constructor |||}0%1 " + "has been explicitly %select{made unavailable|deleted}2">; +def note_ovl_candidate_bad_conv : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)}0%1" + " not viable: no known conversion from %2 to %3 for " + "%select{%ordinal5 argument|object argument}4">; +def note_ovl_candidate_bad_addrspace : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)}0%1 not viable: " + "%select{%ordinal6|'this'}5 argument (%2) is in " + "address space %3, but parameter must be in address space %4">; +def note_ovl_candidate_bad_cvr_this : Note<"candidate " + "%select{|function|||function||||" + "function (the implicit copy assignment operator)}0 not viable: " + "'this' argument has type %2, but method is not marked " + "%select{const|volatile|const or volatile|restrict|const or restrict|" + "volatile or restrict|const, volatile, or restrict}3">; +def note_ovl_candidate_bad_cvr : Note<"candidate " + "%select{function|function|constructor|" + "function |function |constructor |" + "constructor (the implicit default constructor)|" + "constructor (the implicit copy constructor)|" + "function (the implicit copy assignment operator)}0%1 not viable: " + "%ordinal4 argument (%2) would lose " + "%select{const|volatile|const and volatile|restrict|const and restrict|" + "volatile and restrict|const, volatile, and restrict}3 qualifier" + "%select{||s||s|s|s}3">; def note_ambiguous_type_conversion: Note< "because of ambiguity in conversion of %0 to %1">; -def err_ovl_template_candidate : Note< - "candidate function template specialization %0">; -def err_ovl_candidate_deleted : Note< - "candidate function has been explicitly %select{made unavailable|deleted}0">; -def err_ovl_builtin_binary_candidate : Note< +def note_ovl_builtin_binary_candidate : Note< "built-in candidate %0">; -def err_ovl_builtin_unary_candidate : Note< +def note_ovl_builtin_unary_candidate : Note< "built-in candidate %0">; def err_ovl_no_viable_function_in_init : Error< "no matching constructor for initialization of %0">; @@ -920,6 +967,10 @@ def err_ovl_ambiguous_oper : Error< def err_ovl_no_viable_oper : Error<"no viable overloaded '%0'">; def err_ovl_deleted_oper : Error< "overload resolution selected %select{unavailable|deleted}0 operator '%1'">; +def err_ovl_no_viable_subscript : + Error<"no viable overloaded operator[] for type %0">; +def err_ovl_no_oper : + Error<"type %0 does not provide a %select{subscript|call}1 operator">; def err_ovl_no_viable_object_call : Error< "no matching function for call to object of type %0">; @@ -927,7 +978,7 @@ def err_ovl_ambiguous_object_call : Error< "call to object of type %0 is ambiguous">; def err_ovl_deleted_object_call : Error< "call to %select{unavailable|deleted}0 function call operator in type %1">; -def err_ovl_surrogate_cand : Note<"conversion candidate of type %0">; +def note_ovl_surrogate_cand : Note<"conversion candidate of type %0">; def err_member_call_without_object : Error< "call to non-static member function without an object argument">; @@ -1295,6 +1346,8 @@ def err_template_kw_refers_to_class_template : Error< "'%0%1' instantiated to a class template, not a function template">; def note_referenced_class_template : Error< "class template declared here">; +def err_template_kw_missing : Error< + "missing 'template' keyword prior to dependent template name '%0%1'">; // C++0x Variadic Templates def err_template_param_pack_default_arg : Error< @@ -1472,7 +1525,7 @@ def note_protected_by___block : Note< "jump bypasses setup of __block variable">; def err_func_returning_array_function : Error< - "function cannot return array or function type %0">; + "function cannot return %select{array|function}0 type %1">; def err_field_declared_as_function : Error<"field %0 declared as a function">; def err_field_incomplete : Error<"field has incomplete type %0">; def ext_variable_sized_type_in_struct : ExtWarn< @@ -1543,15 +1596,17 @@ def warn_floatingpoint_eq : Warning< "comparing floating point with == or != is unsafe">, InGroup<DiagGroup<"float-equal">>, DefaultIgnore; -def warn_shift_negative : Warning< - "shift count is negative">; -def warn_shift_gt_typewidth : Warning< - "shift count >= width of type">; +def warn_division_by_zero : Warning<"division by zero is undefined">; +def warn_remainder_by_zero : Warning<"remainder by zero is undefined">; +def warn_shift_negative : Warning<"shift count is negative">; +def warn_shift_gt_typewidth : Warning<"shift count >= width of type">; def warn_precedence_bitwise_rel : Warning< "%0 has lower precedence than %1; %1 will be evaluated first">, InGroup<Parentheses>; - +def note_precedence_bitwise_first : Note< + "place parentheses around the %0 expression to evaluate it first">; + def err_sizeof_nonfragile_interface : Error< "invalid application of '%select{alignof|sizeof}1' to interface %0 in " "non-fragile ABI">; @@ -1647,6 +1702,8 @@ def err_static_block_func : Error< def err_typecheck_address_of : Error<"address of %0 requested">; def ext_typecheck_addrof_void : Extension< "ISO C forbids taking the address of an expression of type 'void'">; +def err_unqualified_pointer_member_function : Error< + "must explicitly qualify member function %0 when taking its address">; def err_typecheck_invalid_lvalue_addrof : Error< "address expression must be an lvalue or a function designator">; def err_typecheck_unary_expr : Error< @@ -1721,6 +1778,10 @@ def warn_printf_nonliteral : Warning< def err_unexpected_interface : Error< "unexpected interface name %0: expected expression">; def err_ref_non_value : Error<"%0 does not refer to a value">; +def err_ref_vm_type : Error< + "cannot refer to declaration with a variably modified type inside block">; +def err_ref_array_type : Error< + "cannot refer to declaration with an array type inside block">; def err_property_not_found : Error< "property %0 not found on object of type %1">; def err_duplicate_property : Error< @@ -1952,6 +2013,8 @@ def warn_condition_is_assignment : Warning<"using the result of an " def warn_condition_is_idiomatic_assignment : Warning<"using the result " "of an assignment as a condition without parentheses">, InGroup<DiagGroup<"idiomatic-parentheses">>, DefaultIgnore; +def note_condition_assign_to_comparison : Note< + "use '==' to turn this assignment into an equality comparison">; def warn_value_always_zero : Warning< "%0 is always %select{zero|false|NULL}1 in this context">; @@ -2303,6 +2366,13 @@ def err_operator_delete_dependent_param_type : Error< def err_operator_delete_param_type : Error< "%0 takes type %1 as first parameter">; +// C++ literal operators +def err_literal_operator_outside_namespace : Error< + "literal operator %0 must be in a namespace or global scope">; +// FIXME: This diagnostic sucks +def err_literal_operator_params : Error< + "parameter declaration for literal operator %0 is not valid">; + // C++ conversion functions def err_conv_function_not_member : Error< "conversion function must be a non-static member function">; @@ -2569,7 +2639,21 @@ def err_mem_init_not_member_or_class_suggest : Error< def err_field_designator_unknown_suggest : Error< "field designator %0 does not refer to any field in type %1; did you mean " "%2?">; - +def err_typecheck_member_reference_ivar_suggest : Error< + "%0 does not have a member named %1; did you mean %2?">; +def err_property_not_found_suggest : Error< + "property %0 not found on object of type %1; did you mean %2?">; +def err_undef_interface_suggest : Error< + "cannot find interface declaration for %0; did you mean %1?">; +def warn_undef_interface_suggest : Warning< + "cannot find interface declaration for %0; did you mean %1?">; +def err_undef_superclass_suggest : Error< + "cannot find interface declaration for %0, superclass of %1; did you mean " + "%2?">; +def err_undeclared_protocol_suggest : Error< + "cannot find protocol declaration for %0; did you mean %1?">; +def note_base_class_specified_here : Note< + "base class %0 specified here">; } diff --git a/include/clang/Basic/PartialDiagnostic.h b/include/clang/Basic/PartialDiagnostic.h index ae11a75..0d97012 100644 --- a/include/clang/Basic/PartialDiagnostic.h +++ b/include/clang/Basic/PartialDiagnostic.h @@ -26,7 +26,8 @@ class DeclarationName; class PartialDiagnostic { struct Storage { - Storage() : NumDiagArgs(0), NumDiagRanges(0) { } + Storage() : NumDiagArgs(0), NumDiagRanges(0), NumCodeModificationHints(0) { + } enum { /// MaxArguments - The maximum number of arguments we can hold. We @@ -42,6 +43,10 @@ class PartialDiagnostic { /// NumDiagRanges - This is the number of ranges in the DiagRanges array. unsigned char NumDiagRanges; + /// \brief The number of code modifications hints in the + /// CodeModificationHints array. + unsigned char NumCodeModificationHints; + /// DiagArgumentsKind - This is an array of ArgumentKind::ArgumentKind enum /// values, with one for each argument. This specifies whether the argument /// is in DiagArgumentsStr or in DiagArguments. @@ -56,6 +61,12 @@ class PartialDiagnostic { /// DiagRanges - The list of ranges added to this diagnostic. It currently /// only support 10 ranges, could easily be extended if needed. SourceRange DiagRanges[10]; + + enum { MaxCodeModificationHints = 3 }; + + /// CodeModificationHints - If valid, provides a hint with some code + /// to insert, remove, or modify at a particular position. + CodeModificationHint CodeModificationHints[MaxCodeModificationHints]; }; /// DiagID - The diagnostic ID. @@ -84,6 +95,20 @@ class PartialDiagnostic { DiagStorage->DiagRanges[DiagStorage->NumDiagRanges++] = R; } + void AddCodeModificationHint(const CodeModificationHint &Hint) const { + if (Hint.isNull()) + return; + + if (!DiagStorage) + DiagStorage = new Storage; + + assert(DiagStorage->NumCodeModificationHints < + Storage::MaxCodeModificationHints && + "Too many code modification hints!"); + DiagStorage->CodeModificationHints[DiagStorage->NumCodeModificationHints++] + = Hint; + } + public: PartialDiagnostic(unsigned DiagID) : DiagID(DiagID), DiagStorage(0) { } @@ -130,6 +155,10 @@ public: // Add all ranges. for (unsigned i = 0, e = DiagStorage->NumDiagRanges; i != e; ++i) DB.AddSourceRange(DiagStorage->DiagRanges[i]); + + // Add all code modification hints + for (unsigned i = 0, e = DiagStorage->NumCodeModificationHints; i != e; ++i) + DB.AddCodeModificationHint(DiagStorage->CodeModificationHints[i]); } friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, @@ -165,6 +194,13 @@ public: friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, DeclarationName N); + + friend const PartialDiagnostic &operator<<(const PartialDiagnostic &PD, + const CodeModificationHint &Hint) { + PD.AddCodeModificationHint(Hint); + return PD; + } + }; inline PartialDiagnostic PDiag(unsigned DiagID = 0) { diff --git a/include/clang/Basic/SourceLocation.h b/include/clang/Basic/SourceLocation.h index 36baf5f..d4f557b 100644 --- a/include/clang/Basic/SourceLocation.h +++ b/include/clang/Basic/SourceLocation.h @@ -162,6 +162,7 @@ public: void setEnd(SourceLocation e) { E = e; } bool isValid() const { return B.isValid() && E.isValid(); } + bool isInvalid() const { return !isValid(); } bool operator==(const SourceRange &X) const { return B == X.B && E == X.E; diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 0d95e6a..97e0495 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -30,6 +30,7 @@ class StringRef; namespace clang { class Diagnostic; class LangOptions; +class MacroBuilder; class SourceLocation; class SourceManager; class TargetOptions; @@ -209,7 +210,7 @@ public: /// getTargetDefines - Appends the target-specific #define values for this /// target set to the specified buffer. virtual void getTargetDefines(const LangOptions &Opts, - std::vector<char> &DefineBuffer) const = 0; + MacroBuilder &Builder) const = 0; /// getTargetBuiltins - Return information about target-specific builtins for diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 6a0d816..2511dfb 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -178,6 +178,8 @@ def fdiagnostics_print_source_range_info : Flag<"-fdiagnostics-print-source-rang HelpText<"Print source range spans in numeric form">; def fdiagnostics_show_option : Flag<"-fdiagnostics-show-option">, HelpText<"Print diagnostic name with mappable diagnostics">; +def ftabstop : Separate<"-ftabstop">, MetaVarName<"<N>">, + HelpText<"Set the tab stop distance.">; def fmessage_length : Separate<"-fmessage-length">, MetaVarName<"<N>">, HelpText<"Format message diagnostics so that they fit within N columns or fewer, when possible.">; def fcolor_diagnostics : Flag<"-fcolor-diagnostics">, @@ -323,6 +325,8 @@ def fgnu_runtime : Flag<"-fgnu-runtime">, HelpText<"Generate output compatible with the standard GNU Objective-C runtime">; def std_EQ : Joined<"-std=">, HelpText<"Language standard to compile for">; +def fmath_errno : Flag<"-fmath-errno">, + HelpText<"Require math functions to indicate errors by setting errno">; def fms_extensions : Flag<"-fms-extensions">, HelpText<"Accept some non-standard constructs used in Microsoft header files ">; def main_file_name : Separate<"-main-file-name">, @@ -331,8 +335,6 @@ def fno_elide_constructors : Flag<"-fno-elide-constructors">, HelpText<"Disable C++ copy constructor elision">; def fno_lax_vector_conversions : Flag<"-fno-lax-vector-conversions">, HelpText<"Disallow implicit conversions between vectors with a different number of elements or different element types">; -def fno_math_errno : Flag<"-fno-math-errno">, - HelpText<"Don't require math functions to respect errno">; def fno_signed_char : Flag<"-fno-signed-char">, HelpText<"Char is unsigned">; def fno_operator_names : Flag<"-fno-operator-names">, diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 247e1f5..955d98e 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -345,6 +345,7 @@ def fstack_protector_all : Flag<"-fstack-protector-all">, Group<f_Group>; def fstack_protector : Flag<"-fstack-protector">, Group<f_Group>; def fstrict_aliasing : Flag<"-fstrict-aliasing">, Group<clang_ignored_f_Group>; def fsyntax_only : Flag<"-fsyntax-only">, Flags<[DriverOption]>; +def ftabstop_EQ : Joined<"-ftabstop=">, Group<f_Group>; def ftemplate_depth_ : Joined<"-ftemplate-depth-">, Group<f_Group>; def fterminated_vtables : Flag<"-fterminated-vtables">, Group<f_Group>; def ftime_report : Flag<"-ftime-report">, Group<f_Group>; diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index b3c2d05..cc8d438 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -87,10 +87,6 @@ public: // Platform defaults information - /// IsMathErrnoDefault - Does this tool chain set -fmath-errno by - /// default. - virtual bool IsMathErrnoDefault() const = 0; - /// IsBlocksDefault - Does this tool chain enable -fblocks by default. virtual bool IsBlocksDefault() const { return false; } diff --git a/include/clang/Driver/Types.def b/include/clang/Driver/Types.def index e01a04c..d66fe92 100644 --- a/include/clang/Driver/Types.def +++ b/include/clang/Driver/Types.def @@ -41,6 +41,7 @@ // C family source language (with and without preprocessing). TYPE("cpp-output", PP_C, INVALID, "i", "u") TYPE("c", C, PP_C, 0, "u") +TYPE("cl", CL, PP_C, 0, "u") TYPE("objective-c-cpp-output", PP_ObjC, INVALID, "mi", "u") TYPE("objective-c", ObjC, PP_ObjC, 0, "u") TYPE("c++-cpp-output", PP_CXX, INVALID, "ii", "u") diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h index 18ec429..edafe62 100644 --- a/include/clang/Frontend/CompilerInstance.h +++ b/include/clang/Frontend/CompilerInstance.h @@ -32,6 +32,7 @@ class Diagnostic; class DiagnosticClient; class ExternalASTSource; class FileManager; +class FrontendAction; class Preprocessor; class Source; class SourceManager; @@ -103,6 +104,42 @@ public: bool _OwnsLLVMContext = true); ~CompilerInstance(); + /// @name High-Level Operations + /// { + + /// ExecuteAction - Execute the provided action against the compiler's + /// CompilerInvocation object. + /// + /// This function makes the following assumptions: + /// + /// - The invocation options should be initialized. This function does not + /// handle the '-help' or '-version' options, clients should handle those + /// directly. + /// + /// - The diagnostics engine should have already been created by the client. + /// + /// - No other CompilerInstance state should have been initialized (this is + /// an unchecked error). + /// + /// - Clients should have initialized any LLVM target features that may be + /// required. + /// + /// - Clients should eventually call llvm_shutdown() upon the completion of + /// this routine to ensure that any managed objects are properly destroyed. + /// + /// Note that this routine may write output to 'stderr'. + /// + /// \param Act - The action to execute. + /// \return - True on success. + // + // FIXME: This function should take the stream to write any debugging / + // verbose output to as an argument. + // + // FIXME: Eliminate the llvm_shutdown requirement, that should either be part + // of the context or else not CompilerInstance specific. + bool ExecuteAction(FrontendAction &Act); + + /// } /// @name LLVM Context /// { @@ -451,6 +488,7 @@ public: const HeaderSearchOptions &, const DependencyOutputOptions &, const TargetInfo &, + const FrontendOptions &, SourceManager &, FileManager &); /// Create the AST context. diff --git a/include/clang/Frontend/DiagnosticOptions.h b/include/clang/Frontend/DiagnosticOptions.h index 6346dc0..13039bb 100644 --- a/include/clang/Frontend/DiagnosticOptions.h +++ b/include/clang/Frontend/DiagnosticOptions.h @@ -35,6 +35,10 @@ public: /// diagnostics, indicated by markers in the /// input source file. + /// The distance between tab stops. + unsigned TabStop; + enum { DefaultTabStop = 8, MaxTabStop = 100 }; + /// Column limit for formatting message diagnostics, or 0 if unused. unsigned MessageLength; @@ -49,6 +53,7 @@ public: public: DiagnosticOptions() { IgnoreWarnings = 0; + TabStop = DefaultTabStop; MessageLength = 0; NoRewriteMacros = 0; Pedantic = 0; diff --git a/include/clang/Frontend/PCHReader.h b/include/clang/Frontend/PCHReader.h index 7e2c656..9665ce1 100644 --- a/include/clang/Frontend/PCHReader.h +++ b/include/clang/Frontend/PCHReader.h @@ -20,6 +20,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Type.h" #include "clang/AST/TemplateBase.h" +#include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/SourceManager.h" @@ -146,7 +147,8 @@ public: /// required when traversing the AST. Only those AST nodes that are /// actually required will be de-serialized. class PCHReader - : public ExternalSemaSource, + : public ExternalPreprocessorSource, + public ExternalSemaSource, public IdentifierInfoLookup, public ExternalIdentifierLookup, public ExternalSLocEntrySource { @@ -183,6 +185,10 @@ private: llvm::BitstreamReader StreamFile; llvm::BitstreamCursor Stream; + /// \brief The cursor to the start of the preprocessor block, which stores + /// all of the macro definitions. + llvm::BitstreamCursor MacroCursor; + /// DeclsCursor - This is a cursor to the start of the DECLS_BLOCK block. It /// has read all the abbreviations at the start of the block and is ready to /// jump around with these in context. @@ -634,8 +640,7 @@ public: /// This routine builds a new IdentifierInfo for the given identifier. If any /// declarations with this name are visible from translation unit scope, their /// declarations will be deserialized and introduced into the declaration - /// chain of the identifier. FIXME: if this identifier names a macro, - /// deserialize the macro. + /// chain of the identifier. virtual IdentifierInfo* get(const char *NameStart, const char *NameEnd); IdentifierInfo* get(llvm::StringRef Name) { return get(Name.begin(), Name.end()); @@ -712,6 +717,9 @@ public: /// \brief Reads the macro record located at the given offset. void ReadMacroRecord(uint64_t Offset); + /// \brief Read the set of macros defined by this external macro source. + virtual void ReadDefinedMacros(); + /// \brief Retrieve the AST context that this PCH reader /// supplements. ASTContext *getContext() { return Context; } diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h index 27c14c9..c8df494 100644 --- a/include/clang/Frontend/Utils.h +++ b/include/clang/Frontend/Utils.h @@ -15,13 +15,11 @@ #define LLVM_CLANG_FRONTEND_UTILS_H #include "llvm/ADT/StringRef.h" -#include <vector> -#include <string> +#include "llvm/ADT/Twine.h" +#include "llvm/Support/raw_ostream.h" namespace llvm { class Triple; -class raw_ostream; -class raw_fd_ostream; } namespace clang { @@ -41,6 +39,29 @@ class PreprocessorOutputOptions; class SourceManager; class Stmt; class TargetInfo; +class FrontendOptions; + +class MacroBuilder { + llvm::raw_ostream &Out; +public: + MacroBuilder(llvm::raw_ostream &Output) : Out(Output) {} + + /// Append a #define line for macro of the form "#define Name Value\n". + void defineMacro(const llvm::Twine &Name, const llvm::Twine &Value = "1") { + Out << "#define " << Name << ' ' << Value << '\n'; + } + + /// Append a #undef line for Name. Name should be of the form XXX + /// and we emit "#undef XXX". + void undefineMacro(const llvm::Twine &Name) { + Out << "#undef " << Name << '\n'; + } + + /// Directly append Str and a newline to the underlying buffer. + void append(const llvm::Twine &Str) { + Out << Str << '\n'; + } +}; /// Normalize \arg File for use in a user defined #include directive (in the /// predefines buffer). @@ -56,7 +77,8 @@ void ApplyHeaderSearchOptions(HeaderSearch &HS, /// environment ready to process a single file. void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts, - const HeaderSearchOptions &HSOpts); + const HeaderSearchOptions &HSOpts, + const FrontendOptions &FEOpts); /// ProcessWarningOptions - Initialize the diagnostic client and process the /// warning options specified on the command line. diff --git a/include/clang/Lex/DirectoryLookup.h b/include/clang/Lex/DirectoryLookup.h index c94a990..64687a1 100644 --- a/include/clang/Lex/DirectoryLookup.h +++ b/include/clang/Lex/DirectoryLookup.h @@ -16,6 +16,9 @@ #include "clang/Basic/SourceManager.h" +namespace llvm { + class StringRef; +} namespace clang { class HeaderMap; class DirectoryEntry; @@ -118,12 +121,10 @@ public: /// LookupFile - Lookup the specified file in this search path, returning it /// if it exists or returning null if not. - const FileEntry *LookupFile(const char *FilenameStart, - const char *FilenameEnd, HeaderSearch &HS) const; + const FileEntry *LookupFile(llvm::StringRef Filename, HeaderSearch &HS) const; private: - const FileEntry *DoFrameworkLookup(const char *FilenameStart, - const char *FilenameEnd, + const FileEntry *DoFrameworkLookup(llvm::StringRef Filename, HeaderSearch &HS) const; }; diff --git a/include/clang/Lex/ExternalPreprocessorSource.h b/include/clang/Lex/ExternalPreprocessorSource.h new file mode 100644 index 0000000..af5c389 --- /dev/null +++ b/include/clang/Lex/ExternalPreprocessorSource.h @@ -0,0 +1,34 @@ +//===- ExternalPreprocessorSource.h - Abstract Macro Interface --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the ExternalPreprocessorSource interface, which enables +// construction of macro definitions from some external source. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H +#define LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H + +namespace clang { + +/// \brief Abstract interface for external sources of preprocessor +/// information. +/// +/// This abstract class allows an external sources (such as the \c PCHReader) +/// to provide additional macro definitions. +class ExternalPreprocessorSource { +public: + virtual ~ExternalPreprocessorSource(); + + /// \brief Read the set of macros defined by this external macro source. + virtual void ReadDefinedMacros() = 0; +}; + +} + +#endif // LLVM_CLANG_LEX_EXTERNAL_PREPROCESSOR_SOURCE_H diff --git a/include/clang/Lex/HeaderMap.h b/include/clang/Lex/HeaderMap.h index 6bb7c25..9837e29 100644 --- a/include/clang/Lex/HeaderMap.h +++ b/include/clang/Lex/HeaderMap.h @@ -16,6 +16,7 @@ namespace llvm { class MemoryBuffer; + class StringRef; } namespace clang { class FileEntry; @@ -46,8 +47,7 @@ public: /// LookupFile - Check to see if the specified relative filename is located in /// this HeaderMap. If so, open it and return its FileEntry. - const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd, - FileManager &FM) const; + const FileEntry *LookupFile(llvm::StringRef Filename, FileManager &FM) const; /// getFileName - Return the filename of the headermap. const char *getFileName() const; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 7517440..16b8379 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -150,8 +150,7 @@ public: /// search location. This is used to implement #include_next. CurFileEnt, if /// non-null, indicates where the #including file is, in case a relative /// search is needed. - const FileEntry *LookupFile(const char *FilenameStart, - const char *FilenameEnd, bool isAngled, + const FileEntry *LookupFile(llvm::StringRef Filename, bool isAngled, const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir, const FileEntry *CurFileEnt); @@ -161,16 +160,14 @@ public: /// within ".../Carbon.framework/Headers/Carbon.h", check to see if HIToolbox /// is a subframework within Carbon.framework. If so, return the FileEntry /// for the designated file, otherwise return null. - const FileEntry *LookupSubframeworkHeader(const char *FilenameStart, - const char *FilenameEnd, + const FileEntry *LookupSubframeworkHeader(llvm::StringRef Filename, const FileEntry *RelativeFileEnt); /// LookupFrameworkCache - Look up the specified framework name in our /// framework cache, returning the DirectoryEntry it is in if we know, /// otherwise, return null. - const DirectoryEntry *&LookupFrameworkCache(const char *FWNameStart, - const char *FWNameEnd) { - return FrameworkMap.GetOrCreateValue(FWNameStart, FWNameEnd).getValue(); + const DirectoryEntry *&LookupFrameworkCache(llvm::StringRef FWName) { + return FrameworkMap.GetOrCreateValue(FWName).getValue(); } /// ShouldEnterIncludeFile - Mark the specified file as a target of of a diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 7c838ff..fc2671f 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -32,6 +32,7 @@ namespace clang { class SourceManager; +class ExternalPreprocessorSource; class FileManager; class FileEntry; class HeaderSearch; @@ -42,7 +43,7 @@ class ScratchBuffer; class TargetInfo; class PPCallbacks; class DirectoryLookup; - + /// Preprocessor - This object engages in a tight little dance with the lexer to /// efficiently preprocess tokens. Lexers know only about tokens within a /// single source file, and don't know anything about preprocessor-level issues @@ -57,6 +58,9 @@ class Preprocessor { ScratchBuffer *ScratchBuf; HeaderSearch &HeaderInfo; + /// \brief External source of macros. + ExternalPreprocessorSource *ExternalSource; + /// PTH - An optional PTHManager object used for getting tokens from /// a token cache rather than lexing the original source file. llvm::OwningPtr<PTHManager> PTH; @@ -99,6 +103,9 @@ class Preprocessor { /// DisableMacroExpansion - True if macro expansion is disabled. bool DisableMacroExpansion : 1; + /// \brief Whether we have already loaded macros from the external source. + mutable bool ReadMacrosFromExternalSource : 1; + /// Identifiers - This is mapping/lookup information for all identifiers in /// the program, including program keywords. mutable IdentifierTable Identifiers; @@ -247,6 +254,14 @@ public: PTHManager *getPTHManager() { return PTH.get(); } + void setExternalSource(ExternalPreprocessorSource *Source) { + ExternalSource = Source; + } + + ExternalPreprocessorSource *getExternalSource() const { + return ExternalSource; + } + /// SetCommentRetentionState - Control whether or not the preprocessor retains /// comments in output. void SetCommentRetentionState(bool KeepComments, bool KeepMacroComments) { @@ -296,11 +311,9 @@ public: /// state of the macro table. This visits every currently-defined macro. typedef llvm::DenseMap<IdentifierInfo*, MacroInfo*>::const_iterator macro_iterator; - macro_iterator macro_begin() const { return Macros.begin(); } - macro_iterator macro_end() const { return Macros.end(); } - - - + macro_iterator macro_begin(bool IncludeExternalMacros = true) const; + macro_iterator macro_end(bool IncludeExternalMacros = true) const; + const std::string &getPredefines() const { return Predefines; } /// setPredefines - Set the predefines for this Preprocessor. These /// predefines are automatically injected when parsing the main file. @@ -678,14 +691,14 @@ public: /// caller is expected to provide a buffer that is large enough to hold the /// spelling of the filename, but is also expected to handle the case when /// this method decides to use a different buffer. - bool GetIncludeFilenameSpelling(SourceLocation Loc, - const char *&BufStart, const char *&BufEnd); + bool GetIncludeFilenameSpelling(SourceLocation Loc,llvm::StringRef &Filename); /// LookupFile - Given a "foo" or <foo> reference, look up the indicated file, /// return null on failure. isAngled indicates whether the file reference is /// for system #include's or not (i.e. using <> instead of ""). - const FileEntry *LookupFile(const char *FilenameStart,const char *FilenameEnd, - bool isAngled, const DirectoryLookup *FromDir, + const FileEntry *LookupFile(llvm::StringRef Filename, + SourceLocation FilenameTokLoc, bool isAngled, + const DirectoryLookup *FromDir, const DirectoryLookup *&CurDir); /// GetCurLookup - The DirectoryLookup structure used to find the current diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h index 4cbc21a..7209e0a 100644 --- a/include/clang/Parse/Action.h +++ b/include/clang/Parse/Action.h @@ -291,6 +291,42 @@ public: bool EnteringContext, TemplateTy &Template) = 0; + /// \brief Action called as part of error recovery when the parser has + /// determined that the given name must refer to a template, but + /// \c isTemplateName() did not return a result. + /// + /// This callback permits the action to give a detailed diagnostic when an + /// unknown template name is encountered and, potentially, to try to recover + /// by producing a new template in \p SuggestedTemplate. + /// + /// \param II the name that should be a template. + /// + /// \param IILoc the location of the name in the source. + /// + /// \param S the scope in which name lookup was performed. + /// + /// \param SS the C++ scope specifier that preceded the name. + /// + /// \param SuggestedTemplate if the action sets this template to a non-NULL, + /// template, the parser will recover by consuming the template name token + /// and the template argument list that follows. + /// + /// \param SuggestedTemplateKind as input, the kind of template that we + /// expect (e.g., \c TNK_Type_template or \c TNK_Function_template). If the + /// action provides a suggested template, this should be set to the kind of + /// template. + /// + /// \returns true if a diagnostic was emitted, false otherwise. When false, + /// the parser itself will emit a generic "unknown template name" diagnostic. + virtual bool DiagnoseUnknownTemplateName(const IdentifierInfo &II, + SourceLocation IILoc, + Scope *S, + const CXXScopeSpec *SS, + TemplateTy &SuggestedTemplate, + TemplateNameKind &SuggestedKind) { + return false; + } + /// ActOnCXXGlobalScopeSpecifier - Return the object that represents the /// global scope ('::'). virtual CXXScopeTy *ActOnCXXGlobalScopeSpecifier(Scope *S, @@ -866,7 +902,8 @@ public: MultiExprArg Exprs, ExprArg AsmString, MultiExprArg Clobbers, - SourceLocation RParenLoc) { + SourceLocation RParenLoc, + bool MSAsm = false) { return StmtEmpty(); } @@ -2176,7 +2213,7 @@ public: // protocols, categories), the parser passes all methods/properties. // For class implementations, these values default to 0. For implementations, // methods are processed incrementally (by ActOnMethodDeclaration above). - virtual void ActOnAtEnd(SourceLocation AtEndLoc, + virtual void ActOnAtEnd(SourceRange AtEnd, DeclPtrTy classDecl, DeclPtrTy *allMethods = 0, unsigned allNum = 0, @@ -2339,11 +2376,49 @@ public: /// \todo Code completion for attributes. //@{ + /// \brief Describes the context in which code completion occurs. + enum CodeCompletionContext { + /// \brief Code completion occurs at top-level or namespace context. + CCC_Namespace, + /// \brief Code completion occurs within a class, struct, or union. + CCC_Class, + /// \brief Code completion occurs within an Objective-C interface, protocol, + /// or category. + CCC_ObjCInterface, + /// \brief Code completion occurs within an Objective-C implementation or + /// category implementation + CCC_ObjCImplementation, + /// \brief Code completion occurs within the list of instance variables + /// in an Objective-C interface, protocol, category, or implementation. + CCC_ObjCInstanceVariableList, + /// \brief Code completion occurs following one or more template + /// headers. + CCC_Template, + /// \brief Code completion occurs following one or more template + /// headers within a class. + CCC_MemberTemplate, + /// \brief Code completion occurs within an expression. + CCC_Expression, + /// \brief Code completion occurs within a statement, which may + /// also be an expression or a declaration. + CCC_Statement, + /// \brief Code completion occurs at the beginning of the + /// initialization statement (or expression) in a for loop. + CCC_ForInit, + /// \brief Code completion ocurs within the condition of an if, + /// while, switch, or for statement. + CCC_Condition + }; + /// \brief Code completion for an ordinary name that occurs within the given /// scope. /// /// \param S the scope in which the name occurs. - virtual void CodeCompleteOrdinaryName(Scope *S) { } + /// + /// \param CompletionContext the context in which code completion + /// occurs. + virtual void CodeCompleteOrdinaryName(Scope *S, + CodeCompletionContext CompletionContext) { } /// \brief Code completion for a member access expression. /// @@ -2458,6 +2533,9 @@ public: virtual void CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl, bool InInterface) { } + /// \brief Code completion after the '@' in the list of instance variables. + virtual void CodeCompleteObjCAtVisibility(Scope *S) { } + /// \brief Code completion after the '@' in a statement. virtual void CodeCompleteObjCAtStatement(Scope *S) { } diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 7c99e3e..6a3d8a9 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -194,6 +194,7 @@ private: SourceLocation StorageClassSpecLoc, SCS_threadLoc; SourceLocation TSWLoc, TSCLoc, TSSLoc, TSTLoc; + SourceRange TypeofParensRange; SourceLocation TQ_constLoc, TQ_restrictLoc, TQ_volatileLoc; SourceLocation FS_inlineLoc, FS_virtualLoc, FS_explicitLoc; SourceLocation FriendLoc, ConstexprLoc; @@ -257,6 +258,9 @@ public: SourceLocation getTypeSpecSignLoc() const { return TSSLoc; } SourceLocation getTypeSpecTypeLoc() const { return TSTLoc; } + SourceRange getTypeofParensRange() const { return TypeofParensRange; } + void setTypeofParensRange(SourceRange range) { TypeofParensRange = range; } + /// getSpecifierName - Turn a type-specifier-type into a string like "_Bool" /// or "union". static const char *getSpecifierName(DeclSpec::TST T); @@ -493,6 +497,8 @@ public: IK_LiteralOperatorId, /// \brief A constructor name. IK_ConstructorName, + /// \brief A constructor named via a template-id. + IK_ConstructorTemplateId, /// \brief A destructor name. IK_DestructorName, /// \brief A template-id, e.g., f<int>. @@ -534,8 +540,9 @@ public: /// class-name. ActionBase::TypeTy *DestructorName; - /// \brief When Kind == IK_TemplateId, the template-id annotation that - /// contains the template name and template arguments. + /// \brief When Kind == IK_TemplateId or IK_ConstructorTemplateId, + /// the template-id annotation that contains the template name and + /// template arguments. TemplateIdAnnotation *TemplateId; }; @@ -648,6 +655,14 @@ public: ConstructorName = ClassType; } + /// \brief Specify that this unqualified-id was parsed as a + /// template-id that names a constructor. + /// + /// \param TemplateId the template-id annotation that describes the parsed + /// template-id. This UnqualifiedId instance will take ownership of the + /// \p TemplateId and will free it on destruction. + void setConstructorTemplateId(TemplateIdAnnotation *TemplateId); + /// \brief Specify that this unqualified-id was parsed as a destructor name. /// /// \param TildeLoc the location of the '~' that introduces the destructor diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 2214797..0fc9413 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -784,7 +784,7 @@ private: llvm::SmallVector<DeclPtrTy, 4> PendingObjCImpDecl; DeclPtrTy ParseObjCAtImplementationDeclaration(SourceLocation atLoc); - DeclPtrTy ParseObjCAtEndDeclaration(SourceLocation atLoc); + DeclPtrTy ParseObjCAtEndDeclaration(SourceRange atEnd); DeclPtrTy ParseObjCAtAliasDeclaration(SourceLocation atLoc); DeclPtrTy ParseObjCPropertySynthesize(SourceLocation atLoc); DeclPtrTy ParseObjCPropertyDynamic(SourceLocation atLoc); @@ -1037,7 +1037,8 @@ private: /// would be best implemented in the parser. enum DeclSpecContext { DSC_normal, // normal context - DSC_class // class context, enables 'friend' + DSC_class, // class context, enables 'friend' + DSC_top_level // top-level/namespace declaration context }; DeclGroupPtrTy ParseDeclaration(unsigned Context, SourceLocation &DeclEnd, @@ -1056,6 +1057,7 @@ private: bool ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS, const ParsedTemplateInfo &TemplateInfo, AccessSpecifier AS); + DeclSpecContext getDeclSpecContextFromDeclaratorContext(unsigned Context); void ParseDeclarationSpecifiers(DeclSpec &DS, const ParsedTemplateInfo &TemplateInfo = ParsedTemplateInfo(), AccessSpecifier AS = AS_none, @@ -1109,6 +1111,11 @@ private: return isDeclarationSpecifier(); } + /// \brief Starting with a scope specifier, identifier, or + /// template-id that refers to the current class, determine whether + /// this is a constructor declarator. + bool isConstructorDeclarator(); + /// \brief Specifies the context in which type-id/expression /// disambiguation will occur. enum TentativeCXXTypeIdContext { diff --git a/include/clang/Rewrite/Rewriter.h b/include/clang/Rewrite/Rewriter.h index 29e78fa..1692180 100644 --- a/include/clang/Rewrite/Rewriter.h +++ b/include/clang/Rewrite/Rewriter.h @@ -146,13 +146,13 @@ public: /// are in the same file. If not, this returns -1. int getRangeSize(SourceRange Range) const; - /// getRewritenText - Return the rewritten form of the text in the specified + /// getRewrittenText - Return the rewritten form of the text in the specified /// range. If the start or end of the range was unrewritable or if they are /// in different buffers, this returns an empty string. /// /// Note that this method is not particularly efficient. /// - std::string getRewritenText(SourceRange Range) const; + std::string getRewrittenText(SourceRange Range) const; /// InsertText - Insert the specified string at the specified location in the /// original buffer. This method returns true (and does nothing) if the input diff --git a/include/clang/Sema/CodeCompleteConsumer.h b/include/clang/Sema/CodeCompleteConsumer.h index aec10f3..348917a 100644 --- a/include/clang/Sema/CodeCompleteConsumer.h +++ b/include/clang/Sema/CodeCompleteConsumer.h @@ -85,7 +85,18 @@ public: /// \brief A right angle bracket ('>'). CK_RightAngle, /// \brief A comma separator (','). - CK_Comma + CK_Comma, + /// \brief A colon (':'). + CK_Colon, + /// \brief A semicolon (';'). + CK_SemiColon, + /// \brief An '=' sign. + CK_Equal, + /// \brief Horizontal whitespace (' '). + CK_HorizontalSpace, + /// \brief Verticle whitespace ('\n' or '\r\n', depending on the + /// platform). + CK_VerticalSpace }; /// \brief One piece of the code completion string. @@ -270,10 +281,6 @@ public: IdentifierInfo *Macro; }; - /// \brief Describes how good this result is, with zero being the best - /// result and progressively higher numbers representing poorer results. - unsigned Rank; - /// \brief Specifiers which parameter (of a function, Objective-C method, /// macro, etc.) we should start with when formatting the result. unsigned StartParameter; @@ -298,32 +305,32 @@ public: NestedNameSpecifier *Qualifier; /// \brief Build a result that refers to a declaration. - Result(NamedDecl *Declaration, unsigned Rank, + Result(NamedDecl *Declaration, NestedNameSpecifier *Qualifier = 0, bool QualifierIsInformative = false) - : Kind(RK_Declaration), Declaration(Declaration), Rank(Rank), + : Kind(RK_Declaration), Declaration(Declaration), StartParameter(0), Hidden(false), QualifierIsInformative(QualifierIsInformative), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(Qualifier) { } /// \brief Build a result that refers to a keyword or symbol. - Result(const char *Keyword, unsigned Rank) - : Kind(RK_Keyword), Keyword(Keyword), Rank(Rank), StartParameter(0), + Result(const char *Keyword) + : Kind(RK_Keyword), Keyword(Keyword), StartParameter(0), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(0) { } /// \brief Build a result that refers to a macro. - Result(IdentifierInfo *Macro, unsigned Rank) - : Kind(RK_Macro), Macro(Macro), Rank(Rank), StartParameter(0), + Result(IdentifierInfo *Macro) + : Kind(RK_Macro), Macro(Macro), StartParameter(0), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(0) { } /// \brief Build a result that refers to a pattern. - Result(CodeCompletionString *Pattern, unsigned Rank) - : Kind(RK_Pattern), Pattern(Pattern), Rank(Rank), StartParameter(0), + Result(CodeCompletionString *Pattern) + : Kind(RK_Pattern), Pattern(Pattern), StartParameter(0), Hidden(false), QualifierIsInformative(0), StartsNestedNameSpecifier(false), AllParametersAreInformative(false), Qualifier(0) { } |